def test_user(self): self.append('a', 'a') rev, node = self.client.commit(b('first'), addremove=True, user=b('foo')) rev = self.client.log(node)[0] self.assertEquals(rev.author, b('foo'))
def test_exists(self): self.append('a', 'a') self.client.commit(b('first'), addremove=True) self.client.branch(b('foo')) self.append('a', 'a') self.client.commit(b('second')) self.assertRaises(hglib.error.CommandError, self.client.branch, b('default'))
def setUp(self): common.basetest.setUp(self) self.append('a', 'a') rev, self.node0 = self.client.commit(b('first'), addremove=True) self.append('a', 'a') rev, self.node1 = self.client.commit(b('change'))
def test_unresolved(self): self.client.update(self.rev0) self.append('a', 'b') u, m, r, ur = self.client.update() self.assertEquals(u, 0) self.assertEquals(m, 0) self.assertEquals(r, 0) self.assertEquals(ur, 1) self.assertTrue((b('M'), b('a')) in self.client.status())
def _cloneRepository(self, clone_url, clone_dir): """Clone repository :param clone_url: repository clone url :type clone_url: string :param clone_dir: directory to clone repository to :type clone_dir: string """ hglib.clone(b(clone_url), b(clone_dir))
def test_basic(self): self.append('a', 'a') rev, node0 = self.client.commit(b('first'), addremove=True) self.client.clone(dest=b('other')) self.append('a', 'a') rev, node1 = self.client.commit(b('second')) self.assertTrue(self.client.bundle(b('bundle'), destrepo=b('other')))
def test_basic(self): self.assertEquals(self.client.branch(b('foo')), b('foo')) self.append('a', 'a') rev, node = self.client.commit(b('first'), addremove=True) rev = self.client.log(node)[0] self.assertEquals(rev.branch, b('foo')) self.assertEquals(self.client.branches(), [(rev.branch, int(rev.rev), rev.node[:12])])
def test_basic(self): self.append('a', 'a') rev, node0 = self.client.commit(b('first'), addremove=True) self.assertEquals(self.client.heads(), [self.client.tip()]) self.client.branch(b('foo')) self.append('a', 'a') rev, node1 = self.client.commit(b('second')) self.assertEquals(self.client.heads(node0, topological=True), [])
def pathto(self, f, cwd=b('.')): """ Return relative path to f. If cwd is given, use it as current working directory. The returned path uses os.sep as separator. f - file path with / as separator cwd - working directory with os.sep as separator """ return os.path.relpath(os.path.join(self.root(), *(f.split(b('/')))), start=cwd)
def main(lang, reference_dir, localization_dir, blame, migrations, dry_run): """Run migrations and commit files with the result.""" changesets = convert_blame_to_changesets(blame) client = hglib.open(localization_dir) for migration in migrations: print('Running migration {}'.format(migration.__name__)) # For each migration create a new context. ctx = MergeContext(lang, reference_dir, localization_dir) try: # Add the migration spec. migration.migrate(ctx) except MigrationError as err: sys.exit(err.message) # Keep track of how many changesets we're committing. index = 0 for changeset in changesets: # Run the migration for the changeset. snapshot = ctx.serialize_changeset(changeset['changes']) # Did it change any files? if not snapshot: continue # Write serialized FTL files to disk. for path, content in snapshot.iteritems(): fullpath = os.path.join(localization_dir, path) print(' Writing to {}'.format(fullpath)) if not dry_run: fulldir = os.path.dirname(fullpath) if not os.path.isdir(fulldir): os.makedirs(fulldir) with open(fullpath, 'w') as f: f.write(content.encode('utf8')) f.close() index += 1 author = changeset['author'].encode('utf8') message = migration.migrate.__doc__.format( index=index, author=author ) print(' Committing changeset: {}'.format(message)) if not dry_run: client.commit( b(message), user=b(author), addremove=True )
def test_basic(self): self.append('a', 'a') self.client.commit(b('first'), addremove=True) self.client.clone(dest=b('other')) other = hglib.open(b('other')) self.append('a', 'a') self.client.commit(b('second')) self.assertTrue(other.pull()) self.assertEquals(self.client.log(), other.log())
def test_basic(self): f = open('.hg/hgrc', 'a') f.write('[paths]\nfoo = bar\n') f.close() # hgrc isn't watched for changes yet, have to reopen self.client = hglib.open() paths = self.client.paths() self.assertEquals(len(paths), 1) self.assertEquals(paths[b('foo')], os.path.abspath('bar').encode('latin-1')) self.assertEquals(self.client.paths(b('foo')), os.path.abspath('bar').encode('latin-1'))
def main(): if len(sys.argv) > 2: print('Unknown parameter: {}'.format(sys.argv)) return -1 patch = b(sys.argv[1]) if len(sys.argv) == 2 else b('../patch.diff') if not os.path.isfile(patch): if patchy is not None: print('Try to ask Review Board for patch file') patchy.save(patch) if not os.path.isfile(patch): print('Patch file "{}" does not exists'.format(patch)) return -1 if 'BUILD_URL' not in os.environ: print('Warning: This script should be called on jenkins only') return -1 cfg = [ 'extensions.hgext.purge=', 'extensions.hgext.strip=', 'phases.new-commit=draft' ] client = hglib.open(configs=cfg) print('Revert workspace...') client.revert(b('.'), all=True, nobackup=True) print('Purge workspace...') client.rawcommand([b('purge'), b('--all')]) revs = len(client.log(revrange='secret() or draft()')) print('Found secret/draft changesets: {}'.format(revs)) if revs > 0: print('Strip secret and draft changesets...') client.rawcommand([ b('strip'), b('-r'), b('secret() or draft()'), b('--no-backup'), b('--force') ]) print('Import patch: {}'.format(patch)) client.import_([patch], user='******', date='today', message='jenkins patch review') return 0
def test_files(self): self.append('a', 'a\n') rev, node0 = self.client.commit(b('first'), addremove=True) self.append('b', 'b\n') rev, node1 = self.client.commit(b('second'), addremove=True) self.assertEquals(list(self.client.annotate([b('a'), b('b')])), [(b('0'), b('a')), (b('1'), b('b'))])
def test_basic_file(self): f = open('patch', 'wb') f.write(patch) f.close() # --no-commit self.client.import_([b('patch')], nocommit=True) self.assertEquals(open('a').read(), '1\n') self.client.update(clean=True) os.remove('a') self.client.import_([b('patch')]) self.assertEquals(self.client.cat([b('a')]), b('1\n'))
def test_basic(self): self.append('a', 'a') rev, node = self.client.commit(b('first'), addremove=True) d = { b('parent'): [(0, node[:12], b('tip'), b('first'))], b('branch'): b('default'), b('commit'): True, b('update'): 0 } if self.client.version >= (3, 5): d[b('phases')] = b('1 draft') self.assertEquals(self.client.summary(), d)
def attribution(self, file_paths): args = cmdbuilder(b('annotate'), *[b(p) for p in file_paths], template='json', date=True, user=True, cwd=self.client.root()) blame_json = self.client.rawcommand(args) file_blames = json.loads(blame_json) for file_blame in file_blames: self.handleFile(file_blame) return {'authors': self.users, 'blame': self.blame}
def test_basic(self): self.append('a', 'a') rev0 = self.client.commit(b('first'), addremove=True) self.client.branch(b('foo')) self.append('a', 'a') rev1 = self.client.commit(b('second')) branches = self.client.branches() expected = [] for r, n in (rev1, rev0): r = self.client.log(r)[0] expected.append((r.branch, int(r.rev), r.node[:12])) self.assertEquals(branches, expected)
def main(lang, reference_dir, localization_dir, blame, migrations, dry_run): """Run migrations and commit files with the result.""" changesets = convert_blame_to_changesets(blame) client = hglib.open(localization_dir) for migration in migrations: print('Running migration {}'.format(migration.__name__)) # For each migration create a new context. ctx = MergeContext(lang, reference_dir, localization_dir) try: # Add the migration spec. migration.migrate(ctx) except MigrationError as err: sys.exit(err.message) # Keep track of how many changesets we're committing. index = 0 for changeset in changesets: # Run the migration for the changeset. snapshot = ctx.serialize_changeset(changeset['changes']) # Did it change any files? if not snapshot: continue # Write serialized FTL files to disk. for path, content in snapshot.iteritems(): fullpath = os.path.join(localization_dir, path) print(' Writing to {}'.format(fullpath)) if not dry_run: fulldir = os.path.dirname(fullpath) if not os.path.isdir(fulldir): os.makedirs(fulldir) with open(fullpath, 'w') as f: f.write(content.encode('utf8')) f.close() index += 1 author = changeset['author'].encode('utf8') message = migration.migrate.__doc__.format(index=index, author=author) print(' Committing changeset: {}'.format(message)) if not dry_run: client.commit(b(message), user=b(author), addremove=True)
def test_basic(self): self.append('a', 'a') self.client.commit(b('first'), addremove=True) self.client.clone(dest=b('other')) other = hglib.open(b('other')) # broken in hg, doesn't return 1 if nothing to push #self.assertFalse(self.client.push('other')) self.append('a', 'a') self.client.commit(b('second')) self.assertTrue(self.client.push(b('other'))) self.assertEquals(self.client.log(), other.log())
def main(lang, reference_dir, localization_dir, blame, migrations, dry_run): """Run migrations and commit files with the result.""" changesets = convert_blame_to_changesets(blame) client = hglib.open(localization_dir) for migration in migrations: print('Running migration {}'.format(migration.__name__)) # For each migration create a new context. ctx = MergeContext(lang, reference_dir, localization_dir) # Add the migration spec. migration.migrate(ctx) # Keep track of how many changesets we're committing. index = 0 for changeset in changesets: # Run the migration. snapshot = ctx.serialize_changeset(changeset['changes']) # The current changeset didn't touch any of the translations # affected by the migration. if not snapshot: continue # Write serialized FTL files to disk. for path, content in snapshot.iteritems(): fullpath = os.path.join(localization_dir, path) print(' Writing to {}'.format(fullpath)) if not dry_run: with open(fullpath, 'w') as f: f.write(content.encode('utf8')) f.close() index += 1 author = changeset['author'].encode('utf8') message = migration.migrate.__doc__.format( index=index, author=author ) print(' Committing changeset: {}'.format(message)) if not dry_run: client.commit( b(message), user=b(author), addremove=True )
def test_basic(self): self.append('a', 'a') rev0, node0 = self.client.commit(b('first'), addremove=True) self.append('a', 'a') rev1, node1 = self.client.commit(b('second')) revs = self.client.log() revs.reverse() self.assertTrue(len(revs) == 2) self.assertEquals(revs[1].node, node1) self.assertEquals(revs[0], self.client.log(b('0'))[0]) self.assertEquals(self.client.log(), self.client.log(files=[b('a')])) self.assertEquals(self.client.log(), self.client.log(hidden=True))
def test_close_branch(self): self.append('a', 'a') rev0, node0 = self.client.commit(b('first'), addremove=True) self.client.branch(b('foo')) self.append('a', 'a') rev1, node1 = self.client.commit(b('second')) revclose = self.client.commit(b('closing foo'), closebranch=True) rev0, rev1, revclose = self.client.log([node0, node1, revclose[1]]) self.assertEquals(self.client.branches(), [(rev0.branch, int(rev0.rev), rev0.node[:12])]) self.assertEquals( self.client.branches(closed=True), [(revclose.branch, int(revclose.rev), revclose.node[:12]), (rev0.branch, int(rev0.rev), rev0.node[:12])])
def test_basic(self): self.client.close() self.client = None shutil.rmtree('.hg') self.client = hglib.init().open() self.assertTrue(self.client.root().endswith(b('test_init')))
def test_merge(self): self.append('a', '\n\n\n\nb') rev2, node2 = self.client.commit(b('third')) self.append('a', 'b') self.client.commit(b('fourth')) self.client.update(rev2) old = open('a').read() f = open('a', 'wb') f.write(b('a') + old.encode('latin-1')) f.close() u, m, r, ur = self.client.update() self.assertEquals(u, 0) self.assertEquals(m, 1) self.assertEquals(r, 0) self.assertEquals(ur, 0) self.assertEquals(self.client.status(), [(b('M'), b('a'))])
def test_basic(self): self.client.update(self.node0) self.append('b', 'a') rev, node2 = self.client.commit(b('new file'), addremove=True) self.client.merge(self.node1) rev, node = self.client.commit(b('merge')) diff = b("diff -r ") + node2[:12] + b(" -r ") + node[:12] + b(""" a --- a/a +++ b/a @@ -1,1 +1,1 @@ -a \ No newline at end of file +aa \ No newline at end of file """) self.assertEquals(diff, self.client.diff(change=node, nodates=True))
def test_basic(self): self.client.update(self.node0) self.append('a', 'b') self.append('b', 'a') rev, self.node3 = self.client.commit(b('third')) self.assertRaises(hglib.error.CommandError, self.client.merge, self.node1) self.assertRaises(hglib.error.CommandError, self.client.resolve, all=True) self.assertEquals([(b('U'), b('a')), (b('U'), b('b'))], self.client.resolve(listfiles=True)) self.client.resolve(b('a'), mark=True) self.assertEquals([(b('R'), b('a')), (b('U'), b('b'))], self.client.resolve(listfiles=True))
def test_date(self): self.append('a', 'a') now = datetime.datetime.now().replace(microsecond=0) rev0, node0 = self.client.commit( b('first'), addremove=True, date=now.isoformat(' ').encode('latin-1')) self.assertEquals(now, self.client.tip().date)
def test_merge_prompt_cb(self): self.client.update(self.node0) self.client.remove(b('a')) rev, node = self.client.commit(b('remove')) def cb(output): return b('c') self.client.merge(cb=cb) diff = b("diff -r ") + node[:12] + b(""" a --- /dev/null +++ b/a @@ -0,0 +1,1 @@ +aa \ No newline at end of file """) self.assertEquals(diff, self.client.diff(nodates=True))
def test_empty(self): d = { b('parent'): [(-1, b('000000000000'), b('tip'), None)], b('branch'): b('default'), b('commit'): True, b('update'): 0 } self.assertEquals(self.client.summary(), d)
def get_file_contents(self, path, revision=None): # Note: Should ideally use the library's "cat" function, but it # has a bug in that it doesn't provide a "cwd" argument. This implementation # is based on the library's with the fix implemented. from hglib.util import b, cmdbuilder if path is not None: path = b(str(path)) if revision is not None: revision = b(str(revision)) files = [path] args = cmdbuilder(b('cat'), r=revision, o=None, cwd=self.path, hidden=self.client.hidden, *files) print("hg " + ' '.join([x.decode() for x in args])) return BytesIO(self.client.rawcommand(args))
def test_merge_prompt_noninteractive(self): self.client.update(self.node0) self.client.remove(b('a')) rev, node = self.client.commit(b('remove')) if self.client.version >= (3, 7): self.assertRaises(hglib.error.CommandError, self.client.merge, cb=hglib.merge.handlers.noninteractive) else: self.client.merge(cb=hglib.merge.handlers.noninteractive) diff = b("diff -r ") + node[:12] + b(""" a --- /dev/null +++ b/a @@ -0,0 +1,1 @@ +aa \ No newline at end of file """) self.assertEquals(diff, self.client.diff(nodates=True))
def main(self): args = cmdbuilder( b('annotate'), self.client.root(), d=True, u=True, T='json') blame_json = ''.join(self.client.rawcommand(args)) file_blames = json.loads(blame_json) for file_blame in file_blames: self.handleFile(file_blame) return {'authors': self.users, 'blame': self.blame}
def test_tip(self): self.client.update(self.rev0) u, m, r, ur = self.client.update() self.assertEquals(u, 1) self.assertEquals(self.client.parents()[0].node, self.node1) self.client.update(self.rev0) self.append('a', 'b') rev2, node2 = self.client.commit(b('new head')) self.client.update(self.rev0) self.client.update() self.assertEquals(self.client.parents()[0].node, node2)
def pathto(self, f, cwd='.'): """ Return relative path to f. If cwd is given, use it as current working directory. The returned path uses os.sep as separator. f - file path with / as separator cwd - working directory with os.sep as separator """ return b( os.path.relpath( os.path.join( self.root().decode('latin-1'), *(f.split('/')) ), start=cwd ) )
def handleFile(self, leaf): try: parser = getParser(leaf) except UserWarning: return args = cmdbuilder(b('annotate'), d=True, u=True, T='json', *['path:' + leaf]) blame_json = ''.join(self.client.rawcommand(args)) blames = json.loads(blame_json) fname = os.path.join(self.client.root(), leaf) parser.readFile(fname) entities, emap = parser.parse() self.blame[leaf] = {} for e in entities: blines = blames[(e.value_position()[0] - 1):e.value_position(-1)[0]] blines.sort(key=lambda blame: -blame['date'][0]) # ignore timezone blame = blines[0] user = blame['user'] timestamp = blame['date'][0] # ignore timezone if user not in self.users: self.users.append(user) userid = self.users.index(user) self.blame[leaf][e.key] = [userid, timestamp]
def __init__(self, repo, changeid=b('')): """changeid is a revision number, node, or tag""" if changeid == b(''): changeid = b('.') self._repo = repo if isinstance(changeid, hglib.client.revision): cset = changeid elif changeid == -1: cset = _nullcset else: if isinstance(changeid, integertypes): changeid = b('rev(') + strtobytes(changeid) + b(')') notfound = False try: cset = self._repo.log(changeid) # hg bbf4f3dfd700 gave a null result for tip+1 if (cset and cset[0][1] == _nullcset[1] and cset[0][0] != _nullcset[0]): notfound = True except CommandError: notfound = True if notfound or not len(cset): raise ValueError('changeid %r not found in repo' % changeid) if len(cset) > 1: raise ValueError('changeid must yield a single changeset') cset = cset[0] self._rev, self._node, self._tags = cset[:3] self._branch, self._author, self._description, self._date = cset[3:] self._rev = int(self._rev) self._tags = self._tags.split() try: self._tags.remove(b('tip')) except ValueError: pass self._ignored = None self._clean = None
import hglib.client # Circular dependency. from hglib import util, templates from hglib.error import CommandError from hglib.util import b, strtobytes, integertypes _nullcset = [b('-1'), b('0000000000000000000000000000000000000000'), b(''), b(''), b(''), b(''), b('')] class changectx(object): """A changecontext object makes access to data related to a particular changeset convenient.""" def __init__(self, repo, changeid=b('')): """changeid is a revision number, node, or tag""" if changeid == b(''): changeid = b('.') self._repo = repo if isinstance(changeid, hglib.client.revision): cset = changeid elif changeid == -1: cset = _nullcset else: if isinstance(changeid, integertypes): changeid = b('rev(') + strtobytes(changeid) + b(')') notfound = False try: cset = self._repo.log(changeid) # hg bbf4f3dfd700 gave a null result for tip+1 if (cset and cset[0][1] == _nullcset[1] and cset[0][0] != _nullcset[0]): notfound = True
def hidden(self): """return True if the changeset is hidden, else False""" return bool(self._repo.log(revrange=self._node + b(' and hidden()'), hidden=True))
def children(self): """return contexts for each child changeset""" for c in self._repo.log(b('children(') + self._node + b(')')): yield changectx(self._repo, c)
def ancestors(self): for a in self._repo.log(b('ancestors(') + self._node + b(')')): yield changectx(self._repo, a)
def descendants(self): for d in self._repo.log(b('descendants(') + self._node + b(')')): yield changectx(self._repo, d)
def ancestor(self, c2): """ return the ancestor context of self and c2 """ return changectx(self._repo, b('ancestor(') + self + b(', ') + c2 + b(')'))
def abort(size, output): """ Abort the merge if a prompt appears. """ return b('')
def _parsestatus(self, stat): d = dict((c, []) for c in (b('M'), b('A'), b('R'), b('!'), b('?'), b('I'), b('C'), b(' '))) for k, path in stat: d[k].append(path) return (d[b('M')], d[b('A')], d[b('R')], d[b('!')], d[b('?')], d[b('I')], d[b('C')])
from hglib.util import b changeset = b('{rev}\\0{node}\\0{tags}\\0{branch}\\0{author}' '\\0{desc}\\0{date}\\0')