@@ -5,116 +5,148 @@ import (
5
5
"strings"
6
6
)
7
7
8
+ type pkgExtractor func (args []string ) (string , error )
9
+
10
+ type flagNameSet map [string ]struct {}
11
+
8
12
type Spec struct {
9
13
ShouldIgnoreFlag func (string ) bool
10
14
ExtractPackageName func ([]string ) (string , error )
11
15
}
12
16
17
+ func NewSpec (ignoreFlags flagNameSet , extractor pkgExtractor ) Spec {
18
+ return Spec {
19
+ ShouldIgnoreFlag : func (flagName string ) bool {
20
+ _ , ok := ignoreFlags [flagName ]
21
+ return ok
22
+ },
23
+ ExtractPackageName : extractor ,
24
+ }
25
+ }
26
+
13
27
func Specs () map [Runtime ]Spec {
14
28
return map [Runtime ]Spec {
15
- Docker : {
16
- ShouldIgnoreFlag : func (flag string ) bool {
17
- switch flag {
18
- case "--rm" , "--name" , "--volume" , "-v" , "--network" , "--detach" , "-d" , "-i" :
19
- return true
29
+ Docker : NewSpec (dockerIgnoreFlags (), dockerPackageExtractor ()),
30
+ NPX : NewSpec (flagNameSet {"-y" : {}}, npxPackageExtractor ()),
31
+ UVX : NewSpec (flagNameSet {"--from" : {}}, uvxPackageExtractor ()),
32
+ Python : NewSpec (flagNameSet {"-m" : {}}, pythonPackageExtractor ()),
33
+ }
34
+ }
35
+
36
+ func dockerIgnoreFlags () flagNameSet {
37
+ return flagNameSet {
38
+ "-d" : {},
39
+ "--detach" : {},
40
+ "-i" : {},
41
+ "--name" : {},
42
+ "--network" : {},
43
+ "--rm" : {},
44
+ "-v" : {},
45
+ "--volume" : {},
46
+ }
47
+ }
48
+
49
+ func dockerPackageExtractor () pkgExtractor {
50
+ return func (args []string ) (string , error ) {
51
+ skip := true
52
+ skipNext := false
53
+
54
+ flagsWithValues := flagNameSet {
55
+ "-e" : {},
56
+ "--env" : {},
57
+ "-p" : {},
58
+ "--name" : {},
59
+ "--network" : {},
60
+ "-v" : {},
61
+ "--volume" : {},
62
+ }
63
+
64
+ for i := 0 ; i < len (args ); i ++ {
65
+ arg := args [i ]
66
+
67
+ if skip {
68
+ if arg == "run" {
69
+ skip = false
20
70
}
21
- return false
22
- },
23
- ExtractPackageName : func (args []string ) (string , error ) {
24
- skip := true
25
- skipNext := false
26
-
27
- // Flags that take a value (e.g. --name greptime)
28
- flagsWithValues := map [string ]struct {}{
29
- "-e" : {},
30
- "--env" : {},
31
- "-p" : {},
32
- "-v" : {},
33
- "--volume" : {},
34
- "--name" : {},
35
- "--network" : {},
71
+ continue
72
+ }
73
+
74
+ if skipNext {
75
+ skipNext = false
76
+ continue
77
+ }
78
+
79
+ if strings .HasPrefix (arg , "-" ) {
80
+ if _ , ok := flagsWithValues [arg ]; ok {
81
+ skipNext = true
36
82
}
83
+ continue
84
+ }
37
85
38
- for i := 0 ; i < len ( args ); i ++ {
39
- arg := args [ i ]
86
+ return arg , nil
87
+ }
40
88
41
- if skip {
42
- if arg == "run" {
43
- skip = false
44
- }
45
- continue
46
- }
89
+ return "" , fmt .Errorf ("no %s image found" , Docker )
90
+ }
91
+ }
47
92
48
- if skipNext {
49
- skipNext = false
50
- continue
51
- }
93
+ func npxPackageExtractor () pkgExtractor {
94
+ return func (args []string ) (string , error ) {
95
+ for _ , arg := range args {
96
+ if strings .HasPrefix (arg , "-" ) {
97
+ continue
98
+ }
99
+ normalizedArg := strings .ToLower (arg )
100
+ if strings .HasPrefix (normalizedArg , "git+" ) || strings .HasPrefix (normalizedArg , "https://" ) {
101
+ return "" , fmt .Errorf ("remote sources are unsupported" )
102
+ }
103
+ return arg , nil
104
+ }
105
+ return "" , fmt .Errorf ("no %s package found" , NPX )
106
+ }
107
+ }
52
108
53
- if strings .HasPrefix (arg , "-" ) {
54
- _ , takesValue := flagsWithValues [arg ]
55
- skipNext = takesValue
56
- continue
57
- }
109
+ func uvxPackageExtractor () pkgExtractor {
110
+ return func (args []string ) (string , error ) {
111
+ for i := 0 ; i < len (args ); i ++ {
112
+ arg := strings .TrimSpace (args [i ])
58
113
59
- return arg , nil
114
+ if arg == "--from" && i + 1 < len (args ) {
115
+ next := strings .ToLower (strings .TrimSpace (args [i + 1 ]))
116
+ if strings .HasPrefix (next , "git+" ) {
117
+ return "" , fmt .Errorf ("remote git repositories are unsupported" )
60
118
}
61
-
62
- return "" , fmt .Errorf ("no %s image found" , Docker )
63
- },
64
- },
65
- NPX : {
66
- ShouldIgnoreFlag : func (flag string ) bool {
67
- return flag == "-y"
68
- },
69
- ExtractPackageName : func (args []string ) (string , error ) {
70
- // First non-flag value
71
- for _ , arg := range args {
72
- if ! strings .HasPrefix (arg , "-" ) {
73
- return arg , nil
74
- }
119
+ if strings .HasPrefix (next , "https://" ) {
120
+ return "" , fmt .Errorf ("arbitrary HTTP repositories are unsupported" )
75
121
}
76
- return "" , fmt .Errorf ("no %s package found" , NPX )
77
- },
78
- },
79
- UVX : {
80
- ShouldIgnoreFlag : func (flag string ) bool {
81
- switch flag {
82
- case "--from" :
83
- return true
122
+
123
+ i ++ // Skip the next value
124
+ continue
125
+ }
126
+
127
+ if ! strings .HasPrefix (arg , "-" ) {
128
+ return arg , nil
129
+ }
130
+ }
131
+
132
+ return "" , fmt .Errorf ("no %s package found" , UVX )
133
+ }
134
+ }
135
+
136
+ func pythonPackageExtractor () pkgExtractor {
137
+ return func (args []string ) (string , error ) {
138
+ for i , arg := range args {
139
+ if arg == "-m" {
140
+ if i + 1 >= len (args ) {
141
+ return "" , fmt .Errorf ("missing module name after -m" )
84
142
}
85
- return false
86
- },
87
- ExtractPackageName : func (args []string ) (string , error ) {
88
- for i := 0 ; i < len (args ); i ++ {
89
- arg := strings .TrimSpace (args [i ])
90
- nextIndex := i + 1
91
- if args [i ] == "--from" && nextIndex < len (args ) {
92
- nextArg := strings .TrimSpace (args [nextIndex ])
93
- if strings .HasPrefix (nextArg , "git+" ) {
94
- return "" , fmt .Errorf ("remote git repositories are unsupported" )
95
- }
96
- if strings .HasPrefix (nextArg , "https://" ) {
97
- return "" , fmt .Errorf ("arbitrary HTTP repositories are unsupported" )
98
- }
99
-
100
- i ++ // Skip next value.
101
- continue
102
- }
103
- if ! strings .HasPrefix (arg , "-" ) {
104
- return arg , nil
105
- }
143
+ next := args [i + 1 ]
144
+ if strings .HasPrefix (next , "-" ) {
145
+ return "" , fmt .Errorf ("invalid module name after -m: %s" , next )
106
146
}
107
- return "" , fmt .Errorf ("no %s package found" , UVX )
108
- },
109
- },
110
- Python : {
111
- ShouldIgnoreFlag : func (flag string ) bool {
112
- return flag == "-m"
113
- },
114
- ExtractPackageName : func (args []string ) (string , error ) {
115
- // No clear package name? Could return empty or static
116
- return "" , nil
117
- },
118
- },
147
+ return next , nil
148
+ }
149
+ }
150
+ return "" , fmt .Errorf ("no %s module found" , Python )
119
151
}
120
152
}
0 commit comments