11import json
22import logging
3+ from collections import Counter
34from pathlib import Path
4- from typing import Iterable
5+ from typing import Dict , Iterable , List
56
7+ from aws_doc_sdk_examples_tools .yaml_writer import prepare_write , write_many
8+
9+ from aws_doc_sdk_examples_tools .lliam .config import (
10+ AILLY_DIR_PATH ,
11+ BATCH_PREFIX ,
12+ )
13+ from aws_doc_sdk_examples_tools .lliam .domain .commands import UpdateReservoir
614from aws_doc_sdk_examples_tools .doc_gen import DocGen , Example
715
8- logging .basicConfig (level = logging .INFO )
916logger = logging .getLogger (__name__ )
1017
18+ IAM_LANGUAGE = "IAMPolicyGrammar"
19+
1120
12- def examples_from_updates (updates_path : Path ) -> Iterable [Example ]:
21+ def examples_from_updates (updates : List [ Dict ] ) -> Iterable [Example ]:
1322 """
14- Take a path to a file containing a list of example metadata updates
15- and returns an iterable of examples with the applied updates.
23+ Takes a list of example metadata updates and returns an
24+ iterable of examples with the applied updates.
1625 """
17- updates = json .loads (updates_path .read_text ())
1826
19- if isinstance (updates , list ):
20- updates_dict = {}
21- for item in updates :
22- if "id" in item :
23- updates_dict [item ["id" ]] = item
24- updates = updates_dict
27+ indexed_updates = {}
28+ for item in updates :
29+ if "id" in item :
30+ indexed_updates [item ["id" ]] = item
2531
2632 examples = [
2733 Example (
@@ -32,26 +38,78 @@ def examples_from_updates(updates_path: Path) -> Iterable[Example]:
3238 title_abbrev = update .get ("title_abbrev" ),
3339 synopsis = update .get ("synopsis" ),
3440 )
35- for id , update in updates .items ()
41+ for id , update in indexed_updates .items ()
3642 ]
3743 return examples
3844
3945
40- def update_examples (doc_gen : DocGen , examples : Iterable [Example ]) -> None :
46+ def make_title_abbreviation (old : Example , new : Example , abbreviations : Counter ):
47+ language = old .languages [IAM_LANGUAGE ]
48+ version = language .versions [0 ]
49+ source = version .source
50+ source_title = source .title if source else ""
51+ base = f"{ new .title_abbrev } (from '{ source_title } ' docs)"
52+ abbreviations [base ] += 1
53+ count = abbreviations [base ]
54+ return f"{ base } ({ count } )" if count > 1 else base
55+
56+
57+ def update_examples (doc_gen : DocGen , examples : Iterable [Example ]) -> Dict [str , Example ]:
4158 """
4259 Merge a subset of example properties into a DocGen instance.
4360 """
61+ title_abbrevs = Counter (
62+ [example .title_abbrev for example in doc_gen .examples .values ()]
63+ )
64+ updated = {}
4465 for example in examples :
4566 if doc_gen_example := doc_gen .examples .get (example .id ):
4667 doc_gen_example .title = example .title
47- doc_gen_example .title_abbrev = example .title_abbrev
68+ doc_gen_example .title_abbrev = make_title_abbreviation (
69+ old = doc_gen_example , new = example , abbreviations = title_abbrevs
70+ )
4871 doc_gen_example .synopsis = example .synopsis
72+ updated [doc_gen_example .id ] = doc_gen_example
4973 else :
5074 logger .warning (f"Could not find example with id: { example .id } " )
75+ return updated
5176
5277
53- def update_doc_gen (doc_gen_root : Path , iam_updates_path : Path ) -> DocGen :
78+ def update_doc_gen (doc_gen_root : Path , updates : List [ Dict ] ) -> Dict [ str , Example ] :
5479 doc_gen = DocGen .from_root (doc_gen_root )
55- examples = examples_from_updates (iam_updates_path )
56- update_examples (doc_gen , examples )
57- return doc_gen
80+ examples = examples_from_updates (updates )
81+ updated_examples = update_examples (doc_gen , examples )
82+ return updated_examples
83+
84+
85+ def handle_update_reservoir (cmd : UpdateReservoir , uow : None ):
86+ update_files = (
87+ [AILLY_DIR_PATH / f"updates_{ batch } .json" for batch in cmd .batches ]
88+ if cmd .batches
89+ else list (AILLY_DIR_PATH .glob (f"updates_{ BATCH_PREFIX } *.json" ))
90+ )
91+
92+ if not update_files :
93+ logger .warning ("No IAM update files found to process" )
94+ return
95+
96+ for update_file in sorted (update_files ):
97+ if update_file .exists ():
98+ logger .info (f"Processing updates from { update_file .name } " )
99+ updates = json .loads (update_file .read_text ())
100+ if cmd .packages :
101+ updates = [
102+ update
103+ for package , update_list in updates .items ()
104+ if package in cmd .packages
105+ for update in update_list
106+ ]
107+ if not updates :
108+ logger .warning (f"No matching updates to run in { update_file .name } " )
109+ continue
110+ examples = update_doc_gen (doc_gen_root = cmd .root , updates = updates )
111+
112+ writes = prepare_write (examples )
113+ write_many (cmd .root , writes )
114+ else :
115+ logger .warning (f"Update file not found: { update_file } " )
0 commit comments