|
8 | 8 | from dataclasses import dataclass, field, is_dataclass, asdict |
9 | 9 | from functools import reduce |
10 | 10 | from pathlib import Path |
11 | | -from typing import Dict, Iterable, Optional, Set, Tuple |
| 11 | +from typing import Dict, Iterable, Optional, Set, Tuple, List, Any |
12 | 12 |
|
13 | 13 | # from os import glob |
14 | 14 |
|
15 | 15 | from .metadata import ( |
16 | 16 | Example, |
17 | | - parse as parse_examples, |
| 17 | + DocFilenames, |
| 18 | + SDKPages, |
| 19 | + SDKPageVersion, |
| 20 | + CrossServicePage, |
18 | 21 | validate_no_duplicate_api_examples, |
19 | 22 | ) |
20 | 23 | from .entities import expand_all_entities, EntityErrors |
21 | | -from .metadata_errors import MetadataErrors, MetadataError |
| 24 | +from .metadata_errors import ( |
| 25 | + MetadataErrors, |
| 26 | + MetadataError, |
| 27 | + NameFormat, |
| 28 | + ActionNameFormat, |
| 29 | + ServiceNameFormat, |
| 30 | +) |
22 | 31 | from .metadata_validator import validate_metadata |
23 | 32 | from .project_validator import ValidationConfig |
24 | 33 | from .sdks import Sdk, parse as parse_sdks |
|
29 | 38 | collect_snippet_files, |
30 | 39 | validate_snippets, |
31 | 40 | ) |
| 41 | +from .yaml_mapper import example_from_yaml |
32 | 42 |
|
33 | 43 |
|
34 | 44 | @dataclass |
@@ -322,3 +332,91 @@ def default(self, obj): |
322 | 332 | return {"__set__": list(obj)} |
323 | 333 |
|
324 | 334 | return super().default(obj) |
| 335 | + |
| 336 | + |
| 337 | +def parse_examples( |
| 338 | + file: Path, |
| 339 | + yaml: Dict[str, Any], |
| 340 | + sdks: Dict[str, Sdk], |
| 341 | + services: Dict[str, Service], |
| 342 | + blocks: Set[str], |
| 343 | + validation: Optional[ValidationConfig], |
| 344 | + root: Optional[Path] = None, |
| 345 | +) -> Tuple[List[Example], MetadataErrors]: |
| 346 | + examples: List[Example] = [] |
| 347 | + errors = MetadataErrors() |
| 348 | + validation = validation or ValidationConfig() |
| 349 | + for id in yaml: |
| 350 | + example, example_errors = example_from_yaml( |
| 351 | + yaml[id], sdks, services, blocks, validation, root or file.parent |
| 352 | + ) |
| 353 | + check_id_format( |
| 354 | + id, |
| 355 | + example.services, |
| 356 | + validation.strict_titles and example.category == "Api", |
| 357 | + example_errors, |
| 358 | + ) |
| 359 | + for error in example_errors: |
| 360 | + error.file = file |
| 361 | + error.id = id |
| 362 | + errors.extend(example_errors) |
| 363 | + example.file = file |
| 364 | + example.id = id |
| 365 | + example.doc_filenames = get_doc_filenames(id, example) |
| 366 | + examples.append(example) |
| 367 | + |
| 368 | + return examples, errors |
| 369 | + |
| 370 | + |
| 371 | +def check_id_format( |
| 372 | + id: str, |
| 373 | + parsed_services: Dict[str, Set[str]], |
| 374 | + check_action: bool, |
| 375 | + errors: MetadataErrors, |
| 376 | +): |
| 377 | + [service, *rest] = id.split("_") |
| 378 | + if len(rest) == 0: |
| 379 | + errors.append(NameFormat(id=id)) |
| 380 | + elif service not in parsed_services and service not in ["cross", "serverless"]: |
| 381 | + errors.append( |
| 382 | + ServiceNameFormat(id=id, svc=service, svcs=[*parsed_services.keys()]) |
| 383 | + ) |
| 384 | + elif check_action and ( |
| 385 | + len(rest) > 1 or rest[0] not in parsed_services.get(service, {}) |
| 386 | + ): |
| 387 | + errors.append(ActionNameFormat(id=id)) |
| 388 | + |
| 389 | + |
| 390 | +def get_doc_filenames(example_id: str, example: Example) -> Optional[DocFilenames]: |
| 391 | + base_url = "https://docs.aws.amazon.com/code-library/latest/ug" |
| 392 | + service_pages = { |
| 393 | + service_id: f"{base_url}/{service_id}_example_{example_id}_section.html" |
| 394 | + for service_id in example.services |
| 395 | + } |
| 396 | + |
| 397 | + if example.file is not None: |
| 398 | + is_cross = example.file.match("cross_*") |
| 399 | + else: |
| 400 | + is_cross = False |
| 401 | + |
| 402 | + sdk_pages: SDKPages = {} |
| 403 | + |
| 404 | + for language in example.languages.values(): |
| 405 | + sdk_pages[language.property] = {} |
| 406 | + for version in language.versions: |
| 407 | + if is_cross: |
| 408 | + sdk_pages[language.property][version.sdk_version] = SDKPageVersion( |
| 409 | + cross_service=CrossServicePage( |
| 410 | + cross=f"{base_url}/{example_id}_{language.property}_{version.sdk_version}_topic.html" |
| 411 | + ) |
| 412 | + ) |
| 413 | + else: |
| 414 | + anchor = "actions" if example.category == "Actions" else "scenarios" |
| 415 | + sdk_pages[language.property][version.sdk_version] = SDKPageVersion( |
| 416 | + actions_scenarios={ |
| 417 | + service_id: f"{base_url}/{language.property}_{version.sdk_version}_{service_id}_code_examples.html#{anchor}" |
| 418 | + for service_id in example.services |
| 419 | + } |
| 420 | + ) |
| 421 | + |
| 422 | + return DocFilenames(service_pages, sdk_pages) |
0 commit comments