diff --git a/gitc_utils.py b/gitc_utils.py index dd38f890..0f3e1818 100644 --- a/gitc_utils.py +++ b/gitc_utils.py @@ -24,23 +24,13 @@ import git_command import git_config import wrapper -GITC_FS_ROOT_DIR = '/gitc/manifest-rw/' NUM_BATCH_RETRIEVE_REVISIONID = 300 def get_gitc_manifest_dir(): return wrapper.Wrapper().get_gitc_manifest_dir() def parse_clientdir(gitc_fs_path): - """Parse a path in the GITC FS and return its client name. - - @param gitc_fs_path: A subdirectory path within the GITC_FS_ROOT_DIR. - - @returns: The GITC client name - """ - if (gitc_fs_path == GITC_FS_ROOT_DIR or - not gitc_fs_path.startswith(GITC_FS_ROOT_DIR)): - return None - return gitc_fs_path.split(GITC_FS_ROOT_DIR)[1].split('/')[0] + return wrapper.Wrapper().gitc_parse_clientdir(gitc_fs_path) def _set_project_revisions(projects): """Sets the revisionExpr for a list of projects. diff --git a/repo b/repo index 502bb324..d1c5427f 100755 --- a/repo +++ b/repo @@ -109,6 +109,7 @@ S_manifests = 'manifests' # special manifest repository REPO_MAIN = S_repo + '/main.py' # main script MIN_PYTHON_VERSION = (2, 6) # minimum supported python version GITC_CONFIG_FILE = '/gitc/.config' +GITC_FS_ROOT_DIR = '/gitc/manifest-rw/' import errno @@ -221,7 +222,7 @@ def _GitcInitOptions(init_optparse): help='Optional manifest file to use for this GITC client.') g.add_option('-c', '--gitc-client', dest='gitc_client', - help='The name for the new gitc_client instance.') + help='The name of the gitc_client instance to create or modify.') _gitc_manifest_dir = None def get_gitc_manifest_dir(): @@ -238,6 +239,28 @@ def get_gitc_manifest_dir(): pass return _gitc_manifest_dir +def gitc_parse_clientdir(gitc_fs_path): + """Parse a path in the GITC FS and return its client name. + + @param gitc_fs_path: A subdirectory path within the GITC_FS_ROOT_DIR. + + @returns: The GITC client name + """ + if gitc_fs_path == GITC_FS_ROOT_DIR: + return None + if not gitc_fs_path.startswith(GITC_FS_ROOT_DIR): + manifest_dir = get_gitc_manifest_dir() + if manifest_dir == '': + return None + if manifest_dir[-1] != '/': + manifest_dir += '/' + if gitc_fs_path == manifest_dir: + return None + if not gitc_fs_path.startswith(manifest_dir): + return None + return gitc_fs_path.split(manifest_dir)[1].split('/')[0] + return gitc_fs_path.split(GITC_FS_ROOT_DIR)[1].split('/')[0] + class CloneFailure(Exception): """Indicate the remote clone of repo itself failed. """ @@ -276,10 +299,13 @@ def _Init(args, gitc_init=False): _print('fatal: GITC filesystem is not available. Exiting...', file=sys.stderr) sys.exit(1) - if not opt.gitc_client: + gitc_client = opt.gitc_client + if not gitc_client: + gitc_client = gitc_parse_clientdir(os.getcwd()) + if not gitc_client: _print('fatal: GITC client (-c) is required.', file=sys.stderr) sys.exit(1) - client_dir = os.path.join(gitc_manifest_dir, opt.gitc_client) + client_dir = os.path.join(gitc_manifest_dir, gitc_client) if not os.path.exists(client_dir): os.makedirs(client_dir) os.chdir(client_dir) @@ -772,9 +798,13 @@ def _SetDefaultsTo(gitdir): def main(orig_args): - repo_main, rel_repo_dir = _FindRepo() cmd, opt, args = _ParseArguments(orig_args) + repo_main, rel_repo_dir = None, None + # Don't use the local repo copy, make sure to switch to the gitc client first. + if cmd != 'gitc-init': + repo_main, rel_repo_dir = _FindRepo() + wrapper_path = os.path.abspath(__file__) my_main, my_git = _RunSelf(wrapper_path) diff --git a/subcmds/gitc_init.py b/subcmds/gitc_init.py index 4f9d7344..2726eaec 100644 --- a/subcmds/gitc_init.py +++ b/subcmds/gitc_init.py @@ -21,6 +21,7 @@ import gitc_utils from command import GitcAvailableCommand from manifest_xml import GitcManifest from subcmds import init +import wrapper class GitcInit(init.Init, GitcAvailableCommand): @@ -55,18 +56,15 @@ use for this GITC client. help='Optional manifest file to use for this GITC client.') g.add_option('-c', '--gitc-client', dest='gitc_client', - help='The name for the new gitc_client instance.') + help='The name of the gitc_client instance to create or modify.') def Execute(self, opt, args): - if not opt.gitc_client: - print('fatal: gitc client (-c) is required', file=sys.stderr) + gitc_client = gitc_utils.parse_clientdir(os.getcwd()) + if not gitc_client or (opt.gitc_client and gitc_client != opt.gitc_client): + print('fatal: Please update your repo command. See go/gitc for instructions.', file=sys.stderr) sys.exit(1) self.client_dir = os.path.join(gitc_utils.get_gitc_manifest_dir(), - opt.gitc_client) - if not os.path.exists(gitc_utils.get_gitc_manifest_dir()): - os.makedirs(gitc_utils.get_gitc_manifest_dir()) - if not os.path.exists(self.client_dir): - os.mkdir(self.client_dir) + gitc_client) super(GitcInit, self).Execute(opt, args) manifest_file = self.manifest.manifestFile @@ -77,8 +75,8 @@ use for this GITC client. sys.exit(1) manifest_file = opt.manifest_file - manifest = GitcManifest(self.repodir, opt.gitc_client) + manifest = GitcManifest(self.repodir, gitc_client) manifest.Override(manifest_file) gitc_utils.generate_gitc_manifest(None, manifest) print('Please run `cd %s` to view your GITC client.' % - os.path.join(gitc_utils.GITC_FS_ROOT_DIR, opt.gitc_client)) + os.path.join(wrapper.Wrapper().GITC_FS_ROOT_DIR, gitc_client)) diff --git a/tests/fixtures/gitc_config b/tests/fixtures/gitc_config new file mode 100644 index 00000000..a7f3d1c9 --- /dev/null +++ b/tests/fixtures/gitc_config @@ -0,0 +1 @@ +gitc_dir=/test/usr/local/google/gitc diff --git a/tests/test_wrapper.py b/tests/test_wrapper.py new file mode 100644 index 00000000..fb32e38a --- /dev/null +++ b/tests/test_wrapper.py @@ -0,0 +1,75 @@ +# +# Copyright (C) 2015 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +import unittest + +import wrapper + +def fixture(*paths): + """Return a path relative to tests/fixtures. + """ + return os.path.join(os.path.dirname(__file__), 'fixtures', *paths) + +class RepoWrapperUnitTest(unittest.TestCase): + """Tests helper functions in the repo wrapper + """ + def setUp(self): + """Load the wrapper module every time + """ + wrapper._wrapper_module = None + self.wrapper = wrapper.Wrapper() + + def test_get_gitc_manifest_dir_no_gitc(self): + """ + Test reading a missing gitc config file + """ + self.wrapper.GITC_CONFIG_FILE = fixture('missing_gitc_config') + val = self.wrapper.get_gitc_manifest_dir() + self.assertEqual(val, '') + + def test_get_gitc_manifest_dir(self): + """ + Test reading the gitc config file and parsing the directory + """ + self.wrapper.GITC_CONFIG_FILE = fixture('gitc_config') + val = self.wrapper.get_gitc_manifest_dir() + self.assertEqual(val, '/test/usr/local/google/gitc') + + def test_gitc_parse_clientdir_no_gitc(self): + """ + Test parsing the gitc clientdir without gitc running + """ + self.wrapper.GITC_CONFIG_FILE = fixture('missing_gitc_config') + self.assertEqual(self.wrapper.gitc_parse_clientdir('/something'), None) + self.assertEqual(self.wrapper.gitc_parse_clientdir('/gitc/manifest-rw/test'), 'test') + + def test_gitc_parse_clientdir(self): + """ + Test parsing the gitc clientdir + """ + self.wrapper.GITC_CONFIG_FILE = fixture('gitc_config') + self.assertEqual(self.wrapper.gitc_parse_clientdir('/something'), None) + self.assertEqual(self.wrapper.gitc_parse_clientdir('/gitc/manifest-rw/test'), 'test') + self.assertEqual(self.wrapper.gitc_parse_clientdir('/gitc/manifest-rw/test/'), 'test') + self.assertEqual(self.wrapper.gitc_parse_clientdir('/gitc/manifest-rw/test/extra'), 'test') + self.assertEqual(self.wrapper.gitc_parse_clientdir('/test/usr/local/google/gitc/test'), 'test') + self.assertEqual(self.wrapper.gitc_parse_clientdir('/test/usr/local/google/gitc/test/'), 'test') + self.assertEqual(self.wrapper.gitc_parse_clientdir('/test/usr/local/google/gitc/test/extra'), 'test') + self.assertEqual(self.wrapper.gitc_parse_clientdir('/gitc/manifest-rw/'), None) + self.assertEqual(self.wrapper.gitc_parse_clientdir('/test/usr/local/google/gitc/'), None) + +if __name__ == '__main__': + unittest.main()