1+ #!/usr/bin/env python3
2+ from pathlib import Path
3+ import json
4+ import sys
5+ import re
6+
7+ # This script validates that:
8+ # - All SDK modules are mapped or skipped for internal import
9+ # - All non-SDK dependencies of imported modules are mapped to internal
10+ # packages
11+ #
12+ # Usage: validate-brazil-config [module-paths-file] [dependencies-file]
13+
14+ # Generating module-paths-file:
15+ # mvn exec:exec -Dexec.executable=pwd -pl \!:aws-sdk-java-pom,\!:sdk-benchmarks,\!:module-path-tests -q 2>&1 > modules.txt
16+ #
17+ # Generates contents similar to:
18+ # /workspace/aws-sdk-java-v2/build-tools
19+ # /workspace/aws-sdk-java-v2/core
20+ # /workspace/aws-sdk-java-v2/core/annotations
21+ # /workspace/aws-sdk-java-v2/utils
22+ # /workspace/aws-sdk-java-v2/test/test-utils
23+ # /workspace/aws-sdk-java-v2/core/metrics-spi
24+ # /workspace/aws-sdk-java-v2/http-client-spi
25+ # /workspace/aws-sdk-java-v2/core/endpoints-spi
26+ # /workspace/aws-sdk-java-v2/core/identity-spi
27+ # /workspace/aws-sdk-java-v2/core/http-auth-spi
28+ # ...
29+
30+ # Generating dependencies-file:
31+ # mvn dependency:list -DexcludeTransitive=true -DincludeScope=runtime 2>&1 > deps.txt
32+ #
33+ # Generates content similar to:
34+ #
35+ # [INFO] -----------------< software.amazon.awssdk:test-utils >------------------
36+ # [INFO] Building AWS Java SDK :: Test :: Test Utils 2.31.61-SNAPSHOT [6/493]
37+ # [INFO] from test/test-utils/pom.xml
38+ # [INFO] --------------------------------[ jar ]---------------------------------
39+ # [INFO]
40+ # [INFO] --- dependency:3.1.1:list (default-cli) @ test-utils ---
41+ # [INFO]
42+ # [INFO] The following files have been resolved:
43+ # [INFO] org.slf4j:slf4j-api:jar:1.7.36:compile -- module org.slf4j [auto]
44+ # [INFO] org.junit.jupiter:junit-jupiter:jar:5.10.0:compile -- module org.junit.jupiter
45+ # [INFO] com.fasterxml.jackson.core:jackson-core:jar:2.15.2:compile -- module com.fasterxml.jackson.core
46+ # ...
47+
48+ brazil_import_config_path = ".brazil.json"
49+
50+ with open (brazil_import_config_path ) as f :
51+ brazil_import_config = json .loads (f .read ())
52+
53+ modules_path = sys .argv [1 ]
54+
55+ core_modules = set ()
56+
57+ with open (modules_path ) as f :
58+ for l in f .readlines ():
59+ l = l .strip ()
60+ module_path = Path (l )
61+ name = module_path .name
62+ if module_path .parent .name != 'services' :
63+ core_modules .add (name )
64+
65+ # Ensure all 'core' modules are mapped. For the purposes of this validation, we
66+ # don't care if we map to a package name or skip import.
67+ config_modules = brazil_import_config ['modules' ]
68+ for core_module in core_modules :
69+ if core_module not in config_modules :
70+ raise Exception (f"The module { core_module } is not mapped!" )
71+
72+
73+ # Ensure all dependencies are mapped.
74+ current_module_pattern = re .compile (r"\[INFO\] --- .*:list \(default-cli\) @ (.*) ---" )
75+ dependency_pattern = re .compile (r"\[INFO\] ([^: ]+:[^: ]+):jar:[^: ]+:(compile|runtime)" )
76+
77+ deps_path = sys .argv [2 ]
78+ config_dependencies = brazil_import_config ['dependencies' ]
79+ with open (deps_path ) as f :
80+ for l in f .readlines ():
81+ # Match a line that gives the name of the current module
82+ match = current_module_pattern .match (l )
83+ if match is not None :
84+ # Unless explicitly skipped, all modules are imported
85+ skipping_import = False
86+ current_module = match .group (1 )
87+
88+ if current_module in config_modules :
89+ module_import = config_modules [current_module ]
90+
91+ if 'skipImport' in module_import and module_import ['skipImport' ]:
92+ print (f"Module import skipped for { current_module } " )
93+ skipping_import = True
94+
95+ continue
96+
97+ # Match a line that gives a dependency of a given module
98+ match = dependency_pattern .match (l )
99+ if match is not None and \
100+ not skipping_import and \
101+ not match .group (1 ).startswith ("software.amazon.awssdk:" ):
102+ # The current module is being imported, and this dependency is not an SDK
103+ # module. Ensure that it's mapped
104+ dependency_name = match .group (1 )
105+ if dependency_name not in config_dependencies :
106+ raise Exception (f"The dependency { dependency_name } is not mapped!" )
0 commit comments