Skip to content

Commit 8e1c4c6

Browse files
adamthom-amznsrchase
authored andcommitted
Fix dependency versioning of AWS-vended packages (smithy-lang#388)
smithy-aws-typescript-codegen bundles a properties file that has the version of every client and library that the JS SDK vends. This essentially ties that set of versions to the published version of the smithy-aws-typescript-codegen package. Instead of hardcoding specific versions of AWS clients and libraries, this change parses that file if smithy-aws-typescript-codegen is also on the classpath, so that we can use compatible versions of these packages when we generate package.json. If smithy-aws-typescript-codegen is not on the classpath we fall back to "latest" for these packages.
1 parent 4eb71fe commit 8e1c4c6

File tree

1 file changed

+79
-32
lines changed

1 file changed

+79
-32
lines changed

smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/TypeScriptDependency.java

Lines changed: 79 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,19 @@
1616
package software.amazon.smithy.typescript.codegen;
1717

1818

19+
import java.io.BufferedReader;
20+
import java.io.IOException;
21+
import java.io.InputStreamReader;
22+
import java.io.Reader;
23+
import java.net.URL;
24+
import java.nio.charset.StandardCharsets;
1925
import java.util.ArrayList;
2026
import java.util.Collections;
27+
import java.util.HashMap;
2128
import java.util.List;
29+
import java.util.Map;
30+
import java.util.Properties;
31+
import java.util.logging.Logger;
2232
import software.amazon.smithy.codegen.core.Symbol;
2333
import software.amazon.smithy.codegen.core.SymbolDependency;
2434
import software.amazon.smithy.codegen.core.SymbolDependencyContainer;
@@ -30,58 +40,58 @@
3040
@SmithyUnstableApi
3141
public enum TypeScriptDependency implements SymbolDependencyContainer {
3242

33-
AWS_SDK_CLIENT_DOCGEN("devDependencies", "@aws-sdk/client-documentation-generator", SdkVersion.LIVE, true),
34-
AWS_SDK_TYPES("dependencies", "@aws-sdk/types", SdkVersion.LIVE, true),
35-
AWS_SMITHY_CLIENT("dependencies", "@aws-sdk/smithy-client", SdkVersion.LIVE, true),
36-
INVALID_DEPENDENCY("dependencies", "@aws-sdk/invalid-dependency", SdkVersion.LIVE, true),
37-
CONFIG_RESOLVER("dependencies", "@aws-sdk/config-resolver", SdkVersion.LIVE, true),
43+
AWS_SDK_CLIENT_DOCGEN("devDependencies", "@aws-sdk/client-documentation-generator", true),
44+
AWS_SDK_TYPES("dependencies", "@aws-sdk/types", true),
45+
AWS_SMITHY_CLIENT("dependencies", "@aws-sdk/smithy-client", true),
46+
INVALID_DEPENDENCY("dependencies", "@aws-sdk/invalid-dependency", true),
47+
CONFIG_RESOLVER("dependencies", "@aws-sdk/config-resolver", true),
3848
TYPES_NODE("devDependencies", "@types/node", "^12.7.5", true),
3949

40-
MIDDLEWARE_CONTENT_LENGTH("dependencies", "@aws-sdk/middleware-content-length", SdkVersion.LIVE, true),
41-
MIDDLEWARE_SERDE("dependencies", "@aws-sdk/middleware-serde", SdkVersion.LIVE, true),
42-
MIDDLEWARE_RETRY("dependencies", "@aws-sdk/middleware-retry", SdkVersion.LIVE, true),
43-
MIDDLEWARE_STACK("dependencies", "@aws-sdk/middleware-stack", SdkVersion.LIVE, true),
50+
MIDDLEWARE_CONTENT_LENGTH("dependencies", "@aws-sdk/middleware-content-length", true),
51+
MIDDLEWARE_SERDE("dependencies", "@aws-sdk/middleware-serde", true),
52+
MIDDLEWARE_RETRY("dependencies", "@aws-sdk/middleware-retry", true),
53+
MIDDLEWARE_STACK("dependencies", "@aws-sdk/middleware-stack", true),
4454

4555
AWS_CRYPTO_SHA256_BROWSER("dependencies", "@aws-crypto/sha256-browser", "^1.1.0", true),
4656
AWS_CRYPTO_SHA256_JS("dependencies", "@aws-crypto/sha256-js", "^1.1.0", true),
47-
AWS_SDK_HASH_NODE("dependencies", "@aws-sdk/hash-node", SdkVersion.LIVE, true),
57+
AWS_SDK_HASH_NODE("dependencies", "@aws-sdk/hash-node", true),
4858

49-
AWS_SDK_URL_PARSER("dependencies", "@aws-sdk/url-parser", SdkVersion.LIVE, true),
59+
AWS_SDK_URL_PARSER("dependencies", "@aws-sdk/url-parser", true),
5060

51-
AWS_SDK_UTIL_BASE64_BROWSER("dependencies", "@aws-sdk/util-base64-browser", SdkVersion.LIVE, true),
52-
AWS_SDK_UTIL_BASE64_NODE("dependencies", "@aws-sdk/util-base64-node", SdkVersion.LIVE, true),
61+
AWS_SDK_UTIL_BASE64_BROWSER("dependencies", "@aws-sdk/util-base64-browser", true),
62+
AWS_SDK_UTIL_BASE64_NODE("dependencies", "@aws-sdk/util-base64-node", true),
5363

54-
AWS_SDK_UTIL_BODY_LENGTH_BROWSER("dependencies", "@aws-sdk/util-body-length-browser", SdkVersion.LIVE, true),
55-
AWS_SDK_UTIL_BODY_LENGTH_NODE("dependencies", "@aws-sdk/util-body-length-node", SdkVersion.LIVE, true),
64+
AWS_SDK_UTIL_BODY_LENGTH_BROWSER("dependencies", "@aws-sdk/util-body-length-browser", true),
65+
AWS_SDK_UTIL_BODY_LENGTH_NODE("dependencies", "@aws-sdk/util-body-length-node", true),
5666

57-
AWS_SDK_UTIL_UTF8_BROWSER("dependencies", "@aws-sdk/util-utf8-browser", SdkVersion.LIVE, true),
58-
AWS_SDK_UTIL_UTF8_NODE("dependencies", "@aws-sdk/util-utf8-node", SdkVersion.LIVE, true),
67+
AWS_SDK_UTIL_UTF8_BROWSER("dependencies", "@aws-sdk/util-utf8-browser", true),
68+
AWS_SDK_UTIL_UTF8_NODE("dependencies", "@aws-sdk/util-utf8-node", true),
5969

60-
AWS_SDK_UTIL_WAITERS("dependencies", "@aws-sdk/util-waiter", SdkVersion.LIVE, false),
70+
AWS_SDK_UTIL_WAITERS("dependencies", "@aws-sdk/util-waiter", false),
6171

6272
// Conditionally added when httpChecksumRequired trait exists
63-
MD5_BROWSER("dependencies", "@aws-sdk/md5-js", SdkVersion.LIVE, false),
64-
STREAM_HASHER_NODE("dependencies", "@aws-sdk/hash-stream-node", SdkVersion.LIVE, false),
65-
STREAM_HASHER_BROWSER("dependencies", "@aws-sdk/hash-blob-browser", SdkVersion.LIVE, false),
66-
BODY_CHECKSUM("dependencies", "@aws-sdk/middleware-apply-body-checksum", SdkVersion.LIVE, false),
73+
MD5_BROWSER("dependencies", "@aws-sdk/md5-js", false),
74+
STREAM_HASHER_NODE("dependencies", "@aws-sdk/hash-stream-node", false),
75+
STREAM_HASHER_BROWSER("dependencies", "@aws-sdk/hash-blob-browser", false),
76+
BODY_CHECKSUM("dependencies", "@aws-sdk/middleware-apply-body-checksum", false),
6777

6878
// Conditionally added when using an HTTP application protocol.
69-
AWS_SDK_PROTOCOL_HTTP("dependencies", "@aws-sdk/protocol-http", SdkVersion.LIVE, false),
70-
AWS_SDK_FETCH_HTTP_HANDLER("dependencies", "@aws-sdk/fetch-http-handler", SdkVersion.LIVE, false),
71-
AWS_SDK_NODE_HTTP_HANDLER("dependencies", "@aws-sdk/node-http-handler", SdkVersion.LIVE, false),
79+
AWS_SDK_PROTOCOL_HTTP("dependencies", "@aws-sdk/protocol-http", false),
80+
AWS_SDK_FETCH_HTTP_HANDLER("dependencies", "@aws-sdk/fetch-http-handler", false),
81+
AWS_SDK_NODE_HTTP_HANDLER("dependencies", "@aws-sdk/node-http-handler", false),
7282

7383
// Conditionally added if a event stream shape is found anywhere in the model
7484
AWS_SDK_EVENTSTREAM_SERDE_CONFIG_RESOLVER("dependencies", "@aws-sdk/eventstream-serde-config-resolver",
75-
SdkVersion.LIVE, false),
76-
AWS_SDK_EVENTSTREAM_SERDE_NODE("dependencies", "@aws-sdk/eventstream-serde-node", SdkVersion.LIVE, false),
77-
AWS_SDK_EVENTSTREAM_SERDE_BROWSER("dependencies", "@aws-sdk/eventstream-serde-browser", SdkVersion.LIVE, false),
85+
false),
86+
AWS_SDK_EVENTSTREAM_SERDE_NODE("dependencies", "@aws-sdk/eventstream-serde-node", false),
87+
AWS_SDK_EVENTSTREAM_SERDE_BROWSER("dependencies", "@aws-sdk/eventstream-serde-browser", false),
7888

7989
// Conditionally added if a big decimal shape is found in a model.
8090
BIG_JS("dependencies", "big.js", "^5.2.2", false),
8191
TYPES_BIG_JS("devDependencies", "@types/big.js", "^4.0.5", false),
8292

8393
// Conditionally added when interacting with specific protocol test bodyMediaType values.
84-
AWS_SDK_QUERYSTRING_BUILDER("dependencies", "@aws-sdk/querystring-builder", SdkVersion.LIVE, false),
94+
AWS_SDK_QUERYSTRING_BUILDER("dependencies", "@aws-sdk/querystring-builder", false),
8595

8696
// Conditionally added when XML parser needs to be used.
8797
XML_PARSER("dependencies", "fast-xml-parser", "3.19.0", false),
@@ -100,6 +110,10 @@ public enum TypeScriptDependency implements SymbolDependencyContainer {
100110
public final String version;
101111
public final SymbolDependency dependency;
102112

113+
TypeScriptDependency(String type, String name, boolean unconditional) {
114+
this(type, name, SdkVersion.getVersion(name), unconditional);
115+
}
116+
103117
TypeScriptDependency(String type, String name, String version, boolean unconditional) {
104118
this.dependency = SymbolDependency.builder()
105119
.dependencyType(type)
@@ -157,11 +171,44 @@ public Symbol createSymbol(String name) {
157171
}
158172

159173
/**
160-
* Holds package-wide constants, such as the current version of the AWS SDK for JS v3.
174+
* Reads the versions of AWS-published libraries from smithy-aws-typescript-codegen, if it's available
175+
* on the classpath.
161176
*/
162177
private static final class SdkVersion {
163-
static final String LIVE = "3.18.0";
178+
private static final Logger LOGGER = Logger.getLogger(SdkVersion.class.getName());
179+
private static final String PROPERTIES_PATH =
180+
"/software/amazon/smithy/aws/typescript/codegen/sdkVersions.properties";
181+
private static final Map<String, String> VERSIONS;
182+
183+
static {
184+
Map<String, String> tmpVersions;
185+
try {
186+
URL versionsUrl = SdkVersion.class.getResource(PROPERTIES_PATH);
187+
if (versionsUrl == null) {
188+
throw new IOException();
189+
}
190+
Properties p = new Properties();
191+
try (Reader r =
192+
new BufferedReader(new InputStreamReader(versionsUrl.openStream(), StandardCharsets.UTF_8))) {
193+
p.load(r);
194+
}
195+
final Map<String, String> versions = new HashMap<>(p.size());
196+
p.forEach((k, v) -> {
197+
if (versions.put(k.toString(), v.toString()) != null) {
198+
throw new IllegalArgumentException(String.format("Multiple versions defined for %s", k));
199+
}
200+
});
201+
tmpVersions = Collections.unmodifiableMap(versions);
202+
} catch (IOException e) {
203+
LOGGER.info("Could not read AWS dependency versions from smithy-aws-typescript-codegen, "
204+
+ "will use 'latest' for AWS dependencies");
205+
tmpVersions = Collections.emptyMap();
206+
}
207+
VERSIONS = tmpVersions;
208+
}
164209

165-
private SdkVersion() {}
210+
private static String getVersion(String packageName) {
211+
return VERSIONS.getOrDefault(packageName, "latest");
212+
}
166213
}
167214
}

0 commit comments

Comments
 (0)