def test_branch(self): repo = Repository(self.main_repo) repo.branch("new-branch") hgrepo = hglib.open(self.main_repo) self.assertEquals(hgrepo.branch(), "new-branch") hgrepo.close() # this does not throw exception, even though the branch already exists, # because it is forced repo.branch(INITIAL_BRANCH) hgrepo = hglib.open(self.main_repo) self.assertEquals(hgrepo.branch(), INITIAL_BRANCH) hgrepo.close()
def _get_tag_changeset(self, tag_name): """ Gets the changeset that correspond to the given tag :param tag_name: name of the tag :type string """ with hglib.open(self.path) as repo: try: repo = hglib.open(self.path) rev = [t[2] for t in repo.tags() if t[0] == tag_name][0] return self._new_changeset_object(self[rev]) except (IndexError, hglib.error.CommandError) as e: logger.exception("Eror getting tag '%s': %s" % (tag_name, e)) raise RepositoryError(e)
def test_merge(self): repo = hglib.open(self.main_repo) repository = Repository(self.main_repo) orig_rev = repo.tip()[1] commits = ['extra commit', '#INT-00 another extra commit'] self.commit_in_repo(self.main_repo, ['f1', 'f2'], commits) new_rev = repository[repo.tip()[1]] repo.update(rev=orig_rev) self.commit_in_repo(self.main_repo, ['f3', ' f4'], [ 'extra commit in another branch', 'another extra commit in another branch' ]) third_revision = repository[repo.tip()[1]] # need to commit, return true repository.merge(other_rev=new_rev) cs = repository["tip"] self.assertEquals(len(cs.parents), 2) repo.update(third_revision, clean=True) self.commit_in_repo( self.main_repo, ['f1', 'f2'], ['this should conflict', 'this should conflict too']) # conflicts with self.assertRaises(RepositoryError): repository.merge(new_rev) with self.assertRaises(RepositoryError): # this calls send_mail, what raises exception # TODO: use stubs repository.merge("wrong_revision") repo.close()
def test_commit_commits_all(self): repo = hglib.open(self.main_repo) file_name = "f1" file_path = os.path.join(self.main_repo, file_name) expected_content = "changed content" with open(file_path, "w+") as file: file.write("foo test content") commit_msg = "Test message" repo.add(file_path) repo.commit('Creating file', user="******") with open(file_path, "w+") as file: file.write(expected_content) repository = Repository(self.main_repo) repository.commit(commit_msg) with open(file_path, "w+") as file: file.write('content changed again') repo.update(clean=True) with open(file_path) as file: self.assertEquals(expected_content, file.read()) repo.close()
def test_get_ancestor(self): repo_main = hglib.open(self.main_repo) orig_rev = repo_main.tip() commits_integration = [ 'commit in integration', 'another extra commit in integration' ] self.commit_in_repo(self.main_repo, ['f1', 'f2'], commits_integration) rev1 = repo_main.tip() repo_main.update(rev="tip~%i" % len(commits_integration)) repo_main.branch("other-branch") commits = [ 'commit in other-branch', 'another extra commit in other-branch' ] self.commit_in_repo(self.main_repo, ['f3', 'f2'], commits) rev2 = repo_main.tip() repo_main.update(rev=orig_rev[1]) repo = Repository(self.main_repo) ancestor = repo.get_ancestor(repo[rev1[1]], repo[rev2[1]]) self.assertEquals(ancestor.hash, orig_rev[1]) repo_main.close() with self.assertRaises(RepositoryError): repo.get_ancestor(None, repo[rev2[1]]) with self.assertRaises(RepositoryError): repo.get_ancestor(repo["bad_revision"], repo["another"])
def test_update(self): hgrepo = hglib.open(self.main_repo) tip = Changeset(None, hgrepo.tip()) repo = Repository(self.main_repo) repo.update(tip) self.assertEquals(hgrepo.parents()[0].node, tip.hash)
def test_merge(self): repo = hglib.open(self.main_repo) repository = Repository(self.main_repo) orig_rev = repo.tip()[1] commits = ['extra commit', '#INT-00 another extra commit'] self.commit_in_repo(self.main_repo, ['f1', 'f2'], commits) new_rev = repository[repo.tip()[1]] repo.update(rev=orig_rev) self.commit_in_repo( self.main_repo, ['f3', ' f4'], [ 'extra commit in another branch', 'another extra commit in another branch' ]) third_revision = repository[repo.tip()[1]] # need to commit, return true repository.merge(other_rev=new_rev) cs = repository["tip"] self.assertEquals(len(cs.parents), 2) repo.update(third_revision, clean=True) self.commit_in_repo( self.main_repo, ['f1', 'f2'], ['this should conflict', 'this should conflict too']) # conflicts with self.assertRaises(RepositoryError): repository.merge(new_rev) with self.assertRaises(RepositoryError): # this calls send_mail, what raises exception # TODO: use stubs repository.merge("wrong_revision") repo.close()
def set_source(self, path, source): """ Inherited method :func:`~repoman.depot_operations.DepotOperations.set_source` """ try: with hglib.open(path) as dep: paths = dep.paths() except (hglib.util.error.ServerError, hglib.util.error.CommandError, hglib.error.ResponseError) as e: logger.exception('Error getting depot paths %s: %s' % (path, e)) raise e if not paths or "default" not in paths or paths["default"] != source: hgrc_path = os.path.join(path, ".hg/hgrc") already_exists = os.path.exists(hgrc_path) with open(hgrc_path, 'r+' if already_exists else 'w') as hgrc: if already_exists: prev_content = hgrc.read() prev_has_path = re.search("default=.*($|\\n)", prev_content, re.MULTILINE) if prev_has_path: new_content = re.sub("default=.*($|\\n)", "default=%s\n" % source, prev_content) else: new_content = "%s\n[paths]\ndefault=%s\n" % ( prev_content, source) else: new_content = "[paths]\ndefault=%s\n" % source logger.debug("Setting default source in %s hgrc: %s" % (path, new_content)) hgrc.write(new_content)
def check_changeset_availability(self, path, changesets): """ Inherited method :func:`~repoman.depot_operations.DepotOperations.check_changeset_availability` """ missing = [] try: with hglib.open(path) as dep: branches = dep.branches() for changeset in changesets: try: if changeset != 'tip': isbranch = any(x[0] == changeset for x in branches) if isbranch: missing.append(changeset) else: log = dep.log(revrange=changeset) if not log: missing.append(changeset) else: missing.append('tip') except: missing.append(changeset) logger.debug( 'Checking availability of changesets in %s: Missing %s' % (path, "'".join(missing))) except (hglib.util.error.CommandError, hglib.error.ResponseError) as e: logger.exception( 'Error in check_changeset_availability method: %s' % e) return missing
def test___str__(self): clon = hglib.open(os.path.join(self.environment_path, 'repo1')) clon.update('default') hgrepo = Repository(os.path.join(self.environment_path, 'repo1')) hgcs = Changeset(hgrepo, clon.tip()) self.assertEquals( hgcs.__str__(), clon.tip().node[:Changeset.SHORT_HASH_COUNT])
def test_get_ancestor(self): repo_main = hglib.open(self.main_repo) orig_rev = repo_main.tip() commits_integration = ['commit in integration', 'another extra commit in integration'] self.commit_in_repo(self.main_repo, ['f1', 'f2'], commits_integration) rev1 = repo_main.tip() repo_main.update(rev="tip~%i" % len(commits_integration)) repo_main.branch("other-branch") commits = ['commit in other-branch', 'another extra commit in other-branch'] self.commit_in_repo(self.main_repo, ['f3', 'f2'], commits) rev2 = repo_main.tip() repo_main.update(rev=orig_rev[1]) repo = Repository(self.main_repo) ancestor = repo.get_ancestor(repo[rev1[1]], repo[rev2[1]]) self.assertEquals(ancestor.hash, orig_rev[1]) repo_main.close() with self.assertRaises(RepositoryError): repo.get_ancestor(None, repo[rev2[1]]) with self.assertRaises(RepositoryError): repo.get_ancestor(repo["bad_revision"], repo["another"])
def test___str__(self): clon = hglib.open(os.path.join(self.environment_path, 'repo1')) clon.update('default') hgrepo = Repository(os.path.join(self.environment_path, 'repo1')) hgcs = Changeset(hgrepo, clon.tip()) self.assertEquals(hgcs.__str__(), clon.tip().node[:Changeset.SHORT_HASH_COUNT])
def check_changeset_availability(self, path, changesets): """ Inherited method :func:`~repoman.depot_operations.DepotOperations.check_changeset_availability` """ missing = [] try: with hglib.open(path) as dep: branches = dep.branches() for changeset in changesets: try: if changeset != 'tip': isbranch = any(x[0] == changeset for x in branches) if isbranch: missing.append(changeset) else: log = dep.log(revrange=changeset) if not log: missing.append(changeset) else: missing.append('tip') except: missing.append(changeset) logger.debug( 'Checking availability of changesets in %s: Missing %s' % ( path, "'".join(missing))) except (hglib.util.error.CommandError, hglib.error.ResponseError) as e: logger.exception( 'Error in check_changeset_availability method: %s' % e) return missing
def terminate_branch(self, branch_name, repo_origin, repo_dest): """ Inherited method :func:`~repoman.repository.Repository.terminate_branch` """ repo = None try: with hglib.open(self.path) as repo: try: repo.pull(repo_origin, branch=branch_name) except hglib.error.CommandError: # Ignore this error, the branch could be only local thus # the pull can safely fail pass repo.update(branch_name, clean=True) repo.commit(message=str( self.message_builder.close_branch(branch=branch_name)), user=self.signature.user, closebranch=True) parents = repo.parents() self.push(repo_origin, repo_dest, self._new_changeset_object(parents[0])) except hglib.error.CommandError as e: if 'can only close branch heads' in e.err: logger.exception( "Cannot close %s branch, it's already closed" % branch_name) return logger.exception("Error closing the release branch %s: %s" % (branch_name, e)) raise RepositoryError(e)
def terminate_branch(self, branch_name, signature, repo_origin, repo_dest): """ Inherited method :func:`~repoman.repository.Repository.terminate_branch` """ repo = None try: with hglib.open(self.path) as repo: try: repo.pull(repo_origin, branch=branch_name) except hglib.error.CommandError: # Ignore this error, the branch could be only local thus # the pull can safely fail pass repo.update(branch_name, clean=True) repo.commit( message=str(self.message_builder.close_branch( branch=branch_name )), user=signature.user, closebranch=True) parents = repo.parents() self.push(repo_origin, repo_dest, self._new_changeset_object(parents[0])) except hglib.error.CommandError as e: if 'can only close branch heads' in e.err: logger.exception( "Cannot close %s branch, it's already closed" % branch_name) return logger.exception("Error closing the release branch %s: %s" % ( branch_name, e)) raise RepositoryError(e)
def set_source(self, path, source): """ Inherited method :func:`~repoman.depot_operations.DepotOperations.set_source` """ try: with hglib.open(path) as dep: paths = dep.paths() except (hglib.util.error.ServerError, hglib.util.error.CommandError, hglib.error.ResponseError) as e: logger.exception('Error getting depot paths %s: %s' % (path, e)) raise e if not paths or "default" not in paths or paths["default"] != source: hgrc_path = os.path.join(path, ".hg/hgrc") already_exists = os.path.exists(hgrc_path) with open(hgrc_path, 'r+' if already_exists else 'w') as hgrc: if already_exists: prev_content = hgrc.read() prev_has_path = re.search("default=.*($|\\n)", prev_content, re.MULTILINE) if prev_has_path: new_content = re.sub( "default=.*($|\\n)", "default=%s\n" % source, prev_content) else: new_content = "%s\n[paths]\ndefault=%s\n" % ( prev_content, source) else: new_content = "[paths]\ndefault=%s\n" % source logger.debug( "Setting default source in %s hgrc: %s" % (path, new_content)) hgrc.write(new_content)
def test_create_branch(self): clon = hglib.open(os.path.join(self.environment_path, 'repo1')) clon.update('default') hgrepo = Repository(os.path.join(self.environment_path, 'repo1')) hgcs = Changeset(hgrepo, clon.tip()) branch = hgcs.create_branch('fakebranch') self.assertEquals(branch.get_changeset(), hgrepo.tip()) self.assertEquals('fakebranch', clon.branch()) clon.close()
def get_revset(self, cs_from=None, cs_to=None, branch=None, keyword=None, date=None): """ Inherited method :func:`~repoman.repository.Repository.get_revset` """ repo = None if cs_from: if cs_to: revset = "%s::%s" % (cs_from, cs_to) else: revset = cs_from else: revset = None with hglib.open(self.path) as repo: try: # If a revset is given, not heavy, not needed to split # the log in chunks if revset: # Adding cs_from because it's not added due to the :: usage result = [ self._new_changeset_object( repo.log(revrange=cs_from)[0]) ] for revision in repo.log(revrange=revset, branch=branch): changeset = self._new_changeset_object(revision) if changeset not in result: result.append(changeset) for changeset in result: yield changeset else: chunk_size = 15 first = repo.log(limit=1, branch=branch)[0] previous_hash = None first_hash = first.node revrange = None while previous_hash != first_hash: changesets = repo.log(limit=chunk_size, branch=branch, revrange=revrange) previous_hash = first_hash if len(changesets) > chunk_size: first = changesets.pop(-1) first_hash = first.node revrange = "%s:%s" % (first_hash, chunk_size) while changesets: cs = self._new_changeset_object(changesets.pop(0)) yield cs except hglib.error.CommandError as e: logger.exception(e) raise RepositoryError(e)
def parents(self, repo): """ Inherited method :func:`~repoman.repository.Repository.parents` """ repo = hglib.open(self.path) try: return [self._new_changeset_object(cs) for cs in repo.parents()] except TypeError: raise RepositoryError("Working copy for repo %s has no parents " "(is it bare?)" % self.path)
def add(self, files): """ Inherited method :func:`~repoman.repository.Repository.add` """ if not isinstance(files, list): files = [files] with hglib.open(self.path) as repo: for file in files: if not repo.add(os.path.join(self.path, file)): raise RepositoryError("Could not add file '%s'" % file)
def test_get_changeset_tags(self): hgrepo = hglib.open(self.main_repo) hgrepo.update() rev = hgrepo.tip().node hgrepo.tag("test_tag", rev=rev, user='******') hgrepo.tag("test_tag2", rev=rev, user='******') repo = Repository(self.main_repo) tags = repo.get_changeset_tags(rev) self.assertListEqual(tags, ["test_tag", "test_tag2"]) hgrepo.close()
def test_strip(self): hgrepo = hglib.open(self.main_repo) hgrepo.update(rev=INITIAL_BRANCH) rev = self.commit_in_repo(self.main_repo, ['f199'], ['extra commit'])[1] repo = Repository(self.main_repo) repo.strip(repo[rev]) with self.assertRaises(hglib.error.CommandError): hgrepo.log(revrange=rev) hgrepo.close()
def test_get_branch_tip(self): repo = hglib.open(self.main_repo) branch = repo.branch() tip = repo.log(branch=branch, limit=1)[0][1] repo.close() repository = Repository(self.main_repo) self.assertEquals(repository.get_branch_tip(branch).hash, tip) with self.assertRaises(RepositoryError): repository.get_branch_tip("inexistent_branch")
def test_commit_without_allow_empty_does_not_fail_when_no_changes(self): repo = hglib.open(self.main_repo) initial_len = len(repo.log()) commit_msg = 'foo message' repository = Repository(self.main_repo) result = repository.commit(commit_msg) self.assertIsNone(result) self.assertEquals(len(repo.log()), initial_len) repo.close()
def commit_in_repo(self, repo_path, files, commits): repo = hglib.open(repo_path) rev = None for commit in commits: for file_name in files: file = open(os.path.join(repo_path, file_name), "a") file.write("%s in %s\n" % (commit, file_name)) file.close() repo.add(os.path.join(repo_path, file_name)) rev = repo.commit(message=commit, user="******") repo.close() return rev
def test_compare_branches(self): test1 = 'test1' hgrepo = hglib.open(self.main_repo) hgrepo.update(rev=INITIAL_BRANCH) hgrepo.branch(test1) self.commit_in_repo(self.main_repo, ['f199', 'f99'], ['extra commit', 'another extra commit']) repo = Repository(self.main_repo) diff = repo.compare_branches(test1, INITIAL_BRANCH) self.assertEquals(2, len(diff)) hgrepo.close()
def test_init(self): clon = hglib.open(os.path.join(self.environment_path, 'repo1')) hgrepo = Repository(os.path.join(self.environment_path, 'repo1')) hgcs = Changeset(hgrepo, clon.tip()) clon.close() self.assertEquals(hgcs.author, "Jose Plana <*****@*****.**>") self.assertEquals(hgcs.hash, "c377d40d21153bdcc4ec0b24bba48af3899fcc7c") self.assertEquals(hgcs.desc, "Second changeset") self.assertFalse(hgcs.merge) self.assertEquals(hgcs.parents[0].hash, "b93d349f220d892047817f7ab29b2e8bfc5569ba")
def test_init(self): clon = hglib.open(os.path.join(self.environment_path, 'repo1')) hgrepo = Repository(os.path.join(self.environment_path, 'repo1')) hgcs = Changeset(hgrepo, clon.tip()) clon.close() self.assertEquals(hgcs.author, "Jose Plana <*****@*****.**>") self.assertEquals( hgcs.hash, "c377d40d21153bdcc4ec0b24bba48af3899fcc7c") self.assertEquals(hgcs.desc, "Second changeset") self.assertFalse(hgcs.merge) self.assertEquals( hgcs.parents[0].hash, "b93d349f220d892047817f7ab29b2e8bfc5569ba")
def test_pull(self): self.commit_in_repo(self.main_repo, ['f1', 'f2'], ['extra commit', 'another extra commit']) repo_main = hglib.open(self.main_repo) second_repo = hglib.open(self.second_repo) self.assertNotEqual(len(repo_main.log()), len(second_repo.log())) repo = Repository(self.second_repo) repo.pull(remote=self.main_repo) self.assertEquals(len(repo_main.log()), len(second_repo.log())) repo_main.close() second_repo.close() repo = Repository(self.second_repo) with self.assertRaises(RepositoryError): repo.pull(revision="tip", remote="wrong_repo") with self.assertRaises(RepositoryError): repo.pull(revision="none_revision", remote=self.main_repo)
def get_branch(self, repo, branch_name=None): """ Inherited method :func:`~repoman.repository.Repository.get_branch` """ if not branch_name: repo = hglib.open(self.path) branch_name = repo.branch() else: if not self.branch_exists(branch_name): raise RepositoryError("Branch %s does not exist in repo %s" % (branch_name, self.path)) return self._new_branch_object(branch_name)
def create_repo(self, path, branch_name='integration', repo_name=None): if not repo_name: repo_name = "tuenti-ng" full_path = os.path.join(path, repo_name) os.mkdir(full_path) hglib.init(full_path) repo = hglib.open(full_path) repo.branch(branch_name) commits = ['initial commit', 'second commit', 'third commit'] files = ['f1', 'f2', 'f3', 'f4'] self.commit_in_repo(full_path, files, commits) repo.close() return full_path
def test_commit_commits_all_but_removed_files(self): file_name = "f1" file_path = os.path.join(self.main_repo, file_name) commit_msg = "Test message" repository = Repository(self.main_repo) os.remove(file_path) repository.commit(commit_msg) hglibrepo = hglib.open(self.main_repo) hglibrepo.branch(clean=True) self.assertFalse(os.path.exists(file_path))
def test_add_files(self): file_name = "absurd_file" file_path = os.path.join(self.main_repo, file_name) with open(file_path, "w") as file: file_content = "Absurd content" file.write(file_content) repo_main = hglib.open(self.main_repo) with self.assertRaises(hglib.error.CommandError): repo_main.cat([file_path], rev="tip") status = repo_main.status()[0][0] repo_main.close() self.assertEquals(status, "?") repo = Repository(self.main_repo) repo.add(file_name) repo_main = hglib.open(self.main_repo) status = repo_main.status()[0][0] repo_main.close() self.assertEquals(status, "A") with self.assertRaises(RepositoryError): repo.add("nonexistentfile")
def test_get_branch_no_name(self): repo = Repository(self.main_repo) hgrepo = hglib.open(self.main_repo) hgrepo.close() branch = repo.get_branch() self.assertEquals(branch.name, "test_branch") changesets_list = [x for x in repo.get_revset(branch=branch.name)] self.assertEquals(len(changesets_list), 2) self.assertEquals( changesets_list[0].desc, "#TICKET-2 yet another commit") self.assertEquals(changesets_list[1].desc, "TICKET-1 one commit")
def test_get_branch_no_name(self): repo = Repository(self.main_repo) hgrepo = hglib.open(self.main_repo) hgrepo.close() branch = repo.get_branch() self.assertEquals(branch.name, "test_branch") changesets_list = [x for x in repo.get_revset(branch=branch.name)] self.assertEquals(len(changesets_list), 2) self.assertEquals(changesets_list[0].desc, "#TICKET-2 yet another commit") self.assertEquals(changesets_list[1].desc, "TICKET-1 one commit")
def grab_changesets(self, path, url, changesets): """ Inherited method :func:`~repoman.depot_operations.DepotOperations.grab_changesets` """ logger.debug('Grabbing changesets %s from %s to %s' % ( "'".join(changesets), url, path)) try: with hglib.open(path) as dep: result = dep.pull(source=url, rev=changesets) logger.debug('Done grabbing changesets %s' % result) return result except (hglib.util.error.CommandError, hglib.error.ResponseError) as e: logger.exception('Error Grabbing changesets: %s' % e) return False
def wrapped(they, *args, **kwargs): try: with hglib.open(they.path) as repo: return f(they, repo, *args, **kwargs) except self.exceptions as e: if self.error_message: arguments = ", ".join(str(arg) for arg in args) arguments += ", " + str(kwargs) logger.exception("%s (%s)" % (self.error_message, arguments)) raise RepositoryError(self.error_message + str(e)) else: logger.exception(e) raise RepositoryError(e)
def wrapped(they, *args, **kwargs): try: with hglib.open(they.path) as repo: return f(they, repo, *args, **kwargs) except self.exceptions as e: if self.error_message: arguments = ", ".join(str(arg) for arg in args) arguments += ", " + str(kwargs) logger.exception("%s (%s)" % ( self.error_message, arguments)) raise RepositoryError(self.error_message + str(e)) else: logger.exception(e) raise RepositoryError(e)
def test_full_merge_and_push(self): repo_path = os.path.join(self.environment_path, "mergepush") self.clone_repo(repo_path, self.main_repo, revision="tip") base_branch = "integration" origin = self.main_repo destination = 'http://push.fake' repo = hglib.open(repo_path) repo.branch(base_branch) # Let's merge with an ancestor so the push is not performed hash = 1 repo = Repository(self.main_repo) repo.full_merge_and_push(base_branch, hash, 'fake_branch', origin, destination)
def grab_changesets(self, path, url, changesets): """ Inherited method :func:`~repoman.depot_operations.DepotOperations.grab_changesets` """ logger.debug('Grabbing changesets %s from %s to %s' % ("'".join(changesets), url, path)) try: with hglib.open(path) as dep: result = dep.pull(source=url, rev=changesets) logger.debug('Done grabbing changesets %s' % result) return result except (hglib.util.error.CommandError, hglib.error.ResponseError) as e: logger.exception('Error Grabbing changesets: %s' % e) return False