diff --git a/git_browse/browse.py b/git_browse/browse.py index 08673cd..80c7886 100755 --- a/git_browse/browse.py +++ b/git_browse/browse.py @@ -36,12 +36,21 @@ def get_url(self, focus_object): self.user, self.repository ) + if focus_object.is_commit_hash(): + return self.commit_hash_url(repository_url, focus_object) if focus_object.is_root(): return self.root_url(repository_url, focus_object) if focus_object.is_directory(): return self.directory_url(repository_url, focus_object) return self.file_url(repository_url, focus_object) + def commit_hash_url(self, repository_url, focus_hash): + repository_url = "%s/commit/%s" % ( + repository_url, + focus_hash.commit_hash + ) + return repository_url + def root_url(self, repository_url, focus_object): return repository_url @@ -69,10 +78,13 @@ def create(url_regex_match): return UberPhabricatorHost(None, None) def get_url(self, focus_object): - path = focus_object.path - # arc browse requires an object, provide the root object by default - if focus_object.is_root(): - path = '.' + if focus_object.is_commit_hash(): + path = focus_object.commit_hash + else: + path = focus_object.path + # arc browse requires an object, provide the root object by default + if focus_object.is_root(): + path = '.' command = ['arc', 'browse'] if path: command.append(path) @@ -90,6 +102,9 @@ class FocusObject(object): def __init__(self, path): self.path = path + def is_commit_hash(self): + return False + def is_root(self): return self.path == os.sep @@ -101,6 +116,14 @@ def default(): return FocusObject(os.sep) +class FocusHash(object): + def __init__(self, commit_hash): + self.commit_hash = commit_hash + + def is_commit_hash(self): + return True + + def get_repository_root(): current_directory = '' new_directory = os.getcwd() @@ -166,6 +189,9 @@ def get_focus_object(sys_argv, path): object_path = os.path.join(directory, focus_object[0]) object_path = os.path.normpath(object_path) if not os.path.exists(object_path): + focus_hash = get_commit_hash(focus_object[0]) + if focus_hash: + return focus_hash error = "specified file does not exist: %s" % object_path raise FileNotFoundError(error) is_dir = os.path.isdir(object_path) and object_path[-1] != os.sep @@ -175,6 +201,21 @@ def get_focus_object(sys_argv, path): return FocusObject(object_path) +def get_commit_hash(focus_object): + command = ['git', 'show', focus_object] + process = subprocess.Popen( + command, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + universal_newlines=True + ) + out, err = process.communicate() + if process.returncode != 0: + return None + commit_hash = out.split("\n")[0].split(" ")[1] + return FocusHash(commit_hash) + + def open_url(url): print(url) if url.__class__ is list: diff --git a/git_browse/tests/test.py b/git_browse/tests/test.py index a96ba45..75ae39b 100644 --- a/git_browse/tests/test.py +++ b/git_browse/tests/test.py @@ -15,6 +15,7 @@ def setUp(self): self.github_host = browse.GithubHost('albertyw', 'git-browse') self.repository_url = 'https://github.com/albertyw/git-browse' self.focus_object = browse.FocusObject('/') + self.focus_hash = browse.FocusHash('v2.0.0') def test_init(self): host = browse.GithubHost('user', 'repository') @@ -48,6 +49,16 @@ def test_file_url(self): 'https://github.com/albertyw/git-browse/blob/master/README.md' ) + def test_commit_hash_url(self): + url = self.github_host.commit_hash_url( + self.repository_url, + self.focus_hash + ) + self.assertEqual( + url, + 'https://github.com/albertyw/git-browse/commit/v2.0.0' + ) + class FocusObject(unittest.TestCase): def test_init(self): @@ -75,6 +86,16 @@ def test_default(self): self.assertTrue(obj.is_root()) +class FocusHash(unittest.TestCase): + def test_init(self): + obj = browse.FocusHash('abcde') + self.assertEqual(obj.commit_hash, 'abcde') + + def test_is_commit_hash(self): + obj = browse.FocusHash('abcde') + self.assertTrue(obj.is_commit_hash()) + + class GetRepositoryRoot(unittest.TestCase): def test_get(self): os.chdir(BASE_DIRECTORY) @@ -179,12 +200,30 @@ def test_directory_focus_object(self): self.assertFalse(focus_object.is_root()) self.assertTrue(focus_object.is_directory()) + def test_get_focus_hash(self): + sys_argv = ['asdf', 'v2.0.0'] + focus_object = browse.get_focus_object(sys_argv, os.getcwd()) + self.assertTrue(focus_object.__class__ is browse.FocusHash) + def test_nonexistend_focus_object(self): sys_argv = ['asdf', 'asdf'] with self.assertRaises(FileNotFoundError): browse.get_focus_object(sys_argv, os.getcwd()) +class TestGetCommitHash(unittest.TestCase): + def test_get_unknown_hash(self): + focus_object = '!@#$' + focus_hash = browse.get_commit_hash(focus_object) + self.assertEqual(focus_hash, None) + + def test_get_hash(self): + focus_object = 'v2.0.0' + focus_hash = browse.get_commit_hash(focus_object) + self.assertTrue(focus_hash.__class__ is browse.FocusHash) + self.assertTrue(focus_hash.commit_hash) + + class TestOpenURL(unittest.TestCase): @patch("builtins.print", autospec=True) def test_open_url(self, mock_print): diff --git a/git_browse/tests/test_git_urls.py b/git_browse/tests/test_git_urls.py index e570b67..75d62e3 100644 --- a/git_browse/tests/test_git_urls.py +++ b/git_browse/tests/test_git_urls.py @@ -49,6 +49,12 @@ TEST_DIR, 'https://github.com/albertyw/git-browse/tree/master/testdir/' ), + ( + 'git@github.com:albertyw/git-browse', + 'v2.0.0', + 'https://github.com/albertyw/git-browse/commit/' + + 'f5631b4c423f2fa5c9c4b64853607f1727d4b7a9' + ), ( 'gitolite@code.uber.internal:a/b', None, @@ -63,6 +69,11 @@ 'gitolite@code.uber.internal:a/b', TEST_DIR, ['arc', 'browse', TEST_DIR+'/'] + ), + ( + 'gitolite@code.uber.internal:a/b', + 'v2.0.0', + ['arc', 'browse', 'f5631b4c423f2fa5c9c4b64853607f1727d4b7a9'] ) ]