dev-data.py 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. """ Populate the pagure db with some dev data. """
  4. from __future__ import print_function, unicode_literals
  5. import argparse
  6. import os
  7. import sys
  8. import tempfile
  9. import pygit2
  10. import shutil
  11. import six
  12. from sqlalchemy import create_engine, MetaData
  13. import pagure
  14. import tests
  15. import pagure.lib.model
  16. import pagure.lib.query
  17. from pagure.lib.login import generate_hashed_value
  18. from pagure.lib.model import create_default_status
  19. from pagure.lib.repo import PagureRepo
  20. '''
  21. Usage:
  22. python dev-data.py --init
  23. python dev-data.py --clean
  24. python dev-data.py --populate
  25. python dev-data.py --all
  26. '''
  27. _config = pagure.config.reload_config()
  28. def init_database():
  29. DB_URL = _config['DB_URL']
  30. # create the table if it doesnt exist
  31. pagure.lib.model.create_tables(
  32. DB_URL,
  33. _config.get('PATH_ALEMBIC_INI', None),
  34. acls=_config.get('ACLS', {}),
  35. debug=True)
  36. engine = pagure.lib.query.create_engine('%s' % DB_URL, echo=True)
  37. metadata = MetaData(engine)
  38. metadata.reflect(bind=engine)
  39. return engine, metadata
  40. def empty_dev_db(metadata, engine):
  41. print('')
  42. print('')
  43. print('WARNING: Deleting all data from ', _config['DB_URL'])
  44. # Dangerous: this will wipe the data from the table but keep the schema
  45. print('')
  46. response = six.moves.input('Do you want to continue? (yes/no) ')
  47. if 'yes'.startswith(response.lower()):
  48. for tbl in reversed(metadata.sorted_tables):
  49. if tbl.fullname != 'acls':
  50. engine.execute(tbl.delete())
  51. else:
  52. exit("Aborting.")
  53. def insert_data(session, username, user_email):
  54. _config['EMAIL_SEND'] = False
  55. _config['TESTING'] = True
  56. # Populate with default statuses
  57. create_default_status(session)
  58. print('Default statuses populated')
  59. ######################################
  60. # tags
  61. item = pagure.lib.model.Tag(
  62. tag='tag1',
  63. )
  64. session.add(item)
  65. session.commit()
  66. ######################################
  67. # Users
  68. # Create a couple of users
  69. pingou = item = pagure.lib.model.User(
  70. user='pingou',
  71. fullname='PY C',
  72. password=generate_hashed_value(u'testing123'),
  73. token=None,
  74. default_email='bar@pingou.com',
  75. )
  76. session.add(item)
  77. session.commit()
  78. print("User created: {} <{}>, {}".format(item.user, item.default_email, 'testing123'))
  79. foo = item = pagure.lib.model.User(
  80. user='foo',
  81. fullname='foo bar',
  82. password=generate_hashed_value(u'testing123'),
  83. token=None,
  84. default_email='foo@bar.com',
  85. )
  86. session.add(item)
  87. session.commit()
  88. print("User created: {} <{}>, {}".format(item.user, item.default_email, 'testing123'))
  89. you = item = pagure.lib.model.User(
  90. user=username,
  91. fullname=username,
  92. password=generate_hashed_value(u'testing123'),
  93. token=None,
  94. default_email=user_email,
  95. )
  96. session.add(item)
  97. session.commit()
  98. print("User created: {} <{}>, {}".format(item.user, item.default_email, 'testing123'))
  99. ######################################
  100. # pagure_group
  101. item = pagure.lib.model.PagureGroup(
  102. group_name='admin',
  103. group_type='admin',
  104. user_id=pingou.id,
  105. display_name='admin',
  106. description='Admin Group',
  107. )
  108. session.add(item)
  109. session.commit()
  110. print('Created "admin" group. Pingou is a member.')
  111. # Add a couple of groups so that we can list them
  112. item = pagure.lib.model.PagureGroup(
  113. group_name='group',
  114. group_type='user',
  115. user_id=pingou.id,
  116. display_name='group group',
  117. description='this is a group group',
  118. )
  119. session.add(item)
  120. session.commit()
  121. print('Created "group" group. Pingou is a member.')
  122. item = pagure.lib.model.PagureGroup(
  123. group_name='rel-eng',
  124. group_type='user',
  125. user_id=pingou.id,
  126. display_name='Release Engineering',
  127. description='The group of release engineers',
  128. )
  129. session.add(item)
  130. session.commit()
  131. print('Created "rel-eng" group. Pingou is a member.')
  132. ######################################
  133. # projects
  134. import shutil
  135. # delete folder from local instance to start from a clean slate
  136. if os.path.exists(_config['GIT_FOLDER']):
  137. shutil.rmtree(_config['GIT_FOLDER'])
  138. # Create projects
  139. item = project1 = pagure.lib.model.Project(
  140. user_id=pingou.id,
  141. name='test',
  142. is_fork=False,
  143. parent_id=None,
  144. description='test project #1',
  145. hook_token='aaabbbccc',
  146. )
  147. item.close_status = ['Invalid', 'Insufficient data', 'Fixed', 'Duplicate']
  148. session.add(item)
  149. session.flush()
  150. tests.create_locks(session, item)
  151. item = project2 = pagure.lib.model.Project(
  152. user_id=pingou.id,
  153. name='test2',
  154. is_fork=False,
  155. parent_id=None,
  156. description='test project #2',
  157. hook_token='aaabbbddd',
  158. )
  159. item.close_status = ['Invalid', 'Insufficient data', 'Fixed', 'Duplicate']
  160. session.add(item)
  161. item = project3 = pagure.lib.model.Project(
  162. user_id=pingou.id,
  163. name='test3',
  164. is_fork=False,
  165. parent_id=None,
  166. description='namespaced test project',
  167. hook_token='aaabbbeee',
  168. namespace='somenamespace',
  169. )
  170. item.close_status = ['Invalid', 'Insufficient data', 'Fixed', 'Duplicate']
  171. session.add(item)
  172. session.commit()
  173. tests.create_projects_git(_config['GIT_FOLDER'], bare=True)
  174. add_content_git_repo(
  175. os.path.join(_config['GIT_FOLDER'], 'test.git'))
  176. tests.add_readme_git_repo(
  177. os.path.join(_config['GIT_FOLDER'], 'test.git'))
  178. # Add some content to the git repo
  179. add_content_git_repo(
  180. os.path.join(_config['GIT_FOLDER'], 'forks', 'pingou',
  181. 'test.git'))
  182. tests.add_readme_git_repo(
  183. os.path.join(_config['GIT_FOLDER'], 'forks', 'pingou',
  184. 'test.git'))
  185. tests.add_commit_git_repo(
  186. os.path.join(_config['GIT_FOLDER'], 'forks', 'pingou',
  187. 'test.git'), ncommits=10)
  188. ######################################
  189. # user_emails
  190. item = pagure.lib.model.UserEmail(
  191. user_id=pingou.id,
  192. email='bar@pingou.com')
  193. session.add(item)
  194. item = pagure.lib.model.UserEmail(
  195. user_id=pingou.id,
  196. email='foo@pingou.com')
  197. session.add(item)
  198. item = pagure.lib.model.UserEmail(
  199. user_id=foo.id,
  200. email='foo@bar.com')
  201. session.add(item)
  202. item = pagure.lib.model.UserEmail(
  203. user_id=you.id,
  204. email=user_email)
  205. session.add(item)
  206. session.commit()
  207. ######################################
  208. # user_emails_pending
  209. email_pend = pagure.lib.model.UserEmailPending(
  210. user_id=pingou.id,
  211. email='foo@fp.o',
  212. token='abcdef',
  213. )
  214. session.add(email_pend)
  215. session.commit()
  216. ######################################
  217. # issues
  218. # Add an issue and tag it so that we can list them
  219. item = pagure.lib.model.Issue(
  220. id=1001,
  221. uid='foobar',
  222. project_id=project1.id,
  223. title='Problem with jenkins build',
  224. content='For some reason the tests fail at line:24',
  225. user_id=pingou.id,
  226. )
  227. session.add(item)
  228. session.commit()
  229. item = pagure.lib.model.Issue(
  230. id=1002,
  231. uid='foobar2',
  232. project_id=project1.id,
  233. title='Unit tests failing',
  234. content='Need to fix code for the unit tests to '
  235. 'pass so jenkins build can complete.',
  236. user_id=pingou.id,
  237. )
  238. session.add(item)
  239. session.commit()
  240. item = pagure.lib.model.Issue(
  241. id=1003,
  242. uid='foobar3',
  243. project_id=project1.id,
  244. title='Segfault during execution',
  245. content='Index out of bounds for variable i?',
  246. user_id=you.id,
  247. )
  248. session.add(item)
  249. session.commit()
  250. ######################################
  251. # pagure_user_group
  252. group = pagure.lib.query.search_groups(session, pattern=None,
  253. group_name="rel-eng", group_type=None)
  254. item = pagure.lib.model.PagureUserGroup(
  255. user_id=pingou.id,
  256. group_id=group.id
  257. )
  258. session.add(item)
  259. session.commit()
  260. group = pagure.lib.query.search_groups(session, pattern=None,
  261. group_name="admin", group_type=None)
  262. item = pagure.lib.model.PagureUserGroup(
  263. user_id=you.id,
  264. group_id=group.id
  265. )
  266. session.add(item)
  267. session.commit()
  268. group = pagure.lib.query.search_groups(session, pattern=None,
  269. group_name="group", group_type=None)
  270. item = pagure.lib.model.PagureUserGroup(
  271. user_id=foo.id,
  272. group_id=group.id
  273. )
  274. session.add(item)
  275. session.commit()
  276. ######################################
  277. # projects_groups
  278. group = pagure.lib.query.search_groups(session, pattern=None,
  279. group_name="rel-eng", group_type=None)
  280. repo = pagure.lib.query.get_authorized_project(session, 'test')
  281. item = pagure.lib.model.ProjectGroup(
  282. project_id=repo.id,
  283. group_id=group.id,
  284. access="commit"
  285. )
  286. session.add(item)
  287. session.commit()
  288. group = pagure.lib.query.search_groups(session, pattern=None,
  289. group_name="admin", group_type=None)
  290. repo = pagure.lib.query.get_authorized_project(session, 'test2')
  291. item = pagure.lib.model.ProjectGroup(
  292. project_id=repo.id,
  293. group_id=group.id,
  294. access="admin"
  295. )
  296. session.add(item)
  297. session.commit()
  298. ######################################
  299. # pull_requests
  300. repo = pagure.lib.query.get_authorized_project(session, 'test')
  301. forked_repo = pagure.lib.query.get_authorized_project(session, 'test')
  302. req = pagure.lib.query.new_pull_request(
  303. session=session,
  304. repo_from=forked_repo,
  305. branch_from='master',
  306. repo_to=repo,
  307. branch_to='master',
  308. title='Fixing code for unittest',
  309. user=username
  310. )
  311. session.commit()
  312. ######################################
  313. # tokens
  314. tests.create_tokens(session, user_id=pingou.id, project_id=project1.id)
  315. ######################################
  316. # user_projects
  317. repo = pagure.lib.query.get_authorized_project(session, 'test')
  318. item = pagure.lib.model.ProjectUser(
  319. project_id=repo.id,
  320. user_id=foo.id,
  321. access="commit"
  322. )
  323. session.add(item)
  324. session.commit()
  325. repo = pagure.lib.query.get_authorized_project(session, 'test2')
  326. item = pagure.lib.model.ProjectUser(
  327. project_id=repo.id,
  328. user_id=you.id,
  329. access="commit"
  330. )
  331. session.add(item)
  332. session.commit()
  333. ######################################
  334. # issue_comments
  335. item = pagure.lib.model.IssueComment(
  336. user_id=pingou.id,
  337. issue_uid='foobar',
  338. comment='We may need to adjust the unittests instead of the code.',
  339. )
  340. session.add(item)
  341. session.commit()
  342. ######################################
  343. # issue_to_issue
  344. repo = pagure.lib.query.get_authorized_project(session, 'test')
  345. all_issues = pagure.lib.query.search_issues(session, repo)
  346. pagure.lib.query.add_issue_dependency(session, all_issues[0],
  347. all_issues[1], 'pingou')
  348. ######################################
  349. # pull_request_comments
  350. user = pagure.lib.query.search_user(session, username='pingou')
  351. # only 1 pull request available atm
  352. pr = pagure.lib.query.get_pull_request_of_user(session, "pingou")[0]
  353. item = pagure.lib.model.PullRequestComment(
  354. pull_request_uid=pr.uid,
  355. user_id=user.id,
  356. comment="+1 for me. Btw, could you rebase before you merge?",
  357. notification=0
  358. )
  359. session.add(item)
  360. session.commit()
  361. ######################################
  362. # pull_request_flags
  363. # only 1 pull request available atm
  364. pr = pagure.lib.query.get_pull_request_of_user(session, "pingou")[0]
  365. item = pagure.lib.model.PullRequestFlag(
  366. uid="random_pr_flag_uid",
  367. pull_request_uid=pr.uid,
  368. user_id=pingou.id,
  369. username=pingou.user,
  370. percent=80,
  371. comment="Jenkins build passes",
  372. url=str(pr.id),
  373. status="Open"
  374. )
  375. session.add(item)
  376. session.commit()
  377. ######################################
  378. # tags_issues
  379. repo = pagure.lib.query.get_authorized_project(session, 'test')
  380. issues = pagure.lib.query.search_issues(session, repo)
  381. item = pagure.lib.model.TagIssue(
  382. issue_uid=issues[0].uid,
  383. tag='tag1',
  384. )
  385. session.add(item)
  386. session.commit()
  387. ######################################
  388. # tokens_acls
  389. tests.create_tokens_acl(session)
  390. ######################################
  391. # Fork a project
  392. # delete fork data
  393. fork_proj_location = "forks/foo/test.git"
  394. try:
  395. shutil.rmtree(os.path.join(_config['GIT_FOLDER'],
  396. fork_proj_location))
  397. except:
  398. print('git folder already deleted')
  399. try:
  400. shutil.rmtree(os.path.join(_config['DOCS_FOLDER'],
  401. fork_proj_location))
  402. except:
  403. print('docs folder already deleted')
  404. try:
  405. shutil.rmtree(os.path.join(_config['TICKETS_FOLDER'],
  406. fork_proj_location))
  407. except:
  408. print('tickets folder already deleted')
  409. try:
  410. shutil.rmtree(os.path.join(_config['REQUESTS_FOLDER'],
  411. fork_proj_location))
  412. except:
  413. print('requests folder already deleted')
  414. repo = pagure.lib.query.get_authorized_project(session, 'test')
  415. result = pagure.lib.query.fork_project(session, 'foo', repo)
  416. if result == 'Repo "test" cloned to "foo/test"':
  417. session.commit()
  418. def add_content_git_repo(folder, branch='master'):
  419. """ Create some content for the specified git repo. """
  420. if not os.path.exists(folder):
  421. os.makedirs(folder)
  422. brepo = pygit2.init_repository(folder, bare=True)
  423. newfolder = tempfile.mkdtemp(prefix='pagure-tests')
  424. repo = pygit2.clone_repository(folder, newfolder)
  425. # Create a file in that git repo
  426. with open(os.path.join(newfolder, 'sources'), 'w') as stream:
  427. stream.write('foo\n bar')
  428. repo.index.add('sources')
  429. repo.index.write()
  430. parents = []
  431. commit = None
  432. try:
  433. commit = repo.revparse_single(
  434. 'HEAD' if branch == 'master' else branch)
  435. except KeyError:
  436. pass
  437. if commit:
  438. parents = [commit.oid.hex]
  439. # Commits the files added
  440. tree = repo.index.write_tree()
  441. author = pygit2.Signature(
  442. 'Alice Author', 'alice@authors.tld')
  443. committer = pygit2.Signature(
  444. 'Cecil Committer', 'cecil@committers.tld')
  445. repo.create_commit(
  446. 'refs/heads/%s' % branch, # the name of the reference to update
  447. author,
  448. committer,
  449. 'Add sources file for testing',
  450. # binary string representing the tree object ID
  451. tree,
  452. # list of binary strings representing parents of the new commit
  453. parents,
  454. )
  455. parents = []
  456. commit = None
  457. try:
  458. commit = repo.revparse_single(
  459. 'HEAD' if branch == 'master' else branch)
  460. except KeyError:
  461. pass
  462. if commit:
  463. parents = [commit.oid.hex]
  464. subfolder = os.path.join('folder1', 'folder2')
  465. if not os.path.exists(os.path.join(newfolder, subfolder)):
  466. os.makedirs(os.path.join(newfolder, subfolder))
  467. # Create a file in that git repo
  468. with open(os.path.join(newfolder, subfolder, 'file'), 'w') as stream:
  469. stream.write('foo\n bar\nbaz')
  470. repo.index.add(os.path.join(subfolder, 'file'))
  471. repo.index.write()
  472. # Commits the files added
  473. tree = repo.index.write_tree()
  474. author = pygit2.Signature(
  475. 'Alice Author', 'alice@authors.tld')
  476. committer = pygit2.Signature(
  477. 'Cecil Committer', 'cecil@committers.tld')
  478. repo.create_commit(
  479. 'refs/heads/%s' % branch, # the name of the reference to update
  480. author,
  481. committer,
  482. 'Add some directory and a file for more testing',
  483. # binary string representing the tree object ID
  484. tree,
  485. # list of binary strings representing parents of the new commit
  486. parents
  487. )
  488. # Push to origin
  489. ori_remote = repo.remotes[0]
  490. master_ref = repo.lookup_reference(
  491. 'HEAD' if branch == 'master' else 'refs/heads/%s' % branch).resolve()
  492. refname = '%s:%s' % (master_ref.name, master_ref.name)
  493. PagureRepo.push(ori_remote, refname)
  494. shutil.rmtree(newfolder)
  495. if __name__ == "__main__":
  496. desc = "Run the dev database initialization/insertion/deletion " \
  497. "script for db located " + str(_config['DB_URL'])
  498. parser = argparse.ArgumentParser(prog="dev-data", description=desc)
  499. parser.add_argument('-i', '--init', action="store_true",
  500. help="Create the dev db")
  501. parser.add_argument('-p', '--populate', action="store_true",
  502. help="Add test data to the db")
  503. parser.add_argument('-d', '--delete', action="store_true",
  504. help="Wipe the dev db")
  505. parser.add_argument('-a', '--all', action="store_true",
  506. help="Create, Wipe, Populate the dev db")
  507. args = parser.parse_args()
  508. # forcing the user to choose
  509. if not any(vars(args).values()):
  510. parser.error('No arguments provided.')
  511. if args.init or args.delete or args.all:
  512. eng, meta = init_database()
  513. if args.delete or args.all:
  514. empty_dev_db(meta, eng)
  515. if args.populate or args.all:
  516. session = create_session(_config['DB_URL'])
  517. invalid_option = ['pingou', 'bar@pingou.com', 'foo', 'foo@bar.com']
  518. print("")
  519. user_name = six.moves.input(
  520. "Enter your username so we can add you into the test data: ")
  521. while user_name in invalid_option:
  522. print("Reserved names: " + str(invalid_option))
  523. user_name = six.moves.input(
  524. "Enter your username so we can add you into the test data: ")
  525. if not user_name.replace(" ", ""):
  526. user_name = 'pythagoras'
  527. print("")
  528. user_email = six.moves.input("Enter your user email: ")
  529. while user_email in invalid_option:
  530. print("Reserved names: " + str(invalid_option))
  531. user_email = six.moves.input("Enter your user email: ")
  532. if not user_email.replace(" ", ""):
  533. user_email = 'pythagoras@math.com'
  534. insert_data(session, user_name, user_email)