@@ -16,6 +16,7 @@ package build
16
16
17
17
import (
18
18
"archive/tar"
19
+ "bufio"
19
20
"bytes"
20
21
"context"
21
22
"errors"
@@ -252,7 +253,14 @@ func getGoBinary() string {
252
253
}
253
254
254
255
func build (ctx context.Context , ip string , dir string , platform v1.Platform , config Config ) (string , error ) {
255
- buildArgs , err := createBuildArgs (config )
256
+ // Merge the user and config environment variables.
257
+ mergedEnv , err := buildEnv (platform , os .Environ (), config .Env )
258
+ if err != nil {
259
+ return "" , fmt .Errorf ("could not create env for %s: %w" , ip , err )
260
+ }
261
+
262
+ // Get the version of the GO binary used to build.
263
+ buildArgs , err := createBuildArgs (ctx , mergedEnv , config )
256
264
if err != nil {
257
265
return "" , err
258
266
}
@@ -261,11 +269,6 @@ func build(ctx context.Context, ip string, dir string, platform v1.Platform, con
261
269
args = append (args , "build" )
262
270
args = append (args , buildArgs ... )
263
271
264
- env , err := buildEnv (platform , os .Environ (), config .Env )
265
- if err != nil {
266
- return "" , fmt .Errorf ("could not create env for %s: %w" , ip , err )
267
- }
268
-
269
272
tmpDir := ""
270
273
271
274
if dir := os .Getenv ("KOCACHE" ); dir != "" {
@@ -301,7 +304,7 @@ func build(ctx context.Context, ip string, dir string, platform v1.Platform, con
301
304
gobin := getGoBinary ()
302
305
cmd := exec .CommandContext (ctx , gobin , args ... )
303
306
cmd .Dir = dir
304
- cmd .Env = env
307
+ cmd .Env = mergedEnv
305
308
306
309
var output bytes.Buffer
307
310
cmd .Stderr = & output
@@ -310,13 +313,49 @@ func build(ctx context.Context, ip string, dir string, platform v1.Platform, con
310
313
log .Printf ("Building %s for %s" , ip , platform )
311
314
if err := cmd .Run (); err != nil {
312
315
if os .Getenv ("KOCACHE" ) == "" {
313
- os .RemoveAll (tmpDir )
316
+ _ = os .RemoveAll (tmpDir )
314
317
}
315
318
return "" , fmt .Errorf ("go build: %w: %s" , err , output .String ())
316
319
}
317
320
return file , nil
318
321
}
319
322
323
+ func goenv (ctx context.Context ) (map [string ]string , error ) {
324
+ gobin := getGoBinary ()
325
+ cmd := exec .CommandContext (ctx , gobin , "env" )
326
+ var output bytes.Buffer
327
+ cmd .Stdout = & output
328
+ cmd .Stderr = & output
329
+ if err := cmd .Run (); err != nil {
330
+ return nil , fmt .Errorf ("go env: %w: %s" , err , output .String ())
331
+ }
332
+
333
+ env := make (map [string ]string )
334
+ scanner := bufio .NewScanner (bytes .NewReader (output .Bytes ()))
335
+
336
+ line := 0
337
+ for scanner .Scan () {
338
+ line ++
339
+ kv := strings .SplitN (scanner .Text (), "=" , 2 )
340
+ if len (kv ) != 2 {
341
+ return nil , fmt .Errorf ("go env: failed parsing line: %d" , line )
342
+ }
343
+ key := strings .TrimSpace (kv [0 ])
344
+ value := strings .TrimSpace (kv [1 ])
345
+
346
+ // Unquote the value. Handle single or double quoted strings.
347
+ if len (value ) > 1 && ((value [0 ] == '\'' && value [len (value )- 1 ] == '\'' ) ||
348
+ (value [0 ] == '"' && value [len (value )- 1 ] == '"' )) {
349
+ value = value [1 : len (value )- 1 ]
350
+ }
351
+ env [key ] = value
352
+ }
353
+ if err := scanner .Err (); err != nil {
354
+ return nil , fmt .Errorf ("go env: failed parsing: %w" , err )
355
+ }
356
+ return env , nil
357
+ }
358
+
320
359
func goversionm (ctx context.Context , file string , appPath string , appFileName string , se oci.SignedEntity , dir string ) ([]byte , types.MediaType , error ) {
321
360
gobin := getGoBinary ()
322
361
@@ -708,18 +747,35 @@ func (g *gobuild) tarKoData(ref reference, platform *v1.Platform) (*bytes.Buffer
708
747
return buf , walkRecursive (tw , root , chroot , creationTime , platform )
709
748
}
710
749
711
- func createTemplateData () map [string ]interface {} {
750
+ func createTemplateData (ctx context. Context , mergedEnv [] string ) ( map [string ]interface {}, error ) {
712
751
envVars := map [string ]string {
713
752
"LDFLAGS" : "" ,
714
753
}
715
- for _ , entry := range os . Environ () {
754
+ for _ , entry := range mergedEnv {
716
755
kv := strings .SplitN (entry , "=" , 2 )
756
+ if len (kv ) != 2 {
757
+ return nil , fmt .Errorf ("invalid entry in os.Environ %q" , entry )
758
+ }
717
759
envVars [kv [0 ]] = kv [1 ]
718
760
}
719
761
720
- return map [string ]interface {}{
721
- "Env" : envVars ,
762
+ // Get the go environment.
763
+ goEnv , err := goenv (ctx )
764
+ if err != nil {
765
+ return nil , err
722
766
}
767
+
768
+ // Override go env with any matching values from the merged variables.
769
+ for k , v := range envVars {
770
+ if _ , ok := goEnv [k ]; ok {
771
+ goEnv [k ] = v
772
+ }
773
+ }
774
+
775
+ return map [string ]interface {}{
776
+ "Env" : envVars ,
777
+ "GoEnv" : goEnv ,
778
+ }, nil
723
779
}
724
780
725
781
func applyTemplating (list []string , data map [string ]interface {}) ([]string , error ) {
@@ -741,10 +797,13 @@ func applyTemplating(list []string, data map[string]interface{}) ([]string, erro
741
797
return result , nil
742
798
}
743
799
744
- func createBuildArgs (buildCfg Config ) ([]string , error ) {
800
+ func createBuildArgs (ctx context. Context , mergedEnv [] string , buildCfg Config ) ([]string , error ) {
745
801
var args []string
746
802
747
- data := createTemplateData ()
803
+ data , err := createTemplateData (ctx , mergedEnv )
804
+ if err != nil {
805
+ return nil , err
806
+ }
748
807
749
808
if len (buildCfg .Flags ) > 0 {
750
809
flags , err := applyTemplating (buildCfg .Flags , data )
@@ -1063,7 +1122,7 @@ func (g *gobuild) buildAll(ctx context.Context, ref string, baseRef name.Referen
1063
1122
return nil , err
1064
1123
}
1065
1124
1066
- matches := []v1.Descriptor {}
1125
+ var matches []v1.Descriptor
1067
1126
for _ , desc := range im .Manifests {
1068
1127
// Nested index is pretty rare. We could support this in theory, but return an error for now.
1069
1128
if desc .MediaType != types .OCIManifestSchema1 && desc .MediaType != types .DockerManifestSchema2 {
@@ -1188,7 +1247,7 @@ func parseSpec(spec []string) (*platformMatcher, error) {
1188
1247
return & platformMatcher {spec : spec }, nil
1189
1248
}
1190
1249
1191
- platforms := []v1.Platform {}
1250
+ var platforms []v1.Platform
1192
1251
for _ , s := range spec {
1193
1252
p , err := v1 .ParsePlatform (s )
1194
1253
if err != nil {
0 commit comments