diff --git a/presubmit_support.py b/presubmit_support.py index f0d5228c3..6e897ec5a 100755 --- a/presubmit_support.py +++ b/presubmit_support.py @@ -1336,6 +1336,10 @@ class Change(object): """Convenience function.""" return [af.AbsoluteLocalPath() for af in self.AffectedFiles()] + def ListSubmodules(self): + """Returns submodule paths for current change's repo.""" + return scm.GIT.ListSubmodules(self.change.RepositoryRoot()) + def RightHandSideLines(self): """An iterator over all text lines in 'new' version of changed files. diff --git a/scm.py b/scm.py index 40833613a..022b18bd3 100644 --- a/scm.py +++ b/scm.py @@ -455,6 +455,17 @@ class GIT(object): return VERSIONED_SUBMODULE return VERSIONED_DIR + @staticmethod + def ListSubmodules(repo_root): + # type: (str) -> Collection[str] + """Returns the list of submodule paths for the given repo.""" + if not os.path.exists(os.path.join(repo_root, '.gitmodules')): + return [] + config_output = GIT.Capture( + ['git', 'config', '--file', '.gitmodules', '--get-regexp', 'path'], + cwd=repo_root) + return [line.split()[-1] for line in config_output.splitlines()] + @staticmethod def CleanupDir(cwd, relative_dir): """Cleans up untracked file inside |relative_dir|.""" diff --git a/tests/scm_unittest.py b/tests/scm_unittest.py index 81b4d6e68..b46b387de 100755 --- a/tests/scm_unittest.py +++ b/tests/scm_unittest.py @@ -132,6 +132,18 @@ class GitWrapperTestCase(unittest.TestCase): actual_state = scm.GIT.IsVersioned('cwd', 'dir') self.assertEqual(actual_state, scm.VERSIONED_DIR) + @mock.patch('scm.GIT.Capture') + @mock.patch('os.path.exists', return_value=True) + def testListSubmodules(self, mockExists, mockCapture): + mockCapture.return_value = ( + 'submodule.submodulename.path foo/path/script' + '\nsubmodule.submodule2name.path foo/path/script2') + actual_list = scm.GIT.ListSubmodules('root') + self.assertEqual(actual_list, ['foo/path/script', 'foo/path/script2']) + + def testListSubmodules_missing(self): + self.assertEqual(scm.GIT.ListSubmodules('root'), []) + class RealGitTest(fake_repos.FakeReposTestBase): def setUp(self):