def build_git_context(lint_config, msg_filename, refspec): """ Builds a git context based on passed parameters and order of precedence """ # Determine which GitContext method to use if a custom message is passed from_commit_msg = GitContext.from_commit_msg if lint_config.staged: LOG.debug("Fetching additional meta-data from staged commit") from_commit_msg = lambda message: GitContext.from_staged_commit( message, lint_config.target) # noqa # Order of precedence: # 1. Any data specified via --msg-filename if msg_filename: LOG.debug("Using --msg-filename.") return from_commit_msg(str(msg_filename.read())) # 2. Any data sent to stdin (unless stdin is being ignored) if not lint_config.ignore_stdin: stdin_input = get_stdin_data() if stdin_input: LOG.debug("Stdin data: '%s'", stdin_input) LOG.debug("Stdin detected and not ignored. Using as input.") return from_commit_msg(stdin_input) if lint_config.staged: raise GitLintUsageError( "The 'staged' option (--staged) can only be used when using '--msg-filename' or " "when piping data to gitlint via stdin.") # 3. Fallback to reading from local repository LOG.debug( "No --msg-filename flag, no or empty data passed to stdin. Using the local repo." ) return GitContext.from_local_repository(lint_config.target, refspec)
def test_staged_commit_with_missing_username(self, sh): # StagedLocalGitCommit() sh.git.side_effect = [ "#", # git config --get core.commentchar ErrorReturnCode('git config --get user.name', b"", b""), ] expected_msg = "Missing git configuration: please set user.name" with self.assertRaisesMessage(GitContextError, expected_msg): ctx = GitContext.from_staged_commit("Foōbar 123\n\ncömmit-body\n", "fåke/path") [str(commit) for commit in ctx.commits]
def test_staged_commit(self, now, sh): # StagedLocalGitCommit() sh.git.side_effect = [ "#", # git config --get core.commentchar "test åuthor\n", # git config --get user.name "test-emå[email protected]\n", # git config --get user.email "my-brånch\n", # git rev-parse --abbrev-ref HEAD "file1.txt\npåth/to/file2.txt\n", ] now.side_effect = [arrow.get("2020-02-19T12:18:46.675182+01:00")] # We use a fixup commit, just to test a non-default path context = GitContext.from_staged_commit("fixup! Foōbar 123\n\ncömmit-body\n", "fåke/path") # git calls we're expexting expected_calls = [ call('config', '--get', 'core.commentchar', _ok_code=[0, 1], **self.expected_sh_special_args), call('config', '--get', 'user.name', **self.expected_sh_special_args), call('config', '--get', 'user.email', **self.expected_sh_special_args), call("rev-parse", "--abbrev-ref", "HEAD", **self.expected_sh_special_args), call("diff", "--staged", "--name-only", "-r", **self.expected_sh_special_args) ] last_commit = context.commits[-1] self.assertIsInstance(last_commit, StagedLocalGitCommit) self.assertIsNone(last_commit.sha, None) self.assertEqual(last_commit.message.title, "fixup! Foōbar 123") self.assertEqual(last_commit.message.body, ["", "cömmit-body"]) # Only `git config --get core.commentchar` should've happened up until this point self.assertListEqual(sh.git.mock_calls, expected_calls[0:1]) self.assertEqual(last_commit.author_name, "test åuthor") self.assertListEqual(sh.git.mock_calls, expected_calls[0:2]) self.assertEqual(last_commit.author_email, "test-emå[email protected]") self.assertListEqual(sh.git.mock_calls, expected_calls[0:3]) self.assertEqual(last_commit.date, datetime.datetime(2020, 2, 19, 12, 18, 46, tzinfo=dateutil.tz.tzoffset("+0100", 3600))) now.assert_called_once() self.assertListEqual(last_commit.parents, []) self.assertFalse(last_commit.is_merge_commit) self.assertTrue(last_commit.is_fixup_commit) self.assertFalse(last_commit.is_squash_commit) self.assertFalse(last_commit.is_revert_commit) self.assertListEqual(last_commit.branches, ["my-brånch"]) self.assertListEqual(sh.git.mock_calls, expected_calls[0:4]) self.assertListEqual(last_commit.changed_files, ["file1.txt", "påth/to/file2.txt"]) self.assertListEqual(sh.git.mock_calls, expected_calls[0:5])