Skip to content

Commit

Permalink
Merge pull request #58 from Yelp/smarter-import
Browse files Browse the repository at this point in the history
More intelligent upgrade of baselines
  • Loading branch information
domanchi authored Jul 11, 2018
2 parents 116dfa2 + 49cfa35 commit 80e2398
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 19 deletions.
6 changes: 3 additions & 3 deletions detect_secrets/core/usage.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,12 +107,12 @@ def _add_initialize_baseline_argument(self):
help='Pass in regex to specify ignored paths during initialization scan.',
)

# Pairing `--import` with `--scan` because it's only used for initialization.
# Pairing `--update` with `--scan` because it's only used for initialization.
self.parser.add_argument(
'--import',
'--update',
nargs=1,
metavar='OLD_BASELINE_FILE',
help='Import settings from previous existing baseline.',
help='Update existing baseline by importing settings from it.',
dest='import_filename',
)

Expand Down
36 changes: 27 additions & 9 deletions detect_secrets/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,17 @@ def main(argv=None):
log.set_debug_level(args.verbose)

if args.action == 'scan':
print(
json.dumps(
_perform_scan(args),
indent=2,
sort_keys=True,
),
output = json.dumps(
_perform_scan(args),
indent=2,
sort_keys=True,
)

if args.import_filename:
_write_to_file(args.import_filename[0], output)
else:
print(output)

elif args.action == 'audit':
audit.audit_baseline(args.filename[0])

Expand All @@ -53,6 +56,11 @@ def _perform_scan(args):
elif old_baseline and old_baseline.get('exclude_regex'):
args.exclude = old_baseline['exclude_regex']

# If we have knowledge of an existing baseline file, we should use
# that knowledge and *not* scan that file.
if args.import_filename and args.exclude:
args.exclude += r'|^{}$'.format(args.import_filename[0])

new_baseline = baseline.initialize(
plugins,
args.exclude,
Expand All @@ -71,12 +79,22 @@ def _perform_scan(args):
def _get_existing_baseline(import_filename):
# Favors --import argument over stdin.
if import_filename:
with open(import_filename[0]) as f:
return json.loads(f.read())

return _read_from_file(import_filename[0])
if not sys.stdin.isatty():
return json.loads(sys.stdin.read())


def _read_from_file(filename):
"""Used for mocking."""
with open(filename[0]) as f:
return json.loads(f.read())


def _write_to_file(filename, content):
"""Used for mocking."""
with open(filename, 'w') as f:
f.write(content)


if __name__ == '__main__':
sys.exit(main())
48 changes: 41 additions & 7 deletions tests/main_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
from detect_secrets.main import main
from testing.factories import secrets_collection_factory
from testing.mocks import Any
from testing.mocks import mock_open
from testing.mocks import mock_printer


Expand Down Expand Up @@ -83,18 +82,53 @@ def test_reads_from_stdin(self, mock_merge_baseline):
)

def test_reads_old_baseline_from_file(self, mock_merge_baseline):
with mock_stdin(), mock_open(
json.dumps({'key': 'value'}),
'detect_secrets.main.open',
) as m:
assert main('scan --import old_baseline_file'.split()) == 0
assert m.call_args[0][0] == 'old_baseline_file'
with mock_stdin(), mock.patch(
'detect_secrets.main._read_from_file',
return_value={'key': 'value'},
) as m_read, mock.patch(
'detect_secrets.main._write_to_file',
) as m_write:
assert main('scan --update old_baseline_file'.split()) == 0
assert m_read.call_args[0][0] == 'old_baseline_file'
assert m_write.call_args[0] == ('old_baseline_file', Any(str))

mock_merge_baseline.assert_called_once_with(
{'key': 'value'},
Any(dict),
)

@pytest.mark.parametrize(
'exclude_param, expected_regex',
[
(
'',
'^old_baseline_file$',
),
(
'--exclude "secrets/.*"',
'secrets/.*|^old_baseline_file$',
),
],
)
def test_old_baseline_ignored_with_update_flag(
self,
mock_baseline_initialize,
exclude_param,
expected_regex,
):
with mock_stdin(), mock.patch(
'detect_secrets.main._read_from_file',
return_value={},
), mock.patch(
# We don't want to be creating a file during test
'detect_secrets.main._write_to_file',
):
assert main(
'scan --update old_baseline_file {}'.format(
exclude_param,
).split(),
) == 0

@pytest.mark.parametrize(
'filename, expected_output',
[
Expand Down

0 comments on commit 80e2398

Please sign in to comment.