Skip to content

Commit

Permalink
Merge pull request #137 from DanCardin/master
Browse files Browse the repository at this point in the history
Adding the ability to ignore unstaged changes
  • Loading branch information
Bachmann1234 committed Feb 5, 2015
1 parent 300ca25 commit eb86d12
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 12 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ Mihai Bivol <mm.bivol@gmail.com>
Matt Bachmann <bachmann.matt@gmail.com>
David Baumgold <david@davidbaumgold.com>
Ricardo Newbery <ric@digitalmarbles.com>
Daniel Cardin <danielcardin@outlook.com>
22 changes: 15 additions & 7 deletions diff_cover/diff_reporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class GitDiffReporter(BaseDiffReporter):
Query information from a Git diff between branches.
"""

def __init__(self, compare_branch='origin/master', git_diff=None):
def __init__(self, compare_branch='origin/master', git_diff=None, ignore_unstaged=None):
"""
Configure the reporter to use `git_diff` as the wrapper
for the `git diff` tool. (Should have same interface
Expand All @@ -65,6 +65,7 @@ def __init__(self, compare_branch='origin/master', git_diff=None):

self._compare_branch = compare_branch
self._git_diff_tool = git_diff
self._ignore_unstaged = ignore_unstaged

# Cache diff information as a dictionary
# with file path keys and line number list values
Expand Down Expand Up @@ -100,6 +101,18 @@ def lines_changed(self, src_path):
# If no lines modified, return an empty list
return diff_dict.get(src_path, [])

def _get_included_diff_results(self):
"""
Return a list of stages to be included in the diff results.
"""
included = [self._git_diff_tool.diff_committed(self._compare_branch),
self._git_diff_tool.diff_staged()]
if not self._ignore_unstaged:
included.append(self._git_diff_tool.diff_unstaged())

return included


def _git_diff(self):
"""
Run `git diff` and returns a dict in which the keys
Expand All @@ -119,12 +132,7 @@ def _git_diff(self):

result_dict = dict()

for diff_str in [
self._git_diff_tool.diff_committed(self._compare_branch),
self._git_diff_tool.diff_staged(),
self._git_diff_tool.diff_unstaged()
]:

for diff_str in self._get_included_diff_results():
# Parse the output of the diff string
diff_dict = self._parse_diff_str(diff_str)

Expand Down
16 changes: 16 additions & 0 deletions diff_cover/tests/test_args.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ def test_parse_with_html_report(self):
arg_dict.get('html_report'),
'diff_cover.html'
)
self.assertEqual(arg_dict.get('ignore_unstaged'), False)

def test_parse_with_no_html_report(self):
argv = ['reports/coverage.xml']
Expand All @@ -30,6 +31,13 @@ def test_parse_with_no_html_report(self):
arg_dict.get('coverage_xml'),
['reports/coverage.xml']
)
self.assertEqual(arg_dict.get('ignore_unstaged'), False)

def test_parse_with_ignored_unstaged(self):
argv = ['reports/coverage.xml', '--ignore-unstaged']

arg_dict = parse_coverage_args(argv)
self.assertEqual(arg_dict.get('ignore_unstaged'), True)

def test_parse_invalid_arg(self):

Expand All @@ -53,13 +61,15 @@ def test_parse_with_html_report(self):
self.assertEqual(arg_dict.get('violations'), 'pep8')
self.assertEqual(arg_dict.get('html_report'), 'diff_cover.html')
self.assertEqual(arg_dict.get('input_reports'), [])
self.assertEqual(arg_dict.get('ignore_unstaged'), False)

def test_parse_with_no_html_report(self):
argv = ['--violations', 'pylint']

arg_dict = parse_quality_args(argv)
self.assertEqual(arg_dict.get('violations'), 'pylint')
self.assertEqual(arg_dict.get('input_reports'), [])
self.assertEqual(arg_dict.get('ignore_unstaged'), False)

def test_parse_with_one_input_report(self):
argv = ['--violations', 'pylint', 'pylint_report.txt']
Expand Down Expand Up @@ -90,6 +100,12 @@ def test_parse_with_options(self):
'"--exclude=\'*/migrations*\'"'
)

def test_parse_with_ignored_unstaged(self):
argv = ['--violations', 'pylint', '--ignore-unstaged']

arg_dict = parse_quality_args(argv)
self.assertEqual(arg_dict.get('ignore_unstaged'), True)

def test_parse_invalid_arg(self):
# No code quality test provided
invalid_argv = [[], ['--html-report', 'diff_cover.html']]
Expand Down
16 changes: 16 additions & 0 deletions diff_cover/tests/test_diff_reporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,22 @@ def test_merge_conflict_diff(self):
lines_changed = self.diff.lines_changed('subdir/src.py')
self.assertEqual(lines_changed, [16, 17, 18, 19])

def test_inclusion_list(self):
unstaged_input = git_diff_output({'subdir/file1.py': line_numbers(3, 10) + line_numbers(34, 47)})
self._set_git_diff_output('', '', unstaged_input)

self.assertEqual(3, len(self.diff._get_included_diff_results()))
self.assertEqual(['', '', unstaged_input], self.diff._get_included_diff_results())

def test_ignore_unstaged_inclusion(self):
self.diff = GitDiffReporter(git_diff=self._git_diff, ignore_unstaged=True)

unstaged_input = git_diff_output({'subdir/file1.py': line_numbers(3, 10) + line_numbers(34, 47)})
self._set_git_diff_output('', '', unstaged_input)

self.assertEqual(2, len(self.diff._get_included_diff_results()))
self.assertEqual(['', ''], self.diff._get_included_diff_results())

def _set_git_diff_output(self, committed_diff,
staged_diff, unstaged_diff):
"""
Expand Down
27 changes: 22 additions & 5 deletions diff_cover/tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
INPUT_REPORTS_HELP = "Pep8, pyflakes, flake8, or pylint reports to use"
OPTIONS_HELP = "Options to be passed to the violations tool"
FAIL_UNDER_HELP = "Returns an error code if coverage or quality score is below this value"
IGNORE_UNSTAGED_HELP = "Ignores unstaged changes"

QUALITY_REPORTERS = {
'pep8': Pep8QualityReporter,
Expand Down Expand Up @@ -86,6 +87,13 @@ def parse_coverage_args(argv):
help=FAIL_UNDER_HELP
)

parser.add_argument(
'--ignore-unstaged',
action='store_true',
default=False,
help=IGNORE_UNSTAGED_HELP
)

return vars(parser.parse_args(argv))


Expand Down Expand Up @@ -149,14 +157,21 @@ def parse_quality_args(argv):
help=FAIL_UNDER_HELP
)

parser.add_argument(
'--ignore-unstaged',
action='store_true',
default=False,
help=IGNORE_UNSTAGED_HELP
)

return vars(parser.parse_args(argv))


def generate_coverage_report(coverage_xml, compare_branch, html_report=None):
def generate_coverage_report(coverage_xml, compare_branch, html_report=None, ignore_unstaged=False):
"""
Generate the diff coverage report, using kwargs from `parse_args()`.
"""
diff = GitDiffReporter(compare_branch, git_diff=GitDiffTool())
diff = GitDiffReporter(compare_branch, git_diff=GitDiffTool(), ignore_unstaged=ignore_unstaged)

xml_roots = [cElementTree.parse(xml_root) for xml_root in coverage_xml]
coverage = XmlCoverageReporter(xml_roots)
Expand All @@ -175,11 +190,11 @@ def generate_coverage_report(coverage_xml, compare_branch, html_report=None):
return reporter.total_percent_covered()


def generate_quality_report(tool, compare_branch, html_report=None):
def generate_quality_report(tool, compare_branch, html_report=None, ignore_unstaged=False):
"""
Generate the quality report, using kwargs from `parse_args()`.
"""
diff = GitDiffReporter(compare_branch, git_diff=GitDiffTool())
diff = GitDiffReporter(compare_branch, git_diff=GitDiffTool(), ignore_unstaged=ignore_unstaged)

if html_report is not None:
reporter = HtmlQualityReportGenerator(tool, diff)
Expand Down Expand Up @@ -222,6 +237,7 @@ def main(argv=None, directory=None):
arg_dict['coverage_xml'],
arg_dict['compare_branch'],
html_report=arg_dict['html_report'],
ignore_unstaged=arg_dict['ignore_unstaged'],
)

if percent_covered >= fail_under:
Expand Down Expand Up @@ -258,7 +274,8 @@ def main(argv=None, directory=None):
percent_passing = generate_quality_report(
reporter,
arg_dict['compare_branch'],
arg_dict['html_report']
arg_dict['html_report'],
arg_dict['ignore_unstaged'],
)
if percent_passing >= fail_under:
return 0
Expand Down

0 comments on commit eb86d12

Please sign in to comment.