11package compose
22
33import (
4+ "bufio"
45 "context"
56 "fmt"
67 "os"
78 "os/exec"
9+ "regexp"
810 "strings"
911 "syscall"
1012
@@ -13,6 +15,7 @@ import (
1315 "github.com/werf/logboek"
1416 "github.com/werf/werf/v2/cmd/werf/common"
1517 "github.com/werf/werf/v2/pkg/build"
18+ "github.com/werf/werf/v2/pkg/config"
1619 "github.com/werf/werf/v2/pkg/container_backend"
1720 "github.com/werf/werf/v2/pkg/git_repo"
1821 "github.com/werf/werf/v2/pkg/git_repo/gitdata"
@@ -47,6 +50,95 @@ type composeCmdData struct {
4750 imagesToProcess build.ImagesToProcess
4851}
4952
53+ func (d * composeCmdData ) GetOrExtractImagesToProcess (werfConfig * config.WerfConfig ) (build.ImagesToProcess , error ) {
54+ if len (d .imagesToProcess .ImageNameList ) != 0 {
55+ return d .imagesToProcess , nil
56+ }
57+
58+ // Replace all special characters in image name with empty string to find the same image name in werf config.
59+ replaceAllFunc := func (s string ) string {
60+ for _ , l := range []string {"_" , "-" , "/" } {
61+ s = strings .ReplaceAll (s , l , "" )
62+ }
63+ return s
64+ }
65+
66+ extractedImageNameList , err := extractImageNamesFromDockerComposeFile (d .getComposeFilePath ())
67+ if err != nil {
68+ return build.ImagesToProcess {}, fmt .Errorf ("unable to extract image names from docker-compose file: %w" , err )
69+ }
70+
71+ configImageNameList := werfConfig .GetImageNameList (false )
72+
73+ var imageNameList []string
74+ for _ , configImageName := range configImageNameList {
75+ for _ , imageName := range extractedImageNameList {
76+ if configImageName == imageName {
77+ imageNameList = append (imageNameList , imageName )
78+ continue
79+ }
80+
81+ if replaceAllFunc (configImageName ) == replaceAllFunc (imageName ) {
82+ imageNameList = append (imageNameList , configImageName )
83+ continue
84+ }
85+ }
86+ }
87+
88+ return build .NewImagesToProcess (imageNameList , len (imageNameList ) == 0 ), nil
89+ }
90+
91+ func (d * composeCmdData ) getComposeFilePath () string {
92+ for ind , value := range d .ComposeOptions {
93+ if strings .HasPrefix (value , "-f" ) || strings .HasPrefix (value , "--file" ) {
94+ parts := strings .Split (value , "=" )
95+ if len (parts ) == 2 {
96+ return parts [1 ]
97+ } else if len (d .ComposeOptions ) > ind + 1 {
98+ return d .ComposeOptions [ind + 1 ]
99+ }
100+ }
101+ }
102+
103+ return "docker-compose.yml"
104+ }
105+
106+ func extractImageNamesFromDockerComposeFile (filename string ) ([]string , error ) {
107+ file , err := os .Open (filename )
108+ if err != nil {
109+ return nil , fmt .Errorf ("error opening file: %v" , err )
110+ }
111+ defer file .Close ()
112+
113+ // Matches $WERF_<IMAGE_NAME>_DOCKER_IMAGE_NAME and ${WERF_<IMAGE_NAME>_DOCKER_IMAGE_NAME}.
114+ re := regexp .MustCompile (`\${?WERF_(.*)_DOCKER_IMAGE_NAME}?` )
115+
116+ var imageNames []string
117+ scanner := bufio .NewScanner (file )
118+ for scanner .Scan () {
119+ line := strings .TrimSpace (scanner .Text ())
120+
121+ // Ignore commented lines.
122+ if strings .HasPrefix (line , "#" ) {
123+ continue
124+ }
125+
126+ matches := re .FindAllStringSubmatch (line , - 1 )
127+ for _ , match := range matches {
128+ if len (match ) > 1 {
129+ imageName := strings .ToLower (match [1 ])
130+ imageNames = append (imageNames , imageName )
131+ }
132+ }
133+ }
134+
135+ if err := scanner .Err (); err != nil {
136+ return nil , fmt .Errorf ("error reading file: %v" , err )
137+ }
138+
139+ return imageNames , nil
140+ }
141+
50142func NewConfigCmd (ctx context.Context ) * cobra.Command {
51143 return newCmd (ctx , "config" , & newCmdOptions {
52144 Use : "config [IMAGE_NAME...] [options] [--docker-compose-options=\" OPTIONS\" ] [--docker-compose-command-options=\" OPTIONS\" ]" ,
@@ -342,13 +434,16 @@ func runMain(ctx context.Context, dockerComposeCmdName string, cmdData composeCm
342434}
343435
344436func run (ctx context.Context , containerBackend container_backend.ContainerBackend , giterminismManager giterminism_manager.Interface , commonCmdData common.CmdData , cmdData composeCmdData , dockerComposeCmdName string ) error {
345- imagesToProcess := cmdData .imagesToProcess
346-
347437 _ , werfConfig , err := common .GetRequiredWerfConfig (ctx , & commonCmdData , giterminismManager , common .GetWerfConfigOptions (& commonCmdData , true ))
348438 if err != nil {
349439 return fmt .Errorf ("unable to load werf config: %w" , err )
350440 }
351441
442+ imagesToProcess , err := cmdData .GetOrExtractImagesToProcess (werfConfig )
443+ if err != nil {
444+ return err
445+ }
446+
352447 if err := imagesToProcess .CheckImagesExistence (werfConfig ); err != nil {
353448 return err
354449 }
0 commit comments