Skip to content

Commit

Permalink
Automate versioning of @smithy packages (#832)
Browse files Browse the repository at this point in the history
  • Loading branch information
srchase authored Sep 8, 2023
1 parent 8e23b1b commit a7ad899
Show file tree
Hide file tree
Showing 4 changed files with 153 additions and 90 deletions.
46 changes: 0 additions & 46 deletions scripts/update-codegen-package-versions.js

This file was deleted.

33 changes: 33 additions & 0 deletions smithy-typescript-codegen/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
* permissions and limitations under the License.
*/

import software.amazon.smithy.model.node.Node

description = "Generates TypeScript code from Smithy models"
extra["displayName"] = "Smithy :: Typescript :: Codegen"
extra["moduleName"] = "software.amazon.smithy.typescript.codegen"
Expand All @@ -37,3 +39,34 @@ dependencies {
api("software.amazon.smithy:smithy-waiters:$smithyVersion")
implementation("software.amazon.smithy:smithy-protocol-test-traits:$smithyVersion")
}

sourceSets {
main {
resources {
setSrcDirs(listOf("src/main/resources", "$buildDir/generated/resources"))
}
}
}

tasks.register("set-dependency-versions") {
doLast {
mkdir("$buildDir/generated/resources/software/amazon/smithy/typescript/codegen")
var versionsFile =
file("$buildDir/generated/resources/software/amazon/smithy/typescript/codegen/dependencyVersions.properties")
var roots = project.file("../packages").listFiles().toMutableList() + project.file("../smithy-typescript-ssdk-libs").listFiles().toList()
roots.forEach { packageDir ->
var packageJsonFile = File(packageDir, "package.json")
if (packageJsonFile.isFile()) {
var packageJson = Node.parse(packageJsonFile.readText()).expectObjectNode()
var packageName = packageJson.expectStringMember("name").getValue()
var packageVersion = packageJson.expectStringMember("version").getValue()
var isPrivate = packageJson.getBooleanMemberOrDefault("private", false)
if (!isPrivate) {
versionsFile.appendText("$packageName=$packageVersion\n")
}
}
}
}
}

tasks["processResources"].dependsOn(tasks["set-dependency-versions"])
Original file line number Diff line number Diff line change
Expand Up @@ -38,95 +38,96 @@
@SmithyUnstableApi
public enum TypeScriptDependency implements Dependency {

AWS_SDK_CLIENT_DOCGEN("devDependencies", "@smithy/service-client-documentation-generator", "^2.0.0", true),
AWS_SDK_CLIENT_DOCGEN("devDependencies", "@smithy/service-client-documentation-generator", true),
AWS_SDK_TYPES("dependencies", "@aws-sdk/types", true),
SMITHY_TYPES("dependencies", "@smithy/types", "^2.3.0", true),
AWS_SMITHY_CLIENT("dependencies", "@smithy/smithy-client", "^2.1.3", true),
INVALID_DEPENDENCY("dependencies", "@smithy/invalid-dependency", "^2.0.6", true),
CONFIG_RESOLVER("dependencies", "@smithy/config-resolver", "^2.0.7", true),
SMITHY_TYPES("dependencies", "@smithy/types", true),
AWS_SMITHY_CLIENT("dependencies", "@smithy/smithy-client", true),
INVALID_DEPENDENCY("dependencies", "@smithy/invalid-dependency", true),
CONFIG_RESOLVER("dependencies", "@smithy/config-resolver", true),
TYPES_NODE("devDependencies", "@types/node", "^14.14.31", true),

MIDDLEWARE_CONTENT_LENGTH("dependencies", "@smithy/middleware-content-length", "^2.0.8", true),
MIDDLEWARE_SERDE("dependencies", "@smithy/middleware-serde", "^2.0.6", true),
MIDDLEWARE_RETRY("dependencies", "@smithy/middleware-retry", "^2.0.9", true),
UTIL_RETRY("dependencies", "@smithy/util-retry", "^2.0.0", false),
MIDDLEWARE_STACK("dependencies", "@smithy/middleware-stack", "^2.0.0", true),
MIDDLEWARE_ENDPOINTS_V2("dependencies", "@smithy/middleware-endpoint", "^2.0.6", false),
MIDDLEWARE_CONTENT_LENGTH("dependencies", "@smithy/middleware-content-length", true),
MIDDLEWARE_SERDE("dependencies", "@smithy/middleware-serde", true),
MIDDLEWARE_RETRY("dependencies", "@smithy/middleware-retry", true),
UTIL_RETRY("dependencies", "@smithy/util-retry", false),
MIDDLEWARE_STACK("dependencies", "@smithy/middleware-stack", true),
MIDDLEWARE_ENDPOINTS_V2("dependencies", "@smithy/middleware-endpoint", false),
AWS_SDK_UTIL_ENDPOINTS("dependencies", "@aws-sdk/util-endpoints", false),

AWS_CRYPTO_SHA256_BROWSER("dependencies", "@aws-crypto/sha256-browser", "3.0.0", true),
AWS_CRYPTO_SHA256_JS("dependencies", "@aws-crypto/sha256-js", "3.0.0", true),
AWS_SDK_HASH_NODE("dependencies", "@smithy/hash-node", "^2.0.6", true),

AWS_SDK_URL_PARSER("dependencies", "@smithy/url-parser", "^2.0.6", true),
AWS_SDK_HASH_NODE("dependencies", "@smithy/hash-node", true),

@Deprecated AWS_SDK_UTIL_BASE64_BROWSER("dependencies", "@smithy/util-base64-browser", "^1.0.1", false),
@Deprecated AWS_SDK_UTIL_BASE64_NODE("dependencies", "@smithy/util-base64-node", "^1.0.1", false),
AWS_SDK_UTIL_BASE64("dependencies", "@smithy/util-base64", "^2.0.0", true),
AWS_SDK_URL_PARSER("dependencies", "@smithy/url-parser", true),

AWS_SDK_UTIL_BODY_LENGTH_BROWSER("dependencies", "@smithy/util-body-length-browser", "^2.0.0", true),
AWS_SDK_UTIL_BODY_LENGTH_NODE("dependencies", "@smithy/util-body-length-node", "^2.1.0", true),
@Deprecated AWS_SDK_UTIL_BASE64_BROWSER("dependencies", "@aws-sdk/util-base64-browser", false),
@Deprecated AWS_SDK_UTIL_BASE64_NODE("dependencies", "@aws-sdk/util-base64-node", false),
AWS_SDK_UTIL_BASE64("dependencies", "@smithy/util-base64", true),

AWS_SDK_UTIL_UTF8("dependencies", "@smithy/util-utf8", "^2.0.0", true),
AWS_SDK_UTIL_BODY_LENGTH_BROWSER("dependencies", "@smithy/util-body-length-browser", true),
AWS_SDK_UTIL_BODY_LENGTH_NODE("dependencies", "@smithy/util-body-length-node", true),

AWS_SDK_UTIL_WAITERS("dependencies", "@smithy/util-waiter", "^2.0.6", false),
AWS_SDK_UTIL_UTF8("dependencies", "@smithy/util-utf8", true),

AWS_SDK_UTIL_DEFAULTS_MODE_NODE("dependencies", "@smithy/util-defaults-mode-node", "^2.0.9", true),
AWS_SDK_UTIL_DEFAULTS_MODE_BROWSER("dependencies", "@smithy/util-defaults-mode-browser", "^2.0.7", true),
AWS_SDK_UTIL_WAITERS("dependencies", "@smithy/util-waiter", false),

NODE_CONFIG_PROVIDER("dependencies", "@smithy/node-config-provider", "^2.0.9", false),
AWS_SDK_UTIL_DEFAULTS_MODE_NODE("dependencies", "@smithy/util-defaults-mode-node", true),
AWS_SDK_UTIL_DEFAULTS_MODE_BROWSER("dependencies", "@smithy/util-defaults-mode-browser", true),

NODE_CONFIG_PROVIDER("dependencies", "@smithy/node-config-provider", false),

UUID("dependencies", "uuid", "^8.3.2", false),

// Conditionally added when httpChecksumRequired trait exists
MD5_BROWSER("dependencies", "@smithy/md5-js", "^2.0.6", false),
STREAM_HASHER_NODE("dependencies", "@smithy/hash-stream-node", "^2.0.6", false),
STREAM_HASHER_BROWSER("dependencies", "@smithy/hash-blob-browser", "^2.0.6", false),
BODY_CHECKSUM("dependencies", "@smithy/middleware-apply-body-checksum", "^2.0.8", false),
MD5_BROWSER("dependencies", "@smithy/md5-js", false),
STREAM_HASHER_NODE("dependencies", "@smithy/hash-stream-node", false),
STREAM_HASHER_BROWSER("dependencies", "@smithy/hash-blob-browser", false),
BODY_CHECKSUM("dependencies", "@smithy/middleware-apply-body-checksum", false),

// Conditionally added when using an HTTP application protocol.
PROTOCOL_HTTP("dependencies", "@smithy/protocol-http", "^3.0.2", false),
AWS_SDK_FETCH_HTTP_HANDLER("dependencies", "@smithy/fetch-http-handler", "^2.1.2", false),
AWS_SDK_NODE_HTTP_HANDLER("dependencies", "@smithy/node-http-handler", "^2.1.2", false),
PROTOCOL_HTTP("dependencies", "@smithy/protocol-http", false),
AWS_SDK_FETCH_HTTP_HANDLER("dependencies", "@smithy/fetch-http-handler", false),
AWS_SDK_NODE_HTTP_HANDLER("dependencies", "@smithy/node-http-handler", false),

// Conditionally added when setting the auth middleware.
UTIL_MIDDLEWARE("dependencies", "@smithy/util-middleware", "^2.0.0", false),
@Deprecated AWS_SDK_UTIL_MIDDLEWARE("dependencies", "@smithy/util-middleware", "^2.0.0", false),
UTIL_MIDDLEWARE("dependencies", "@smithy/util-middleware", false),
@Deprecated AWS_SDK_UTIL_MIDDLEWARE("dependencies", "@smithy/util-middleware", false),

// Conditionally added if a event stream shape is found anywhere in the model
AWS_SDK_EVENTSTREAM_SERDE_CONFIG_RESOLVER(
"dependencies", "@smithy/eventstream-serde-config-resolver", "^2.0.6", false),
AWS_SDK_EVENTSTREAM_SERDE_NODE("dependencies", "@smithy/eventstream-serde-node", "^2.0.6", false),
AWS_SDK_EVENTSTREAM_SERDE_BROWSER("dependencies", "@smithy/eventstream-serde-browser", "^2.0.6", false),
AWS_SDK_EVENTSTREAM_SERDE_CONFIG_RESOLVER("dependencies", "@smithy/eventstream-serde-config-resolver",
false),
AWS_SDK_EVENTSTREAM_SERDE_NODE("dependencies", "@smithy/eventstream-serde-node", false),
AWS_SDK_EVENTSTREAM_SERDE_BROWSER("dependencies", "@smithy/eventstream-serde-browser", false),

// Conditionally added if a big decimal shape is found in a model.
BIG_JS("dependencies", "big.js", "^6.0.0", false),
TYPES_BIG_JS("devDependencies", "@types/big.js", "^6.0.0", false),

// Conditionally added when interacting with specific protocol test bodyMediaType values.
AWS_SDK_QUERYSTRING_BUILDER("dependencies", "@smithy/querystring-builder", "^2.0.6", false),
AWS_SDK_QUERYSTRING_BUILDER("dependencies", "@smithy/querystring-builder", false),

// Conditionally added when XML parser needs to be used.
XML_PARSER("dependencies", "fast-xml-parser", "4.2.5", false),
HTML_ENTITIES("dependencies", "entities", "2.2.0", false),

// Conditionally added when streaming blob response payload exists.
@Deprecated UTIL_STREAM_NODE("dependencies", "@smithy/util-stream-node", "^2.0.8", false),
@Deprecated UTIL_STREAM_BROWSER("dependencies", "@smithy/util-stream-browser", "^2.0.8", false),
UTIL_STREAM("dependencies", "@smithy/util-stream", "^2.0.9", false),
@Deprecated UTIL_STREAM_NODE("dependencies", "@smithy/util-stream-node", false),
@Deprecated UTIL_STREAM_BROWSER("dependencies", "@smithy/util-stream-browser", false),
UTIL_STREAM("dependencies", "@smithy/util-stream", false),

// Conditionally added when @aws.auth#sigv4 is used
SIGNATURE_V4("dependencies", "@smithy/signature-v4", "^2.0.6", false),
SIGNATURE_V4("dependencies", "@smithy/signature-v4", false),

// feat(experimentalIdentityAndAuth): Conditionally added dependencies for `experimentalIdentityAndAuth`.
// This package should never have a major version, and should only use minor and patch versions in development.
EXPERIMENTAL_IDENTITY_AND_AUTH("dependencies", "@smithy/experimental-identity-and-auth", "~0.0.4", false),
EXPERIMENTAL_IDENTITY_AND_AUTH("dependencies", "@smithy/experimental-identity-and-auth", false),

// Conditionally added when specs have been generated.
VITEST("devDependencies", "vitest", "^0.33.0", false),

// Server dependency for SSDKs
SERVER_COMMON("dependencies", "@aws-smithy/server-common", "1.0.0-alpha.10", false);
SERVER_COMMON("dependencies", "@aws-smithy/server-common", false);

public static final String NORMAL_DEPENDENCY = "dependencies";
public static final String DEV_DEPENDENCY = "devDependencies";
Expand All @@ -139,7 +140,25 @@ public enum TypeScriptDependency implements Dependency {
public final SymbolDependency dependency;

TypeScriptDependency(String type, String name, boolean unconditional) {
this(type, name, SdkVersion.getVersion(name), unconditional);
String version;
if (name.startsWith("@aws-sdk/")) {
version = SdkVersion.getVersion(name);
} else {
version = DependencyVersion.getVersion(name);
}

if (name.startsWith("@smithy/")) {
version = "^" + version;
}
this.dependency = SymbolDependency.builder()
.dependencyType(type)
.packageName(name)
.version(version)
.putProperty("unconditional", unconditional)
.build();
this.packageName = name;
this.version = version;

}

TypeScriptDependency(String type, String name, String version, boolean unconditional) {
Expand Down Expand Up @@ -244,4 +263,42 @@ private static String getVersion(String packageName) {
return VERSIONS.getOrDefault(packageName, "latest");
}
}

/**
* Reads the version of smithy-typescript published libraries.
*/
private static final class DependencyVersion {
private static final Logger LOGGER = Logger.getLogger(DependencyVersion.class.getName());
private static final Map<String, String> VERSIONS;

static {
Map<String, String> tmpVersions;
try {
URL versionsUrl = DependencyVersion.class.getResource("dependencyVersions.properties");
if (versionsUrl == null) {
throw new IOException();
}
Properties p = new Properties();
try (Reader r =
new BufferedReader(new InputStreamReader(versionsUrl.openStream(), StandardCharsets.UTF_8))) {
p.load(r);
}
final Map<String, String> versions = new HashMap<>(p.size());
p.forEach((k, v) -> {
if (versions.put(k.toString(), v.toString()) != null) {
throw new IllegalArgumentException(String.format("Multiple versions defined for %s", k));
}
});
tmpVersions = Collections.unmodifiableMap(versions);
} catch (IOException e) {
LOGGER.info("Could not read dependency versions from smithy-typescript-codegen");
tmpVersions = Collections.emptyMap();
}
VERSIONS = tmpVersions;
}

private static String getVersion(String packageName) {
return VERSIONS.get(packageName);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.startsWith;

import java.util.List;

import org.junit.jupiter.api.Test;
import software.amazon.smithy.codegen.core.Symbol;
import software.amazon.smithy.codegen.core.SymbolDependency;

public class TypeScriptDependencyTest {
@Test
Expand All @@ -23,4 +28,18 @@ public void getsUnconditionalDependencies() {
assertThat(TypeScriptDependency.getUnconditionalDependencies(),
hasItem(TypeScriptDependency.AWS_SDK_CLIENT_DOCGEN.dependency));
}

@Test
public void getsVendedDependencyVersions() {
List<SymbolDependency> smithyTypes = TypeScriptDependency.SMITHY_TYPES.getDependencies();
List<SymbolDependency> serverCommon = TypeScriptDependency.SERVER_COMMON.getDependencies();

assertThat(smithyTypes.size(), equalTo(1));
assertThat(smithyTypes.get(0).getVersion(), startsWith("^"));
assertThat(smithyTypes.get(0).getPackageName(), equalTo("@smithy/types"));

assertThat(serverCommon.size(), equalTo(1));
assertThat(serverCommon.get(0).getVersion(), not(startsWith("^")));
assertThat(serverCommon.get(0).getPackageName(), equalTo("@aws-smithy/server-common"));
}
}

0 comments on commit a7ad899

Please sign in to comment.