diff --git a/gclient.py b/gclient.py index ab3deeda2..e8e496ef0 100755 --- a/gclient.py +++ b/gclient.py @@ -2936,6 +2936,48 @@ def CMDrevinfo(parser, args): return 0 +def CMDgetdep(parser, args): + """Gets revision information and variable values from a DEPS file.""" + parser.add_option('--var', action='append', + dest='vars', metavar='VAR', default=[], + help='Gets the value of a given variable.') + parser.add_option('-r', '--revision', action='append', + dest='revisions', metavar='DEP', default=[], + help='Gets the revision/version for the given dependency. ' + 'If it is a git dependency, dep must be a path. If it ' + 'is a CIPD dependency, dep must be of the form ' + 'path:package.') + parser.add_option('--deps-file', default='DEPS', + # TODO(ehmaldonado): Try to find the DEPS file pointed by + # .gclient first. + help='The DEPS file to be edited. Defaults to the DEPS ' + 'file in the current directory.') + (options, args) = parser.parse_args(args) + + if not os.path.isfile(options.deps_file): + raise gclient_utils.Error( + 'DEPS file %s does not exist.' % options.deps_file) + with open(options.deps_file) as f: + contents = f.read() + local_scope = gclient_eval.Parse( + contents, expand_vars=True, validate_syntax=True, + filename=options.deps_file) + + for var in options.vars: + print(gclient_eval.GetVar(local_scope, var)) + + for name in options.revisions: + if ':' in name: + name, _, package = name.partition(':') + if not name or not package: + parser.error( + 'Wrong CIPD format: %s:%s should be of the form path:pkg.' + % (name, package)) + print(gclient_eval.GetCIPD(local_scope, name, package)) + else: + print(gclient_eval.GetRevision(local_scope, name)) + + def CMDsetdep(parser, args): """Modifies dependency revisions and variable values in a DEPS file""" parser.add_option('--var', action='append', diff --git a/gclient_eval.py b/gclient_eval.py index aac3535f0..64fbf133e 100644 --- a/gclient_eval.py +++ b/gclient_eval.py @@ -690,3 +690,49 @@ def SetRevision(gclient_dict, dep_name, new_revision): _UpdateRevision(gclient_dict['deps'][dep_name], 'url', new_revision) else: _UpdateRevision(gclient_dict['deps'], dep_name, new_revision) + + +def GetVar(gclient_dict, var_name): + if 'vars' not in gclient_dict or var_name not in gclient_dict['vars']: + raise KeyError( + "Could not find any variable called %s." % var_name) + + return gclient_dict['vars'][var_name] + + +def GetCIPD(gclient_dict, dep_name, package_name): + if 'deps' not in gclient_dict or dep_name not in gclient_dict['deps']: + raise KeyError( + "Could not find any dependency called %s." % dep_name) + + # Find the package with the given name + packages = [ + package + for package in gclient_dict['deps'][dep_name]['packages'] + if package['package'] == package_name + ] + if len(packages) != 1: + raise ValueError( + "There must be exactly one package with the given name (%s), " + "%s were found." % (package_name, len(packages))) + + return packages[0]['version'][len('version:'):] + + +def GetRevision(gclient_dict, dep_name): + if 'deps' not in gclient_dict or dep_name not in gclient_dict['deps']: + raise KeyError( + "Could not find any dependency called %s." % dep_name) + + dep = gclient_dict['deps'][dep_name] + if dep is None: + return None + elif isinstance(dep, basestring): + _, _, revision = dep.partition('@') + return revision or None + elif isinstance(dep, collections.Mapping) and 'url' in dep: + _, _, revision = dep['url'].partition('@') + return revision or None + else: + raise ValueError( + '%s is not a valid git dependency.' % dep_name) diff --git a/tests/gclient_eval_unittest.py b/tests/gclient_eval_unittest.py index c7896b362..f341c98e5 100755 --- a/tests/gclient_eval_unittest.py +++ b/tests/gclient_eval_unittest.py @@ -236,7 +236,7 @@ class EvaluateConditionTest(unittest.TestCase): str(cm.exception)) -class AddVarTest(unittest.TestCase): +class VarTest(unittest.TestCase): def assert_adds_var(self, before, after): local_scope = gclient_eval.Exec('\n'.join(before)) gclient_eval.AddVar(local_scope, 'baz', 'lemur') @@ -276,7 +276,26 @@ class AddVarTest(unittest.TestCase): '}', ])) - def test_preserves_formatting(self): + def test_gets_and_sets_var(self): + local_scope = gclient_eval.Exec('\n'.join([ + 'vars = {', + ' "foo": "bar",', + '}', + ])) + + result = gclient_eval.GetVar(local_scope, 'foo') + self.assertEqual(result, "bar") + + gclient_eval.SetVar(local_scope, 'foo', 'baz') + result = gclient_eval.RenderDEPSFile(local_scope) + + self.assertEqual(result, '\n'.join([ + 'vars = {', + ' "foo": "baz",', + '}', + ])) + + def test_add_preserves_formatting(self): before = [ '# Copyright stuff', '# some initial comments', @@ -310,25 +329,7 @@ class AddVarTest(unittest.TestCase): ] self.assert_adds_var(before, after) - -class SetVarTest(unittest.TestCase): - def test_sets_var(self): - local_scope = gclient_eval.Exec('\n'.join([ - 'vars = {', - ' "foo": "bar",', - '}', - ])) - - gclient_eval.SetVar(local_scope, 'foo', 'baz') - result = gclient_eval.RenderDEPSFile(local_scope) - - self.assertEqual(result, '\n'.join([ - 'vars = {', - ' "foo": "baz",', - '}', - ])) - - def test_preserves_formatting(self): + def test_set_preserves_formatting(self): local_scope = gclient_eval.Exec('\n'.join([ 'vars = {', ' # Comment with trailing space ', @@ -347,8 +348,8 @@ class SetVarTest(unittest.TestCase): ])) -class SetCipdTest(unittest.TestCase): - def test_sets_cipd(self): +class CipdTest(unittest.TestCase): + def test_gets_and_sets_cipd(self): local_scope = gclient_eval.Exec('\n'.join([ 'deps = {', ' "src/cipd/package": {', @@ -368,6 +369,10 @@ class SetCipdTest(unittest.TestCase): '}', ])) + result = gclient_eval.GetCIPD( + local_scope, 'src/cipd/package', 'another/cipd/package') + self.assertEqual(result, '5678') + gclient_eval.SetCIPD( local_scope, 'src/cipd/package', 'another/cipd/package', '6.789') result = gclient_eval.RenderDEPSFile(local_scope) @@ -392,13 +397,17 @@ class SetCipdTest(unittest.TestCase): ])) -class SetRevisionTest(unittest.TestCase): - def assert_changes_revision(self, before, after): +class RevisionTest(unittest.TestCase): + def assert_gets_and_sets_revision(self, before, after, rev_before='deadbeef'): local_scope = gclient_eval.Exec('\n'.join(before)) + + result = gclient_eval.GetRevision(local_scope, 'src/dep') + self.assertEqual(result, rev_before) + gclient_eval.SetRevision(local_scope, 'src/dep', 'deadfeed') self.assertEqual('\n'.join(after), gclient_eval.RenderDEPSFile(local_scope)) - def test_sets_revision(self): + def test_revision(self): before = [ 'deps = {', ' "src/dep": "https://example.com/dep.git@deadbeef",', @@ -409,9 +418,9 @@ class SetRevisionTest(unittest.TestCase): ' "src/dep": "https://example.com/dep.git@deadfeed",', '}', ] - self.assert_changes_revision(before, after) + self.assert_gets_and_sets_revision(before, after) - def test_sets_revision_new_line(self): + def test_revision_new_line(self): before = [ 'deps = {', ' "src/dep": "https://example.com/dep.git@"', @@ -424,9 +433,9 @@ class SetRevisionTest(unittest.TestCase): ' + "deadfeed",', '}', ] - self.assert_changes_revision(before, after) + self.assert_gets_and_sets_revision(before, after) - def test_sets_revision_inside_dict(self): + def test_revision_inside_dict(self): before = [ 'deps = {', ' "src/dep": {', @@ -443,7 +452,7 @@ class SetRevisionTest(unittest.TestCase): ' },', '}', ] - self.assert_changes_revision(before, after) + self.assert_gets_and_sets_revision(before, after) def test_follows_var_braces(self): before = [ @@ -462,7 +471,7 @@ class SetRevisionTest(unittest.TestCase): ' "src/dep": "https://example.com/dep.git@{dep_revision}",', '}', ] - self.assert_changes_revision(before, after) + self.assert_gets_and_sets_revision(before, after) def test_follows_var_braces_newline(self): before = [ @@ -483,7 +492,7 @@ class SetRevisionTest(unittest.TestCase): ' + "@{dep_revision}",', '}', ] - self.assert_changes_revision(before, after) + self.assert_gets_and_sets_revision(before, after) def test_follows_var_function(self): before = [ @@ -502,7 +511,7 @@ class SetRevisionTest(unittest.TestCase): ' "src/dep": "https://example.com/dep.git@" + Var("dep_revision"),', '}', ] - self.assert_changes_revision(before, after) + self.assert_gets_and_sets_revision(before, after) def test_pins_revision(self): before = [ @@ -515,7 +524,7 @@ class SetRevisionTest(unittest.TestCase): ' "src/dep": "https://example.com/dep.git@deadfeed",', '}', ] - self.assert_changes_revision(before, after) + self.assert_gets_and_sets_revision(before, after, rev_before=None) def test_preserves_formatting(self): @@ -545,7 +554,7 @@ class SetRevisionTest(unittest.TestCase): ' },', '}', ] - self.assert_changes_revision(before, after) + self.assert_gets_and_sets_revision(before, after) class ParseTest(unittest.TestCase):