Skip to content

Commit 6bafc07

Browse files
authored
Merge pull request #2728 from 89luca89/fix/run_watch_globs
fix: run_watch glob pattern handling
2 parents 5f97e99 + 2d4121d commit 6bafc07

4 files changed

Lines changed: 67 additions & 3 deletions

File tree

docs/pages/_partials/command_run_watch.mdx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,16 @@ run_watch --path [MY_PATH] -- [my_command]
1212

1313
### `--path`, `-p`
1414

15-
The paths to watch. Can be patterns in the form of `./**/my-file.txt`.
15+
The paths to watch. Can be patterns in the form of `"./**/my-file.txt"`.
16+
17+
Please note that globgs need to be quoted in order to avoid them being expanded
18+
by your shell, for example:
19+
20+
21+
```
22+
run_watch --path "**/*.go" -- devspace dev
23+
```
24+
1625

1726
```
1827
```

e2e/tests/pipelines/pipelines.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,34 @@ var _ = DevSpaceDescribe("pipelines", func() {
301301
framework.ExpectNoError(err)
302302
}
303303
})
304+
ginkgo.It("should fail to watch files with unquoted globbing", func(ctx context.Context) {
305+
tempDir, err := framework.CopyToTempDir("tests/pipelines/testdata/run_watch")
306+
framework.ExpectNoError(err)
307+
ginkgo.DeferCleanup(framework.CleanupTempDir, initialDir, tempDir)
308+
309+
ns, err := kubeClient.CreateNamespace("pipelines")
310+
framework.ExpectNoError(err)
311+
ginkgo.DeferCleanup(framework.ExpectDeleteNamespace, kubeClient, ns)
312+
313+
cancelCtx, cancel := context.WithCancel(ctx)
314+
ginkgo.DeferCleanup(cancel)
315+
316+
output := &bytes.Buffer{}
317+
multiWriter := io.MultiWriter(output, os.Stdout)
318+
log := logpkg.NewStreamLogger(multiWriter, multiWriter, logrus.DebugLevel)
319+
320+
devCmd := &cmd.RunPipelineCmd{
321+
GlobalFlags: &flags.GlobalFlags{
322+
NoWarn: true,
323+
Namespace: ns,
324+
},
325+
Pipeline: "unquoted-glob",
326+
Ctx: cancelCtx,
327+
Log: log,
328+
}
329+
err = devCmd.RunDefault(f)
330+
framework.ExpectError(err)
331+
})
304332

305333
ginkgo.It("should use --set and --set-string values from run_pipelines command", func() {
306334
tempDir, err := framework.CopyToTempDir("tests/pipelines/testdata/run_pipelines")

e2e/tests/pipelines/testdata/run_watch/devspace.yaml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,9 @@ pipelines:
3232
--path './foo*/**/*' \
3333
--exclude './foo2/*' \
3434
-- date
35-
36-
35+
36+
unquoted-glob: |-
37+
# Still triggers run_watch for foo2/bar2.txt changes
38+
run_watch \
39+
--path **/* \
40+
-- date

pkg/devspace/pipeline/engine/basichandler/commands/run_watch.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,15 @@ type RunWatchOptions struct {
3030
}
3131

3232
func RunWatch(ctx context.Context, args []string, handler types2.ExecHandler, log log.Logger) error {
33+
command := []string{}
34+
35+
// Separately handle the `--` catchall flag
36+
// in order to have clean arguments for the parsing below
37+
commandINdex := indexOf("--", args)
38+
if commandINdex > 0 {
39+
command = args[commandINdex+1:]
40+
}
41+
3342
options := &RunWatchOptions{}
3443
args, err := flags.ParseArgs(options, args)
3544
if err != nil {
@@ -41,10 +50,15 @@ func RunWatch(ctx context.Context, args []string, handler types2.ExecHandler, lo
4150
if len(args) == 0 {
4251
return fmt.Errorf("usage: run_watch --path MY_PATH -- my_command")
4352
}
53+
if len(args) > len(command) {
54+
// if we have more args left thant the one after "--" then we have some invalid flags inside
55+
return fmt.Errorf("invalid flags: %v, usage: run_watch --path MY_PATH --path 'MY/**/GLOB*/PATH' -- my_command", command)
56+
}
4457

4558
w := &watcher{
4659
options: *options,
4760
}
61+
4862
return w.Watch(ctx, func(ctx context.Context) error {
4963
return handler.ExecHandler(ctx, args)
5064
}, log)
@@ -232,3 +246,12 @@ func (w *watcher) startCommand(ctx context.Context, action func(ctx context.Cont
232246
})
233247
return t
234248
}
249+
250+
func indexOf(element string, data []string) int {
251+
for k, v := range data {
252+
if element == v {
253+
return k
254+
}
255+
}
256+
return -1
257+
}

0 commit comments

Comments
 (0)