Skip to content

Commit f37a1f3

Browse files
committed
Add source target filters to release-risk-monitor CLI
1 parent 47e81ff commit f37a1f3

3 files changed

Lines changed: 29 additions & 2 deletions

File tree

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,12 +78,13 @@ Exit code policy:
7878

7979
```bash
8080
python3 ./scripts/release-risk-monitor.py
81+
python3 ./scripts/release-risk-monitor.py citrix
82+
python3 ./scripts/release-risk-monitor.py sonicwall vmware
8183
python3 ./scripts/release-risk-monitor.py --output json
8284
python3 ./scripts/release-risk-monitor.py --output markdown
8385
python3 ./scripts/release-risk-monitor.py --alert-on high
8486
python3 ./scripts/release-risk-monitor.py --no-state --output json
8587
```
86-
8788
What it does:
8889

8990
- Tracks release and advisory pages for frequently targeted internet-facing products

scripts/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ Monitor selected vendor release notes, detect changes, extract CVEs, and apply h
3838
Examples:
3939
```bash
4040
python3 ./release-risk-monitor.py
41+
python3 ./release-risk-monitor.py citrix
42+
python3 ./release-risk-monitor.py sonicwall vmware
4143
python3 ./release-risk-monitor.py --output json
4244
python3 ./release-risk-monitor.py --output markdown
4345
python3 ./release-risk-monitor.py --alert-on high

scripts/release-risk-monitor.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,7 @@ def level_rank(level: str) -> int:
245245

246246
def parse_args() -> argparse.Namespace:
247247
p = argparse.ArgumentParser(description="Release notes monitor with high-risk scoring")
248+
p.add_argument("targets", nargs="*", help="Optional source filters, for example: citrix vmware sonicwall")
248249
p.add_argument("--json", action="store_true", help="Legacy JSON switch")
249250
p.add_argument("--output", choices=["text", "json", "markdown"], default="text", help="Output format")
250251
p.add_argument("--alert-on", choices=["low", "medium", "high", "none"], default="none", help="Exit non-zero if any item meets threshold")
@@ -253,6 +254,21 @@ def parse_args() -> argparse.Namespace:
253254
return p.parse_args()
254255

255256

257+
def select_sources(target_filters: list[str]) -> list[Source]:
258+
if not target_filters:
259+
return SOURCES
260+
261+
filters = [f.strip().lower() for f in target_filters if f.strip()]
262+
selected: list[Source] = []
263+
264+
for source in SOURCES:
265+
hay = f"{source.name} {source.product}".lower()
266+
if any(f in hay for f in filters):
267+
selected.append(source)
268+
269+
return selected
270+
271+
256272
def render_markdown(updates: list[ReleaseInfo]) -> str:
257273
if not updates:
258274
return "No new releases detected."
@@ -280,11 +296,19 @@ def main() -> int:
280296
ensure_dependencies()
281297
kev_set = load_kev_set()
282298

299+
active_sources = select_sources(args.targets)
300+
if not active_sources:
301+
print("No matching sources for provided targets.", file=sys.stderr)
302+
print("Available source names:", file=sys.stderr)
303+
for s in SOURCES:
304+
print(f"- {s.name}", file=sys.stderr)
305+
return 1
306+
283307
old_state = {} if args.no_state else load_state()
284308
new_state: dict = {}
285309
updates: list[ReleaseInfo] = []
286310

287-
for source in SOURCES:
311+
for source in active_sources:
288312
try:
289313
html = fetch(source.url)
290314
text = text_from_html(html)

0 commit comments

Comments
 (0)