1313
1414@dataclass (frozen = True )
1515class ExampleArtifactSet :
16+ slug : str
1617 name : str
1718 base_args : tuple [str , ...]
1819 outputs : tuple [tuple [str , str ], ...]
@@ -22,6 +23,7 @@ class ExampleArtifactSet:
2223
2324ARTIFACT_SETS : tuple [ExampleArtifactSet , ...] = (
2425 ExampleArtifactSet (
26+ slug = "cyclonedx" ,
2527 name = "cyclonedx report, summary, and markdown" ,
2628 base_args = (
2729 "--before" ,
@@ -38,6 +40,7 @@ class ExampleArtifactSet:
3840 ),
3941 ),
4042 ExampleArtifactSet (
43+ slug = "policy-warn" ,
4144 name = "warn-only policy report" ,
4245 base_args = (
4346 "--before" ,
@@ -53,6 +56,7 @@ class ExampleArtifactSet:
5356 ),
5457 ),
5558 ExampleArtifactSet (
59+ slug = "policy-fail" ,
5660 name = "blocking policy report and sidecar" ,
5761 base_args = (
5862 "--before" ,
@@ -70,6 +74,7 @@ class ExampleArtifactSet:
7074 expected_exit_codes = (1 ,),
7175 ),
7276 ExampleArtifactSet (
77+ slug = "requirements" ,
7378 name = "requirements report" ,
7479 base_args = (
7580 "--before" ,
@@ -85,6 +90,7 @@ class ExampleArtifactSet:
8590 ),
8691 ),
8792 ExampleArtifactSet (
93+ slug = "sarif" ,
8894 name = "strict-policy SARIF report" ,
8995 base_args = (
9096 "--before" ,
@@ -112,28 +118,73 @@ def main(argv: Sequence[str] | None = None) -> int:
112118 action = "store_true" ,
113119 help = "Generate artifacts into a temporary directory and fail if checked-in examples are stale." ,
114120 )
121+ parser .add_argument (
122+ "--list" ,
123+ action = "store_true" ,
124+ help = "List available artifact set slugs and exit." ,
125+ )
126+ parser .add_argument (
127+ "--only" ,
128+ action = "append" ,
129+ default = [],
130+ metavar = "SLUG" ,
131+ help = "Regenerate or check only one artifact set slug. Repeat to select multiple sets." ,
132+ )
115133 args = parser .parse_args (argv )
116134
117135 project_root = Path (__file__ ).resolve ().parents [1 ]
136+ artifact_sets = _select_artifact_sets (args .only , parser )
137+ if args .list :
138+ _print_artifact_sets (artifact_sets )
139+ return 0
118140 if args .check :
119141 with tempfile .TemporaryDirectory (prefix = "sbom-diff-risk-examples-" ) as temp_dir :
120- return _check_artifacts (project_root , Path (temp_dir ))
121- return _write_artifacts (project_root , project_root / "examples" )
142+ return _check_artifacts (project_root , Path (temp_dir ), artifact_sets )
143+ return _write_artifacts (project_root , project_root / "examples" , artifact_sets )
144+
145+
146+ def _select_artifact_sets (
147+ selected_slugs : Sequence [str ],
148+ parser : argparse .ArgumentParser ,
149+ ) -> tuple [ExampleArtifactSet , ...]:
150+ if not selected_slugs :
151+ return ARTIFACT_SETS
152+
153+ by_slug = {artifact_set .slug : artifact_set for artifact_set in ARTIFACT_SETS }
154+ unknown = [slug for slug in selected_slugs if slug not in by_slug ]
155+ if unknown :
156+ parser .error (f"unknown artifact set slug: { unknown [0 ]} " )
157+
158+ return tuple (by_slug [slug ] for slug in selected_slugs )
159+
160+
161+ def _print_artifact_sets (artifact_sets : Sequence [ExampleArtifactSet ]) -> None :
162+ for artifact_set in artifact_sets :
163+ outputs = ", " .join (output_name for _ , output_name in artifact_set .outputs )
164+ print (f"{ artifact_set .slug } : { artifact_set .name } ({ outputs } )" )
122165
123166
124- def _write_artifacts (project_root : Path , output_root : Path ) -> int :
125- for artifact_set in ARTIFACT_SETS :
167+ def _write_artifacts (
168+ project_root : Path ,
169+ output_root : Path ,
170+ artifact_sets : Sequence [ExampleArtifactSet ],
171+ ) -> int :
172+ for artifact_set in artifact_sets :
126173 _run_artifact_set (project_root , output_root , artifact_set )
127- print (f"generated: { artifact_set .name } " )
174+ print (f"generated: { artifact_set .slug } " )
128175 return 0
129176
130177
131- def _check_artifacts (project_root : Path , output_root : Path ) -> int :
132- _write_artifacts (project_root , output_root )
178+ def _check_artifacts (
179+ project_root : Path ,
180+ output_root : Path ,
181+ artifact_sets : Sequence [ExampleArtifactSet ],
182+ ) -> int :
183+ _write_artifacts (project_root , output_root , artifact_sets )
133184
134185 examples_dir = project_root / "examples"
135186 stale_files : list [str ] = []
136- for artifact_set in ARTIFACT_SETS :
187+ for artifact_set in artifact_sets :
137188 for _ , output_name in artifact_set .outputs :
138189 expected = (examples_dir / output_name ).read_text (encoding = "utf-8" )
139190 generated = (output_root / output_name ).read_text (encoding = "utf-8" )
0 commit comments