def set_up_git_repo(self, name='test'): """ Set up the git repo to play with. """ # Create a git repo to play with gitrepo = os.path.join(self.path, 'repos', '%s.git' % name) repo = pygit2.init_repository(gitrepo, bare=True) newpath = tempfile.mkdtemp(prefix='pagure-other-test') repopath = os.path.join(newpath, 'test') clone_repo = pygit2.clone_repository(gitrepo, repopath) # Create a file in that git repo with open(os.path.join(repopath, 'sources'), 'w') as stream: stream.write('foo\n bar') clone_repo.index.add('sources') clone_repo.index.write() # Commits the files added tree = clone_repo.index.write_tree() author = pygit2.Signature('Alice Author', '*****@*****.**') committer = pygit2.Signature('Cecil Committer', '*****@*****.**') clone_repo.create_commit( 'refs/heads/master', # the name of the reference to update author, committer, 'Add sources file for testing', # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit []) refname = 'refs/heads/master' ori_remote = clone_repo.remotes[0] PagureRepo.push(ori_remote, refname)
def clean_git(obj, repo, repofolder, objtype='ticket'): """ Update the given issue remove it from its git. """ if not repofolder: return # Get the fork repopath = os.path.join(repofolder, repo.path) # Clone the repo into a temp folder newpath = tempfile.mkdtemp(prefix='pagure-') new_repo = pygit2.clone_repository(repopath, newpath) file_path = os.path.join(newpath, obj.uid) # Get the current index index = new_repo.index # Are we adding files if not os.path.exists(file_path): shutil.rmtree(newpath) return # Remove the file os.unlink(file_path) # Add the changes to the index index.remove(obj.uid) # See if there is a parent to this commit parent = None try: parent = new_repo.head.get_object().oid except pygit2.GitError: pass parents = [] if parent: parents.append(parent) # Author/commiter will always be this one author = pygit2.Signature(name='pagure', email='pagure') # Actually commit new_repo.create_commit('refs/heads/master', author, author, 'Removed %s %s: %s' % (objtype, obj.uid, obj.title), new_repo.index.write_tree(), parents) index.write() # Push to origin ori_remote = new_repo.remotes[0] master_ref = new_repo.lookup_reference('HEAD').resolve() refname = '%s:%s' % (master_ref.name, master_ref.name) PagureRepo.push(ori_remote, refname) # Remove the clone shutil.rmtree(newpath)
def set_up_git_repo(self, name="test"): """ Set up the git repo to play with. """ # Create a git repo to play with gitrepo = os.path.join(self.path, "repos", "%s.git" % name) repo = pygit2.init_repository(gitrepo, bare=True) newpath = tempfile.mkdtemp(prefix="pagure-other-test") repopath = os.path.join(newpath, "test") clone_repo = pygit2.clone_repository(gitrepo, repopath) # Create a file in that git repo with open(os.path.join(repopath, "sources"), "w") as stream: stream.write("foo\n bar") clone_repo.index.add("sources") clone_repo.index.write() # Commits the files added tree = clone_repo.index.write_tree() author = pygit2.Signature("Alice Author", "*****@*****.**") committer = pygit2.Signature("Cecil Committer", "*****@*****.**") clone_repo.create_commit( "refs/heads/master", # the name of the reference to update author, committer, "Add sources file for testing", # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit [], ) refname = "refs/heads/master" ori_remote = clone_repo.remotes[0] PagureRepo.push(ori_remote, refname)
def remove_file_git_repo(folder, filename, branch='master'): """ Delete the specified file on the give git repo and branch. """ repo, newfolder, parents = _clone_and_top_commits(folder, branch) # Remove file repo.index.remove(filename) # Write the change and commit it tree = repo.index.write_tree() author = pygit2.Signature('Alice Author', '*****@*****.**') committer = pygit2.Signature('Cecil Committer', '*****@*****.**') branch_ref = "refs/heads/%s" % branch repo.create_commit( branch_ref, # the name of the reference to update author, committer, 'Remove file %s' % filename, # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit parents) # Push to origin ori_remote = repo.remotes[0] PagureRepo.push(ori_remote, '%s:%s' % (branch_ref, branch_ref)) shutil.rmtree(newfolder)
def remove_file_git_repo(folder, filename, branch="master"): """ Delete the specified file on the give git repo and branch. """ repo, newfolder, parents = _clone_and_top_commits(folder, branch) # Remove file repo.index.remove(filename) # Write the change and commit it tree = repo.index.write_tree() author = pygit2.Signature("Alice Author", "*****@*****.**") committer = pygit2.Signature("Cecil Committer", "*****@*****.**") branch_ref = "refs/heads/%s" % branch repo.create_commit( branch_ref, # the name of the reference to update author, committer, "Remove file %s" % filename, # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit parents, ) # Push to origin ori_remote = repo.remotes[0] PagureRepo.push(ori_remote, "%s:%s" % (branch_ref, branch_ref)) shutil.rmtree(newfolder)
def set_up_git_repo(self): """ Set up the git repo to play with. """ # Create a git repo to play with gitrepo = os.path.join(tests.HERE, "repos", "test.git") repo = pygit2.init_repository(gitrepo, bare=True) newpath = tempfile.mkdtemp(prefix="pagure-other-test") repopath = os.path.join(newpath, "test") clone_repo = pygit2.clone_repository(gitrepo, repopath) # Create a file in that git repo with open(os.path.join(repopath, "sources"), "w") as stream: stream.write("foo\n bar") clone_repo.index.add("sources") clone_repo.index.write() # Commits the files added tree = clone_repo.index.write_tree() author = pygit2.Signature("Alice Author", "*****@*****.**") committer = pygit2.Signature("Cecil Committer", "*****@*****.**") clone_repo.create_commit( "refs/heads/feature", # the name of the reference to update author, committer, "Add sources file for testing", # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit [], ) feature_branch = clone_repo.lookup_branch("feature") first_commit = feature_branch.get_object().hex # Second commit with open(os.path.join(repopath, ".gitignore"), "w") as stream: stream.write("*~") clone_repo.index.add(".gitignore") clone_repo.index.write() tree = clone_repo.index.write_tree() author = pygit2.Signature("Alice Author", "*****@*****.**") committer = pygit2.Signature("Cecil Committer", "*****@*****.**") clone_repo.create_commit( "refs/heads/feature", author, committer, "Add .gitignore file for testing", # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit [first_commit], ) refname = "refs/heads/feature" ori_remote = clone_repo.remotes[0] PagureRepo.push(ori_remote, refname) shutil.rmtree(newpath)
def add_readme_git_repo(folder, readme_name='README.rst', branch='master'): """ Create a README file for the specified git repo. """ repo, newfolder, parents = _clone_and_top_commits(folder, branch) if readme_name == 'README.rst': content = """Pagure ====== :Author: Pierre-Yves Chibon <*****@*****.**> Pagure is a light-weight git-centered forge based on pygit2. Currently, Pagure offers a web-interface for git repositories, a ticket system and possibilities to create new projects, fork existing ones and create/merge pull-requests across or within projects. Homepage: https://github.com/pypingou/pagure Dev instance: http://209.132.184.222/ (/!\\ May change unexpectedly, it's a dev instance ;-)) """ else: content = """Pagure ====== This is a placeholder """ + readme_name + """ that should never get displayed on the website if there is a README.rst in the repo. """ # Create a file in that git repo with open(os.path.join(newfolder, readme_name), 'w') as stream: stream.write(content) repo.index.add(readme_name) repo.index.write() # Commits the files added tree = repo.index.write_tree() author = pygit2.Signature( 'Alice Author', '*****@*****.**') committer = pygit2.Signature( 'Cecil Committer', '*****@*****.**') branch_ref = "refs/heads/%s" % branch repo.create_commit( branch_ref, # the name of the reference to update author, committer, 'Add a README file', # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit parents ) # Push to origin ori_remote = repo.remotes[0] PagureRepo.push(ori_remote, '%s:%s' % (branch_ref, branch_ref)) shutil.rmtree(newfolder)
def add_content_to_git(folder, filename='sources', content='foo'): """ Create some more commits for the specified git repo. """ repo, newfolder, parents = _clone_and_top_commits(folder, 'master') # Create a file in that git repo with open(os.path.join(newfolder, filename), 'a', encoding="utf-8") as stream: stream.write('%s\n' % content) repo.index.add(filename) repo.index.write() # Commits the files added tree = repo.index.write_tree() author = pygit2.Signature('Alice Author', '*****@*****.**') committer = pygit2.Signature('Cecil Committer', '*****@*****.**') repo.create_commit( 'refs/heads/master', # the name of the reference to update author, committer, 'Add content to file %s' % (filename), # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit parents, ) # Push to origin ori_remote = repo.remotes[0] master_ref = repo.lookup_reference('HEAD').resolve() refname = '%s:%s' % (master_ref.name, master_ref.name) PagureRepo.push(ori_remote, refname) shutil.rmtree(newfolder)
def set_up_git_repo(self): """ Set up the git repo to play with. """ # Create a git repo to play with gitrepo = os.path.join(tests.HERE, 'repos', 'test.git') repo = pygit2.init_repository(gitrepo, bare=True) newpath = tempfile.mkdtemp(prefix='pagure-other-test') repopath = os.path.join(newpath, 'test') clone_repo = pygit2.clone_repository(gitrepo, repopath) # Create a file in that git repo with open(os.path.join(repopath, 'sources'), 'w') as stream: stream.write('foo\n bar') clone_repo.index.add('sources') clone_repo.index.write() # Commits the files added tree = clone_repo.index.write_tree() author = pygit2.Signature('Alice Author', '*****@*****.**') committer = pygit2.Signature('Cecil Committer', '*****@*****.**') clone_repo.create_commit( 'refs/heads/feature', # the name of the reference to update author, committer, 'Add sources file for testing', # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit []) feature_branch = clone_repo.lookup_branch('feature') first_commit = feature_branch.get_object().hex # Second commit with open(os.path.join(repopath, '.gitignore'), 'w') as stream: stream.write('*~') clone_repo.index.add('.gitignore') clone_repo.index.write() tree = clone_repo.index.write_tree() author = pygit2.Signature('Alice Author', '*****@*****.**') committer = pygit2.Signature('Cecil Committer', '*****@*****.**') clone_repo.create_commit( 'refs/heads/feature', author, committer, 'Add .gitignore file for testing', # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit [first_commit]) refname = 'refs/heads/feature' ori_remote = clone_repo.remotes[0] PagureRepo.push(ori_remote, refname) shutil.rmtree(newpath)
def add_binary_git_repo(folder, filename): """ Create a fake image file for the specified git repo. """ if not os.path.exists(folder): os.makedirs(folder) brepo = pygit2.init_repository(folder, bare=True) newfolder = tempfile.mkdtemp(prefix='pagure-tests') repo = pygit2.clone_repository(folder, newfolder) content = b"""\x00\x00\x01\x00\x01\x00\x18\x18\x00\x00\x01\x00 \x00\x88 \t\x00\x00\x16\x00\x00\x00(\x00\x00\x00\x18\x00x00\x00\x01\x00 \x00\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7lM\x01\xa6kM\t\xa6kM\x01 \xa4fF\x04\xa2dE\x95\xa2cD8\xa1a """ parents = [] commit = None try: commit = repo.revparse_single('HEAD') except KeyError: pass if commit: parents = [commit.oid.hex] # Create a file in that git repo with open(os.path.join(newfolder, filename), 'wb') as stream: stream.write(content) repo.index.add(filename) repo.index.write() # Commits the files added tree = repo.index.write_tree() author = pygit2.Signature( 'Alice Author', '*****@*****.**') committer = pygit2.Signature( 'Cecil Committer', '*****@*****.**') repo.create_commit( 'refs/heads/master', # the name of the reference to update author, committer, 'Add a fake image file', # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit parents ) # Push to origin ori_remote = repo.remotes[0] master_ref = repo.lookup_reference('HEAD').resolve() refname = '%s:%s' % (master_ref.name, master_ref.name) PagureRepo.push(ori_remote, refname) shutil.rmtree(newfolder)
def test_api_git_tags(self): """ Test the api_git_tags method of the flask api. """ tests.create_projects(self.session) # Create a git repo to play with gitrepo = os.path.join(tests.HERE, 'repos', 'test.git') repo = pygit2.init_repository(gitrepo, bare=True) newpath = tempfile.mkdtemp(prefix='pagure-fork-test') repopath = os.path.join(newpath, 'test') clone_repo = pygit2.clone_repository(gitrepo, repopath) # Create a file in that git repo with open(os.path.join(repopath, 'sources'), 'w') as stream: stream.write('foo\n bar') clone_repo.index.add('sources') clone_repo.index.write() # Commits the files added tree = clone_repo.index.write_tree() author = pygit2.Signature( 'Alice Author', '*****@*****.**') committer = pygit2.Signature( 'Cecil Committer', '*****@*****.**') clone_repo.create_commit( 'refs/heads/master', # the name of the reference to update author, committer, 'Add sources file for testing', # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit [] ) refname = 'refs/heads/master:refs/heads/master' ori_remote = clone_repo.remotes[0] PagureRepo.push(ori_remote, refname) # Tag our first commit first_commit = repo.revparse_single('HEAD') tagger = pygit2.Signature('Alice Doe', '*****@*****.**', 12347, 0) repo.create_tag( "0.0.1", first_commit.oid.hex, pygit2.GIT_OBJ_COMMIT, tagger, "Release 0.0.1") # Check tags output = self.app.get('/api/0/test/git/tags') self.assertEqual(output.status_code, 200) data = json.loads(output.data) self.assertDictEqual( data, {'tags': ['0.0.1'], 'total_tags': 1} ) shutil.rmtree(newpath)
def add_commit_git_repo(folder, ncommits=10, filename="sources", branch="master", symlink_to=None): """ Create some more commits for the specified git repo. """ repo, newfolder, branch_ref_obj = _clone_and_top_commits(folder, branch, branch_ref=True) for index in range(ncommits): # Create a file in that git repo if symlink_to: os.symlink(symlink_to, os.path.join(newfolder, filename)) else: with open(os.path.join(newfolder, filename), "a") as stream: stream.write("Row %s\n" % index) repo.index.add(filename) repo.index.write() parents = [] commit = None try: if branch_ref_obj: commit = repo[branch_ref_obj.peel().hex] else: commit = repo.revparse_single("HEAD") except (KeyError, AttributeError): pass if commit: parents = [commit.oid.hex] # Commits the files added tree = repo.index.write_tree() author = pygit2.Signature("Alice Author", "*****@*****.**") committer = pygit2.Signature("Cecil Committer", "*****@*****.**") branch_ref = "refs/heads/%s" % branch repo.create_commit( branch_ref, author, committer, "Add row %s to %s file" % (index, filename), # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit parents, ) branch_ref_obj = pagure.lib.git.get_branch_ref(repo, branch) # Push to origin ori_remote = repo.remotes[0] PagureRepo.push(ori_remote, "%s:%s" % (branch_ref, branch_ref)) shutil.rmtree(newfolder)
def test_api_git_tags(self): """ Test the api_git_tags method of the flask api. """ tests.create_projects(self.session) # Create a git repo to play with gitrepo = os.path.join(tests.HERE, 'repos', 'test.git') repo = pygit2.init_repository(gitrepo, bare=True) newpath = tempfile.mkdtemp(prefix='pagure-fork-test') repopath = os.path.join(newpath, 'test') clone_repo = pygit2.clone_repository(gitrepo, repopath) # Create a file in that git repo with open(os.path.join(repopath, 'sources'), 'w') as stream: stream.write('foo\n bar') clone_repo.index.add('sources') clone_repo.index.write() # Commits the files added tree = clone_repo.index.write_tree() author = pygit2.Signature( 'Alice Author', '*****@*****.**') committer = pygit2.Signature( 'Cecil Committer', '*****@*****.**') clone_repo.create_commit( 'refs/heads/master', # the name of the reference to update author, committer, 'Add sources file for testing', # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit [] ) refname = 'refs/heads/master:refs/heads/master' ori_remote = clone_repo.remotes[0] PagureRepo.push(ori_remote, refname) # Tag our first commit first_commit = repo.revparse_single('HEAD') tagger = pygit2.Signature('Alice Doe', '*****@*****.**', 12347, 0) repo.create_tag( "0.0.1", first_commit.oid.hex, pygit2.GIT_OBJ_COMMIT, tagger, "Release 0.0.1") # Check tags output = self.app.get('/api/0/test/git/tags') self.assertEqual(output.status_code, 200) data = json.loads(output.data) self.assertDictEqual( data, {'tags': ['0.0.1'], 'total_tags': 1} )
def add_commit_git_repo( folder, ncommits=10, filename="sources", branch="master", symlink_to=None ): """ Create some more commits for the specified git repo. """ repo, newfolder, branch_ref_obj = _clone_and_top_commits( folder, branch, branch_ref=True ) for index in range(ncommits): # Create a file in that git repo if symlink_to: os.symlink(symlink_to, os.path.join(newfolder, filename)) else: with open(os.path.join(newfolder, filename), "a") as stream: stream.write("Row %s\n" % index) repo.index.add(filename) repo.index.write() parents = [] commit = None try: if branch_ref_obj: commit = repo[branch_ref_obj.peel().hex] else: commit = repo.revparse_single("HEAD") except (KeyError, AttributeError): pass if commit: parents = [commit.oid.hex] # Commits the files added tree = repo.index.write_tree() author = pygit2.Signature("Alice Author", "*****@*****.**") committer = pygit2.Signature("Cecil Committer", "*****@*****.**") branch_ref = "refs/heads/%s" % branch repo.create_commit( branch_ref, author, committer, "Add row %s to %s file" % (index, filename), # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit parents, ) branch_ref_obj = pagure.lib.git.get_branch_ref(repo, branch) # Push to origin ori_remote = repo.remotes[0] PagureRepo.push(ori_remote, "%s:%s" % (branch_ref, branch_ref)) shutil.rmtree(newfolder)
def add_content_to_git(folder, branch='master', filename='sources', content='foo', message=None): """ Create some more commits for the specified git repo. """ repo, newfolder, branch_ref_obj = _clone_and_top_commits(folder, branch, branch_ref=True) # Create a file in that git repo with open(os.path.join(newfolder, filename), 'a', encoding="utf-8") as stream: stream.write('%s\n' % content) repo.index.add(filename) repo.index.write() parents = [] commit = None try: if branch_ref_obj: commit = repo[branch_ref_obj.get_object().hex] else: commit = repo.revparse_single('HEAD') except (KeyError, AttributeError): pass if commit: parents = [commit.oid.hex] # Commits the files added tree = repo.index.write_tree() author = pygit2.Signature('Alice Author', '*****@*****.**') committer = pygit2.Signature('Cecil Committer', '*****@*****.**') branch_ref = "refs/heads/%s" % branch message = message or 'Add content to file %s' % (filename) repo.create_commit( branch_ref, # the name of the reference to update author, committer, message, # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit parents, ) # Push to origin ori_remote = repo.remotes[0] PagureRepo.push(ori_remote, '%s:%s' % (branch_ref, branch_ref)) shutil.rmtree(newfolder)
def add_content_to_git( folder, branch="master", filename="sources", content="foo", message=None ): """ Create some more commits for the specified git repo. """ repo, newfolder, branch_ref_obj = _clone_and_top_commits( folder, branch, branch_ref=True ) # Create a file in that git repo with open( os.path.join(newfolder, filename), "a", encoding="utf-8" ) as stream: stream.write("%s\n" % content) repo.index.add(filename) repo.index.write() parents = [] commit = None try: if branch_ref_obj: commit = repo[branch_ref_obj.peel().hex] else: commit = repo.revparse_single("HEAD") except (KeyError, AttributeError): pass if commit: parents = [commit.oid.hex] # Commits the files added tree = repo.index.write_tree() author = pygit2.Signature("Alice Author", "*****@*****.**") committer = pygit2.Signature("Cecil Committer", "*****@*****.**") branch_ref = "refs/heads/%s" % branch message = message or "Add content to file %s" % (filename) repo.create_commit( branch_ref, # the name of the reference to update author, committer, message, # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit parents, ) # Push to origin ori_remote = repo.remotes[0] PagureRepo.push(ori_remote, "%s:%s" % (branch_ref, branch_ref)) shutil.rmtree(newfolder)
def add_commit_git_repo(folder, ncommits=10): """ Create some more commits for the specified git repo. """ if not os.path.exists(folder): os.makedirs(folder) brepo = pygit2.init_repository(folder, bare=True) newfolder = tempfile.mkdtemp(prefix='pagure-tests') repo = pygit2.clone_repository(folder, newfolder) for index in range(ncommits): # Create a file in that git repo with open(os.path.join(newfolder, 'sources'), 'a') as stream: stream.write('Row %s\n' % index) repo.index.add('sources') repo.index.write() parents = [] commit = None try: commit = repo.revparse_single('HEAD') except KeyError: pass if commit: parents = [commit.oid.hex] # Commits the files added tree = repo.index.write_tree() author = pygit2.Signature( 'Alice Author', '*****@*****.**') committer = pygit2.Signature( 'Cecil Committer', '*****@*****.**') repo.create_commit( 'refs/heads/master', # the name of the reference to update author, committer, 'Add row %s to sources file' % index, # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit parents, ) # Push to origin ori_remote = repo.remotes[0] master_ref = repo.lookup_reference('HEAD').resolve() refname = '%s:%s' % (master_ref.name, master_ref.name) PagureRepo.push(ori_remote, refname) shutil.rmtree(newfolder)
def add_commit_git_repo(folder, ncommits=10, filename='sources'): """ Create some more commits for the specified git repo. """ if not os.path.exists(folder): os.makedirs(folder) brepo = pygit2.init_repository(folder, bare=True) newfolder = tempfile.mkdtemp(prefix='pagure-tests') repo = pygit2.clone_repository(folder, newfolder) for index in range(ncommits): # Create a file in that git repo with open(os.path.join(newfolder, filename), 'a') as stream: stream.write('Row %s\n' % index) repo.index.add(filename) repo.index.write() parents = [] commit = None try: commit = repo.revparse_single('HEAD') except KeyError: pass if commit: parents = [commit.oid.hex] # Commits the files added tree = repo.index.write_tree() author = pygit2.Signature( 'Alice Author', '*****@*****.**') committer = pygit2.Signature( 'Cecil Committer', '*****@*****.**') repo.create_commit( 'refs/heads/master', # the name of the reference to update author, committer, 'Add row %s to %s file' % (index, filename), # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit parents, ) # Push to origin ori_remote = repo.remotes[0] master_ref = repo.lookup_reference('HEAD').resolve() refname = '%s:%s' % (master_ref.name, master_ref.name) PagureRepo.push(ori_remote, refname) shutil.rmtree(newfolder)
def _set_up_doc(self): # forked doc repo docrepo = os.path.join(self.path, "repos", "docs", "test", "test.git") repo = pygit2.init_repository(docrepo) # Create files in that git repo with open(os.path.join(docrepo, "sources"), "w") as stream: stream.write("foo\n bar") repo.index.add("sources") repo.index.write() folderpart = os.path.join(docrepo, "folder1", "folder2") os.makedirs(folderpart) with open(os.path.join(folderpart, "test_file"), "w") as stream: stream.write("row1\nrow2\nrow3") repo.index.add(os.path.join("folder1", "folder2", "test_file")) repo.index.write() # Commits the files added tree = repo.index.write_tree() author = pygit2.Signature("Alice Author", "*****@*****.**") committer = pygit2.Signature("Cecil Committer", "*****@*****.**") repo.create_commit( "refs/heads/master", # the name of the reference to update author, committer, "Add test files and folder", # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit [], ) # Push the changes to the bare repo remote = repo.create_remote( "origin", os.path.join(self.path, "repos", "docs", "test.git") ) PagureRepo.push(remote, "refs/heads/master:refs/heads/master") # Turn on the docs project since it's off by default repo = pagure.lib.query.get_authorized_project(self.session, "test") repo.settings = {"project_documentation": True} self.session.add(repo) self.session.commit()
def _set_up_doc(self): # forked doc repo docrepo = os.path.join(self.path, "repos", "docs", "test", "test.git") repo = pygit2.init_repository(docrepo) # Create files in that git repo with open(os.path.join(docrepo, "sources"), "w") as stream: stream.write("foo\n bar") repo.index.add("sources") repo.index.write() folderpart = os.path.join(docrepo, "folder1", "folder2") os.makedirs(folderpart) with open(os.path.join(folderpart, "test_file"), "w") as stream: stream.write("row1\nrow2\nrow3") repo.index.add(os.path.join("folder1", "folder2", "test_file")) repo.index.write() # Commits the files added tree = repo.index.write_tree() author = pygit2.Signature("Alice Author", "*****@*****.**") committer = pygit2.Signature("Cecil Committer", "*****@*****.**") repo.create_commit( "refs/heads/master", # the name of the reference to update author, committer, "Add test files and folder", # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit [], ) # Push the changes to the bare repo remote = repo.create_remote( "origin", os.path.join(self.path, "repos", "docs", "test.git")) PagureRepo.push(remote, "refs/heads/master:refs/heads/master") # Turn on the docs project since it's off by default repo = pagure.lib.query.get_authorized_project(self.session, "test") repo.settings = {"project_documentation": True} self.session.add(repo) self.session.commit()
def _set_up_doc(self): # forked doc repo docrepo = os.path.join(self.path, 'repos', 'docs', 'test', 'test.git') repo = pygit2.init_repository(docrepo) # Create files in that git repo with open(os.path.join(docrepo, 'sources'), 'w') as stream: stream.write('foo\n bar') repo.index.add('sources') repo.index.write() folderpart = os.path.join(docrepo, 'folder1', 'folder2') os.makedirs(folderpart) with open(os.path.join(folderpart, 'test_file'), 'w') as stream: stream.write('row1\nrow2\nrow3') repo.index.add(os.path.join('folder1', 'folder2', 'test_file')) repo.index.write() # Commits the files added tree = repo.index.write_tree() author = pygit2.Signature('Alice Author', '*****@*****.**') committer = pygit2.Signature('Cecil Committer', '*****@*****.**') repo.create_commit( 'refs/heads/master', # the name of the reference to update author, committer, 'Add test files and folder', # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit []) # Push the changes to the bare repo remote = repo.create_remote( 'origin', os.path.join(self.path, 'repos', 'docs', 'test.git')) PagureRepo.push(remote, 'refs/heads/master:refs/heads/master') # Turn on the docs project since it's off by default repo = pagure.lib.query.get_authorized_project(self.session, 'test') repo.settings = {'project_documentation': True} self.session.add(repo) self.session.commit()
def add_binary_git_repo(folder, filename): """ Create a fake image file for the specified git repo. """ repo, newfolder, parents = _clone_and_top_commits(folder, 'master') content = b"""\x00\x00\x01\x00\x01\x00\x18\x18\x00\x00\x01\x00 \x00\x88 \t\x00\x00\x16\x00\x00\x00(\x00\x00\x00\x18\x00x00\x00\x01\x00 \x00\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7lM\x01\xa6kM\t\xa6kM\x01 \xa4fF\x04\xa2dE\x95\xa2cD8\xa1a """ # Create a file in that git repo with open(os.path.join(newfolder, filename), 'wb') as stream: stream.write(content) repo.index.add(filename) repo.index.write() # Commits the files added tree = repo.index.write_tree() author = pygit2.Signature( 'Alice Author', '*****@*****.**') committer = pygit2.Signature( 'Cecil Committer', '*****@*****.**') repo.create_commit( 'refs/heads/master', # the name of the reference to update author, committer, 'Add a fake image file', # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit parents ) # Push to origin ori_remote = repo.remotes[0] master_ref = repo.lookup_reference('HEAD').resolve() refname = '%s:%s' % (master_ref.name, master_ref.name) PagureRepo.push(ori_remote, refname) shutil.rmtree(newfolder)
def add_tag_git_repo(folder, tagname, obj_hash, message): """ Add a tag to the given object of the given repo annotated by given message. """ repo, newfolder, branch_ref_obj = _clone_and_top_commits(folder, "master", branch_ref=True) tag_sha = repo.create_tag( tagname, obj_hash, repo.get(obj_hash).type, pygit2.Signature("Alice Author", "*****@*****.**"), message, ) # Push to origin ori_remote = repo.remotes[0] PagureRepo.push(ori_remote, "refs/tags/%s:refs/tags/%s" % (tagname, tagname)) shutil.rmtree(newfolder) return tag_sha
def add_binary_git_repo(folder, filename): """ Create a fake image file for the specified git repo. """ repo, newfolder, parents = _clone_and_top_commits(folder, "master") content = b"""\x00\x00\x01\x00\x01\x00\x18\x18\x00\x00\x01\x00 \x00\x88 \t\x00\x00\x16\x00\x00\x00(\x00\x00\x00\x18\x00x00\x00\x01\x00 \x00\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7lM\x01\xa6kM\t\xa6kM\x01 \xa4fF\x04\xa2dE\x95\xa2cD8\xa1a """ # Create a file in that git repo with open(os.path.join(newfolder, filename), "wb") as stream: stream.write(content) repo.index.add(filename) repo.index.write() # Commits the files added tree = repo.index.write_tree() author = pygit2.Signature("Alice Author", "*****@*****.**") committer = pygit2.Signature("Cecil Committer", "*****@*****.**") repo.create_commit( "refs/heads/master", # the name of the reference to update author, committer, "Add a fake image file", # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit parents, ) # Push to origin ori_remote = repo.remotes[0] master_ref = repo.lookup_reference("HEAD").resolve() refname = "%s:%s" % (master_ref.name, master_ref.name) PagureRepo.push(ori_remote, refname) shutil.rmtree(newfolder)
def add_tag_git_repo(folder, tagname, obj_hash, message): """ Add a tag to the given object of the given repo annotated by given message. """ repo, newfolder, branch_ref_obj = _clone_and_top_commits( folder, "master", branch_ref=True ) tag_sha = repo.create_tag( tagname, obj_hash, repo.get(obj_hash).type, pygit2.Signature("Alice Author", "*****@*****.**"), message, ) # Push to origin ori_remote = repo.remotes[0] PagureRepo.push( ori_remote, "refs/tags/%s:refs/tags/%s" % (tagname, tagname) ) shutil.rmtree(newfolder) return tag_sha
def set_up_git_repo(self, name='test'): """ Set up the git repo to play with. """ # Create a git repo to play with gitrepo = os.path.join(self.path, 'repos', '%s.git' % name) repo = pygit2.init_repository(gitrepo, bare=True) newpath = tempfile.mkdtemp(prefix='pagure-other-test') repopath = os.path.join(newpath, 'test') clone_repo = pygit2.clone_repository(gitrepo, repopath) # Create a file in that git repo with open(os.path.join(repopath, 'sources'), 'w') as stream: stream.write('foo\n bar') clone_repo.index.add('sources') clone_repo.index.write() # Commits the files added tree = clone_repo.index.write_tree() author = pygit2.Signature( 'Alice Author', '*****@*****.**') committer = pygit2.Signature( 'Cecil Committer', '*****@*****.**') clone_repo.create_commit( 'refs/heads/master', # the name of the reference to update author, committer, 'Add sources file for testing', # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit [] ) refname = 'refs/heads/master' ori_remote = clone_repo.remotes[0] PagureRepo.push(ori_remote, refname)
def test_view_docs(self): """ Test the view_docs endpoint. """ tests.create_projects(self.session) repo = pygit2.init_repository( os.path.join(tests.HERE, 'docs', 'test.git'), bare=True) output = self.app.get('/test/docs') self.assertEqual(output.status_code, 404) # forked doc repo docrepo = os.path.join(tests.HERE, 'docs', 'test', 'test.git') repo = pygit2.init_repository(docrepo) # Create files in that git repo with open(os.path.join(docrepo, 'sources'), 'w') as stream: stream.write('foo\n bar') repo.index.add('sources') repo.index.write() folderpart = os.path.join(docrepo, 'folder1', 'folder2') os.makedirs(folderpart) with open(os.path.join(folderpart, 'test_file'), 'w') as stream: stream.write('row1\nrow2\nrow3') repo.index.add(os.path.join('folder1', 'folder2', 'test_file')) repo.index.write() # Commits the files added tree = repo.index.write_tree() author = pygit2.Signature( 'Alice Author', '*****@*****.**') committer = pygit2.Signature( 'Cecil Committer', '*****@*****.**') repo.create_commit( 'refs/heads/master', # the name of the reference to update author, committer, 'Add test files and folder', # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit [] ) # Push the changes to the bare repo remote = repo.create_remote( 'origin', os.path.join(tests.HERE, 'docs', 'test.git')) PagureRepo.push(remote, 'refs/heads/master:refs/heads/master') # Now check the UI output = self.app.get('/test/docs') self.assertEqual(output.status_code, 404) output = self.app.get('/test/sources') self.assertEqual(output.status_code, 200) self.assertEqual('<pre>foo\n bar</pre>', output.data) output = self.app.get('/test/folder1/folder2') self.assertEqual(output.status_code, 200) self.assertTrue( '<li><ul><a href="test_file">test_file</a></ul></li>' in output.data) output = self.app.get('/test/folder1/folder2/test_file') self.assertEqual(output.status_code, 200) self.assertEqual('<pre>row1\nrow2\nrow3</pre>', output.data) output = self.app.get('/test/folder1') self.assertEqual(output.status_code, 200) self.assertTrue( '<li><ul><a href="folder2">folder2/</a></ul></li>' in output.data) output = self.app.get('/test/folder1/foo') self.assertEqual(output.status_code, 404) output = self.app.get('/test/folder1/foo/folder2') self.assertEqual(output.status_code, 404)
def add_file_to_git(repo, issue, ticketfolder, user, filename, filestream): ''' Add a given file to the specified ticket git repository. :arg repo: the Project object from the database :arg ticketfolder: the folder on the filesystem where the git repo for tickets are stored :arg user: the user object with its username and email :arg filename: the name of the file to save :arg filestream: the actual content of the file ''' if not ticketfolder: return # Prefix the filename with a timestamp: filename = '%s-%s' % ( hashlib.sha256(filestream.read()).hexdigest(), werkzeug.secure_filename(filename) ) # Get the fork repopath = os.path.join(ticketfolder, repo.path) # Clone the repo into a temp folder newpath = tempfile.mkdtemp(prefix='pagure-') new_repo = pygit2.clone_repository(repopath, newpath) folder_path = os.path.join(newpath, 'files') file_path = os.path.join(folder_path, filename) # Get the current index index = new_repo.index # Are we adding files added = False if not os.path.exists(file_path): added = True else: # File exists, remove the clone and return shutil.rmtree(newpath) return os.path.join('files', filename) if not os.path.exists(folder_path): os.mkdir(folder_path) # Write down what changed filestream.seek(0) with open(file_path, 'w') as stream: stream.write(filestream.read()) # Retrieve the list of files that changed diff = new_repo.diff() files = [patch.new_file_path for patch in diff] # Add the changes to the index if added: index.add(os.path.join('files', filename)) for filename in files: index.add(filename) # If not change, return if not files and not added: shutil.rmtree(newpath) return # See if there is a parent to this commit parent = None try: parent = new_repo.head.get_object().oid except pygit2.GitError: pass parents = [] if parent: parents.append(parent) # Author/commiter will always be this one author = pygit2.Signature( name=user.username.encode('utf-8'), email=user.email.encode('utf-8') ) # Actually commit new_repo.create_commit( 'refs/heads/master', author, author, 'Add file %s to ticket %s: %s' % (filename, issue.uid, issue.title), new_repo.index.write_tree(), parents) index.write() # Push to origin ori_remote = new_repo.remotes[0] master_ref = new_repo.lookup_reference('HEAD').resolve() refname = '%s:%s' % (master_ref.name, master_ref.name) PagureRepo.push(ori_remote, refname) # Remove the clone shutil.rmtree(newpath) return os.path.join('files', filename)
def set_up_git_repo(self, repo, fork, branch_from="feature"): """ Set up the git repo and create the corresponding PullRequest object. """ # Clone the main repo gitrepo = os.path.join(self.path, "repos", repo.path) newpath = tempfile.mkdtemp(prefix="pagure-fork-test") repopath = os.path.join(newpath, "test") clone_repo = pygit2.clone_repository(gitrepo, repopath) # Create a file in that git repo with open(os.path.join(repopath, "sources"), "w") as stream: stream.write("foo\n bar") clone_repo.index.add("sources") clone_repo.index.write() # Commits the files added tree = clone_repo.index.write_tree() author = pygit2.Signature("Alice Author", "*****@*****.**") committer = pygit2.Signature("Cecil Committer", "*****@*****.**") clone_repo.create_commit( "refs/heads/master", # the name of the reference to update author, committer, "Add sources file for testing", # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit [], ) refname = "refs/heads/master:refs/heads/master" ori_remote = clone_repo.remotes[0] PagureRepo.push(ori_remote, refname) first_commit = clone_repo.revparse_single("HEAD") # Set the second repo repopath = os.path.join(self.path, "repos", fork.path) new_gitrepo = os.path.join(newpath, "fork_test") clone_repo = pygit2.clone_repository(repopath, new_gitrepo) # Add the main project as remote repo upstream_path = os.path.join(self.path, "repos", repo.path) remote = clone_repo.create_remote("upstream", upstream_path) remote.fetch() # Edit the sources file again with open(os.path.join(new_gitrepo, "sources"), "w") as stream: stream.write("foo\n bar\nbaz\n boose") clone_repo.index.add("sources") clone_repo.index.write() # Commits the files added tree = clone_repo.index.write_tree() author = pygit2.Signature("Alice Author", "*****@*****.**") committer = pygit2.Signature("Cecil Committer", "*****@*****.**") clone_repo.create_commit( "refs/heads/%s" % branch_from, author, committer, "A commit on branch %s" % branch_from, tree, [first_commit.oid.hex], ) refname = "refs/heads/%s" % (branch_from) ori_remote = clone_repo.remotes[0] PagureRepo.push(ori_remote, refname) # Create a PR for these changes project = pagure.lib.query.get_authorized_project(self.session, "test") req = pagure.lib.query.new_pull_request( session=self.session, repo_from=fork, branch_from=branch_from, repo_to=project, branch_to="master", title="PR from the %s branch" % branch_from, user="******", ) self.session.commit() self.assertEqual(req.id, 1) self.assertEqual(req.title, "PR from the %s branch" % branch_from) shutil.rmtree(newpath)
def test_get_revs_between(self): """ Test the get_revs_between method of pagure.lib.git. """ self.test_update_git() gitrepo = os.path.join(tests.HERE, 'test_ticket_repo.git') output = pagure.lib.git.read_git_lines( ['log', '-3', "--pretty='%H'"], gitrepo) self.assertEqual(len(output), 2) from_hash = output[1].replace("'", '') # Case 1, repo BASE is null and HEAD is equal to from_hash to_hash = '0' output1 = pagure.lib.git.get_revs_between( to_hash, from_hash, gitrepo, 'refs/heads/master') self.assertEqual(output1, [from_hash]) # Case 2, get revs between two commits (to_hash, from_hash) to_hash = output[0].replace("'", '') output2 = pagure.lib.git.get_revs_between( to_hash, from_hash, gitrepo, 'refs/heads/master') self.assertEqual(output2, [to_hash]) # Case 3, get revs between two commits (from_hash, to_hash) output3 = pagure.lib.git.get_revs_between( from_hash, to_hash, gitrepo, 'refs/heads/master') self.assertEqual(output3, [to_hash]) # Case 4, get revs between two commits on two different branches newgitrepo = tempfile.mkdtemp(prefix='pagure-') newrepo = pygit2.clone_repository(gitrepo, newgitrepo) newrepo.create_branch('feature', newrepo.head.get_object()) with open(os.path.join(newgitrepo, 'sources'), 'w') as stream: stream.write('foo\n bar') newrepo.index.add('sources') newrepo.index.write() # Commits the files added tree = newrepo.index.write_tree() author = pygit2.Signature( 'Alice Author', '*****@*****.**') committer = pygit2.Signature( 'Cecil Committer', '*****@*****.**') newrepo.create_commit( 'refs/heads/feature', # the name of the reference to update author, committer, 'Add sources file for testing', # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit [to_hash] ) branch_commit = newrepo.revparse_single('refs/heads/feature') # Push to origin ori_remote = newrepo.remotes[0] PagureRepo.push(ori_remote, 'refs/heads/feature') # Remove the clone shutil.rmtree(newgitrepo) output4 = pagure.lib.git.get_revs_between( '0', branch_commit.oid.hex, gitrepo, 'refs/heads/feature') self.assertEqual(output4, [branch_commit.oid.hex])
def add_content_git_repo(folder, branch="master", append=None): """ Create some content for the specified git repo. """ repo, newfolder, parents = _clone_and_top_commits(folder, branch) # Create a file in that git repo filename = os.path.join(newfolder, "sources") content = "foo\n bar" if os.path.exists(filename): content = "foo\n bar\nbaz" if append: content += append with open(filename, "w") as stream: stream.write(content) repo.index.add("sources") repo.index.write() # Commits the files added tree = repo.index.write_tree() author = pygit2.Signature("Alice Author", "*****@*****.**") committer = pygit2.Signature("Cecil Committer", "*****@*****.**") commit = repo.create_commit( "refs/heads/%s" % branch, # the name of the reference to update author, committer, "Add sources file for testing", # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit parents, ) if commit: parents = [commit.hex] subfolder = os.path.join("folder1", "folder2") if not os.path.exists(os.path.join(newfolder, subfolder)): os.makedirs(os.path.join(newfolder, subfolder)) # Create a file in that git repo with open(os.path.join(newfolder, subfolder, "file"), "w") as stream: stream.write("foo\n bar\nbaz") repo.index.add(os.path.join(subfolder, "file")) with open(os.path.join(newfolder, subfolder, "fileŠ"), "w") as stream: stream.write("foo\n bar\nbaz") repo.index.add(os.path.join(subfolder, "fileŠ")) repo.index.write() # Commits the files added tree = repo.index.write_tree() author = pygit2.Signature("Alice Author", "*****@*****.**") committer = pygit2.Signature("Cecil Committer", "*****@*****.**") commit = repo.create_commit( "refs/heads/%s" % branch, # the name of the reference to update author, committer, "Add some directory and a file for more testing", # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit parents, ) # Push to origin ori_remote = repo.remotes[0] master_ref = repo.lookup_reference( "HEAD" if branch == "master" else "refs/heads/%s" % branch ).resolve() refname = "%s:%s" % (master_ref.name, master_ref.name) PagureRepo.push(ori_remote, refname) shutil.rmtree(newfolder)
def add_readme_git_repo(folder): """ Create a README file for the specified git repo. """ if not os.path.exists(folder): os.makedirs(folder) brepo = pygit2.init_repository(folder, bare=True) newfolder = tempfile.mkdtemp(prefix='pagure-tests') repo = pygit2.clone_repository(folder, newfolder) content = """Pagure ====== :Author: Pierre-Yves Chibon <*****@*****.**> Pagure is a light-weight git-centered forge based on pygit2. Currently, Pagure offers a web-interface for git repositories, a ticket system and possibilities to create new projects, fork existing ones and create/merge pull-requests across or within projects. Homepage: https://github.com/pypingou/pagure Dev instance: http://209.132.184.222/ (/!\\ May change unexpectedly, it's a dev instance ;-)) """ parents = [] commit = None try: commit = repo.revparse_single('HEAD') except KeyError: pass if commit: parents = [commit.oid.hex] # Create a file in that git repo with open(os.path.join(newfolder, 'README.rst'), 'w') as stream: stream.write(content) repo.index.add('README.rst') repo.index.write() # Commits the files added tree = repo.index.write_tree() author = pygit2.Signature( 'Alice Author', '*****@*****.**') committer = pygit2.Signature( 'Cecil Committer', '*****@*****.**') repo.create_commit( 'refs/heads/master', # the name of the reference to update author, committer, 'Add a README file', # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit parents ) # Push to origin ori_remote = repo.remotes[0] master_ref = repo.lookup_reference('HEAD').resolve() refname = '%s:%s' % (master_ref.name, master_ref.name) PagureRepo.push(ori_remote, refname) shutil.rmtree(newfolder)
def update_git(obj, repo, repofolder, objtype='ticket'): """ Update the given issue in its git. This method forks the provided repo, add/edit the issue whose file name is defined by the uid field of the issue and if there are additions/ changes commit them and push them back to the original repo. """ if not repofolder: return # Get the fork repopath = os.path.join(repofolder, repo.path) # Clone the repo into a temp folder newpath = tempfile.mkdtemp(prefix='pagure-') new_repo = pygit2.clone_repository(repopath, newpath) file_path = os.path.join(newpath, obj.uid) # Get the current index index = new_repo.index # Are we adding files added = False if not os.path.exists(file_path): added = True # Write down what changed with open(file_path, 'w') as stream: stream.write( json.dumps(obj.to_json(), sort_keys=True, indent=4, separators=(',', ': '))) # Retrieve the list of files that changed diff = new_repo.diff() files = [patch.new_file_path for patch in diff] # Add the changes to the index if added: index.add(obj.uid) for filename in files: index.add(filename) # If not change, return if not files and not added: shutil.rmtree(newpath) return # See if there is a parent to this commit parent = None try: parent = new_repo.head.get_object().oid except pygit2.GitError: pass parents = [] if parent: parents.append(parent) # Author/commiter will always be this one author = pygit2.Signature(name='pagure', email='pagure') # Actually commit new_repo.create_commit('refs/heads/master', author, author, 'Updated %s %s: %s' % (objtype, obj.uid, obj.title), new_repo.index.write_tree(), parents) index.write() # Push to origin ori_remote = new_repo.remotes[0] master_ref = new_repo.lookup_reference('HEAD').resolve() refname = '%s:%s' % (master_ref.name, master_ref.name) PagureRepo.push(ori_remote, refname) # Remove the clone shutil.rmtree(newpath)
def set_up_git_repo(self, new_project=None, branch_from="feature"): """ Set up the git repo and create the corresponding PullRequest object. """ # Create a git repo to play with gitrepo = os.path.join(self.path, "repos", "test.git") repo = pygit2.init_repository(gitrepo, bare=True) repopath = os.path.join(self.newpath, "test") clone_repo = pygit2.clone_repository(gitrepo, repopath) # Create a file in that git repo with open(os.path.join(repopath, "sources"), "w") as stream: stream.write("foo\n bar") clone_repo.index.add("sources") clone_repo.index.write() try: com = repo.revparse_single("HEAD") prev_commit = [com.oid.hex] except: prev_commit = [] # Commits the files added tree = clone_repo.index.write_tree() author = _make_signature("Alice Author", "*****@*****.**") committer = _make_signature("Cecil Committer", "*****@*****.**") clone_repo.create_commit( "refs/heads/master", # the name of the reference to update author, committer, "Add sources file for testing", # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit prev_commit, ) # time.sleep(1) refname = "refs/heads/master:refs/heads/master" ori_remote = clone_repo.remotes[0] PagureRepo.push(ori_remote, refname) first_commit = repo.revparse_single("HEAD") with open(os.path.join(repopath, ".gitignore"), "w") as stream: stream.write("*~") clone_repo.index.add(".gitignore") clone_repo.index.write() # Commits the files added tree = clone_repo.index.write_tree() author = _make_signature("Alice Äuthòr", "alice@äuthòrs.tld") committer = _make_signature("Cecil Cõmmîttër", "cecil@cõmmîttërs.tld") clone_repo.create_commit( "refs/heads/master", author, committer, "Add .gitignore file for testing", # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit [first_commit.oid.hex], ) refname = "refs/heads/master:refs/heads/master" ori_remote = clone_repo.remotes[0] PagureRepo.push(ori_remote, refname) # Set the second repo new_gitrepo = repopath if new_project: # Create a new git repo to play with new_gitrepo = os.path.join(self.newpath, new_project.fullname) if not os.path.exists(new_gitrepo): os.makedirs(new_gitrepo) new_repo = pygit2.clone_repository(gitrepo, new_gitrepo) repo = pygit2.Repository(new_gitrepo) # Edit the sources file again with open(os.path.join(new_gitrepo, "sources"), "w") as stream: stream.write("foo\n bar\nbaz\n boose") repo.index.add("sources") repo.index.write() # Commits the files added tree = repo.index.write_tree() author = _make_signature("Alice Author", "*****@*****.**") committer = _make_signature("Cecil Committer", "*****@*****.**") repo.create_commit( "refs/heads/%s" % branch_from, author, committer, "A commit on branch %s" % branch_from, tree, [first_commit.oid.hex], ) refname = "refs/heads/%s" % (branch_from) ori_remote = repo.remotes[0] PagureRepo.push(ori_remote, refname)
def setUp(self): """ Set up the environnment, ran before every tests. """ super(PagureFlaskPrIssueLinkTest, self).setUp() tests.create_projects(self.session) tests.create_projects(self.session, is_fork=True, user_id=2, hook_token_suffix='bar') tests.create_projects_git(os.path.join(self.path, 'repos'), bare=True) tests.create_projects_git(os.path.join(self.path, 'repos', 'forks', 'foo'), bare=True) repo = pagure.lib.query.get_authorized_project(self.session, 'test') # Create issues to play with msg = pagure.lib.query.new_issue( session=self.session, repo=repo, title='tést íssüé', content='We should work on this', user='******', ) self.session.commit() self.assertEqual(msg.title, 'tést íssüé') msg = pagure.lib.query.new_issue( session=self.session, repo=repo, title='tést íssüé #2', content='We should still work on this', user='******', ) self.session.commit() self.assertEqual(msg.title, 'tést íssüé #2') # Add a commit to the fork newpath = tempfile.mkdtemp(prefix='pagure-fork-test') repopath = os.path.join(newpath, 'test') clone_repo = pygit2.clone_repository( os.path.join(self.path, 'repos', 'forks', 'foo', 'test.git'), repopath) # Create a file in that git repo with open(os.path.join(repopath, 'sources'), 'w') as stream: stream.write('foo\n bar') clone_repo.index.add('sources') clone_repo.index.write() try: com = repo.revparse_single('HEAD') prev_commit = [com.oid.hex] except: prev_commit = [] # Commits the files added tree = clone_repo.index.write_tree() author = pygit2.Signature('Alice Author', '*****@*****.**') committer = pygit2.Signature('Cecil Committer', '*****@*****.**') clone_repo.create_commit( 'refs/heads/master', # the name of the reference to update author, committer, 'Add sources file for testing\n\n Relates to #2', # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit prev_commit) refname = 'refs/heads/master:refs/heads/master' ori_remote = clone_repo.remotes[0] PagureRepo.push(ori_remote, refname) # Create the corresponding PR repo = pagure.lib.query.get_authorized_project(self.session, 'test') fork_repo = pagure.lib.query.get_authorized_project(self.session, 'test', user='******') request = pagure.lib.query.new_pull_request( self.session, branch_from='master', repo_to=repo, branch_to='master', title='test PR', user='******', initial_comment=None, repo_from=fork_repo, ) self.session.commit() pagure.lib.tasks.link_pr_to_ticket(request.uid) self.assertEqual(request.id, 3)
def test_diff_pull_request_updated(self): """ Test that calling pagure.lib.git.diff_pull_request on an updated PR updates the PR reference """ gitrepo = os.path.join(self.path, "repos", "test.git") gitrepo2 = os.path.join( self.path, "repos", "forks", "pingou", "test.git" ) request = pagure.lib.query.search_pull_requests( self.session, requestid=1, project_id=1 ) # Get the diff corresponding to the PR and check its ref diff_commits, diff = pagure.lib.git.diff_pull_request( self.session, request=request, repo_obj=PagureRepo(gitrepo2), orig_repo=PagureRepo(gitrepo), with_diff=True, ) self.assertEqual(len(diff_commits), 2) # Check that the PR has its PR refs # we don't know the task id but we'll give it 30 sec to finish cnt = 0 repo = PagureRepo(gitrepo) self.assertIn("refs/pull/1/head", list(repo.listall_references())) self.assertTrue(cnt < 60) pr_ref = repo.lookup_reference("refs/pull/1/head") commit = pr_ref.peel() self.assertEqual(commit.oid.hex, diff_commits[0].oid.hex) # Add a new commit on the fork repopath = os.path.join(self.path, "pingou_test2") clone_repo = pygit2.clone_repository( gitrepo2, repopath, checkout_branch="feature_foo" ) with open(os.path.join(repopath, "sources"), "w") as stream: stream.write("foo\n bar\nbaz\nhey there\n") clone_repo.index.add("sources") clone_repo.index.write() last_commit = clone_repo.lookup_branch("feature_foo").peel() # Commits the files added tree = clone_repo.index.write_tree() author = pygit2.Signature("Alice Author", "*****@*****.**") committer = pygit2.Signature("Cecil Committer", "*****@*****.**") last_commit = clone_repo.create_commit( "refs/heads/feature_foo", # the name of the reference to update author, committer, "Third edit on side branch of the file sources for testing", # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit [last_commit.oid.hex], ) # Push to the fork repo ori_remote = clone_repo.remotes[0] refname = "refs/heads/feature_foo:refs/heads/feature_foo" PagureRepo.push(ori_remote, refname) # Get the new diff for that PR and check its new ref diff_commits, diff = pagure.lib.git.diff_pull_request( self.session, request=request, repo_obj=PagureRepo(gitrepo2), orig_repo=PagureRepo(gitrepo), with_diff=True, ) self.assertEqual(len(diff_commits), 3) # Check that the PR has its PR refs # we don't know the task id but we'll give it 30 sec to finish cnt = 0 repo = PagureRepo(gitrepo) self.assertIn("refs/pull/1/head", list(repo.listall_references())) self.assertTrue(cnt < 60) pr_ref = repo.lookup_reference("refs/pull/1/head") commit2 = pr_ref.peel() self.assertEqual(commit2.oid.hex, diff_commits[0].oid.hex) self.assertNotEqual(commit.oid.hex, commit2.oid.hex)
def merge_pull_request( session, request, username, request_folder, domerge=True): ''' Merge the specified pull-request. ''' if request.remote: # Get the fork repopath = pagure.get_remote_repo_path( request.remote_git, request.branch_from) else: # Get the fork repopath = pagure.get_repo_path(request.project_from) fork_obj = PagureRepo(repopath) # Get the original repo parentpath = pagure.get_repo_path(request.project) # Clone the original repo into a temp folder newpath = tempfile.mkdtemp(prefix='pagure-pr-merge') new_repo = pygit2.clone_repository(parentpath, newpath) # Update the start and stop commits in the DB, one last time diff_commits = diff_pull_request( session, request, fork_obj, PagureRepo(parentpath), requestfolder=request_folder, with_diff=False)[0] if request.project.settings.get( 'Enforce_signed-off_commits_in_pull-request', False): for commit in diff_commits: if 'signed-off-by' not in commit.message.lower(): shutil.rmtree(newpath) raise pagure.exceptions.PagureException( 'This repo enforces that all commits are ' 'signed off by their author. ') # Checkout the correct branch branch_ref = get_branch_ref(new_repo, request.branch) if not branch_ref: shutil.rmtree(newpath) raise pagure.exceptions.BranchNotFoundException( 'Branch %s could not be found in the repo %s' % ( request.branch, request.project.fullname )) new_repo.checkout(branch_ref) branch = get_branch_ref(fork_obj, request.branch_from) if not branch: shutil.rmtree(newpath) raise pagure.exceptions.BranchNotFoundException( 'Branch %s could not be found in the repo %s' % ( request.branch_from, request.project_from.fullname if request.project_from else request.remote_git )) repo_commit = fork_obj[branch.get_object().hex] ori_remote = new_repo.remotes[0] # Add the fork as remote repo reponame = '%s_%s' % (request.user.user, request.uid) remote = new_repo.create_remote(reponame, repopath) # Fetch the commits remote.fetch() merge = new_repo.merge(repo_commit.oid) if merge is None: mergecode = new_repo.merge_analysis(repo_commit.oid)[0] refname = '%s:refs/heads/%s' % (branch_ref.name, request.branch) if ( (merge is not None and merge.is_uptodate) or (merge is None and mergecode & pygit2.GIT_MERGE_ANALYSIS_UP_TO_DATE)): if domerge: pagure.lib.close_pull_request( session, request, username, requestfolder=request_folder) shutil.rmtree(newpath) try: session.commit() except SQLAlchemyError as err: # pragma: no cover session.rollback() pagure.APP.logger.exception(err) raise pagure.exceptions.PagureException( 'Could not close this pull-request') raise pagure.exceptions.PagureException( 'Nothing to do, changes were already merged') else: request.merge_status = 'NO_CHANGE' session.commit() shutil.rmtree(newpath) return 'NO_CHANGE' elif ( (merge is not None and merge.is_fastforward) or (merge is None and mergecode & pygit2.GIT_MERGE_ANALYSIS_FASTFORWARD)): if domerge: if not request.project.settings.get('always_merge', False): if merge is not None: # This is depending on the pygit2 version branch_ref.target = merge.fastforward_oid elif merge is None and mergecode is not None: branch_ref.set_target(repo_commit.oid.hex) else: tree = new_repo.index.write_tree() head = new_repo.lookup_reference('HEAD').get_object() user_obj = pagure.lib.__get_user(session, username) author = pygit2.Signature( user_obj.fullname.encode('utf-8'), user_obj.default_email.encode('utf-8')) new_repo.create_commit( 'refs/heads/%s' % request.branch, author, author, 'Merge #%s `%s`' % (request.id, request.title), tree, [head.hex, repo_commit.oid.hex]) PagureRepo.push(ori_remote, refname) else: request.merge_status = 'FFORWARD' session.commit() shutil.rmtree(newpath) return 'FFORWARD' else: tree = None try: tree = new_repo.index.write_tree() except pygit2.GitError: shutil.rmtree(newpath) if domerge: raise pagure.exceptions.PagureException('Merge conflicts!') else: request.merge_status = 'CONFLICTS' session.commit() return 'CONFLICTS' if domerge: head = new_repo.lookup_reference('HEAD').get_object() user_obj = pagure.lib.__get_user(session, username) author = pygit2.Signature( user_obj.fullname.encode('utf-8'), user_obj.default_email.encode('utf-8')) new_repo.create_commit( 'refs/heads/%s' % request.branch, author, author, 'Merge #%s `%s`' % (request.id, request.title), tree, [head.hex, repo_commit.oid.hex]) PagureRepo.push(ori_remote, refname) else: request.merge_status = 'MERGE' session.commit() shutil.rmtree(newpath) return 'MERGE' # Update status pagure.lib.close_pull_request( session, request, username, requestfolder=request_folder, ) try: # Reset the merge_status of all opened PR to refresh their cache pagure.lib.reset_status_pull_request(session, request.project) session.commit() except SQLAlchemyError as err: # pragma: no cover session.rollback() pagure.APP.logger.exception(err) shutil.rmtree(newpath) raise pagure.exceptions.PagureException( 'Could not update this pull-request in the database') shutil.rmtree(newpath) return 'Changes merged!'
def set_up_git_repo(self, new_project=None, branch_from='feature'): """ Set up the git repo and create the corresponding PullRequest object. """ # Create a git repo to play with gitrepo = os.path.join(self.path, 'repos', 'test.git') repo = pygit2.init_repository(gitrepo, bare=True) repopath = os.path.join(self.newpath, 'test') clone_repo = pygit2.clone_repository(gitrepo, repopath) # Create a file in that git repo with open(os.path.join(repopath, 'sources'), 'w') as stream: stream.write('foo\n bar') clone_repo.index.add('sources') clone_repo.index.write() try: com = repo.revparse_single('HEAD') prev_commit = [com.oid.hex] except: prev_commit = [] # Commits the files added tree = clone_repo.index.write_tree() author = _make_signature('Alice Author', '*****@*****.**') committer = _make_signature('Cecil Committer', '*****@*****.**') clone_repo.create_commit( 'refs/heads/master', # the name of the reference to update author, committer, 'Add sources file for testing', # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit prev_commit) time.sleep(1) refname = 'refs/heads/master:refs/heads/master' ori_remote = clone_repo.remotes[0] PagureRepo.push(ori_remote, refname) first_commit = repo.revparse_single('HEAD') with open(os.path.join(repopath, '.gitignore'), 'w') as stream: stream.write('*~') clone_repo.index.add('.gitignore') clone_repo.index.write() # Commits the files added tree = clone_repo.index.write_tree() author = _make_signature('Alice Äuthòr', 'alice@äuthòrs.tld') committer = _make_signature('Cecil Cõmmîttër', 'cecil@cõmmîttërs.tld') clone_repo.create_commit( 'refs/heads/master', author, committer, 'Add .gitignore file for testing', # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit [first_commit.oid.hex]) refname = 'refs/heads/master:refs/heads/master' ori_remote = clone_repo.remotes[0] PagureRepo.push(ori_remote, refname) # Set the second repo new_gitrepo = repopath if new_project: # Create a new git repo to play with new_gitrepo = os.path.join(self.newpath, new_project.fullname) if not os.path.exists(new_gitrepo): os.makedirs(new_gitrepo) new_repo = pygit2.clone_repository(gitrepo, new_gitrepo) repo = pygit2.Repository(new_gitrepo) # Edit the sources file again with open(os.path.join(new_gitrepo, 'sources'), 'w') as stream: stream.write('foo\n bar\nbaz\n boose') repo.index.add('sources') repo.index.write() # Commits the files added tree = repo.index.write_tree() author = _make_signature('Alice Author', '*****@*****.**') committer = _make_signature('Cecil Committer', '*****@*****.**') repo.create_commit('refs/heads/%s' % branch_from, author, committer, 'A commit on branch %s' % branch_from, tree, [first_commit.oid.hex]) refname = 'refs/heads/%s' % (branch_from) ori_remote = repo.remotes[0] PagureRepo.push(ori_remote, refname)
def add_content_git_repo(folder, branch='master'): """ Create some content for the specified git repo. """ if not os.path.exists(folder): os.makedirs(folder) brepo = pygit2.init_repository(folder, bare=True) newfolder = tempfile.mkdtemp(prefix='pagure-tests') repo = pygit2.clone_repository(folder, newfolder) # Create a file in that git repo with open(os.path.join(newfolder, 'sources'), 'w') as stream: stream.write('foo\n bar') repo.index.add('sources') repo.index.write() parents = [] commit = None try: commit = repo.revparse_single('HEAD' if branch == 'master' else branch) except KeyError: pass if commit: parents = [commit.oid.hex] # Commits the files added tree = repo.index.write_tree() author = pygit2.Signature('Alice Author', '*****@*****.**') committer = pygit2.Signature('Cecil Committer', '*****@*****.**') repo.create_commit( 'refs/heads/%s' % branch, # the name of the reference to update author, committer, 'Add sources file for testing', # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit parents, ) parents = [] commit = None try: commit = repo.revparse_single('HEAD' if branch == 'master' else branch) except KeyError: pass if commit: parents = [commit.oid.hex] subfolder = os.path.join('folder1', 'folder2') if not os.path.exists(os.path.join(newfolder, subfolder)): os.makedirs(os.path.join(newfolder, subfolder)) # Create a file in that git repo with open(os.path.join(newfolder, subfolder, 'file'), 'w') as stream: stream.write('foo\n bar\nbaz') repo.index.add(os.path.join(subfolder, 'file')) repo.index.write() # Commits the files added tree = repo.index.write_tree() author = pygit2.Signature('Alice Author', '*****@*****.**') committer = pygit2.Signature('Cecil Committer', '*****@*****.**') repo.create_commit( 'refs/heads/%s' % branch, # the name of the reference to update author, committer, 'Add some directory and a file for more testing', # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit parents) # Push to origin ori_remote = repo.remotes[0] master_ref = repo.lookup_reference( 'HEAD' if branch == 'master' else 'refs/heads/%s' % branch).resolve() refname = '%s:%s' % (master_ref.name, master_ref.name) PagureRepo.push(ori_remote, refname) shutil.rmtree(newfolder)
def add_readme_git_repo(folder, readme_name="README.rst", branch="master"): """ Create a README file for the specified git repo. """ repo, newfolder, parents = _clone_and_top_commits(folder, branch) if readme_name == "README.rst": content = """Pagure ====== :Author: Pierre-Yves Chibon <*****@*****.**> Pagure is a light-weight git-centered forge based on pygit2. Currently, Pagure offers a web-interface for git repositories, a ticket system and possibilities to create new projects, fork existing ones and create/merge pull-requests across or within projects. Homepage: https://github.com/pypingou/pagure Dev instance: http://209.132.184.222/ (/!\\ May change unexpectedly, it's a dev instance ;-)) """ else: content = ( """Pagure ====== This is a placeholder """ + readme_name + """ that should never get displayed on the website if there is a README.rst in the repo. """ ) # Create a file in that git repo with open(os.path.join(newfolder, readme_name), "w") as stream: stream.write(content) repo.index.add(readme_name) repo.index.write() # Commits the files added tree = repo.index.write_tree() author = pygit2.Signature("Alice Author", "*****@*****.**") committer = pygit2.Signature("Cecil Committer", "*****@*****.**") branch_ref = "refs/heads/%s" % branch repo.create_commit( branch_ref, # the name of the reference to update author, committer, "Add a README file", # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit parents, ) # Push to origin ori_remote = repo.remotes[0] PagureRepo.push(ori_remote, "%s:%s" % (branch_ref, branch_ref)) shutil.rmtree(newfolder)
def setUp(self): """ Set up the environnment, ran before every tests. """ super(PagureFlaskForkPrtests, self).setUp() # Create the main project in the DB item = pagure.lib.model.Project( user_id=1, # pingou name='test', description='test project #1', hook_token='aaabbbccc', ) item.close_status = [ 'Invalid', 'Insufficient data', 'Fixed', 'Duplicate' ] self.session.add(item) self.session.commit() # Create the fork item = pagure.lib.model.Project( user_id=1, # pingou name='test', description='test project #1', hook_token='aaabbbcccdd', parent_id=1, is_fork=True, ) item.close_status = [ 'Invalid', 'Insufficient data', 'Fixed', 'Duplicate' ] self.session.add(item) self.session.commit() # Create two git repos, one has 6 commits, the other 4 of which only # 1 isn't present in the first repo gitrepo = os.path.join(self.path, 'repos', 'test.git') pygit2.init_repository(gitrepo, bare=True) gitrepo2 = os.path.join(self.path, 'repos', 'forks', 'pingou', 'test.git') pygit2.init_repository(gitrepo2, bare=True) newpath = tempfile.mkdtemp(prefix='pagure-fork-test') repopath = os.path.join(newpath, 'test') clone_repo = pygit2.clone_repository(gitrepo, repopath) # Do 3 commits to the main repo for i in range(3): with open(os.path.join(repopath, 'sources'), 'w') as stream: stream.write('foo%s\n bar%s\n' % (i, i)) clone_repo.index.add('sources') clone_repo.index.write() parents = [] try: last_commit = clone_repo.revparse_single('HEAD') parents = [last_commit.oid.hex] except KeyError: pass # Commits the files added tree = clone_repo.index.write_tree() author = pygit2.Signature('Alice Author', '*****@*****.**') committer = pygit2.Signature('Cecil Committer', '*****@*****.**') clone_repo.create_commit( 'refs/heads/master', # the name of the reference to update author, committer, 'Editing the file sources for testing #%s' % i, # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit parents) # Push to the main repo refname = 'refs/heads/master:refs/heads/master' ori_remote = clone_repo.remotes[0] PagureRepo.push(ori_remote, refname) # Push to the fork repo remote = clone_repo.create_remote('pingou_fork', gitrepo2) PagureRepo.push(remote, refname) # Do another 3 commits to the main repo for i in range(3, 6): with open(os.path.join(repopath, 'sources'), 'w') as stream: stream.write('foo%s\n bar%s\n' % (i, i)) clone_repo.index.add('sources') clone_repo.index.write() last_commit = clone_repo.revparse_single('HEAD') # Commits the files added tree = clone_repo.index.write_tree() author = pygit2.Signature('Alice Author', '*****@*****.**') committer = pygit2.Signature('Cecil Committer', '*****@*****.**') clone_repo.create_commit( 'refs/heads/master', # the name of the reference to update author, committer, 'Editing the file sources for testing #%s' % i, # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit [last_commit.oid.hex]) # Push to the main repo refname = 'refs/heads/master:refs/heads/master' ori_remote = clone_repo.remotes[0] PagureRepo.push(ori_remote, refname) # Add two commits to the fork repo repopath = os.path.join(newpath, 'pingou_test') clone_repo = pygit2.clone_repository(gitrepo2, repopath) with open(os.path.join(repopath, 'sources'), 'w') as stream: stream.write('foo\n bar\n') clone_repo.index.add('sources') clone_repo.index.write() last_commit = clone_repo.revparse_single('HEAD') # Commits the files added tree = clone_repo.index.write_tree() author = pygit2.Signature('Alice Author', '*****@*****.**') committer = pygit2.Signature('Cecil Committer', '*****@*****.**') last_commit = clone_repo.create_commit( 'refs/heads/feature_foo', # the name of the reference to update author, committer, 'New edition on side branch of the file sources for testing', # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit [last_commit.oid.hex]) with open(os.path.join(repopath, 'sources'), 'w') as stream: stream.write('foo\n bar\nbaz\n') clone_repo.index.add('sources') clone_repo.index.write() # Commits the files added tree = clone_repo.index.write_tree() author = pygit2.Signature('Alice Author', '*****@*****.**') committer = pygit2.Signature('Cecil Committer', '*****@*****.**') last_commit = clone_repo.create_commit( 'refs/heads/feature_foo', # the name of the reference to update author, committer, 'Second edit on side branch of the file sources for testing', # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit [last_commit.hex]) # Push to the fork repo ori_remote = clone_repo.remotes[0] refname = 'refs/heads/feature_foo:refs/heads/feature_foo' PagureRepo.push(ori_remote, refname) shutil.rmtree(newpath) # Create the PR between the two repos repo = pagure.get_authorized_project(self.session, 'test') forked_repo = pagure.get_authorized_project(self.session, 'test', user='******') req = pagure.lib.new_pull_request( session=self.session, repo_from=forked_repo, branch_from='feature_foo', repo_to=repo, branch_to='master', title='test pull-request', user='******', requestfolder=None, ) self.assertEqual(req.id, 1) self.assertEqual(req.title, 'test pull-request')
def update_git(obj, repo, repofolder): """ Update the given issue in its git. This method forks the provided repo, add/edit the issue whose file name is defined by the uid field of the issue and if there are additions/ changes commit them and push them back to the original repo. """ if not repofolder: return # Get the fork repopath = os.path.join(repofolder, repo.path) # Clone the repo into a temp folder newpath = tempfile.mkdtemp(prefix='pagure-') new_repo = pygit2.clone_repository(repopath, newpath) file_path = os.path.join(newpath, obj.uid) # Get the current index index = new_repo.index # Are we adding files added = False if not os.path.exists(file_path): added = True # Write down what changed with open(file_path, 'w') as stream: stream.write(json.dumps( obj.to_json(), sort_keys=True, indent=4, separators=(',', ': '))) # Retrieve the list of files that changed diff = new_repo.diff() files = [] for p in diff: if hasattr(p, 'new_file_path'): files.append(p.new_file_path) elif hasattr(p, 'delta'): files.append(p.delta.new_file.path) # Add the changes to the index if added: index.add(obj.uid) for filename in files: index.add(filename) # If not change, return if not files and not added: shutil.rmtree(newpath) return # See if there is a parent to this commit parent = None try: parent = new_repo.head.get_object().oid except pygit2.GitError: pass parents = [] if parent: parents.append(parent) # Author/commiter will always be this one author = pygit2.Signature(name='pagure', email='pagure') # Actually commit new_repo.create_commit( 'refs/heads/master', author, author, 'Updated %s %s: %s' % (obj.isa, obj.uid, obj.title), new_repo.index.write_tree(), parents) index.write() # Push to origin ori_remote = new_repo.remotes[0] master_ref = new_repo.lookup_reference('HEAD').resolve() refname = '%s:%s' % (master_ref.name, master_ref.name) PagureRepo.push(ori_remote, refname) # Remove the clone shutil.rmtree(newpath)
def set_up_git_repo(self, repo, fork, branch_from='feature'): """ Set up the git repo and create the corresponding PullRequest object. """ # Clone the main repo gitrepo = os.path.join(self.path, 'repos', repo.path) newpath = tempfile.mkdtemp(prefix='pagure-fork-test') repopath = os.path.join(newpath, 'test') clone_repo = pygit2.clone_repository(gitrepo, repopath) # Create a file in that git repo with open(os.path.join(repopath, 'sources'), 'w') as stream: stream.write('foo\n bar') clone_repo.index.add('sources') clone_repo.index.write() # Commits the files added tree = clone_repo.index.write_tree() author = pygit2.Signature('Alice Author', '*****@*****.**') committer = pygit2.Signature('Cecil Committer', '*****@*****.**') clone_repo.create_commit( 'refs/heads/master', # the name of the reference to update author, committer, 'Add sources file for testing', # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit []) refname = 'refs/heads/master:refs/heads/master' ori_remote = clone_repo.remotes[0] PagureRepo.push(ori_remote, refname) first_commit = clone_repo.revparse_single('HEAD') # Set the second repo repopath = os.path.join(self.path, 'repos', fork.path) new_gitrepo = os.path.join(newpath, 'fork_test') clone_repo = pygit2.clone_repository(repopath, new_gitrepo) # Add the main project as remote repo upstream_path = os.path.join(self.path, 'repos', repo.path) remote = clone_repo.create_remote('upstream', upstream_path) remote.fetch() # Edit the sources file again with open(os.path.join(new_gitrepo, 'sources'), 'w') as stream: stream.write('foo\n bar\nbaz\n boose') clone_repo.index.add('sources') clone_repo.index.write() # Commits the files added tree = clone_repo.index.write_tree() author = pygit2.Signature('Alice Author', '*****@*****.**') committer = pygit2.Signature('Cecil Committer', '*****@*****.**') clone_repo.create_commit('refs/heads/%s' % branch_from, author, committer, 'A commit on branch %s' % branch_from, tree, [first_commit.oid.hex]) refname = 'refs/heads/%s' % (branch_from) ori_remote = clone_repo.remotes[0] PagureRepo.push(ori_remote, refname) # Create a PR for these changes project = pagure.lib.get_authorized_project(self.session, 'test') req = pagure.lib.new_pull_request( session=self.session, repo_from=fork, branch_from=branch_from, repo_to=project, branch_to='master', title='PR from the %s branch' % branch_from, user='******', requestfolder=None, ) self.session.commit() self.assertEqual(req.id, 1) self.assertEqual(req.title, 'PR from the %s branch' % branch_from) shutil.rmtree(newpath)
def setUp(self): """ Set up the environnment, ran before every tests. """ super(PagureFlaskForkPrtests, self).setUp() # Create the main project in the DB item = pagure.lib.model.Project( user_id=1, # pingou name="test", description="test project #1", hook_token="aaabbbccc", ) item.close_status = [ "Invalid", "Insufficient data", "Fixed", "Duplicate", ] self.session.add(item) self.session.commit() # Create the fork item = pagure.lib.model.Project( user_id=1, # pingou name="test", description="test project #1", hook_token="aaabbbcccdd", parent_id=1, is_fork=True, ) item.close_status = [ "Invalid", "Insufficient data", "Fixed", "Duplicate", ] self.session.add(item) self.session.commit() # Create two git repos, one has 6 commits, the other 4 of which only # 1 isn't present in the first repo gitrepo = os.path.join(self.path, "repos", "test.git") pygit2.init_repository(gitrepo, bare=True) gitrepo2 = os.path.join( self.path, "repos", "forks", "pingou", "test.git" ) pygit2.init_repository(gitrepo2, bare=True) newpath = tempfile.mkdtemp(prefix="pagure-fork-test") repopath = os.path.join(newpath, "test") clone_repo = pygit2.clone_repository(gitrepo, repopath) # Do 3 commits to the main repo for i in range(3): with open(os.path.join(repopath, "sources"), "w") as stream: stream.write("foo%s\n bar%s\n" % (i, i)) clone_repo.index.add("sources") clone_repo.index.write() parents = [] try: last_commit = clone_repo.revparse_single("HEAD") parents = [last_commit.oid.hex] except KeyError: pass # Commits the files added tree = clone_repo.index.write_tree() author = pygit2.Signature("Alice Author", "*****@*****.**") committer = pygit2.Signature( "Cecil Committer", "*****@*****.**" ) clone_repo.create_commit( "refs/heads/master", # the name of the reference to update author, committer, "Editing the file sources for testing #%s" % i, # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit parents, ) # Push to the main repo refname = "refs/heads/master:refs/heads/master" ori_remote = clone_repo.remotes[0] PagureRepo.push(ori_remote, refname) # Push to the fork repo remote = clone_repo.create_remote("pingou_fork", gitrepo2) PagureRepo.push(remote, refname) # Do another 3 commits to the main repo for i in range(3, 6): with open(os.path.join(repopath, "sources"), "w") as stream: stream.write("foo%s\n bar%s\n" % (i, i)) clone_repo.index.add("sources") clone_repo.index.write() last_commit = clone_repo.revparse_single("HEAD") # Commits the files added tree = clone_repo.index.write_tree() author = pygit2.Signature("Alice Author", "*****@*****.**") committer = pygit2.Signature( "Cecil Committer", "*****@*****.**" ) clone_repo.create_commit( "refs/heads/master", # the name of the reference to update author, committer, "Editing the file sources for testing #%s" % i, # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit [last_commit.oid.hex], ) # Push to the main repo refname = "refs/heads/master:refs/heads/master" ori_remote = clone_repo.remotes[0] PagureRepo.push(ori_remote, refname) # Add two commits to the fork repo repopath = os.path.join(newpath, "pingou_test") clone_repo = pygit2.clone_repository(gitrepo2, repopath) with open(os.path.join(repopath, "sources"), "w") as stream: stream.write("foo\n bar\n") clone_repo.index.add("sources") clone_repo.index.write() last_commit = clone_repo.revparse_single("HEAD") # Commits the files added tree = clone_repo.index.write_tree() author = pygit2.Signature("Alice Author", "*****@*****.**") committer = pygit2.Signature("Cecil Committer", "*****@*****.**") last_commit = clone_repo.create_commit( "refs/heads/feature_foo", # the name of the reference to update author, committer, "New edition on side branch of the file sources for testing", # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit [last_commit.oid.hex], ) with open(os.path.join(repopath, "sources"), "w") as stream: stream.write("foo\n bar\nbaz\n") clone_repo.index.add("sources") clone_repo.index.write() # Commits the files added tree = clone_repo.index.write_tree() author = pygit2.Signature("Alice Author", "*****@*****.**") committer = pygit2.Signature("Cecil Committer", "*****@*****.**") last_commit = clone_repo.create_commit( "refs/heads/feature_foo", # the name of the reference to update author, committer, "Second edit on side branch of the file sources for testing", # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit [last_commit.hex], ) # Push to the fork repo ori_remote = clone_repo.remotes[0] refname = "refs/heads/feature_foo:refs/heads/feature_foo" PagureRepo.push(ori_remote, refname) shutil.rmtree(newpath) # Create the PR between the two repos repo = pagure.lib.query.get_authorized_project(self.session, "test") forked_repo = pagure.lib.query.get_authorized_project( self.session, "test", user="******" ) req = pagure.lib.query.new_pull_request( session=self.session, repo_from=forked_repo, branch_from="feature_foo", repo_to=repo, branch_to="master", title="test pull-request", user="******", ) self.assertEqual(req.id, 1) self.assertEqual(req.title, "test pull-request")
def merge_pull_request(session, request, username, request_folder, domerge=True): ''' Merge the specified pull-request. ''' if request.remote: # Get the fork repopath = pagure.get_remote_repo_path(request.remote_git, request.branch_from) else: # Get the fork repopath = pagure.get_repo_path(request.project_from) fork_obj = PagureRepo(repopath) # Get the original repo parentpath = pagure.get_repo_path(request.project) # Clone the original repo into a temp folder newpath = tempfile.mkdtemp(prefix='pagure-pr-merge') new_repo = pygit2.clone_repository(parentpath, newpath) # Update the start and stop commits in the DB, one last time diff_commits = diff_pull_request(session, request, PagureRepo(parentpath), fork_obj, requestfolder=request_folder, with_diff=False)[0] if request.project.settings.get( 'Enforce_signed-off_commits_in_pull-request', False): for commit in diff_commits: if 'signed-off-by' not in commit.message.lower(): raise pagure.exceptions.PagureException( 'This repo enforces that all commits are ' 'signed off by their author. ') # Checkout the correct branch branch_ref = get_branch_ref(new_repo, request.branch) if not branch_ref: shutil.rmtree(newpath) raise pagure.exceptions.BranchNotFoundException( 'Branch %s could not be found in the repo %s' % (request.branch, request.project.fullname)) new_repo.checkout(branch_ref) branch = get_branch_ref(fork_obj, request.branch_from) if not branch: shutil.rmtree(newpath) raise pagure.exceptions.BranchNotFoundException( 'Branch %s could not be found in the repo %s' % (request.branch_from, request.project_from.fullname if request.project_from else request.remote_git)) repo_commit = fork_obj[branch.get_object().hex] ori_remote = new_repo.remotes[0] # Add the fork as remote repo reponame = '%s_%s' % (request.user.user, request.uid) remote = new_repo.create_remote(reponame, repopath) # Fetch the commits remote.fetch() merge = new_repo.merge(repo_commit.oid) if merge is None: mergecode = new_repo.merge_analysis(repo_commit.oid)[0] refname = '%s:refs/heads/%s' % (branch_ref.name, request.branch) if ((merge is not None and merge.is_uptodate) or (merge is None and mergecode & pygit2.GIT_MERGE_ANALYSIS_UP_TO_DATE)): if domerge: pagure.lib.close_pull_request(session, request, username, requestfolder=request_folder) try: session.commit() except SQLAlchemyError as err: # pragma: no cover session.rollback() pagure.APP.logger.exception(err) shutil.rmtree(newpath) raise pagure.exceptions.PagureException( 'Could not close this pull-request') raise pagure.exceptions.PagureException( 'Nothing to do, changes were already merged') else: request.merge_status = 'NO_CHANGE' session.commit() return 'NO_CHANGE' elif ( (merge is not None and merge.is_fastforward) or (merge is None and mergecode & pygit2.GIT_MERGE_ANALYSIS_FASTFORWARD)): if domerge: if merge is not None: # This is depending on the pygit2 version branch_ref.target = merge.fastforward_oid elif merge is None and mergecode is not None: branch_ref.set_target(repo_commit.oid.hex) PagureRepo.push(ori_remote, refname) else: request.merge_status = 'FFORWARD' session.commit() return 'FFORWARD' else: tree = None try: tree = new_repo.index.write_tree() except pygit2.GitError: shutil.rmtree(newpath) if domerge: raise pagure.exceptions.PagureException('Merge conflicts!') else: request.merge_status = 'CONFLICTS' session.commit() return 'CONFLICTS' if not domerge: request.merge_status = 'MERGE' session.commit() return 'MERGE' head = new_repo.lookup_reference('HEAD').get_object() new_repo.create_commit('refs/heads/%s' % request.branch, repo_commit.author, repo_commit.committer, 'Merge #%s `%s`' % (request.id, request.title), tree, [head.hex, repo_commit.oid.hex]) PagureRepo.push(ori_remote, refname) # Update status pagure.lib.close_pull_request( session, request, username, requestfolder=request_folder, ) try: # Reset the merge_status of all opened PR to refresh their cache pagure.lib.reset_status_pull_request(session, request.project) session.commit() except SQLAlchemyError as err: # pragma: no cover session.rollback() pagure.APP.logger.exception(err) shutil.rmtree(newpath) raise pagure.exceptions.PagureException( 'Could not update this pull-request in the database') shutil.rmtree(newpath) return 'Changes merged!'
def add_readme_git_repo(folder): """ Create a README file for the specified git repo. """ if not os.path.exists(folder): os.makedirs(folder) brepo = pygit2.init_repository(folder, bare=True) newfolder = tempfile.mkdtemp(prefix='pagure-tests') repo = pygit2.clone_repository(folder, newfolder) content = """Pagure ====== :Author: Pierre-Yves Chibon <*****@*****.**> Pagure is a light-weight git-centered forge based on pygit2. Currently, Pagure offers a web-interface for git repositories, a ticket system and possibilities to create new projects, fork existing ones and create/merge pull-requests across or within projects. Homepage: https://github.com/pypingou/pagure Dev instance: http://209.132.184.222/ (/!\\ May change unexpectedly, it's a dev instance ;-)) """ parents = [] commit = None try: commit = repo.revparse_single('HEAD') except KeyError: pass if commit: parents = [commit.oid.hex] # Create a file in that git repo with open(os.path.join(newfolder, 'README.rst'), 'w') as stream: stream.write(content) repo.index.add('README.rst') repo.index.write() # Commits the files added tree = repo.index.write_tree() author = pygit2.Signature('Alice Author', '*****@*****.**') committer = pygit2.Signature('Cecil Committer', '*****@*****.**') repo.create_commit( 'refs/heads/master', # the name of the reference to update author, committer, 'Add a README file', # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit parents) # Push to origin ori_remote = repo.remotes[0] master_ref = repo.lookup_reference('HEAD').resolve() refname = '%s:%s' % (master_ref.name, master_ref.name) PagureRepo.push(ori_remote, refname) shutil.rmtree(newfolder)
def add_file_to_git(repo, issue, ticketfolder, user, filename, filestream): ''' Add a given file to the specified ticket git repository. :arg repo: the Project object from the database :arg ticketfolder: the folder on the filesystem where the git repo for tickets are stored :arg user: the user object with its username and email :arg filename: the name of the file to save :arg filestream: the actual content of the file ''' if not ticketfolder: return # Prefix the filename with a timestamp: filename = '%s-%s' % (hashlib.sha256( filestream.read()).hexdigest(), werkzeug.secure_filename(filename)) # Get the fork repopath = os.path.join(ticketfolder, repo.path) # Clone the repo into a temp folder newpath = tempfile.mkdtemp(prefix='pagure-') new_repo = pygit2.clone_repository(repopath, newpath) folder_path = os.path.join(newpath, 'files') file_path = os.path.join(folder_path, filename) # Get the current index index = new_repo.index # Are we adding files added = False if not os.path.exists(file_path): added = True else: # File exists, remove the clone and return shutil.rmtree(newpath) return os.path.join('files', filename) if not os.path.exists(folder_path): os.mkdir(folder_path) # Write down what changed filestream.seek(0) with open(file_path, 'w') as stream: stream.write(filestream.read()) # Retrieve the list of files that changed diff = new_repo.diff() files = [patch.new_file_path for patch in diff] # Add the changes to the index if added: index.add(os.path.join('files', filename)) for filename in files: index.add(filename) # If not change, return if not files and not added: shutil.rmtree(newpath) return # See if there is a parent to this commit parent = None try: parent = new_repo.head.get_object().oid except pygit2.GitError: pass parents = [] if parent: parents.append(parent) # Author/commiter will always be this one author = pygit2.Signature(name=user.username, email=user.email) # Actually commit new_repo.create_commit( 'refs/heads/master', author, author, 'Add file %s to ticket %s: %s' % (filename, issue.uid, issue.title), new_repo.index.write_tree(), parents) index.write() # Push to origin ori_remote = new_repo.remotes[0] master_ref = new_repo.lookup_reference('HEAD').resolve() refname = '%s:%s' % (master_ref.name, master_ref.name) PagureRepo.push(ori_remote, refname) # Remove the clone shutil.rmtree(newpath) return os.path.join('files', filename)
def add_content_git_repo(folder, branch='master', append=None): """ Create some content for the specified git repo. """ repo, newfolder, parents = _clone_and_top_commits(folder, branch) # Create a file in that git repo filename = os.path.join(newfolder, 'sources') content = 'foo\n bar' if os.path.exists(filename): content = 'foo\n bar\nbaz' if append: content += append with open(filename, 'w') as stream: stream.write(content) repo.index.add('sources') repo.index.write() # Commits the files added tree = repo.index.write_tree() author = pygit2.Signature('Alice Author', '*****@*****.**') committer = pygit2.Signature('Cecil Committer', '*****@*****.**') commit = repo.create_commit( 'refs/heads/%s' % branch, # the name of the reference to update author, committer, 'Add sources file for testing', # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit parents, ) if commit: parents = [commit.hex] subfolder = os.path.join('folder1', 'folder2') if not os.path.exists(os.path.join(newfolder, subfolder)): os.makedirs(os.path.join(newfolder, subfolder)) # Create a file in that git repo with open(os.path.join(newfolder, subfolder, 'file'), 'w') as stream: stream.write('foo\n bar\nbaz') repo.index.add(os.path.join(subfolder, 'file')) with open(os.path.join(newfolder, subfolder, 'fileŠ'), 'w') as stream: stream.write('foo\n bar\nbaz') repo.index.add(os.path.join(subfolder, 'fileŠ')) repo.index.write() # Commits the files added tree = repo.index.write_tree() author = pygit2.Signature('Alice Author', '*****@*****.**') committer = pygit2.Signature('Cecil Committer', '*****@*****.**') commit = repo.create_commit( 'refs/heads/%s' % branch, # the name of the reference to update author, committer, 'Add some directory and a file for more testing', # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit parents) # Push to origin ori_remote = repo.remotes[0] master_ref = repo.lookup_reference( 'HEAD' if branch == 'master' else 'refs/heads/%s' % branch).resolve() refname = '%s:%s' % (master_ref.name, master_ref.name) PagureRepo.push(ori_remote, refname) shutil.rmtree(newfolder)
def clean_git(obj, repo, repofolder): """ Update the given issue remove it from its git. """ if not repofolder: return # Get the fork repopath = os.path.join(repofolder, repo.path) # Clone the repo into a temp folder newpath = tempfile.mkdtemp(prefix='pagure-') new_repo = pygit2.clone_repository(repopath, newpath) file_path = os.path.join(newpath, obj.uid) # Get the current index index = new_repo.index # Are we adding files if not os.path.exists(file_path): shutil.rmtree(newpath) return # Remove the file os.unlink(file_path) # Add the changes to the index index.remove(obj.uid) # See if there is a parent to this commit parent = None if not new_repo.is_empty: parent = new_repo.head.get_object().oid parents = [] if parent: parents.append(parent) # Author/commiter will always be this one author = pygit2.Signature(name='pagure', email='pagure') # Actually commit new_repo.create_commit( 'refs/heads/master', author, author, 'Removed %s %s: %s' % (obj.isa, obj.uid, obj.title), new_repo.index.write_tree(), parents) index.write() # Push to origin ori_remote = new_repo.remotes[0] master_ref = new_repo.lookup_reference('HEAD').resolve() refname = '%s:%s' % (master_ref.name, master_ref.name) PagureRepo.push(ori_remote, refname) # Remove the clone shutil.rmtree(newpath)
def update_file_in_git(repo, branch, branchto, filename, content, message, user, email): ''' Update a specific file in the specified repository with the content given and commit the change under the user's name. :arg repo: the Project object from the database :arg filename: the name of the file to save :arg content: the new content of the file :arg message: the message of the git commit :arg user: the user object with its username and email ''' # Get the fork repopath = pagure.get_repo_path(repo) # Clone the repo into a temp folder newpath = tempfile.mkdtemp(prefix='pagure-') new_repo = pygit2.clone_repository(repopath, newpath, checkout_branch=branch) file_path = os.path.join(newpath, filename) # Get the current index index = new_repo.index # Write down what changed with open(file_path, 'w') as stream: stream.write(content.replace('\r', '')) # Retrieve the list of files that changed diff = new_repo.diff() files = [patch.new_file_path for patch in diff] # Add the changes to the index added = False for filename in files: added = True index.add(filename) # If not change, return if not files and not added: shutil.rmtree(newpath) return # See if there is a parent to this commit branch_ref = get_branch_ref(new_repo, branch) parent = branch_ref.get_object() # See if we need to create the branch nbranch_ref = None if branchto not in new_repo.listall_branches(): nbranch_ref = new_repo.create_branch(branchto, parent) parents = [] if parent: parents.append(parent.hex) # Author/commiter will always be this one author = pygit2.Signature(name=user.username, email=email) # Actually commit new_repo.create_commit( nbranch_ref.name if nbranch_ref else branch_ref.name, author, author, message.strip(), new_repo.index.write_tree(), parents) index.write() # Push to origin ori_remote = new_repo.remotes[0] refname = '%s:refs/heads/%s' % (nbranch_ref.name if nbranch_ref else branch_ref.name, branchto) try: PagureRepo.push(ori_remote, refname) except pygit2.GitError as err: # pragma: no cover shutil.rmtree(newpath) raise pagure.exceptions.PagureException( 'Commit could not be done: %s' % err) # Remove the clone shutil.rmtree(newpath) return os.path.join('files', filename)
def update_file_in_git( repo, branch, branchto, filename, content, message, user, email): ''' Update a specific file in the specified repository with the content given and commit the change under the user's name. :arg repo: the Project object from the database :arg filename: the name of the file to save :arg content: the new content of the file :arg message: the message of the git commit :arg user: the user object with its username and email ''' # Get the fork repopath = pagure.get_repo_path(repo) # Clone the repo into a temp folder newpath = tempfile.mkdtemp(prefix='pagure-') new_repo = pygit2.clone_repository( repopath, newpath, checkout_branch=branch) file_path = os.path.join(newpath, filename) # Get the current index index = new_repo.index # Write down what changed with open(file_path, 'w') as stream: stream.write(content.replace('\r', '').encode('utf-8')) # Retrieve the list of files that changed diff = new_repo.diff() files = [] for p in diff: if hasattr(p, 'new_file_path'): files.append(p.new_file_path) elif hasattr(p, 'delta'): files.append(p.delta.new_file.path) # Add the changes to the index added = False for filename in files: added = True index.add(filename) # If not change, return if not files and not added: shutil.rmtree(newpath) return # See if there is a parent to this commit branch_ref = get_branch_ref(new_repo, branch) parent = branch_ref.get_object() # See if we need to create the branch nbranch_ref = None if branchto not in new_repo.listall_branches(): nbranch_ref = new_repo.create_branch(branchto, parent) parents = [] if parent: parents.append(parent.hex) # Author/commiter will always be this one author = pygit2.Signature( name=user.username.encode('utf-8'), email=email.encode('utf-8') ) # Actually commit new_repo.create_commit( nbranch_ref.name if nbranch_ref else branch_ref.name, author, author, message.strip(), new_repo.index.write_tree(), parents) index.write() # Push to origin ori_remote = new_repo.remotes[0] refname = '%s:refs/heads/%s' % ( nbranch_ref.name if nbranch_ref else branch_ref.name, branchto) try: PagureRepo.push(ori_remote, refname) except pygit2.GitError as err: # pragma: no cover shutil.rmtree(newpath) raise pagure.exceptions.PagureException( 'Commit could not be done: %s' % err) # Remove the clone shutil.rmtree(newpath) return os.path.join('files', filename)
def add_binary_git_repo(folder, filename): """ Create a fake image file for the specified git repo. """ if not os.path.exists(folder): os.makedirs(folder) brepo = pygit2.init_repository(folder, bare=True) newfolder = tempfile.mkdtemp(prefix='pagure-tests') repo = pygit2.clone_repository(folder, newfolder) content = """<89>PNG^M ^Z ^@^@^@^MIHDR^@^@^@K^@^@^@K^H^F^@^@^@8Nzê^@^@^@^FbKGD^@ÿ^@ÿ^@ÿ ½§<93>^@^@^@ pHYs^@^@^M×^@^@^M×^AB(<9b>x^@^@^@^GtIM E^GÞ ^N^U^F^[<88>]·<9c>^@^@ <8a>IDATxÚí<9c>ÛO^Tg^_Ç?3³»ì^B <8b>®ËË<8b>X^NÕõ^EQÚ^Z^Qc<82>^Pk5Úô¦iMÄ^[{×^K<9b>&^^Xÿ^A<8d>WM^S^SmÒ<8b>j¯Zê<8d> 6^QO^Dª¶´/Ö^M^T5^^*¼¬<9c>^Oî<8 1><99>÷<82>Y<8b>03;3»<83>hù&d óìÃÌw~§çûüf`^Q<8b>XÄ"^V±<88>^?:<84>^Er^N^R ª¿^K3ÎK<99>ñ3^EÈêïÿ8²ò<81> <90>¥C^T^Z<84> É@^Tè^E<86>_g²²<80>^\<95>$^?<86>æ^\TI^[SI|åÉ^R<81>Õ*QNb^\èVÝõ<95>#Ë^M^T^C^Eóì-<83>ÀC þ*<90>%^B+<80>^?¿äÄñ^XèϤ¥e<9 a>,^O°^Vp-<90>l<9f>^@Â<99><8a>gR^FOÌ^O<84>TËZ(HZù3õ'íÉ2<81>^R Ìé+oll¤½½<9d>þþ~^TEAQ^T"<91>^HW¯^åèÑ£¸\º^F]^F¬|Ùn(^@ å@<9e>S^DíÚµ<8b>cÇ<8e>±iÓ¦<94>cãñ8Ç<8f>^_§©©<89>^[7nh^M^Y^Fþ|YdU8ET0^X¤©©<89>Í<9b>7[þî^W_|ÁÄÄ^DçÏ<9f>çÑ£G^Y#,<9d>< 98>µ^RXæ^DQõõõ´¶¶RVfϳÇÇÇyøð!<95><95><95>dggsïÞ½<99><87>½j^B^Z<99>¯<98>åW^CgƱsçN<9a><9b><9b>ÉÎζ=G<þw<89>µaÃ^F^Z^ Z^Zf^OYag^UaDz<jÖË86nÜÈåË<97>§ã<83>`?B<9c>9sæï<85>¥¢^P^L^Fµ,Ì^O^LX©Ã$^[<96>XéTyðË/¿<90><9b><9b>kûûCCC<9c>:u<8a>ÁÁÁ ^WÈN^RöøñcFF^ð¾^B bVÉ°Z<^F<9c>*8¿ùæ^[<82>Á á<98>X,FKK^K'O<9e>äâÅ<8b>ȲLAA^A[·n¥¸¸^XA^Pp»ÝºV¹wï^¾üòËÙ×^_PU<8c><8c>f C7Pí^DQeee<84>ÃaÜn·î<98><9e><9e>^^¶oß®<95>ݦM^^T©®®¦®®<8e>©©)Ý1ׯ_§½½}ö¡ßͬ%¸S±SµÔ<9e>={^L<89>úé§<9f>¨¨¨Ð% """ parents = [] commit = None try: commit = repo.revparse_single('HEAD') except KeyError: pass if commit: parents = [commit.oid.hex] # Create a file in that git repo with open(os.path.join(newfolder, filename), 'w') as stream: stream.write(content) repo.index.add(filename) repo.index.write() # Commits the files added tree = repo.index.write_tree() author = pygit2.Signature( 'Alice Author', '*****@*****.**') committer = pygit2.Signature( 'Cecil Committer', '*****@*****.**') repo.create_commit( 'refs/heads/master', # the name of the reference to update author, committer, 'Add a fake image file', # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit parents ) # Push to origin ori_remote = repo.remotes[0] master_ref = repo.lookup_reference('HEAD').resolve() refname = '%s:%s' % (master_ref.name, master_ref.name) PagureRepo.push(ori_remote, refname) shutil.rmtree(newfolder)
def set_up_git_repo(self): """ Set up the git repo to play with. """ # Create a git repo to play with gitrepo = os.path.join(tests.HERE, 'repos', 'test.git') repo = pygit2.init_repository(gitrepo, bare=True) newpath = tempfile.mkdtemp(prefix='pagure-other-test') repopath = os.path.join(newpath, 'test') clone_repo = pygit2.clone_repository(gitrepo, repopath) # Create a file in that git repo with open(os.path.join(repopath, 'sources'), 'w') as stream: stream.write('foo\n bar') clone_repo.index.add('sources') clone_repo.index.write() # Commits the files added tree = clone_repo.index.write_tree() author = pygit2.Signature( 'Alice Author', '*****@*****.**') committer = pygit2.Signature( 'Cecil Committer', '*****@*****.**') clone_repo.create_commit( 'refs/heads/feature', # the name of the reference to update author, committer, 'Add sources file for testing', # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit [] ) feature_branch = clone_repo.lookup_branch('feature') first_commit = feature_branch.get_object().hex # Second commit with open(os.path.join(repopath, '.gitignore'), 'w') as stream: stream.write('*~') clone_repo.index.add('.gitignore') clone_repo.index.write() tree = clone_repo.index.write_tree() author = pygit2.Signature( 'Alice Author', '*****@*****.**') committer = pygit2.Signature( 'Cecil Committer', '*****@*****.**') clone_repo.create_commit( 'refs/heads/feature', author, committer, 'Add .gitignore file for testing', # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit [first_commit] ) refname = 'refs/heads/feature' ori_remote = clone_repo.remotes[0] PagureRepo.push(ori_remote, refname) shutil.rmtree(newpath)
def test_view_docs(self): """ Test the view_docs endpoint. """ tests.create_projects(self.session) repo = pygit2.init_repository(os.path.join(tests.HERE, 'docs', 'test.git'), bare=True) output = self.app.get('/test/docs') self.assertEqual(output.status_code, 200) self.assertTrue('<h2>Docs</h2>' in output.data) self.assertTrue('<p>This repo is brand new!</p>' in output.data) self.assertTrue( 'git clone [email protected]:docs/test.git' in output.data) # forked doc repo docrepo = os.path.join(tests.HERE, 'docs', 'test', 'test.git') repo = pygit2.init_repository(docrepo) # Create files in that git repo with open(os.path.join(docrepo, 'sources'), 'w') as stream: stream.write('foo\n bar') repo.index.add('sources') repo.index.write() folderpart = os.path.join(docrepo, 'folder1', 'folder2') os.makedirs(folderpart) with open(os.path.join(folderpart, 'test_file'), 'w') as stream: stream.write('row1\nrow2\nrow3') repo.index.add(os.path.join('folder1', 'folder2', 'test_file')) repo.index.write() # Commits the files added tree = repo.index.write_tree() author = pygit2.Signature('Alice Author', '*****@*****.**') committer = pygit2.Signature('Cecil Committer', '*****@*****.**') repo.create_commit( 'refs/heads/master', # the name of the reference to update author, committer, 'Add test files and folder', # binary string representing the tree object ID tree, # list of binary strings representing parents of the new commit []) # Push the changes to the bare repo remote = repo.create_remote( 'origin', os.path.join(tests.HERE, 'docs', 'test.git')) PagureRepo.push(remote, 'refs/heads/master:refs/heads/master') # Now check the UI output = self.app.get('/test/docs') self.assertEqual(output.status_code, 200) self.assertTrue('<h2>Docs</h2>' in output.data) self.assertFalse('<p>This repo is brand new!</p>' in output.data) self.assertTrue('<a href="/test/master/folder1">' in output.data) self.assertTrue('<a href="/test/master/sources">' in output.data) output = self.app.get('/test/master/sources') self.assertEqual(output.status_code, 200) self.assertTrue('<h2>Docs</h2>' in output.data) self.assertTrue('<section class="docs_content">' in output.data) output = self.app.get('/test/master/folder1/folder2') self.assertEqual(output.status_code, 200) self.assertTrue('<h2>Docs</h2>' in output.data) self.assertTrue( '<li class="file">\n ' '<a href="/test/master/folder1/folder2/test_file">' in output.data) output = self.app.get('/test/master/folder1/folder2/test_file') self.assertEqual(output.status_code, 200) self.assertTrue('<h2>Docs</h2>' in output.data) self.assertTrue( ' <section class="docs_content">\n <pre>row1\nrow2\n' 'row3</pre>\n </section>' in output.data) output = self.app.get('/test/master/folder1') self.assertEqual(output.status_code, 200) self.assertTrue('<h2>Docs</h2>' in output.data) self.assertTrue( '<li class="folder">\n ' '<a href="/test/master/folder1/folder2">' in output.data) output = self.app.get('/test/master/folder1/foo') self.assertEqual(output.status_code, 200) self.assertTrue('<h2>Docs</h2>' in output.data) self.assertTrue( '<li class="error">File folder1/foo not found</li>' in output.data) output = self.app.get('/test/master/folder1/foo/folder2') self.assertEqual(output.status_code, 200) self.assertTrue( '<li class="error">File folder1/foo/folder2 not found</li>' in output.data)