Skip to content

Commit da32d1b

Browse files
committed
Add -tools build command to modularize internal build processing.
1 parent a2af7d4 commit da32d1b

File tree

4 files changed

+111
-4
lines changed

4 files changed

+111
-4
lines changed
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
from dataclasses import dataclass, field
2+
import logging
3+
from pathlib import Path
4+
import re
5+
from typing import List, Optional, cast
6+
7+
from aws_doc_sdk_examples_tools.doc_gen import DocGen
8+
from aws_doc_sdk_examples_tools.fs import Fs, PathFs
9+
from aws_doc_sdk_examples_tools.snippets import write_snippets
10+
11+
logging.basicConfig(level=logging.INFO)
12+
13+
logger = logging.getLogger(Path(__file__).name)
14+
15+
16+
IAM_PATTERN = re.compile(r'"Version"\s*:\s*"20(08|12)-10-17"\s*,')
17+
IAM_PATTERN_SLASHES = re.compile(r'\\"Version\\"\s*:\s*\\"20(08|12)-10-17\\"\s*,')
18+
# This exciting set of unicode characters is the expanded version of the &IAM-2025-waiver; entity.
19+
IAM_WAIVER = '"Version":"2012-10-17",\u0009\u0009\u0020\u0009\u0020\u0009\u0020'
20+
IAM_WAIVER_SLASHES = '\\"Version\\":\\"2012-10-17\\",\u0009\u0009\u0020\u0009\u0020\u0009\u0020'
21+
22+
23+
def _iam_replace_all(source: Optional[str]):
24+
if source:
25+
return IAM_PATTERN_SLASHES.subn(IAM_WAIVER_SLASHES, IAM_PATTERN.subn(IAM_WAIVER, source)[0])[0]
26+
return None
27+
28+
29+
def _iam_fixup_metadata(meta_folder: Path):
30+
for meta_path in meta_folder.glob("**/*_metadata.yaml"):
31+
with meta_path.open("r") as meta_file:
32+
contents = meta_file.read()
33+
contents = cast(str, _iam_replace_all(contents))
34+
with meta_path.open("w") as meta_file:
35+
meta_file.write(contents)
36+
37+
38+
def _iam_fixup_docgen(doc_gen: DocGen) -> DocGen:
39+
# For performance, do this mutably, but keep the signature open to making DocGen frozen
40+
for snippet in doc_gen.snippets.values():
41+
snippet.code = cast(str, _iam_replace_all(snippet.code))
42+
return doc_gen
43+
44+
45+
@dataclass
46+
class Builder:
47+
root: Path
48+
dest: Path
49+
doc_gen_folder = ".doc_gen"
50+
snippet_files_folder = "snippet_files"
51+
fs: Fs = field(default_factory=PathFs)
52+
_doc_gen: DocGen = field(init=False)
53+
54+
def __post_init__(self):
55+
self._doc_gen = DocGen.from_root(self.root)
56+
57+
def copy_doc_gen(self):
58+
tmp_mirror_doc_gen = self.root / self.doc_gen_folder
59+
mirror_doc_gen = self.dest / self.doc_gen_folder
60+
logger.info(f"Moving cloned files into package from {tmp_mirror_doc_gen} to {mirror_doc_gen}")
61+
try:
62+
self.fs.copytree(tmp_mirror_doc_gen, mirror_doc_gen)
63+
except Exception as e:
64+
logger.error(f"Failed copy directory {tmp_mirror_doc_gen} to {mirror_doc_gen}\n{e}")
65+
logger.error(e)
66+
raise
67+
68+
def write_snippets(self):
69+
write_snippets(self.dest / self.doc_gen_folder / self.snippet_files_folder, self._doc_gen.snippets)
70+
71+
def run(self):
72+
logger.debug("Copying docgen files...")
73+
self.copy_doc_gen()
74+
_iam_fixup_metadata(self.dest)
75+
logger.debug("Collecting snippets...")
76+
self._doc_gen.collect_snippets()
77+
self._doc_gen = _iam_fixup_docgen(self._doc_gen)
78+
logger.debug("Writing snippets...")
79+
self.write_snippets()
80+
81+
82+
def main():
83+
from argparse import ArgumentParser
84+
argparse = ArgumentParser()
85+
argparse.add_argument('--root', type=Path, default=Path())
86+
argparse.add_argument('--dest', type=Path)
87+
# Load a config from somewhere to get doc_gen_folder and snippets_files_folder
88+
args = argparse.parse_args()
89+
90+
builder = Builder(args.root, args.dest)
91+
builder.run()
92+
93+
94+
if __name__ == "__main__":
95+
main()

aws_doc_sdk_examples_tools/builder_test.py

Whitespace-only changes.

aws_doc_sdk_examples_tools/fs.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from fnmatch import fnmatch
44
from os import listdir
55
from pathlib import Path
6+
import shutil
67
from stat import S_ISREG
78
from typing import Dict, Generator, List
89

@@ -47,6 +48,9 @@ def mkdir(self, path: Path):
4748
def list(self, path: Path) -> List[Path]:
4849
pass
4950

51+
@abstractmethod
52+
def copytree(self, source: Path, dest: Path):
53+
pass
5054

5155
class PathFs(Fs):
5256
def glob(self, path: Path, glob: str) -> Generator[Path, None, None]:
@@ -78,6 +82,9 @@ def list(self, path: Path) -> List[Path]:
7882
if self.stat(path).is_file:
7983
return []
8084
return [path / name for name in listdir(path)]
85+
86+
def copytree(self, source: Path, dest: Path):
87+
shutil.copytree(source, dest)
8188

8289

8390
class RecordFs(Fs):
@@ -137,5 +144,10 @@ def list(self, path: Path) -> List[Path]:
137144

138145
return sorted(children)
139146

147+
def copytree(self, source: Path, dest: Path):
148+
for child in self.list(source):
149+
path = child.relative_to(dest).absolute()
150+
self.fs[path] = self.fs[child]
151+
140152

141153
fs = PathFs()

aws_doc_sdk_examples_tools/snippets.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
ValidationConfig,
1818
)
1919
from . import validator_config
20+
from aws_doc_sdk_examples_tools import fs
2021

2122
SNIPPET_START = "snippet-start:["
2223
SNIPPET_END = "snippet-end:["
@@ -309,16 +310,15 @@ def validate_snippets(
309310
verify_no_secret_keys(snippet.code, root / snippet.file, validation, errors)
310311

311312

312-
def write_snippets(root: Path, snippets: Dict[str, Snippet], check: bool = False):
313+
def write_snippets(root: Path, snippets: Dict[str, Snippet], check: bool = False, fs: Fs = fs.fs):
313314
errors = MetadataErrors()
314315
for tag in snippets:
315316
name = root / f"{tag}.txt"
316-
if check and name.exists():
317+
if check and fs.stat(name).exists:
317318
errors.append(SnippetAlreadyWritten(file=name))
318319
else:
319320
try:
320-
with open(name, "w", encoding="utf-8") as file:
321-
file.write(snippets[tag].code)
321+
fs.write(name, snippets[tag].code)
322322
except Exception as error:
323323
errors.append(SnippetWriteError(file=name, error=error))
324324
return errors

0 commit comments

Comments
 (0)