diff --git a/Package.swift b/Package.swift index 280977d4..5548b313 100644 --- a/Package.swift +++ b/Package.swift @@ -12,26 +12,26 @@ let package = Package( name: "swift-aws-lambda-runtime", platforms: platforms, products: [ - - /* - The runtime library targets - */ - + + // + // The runtime library targets + // + // this library exports `AWSLambdaRuntimeCore` and adds Foundation convenience methods .library(name: "AWSLambdaRuntime", targets: ["AWSLambdaRuntime"]), // this has all the main functionality for lambda and it does not link Foundation .library(name: "AWSLambdaRuntimeCore", targets: ["AWSLambdaRuntimeCore"]), - /* - The plugins - 'lambda-init' creates a new Lambda function - 'lambda-build' packages the Lambda function - 'lambda-deploy' deploys the Lambda function - - Plugins requires Linux or at least macOS v15 + // + // The plugins + // 'lambda-init' creates a new Lambda function + // 'lambda-build' packages the Lambda function + // 'lambda-deploy' deploys the Lambda function + // + // Plugins requires Linux or at least macOS v15 + // - */ // plugin to create a new Lambda function, based on a template .plugin(name: "AWSLambdaInitializer", targets: ["AWSLambdaInitializer"]), @@ -41,9 +41,10 @@ let package = Package( // plugin to deploy a Lambda function .plugin(name: "AWSLambdaDeployer", targets: ["AWSLambdaDeployer"]), - /* - Testing targets - */ + // + // Testing targets + // + // for testing only .library(name: "AWSLambdaTesting", targets: ["AWSLambdaTesting"]), ], @@ -88,23 +89,23 @@ let package = Package( ), // keep this one (with "archive") to not break workflows // This will be deprecated at some point in the future -// .plugin( -// name: "AWSLambdaPackager", -// capability: .command( -// intent: .custom( -// verb: "archive", -// description: -// "Archive the Lambda binary and prepare it for uploading to AWS. Requires docker on macOS or non Amazonlinux 2 distributions." -// ), -// permissions: [ -// .allowNetworkConnections( -// scope: .docker, -// reason: "This plugin uses Docker to create the AWS Lambda ZIP package." -// ) -// ] -// ), -// path: "Plugins/AWSLambdaBuilder" // same sources as the new "lambda-build" plugin -// ), + // .plugin( + // name: "AWSLambdaPackager", + // capability: .command( + // intent: .custom( + // verb: "archive", + // description: + // "Archive the Lambda binary and prepare it for uploading to AWS. Requires docker on macOS or non Amazonlinux 2 distributions." + // ), + // permissions: [ + // .allowNetworkConnections( + // scope: .docker, + // reason: "This plugin uses Docker to create the AWS Lambda ZIP package." + // ) + // ] + // ), + // path: "Plugins/AWSLambdaBuilder" // same sources as the new "lambda-build" plugin + // ), .plugin( name: "AWSLambdaBuilder", capability: .command( diff --git a/Plugins/AWSLambdaBuilder/Plugin.swift b/Plugins/AWSLambdaBuilder/Plugin.swift index e6158b8b..fdb97efb 100644 --- a/Plugins/AWSLambdaBuilder/Plugin.swift +++ b/Plugins/AWSLambdaBuilder/Plugin.swift @@ -17,9 +17,9 @@ import PackagePlugin @main struct AWSLambdaPackager: CommandPlugin { - + func performCommand(context: PackagePlugin.PluginContext, arguments: [String]) async throws { - + // values to pass to the AWSLambdaPluginHelper let outputDirectory: URL let products: [Product] @@ -29,15 +29,15 @@ struct AWSLambdaPackager: CommandPlugin { let packageDirectory = context.package.directoryURL let dockerToolPath = try context.tool(named: "docker").url let zipToolPath = try context.tool(named: "zip").url - + // extract arguments that require PluginContext to fully resolve // resolve them here and pass them to the AWSLambdaPluginHelper as arguments var argumentExtractor = ArgumentExtractor(arguments) - + let outputPathArgument = argumentExtractor.extractOption(named: "output-path") let productsArgument = argumentExtractor.extractOption(named: "products") let configurationArgument = argumentExtractor.extractOption(named: "configuration") - + if let outputPath = outputPathArgument.first { #if os(Linux) var isDirectory: Bool = false @@ -52,7 +52,7 @@ struct AWSLambdaPackager: CommandPlugin { } else { outputDirectory = context.pluginWorkDirectoryURL.appending(path: "\(AWSLambdaPackager.self)") } - + let explicitProducts = !productsArgument.isEmpty if explicitProducts { let _products = try context.package.products(named: productsArgument) @@ -62,11 +62,11 @@ struct AWSLambdaPackager: CommandPlugin { } } products = _products - + } else { products = context.package.products.filter { $0 is ExecutableProduct } } - + if let _buildConfigurationName = configurationArgument.first { guard let _buildConfiguration = PackageManager.BuildConfiguration(rawValue: _buildConfigurationName) else { throw BuilderErrors.invalidArgument("invalid build configuration named '\(_buildConfigurationName)'") @@ -75,22 +75,23 @@ struct AWSLambdaPackager: CommandPlugin { } else { buildConfiguration = .release } - + // TODO: When running on Amazon Linux 2, we have to build directly from the plugin // launch the build, then call the helper just for the ZIP part - + let tool = try context.tool(named: "AWSLambdaPluginHelper") - let args = [ - "build", - "--output-path", outputDirectory.path(), - "--products", products.map { $0.name }.joined(separator: ","), - "--configuration", buildConfiguration.rawValue, - "--package-id", packageID, - "--package-display-name", packageDisplayName, - "--package-directory", packageDirectory.path(), - "--docker-tool-path", dockerToolPath.path, - "--zip-tool-path", zipToolPath.path - ] + arguments + let args = + [ + "build", + "--output-path", outputDirectory.path(), + "--products", products.map { $0.name }.joined(separator: ","), + "--configuration", buildConfiguration.rawValue, + "--package-id", packageID, + "--package-display-name", packageDisplayName, + "--package-directory", packageDirectory.path(), + "--docker-tool-path", dockerToolPath.path, + "--zip-tool-path", zipToolPath.path, + ] + arguments // Invoke the plugin helper on the target directory, passing a configuration // file from the package directory. @@ -103,52 +104,52 @@ struct AWSLambdaPackager: CommandPlugin { Diagnostics.error("AWSLambdaPluginHelper invocation failed: \(problem)") } } - + // TODO: When running on Amazon Linux 2, we have to build directly from the plugin -// private func build( -// packageIdentity: Package.ID, -// products: [Product], -// buildConfiguration: PackageManager.BuildConfiguration, -// verboseLogging: Bool -// ) throws -> [LambdaProduct: URL] { -// print("-------------------------------------------------------------------------") -// print("building \"\(packageIdentity)\"") -// print("-------------------------------------------------------------------------") -// -// var results = [LambdaProduct: URL]() -// for product in products { -// print("building \"\(product.name)\"") -// var parameters = PackageManager.BuildParameters() -// parameters.configuration = buildConfiguration -// parameters.otherSwiftcFlags = ["-static-stdlib"] -// parameters.logging = verboseLogging ? .verbose : .concise -// -// let result = try packageManager.build( -// .product(product.name), -// parameters: parameters -// ) -// guard let artifact = result.executableArtifact(for: product) else { -// throw Errors.productExecutableNotFound(product.name) -// } -// results[.init(product)] = artifact.url -// } -// return results -// } - -// private func isAmazonLinux2() -> Bool { -// if let data = FileManager.default.contents(atPath: "/etc/system-release"), -// let release = String(data: data, encoding: .utf8) -// { -// return release.hasPrefix("Amazon Linux release 2") -// } else { -// return false -// } -// } + // private func build( + // packageIdentity: Package.ID, + // products: [Product], + // buildConfiguration: PackageManager.BuildConfiguration, + // verboseLogging: Bool + // ) throws -> [LambdaProduct: URL] { + // print("-------------------------------------------------------------------------") + // print("building \"\(packageIdentity)\"") + // print("-------------------------------------------------------------------------") + // + // var results = [LambdaProduct: URL]() + // for product in products { + // print("building \"\(product.name)\"") + // var parameters = PackageManager.BuildParameters() + // parameters.configuration = buildConfiguration + // parameters.otherSwiftcFlags = ["-static-stdlib"] + // parameters.logging = verboseLogging ? .verbose : .concise + // + // let result = try packageManager.build( + // .product(product.name), + // parameters: parameters + // ) + // guard let artifact = result.executableArtifact(for: product) else { + // throw Errors.productExecutableNotFound(product.name) + // } + // results[.init(product)] = artifact.url + // } + // return results + // } + + // private func isAmazonLinux2() -> Bool { + // if let data = FileManager.default.contents(atPath: "/etc/system-release"), + // let release = String(data: data, encoding: .utf8) + // { + // return release.hasPrefix("Amazon Linux release 2") + // } else { + // return false + // } + // } } private enum BuilderErrors: Error, CustomStringConvertible { case invalidArgument(String) - + var description: String { switch self { case .invalidArgument(let description): diff --git a/Plugins/AWSLambdaInitializer/Plugin.swift b/Plugins/AWSLambdaInitializer/Plugin.swift index 026e70cd..5b508ff3 100644 --- a/Plugins/AWSLambdaInitializer/Plugin.swift +++ b/Plugins/AWSLambdaInitializer/Plugin.swift @@ -20,7 +20,7 @@ struct AWSLambdaPackager: CommandPlugin { func performCommand(context: PackagePlugin.PluginContext, arguments: [String]) async throws { let tool = try context.tool(named: "AWSLambdaPluginHelper") - + let args = ["init", "--dest-dir", context.package.directoryURL.path()] + arguments // Invoke the plugin helper on the target directory, passing a configuration @@ -35,4 +35,3 @@ struct AWSLambdaPackager: CommandPlugin { } } } - diff --git a/Sources/AWSLambdaPluginHelper/AWSLambdaPluginHelper.swift b/Sources/AWSLambdaPluginHelper/AWSLambdaPluginHelper.swift index 71b5af7e..2c124b5f 100644 --- a/Sources/AWSLambdaPluginHelper/AWSLambdaPluginHelper.swift +++ b/Sources/AWSLambdaPluginHelper/AWSLambdaPluginHelper.swift @@ -14,13 +14,13 @@ @main struct AWSLambdaPluginHelper { - + private enum Command: String { case `init` case build case deploy } - + public static func main() async throws { let args = CommandLine.arguments let helper = AWSLambdaPluginHelper() @@ -34,10 +34,10 @@ struct AWSLambdaPluginHelper { try await Deployer().deploy(arguments: args) } } - + private func command(from arguments: [String]) throws -> Command { let args = CommandLine.arguments - + guard args.count > 2 else { throw AWSLambdaPluginHelperError.noCommand } @@ -45,7 +45,7 @@ struct AWSLambdaPluginHelper { guard let command = Command(rawValue: commandName) else { throw AWSLambdaPluginHelperError.invalidCommand(commandName) } - + return command } } @@ -54,4 +54,3 @@ private enum AWSLambdaPluginHelperError: Error { case noCommand case invalidCommand(String) } - diff --git a/Sources/AWSLambdaPluginHelper/Vendored/crypto/Padding.swift b/Sources/AWSLambdaPluginHelper/Vendored/crypto/Padding.swift index 679e161f..fb714a4f 100644 --- a/Sources/AWSLambdaPluginHelper/Vendored/crypto/Padding.swift +++ b/Sources/AWSLambdaPluginHelper/Vendored/crypto/Padding.swift @@ -33,7 +33,7 @@ public protocol PaddingProtocol { } public enum Padding: PaddingProtocol { - case noPadding, zeroPadding + case noPadding, zeroPadding public func add(to: [UInt8], blockSize: Int) -> [UInt8] { switch self { case .noPadding: diff --git a/Sources/AWSLambdaPluginHelper/Vendored/spm/ArgumentExtractor.swift b/Sources/AWSLambdaPluginHelper/Vendored/spm/ArgumentExtractor.swift index 8406692c..cee229a0 100644 --- a/Sources/AWSLambdaPluginHelper/Vendored/spm/ArgumentExtractor.swift +++ b/Sources/AWSLambdaPluginHelper/Vendored/spm/ArgumentExtractor.swift @@ -50,13 +50,11 @@ public struct ArgumentExtractor { values.append(val) args.remove(at: idx) } - } - else if arg.starts(with: "--\(name)=") { + } else if arg.starts(with: "--\(name)=") { arg.removeFirst(2 + name.count + 1) values.append(arg) args.remove(at: idx) - } - else { + } else { idx += 1 } } @@ -72,8 +70,7 @@ public struct ArgumentExtractor { if arg == "--\(name)" { args.remove(at: idx) count += 1 - } - else { + } else { idx += 1 } } @@ -82,11 +79,11 @@ public struct ArgumentExtractor { /// Returns any unextracted flags or options (based strictly on whether remaining arguments have a "--" prefix). public var unextractedOptionsOrFlags: [String] { - return args.filter{ $0.hasPrefix("--") } + args.filter { $0.hasPrefix("--") } } /// Returns all remaining arguments, including any literals after the first `--` if there is one. public var remainingArguments: [String] { - return args + literals + args + literals } -} \ No newline at end of file +} diff --git a/Sources/AWSLambdaPluginHelper/lambda-build/Builder.swift b/Sources/AWSLambdaPluginHelper/lambda-build/Builder.swift index fb8ff73a..acd01c28 100644 --- a/Sources/AWSLambdaPluginHelper/lambda-build/Builder.swift +++ b/Sources/AWSLambdaPluginHelper/lambda-build/Builder.swift @@ -22,14 +22,14 @@ import Foundation struct Builder { func build(arguments: [String]) async throws { let configuration = try BuilderConfiguration(arguments: arguments) - + if configuration.help { self.displayHelpMessage() return } - + let builtProducts: [String: URL] - + // build with docker // TODO: check if dockerToolPath is provided // When not provided, it means we're building on Amazon Linux 2 @@ -44,7 +44,7 @@ struct Builder { buildConfiguration: configuration.buildConfiguration, verboseLogging: configuration.verboseLogging ) - + // create the archive let archives = try self.package( packageName: configuration.packageDisplayName, @@ -53,7 +53,7 @@ struct Builder { outputDirectory: configuration.outputDirectory, verboseLogging: configuration.verboseLogging ) - + print( "\(archives.count > 0 ? archives.count.description : "no") archive\(archives.count != 1 ? "s" : "") created" ) @@ -61,7 +61,7 @@ struct Builder { print(" * \(product) at \(archivePath.path())") } } - + private func buildInDocker( packageIdentity: String, packageDirectory: URL, @@ -73,11 +73,11 @@ struct Builder { buildConfiguration: BuildConfiguration, verboseLogging: Bool ) throws -> [String: URL] { - + print("-------------------------------------------------------------------------") print("building \"\(packageIdentity)\" in docker") print("-------------------------------------------------------------------------") - + if !disableDockerImageUpdate { // update the underlying docker image, if necessary print("updating \"\(baseImage)\" docker image") @@ -87,7 +87,7 @@ struct Builder { logLevel: verboseLogging ? .debug : .silent ) } - + // get the build output path let buildOutputPathCommand = "swift build -c \(buildConfiguration.rawValue) --show-bin-path" let dockerBuildOutputPath = try Utils.execute( @@ -104,13 +104,13 @@ struct Builder { let buildOutputPath = URL( string: buildPathOutput.replacingOccurrences(of: "/workspace/", with: packageDirectory.description) )! - + // build the products var builtProducts = [String: URL]() for product in products { print("building \"\(product)\"") let buildCommand = - "swift build -c \(buildConfiguration.rawValue) --product \(product) --static-swift-stdlib" + "swift build -c \(buildConfiguration.rawValue) --product \(product) --static-swift-stdlib" if let localPath = ProcessInfo.processInfo.environment["LAMBDA_USE_LOCAL_DEPS"] { // when developing locally, we must have the full swift-aws-lambda-runtime project in the container // because Examples' Package.swift have a dependency on ../.. @@ -136,7 +136,7 @@ struct Builder { ) } let productPath = buildOutputPath.appending(path: product) - + guard FileManager.default.fileExists(atPath: productPath.path()) else { print("expected '\(product)' binary at \"\(productPath.path())\"") throw BuilderErrors.productExecutableNotFound(product) @@ -145,7 +145,7 @@ struct Builder { } return builtProducts } - + // TODO: explore using ziplib or similar instead of shelling out private func package( packageName: String, @@ -154,13 +154,13 @@ struct Builder { outputDirectory: URL, verboseLogging: Bool ) throws -> [String: URL] { - + var archives = [String: URL]() for (product, artifactPath) in products { print("-------------------------------------------------------------------------") print("archiving \"\(product)\"") print("-------------------------------------------------------------------------") - + // prep zipfile location let workingDirectory = outputDirectory.appending(path: product) let zipfilePath = workingDirectory.appending(path: "\(product).zip") @@ -168,23 +168,23 @@ struct Builder { try FileManager.default.removeItem(atPath: workingDirectory.path()) } try FileManager.default.createDirectory(atPath: workingDirectory.path(), withIntermediateDirectories: true) - + // rename artifact to "bootstrap" let relocatedArtifactPath = workingDirectory.appending(path: "bootstrap") try FileManager.default.copyItem(atPath: artifactPath.path(), toPath: relocatedArtifactPath.path()) - + var arguments: [String] = [] -#if os(macOS) || os(Linux) + #if os(macOS) || os(Linux) arguments = [ "--recurse-paths", "--symlinks", zipfilePath.lastPathComponent, relocatedArtifactPath.lastPathComponent, ] -#else + #else throw Errors.unsupportedPlatform("can't or don't know how to create a zip file on this platform") -#endif - + #endif + // add resources var artifactPathComponents = artifactPath.pathComponents _ = artifactPathComponents.removeFirst() // Get rid of beginning "/" @@ -194,7 +194,7 @@ struct Builder { guard let artifactURL = URL(string: "\(artifactDirectory)/\(fileInArtifactDirectory)") else { continue } - + guard artifactURL.pathExtension == "resources" else { continue // Not resources, so don't copy } @@ -208,7 +208,7 @@ struct Builder { arguments.append(resourcesDirectoryName) } } - + // run the zip tool try Utils.execute( executable: zipToolPath, @@ -216,52 +216,52 @@ struct Builder { customWorkingDirectory: workingDirectory, logLevel: verboseLogging ? .debug : .silent ) - + archives[product] = zipfilePath } return archives } - + private func displayHelpMessage() { print( - """ - OVERVIEW: A SwiftPM plugin to build and package your lambda function. - - REQUIREMENTS: To use this plugin, you must have docker installed and started. - - USAGE: swift package --allow-network-connections docker archive - [--help] [--verbose] - [--output-directory ] - [--products ] - [--configuration debug | release] - [--swift-version ] - [--base-docker-image ] - [--disable-docker-image-update] - - - OPTIONS: - --verbose Produce verbose output for debugging. - --output-directory The path of the binary package. - (default is `.build/plugins/AWSLambdaPackager/outputs/...`) - --products The list of executable targets to build. - (default is taken from Package.swift) - --configuration The build configuration (debug or release) - (default is release) - --swift-version The swift version to use for building. - (default is latest) - This parameter cannot be used when --base-docker-image is specified. - --base-docker-image The name of the base docker image to use for the build. - (default : swift-:amazonlinux2) - This parameter cannot be used when --swift-version is specified. - --disable-docker-image-update Do not attempt to update the docker image - --help Show help information. - """ + """ + OVERVIEW: A SwiftPM plugin to build and package your lambda function. + + REQUIREMENTS: To use this plugin, you must have docker installed and started. + + USAGE: swift package --allow-network-connections docker archive + [--help] [--verbose] + [--output-directory ] + [--products ] + [--configuration debug | release] + [--swift-version ] + [--base-docker-image ] + [--disable-docker-image-update] + + + OPTIONS: + --verbose Produce verbose output for debugging. + --output-directory The path of the binary package. + (default is `.build/plugins/AWSLambdaPackager/outputs/...`) + --products The list of executable targets to build. + (default is taken from Package.swift) + --configuration The build configuration (debug or release) + (default is release) + --swift-version The swift version to use for building. + (default is latest) + This parameter cannot be used when --base-docker-image is specified. + --base-docker-image The name of the base docker image to use for the build. + (default : swift-:amazonlinux2) + This parameter cannot be used when --swift-version is specified. + --disable-docker-image-update Do not attempt to update the docker image + --help Show help information. + """ ) } } private struct BuilderConfiguration: CustomStringConvertible { - + // passed by the user public let help: Bool public let outputDirectory: URL @@ -280,7 +280,7 @@ private struct BuilderConfiguration: CustomStringConvertible { public init(arguments: [String]) throws { var argumentExtractor = ArgumentExtractor(arguments) - + let verboseArgument = argumentExtractor.extractFlag(named: "verbose") > 0 let outputPathArgument = argumentExtractor.extractOption(named: "output-path") let packageIDArgument = argumentExtractor.extractOption(named: "package-id") @@ -294,55 +294,55 @@ private struct BuilderConfiguration: CustomStringConvertible { let baseDockerImageArgument = argumentExtractor.extractOption(named: "base-docker-image") let disableDockerImageUpdateArgument = argumentExtractor.extractFlag(named: "disable-docker-image-update") > 0 let helpArgument = argumentExtractor.extractFlag(named: "help") > 0 - + // help required ? self.help = helpArgument - + // verbose logging required ? self.verboseLogging = verboseArgument - + // package id guard !packageIDArgument.isEmpty else { throw BuilderErrors.invalidArgument("--package-id argument is required") } self.packageID = packageIDArgument.first! - + // package display name guard !packageDisplayNameArgument.isEmpty else { throw BuilderErrors.invalidArgument("--package-display-name argument is required") } self.packageDisplayName = packageDisplayNameArgument.first! - + // package directory guard !packageDirectoryArgument.isEmpty else { throw BuilderErrors.invalidArgument("--package-directory argument is required") } self.packageDirectory = URL(fileURLWithPath: packageDirectoryArgument.first!) - + // docker tool path guard !dockerToolPathArgument.isEmpty else { throw BuilderErrors.invalidArgument("--docker-tool-path argument is required") } self.dockerToolPath = URL(fileURLWithPath: dockerToolPathArgument.first!) - + // zip tool path guard !zipToolPathArgument.isEmpty else { throw BuilderErrors.invalidArgument("--zip-tool-path argument is required") } self.zipToolPath = URL(fileURLWithPath: zipToolPathArgument.first!) - + // output directory guard !outputPathArgument.isEmpty else { throw BuilderErrors.invalidArgument("--output-path is required") } self.outputDirectory = URL(fileURLWithPath: outputPathArgument.first!) - + // products guard !productsArgument.isEmpty else { throw BuilderErrors.invalidArgument("--products argument is required") } self.products = productsArgument.flatMap { $0.split(separator: ",").map(String.init) } - + // build configuration guard let buildConfigurationName = configurationArgument.first else { throw BuilderErrors.invalidArgument("--configuration argument is equired") @@ -351,17 +351,17 @@ private struct BuilderConfiguration: CustomStringConvertible { throw BuilderErrors.invalidArgument("invalid build configuration named '\(buildConfigurationName)'") } self.buildConfiguration = _buildConfiguration - + guard !(!swiftVersionArgument.isEmpty && !baseDockerImageArgument.isEmpty) else { throw BuilderErrors.invalidArgument("--swift-version and --base-docker-image are mutually exclusive") } - + let swiftVersion = swiftVersionArgument.first ?? .none // undefined version will yield the latest docker image self.baseDockerImage = - baseDockerImageArgument.first ?? "swift:\(swiftVersion.map { $0 + "-" } ?? "")amazonlinux2" - + baseDockerImageArgument.first ?? "swift:\(swiftVersion.map { $0 + "-" } ?? "")amazonlinux2" + self.disableDockerImageUpdate = disableDockerImageUpdateArgument - + if self.verboseLogging { print("-------------------------------------------------------------------------") print("configuration") @@ -369,22 +369,22 @@ private struct BuilderConfiguration: CustomStringConvertible { print(self) } } - + var description: String { - """ - { - outputDirectory: \(self.outputDirectory) - products: \(self.products) - buildConfiguration: \(self.buildConfiguration) - dockerToolPath: \(self.dockerToolPath) - baseDockerImage: \(self.baseDockerImage) - disableDockerImageUpdate: \(self.disableDockerImageUpdate) - zipToolPath: \(self.zipToolPath) - packageID: \(self.packageID) - packageDisplayName: \(self.packageDisplayName) - packageDirectory: \(self.packageDirectory) - } - """ + """ + { + outputDirectory: \(self.outputDirectory) + products: \(self.products) + buildConfiguration: \(self.buildConfiguration) + dockerToolPath: \(self.dockerToolPath) + baseDockerImage: \(self.baseDockerImage) + disableDockerImageUpdate: \(self.disableDockerImageUpdate) + zipToolPath: \(self.zipToolPath) + packageID: \(self.packageID) + packageDisplayName: \(self.packageDisplayName) + packageDirectory: \(self.packageDirectory) + } + """ } } @@ -396,7 +396,7 @@ private enum BuilderErrors: Error, CustomStringConvertible { case failedWritingDockerfile case failedParsingDockerOutput(String) case processFailed([String], Int32) - + var description: String { switch self { case .invalidArgument(let description): diff --git a/Sources/AWSLambdaPluginHelper/lambda-deploy/Deployer.swift b/Sources/AWSLambdaPluginHelper/lambda-deploy/Deployer.swift index a9e2462f..480ff2d4 100644 --- a/Sources/AWSLambdaPluginHelper/lambda-deploy/Deployer.swift +++ b/Sources/AWSLambdaPluginHelper/lambda-deploy/Deployer.swift @@ -47,7 +47,7 @@ struct Deployer { --help Show help information. """ ) - } + } } private struct DeployerConfiguration: CustomStringConvertible { diff --git a/Sources/AWSLambdaPluginHelper/lambda-init/Initializer.swift b/Sources/AWSLambdaPluginHelper/lambda-init/Initializer.swift index 02954317..8c3d0f28 100644 --- a/Sources/AWSLambdaPluginHelper/lambda-init/Initializer.swift +++ b/Sources/AWSLambdaPluginHelper/lambda-init/Initializer.swift @@ -19,48 +19,47 @@ import Foundation #endif struct Initializer { - + private let destFileName = "Sources/main.swift" - + func initialize(arguments: [String]) async throws { - + let configuration = try InitializerConfiguration(arguments: arguments) - + if configuration.help { self.displayHelpMessage() return } - + let destFileURL = configuration.destinationDir.appendingPathComponent(destFileName) do { - + let template = TemplateType.template(for: configuration.templateType) try template.write(to: destFileURL, atomically: true, encoding: .utf8) - + if configuration.verboseLogging { print("File created at: \(destFileURL)") } - + print("✅ Lambda function written to \(destFileName)") print("📦 You can now package with: 'swift package lambda-build'") } catch { print("🛑Failed to create the Lambda function file: \(error)") } } - - + private func displayHelpMessage() { print( """ OVERVIEW: A SwiftPM plugin to scaffold a HelloWorld Lambda function. By default, it creates a Lambda function that receives a JSON document and responds with another JSON document. - + USAGE: swift package lambda-init [--help] [--verbose] [--with-url] [--allow-writing-to-package-directory] - + OPTIONS: --with-url Create a Lambda function exposed with an URL --allow-writing-to-package-directory Don't ask for permissions to write files. @@ -74,7 +73,7 @@ struct Initializer { private enum TemplateType { case `default` case url - + static func template(for type: TemplateType) -> String { switch type { case .default: return functionWithJSONTemplate @@ -88,27 +87,27 @@ private struct InitializerConfiguration: CustomStringConvertible { public let verboseLogging: Bool public let destinationDir: URL public let templateType: TemplateType - + public init(arguments: [String]) throws { var argumentExtractor = ArgumentExtractor(arguments) let verboseArgument = argumentExtractor.extractFlag(named: "verbose") > 0 let helpArgument = argumentExtractor.extractFlag(named: "help") > 0 let destDirArgument = argumentExtractor.extractOption(named: "dest-dir") let templateURLArgument = argumentExtractor.extractFlag(named: "with-url") > 0 - + // help required ? self.help = helpArgument - + // verbose logging required ? self.verboseLogging = verboseArgument - + // dest dir self.destinationDir = URL(fileURLWithPath: destDirArgument[0]) - + // template type. Default is the JSON one self.templateType = templateURLArgument ? .url : .default } - + var description: String { """ { diff --git a/Sources/AWSLambdaPluginHelper/lambda-init/Template.swift b/Sources/AWSLambdaPluginHelper/lambda-init/Template.swift index 865a122a..404d743b 100644 --- a/Sources/AWSLambdaPluginHelper/lambda-init/Template.swift +++ b/Sources/AWSLambdaPluginHelper/lambda-init/Template.swift @@ -45,7 +45,7 @@ let functionWithJSONTemplate = #""" struct HelloResponse: Encodable { let greetings: String } - + // in this example we receive a HelloRequest JSON and we return a HelloResponse JSON // the Lambda runtime