@@ -23,22 +23,18 @@ import (
23
23
"io"
24
24
"net/http"
25
25
"os"
26
- "path"
27
26
"path/filepath"
28
27
"sort"
29
28
"strings"
30
29
"sync"
31
30
32
31
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2"
33
- "github.com/GoogleContainerTools/skaffold/pkg/skaffold/util"
34
- "github.com/google/go-containerregistry/v1"
35
-
32
+ "github.com/docker/docker/builder/dockerignore"
33
+ "github.com/docker/docker/pkg/fileutils"
36
34
"github.com/google/go-containerregistry/authn"
37
35
"github.com/google/go-containerregistry/name"
36
+ "github.com/google/go-containerregistry/v1"
38
37
"github.com/google/go-containerregistry/v1/remote"
39
-
40
- "github.com/docker/docker/builder/dockerignore"
41
- "github.com/docker/docker/pkg/fileutils"
42
38
"github.com/moby/moby/builder/dockerfile/parser"
43
39
"github.com/moby/moby/builder/dockerfile/shell"
44
40
"github.com/pkg/errors"
@@ -62,11 +58,9 @@ func (d *DockerfileDepResolver) GetDependencies(a *v1alpha2.Artifact) ([]string,
62
58
return GetDockerfileDependencies (a .DockerArtifact .DockerfilePath , a .Workspace )
63
59
}
64
60
65
- // GetDockerfileDependencies parses a dockerfile and returns the full paths
66
- // of all the source files that the resulting docker image depends on.
67
- func GetDockerfileDependencies (dockerfilePath , workspace string ) ([]string , error ) {
61
+ func readDockerfile (workspace , dockerfilePath string ) ([]string , error ) {
68
62
path := filepath .Join (workspace , dockerfilePath )
69
- f , err := util . Fs .Open (path )
63
+ f , err := os .Open (path )
70
64
if err != nil {
71
65
return nil , errors .Wrapf (err , "opening dockerfile: %s" , path )
72
66
}
@@ -96,7 +90,7 @@ func GetDockerfileDependencies(dockerfilePath, workspace string) ([]string, erro
96
90
for _ , value := range r .AST .Children {
97
91
switch value .Value {
98
92
case add , copy :
99
- processCopy (workspace , value , depMap , envs )
93
+ processCopy (value , depMap , envs )
100
94
case env :
101
95
envs [value .Next .Value ] = value .Next .Next .Value
102
96
}
@@ -114,30 +108,86 @@ func GetDockerfileDependencies(dockerfilePath, workspace string) ([]string, erro
114
108
115
109
dispatchInstructions (res )
116
110
117
- deps := []string {}
111
+ var deps []string
118
112
for dep := range depMap {
119
113
deps = append (deps , dep )
120
114
}
121
115
logrus .Infof ("Found dependencies for dockerfile %s" , deps )
122
116
123
- expandedDeps , err := util .ExpandPaths (workspace , deps )
117
+ return deps , nil
118
+ }
119
+
120
+ func GetDockerfileDependencies (dockerfilePath , workspace string ) ([]string , error ) {
121
+ deps , err := readDockerfile (workspace , dockerfilePath )
124
122
if err != nil {
125
- return nil , errors . Wrap ( err , "expanding dockerfile paths" )
123
+ return nil , err
126
124
}
127
- logrus .Infof ("deps %s" , expandedDeps )
128
125
129
- if ! util .StrSliceContains (expandedDeps , path ) {
130
- expandedDeps = append (expandedDeps , path )
126
+ // Read patterns to ignore
127
+ var excludes []string
128
+ dockerignorePath := filepath .Join (workspace , ".dockerignore" )
129
+ if _ , err := os .Stat (dockerignorePath ); ! os .IsNotExist (err ) {
130
+ r , err := os .Open (dockerignorePath )
131
+ if err != nil {
132
+ return nil , err
133
+ }
134
+ defer r .Close ()
135
+
136
+ excludes , err = dockerignore .ReadAll (r )
137
+ if err != nil {
138
+ return nil , err
139
+ }
140
+ }
141
+
142
+ // Walk the workspace
143
+ files := make (map [string ]bool )
144
+ for _ , dep := range deps {
145
+ filepath .Walk (filepath .Join (workspace , dep ), func (fpath string , info os.FileInfo , err error ) error {
146
+ if err != nil {
147
+ return err
148
+ }
149
+
150
+ relPath , err := filepath .Rel (workspace , fpath )
151
+ if err != nil {
152
+ return err
153
+ }
154
+
155
+ ignored , err := fileutils .Matches (relPath , excludes )
156
+ if err != nil {
157
+ return err
158
+ }
159
+
160
+ if info .IsDir () && ignored {
161
+ return filepath .SkipDir
162
+ }
163
+
164
+ if ! info .IsDir () && ! ignored {
165
+ files [relPath ] = true
166
+ }
167
+
168
+ return nil
169
+ })
131
170
}
132
171
133
- // Look for .dockerignore.
134
- ignorePath := filepath .Join (workspace , ".dockerignore" )
135
- filteredDeps , err := ApplyDockerIgnore (expandedDeps , ignorePath )
172
+ // Add dockerfile?
173
+ m , err := fileutils .Matches (dockerfilePath , excludes )
136
174
if err != nil {
137
- return nil , errors .Wrap (err , "applying dockerignore" )
175
+ return nil , err
176
+ }
177
+ if ! m {
178
+ files [dockerfilePath ] = true
138
179
}
139
180
140
- return filteredDeps , nil
181
+ // Ignore .dockerignore
182
+ delete (files , ".dockerignore" )
183
+
184
+ var dependencies []string
185
+ for file := range files {
186
+ dependencies = append (dependencies , file )
187
+ }
188
+ sort .Strings (dependencies )
189
+
190
+ return dependencies , nil
141
191
}
142
192
143
193
func PortsFromDockerfile (r io.Reader ) ([]string , error ) {
@@ -256,7 +306,7 @@ func retrieveRemoteImage(image string) (*v1.ConfigFile, error) {
256
306
return img .ConfigFile ()
257
307
}
258
308
259
- func processCopy (workspace string , value * parser.Node , paths map [string ]struct {}, envs map [string ]string ) error {
309
+ func processCopy (value * parser.Node , paths map [string ]struct {}, envs map [string ]string ) error {
260
310
slex := shell .NewLex ('\\' )
261
311
for {
262
312
// Skip last node, since it is the destination, and stop if we arrive at a comment
@@ -273,8 +323,7 @@ func processCopy(workspace string, value *parser.Node, paths map[string]struct{}
273
323
return nil
274
324
}
275
325
if ! strings .HasPrefix (src , "http://" ) && ! strings .HasPrefix (src , "https://" ) {
276
- dep := path .Join (workspace , src )
277
- paths [dep ] = struct {}{}
326
+ paths [src ] = struct {}{}
278
327
} else {
279
328
logrus .Debugf ("Skipping watch on remote dependency %s" , src )
280
329
}
@@ -300,42 +349,3 @@ func hasMultiStageFlag(flags []string) bool {
300
349
}
301
350
return false
302
351
}
303
-
304
- func ApplyDockerIgnore (paths []string , dockerIgnorePath string ) ([]string , error ) {
305
- absPaths , err := util .RelPathToAbsPath (paths )
306
- if err != nil {
307
- return nil , errors .Wrap (err , "getting absolute path of dependencies" )
308
- }
309
- excludes := []string {}
310
- if _ , err := util .Fs .Stat (dockerIgnorePath ); ! os .IsNotExist (err ) {
311
- r , err := util .Fs .Open (dockerIgnorePath )
312
- if err != nil {
313
- return nil , err
314
- }
315
- defer r .Close ()
316
-
317
- excludes , err = dockerignore .ReadAll (r )
318
- if err != nil {
319
- return nil , err
320
- }
321
- excludes = append (excludes , ".dockerignore" )
322
- }
323
-
324
- absPathExcludes , err := util .RelPathToAbsPath (excludes )
325
- if err != nil {
326
- return nil , errors .Wrap (err , "getting absolute path of docker ignored paths" )
327
- }
328
-
329
- filteredDeps := []string {}
330
- for _ , d := range absPaths {
331
- m , err := fileutils .Matches (d , absPathExcludes )
332
- if err != nil {
333
- return nil , err
334
- }
335
- if ! m {
336
- filteredDeps = append (filteredDeps , d )
337
- }
338
- }
339
- sort .Strings (filteredDeps )
340
- return filteredDeps , nil
341
- }
0 commit comments