@@ -32,6 +32,7 @@ struct AWSLambdaPackager: CommandPlugin {
32
32
if self . isAmazonLinux2 ( ) {
33
33
// build directly on the machine
34
34
builtProducts = try self . build (
35
+ packageIdentity: context. package . id,
35
36
products: configuration. products,
36
37
buildConfiguration: configuration. buildConfiguration,
37
38
verboseLogging: configuration. verboseLogging
@@ -76,57 +77,51 @@ struct AWSLambdaPackager: CommandPlugin {
76
77
) throws -> [ LambdaProduct : Path ] {
77
78
let dockerToolPath = try toolsProvider ( " docker " )
78
79
79
- /*
80
- if verboseLogging {
81
- print("-------------------------------------------------------------------------")
82
- print("preparing docker build image")
83
- print("-------------------------------------------------------------------------")
84
- }
85
- let packageDockerFilePath = packageDirectory.appending("Dockerfile")
86
- let tempDockerFilePath = outputDirectory.appending("Dockerfile")
87
- try FileManager.default.createDirectory(atPath: tempDockerFilePath.removingLastComponent().string, withIntermediateDirectories: true)
88
- if FileManager.default.fileExists(atPath: packageDockerFilePath.string) {
89
- try FileManager.default.copyItem(atPath: packageDockerFilePath.string, toPath: tempDockerFilePath.string)
90
- } else {
91
- FileManager.default.createFile(atPath: tempDockerFilePath.string, contents: "FROM \(baseImage)".data(using: .utf8))
92
- }
93
- try self.execute(
94
- executable: dockerToolPath,
95
- arguments: ["build", "-f", tempDockerFilePath.string, packageDirectory.string , "-t", "\(builderImageName)"],
96
- verboseLogging: verboseLogging
97
- )
98
- */
99
-
100
- let builderImageName = baseImage
80
+ print ( " ------------------------------------------------------------------------- " )
81
+ print ( " building \" \( packageIdentity) \" in docker " )
82
+ print ( " ------------------------------------------------------------------------- " )
83
+
84
+ // get the build output path
85
+ let buildOutputPathCommand = " swift build -c \( buildConfiguration. rawValue) --show-bin-path "
86
+ let dockerBuildOutputPath = try self . execute (
87
+ executable: dockerToolPath,
88
+ arguments: [ " run " , " --rm " , " -v " , " \( packageDirectory. string) :/workspace " , " -w " , " /workspace " , baseImage, " bash " , " -cl " , buildOutputPathCommand] ,
89
+ logLevel: verboseLogging ? . debug : . silent
90
+ )
91
+ let buildOutputPath = Path ( dockerBuildOutputPath. replacingOccurrences ( of: " /workspace " , with: packageDirectory. string) )
101
92
93
+ // build the products
102
94
var builtProducts = [ LambdaProduct: Path] ( )
103
95
for product in products {
104
- print ( " ------------------------------------------------------------------------- " )
105
- print ( " building \" \( product. name) \" in docker " )
106
- print ( " ------------------------------------------------------------------------- " )
107
- //
108
- let buildCommand = " swift build --product \( product. name) -c \( buildConfiguration. rawValue) --static-swift-stdlib "
96
+ print ( " building \" \( product. name) \" " )
97
+ let buildCommand = " swift build -c \( buildConfiguration. rawValue) --product \( product. name) --static-swift-stdlib "
109
98
try self . execute (
110
99
executable: dockerToolPath,
111
- arguments: [ " run " , " --rm " , " -v " , " \( packageDirectory. string) :/workspace " , " -w " , " /workspace " , builderImageName , " bash " , " -cl " , buildCommand] ,
112
- verboseLogging : verboseLogging
100
+ arguments: [ " run " , " --rm " , " -v " , " \( packageDirectory. string) :/workspace " , " -w " , " /workspace " , baseImage , " bash " , " -cl " , buildCommand] ,
101
+ logLevel : verboseLogging ? . debug : . output
113
102
)
114
- // TODO: this knows too much about the underlying implementation
115
- builtProducts [ . init( product) ] = packageDirectory. appending ( [ " .build " , buildConfiguration. rawValue, product. name] )
103
+ let productPath = buildOutputPath. appending ( product. name)
104
+ guard FileManager . default. fileExists ( atPath: productPath. string) else {
105
+ throw Errors . productExecutableNotFound ( " could not find executable for ' \( product. name) ', expected at ' \( productPath) ' " )
106
+ }
107
+ builtProducts [ . init( product) ] = productPath
116
108
}
117
109
return builtProducts
118
110
}
119
111
120
112
private func build(
113
+ packageIdentity: Package . ID ,
121
114
products: [ Product ] ,
122
115
buildConfiguration: PackageManager . BuildConfiguration ,
123
116
verboseLogging: Bool
124
117
) throws -> [ LambdaProduct : Path ] {
118
+ print ( " ------------------------------------------------------------------------- " )
119
+ print ( " building \" \( packageIdentity) \" " )
120
+ print ( " ------------------------------------------------------------------------- " )
121
+
125
122
var results = [ LambdaProduct: Path] ( )
126
123
for product in products {
127
- print ( " ------------------------------------------------------------------------- " )
128
124
print ( " building \" \( product. name) \" " )
129
- print ( " ------------------------------------------------------------------------- " )
130
125
var parameters = PackageManager . BuildParameters ( )
131
126
parameters. configuration = buildConfiguration
132
127
parameters. otherSwiftcFlags = [ " -static-stdlib " ]
@@ -183,7 +178,7 @@ struct AWSLambdaPackager: CommandPlugin {
183
178
try self . execute (
184
179
executable: zipToolPath,
185
180
arguments: arguments,
186
- verboseLogging : verboseLogging
181
+ logLevel : verboseLogging ? . debug : . silent
187
182
)
188
183
189
184
archives [ product] = zipfilePath
@@ -196,9 +191,9 @@ struct AWSLambdaPackager: CommandPlugin {
196
191
executable: Path ,
197
192
arguments: [ String ] ,
198
193
customWorkingDirectory: Path ? = . none,
199
- verboseLogging : Bool
194
+ logLevel : ProcessLogLevel
200
195
) throws -> String {
201
- if verboseLogging {
196
+ if logLevel >= . debug {
202
197
print ( " \( executable. string) \( arguments. joined ( separator: " " ) ) " )
203
198
}
204
199
@@ -207,13 +202,17 @@ struct AWSLambdaPackager: CommandPlugin {
207
202
let outputQueue = DispatchQueue ( label: " AWSLambdaPackager.output " )
208
203
let outputHandler = { ( data: Data ? ) in
209
204
dispatchPrecondition ( condition: . onQueue( outputQueue) )
205
+
206
+ sync. enter ( )
207
+ defer { sync. leave ( ) }
208
+
210
209
guard let _output = data. flatMap ( { String ( data: $0, encoding: . utf8) ? . trimmingCharacters ( in: CharacterSet ( [ " \n " ] ) ) } ) , !_output. isEmpty else {
211
210
return
212
211
}
213
- sync . enter ( )
214
- defer { sync . leave ( ) }
215
- print ( _output )
216
- fflush ( stdout )
212
+ if logLevel >= . output {
213
+ print ( _output )
214
+ fflush ( stdout )
215
+ }
217
216
output += _output
218
217
}
219
218
@@ -350,11 +349,22 @@ private enum Errors: Error {
350
349
case unknownProduct( String )
351
350
case unknownExecutable( String )
352
351
case buildError( String )
352
+ case productExecutableNotFound( String )
353
353
case failedWritingDockerfile
354
354
case processFailed( Int32 )
355
355
case invalidProcessOutput
356
356
}
357
357
358
+ private enum ProcessLogLevel : Int , Comparable {
359
+ case silent = 0
360
+ case output = 1
361
+ case debug = 2
362
+
363
+ static func < ( lhs: ProcessLogLevel , rhs: ProcessLogLevel ) -> Bool {
364
+ lhs. rawValue < rhs. rawValue
365
+ }
366
+ }
367
+
358
368
extension PackageManager . BuildResult {
359
369
// find the executable produced by the build
360
370
func executableArtifact( for product: Product ) -> PackageManager . BuildResult . BuiltArtifact ? {
0 commit comments