4
4
package impl
5
5
6
6
import (
7
- "encoding/json"
8
- "fmt"
9
7
"os"
10
8
"path/filepath"
11
9
"strings"
12
- "unicode"
13
10
14
11
"github.com/pkg/errors"
15
12
"go.jetpack.io/devbox/internal/boxcli/usererr"
16
13
"go.jetpack.io/devbox/internal/cuecfg"
17
14
"go.jetpack.io/devbox/internal/debug"
15
+ "go.jetpack.io/devbox/internal/impl/shellcmd"
18
16
"go.jetpack.io/devbox/internal/planner/plansdk"
19
17
)
20
18
@@ -36,8 +34,8 @@ type Config struct {
36
34
// Shell configures the devbox shell environment.
37
35
Shell struct {
38
36
// InitHook contains commands that will run at shell startup.
39
- InitHook ConfigShellCmds `json:"init_hook,omitempty"`
40
- Scripts map [string ]* ConfigShellCmds `json:"scripts,omitempty"`
37
+ InitHook shellcmd. Commands `json:"init_hook,omitempty"`
38
+ Scripts map [string ]* shellcmd. Commands `json:"scripts,omitempty"`
41
39
} `json:"shell,omitempty"`
42
40
43
41
// Nixpkgs specifies the repository to pull packages from
@@ -94,114 +92,6 @@ func WriteConfig(path string, cfg *Config) error {
94
92
return cuecfg .WriteFile (path , cfg )
95
93
}
96
94
97
- // Formats for marshalling and unmarshalling a series of shell commands in a
98
- // devbox config.
99
- const (
100
- // CmdArray formats shell commands as an array of of strings.
101
- CmdArray CmdFormat = iota
102
-
103
- // CmdString formats shell commands as a single string.
104
- CmdString
105
- )
106
-
107
- // CmdFormat defines a way of formatting shell commands in a devbox config.
108
- type CmdFormat int
109
-
110
- func (c CmdFormat ) String () string {
111
- switch c {
112
- case CmdArray :
113
- return "array"
114
- case CmdString :
115
- return "string"
116
- default :
117
- return fmt .Sprintf ("invalid (%d)" , c )
118
- }
119
- }
120
-
121
- // ConfigShellCmds marshals and unmarshals shell commands from a devbox config
122
- // as either a single string or an array of strings. It preserves the original
123
- // value such that:
124
- //
125
- // data == marshal(unmarshal(data)))
126
- type ConfigShellCmds struct {
127
- // MarshalAs determines how MarshalJSON encodes the shell commands.
128
- // UnmarshalJSON will set MarshalAs automatically so that commands
129
- // marshal back to their original format. The default zero-value
130
- // formats them as an array.
131
- //
132
- MarshalAs CmdFormat
133
- Cmds []string
134
- }
135
-
136
- // AppendScript appends each line of a script to s.Cmds. It also applies the
137
- // following formatting rules:
138
- //
139
- // - Trim leading newlines from the script.
140
- // - Trim trailing whitespace from the script.
141
- // - If the first line of the script begins with one or more tabs ('\t'), then
142
- // unindent each line by that same number of tabs.
143
- // - Remove trailing whitespace from each line.
144
- //
145
- // Note that unindenting only happens when a line starts with at least as many
146
- // tabs as the first line. If it starts with fewer tabs, then it is not
147
- // unindented at all.
148
- func (s * ConfigShellCmds ) AppendScript (script string ) {
149
- script = strings .TrimLeft (script , "\r \n " )
150
- script = strings .TrimRightFunc (script , unicode .IsSpace )
151
- if len (script ) == 0 {
152
- return
153
- }
154
- prefixLen := strings .IndexFunc (script , func (r rune ) bool { return r != '\t' })
155
- prefix := strings .Repeat ("\t " , prefixLen )
156
- for _ , line := range strings .Split (script , "\n " ) {
157
- line = strings .TrimRightFunc (line , unicode .IsSpace )
158
- line = strings .TrimPrefix (line , prefix )
159
- s .Cmds = append (s .Cmds , line )
160
- }
161
- }
162
-
163
- // MarshalJSON marshals shell commands according to s.MarshalAs. It marshals
164
- // commands to a string by joining s.Cmds with newlines.
165
- func (s ConfigShellCmds ) MarshalJSON () ([]byte , error ) {
166
- switch s .MarshalAs {
167
- case CmdArray :
168
- return json .Marshal (s .Cmds )
169
- case CmdString :
170
- return json .Marshal (s .String ())
171
- default :
172
- panic (fmt .Sprintf ("invalid command format: %s" , s .MarshalAs ))
173
- }
174
- }
175
-
176
- // UnmarshalJSON unmarshals shell commands from a string, an array of strings,
177
- // or null. When the JSON value is a string, it unmarshals into the first index
178
- // of s.Cmds.
179
- func (s * ConfigShellCmds ) UnmarshalJSON (data []byte ) error {
180
- if len (data ) == 0 || string (data ) == "null" {
181
- s .MarshalAs = CmdArray
182
- s .Cmds = nil
183
- return nil
184
- }
185
-
186
- switch data [0 ] {
187
- case '"' :
188
- s .MarshalAs = CmdString
189
- s .Cmds = []string {"" }
190
- return json .Unmarshal (data , & s .Cmds [0 ])
191
-
192
- case '[' :
193
- s .MarshalAs = CmdArray
194
- return json .Unmarshal (data , & s .Cmds )
195
- default :
196
- return nil
197
- }
198
- }
199
-
200
- // String formats the commands as a single string by joining them with newlines.
201
- func (s * ConfigShellCmds ) String () string {
202
- return strings .Join (s .Cmds , "\n " )
203
- }
204
-
205
95
// findConfigDir is a utility for using the path
206
96
func findConfigDir (path string ) (string , error ) {
207
97
debug .Log ("findConfigDir: path is %s\n " , path )
0 commit comments