22import logging
33import time
44from collections import defaultdict
5+ from dataclasses import dataclass
56from datetime import timedelta
67from pathlib import Path
78from subprocess import run
89from typing import Any , Dict , List , Optional , Set
910
1011from aws_doc_sdk_examples_tools .lliam .domain .commands import RunAilly
12+ from aws_doc_sdk_examples_tools .lliam .domain .errors import (
13+ CommandExecutionError ,
14+ DomainError ,
15+ )
1116from aws_doc_sdk_examples_tools .lliam .config import (
1217 AILLY_DIR_PATH ,
1318 BATCH_PREFIX ,
1419)
1520
21+ AILLY_CMD_BASE = [
22+ "ailly" ,
23+ "--max-depth" ,
24+ "10" ,
25+ "--root" ,
26+ str (AILLY_DIR_PATH ),
27+ ]
28+
1629logger = logging .getLogger (__file__ )
1730
1831
1932def handle_run_ailly (cmd : RunAilly , uow : None ):
2033 resolved_batches = resolve_requested_batches (cmd .batches )
2134
35+ errors : List [DomainError ] = []
36+
2237 if resolved_batches :
2338 total_start_time = time .time ()
2439
2540 for batch in resolved_batches :
26- run_ailly_single_batch (batch )
41+ try :
42+ run_ailly_single_batch (batch , cmd .packages )
43+ except FileNotFoundError as e :
44+ errors .append (
45+ CommandExecutionError (
46+ command_name = cmd .__class__ .__name__ , message = str (e )
47+ )
48+ )
2749
2850 total_end_time = time .time ()
2951 total_duration = total_end_time - total_start_time
@@ -32,6 +54,8 @@ def handle_run_ailly(cmd: RunAilly, uow: None):
3254 f"[TIMECHECK] { num_batches } batches took { format_duration (total_duration )} to run"
3355 )
3456
57+ return errors
58+
3559
3660def resolve_requested_batches (batch_names : List [str ]) -> List [Path ]:
3761 if not batch_names :
@@ -56,19 +80,26 @@ def resolve_requested_batches(batch_names: List[str]) -> List[Path]:
5680 return batch_paths
5781
5882
59- def run_ailly_single_batch (batch : Path ) -> None :
83+ def run_ailly_single_batch (batch : Path , packages : List [ str ] = [] ) -> None :
6084 """Run ailly and process files for a single batch."""
6185 batch_start_time = time .time ()
6286 iam_updates_path = AILLY_DIR_PATH / f"updates_{ batch .name } .json"
6387
64- cmd = [
65- "ailly" ,
66- "--max-depth" ,
67- "10" ,
68- "--root" ,
69- str (AILLY_DIR_PATH ),
70- batch .name ,
71- ]
88+ if packages :
89+ paths = []
90+ for package in packages :
91+ package_files = [
92+ f"{ batch .name } /{ p .name } " for p in batch .glob (f"*{ package } *.md" )
93+ ]
94+ paths .extend (package_files )
95+
96+ if not paths :
97+ raise FileNotFoundError (f"No matching files found for packages: { packages } " )
98+
99+ cmd = AILLY_CMD_BASE + paths
100+ else :
101+ cmd = AILLY_CMD_BASE + [batch .name ]
102+
72103 logger .info (f"Running { cmd } " )
73104 run (cmd )
74105
@@ -79,7 +110,9 @@ def run_ailly_single_batch(batch: Path) -> None:
79110 )
80111
81112 logger .info (f"Processing generated content for { batch .name } " )
82- process_ailly_files (input_dir = batch , output_file = iam_updates_path )
113+ process_ailly_files (
114+ input_dir = batch , output_file = iam_updates_path , packages = packages
115+ )
83116
84117
85118EXPECTED_KEYS : Set [str ] = set (["title" , "title_abbrev" ])
@@ -177,7 +210,10 @@ def parse_package_name(policy_update: Dict[str, str]) -> Optional[str]:
177210
178211
179212def process_ailly_files (
180- input_dir : Path , output_file : Path , file_pattern : str = "*.md.ailly.md"
213+ input_dir : Path ,
214+ output_file : Path ,
215+ file_pattern : str = "*.md.ailly.md" ,
216+ packages : List [str ] = [],
181217) -> None :
182218 """
183219 Process all .md.ailly.md files in the input directory and write the results as JSON to the output file.
@@ -186,6 +222,7 @@ def process_ailly_files(
186222 input_dir: Directory containing .md.ailly.md files
187223 output_file: Path to the output JSON file
188224 file_pattern: Pattern to match files (default: "*.md.ailly.md")
225+ packages: Optional list of packages to filter by
189226 """
190227 results = defaultdict (list )
191228
@@ -197,6 +234,13 @@ def process_ailly_files(
197234 package_name = parse_package_name (policy_update )
198235 if not package_name :
199236 raise TypeError (f"Could not get package name from policy update." )
237+
238+ if packages and package_name not in packages :
239+ logger .info (
240+ f"Skipping package { package_name } (not in requested packages)"
241+ )
242+ continue
243+
200244 results [package_name ].append (policy_update )
201245
202246 with open (output_file , "w" , encoding = "utf-8" ) as out_file :
0 commit comments