diff --git a/skipper/git.py b/skipper/git.py index 5098114..2766db7 100644 --- a/skipper/git.py +++ b/skipper/git.py @@ -1,10 +1,10 @@ -import os.path import logging +import os import subprocess def get_hash(short=False): - if not os.path.exists('.git'): + if not is_git_repository(): logging.warning('*** Not working in a git repository ***') return 'none' @@ -22,3 +22,10 @@ def get_hash(short=False): def uncommitted_changes(): """Return True is there are uncommitted changes.""" return subprocess.call(['git', 'diff', '--quiet', 'HEAD']) != 0 + + +def is_git_repository(): + if os.path.exists('.git'): + return True + command = ['git', 'rev-parse', '--is-inside-work-tree'] + return subprocess.call(command, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) == 0 diff --git a/tests/test_git.py b/tests/test_git.py index 2eed711..1f3a40a 100644 --- a/tests/test_git.py +++ b/tests/test_git.py @@ -1,3 +1,4 @@ +import subprocess import unittest import mock from skipper import git @@ -9,33 +10,49 @@ class TestGit(unittest.TestCase): @mock.patch('subprocess.check_output', return_value=GIT_HASH_FULL) - @mock.patch('os.path.exists', return_value=True) - def test_get_hash_with_default_argument(self, exists_mock, check_output_mock): + @mock.patch('skipper.git.is_git_repository', return_value=True) + def test_get_hash_with_default_argument(self, is_git_repository_mock, check_output_mock): git_hash = git.get_hash() - exists_mock.assert_called_once_with('.git') + is_git_repository_mock.assert_called_once() check_output_mock.assert_called_once_with(['git', 'rev-parse', 'HEAD']) self.assertEqual(git_hash, GIT_HASH_FULL.decode('utf-8')) @mock.patch('subprocess.check_output', return_value=GIT_HASH_FULL) - @mock.patch('os.path.exists', return_value=True) - def test_get_full_hash(self, exists_mock, check_output_mock): + @mock.patch('skipper.git.is_git_repository', return_value=True) + def test_get_full_hash(self, is_git_repository_mock, check_output_mock): git_hash = git.get_hash(short=False) - exists_mock.assert_called_once_with('.git') + is_git_repository_mock.assert_called_once() check_output_mock.assert_called_once_with(['git', 'rev-parse', 'HEAD']) self.assertEqual(git_hash, GIT_HASH_FULL.decode('utf-8')) @mock.patch('subprocess.check_output', return_value=GIT_HASH_SHORT) - @mock.patch('os.path.exists', return_value=True) - def test_get_short_hash(self, exists_mock, check_output_mock): + @mock.patch('skipper.git.is_git_repository', return_value=True) + def test_get_short_hash(self, is_git_repository_mock, check_output_mock): git_hash = git.get_hash(short=True) - exists_mock.assert_called_once_with('.git') + is_git_repository_mock.assert_called_once() check_output_mock.assert_called_once_with(['git', 'rev-parse', '--short', 'HEAD']) self.assertEqual(git_hash, GIT_HASH_SHORT.decode('utf-8')) - @mock.patch('subprocess.check_output') + @mock.patch('skipper.git.is_git_repository', return_value=False) + def test_not_in_git_project(self, is_git_repository_mock): + self.assertEqual(git.get_hash(), 'none') + is_git_repository_mock.assert_called_once() + + @mock.patch('os.path.exists', return_value=True) + def test_should_be_in_git_project_os_path(self, exists_mock): + self.assertTrue(git.is_git_repository()) + exists_mock.assert_called_once_with('.git') + + @mock.patch('subprocess.call', return_value=0) @mock.patch('os.path.exists', return_value=False) - def test_not_in_git_project(self, exists_mock, check_output_mock): - git_hash = git.get_hash() + def test_should_be_in_git_project_git(self, exists_mock, call_mock): + self.assertTrue(git.is_git_repository()) + exists_mock.assert_called_once_with('.git') + call_mock.assert_called_once_with(['git', 'rev-parse', '--is-inside-work-tree'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + + @mock.patch('subprocess.call', return_value=1) + @mock.patch('os.path.exists', return_value=False) + def test_should_not_be_in_git_project(self, exists_mock, call_mock): + self.assertFalse(git.is_git_repository()) exists_mock.assert_called_once_with('.git') - check_output_mock.assert_not_called() - self.assertEqual(git_hash, 'none') + call_mock.assert_called_once_with(['git', 'rev-parse', '--is-inside-work-tree'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)