diff --git a/presubmit_canned_checks.py b/presubmit_canned_checks.py index 497a4e739a..328d1ef194 100644 --- a/presubmit_canned_checks.py +++ b/presubmit_canned_checks.py @@ -1131,3 +1131,57 @@ def CheckGNFormatted(input_api, output_api): # It's just a warning, so ignore other types of failures assuming they'll be # caught elsewhere. return warnings + + +def CheckCIPDManifest(input_api, output_api, path=None, content=None): + """Verifies that a CIPD ensure file manifest is valid against all platforms. + + Exactly one of "path" or "content" must be provided. An assertion will occur + if neither or both are provided. + + Args: + path (str): If provided, the filesystem path to the manifest to verify. + content (str): If provided, the raw content of the manifest to veirfy. + """ + cipd_bin = 'cipd' if not input_api.is_windows else 'cipd.bat' + cmd = [cipd_bin, 'ensure-file-verify'] + kwargs = {} + + if input_api.is_windows: + # Needs to be able to resolve "cipd.bat". + kwargs['shell'] = True + + if input_api.verbose: + cmd += ['-log-level', 'debug'] + + if path: + assert content is None, 'Cannot provide both "path" and "content".' + cmd += ['-ensure-file', path] + elif content: + assert path is None, 'Cannot provide both "path" and "content".' + cmd += ['-ensure-file=-'] + kwargs['stdin'] = content + else: + raise Exception('Exactly one of "path" or "content" must be provided.') + + return input_api.Command( + 'Check CIPD manifest', + cmd, + kwargs, + output_api.PresubmitError) + + +def CheckCIPDPackages(input_api, output_api, platforms, packages): + """Verifies that all named CIPD packages can be resolved against all supplied + platforms. + + Args: + platforms (list): List of CIPD platforms to verify. + packages (dict): Mapping of package name to version. + """ + manifest = [] + for p in platforms: + manifest.append('$VerifiedPlatform %s' % (p,)) + for k, v in packages.iteritems(): + manifest.append('%s %s' % (k, v)) + return CheckCIPDManifest(input_api, output_api, content='\n'.join(manifest)) diff --git a/presubmit_support.py b/presubmit_support.py index 3bd79fdda8..a082cfd242 100755 --- a/presubmit_support.py +++ b/presubmit_support.py @@ -454,6 +454,7 @@ class InputApi(object): fopen=file, os_path=self.os_path) self.owners_finder = owners_finder.OwnersFinder self.verbose = verbose + self.is_windows = sys.platform == 'win32' self.Command = CommandData # Replace and as headers that need to be included diff --git a/tests/presubmit_unittest.py b/tests/presubmit_unittest.py index 00aeb64148..3c95eccf66 100755 --- a/tests/presubmit_unittest.py +++ b/tests/presubmit_unittest.py @@ -973,6 +973,7 @@ class InputApiUnittest(PresubmitTestsBase): 'glob', 'host_url', 'is_committing', + 'is_windows', 'json', 'logging', 'marshal', @@ -1660,6 +1661,7 @@ class CannedChecksUnittest(PresubmitTestsBase): return 'foo' input_api.subprocess.CalledProcessError = fake_CalledProcessError input_api.verbose = False + input_api.is_windows = False input_api.change = change input_api.host_url = 'http://localhost' @@ -1705,6 +1707,7 @@ class CannedChecksUnittest(PresubmitTestsBase): 'GetCodereviewOwnerAndReviewers', 'GetPythonUnitTests', 'GetPylint', 'GetUnitTests', 'GetUnitTestsInDirectory', 'GetUnitTestsRecursively', + 'CheckCIPDManifest', 'CheckCIPDPackages', ] # If this test fails, you should add the relevant test. self.compareMembers(presubmit_canned_checks, members) @@ -2729,6 +2732,49 @@ class CannedChecksUnittest(PresubmitTestsBase): 'Found line ending with white spaces in:', results[0]._message) self.checkstdout('') + def testCheckCIPDManifest_file(self): + input_api = self.MockInputApi(None, False) + self.mox.ReplayAll() + + command = presubmit_canned_checks.CheckCIPDManifest( + input_api, presubmit.OutputApi, path='/path/to/foo') + self.assertEquals(command.cmd, + ['cipd', 'ensure-file-verify', '-ensure-file', '/path/to/foo']) + self.assertEquals(command.kwargs, {}) + + def testCheckCIPDManifest_content(self): + input_api = self.MockInputApi(None, False) + input_api.verbose = True + self.mox.ReplayAll() + + command = presubmit_canned_checks.CheckCIPDManifest( + input_api, presubmit.OutputApi, content='manifest_content') + self.assertEquals(command.cmd, + ['cipd', 'ensure-file-verify', '-log-level', 'debug', '-ensure-file=-']) + self.assertEquals(command.kwargs, {'stdin': 'manifest_content'}) + + def testCheckCIPDPackages(self): + content = '\n'.join([ + '$VerifiedPlatform foo-bar', + '$VerifiedPlatform baz-qux', + 'foo/bar/baz/${platform} version:ohaithere', + 'qux version:kthxbye', + ]) + + input_api = self.MockInputApi(None, False) + self.mox.ReplayAll() + + command = presubmit_canned_checks.CheckCIPDPackages( + input_api, presubmit.OutputApi, + platforms=['foo-bar', 'baz-qux'], + packages={ + 'foo/bar/baz/${platform}': 'version:ohaithere', + 'qux': 'version:kthxbye', + }) + self.assertEquals(command.cmd, + ['cipd', 'ensure-file-verify', '-ensure-file=-']) + self.assertEquals(command.kwargs, {'stdin': content}) + if __name__ == '__main__': import unittest