Skip to content

Commit d7ac741

Browse files
committed
feat: allow to specify a default reference
Use the .docker/runx.yaml file and set the ref key If some arguments are still passed, we are trying to see if that's an image or not. If that's an image, use runx against it. But if we can't access the image, use it as if it was an action Signed-off-by: Yves Brissaud <[email protected]>
1 parent 3faef8a commit d7ac741

File tree

5 files changed

+108
-7
lines changed

5 files changed

+108
-7
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
/dist
2-
/.coverage
2+
/.coverage
3+
/.docker

internal/commands/root/root.go

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"github.com/eunomie/docker-runx/internal/commands/version"
2020
"github.com/eunomie/docker-runx/internal/constants"
2121
"github.com/eunomie/docker-runx/internal/prompt"
22+
"github.com/eunomie/docker-runx/internal/registry"
2223
"github.com/eunomie/docker-runx/internal/tui"
2324
"github.com/eunomie/docker-runx/runkit"
2425
)
@@ -35,12 +36,41 @@ func NewCmd(dockerCli command.Cli, isPlugin bool) *cobra.Command {
3536
Use: fmt.Sprintf("%s [IMAGE] [ACTION]", name),
3637
Short: "Docker Run, better",
3738
RunE: func(cmd *cobra.Command, args []string) error {
38-
if len(args) == 0 || len(args) > 2 {
39+
var (
40+
src string
41+
action string
42+
lc = runkit.GetLocalConfig()
43+
)
44+
45+
switch len(args) {
46+
case 0:
47+
src = lc.Ref
48+
if src == "" {
49+
return cmd.Help()
50+
}
51+
case 1:
52+
if lc.Ref == "" {
53+
src = args[0]
54+
} else {
55+
// here we need to know if the argument is an image or an action
56+
// there's no easy way, so what we'll do is to check if the argument is a reachable image
57+
if registry.ImageExist(cmd.Context(), args[0]) {
58+
// the image exist, let's say we override the default reference
59+
src = args[0]
60+
} else {
61+
// we can't access the image, let's say it's an action
62+
src = lc.Ref
63+
action = args[0]
64+
}
65+
}
66+
case 2:
67+
src = args[0]
68+
action = args[1]
69+
default:
3970
return cmd.Help()
4071
}
4172

4273
var (
43-
src = args[0]
4474
err error
4575
rk *runkit.RunKit
4676
)
@@ -64,7 +94,7 @@ func NewCmd(dockerCli command.Cli, isPlugin bool) *cobra.Command {
6494
return nil
6595
}
6696

67-
if list || len(args) == 1 {
97+
if list || action == "" {
6898
if tui.IsATTY(dockerCli.In().FD()) {
6999
action := prompt.SelectAction(rk.Config.Actions)
70100
if action != "" {
@@ -76,9 +106,7 @@ func NewCmd(dockerCli command.Cli, isPlugin bool) *cobra.Command {
76106
return nil
77107
}
78108

79-
if len(args) == 2 {
80-
action := args[1]
81-
109+
if action != "" {
82110
return run(cmd.Context(), dockerCli.Err(), rk, action)
83111
}
84112

internal/registry/check.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package registry
2+
3+
import (
4+
"context"
5+
6+
"github.com/google/go-containerregistry/pkg/name"
7+
"github.com/google/go-containerregistry/pkg/v1/remote"
8+
)
9+
10+
func ImageExist(ctx context.Context, src string) bool {
11+
var (
12+
err error
13+
remoteOpts = WithOptions(ctx, nil)
14+
ref, _ = name.ParseReference(src)
15+
)
16+
17+
_, err = remote.Head(ref, remoteOpts...)
18+
return err == nil
19+
}

runkit/config.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package runkit
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
"os"
7+
"sync"
8+
9+
"gopkg.in/yaml.v2"
10+
)
11+
12+
const (
13+
DefaultLocalConfigFile = ".docker/runx.yaml"
14+
)
15+
16+
var (
17+
localConfig LocalConfig
18+
readOnce = sync.Once{}
19+
)
20+
21+
func GetLocalConfig() LocalConfig {
22+
readOnce.Do(func() {
23+
lc, err := getLocalConfig()
24+
if err != nil {
25+
_, _ = fmt.Fprintf(os.Stderr, "error reading local config: %v\n", err)
26+
os.Exit(1)
27+
}
28+
localConfig = lc
29+
})
30+
return localConfig
31+
}
32+
33+
func getLocalConfig() (LocalConfig, error) {
34+
data, err := os.ReadFile(DefaultLocalConfigFile)
35+
if err != nil {
36+
if errors.Is(err, os.ErrNotExist) {
37+
// in this case we just don't have a config file, so use everything as default
38+
return LocalConfig{}, nil
39+
}
40+
return LocalConfig{}, err
41+
}
42+
43+
var config LocalConfig
44+
if err = yaml.Unmarshal(data, &config); err != nil {
45+
return LocalConfig{}, err
46+
}
47+
48+
return config, nil
49+
}

runkit/types.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ type (
3030
}
3131

3232
ActionType string
33+
34+
LocalConfig struct {
35+
Ref string `yaml:"ref,omitempty" json:"ref,omitempty"`
36+
}
3337
)
3438

3539
const (

0 commit comments

Comments
 (0)