secretshield 0.7.0__tar.gz → 0.7.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {secretshield-0.7.0/secretshield.egg-info → secretshield-0.7.1}/PKG-INFO +2 -2
- {secretshield-0.7.0 → secretshield-0.7.1}/README.md +1 -1
- {secretshield-0.7.0 → secretshield-0.7.1}/pyproject.toml +1 -1
- {secretshield-0.7.0 → secretshield-0.7.1}/secretshield/__init__.py +1 -1
- {secretshield-0.7.0 → secretshield-0.7.1}/secretshield/cli.py +10 -4
- {secretshield-0.7.0 → secretshield-0.7.1/secretshield.egg-info}/PKG-INFO +2 -2
- {secretshield-0.7.0 → secretshield-0.7.1}/tests/test_custom_rules_cli_integration.py +54 -1
- {secretshield-0.7.0 → secretshield-0.7.1}/LICENSE +0 -0
- {secretshield-0.7.0 → secretshield-0.7.1}/secretshield/autofix/__init__.py +0 -0
- {secretshield-0.7.0 → secretshield-0.7.1}/secretshield/autofix/env.py +0 -0
- {secretshield-0.7.0 → secretshield-0.7.1}/secretshield/autofix/fixer.py +0 -0
- {secretshield-0.7.0 → secretshield-0.7.1}/secretshield/autofix/gitignore.py +0 -0
- {secretshield-0.7.0 → secretshield-0.7.1}/secretshield/autofix/javascript.py +0 -0
- {secretshield-0.7.0 → secretshield-0.7.1}/secretshield/autofix/python.py +0 -0
- {secretshield-0.7.0 → secretshield-0.7.1}/secretshield/baseline.py +0 -0
- {secretshield-0.7.0 → secretshield-0.7.1}/secretshield/color.py +0 -0
- {secretshield-0.7.0 → secretshield-0.7.1}/secretshield/config.py +0 -0
- {secretshield-0.7.0 → secretshield-0.7.1}/secretshield/custom_rules.py +0 -0
- {secretshield-0.7.0 → secretshield-0.7.1}/secretshield/detector.py +0 -0
- {secretshield-0.7.0 → secretshield-0.7.1}/secretshield/git/__init__.py +0 -0
- {secretshield-0.7.0 → secretshield-0.7.1}/secretshield/git/hooks.py +0 -0
- {secretshield-0.7.0 → secretshield-0.7.1}/secretshield/github/__init__.py +0 -0
- {secretshield-0.7.0 → secretshield-0.7.1}/secretshield/github/actions.py +0 -0
- {secretshield-0.7.0 → secretshield-0.7.1}/secretshield/guardian.py +0 -0
- {secretshield-0.7.0 → secretshield-0.7.1}/secretshield/ignorefile.py +0 -0
- {secretshield-0.7.0 → secretshield-0.7.1}/secretshield/notifications.py +0 -0
- {secretshield-0.7.0 → secretshield-0.7.1}/secretshield/patterns.py +0 -0
- {secretshield-0.7.0 → secretshield-0.7.1}/secretshield/project_config.py +0 -0
- {secretshield-0.7.0 → secretshield-0.7.1}/secretshield/redactor.py +0 -0
- {secretshield-0.7.0 → secretshield-0.7.1}/secretshield.egg-info/SOURCES.txt +0 -0
- {secretshield-0.7.0 → secretshield-0.7.1}/secretshield.egg-info/dependency_links.txt +0 -0
- {secretshield-0.7.0 → secretshield-0.7.1}/secretshield.egg-info/entry_points.txt +0 -0
- {secretshield-0.7.0 → secretshield-0.7.1}/secretshield.egg-info/requires.txt +0 -0
- {secretshield-0.7.0 → secretshield-0.7.1}/secretshield.egg-info/top_level.txt +0 -0
- {secretshield-0.7.0 → secretshield-0.7.1}/setup.cfg +0 -0
- {secretshield-0.7.0 → secretshield-0.7.1}/tests/test_autofix.py +0 -0
- {secretshield-0.7.0 → secretshield-0.7.1}/tests/test_baseline.py +0 -0
- {secretshield-0.7.0 → secretshield-0.7.1}/tests/test_color.py +0 -0
- {secretshield-0.7.0 → secretshield-0.7.1}/tests/test_color_cli_integration.py +0 -0
- {secretshield-0.7.0 → secretshield-0.7.1}/tests/test_custom_rules.py +0 -0
- {secretshield-0.7.0 → secretshield-0.7.1}/tests/test_detector.py +0 -0
- {secretshield-0.7.0 → secretshield-0.7.1}/tests/test_git_hooks.py +0 -0
- {secretshield-0.7.0 → secretshield-0.7.1}/tests/test_github_action.py +0 -0
- {secretshield-0.7.0 → secretshield-0.7.1}/tests/test_ignorefile.py +0 -0
- {secretshield-0.7.0 → secretshield-0.7.1}/tests/test_ignorefile_cli_integration.py +0 -0
- {secretshield-0.7.0 → secretshield-0.7.1}/tests/test_javascript_autofix.py +0 -0
- {secretshield-0.7.0 → secretshield-0.7.1}/tests/test_logging.py +0 -0
- {secretshield-0.7.0 → secretshield-0.7.1}/tests/test_project_config.py +0 -0
- {secretshield-0.7.0 → secretshield-0.7.1}/tests/test_redactor.py +0 -0
- {secretshield-0.7.0 → secretshield-0.7.1}/tests/test_scan.py +0 -0
- {secretshield-0.7.0 → secretshield-0.7.1}/tests/test_ss_alias_and_creator.py +0 -0
- {secretshield-0.7.0 → secretshield-0.7.1}/tests/test_stdout.py +0 -0
- {secretshield-0.7.0 → secretshield-0.7.1}/tests/test_v030_cli_integration.py +0 -0
- {secretshield-0.7.0 → secretshield-0.7.1}/tests/test_v040_cli_integration.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: secretshield
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.1
|
|
4
4
|
Summary: Stop secrets before they leak -- runtime redaction, multi-language scanning, auto-fix, Git hooks, and CI, all in one CLI.
|
|
5
5
|
Author: Samarth Chugh (Sam3360)
|
|
6
6
|
License-Expression: MIT
|
|
@@ -32,7 +32,7 @@ Dynamic: license-file
|
|
|
32
32
|
|
|
33
33
|
[](https://pypi.org/project/secretshield/)
|
|
34
34
|
[](https://pypi.org/project/secretshield/)
|
|
35
|
-
[](https://pypi.org/project/secretshield/)
|
|
36
36
|
[](LICENSE)
|
|
37
37
|
|
|
38
38
|
[Install](#install) · [Demo](#demo) · [Try it](#try-it) · [Full usage guide →](https://github.com/Sam3360/secretshield/blob/main/USAGE.md)
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
[](https://pypi.org/project/secretshield/)
|
|
8
8
|
[](https://pypi.org/project/secretshield/)
|
|
9
|
-
[](https://pypi.org/project/secretshield/)
|
|
10
10
|
[](LICENSE)
|
|
11
11
|
|
|
12
12
|
[Install](#install) · [Demo](#demo) · [Try it](#try-it) · [Full usage guide →](https://github.com/Sam3360/secretshield/blob/main/USAGE.md)
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "secretshield"
|
|
7
|
-
version = "0.7.
|
|
7
|
+
version = "0.7.1"
|
|
8
8
|
description = "Stop secrets before they leak -- runtime redaction, multi-language scanning, auto-fix, Git hooks, and CI, all in one CLI."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
@@ -168,6 +168,12 @@ _KIND_DISPLAY: dict[str, tuple[str, str]] = {
|
|
|
168
168
|
}
|
|
169
169
|
|
|
170
170
|
|
|
171
|
+
def _plural(count: int, word: str) -> str:
|
|
172
|
+
"""`f"{count} {word}"`, pluralized properly -- "1 rule" / "2 rules" --
|
|
173
|
+
instead of the awkward literal "rule(s)" regardless of count."""
|
|
174
|
+
return f"{count} {word}" if count == 1 else f"{count} {word}s"
|
|
175
|
+
|
|
176
|
+
|
|
171
177
|
def _kind_display(kind: str) -> tuple[str, str]:
|
|
172
178
|
return _KIND_DISPLAY.get(kind, (kind, "possible secret"))
|
|
173
179
|
|
|
@@ -437,8 +443,8 @@ def _run_scan(args: argparse.Namespace) -> int:
|
|
|
437
443
|
custom_rules, custom_rule_errors = load_custom_rules(Path.cwd())
|
|
438
444
|
if custom_rule_errors:
|
|
439
445
|
print(
|
|
440
|
-
f"secretshield: warning: {len(custom_rule_errors)
|
|
441
|
-
f"
|
|
446
|
+
f"secretshield: warning: {_plural(len(custom_rule_errors), 'invalid custom rule')} "
|
|
447
|
+
f"in .secretshield-rules.toml -- run `secretshield rules "
|
|
442
448
|
f"check` for details.",
|
|
443
449
|
file=sys.stderr,
|
|
444
450
|
)
|
|
@@ -787,7 +793,7 @@ def _cmd_rules_check(args: argparse.Namespace) -> int:
|
|
|
787
793
|
return 1
|
|
788
794
|
|
|
789
795
|
print(f"{green(chr(0x2713), use_color)} {path.name}")
|
|
790
|
-
print(f"{green(chr(0x2713), use_color)} {len(rules)
|
|
796
|
+
print(f"{green(chr(0x2713), use_color)} {_plural(len(rules), 'rule')} loaded")
|
|
791
797
|
print(f"{green(chr(0x2713), use_color)} All patterns are valid")
|
|
792
798
|
return 0
|
|
793
799
|
|
|
@@ -815,7 +821,7 @@ def _cmd_rules_list(args: argparse.Namespace) -> int:
|
|
|
815
821
|
if errors:
|
|
816
822
|
use_color = supports_color(sys.stdout)
|
|
817
823
|
print(
|
|
818
|
-
f"\n{red(chr(0x2717), use_color)} {len(errors)
|
|
824
|
+
f"\n{red(chr(0x2717), use_color)} {_plural(len(errors), 'rule')} failed to load "
|
|
819
825
|
f"-- run `secretshield rules check` for details."
|
|
820
826
|
)
|
|
821
827
|
return 0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: secretshield
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.1
|
|
4
4
|
Summary: Stop secrets before they leak -- runtime redaction, multi-language scanning, auto-fix, Git hooks, and CI, all in one CLI.
|
|
5
5
|
Author: Samarth Chugh (Sam3360)
|
|
6
6
|
License-Expression: MIT
|
|
@@ -32,7 +32,7 @@ Dynamic: license-file
|
|
|
32
32
|
|
|
33
33
|
[](https://pypi.org/project/secretshield/)
|
|
34
34
|
[](https://pypi.org/project/secretshield/)
|
|
35
|
-
[](https://pypi.org/project/secretshield/)
|
|
36
36
|
[](LICENSE)
|
|
37
37
|
|
|
38
38
|
[Install](#install) · [Demo](#demo) · [Try it](#try-it) · [Full usage guide →](https://github.com/Sam3360/secretshield/blob/main/USAGE.md)
|
|
@@ -129,10 +129,63 @@ def test_rules_check_success(tmp_path, monkeypatch, capsys):
|
|
|
129
129
|
exit_code = main(["rules", "check"])
|
|
130
130
|
assert exit_code == 0
|
|
131
131
|
out = capsys.readouterr().out
|
|
132
|
-
assert "2
|
|
132
|
+
assert "2 rules loaded" in out
|
|
133
133
|
assert "All patterns are valid" in out
|
|
134
134
|
|
|
135
135
|
|
|
136
|
+
# --- Regression tests: singular/plural grammar in rule-count output --------
|
|
137
|
+
# (0.7.1: these counts used to always print the literal "rule(s)"
|
|
138
|
+
# regardless of count, e.g. "1 rule(s) loaded" -- fixed to pluralize
|
|
139
|
+
# properly.)
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def test_rules_check_singular_grammar(tmp_path, monkeypatch, capsys):
|
|
143
|
+
monkeypatch.chdir(tmp_path)
|
|
144
|
+
(tmp_path / ".secretshield-rules.toml").write_text(
|
|
145
|
+
'[[rules]]\nname = "Only One"\npattern = "ONE_[0-9]{4}"\n'
|
|
146
|
+
)
|
|
147
|
+
main(["rules", "check"])
|
|
148
|
+
out = capsys.readouterr().out
|
|
149
|
+
assert "1 rule loaded" in out
|
|
150
|
+
assert "rule(s)" not in out
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def test_rules_check_plural_grammar(tmp_path, monkeypatch, capsys):
|
|
154
|
+
monkeypatch.chdir(tmp_path)
|
|
155
|
+
(tmp_path / ".secretshield-rules.toml").write_text(
|
|
156
|
+
'[[rules]]\nname = "A"\npattern = "AAA_[0-9]{4}"\n'
|
|
157
|
+
'[[rules]]\nname = "B"\npattern = "BBB_[0-9]{4}"\n'
|
|
158
|
+
'[[rules]]\nname = "C"\npattern = "CCC_[0-9]{4}"\n'
|
|
159
|
+
)
|
|
160
|
+
main(["rules", "check"])
|
|
161
|
+
out = capsys.readouterr().out
|
|
162
|
+
assert "3 rules loaded" in out
|
|
163
|
+
assert "rule(s)" not in out
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def test_rules_list_singular_error_grammar(tmp_path, monkeypatch, capsys):
|
|
167
|
+
monkeypatch.chdir(tmp_path)
|
|
168
|
+
(tmp_path / ".secretshield-rules.toml").write_text(
|
|
169
|
+
'[[rules]]\nname = "Broken"\npattern = "["\n'
|
|
170
|
+
)
|
|
171
|
+
main(["rules"])
|
|
172
|
+
out = capsys.readouterr().out
|
|
173
|
+
assert "1 rule failed to load" in out
|
|
174
|
+
assert "rule(s)" not in out
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def test_scan_warning_singular_grammar(tmp_path, monkeypatch, capsys):
|
|
178
|
+
monkeypatch.chdir(tmp_path)
|
|
179
|
+
(tmp_path / ".secretshield-rules.toml").write_text(
|
|
180
|
+
'[[rules]]\nname = "Broken"\npattern = "["\n'
|
|
181
|
+
)
|
|
182
|
+
(tmp_path / "clean.py").write_text("print('hello')\n")
|
|
183
|
+
main(["scan", "."])
|
|
184
|
+
err = capsys.readouterr().err
|
|
185
|
+
assert "1 invalid custom rule in" in err
|
|
186
|
+
assert "rule(s)" not in err
|
|
187
|
+
|
|
188
|
+
|
|
136
189
|
def test_rules_check_reports_errors(tmp_path, monkeypatch, capsys):
|
|
137
190
|
monkeypatch.chdir(tmp_path)
|
|
138
191
|
(tmp_path / ".secretshield-rules.toml").write_text(
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|