secretshield 0.4.1__tar.gz → 0.4.2__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.
Files changed (43) hide show
  1. {secretshield-0.4.1/secretshield.egg-info → secretshield-0.4.2}/PKG-INFO +8 -2
  2. {secretshield-0.4.1 → secretshield-0.4.2}/README.md +7 -1
  3. {secretshield-0.4.1 → secretshield-0.4.2}/pyproject.toml +3 -2
  4. {secretshield-0.4.1 → secretshield-0.4.2}/secretshield/__init__.py +1 -1
  5. {secretshield-0.4.1 → secretshield-0.4.2}/secretshield/cli.py +19 -0
  6. {secretshield-0.4.1 → secretshield-0.4.2/secretshield.egg-info}/PKG-INFO +8 -2
  7. {secretshield-0.4.1 → secretshield-0.4.2}/secretshield.egg-info/SOURCES.txt +1 -0
  8. {secretshield-0.4.1 → secretshield-0.4.2}/secretshield.egg-info/entry_points.txt +1 -0
  9. secretshield-0.4.2/tests/test_ss_alias_and_creator.py +147 -0
  10. {secretshield-0.4.1 → secretshield-0.4.2}/LICENSE +0 -0
  11. {secretshield-0.4.1 → secretshield-0.4.2}/secretshield/autofix/__init__.py +0 -0
  12. {secretshield-0.4.1 → secretshield-0.4.2}/secretshield/autofix/env.py +0 -0
  13. {secretshield-0.4.1 → secretshield-0.4.2}/secretshield/autofix/fixer.py +0 -0
  14. {secretshield-0.4.1 → secretshield-0.4.2}/secretshield/autofix/gitignore.py +0 -0
  15. {secretshield-0.4.1 → secretshield-0.4.2}/secretshield/autofix/python.py +0 -0
  16. {secretshield-0.4.1 → secretshield-0.4.2}/secretshield/baseline.py +0 -0
  17. {secretshield-0.4.1 → secretshield-0.4.2}/secretshield/config.py +0 -0
  18. {secretshield-0.4.1 → secretshield-0.4.2}/secretshield/detector.py +0 -0
  19. {secretshield-0.4.1 → secretshield-0.4.2}/secretshield/git/__init__.py +0 -0
  20. {secretshield-0.4.1 → secretshield-0.4.2}/secretshield/git/hooks.py +0 -0
  21. {secretshield-0.4.1 → secretshield-0.4.2}/secretshield/github/__init__.py +0 -0
  22. {secretshield-0.4.1 → secretshield-0.4.2}/secretshield/github/actions.py +0 -0
  23. {secretshield-0.4.1 → secretshield-0.4.2}/secretshield/guardian.py +0 -0
  24. {secretshield-0.4.1 → secretshield-0.4.2}/secretshield/notifications.py +0 -0
  25. {secretshield-0.4.1 → secretshield-0.4.2}/secretshield/patterns.py +0 -0
  26. {secretshield-0.4.1 → secretshield-0.4.2}/secretshield/project_config.py +0 -0
  27. {secretshield-0.4.1 → secretshield-0.4.2}/secretshield/redactor.py +0 -0
  28. {secretshield-0.4.1 → secretshield-0.4.2}/secretshield.egg-info/dependency_links.txt +0 -0
  29. {secretshield-0.4.1 → secretshield-0.4.2}/secretshield.egg-info/requires.txt +0 -0
  30. {secretshield-0.4.1 → secretshield-0.4.2}/secretshield.egg-info/top_level.txt +0 -0
  31. {secretshield-0.4.1 → secretshield-0.4.2}/setup.cfg +0 -0
  32. {secretshield-0.4.1 → secretshield-0.4.2}/tests/test_autofix.py +0 -0
  33. {secretshield-0.4.1 → secretshield-0.4.2}/tests/test_baseline.py +0 -0
  34. {secretshield-0.4.1 → secretshield-0.4.2}/tests/test_detector.py +0 -0
  35. {secretshield-0.4.1 → secretshield-0.4.2}/tests/test_git_hooks.py +0 -0
  36. {secretshield-0.4.1 → secretshield-0.4.2}/tests/test_github_action.py +0 -0
  37. {secretshield-0.4.1 → secretshield-0.4.2}/tests/test_logging.py +0 -0
  38. {secretshield-0.4.1 → secretshield-0.4.2}/tests/test_project_config.py +0 -0
  39. {secretshield-0.4.1 → secretshield-0.4.2}/tests/test_redactor.py +0 -0
  40. {secretshield-0.4.1 → secretshield-0.4.2}/tests/test_scan.py +0 -0
  41. {secretshield-0.4.1 → secretshield-0.4.2}/tests/test_stdout.py +0 -0
  42. {secretshield-0.4.1 → secretshield-0.4.2}/tests/test_v030_cli_integration.py +0 -0
  43. {secretshield-0.4.1 → secretshield-0.4.2}/tests/test_v040_cli_integration.py +0 -0
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: secretshield
3
- Version: 0.4.1
4
- Summary: Detect, redact, and prevent secret exposure in Python apps, source code, and Git commits — runtime protection, multi-language scanning, auto-fix, and CI integration in one tool.
3
+ Version: 0.4.2
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
7
7
  Project-URL: Homepage, https://github.com/Sam3360/secretshield
@@ -106,6 +106,10 @@ Set a whole project up in one step (config file + Git hook + CI):
106
106
  secretshield init
107
107
  ```
108
108
 
109
+ > Typing `secretshield` a lot? Every command also works with the short
110
+ > alias `ss` — `ss scan .`, `ss init`, `ss --fix`, all identical to
111
+ > their `secretshield` equivalents.
112
+
109
113
  ## What SecretShield does
110
114
 
111
115
  SecretShield isn't just one trick — it's five layers that cover the
@@ -179,6 +183,8 @@ redact("aws_key=AKIAABCDEFGHIJKLMNOP")
179
183
 
180
184
  ## CLI reference
181
185
 
186
+ *(Every command below also works via the shorter `ss` alias — `ss scan .` is identical to `secretshield scan .`.)*
187
+
182
188
  ### `secretshield init` — set a project up in one step
183
189
 
184
190
  ```bash
@@ -80,6 +80,10 @@ Set a whole project up in one step (config file + Git hook + CI):
80
80
  secretshield init
81
81
  ```
82
82
 
83
+ > Typing `secretshield` a lot? Every command also works with the short
84
+ > alias `ss` — `ss scan .`, `ss init`, `ss --fix`, all identical to
85
+ > their `secretshield` equivalents.
86
+
83
87
  ## What SecretShield does
84
88
 
85
89
  SecretShield isn't just one trick — it's five layers that cover the
@@ -153,6 +157,8 @@ redact("aws_key=AKIAABCDEFGHIJKLMNOP")
153
157
 
154
158
  ## CLI reference
155
159
 
160
+ *(Every command below also works via the shorter `ss` alias — `ss scan .` is identical to `secretshield scan .`.)*
161
+
156
162
  ### `secretshield init` — set a project up in one step
157
163
 
158
164
  ```bash
@@ -324,4 +330,4 @@ If you find this project useful, consider [supporting its development through Gi
324
330
 
325
331
  ## License
326
332
 
327
- MIT — see [LICENSE](LICENSE).
333
+ MIT — see [LICENSE](LICENSE).
@@ -4,8 +4,8 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "secretshield"
7
- version = "0.4.1"
8
- description = "Detect, redact, and prevent secret exposure in Python apps, source code, and Git commits — runtime protection, multi-language scanning, auto-fix, and CI integration in one tool."
7
+ version = "0.4.2"
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"
11
11
  requires-python = ">=3.10"
@@ -39,6 +39,7 @@ Issues = "https://github.com/Sam3360/secretshield/issues"
39
39
 
40
40
  [project.scripts]
41
41
  secretshield = "secretshield.cli:main"
42
+ ss = "secretshield.cli:main"
42
43
 
43
44
  [tool.setuptools.packages.find]
44
45
  include = ["secretshield*"]
@@ -23,7 +23,7 @@ from .detector import Match, detect
23
23
  from .guardian import disable, enable, is_enabled
24
24
  from .redactor import redact
25
25
 
26
- __version__ = "0.4.0"
26
+ __version__ = "0.4.2"
27
27
 
28
28
  __all__ = [
29
29
  "__version__",
@@ -726,6 +726,22 @@ def _cmd_init(args: argparse.Namespace) -> int:
726
726
  # --- argparse wiring -----------------------------------------------------
727
727
 
728
728
 
729
+ CREATOR_MESSAGE = "SecretShield\nCreated by Samarth Chugh (Sam3360)\ngithub.com/Sam3360"
730
+
731
+
732
+ class _CreatorAction(argparse.Action):
733
+ """Prints creator info and exits -- mirrors argparse's built-in
734
+ `action="version"` behavior so `--creator` works the same way
735
+ `--version` does, with no subcommand required."""
736
+
737
+ def __init__(self, option_strings, dest, nargs=0, **kwargs):
738
+ super().__init__(option_strings, dest, nargs=nargs, **kwargs)
739
+
740
+ def __call__(self, parser, namespace, values, option_string=None):
741
+ print(CREATOR_MESSAGE)
742
+ parser.exit()
743
+
744
+
729
745
  def build_parser() -> argparse.ArgumentParser:
730
746
  parser = argparse.ArgumentParser(
731
747
  prog="secretshield",
@@ -737,6 +753,9 @@ def build_parser() -> argparse.ArgumentParser:
737
753
  parser.add_argument(
738
754
  "--version", action="version", version=f"secretshield {__version__}"
739
755
  )
756
+ parser.add_argument(
757
+ "--creator", action=_CreatorAction, help="Show who made this and exit."
758
+ )
740
759
 
741
760
  subparsers = parser.add_subparsers(dest="command")
742
761
 
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: secretshield
3
- Version: 0.4.1
4
- Summary: Detect, redact, and prevent secret exposure in Python apps, source code, and Git commits — runtime protection, multi-language scanning, auto-fix, and CI integration in one tool.
3
+ Version: 0.4.2
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
7
7
  Project-URL: Homepage, https://github.com/Sam3360/secretshield
@@ -106,6 +106,10 @@ Set a whole project up in one step (config file + Git hook + CI):
106
106
  secretshield init
107
107
  ```
108
108
 
109
+ > Typing `secretshield` a lot? Every command also works with the short
110
+ > alias `ss` — `ss scan .`, `ss init`, `ss --fix`, all identical to
111
+ > their `secretshield` equivalents.
112
+
109
113
  ## What SecretShield does
110
114
 
111
115
  SecretShield isn't just one trick — it's five layers that cover the
@@ -179,6 +183,8 @@ redact("aws_key=AKIAABCDEFGHIJKLMNOP")
179
183
 
180
184
  ## CLI reference
181
185
 
186
+ *(Every command below also works via the shorter `ss` alias — `ss scan .` is identical to `secretshield scan .`.)*
187
+
182
188
  ### `secretshield init` — set a project up in one step
183
189
 
184
190
  ```bash
@@ -35,6 +35,7 @@ tests/test_logging.py
35
35
  tests/test_project_config.py
36
36
  tests/test_redactor.py
37
37
  tests/test_scan.py
38
+ tests/test_ss_alias_and_creator.py
38
39
  tests/test_stdout.py
39
40
  tests/test_v030_cli_integration.py
40
41
  tests/test_v040_cli_integration.py
@@ -1,2 +1,3 @@
1
1
  [console_scripts]
2
2
  secretshield = secretshield.cli:main
3
+ ss = secretshield.cli:main
@@ -0,0 +1,147 @@
1
+ """
2
+ Tests for v0.4.2: the `ss` short CLI alias and the `--creator` easter
3
+ egg. Both `ss` and `secretshield` are registered as separate console
4
+ scripts pointing to the exact same `secretshield.cli:main` function, so
5
+ most equivalence is tested by exercising `main()` directly; a couple of
6
+ tests also verify the actual installed executables behave identically.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import shutil
12
+ import subprocess
13
+ import sys
14
+
15
+ import pytest
16
+
17
+ from secretshield.cli import CREATOR_MESSAGE, build_parser, main
18
+
19
+ FAKE_SECRET = "ssAliasFakeSecretForTests123456789"
20
+
21
+
22
+ # --- --creator, via main() (fast, no subprocess) -----------------------------
23
+
24
+
25
+ def test_creator_flag_exits_zero():
26
+ with pytest.raises(SystemExit) as exc_info:
27
+ main(["--creator"])
28
+ assert exc_info.value.code in (0, None)
29
+
30
+
31
+ def test_creator_flag_prints_expected_content(capsys):
32
+ with pytest.raises(SystemExit):
33
+ main(["--creator"])
34
+ out = capsys.readouterr().out
35
+ assert "Samarth Chugh (Sam3360)" in out
36
+ assert "github.com/Sam3360" in out
37
+
38
+
39
+ def test_creator_message_constant_matches_requirements():
40
+ assert "Samarth Chugh (Sam3360)" in CREATOR_MESSAGE
41
+ assert "github.com/Sam3360" in CREATOR_MESSAGE
42
+
43
+
44
+ def test_creator_flag_is_not_overly_verbose():
45
+ # Polished, not a wall of text.
46
+ assert CREATOR_MESSAGE.count("\n") <= 3
47
+
48
+
49
+ def test_creator_works_regardless_of_subcommand_position():
50
+ # --creator, like --version, should short-circuit before any
51
+ # subcommand dispatch is required.
52
+ parser = build_parser()
53
+ with pytest.raises(SystemExit):
54
+ parser.parse_args(["--creator"])
55
+
56
+
57
+ # --- console scripts: both entry points exist and are wired identically ----
58
+
59
+
60
+ def test_pyproject_declares_both_console_scripts():
61
+ try:
62
+ import tomllib # Python 3.11+
63
+ except ModuleNotFoundError:
64
+ import tomli as tomllib # Python 3.10 fallback
65
+
66
+ with open("pyproject.toml", "rb") as f:
67
+ data = tomllib.load(f)
68
+ scripts = data["project"]["scripts"]
69
+ assert scripts.get("secretshield") == "secretshield.cli:main"
70
+ assert scripts.get("ss") == "secretshield.cli:main"
71
+
72
+
73
+ def _find_executable(name: str) -> str | None:
74
+ return shutil.which(name)
75
+
76
+
77
+ @pytest.mark.skipif(
78
+ _find_executable("ss") is None or _find_executable("secretshield") is None,
79
+ reason="ss/secretshield not installed as real executables in this environment",
80
+ )
81
+ def test_installed_ss_and_secretshield_creator_output_match():
82
+ result_full = subprocess.run(
83
+ ["secretshield", "--creator"], capture_output=True, text=True
84
+ )
85
+ result_short = subprocess.run(["ss", "--creator"], capture_output=True, text=True)
86
+ assert result_full.returncode == 0
87
+ assert result_short.returncode == 0
88
+ assert result_full.stdout == result_short.stdout
89
+
90
+
91
+ @pytest.mark.skipif(
92
+ _find_executable("ss") is None or _find_executable("secretshield") is None,
93
+ reason="ss/secretshield not installed as real executables in this environment",
94
+ )
95
+ def test_installed_ss_and_secretshield_version_match():
96
+ result_full = subprocess.run(
97
+ ["secretshield", "--version"], capture_output=True, text=True
98
+ )
99
+ result_short = subprocess.run(["ss", "--version"], capture_output=True, text=True)
100
+ assert result_full.stdout == result_short.stdout
101
+
102
+
103
+ @pytest.mark.skipif(
104
+ _find_executable("ss") is None or _find_executable("secretshield") is None,
105
+ reason="ss/secretshield not installed as real executables in this environment",
106
+ )
107
+ def test_installed_ss_and_secretshield_help_match():
108
+ result_full = subprocess.run(
109
+ ["secretshield", "--help"], capture_output=True, text=True
110
+ )
111
+ result_short = subprocess.run(["ss", "--help"], capture_output=True, text=True)
112
+ assert result_full.stdout == result_short.stdout
113
+
114
+
115
+ @pytest.mark.skipif(
116
+ _find_executable("ss") is None or _find_executable("secretshield") is None,
117
+ reason="ss/secretshield not installed as real executables in this environment",
118
+ )
119
+ def test_installed_ss_scan_behaves_like_secretshield_scan(tmp_path):
120
+ (tmp_path / "app.py").write_text(f'API_KEY = "{FAKE_SECRET}"\n')
121
+
122
+ result_full = subprocess.run(
123
+ ["secretshield", "scan", str(tmp_path)], capture_output=True, text=True
124
+ )
125
+ result_short = subprocess.run(
126
+ ["ss", "scan", str(tmp_path)], capture_output=True, text=True
127
+ )
128
+ assert result_full.returncode == result_short.returncode == 1
129
+ assert result_full.stdout == result_short.stdout
130
+ assert FAKE_SECRET not in result_full.stdout
131
+ assert FAKE_SECRET not in result_short.stdout
132
+
133
+
134
+ # --- existing commands unaffected -------------------------------------------
135
+
136
+
137
+ def test_existing_scan_command_still_works_after_creator_addition(tmp_path):
138
+ app = tmp_path / "app.py"
139
+ app.write_text(f'API_KEY = "{FAKE_SECRET}"\n')
140
+ exit_code = main(["scan", str(app)])
141
+ assert exit_code == 1
142
+
143
+
144
+ def test_version_flag_still_works():
145
+ with pytest.raises(SystemExit) as exc_info:
146
+ main(["--version"])
147
+ assert exc_info.value.code in (0, None)
File without changes
File without changes