1+ <!--
2+ -- Copyright (C) 2020-2026 Arm Limited or its affiliates and Contributors. All rights reserved.
3+ -- SPDX-License-Identifier: Apache-2.0
4+ -->
5+ <!doctype html>
6+ < html lang ="en ">
7+ < head >
8+ < meta charset ="utf-8 ">
9+ < meta name ="viewport " content ="width=device-width, initial-scale=1, minimum-scale=1 " />
10+ < meta name ="generator " content ="pdoc 0.10.0 " />
11+ < title > continuous_delivery_scripts.detect_secrets API documentation</ title >
12+ < meta name ="description " content ="Check tracked files against the project's recorded secret registry. " />
13+ < link rel ="preload stylesheet " as ="style " href ="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css " integrity ="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs= " crossorigin >
14+ < link rel ="preload stylesheet " as ="style " href ="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css " integrity ="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg= " crossorigin >
15+ < link rel ="stylesheet preload " as ="style " href ="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css " crossorigin >
16+ < style > : root {--highlight-color : # fe9 }.flex {display : flex !important }body {line-height : 1.5em }# content {padding : 20px }# sidebar {padding : 30px ;overflow : hidden}# sidebar > * : last-child {margin-bottom : 2cm }.http-server-breadcrumbs {font-size : 130% ;margin : 0 0 15px 0 }# footer {font-size : .75em ;padding : 5px 30px ;border-top : 1px solid # ddd ;text-align : right}# footer p {margin : 0 0 0 1em ;display : inline-block}# footer p : last-child {margin-right : 30px }h1 , h2 , h3 , h4 , h5 {font-weight : 300 }h1 {font-size : 2.5em ;line-height : 1.1em }h2 {font-size : 1.75em ;margin : 1em 0 .50em 0 }h3 {font-size : 1.4em ;margin : 25px 0 10px 0 }h4 {margin : 0 ;font-size : 105% }h1 : target , h2 : target , h3 : target , h4 : target , h5 : target , h6 : target {background : var (--highlight-color );padding : .2em 0 }a {color : # 058 ;text-decoration : none;transition : color .3s ease-in-out}a : hover {color : # e82 }.title code {font-weight : bold}h2 [id ^= "header-" ]{margin-top : 2em }.ident {color : # 900 }pre code {background : # f8f8f8 ;font-size : .8em ;line-height : 1.4em }code {background : # f2f2f1 ;padding : 1px 4px ;overflow-wrap : break-word}h1 code {background : transparent}pre {background : # f8f8f8 ;border : 0 ;border-top : 1px solid # ccc ;border-bottom : 1px solid # ccc ;margin : 1em 0 ;padding : 1ex }# http-server-module-list {display : flex;flex-flow : column}# http-server-module-list div {display : flex}# http-server-module-list dt {min-width : 10% }# http-server-module-list p {margin-top : 0 }.toc ul , # index {list-style-type : none;margin : 0 ;padding : 0 }# index code {background : transparent}# index h3 {border-bottom : 1px solid # ddd }# index ul {padding : 0 }# index h4 {margin-top : .6em ;font-weight : bold}@media (min-width : 200ex ){# index .two-column {column-count : 2 }}@media (min-width : 300ex ){# index .two-column {column-count : 3 }}dl {margin-bottom : 2em }dl dl : last-child {margin-bottom : 4em }dd {margin : 0 0 1em 3em }# header-classes + dl > dd {margin-bottom : 3em }dd dd {margin-left : 2em }dd p {margin : 10px 0 }.name {background : # eee ;font-weight : bold;font-size : .85em ;padding : 5px 10px ;display : inline-block;min-width : 40% }.name : hover {background : # e0e0e0 }dt : target .name {background : var (--highlight-color )}.name > span : first-child {white-space : nowrap}.name .class > span : nth-child (2 ){margin-left : .4em }.inherited {color : # 999 ;border-left : 5px solid # eee ;padding-left : 1em }.inheritance em {font-style : normal;font-weight : bold}.desc h2 {font-weight : 400 ;font-size : 1.25em }.desc h3 {font-size : 1em }.desc dt code {background : inherit}.source summary , .git-link-div {color : # 666 ;text-align : right;font-weight : 400 ;font-size : .8em ;text-transform : uppercase}.source summary > * {white-space : nowrap;cursor : pointer}.git-link {color : inherit;margin-left : 1em }.source pre {max-height : 500px ;overflow : auto;margin : 0 }.source pre code {font-size : 12px ;overflow : visible}.hlist {list-style : none}.hlist li {display : inline}.hlist li : after {content : ',\2002' }.hlist li : last-child : after {content : none}.hlist .hlist {display : inline;padding-left : 1em }img {max-width : 100% }td {padding : 0 .5em }.admonition {padding : .1em .5em ;margin-bottom : 1em }.admonition-title {font-weight : bold}.admonition .note , .admonition .info , .admonition .important {background : # aef }.admonition .todo , .admonition .versionadded , .admonition .tip , .admonition .hint {background : # dfd }.admonition .warning , .admonition .versionchanged , .admonition .deprecated {background : # fd4 }.admonition .error , .admonition .danger , .admonition .caution {background : lightpink}</ style >
17+ < style media ="screen and (min-width: 700px) "> @media screen and (min-width : 700px ){# sidebar {width : 30% ;height : 100vh ;overflow : auto;position : sticky;top : 0 }# content {width : 70% ;max-width : 100ch ;padding : 3em 4em ;border-left : 1px solid # ddd }pre code {font-size : 1em }.item .name {font-size : 1em }main {display : flex;flex-direction : row-reverse;justify-content : flex-end}.toc ul ul , # index ul {padding-left : 1.5em }.toc > ul > li {margin-top : .5em }}</ style >
18+ < style media ="print "> @media print{# sidebar h1 {page-break-before : always}.source {display : none}}@media print{* {background : transparent !important ;color : # 000 !important ;box-shadow : none !important ;text-shadow : none !important }a [href ]: after {content : " (" attr (href) ")" ;font-size : 90% }a [href ][title ]: after {content : none}abbr [title ]: after {content : " (" attr (title) ")" }.ir a : after , a [href ^= "javascript:" ]: after , a [href ^= "#" ]: after {content : "" }pre , blockquote {border : 1px solid # 999 ;page-break-inside : avoid}thead {display : table-header-group}tr , img {page-break-inside : avoid}img {max-width : 100% !important }@page {margin : 0.5cm }p , h2 , h3 {orphans : 3 ;widows : 3 }h1 , h2 , h3 , h4 , h5 , h6 {page-break-after : avoid}}</ style >
19+ < script defer src ="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js " integrity ="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8= " crossorigin > </ script >
20+ < script > window . addEventListener ( 'DOMContentLoaded' , ( ) => hljs . initHighlighting ( ) ) </ script >
21+ </ head >
22+ < body >
23+ < main >
24+ < article id ="content ">
25+ < header >
26+ < h1 class ="title "> Module < code > continuous_delivery_scripts.detect_secrets</ code > </ h1 >
27+ </ header >
28+ < section id ="section-intro ">
29+ < p > Check tracked files against the project's recorded secret registry.</ p >
30+ < details class ="source ">
31+ < summary >
32+ < span > Expand source code</ span >
33+ </ summary >
34+ < pre > < code class ="python "> #
35+ # Copyright (C) 2020-2026 Arm Limited or its affiliates and Contributors. All rights reserved.
36+ # SPDX-License-Identifier: Apache-2.0
37+ #
38+ """Check tracked files against the project's recorded secret registry."""
39+
40+ import argparse
41+ import logging
42+ import subprocess
43+ import sys
44+ from pathlib import Path
45+ from typing import List, Optional
46+
47+ from continuous_delivery_scripts.update_secrets_registry import (
48+ _determine_exclude_files,
49+ _get_secrets_baseline_file,
50+ _get_secrets_baseline_filename,
51+ )
52+ from continuous_delivery_scripts.utils.git_helpers import ProjectGitWrapper
53+ from continuous_delivery_scripts.utils.logging import log_exception, set_log_level
54+
55+ logger = logging.getLogger(__name__)
56+
57+
58+ def _generate_detect_secrets_hook_command_list(
59+ baseline_file: Path, exclude_files: List[str], tracked_files: List[str]
60+ ) -> List[str]:
61+ command = ["detect-secrets-hook", "--baseline", str(baseline_file)]
62+ for exclude_file in exclude_files:
63+ command.extend(["--exclude-files", exclude_file])
64+ command.extend(tracked_files)
65+ return command
66+
67+
68+ def _filter_tracked_files(tracked_files: List[str], project_root: Path, registry_file: Path) -> List[str]:
69+ """Remove the registry file from tracked files to avoid scanning recorded accepted findings."""
70+ try:
71+ registry_relative_path = registry_file.relative_to(project_root).as_posix()
72+ except ValueError:
73+ return tracked_files
74+ return [path for path in tracked_files if path != registry_relative_path]
75+
76+
77+ def detect_secrets(baseline_file: Optional[Path] = None) -> None:
78+ """Check tracked files so new secrets are not introduced."""
79+ git = ProjectGitWrapper()
80+ project_root = Path(str(git.root))
81+ resolved_baseline = _get_secrets_baseline_file(baseline_file)
82+ tracked_files = _filter_tracked_files(git.list_tracked_files(), project_root, resolved_baseline)
83+ if not tracked_files:
84+ logger.info("No tracked files found for detect-secrets.")
85+ return
86+ subprocess.check_call(
87+ _generate_detect_secrets_hook_command_list(resolved_baseline, _determine_exclude_files(), tracked_files),
88+ cwd=str(project_root),
89+ )
90+
91+
92+ def main() -> int:
93+ """Script CLI."""
94+ parser = argparse.ArgumentParser(
95+ description=(
96+ "Check tracked files against the recorded secret registry so new secrets are not committed. "
97+ "This uses Yelp detect-secrets (https://github.com/Yelp/detect-secrets)."
98+ )
99+ )
100+ parser.add_argument(
101+ "-r",
102+ "--registry-file",
103+ default=Path(_get_secrets_baseline_filename()),
104+ help="Secret registry file to use.",
105+ type=Path,
106+ )
107+ parser.add_argument(
108+ "-v",
109+ "--verbose",
110+ action="count",
111+ default=0,
112+ help="Verbosity, by default errors are reported.",
113+ )
114+ args = parser.parse_args()
115+ set_log_level(args.verbose)
116+
117+ try:
118+ detect_secrets(args.registry_file)
119+ return 0
120+ except Exception as e:
121+ log_exception(logger, e)
122+ return 1
123+
124+
125+ if __name__ == "__main__":
126+ sys.exit(main())</ code > </ pre >
127+ </ details >
128+ </ section >
129+ < section >
130+ </ section >
131+ < section >
132+ </ section >
133+ < section >
134+ < h2 class ="section-title " id ="header-functions "> Functions</ h2 >
135+ < dl >
136+ < dt id ="continuous_delivery_scripts.detect_secrets.detect_secrets "> < code class ="name flex ">
137+ < span > def < span class ="ident "> detect_secrets</ span > </ span > (< span > baseline_file: Optional[pathlib.Path] = None) ‑> None</ span >
138+ </ code > </ dt >
139+ < dd >
140+ < div class ="desc "> < p > Check tracked files so new secrets are not introduced.</ p > </ div >
141+ < details class ="source ">
142+ < summary >
143+ < span > Expand source code</ span >
144+ </ summary >
145+ < pre > < code class ="python "> def detect_secrets(baseline_file: Optional[Path] = None) -> None:
146+ """Check tracked files so new secrets are not introduced."""
147+ git = ProjectGitWrapper()
148+ project_root = Path(str(git.root))
149+ resolved_baseline = _get_secrets_baseline_file(baseline_file)
150+ tracked_files = _filter_tracked_files(git.list_tracked_files(), project_root, resolved_baseline)
151+ if not tracked_files:
152+ logger.info("No tracked files found for detect-secrets.")
153+ return
154+ subprocess.check_call(
155+ _generate_detect_secrets_hook_command_list(resolved_baseline, _determine_exclude_files(), tracked_files),
156+ cwd=str(project_root),
157+ )</ code > </ pre >
158+ </ details >
159+ </ dd >
160+ < dt id ="continuous_delivery_scripts.detect_secrets.main "> < code class ="name flex ">
161+ < span > def < span class ="ident "> main</ span > </ span > (< span > ) ‑> int</ span >
162+ </ code > </ dt >
163+ < dd >
164+ < div class ="desc "> < p > Script CLI.</ p > </ div >
165+ < details class ="source ">
166+ < summary >
167+ < span > Expand source code</ span >
168+ </ summary >
169+ < pre > < code class ="python "> def main() -> int:
170+ """Script CLI."""
171+ parser = argparse.ArgumentParser(
172+ description=(
173+ "Check tracked files against the recorded secret registry so new secrets are not committed. "
174+ "This uses Yelp detect-secrets (https://github.com/Yelp/detect-secrets)."
175+ )
176+ )
177+ parser.add_argument(
178+ "-r",
179+ "--registry-file",
180+ default=Path(_get_secrets_baseline_filename()),
181+ help="Secret registry file to use.",
182+ type=Path,
183+ )
184+ parser.add_argument(
185+ "-v",
186+ "--verbose",
187+ action="count",
188+ default=0,
189+ help="Verbosity, by default errors are reported.",
190+ )
191+ args = parser.parse_args()
192+ set_log_level(args.verbose)
193+
194+ try:
195+ detect_secrets(args.registry_file)
196+ return 0
197+ except Exception as e:
198+ log_exception(logger, e)
199+ return 1</ code > </ pre >
200+ </ details >
201+ </ dd >
202+ </ dl >
203+ </ section >
204+ < section >
205+ </ section >
206+ </ article >
207+ < nav id ="sidebar ">
208+ < h1 > Index</ h1 >
209+ < div class ="toc ">
210+ < ul > </ ul >
211+ </ div >
212+ < ul id ="index ">
213+ < li > < h3 > Super-module</ h3 >
214+ < ul >
215+ < li > < code > < a title ="continuous_delivery_scripts " href ="index.html "> continuous_delivery_scripts</ a > </ code > </ li >
216+ </ ul >
217+ </ li >
218+ < li > < h3 > < a href ="#header-functions "> Functions</ a > </ h3 >
219+ < ul class ="">
220+ < li > < code > < a title ="continuous_delivery_scripts.detect_secrets.detect_secrets " href ="#continuous_delivery_scripts.detect_secrets.detect_secrets "> detect_secrets</ a > </ code > </ li >
221+ < li > < code > < a title ="continuous_delivery_scripts.detect_secrets.main " href ="#continuous_delivery_scripts.detect_secrets.main "> main</ a > </ code > </ li >
222+ </ ul >
223+ </ li >
224+ </ ul >
225+ </ nav >
226+ </ main >
227+ < footer id ="footer ">
228+ < p > Generated by < a href ="https://pdoc3.github.io/pdoc " title ="pdoc: Python API documentation generator "> < cite > pdoc</ cite > 0.10.0</ a > .</ p >
229+ </ footer >
230+ </ body >
231+ </ html >
0 commit comments