diff --git a/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/PackageManifestGenerator.kt b/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/PackageManifestGenerator.kt index 3bcf40eb7..04307efc3 100644 --- a/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/PackageManifestGenerator.kt +++ b/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/PackageManifestGenerator.kt @@ -6,12 +6,15 @@ package software.amazon.smithy.swift.codegen import software.amazon.smithy.codegen.core.SymbolDependency import software.amazon.smithy.swift.codegen.integration.ProtocolGenerator +import kotlin.jvm.optionals.getOrNull + +val PACKAGE_MANIFEST_NAME = "Package.swift.txt" class PackageManifestGenerator(val ctx: ProtocolGenerator.GenerationContext) { fun writePackageManifest(dependencies: List) { - ctx.delegator.useFileWriter("Package.swift") { writer -> - writer.write("// swift-tools-version:\$L", ctx.settings.swiftVersion) + ctx.delegator.useFileWriter(PACKAGE_MANIFEST_NAME) { writer -> + writer.write("// swift-tools-version: \$L", ctx.settings.swiftVersion) writer.write("") writer.write("import PackageDescription") writer.write("") @@ -27,23 +30,17 @@ class PackageManifestGenerator(val ctx: ProtocolGenerator.GenerationContext) { writer.write(".library(name: \$S, targets: [\$S])", ctx.settings.moduleName, ctx.settings.moduleName) } - val externalDependencies = dependencies.filter { it.getProperty("url", String::class.java).get().isNotEmpty() } - val dependenciesByURL = externalDependencies.distinctBy { it.expectProperty("url", String::class.java) } + val externalDependencies = dependencies.filter { + it.getProperty("url", String::class.java).getOrNull() != null || + it.getProperty("scope", String::class.java).getOrNull() != null + } + val dependenciesByURL = externalDependencies.distinctBy { + it.getProperty("url", String::class.java).getOrNull() + ?: "${it.getProperty("scope", String::class.java).get()}.${it.packageName}" + } writer.openBlock("dependencies: [", "],") { - dependenciesByURL.forEach { dependency -> - writer.openBlock(".package(", "),") { - - val localPath = dependency.expectProperty("localPath", String::class.java) - if (localPath.isNotEmpty()) { - writer.write("path: \$S", localPath) - } else { - val dependencyURL = dependency.expectProperty("url", String::class.java) - writer.write("url: \$S,", dependencyURL) - writer.write("from: \$S", dependency.version) - } - } - } + dependenciesByURL.forEach { writePackageDependency(writer, it) } } val dependenciesByTarget = externalDependencies.distinctBy { it.expectProperty("target", String::class.java) + it.packageName } @@ -51,25 +48,46 @@ class PackageManifestGenerator(val ctx: ProtocolGenerator.GenerationContext) { writer.openBlock("targets: [", "]") { writer.openBlock(".target(", "),") { writer.write("name: \$S,", ctx.settings.moduleName) - writer.openBlock("dependencies: [", "]") { - for (dependency in dependenciesByTarget) { - writer.openBlock(".product(", "),") { - val target = dependency.expectProperty("target", String::class.java) - writer.write("name: \$S,", target) - writer.write("package: \$S", dependency.packageName) - } - } + writer.openBlock("dependencies: [", "],") { + dependenciesByTarget.forEach { writeTargetDependency(writer, it) } + } + writer.openBlock("resources: [", "]") { + writer.write(".process(\"Resources\")") } } writer.openBlock(".testTarget(", ")") { writer.write("name: \$S,", ctx.settings.testModuleName) writer.openBlock("dependencies: [", "]") { writer.write("\$S,", ctx.settings.moduleName) - writer.write(".product(name: \"SmithyTestUtil\", package: \"smithy-swift\"),") + SwiftDependency.SMITHY_TEST_UTIL.dependencies.forEach { writeTargetDependency(writer, it) } } } } } } } + + private fun writePackageDependency(writer: SwiftWriter, dependency: SymbolDependency) { + writer.openBlock(".package(", "),") { + val scope = dependency.getProperty("scope", String::class.java).getOrNull() + scope?.let { + writer.write("id: \$S,", "$it.${dependency.packageName}") + } + val url = dependency.getProperty("url", String::class.java).getOrNull() + url?.let { + writer.write("url: \$S,", it) + } + writer.write("from: \$S", dependency.version) + } + } + + private fun writeTargetDependency(writer: SwiftWriter, dependency: SymbolDependency) { + writer.openBlock(".product(", "),") { + val target = dependency.expectProperty("target", String::class.java) + writer.write("name: \$S,", target) + val scope = dependency.getProperty("scope", String::class.java).getOrNull() + val packageName = scope?.let { "$it.${dependency.packageName}" } ?: dependency.packageName + writer.write("package: \$S", packageName) + } + } } diff --git a/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/SwiftDependency.kt b/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/SwiftDependency.kt index 1ea692a1d..c505b789c 100644 --- a/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/SwiftDependency.kt +++ b/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/SwiftDependency.kt @@ -11,14 +11,44 @@ class SwiftDependency( override val target: String, private val branch: String? = null, private val version: String, - private val url: String, + private val location: String, private val localPath: String, override var packageName: String, + private val distributionMethod: DistributionMethod, ) : Dependency { + enum class DistributionMethod { + SPR, GIT + } + companion object { - val NONE = SwiftDependency("", "", "", "", "", "") - val XCTest = SwiftDependency("XCTest", null, "", "", "", "") + val NONE = SwiftDependency( + "", + "", + "", + "", + "", + "", + DistributionMethod.GIT, + ) + val SWIFT = SwiftDependency( + "Swift", + "", + "", + "", + "", + "", + SwiftDependency.DistributionMethod.GIT, + ) + val XCTest = SwiftDependency( + "XCTest", + null, + "", + "", + "", + "", + DistributionMethod.GIT, + ) val CRT = SwiftDependency( "AwsCommonRuntimeKit", null, @@ -26,174 +56,196 @@ class SwiftDependency( "https://github.com/awslabs/aws-crt-swift", "", "aws-crt-swift", + DistributionMethod.GIT, ) val CLIENT_RUNTIME = SwiftDependency( "ClientRuntime", "main", - "0.1.0", - "https://github.com/smithy-lang/smithy-swift.git", + "0.0.1", + "aws-sdk-swift", "../../../smithy-swift", "smithy-swift", + DistributionMethod.SPR, ) val SMITHY = SwiftDependency( "Smithy", "main", - "0.1.0", - "https://github.com/smithy-lang/smithy-swift.git", + "0.0.1", + "aws-sdk-swift", "../../../smithy-swift", "smithy-swift", + DistributionMethod.SPR, ) val SMITHY_IDENTITY_API = SwiftDependency( "SmithyIdentityAPI", "main", - "0.1.0", - "https://github.com/smithy-lang/smithy-swift.git", + "0.0.1", + "aws-sdk-swift", "../../../smithy-swift", "smithy-swift", + DistributionMethod.SPR, ) val SMITHY_IDENTITY = SwiftDependency( "SmithyIdentity", "main", - "0.1.0", - "https://github.com/smithy-lang/smithy-swift.git", + "0.0.1", + "aws-sdk-swift", "../../../smithy-swift", "smithy-swift", + DistributionMethod.SPR, ) val SMITHY_RETRIES_API = SwiftDependency( "SmithyRetriesAPI", "main", - "0.1.0", - "https://github.com/smithy-lang/smithy-swift.git", + "0.0.1", + "aws-sdk-swift", "../../../smithy-swift", "smithy-swift", + DistributionMethod.SPR, ) val SMITHY_RETRIES = SwiftDependency( "SmithyRetries", "main", - "0.1.0", - "https://github.com/smithy-lang/smithy-swift.git", + "0.0.1", + "aws-sdk-swift", "../../../smithy-swift", "smithy-swift", + DistributionMethod.SPR, ) val SMITHY_HTTP_API = SwiftDependency( "SmithyHTTPAPI", "main", - "0.1.0", - "https://github.com/smithy-lang/smithy-swift.git", + "0.0.1", + "aws-sdk-swift", "../../../smithy-swift", "smithy-swift", + DistributionMethod.SPR, ) val SMITHY_HTTP_AUTH_API = SwiftDependency( "SmithyHTTPAuthAPI", "main", - "0.1.0", - "https://github.com/smithy-lang/smithy-swift.git", + "0.0.1", + "aws-sdk-swift", "../../../smithy-swift", "smithy-swift", + DistributionMethod.SPR, ) val SMITHY_CHECKSUMS_API = SwiftDependency( "SmithyChecksumsAPI", "main", - "0.1.0", - "https://github.com/smithy-lang/smithy-swift.git", + "0.0.1", + "aws-sdk-swift", "../../../smithy-swift", "smithy-swift", + DistributionMethod.SPR, ) val SMITHY_CHECKSUMS = SwiftDependency( "SmithyChecksums", "main", - "0.1.0", - "https://github.com/smithy-lang/smithy-swift.git", + "0.0.1", + "aws-sdk-swift", "../../../smithy-swift", "smithy-swift", + DistributionMethod.SPR, ) val SMITHY_STREAMS = SwiftDependency( "SmithyStreams", "main", - "0.1.0", - "https://github.com/smithy-lang/smithy-swift.git", + "0.0.1", + "aws-sdk-swift", "../../../smithy-swift", "smithy-swift", + DistributionMethod.SPR, ) val SMITHY_EVENT_STREAMS_API = SwiftDependency( "SmithyEventStreamsAPI", "main", - "0.1.0", - "https://github.com/smithy-lang/smithy-swift.git", + "0.0.1", + "aws-sdk-swift", "../../../smithy-swift", "smithy-swift", + DistributionMethod.SPR, ) val SMITHY_EVENT_STREAMS_AUTH_API = SwiftDependency( "SmithyEventStreamsAuthAPI", "main", - "0.1.0", - "https://github.com/smithy-lang/smithy-swift.git", + "0.0.1", + "aws-sdk-swift", "../../../smithy-swift", "smithy-swift", + DistributionMethod.SPR, ) val SMITHY_EVENT_STREAMS = SwiftDependency( "SmithyEventStreams", "main", - "0.1.0", - "https://github.com/smithy-lang/smithy-swift.git", + "0.0.1", + "aws-sdk-swift", "../../../smithy-swift", "smithy-swift", + DistributionMethod.SPR, ) val SMITHY_TEST_UTIL = SwiftDependency( "SmithyTestUtil", "main", - "0.1.0", - "https://github.com/smithy-lang/smithy-swift.git", + "0.0.1", + "aws-sdk-swift", "../../../smithy-swift", "smithy-swift", + DistributionMethod.SPR, ) val SMITHY_READ_WRITE = SwiftDependency( "SmithyReadWrite", "main", - "0.1.0", - "https://github.com/smithy-lang/smithy-swift.git", + "0.0.1", + "aws-sdk-swift", "../../../smithy-swift", "smithy-swift", + DistributionMethod.SPR, ) val SMITHY_TIMESTAMPS = SwiftDependency( "SmithyTimestamps", "main", - "0.1.0", - "https://github.com/smithy-lang/smithy-swift.git", + "0.0.1", + "aws-sdk-swift", "../../../smithy-swift", "smithy-swift", + DistributionMethod.SPR, ) val SMITHY_XML = SwiftDependency( "SmithyXML", "main", - "0.1.0", - "https://github.com/smithy-lang/smithy-swift.git", + "0.0.1", + "aws-sdk-swift", "../../../smithy-swift", "smithy-swift", + DistributionMethod.SPR, ) val SMITHY_JSON = SwiftDependency( "SmithyJSON", "main", - "0.1.0", - "https://github.com/smithy-lang/smithy-swift.git", + "0.0.1", + "aws-sdk-swift", "../../../smithy-swift", "smithy-swift", + DistributionMethod.SPR, ) val SMITHY_FORM_URL = SwiftDependency( "SmithyFormURL", "main", - "0.1.0", - "https://github.com/smithy-lang/smithy-swift.git", + "0.0.1", + "aws-sdk-swift", "../../../smithy-swift", "smithy-swift", + DistributionMethod.SPR, ) val SMITHY_WAITERS_API = SwiftDependency( "SmithyWaitersAPI", "main", - "0.1.0", - "https://github.com/smithy-lang/smithy-swift.git", + "0.0.1", + "aws-sdk-swift", "../../../smithy-swift", "smithy-swift", + DistributionMethod.SPR, ) } @@ -202,13 +254,20 @@ class SwiftDependency( } private fun toSymbolDependency(): SymbolDependency { - return SymbolDependency.builder() + val builder = SymbolDependency.builder() .putProperty("target", target) .putProperty("branch", branch) .putProperty("localPath", localPath) .packageName(packageName) .version(version) - .putProperty("url", url) - .build() + when (distributionMethod) { + DistributionMethod.GIT -> { + builder.putProperty("url", location) + } + DistributionMethod.SPR -> { + builder.putProperty("scope", location) + } + } + return builder.build() } } diff --git a/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/SwiftWriter.kt b/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/SwiftWriter.kt index 8e9cf2c8d..2bee94e35 100644 --- a/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/SwiftWriter.kt +++ b/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/SwiftWriter.kt @@ -154,7 +154,13 @@ class SwiftWriter( // Package.swift requires a special comment at the top to specify Swift tools version, // and the package manifest generator manually writes its own dependency imports // (it only imports the PackageDescription module.) - return contents.takeIf { fullPackageName == "Package" } ?: (copyrightNotice + imports + contents) + // + // Also leave out the headers when JSON or the version file is being written, + // as indicated by the file extension. + val isPackageManifest = listOf(PACKAGE_MANIFEST_NAME, (PACKAGE_MANIFEST_NAME + ".swift")).contains(fullPackageName) + val isNonSwiftSourceFile = listOf(".json", ".version").any { fullPackageName.endsWith(it) } + val noHeader = isPackageManifest || isNonSwiftSourceFile + return contents.takeIf { noHeader } ?: (copyrightNotice + imports + contents) } private class SwiftSymbolFormatter( diff --git a/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/swiftmodules/SwiftTypes.kt b/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/swiftmodules/SwiftTypes.kt index 4fa32b006..784d3776c 100644 --- a/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/swiftmodules/SwiftTypes.kt +++ b/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/swiftmodules/SwiftTypes.kt @@ -37,6 +37,6 @@ object SwiftTypes { private fun builtInSymbol(name: String, declaration: SwiftDeclaration? = null): Symbol = SwiftSymbol.make( name, declaration, - SwiftDependency("Swift", "", "", "", "", ""), + SwiftDependency.SWIFT, null, ) diff --git a/smithy-swift-codegen/src/test/kotlin/PackageManifestGeneratorTests.kt b/smithy-swift-codegen/src/test/kotlin/PackageManifestGeneratorTests.kt index f963572eb..3721ef4d3 100644 --- a/smithy-swift-codegen/src/test/kotlin/PackageManifestGeneratorTests.kt +++ b/smithy-swift-codegen/src/test/kotlin/PackageManifestGeneratorTests.kt @@ -14,7 +14,7 @@ class PackageManifestGeneratorTests { @Test fun `it renders package manifest file with macOS and iOS platforms block`() { - val packageManifest = testContext.manifest.getFileString("Package.swift").get() + val packageManifest = testContext.manifest.getFileString("Package.swift.txt").get() assertNotNull(packageManifest) packageManifest.shouldContain( "platforms: [\n" + @@ -25,7 +25,7 @@ class PackageManifestGeneratorTests { @Test fun `it renders package manifest file with single library in product block`() { - val packageManifest = testContext.manifest.getFileString("Package.swift").get() + val packageManifest = testContext.manifest.getFileString("Package.swift.txt").get() assertNotNull(packageManifest) packageManifest.shouldContain( "products: [\n" + @@ -37,20 +37,26 @@ class PackageManifestGeneratorTests { @Test fun `it renders package manifest file with target and test target`() { println(testContext.manifest.files) - val packageManifest = testContext.manifest.getFileString("Package.swift").get() + val packageManifest = testContext.manifest.getFileString("Package.swift.txt").get() assertNotNull(packageManifest) val expected = """ targets: [ .target( name: "MockSDK", dependencies: [ + ], + resources: [ + .process("Resources") ] ), .testTarget( name: "MockSDKTests", dependencies: [ "MockSDK", - .product(name: "SmithyTestUtil", package: "smithy-swift"), + .product( + name: "SmithyTestUtil", + package: "aws-sdk-swift.smithy-swift" + ), ] ) ]