Skip to content

Commit

Permalink
feat: Add Swift Package Registry tools and config (#771)
Browse files Browse the repository at this point in the history
  • Loading branch information
jbelkins authored Jul 9, 2024
1 parent 9e3ea22 commit 571c78d
Show file tree
Hide file tree
Showing 5 changed files with 169 additions and 80 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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<SymbolDependency>) {
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("")
Expand All @@ -27,49 +30,64 @@ 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 }

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)
}
}
}
Loading

0 comments on commit 571c78d

Please sign in to comment.