Skip to content

Commit d3713d0

Browse files
committedOct 15, 2024
feat: warn user based on flags
Like volume mount, pid, privileged, etc Signed-off-by: Yves Brissaud <[email protected]>
1 parent 02117a9 commit d3713d0

File tree

4 files changed

+81
-2
lines changed

4 files changed

+81
-2
lines changed
 

‎go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ require (
1212
github.com/dustin/go-humanize v1.0.1
1313
github.com/gertd/go-pluralize v0.2.1
1414
github.com/google/go-containerregistry v0.20.2
15+
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
1516
github.com/mattn/go-isatty v0.0.20
1617
github.com/muesli/termenv v0.15.3-0.20240618155329-98d742f6907a
1718
github.com/spf13/cobra v1.8.1

‎go.sum

+2
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,8 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN
172172
github.com/google/go-containerregistry v0.20.2 h1:B1wPJ1SN/S7pB+ZAimcciVD+r+yV/l/DSArMxlbwseo=
173173
github.com/google/go-containerregistry v0.20.2/go.mod h1:z38EKdKh4h7IP2gSfUUqEvalZBqs6AoLeWfUy34nQC8=
174174
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
175+
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
176+
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
175177
github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8=
176178
github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0=
177179
github.com/gorilla/mux v1.7.0 h1:tOSd0UKHQd6urX6ApfOn4XdBMY6Sh1MfxV3kmaazO+U=

‎internal/commands/root/root.go

+27-2
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@ package root
22

33
import (
44
"context"
5+
"errors"
56
"fmt"
67
"io"
78
"os"
89
"strings"
910

11+
"github.com/charmbracelet/huh"
1012
"github.com/charmbracelet/huh/spinner"
1113
"github.com/gertd/go-pluralize"
1214
"github.com/spf13/cobra"
@@ -19,6 +21,7 @@ import (
1921
"github.com/eunomie/docker-runx/internal/commands/help"
2022
"github.com/eunomie/docker-runx/internal/commands/version"
2123
"github.com/eunomie/docker-runx/internal/constants"
24+
"github.com/eunomie/docker-runx/internal/pizza"
2225
"github.com/eunomie/docker-runx/internal/prompt"
2326
"github.com/eunomie/docker-runx/internal/registry"
2427
"github.com/eunomie/docker-runx/internal/sugar"
@@ -224,13 +227,35 @@ func run(ctx context.Context, out io.Writer, src string, rk *runkit.RunKit, acti
224227
return err
225228
}
226229

227-
_, _ = fmt.Fprintln(out, tui.Markdown(fmt.Sprintf(`
230+
mdCommand := fmt.Sprintf(`
228231
> **Running the following command:**
229232
230233
%s
231234
232235
---
233-
`, runnable.Command)))
236+
`, runnable.Command)
237+
238+
if flags, err := runnable.CheckFlags(); err != nil {
239+
return err
240+
} else if len(flags) > 0 {
241+
_, _ = fmt.Fprintln(out, tui.Markdown(mdCommand+fmt.Sprintf(`
242+
> **Some flags require your attention:**
243+
244+
%s
245+
`, strings.Join(pizza.Map(flags, func(flag string) string {
246+
return fmt.Sprintf("- `%s`", flag)
247+
}), "\n"))))
248+
var cont bool
249+
err = huh.NewConfirm().Title("Continue?").Value(&cont).Run()
250+
if err != nil {
251+
return err
252+
}
253+
if !cont {
254+
return errors.New("aborted")
255+
}
256+
} else {
257+
_, _ = fmt.Fprintln(out, tui.Markdown(mdCommand))
258+
}
234259

235260
return runnable.Run(ctx)
236261
}

‎runkit/run.go

+51
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import (
88
"strings"
99
"text/template"
1010

11+
"github.com/google/shlex"
12+
"github.com/spf13/pflag"
1113
"mvdan.cc/sh/v3/expand"
1214
"mvdan.cc/sh/v3/interp"
1315
"mvdan.cc/sh/v3/syntax"
@@ -149,6 +151,19 @@ func (r *Runnable) compute() error {
149151
return nil
150152
}
151153

154+
func flagSet() *pflag.FlagSet {
155+
f := pflag.NewFlagSet("", pflag.ContinueOnError)
156+
f.ParseErrorsWhitelist.UnknownFlags = true
157+
f.StringArrayP("volume", "v", nil, "")
158+
f.StringArray("mount", nil, "")
159+
f.StringArrayP("publish", "p", nil, "")
160+
f.StringP("publish-all", "P", "", "")
161+
f.String("pid", "", "")
162+
f.Bool("privileged", false, "")
163+
f.String("network", "", "")
164+
return f
165+
}
166+
152167
func (r *Runnable) SetOptionValues(opts map[string]string) error {
153168
for _, opt := range r.Action.Options {
154169
if opt.Required && opts[opt.Name] == "" {
@@ -163,9 +178,45 @@ func (r *Runnable) SetOptionValues(opts map[string]string) error {
163178
}
164179

165180
r.Command = fmt.Sprintf("%s %s", r.command, r.args)
181+
166182
return nil
167183
}
168184

185+
func (r *Runnable) CheckFlags() ([]string, error) {
186+
if r.Action.Type != ActionTypeRun {
187+
return nil, nil
188+
}
189+
tokens, err := shlex.Split(r.args)
190+
if err != nil {
191+
return nil, err
192+
}
193+
194+
f := flagSet()
195+
if err = f.Parse(tokens); err != nil {
196+
return nil, err
197+
}
198+
if f.NArg() > 0 {
199+
args, _, _ := strings.Cut(r.args, f.Arg(0))
200+
tokens, err = shlex.Split(args)
201+
if err != nil {
202+
return nil, err
203+
}
204+
f = flagSet()
205+
if err = f.Parse(tokens); err != nil {
206+
return nil, err
207+
}
208+
}
209+
210+
var flagsSet []string
211+
f.Visit(func(flag *pflag.Flag) {
212+
if flag.Changed {
213+
flagsSet = append(flagsSet, flag.Name)
214+
}
215+
})
216+
217+
return flagsSet, nil
218+
}
219+
169220
func (r *Runnable) Run(ctx context.Context) error {
170221
if r.Command == "" {
171222
return fmt.Errorf("command not set")

0 commit comments

Comments
 (0)
Please sign in to comment.