Skip to content

Commit b20e240

Browse files
committed
add box add command
1 parent 89d140e commit b20e240

4 files changed

+223
-0
lines changed

README.md

+12
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,18 @@ func main() {
8282

8383
## Available Actions
8484

85+
### BoxAdd
86+
Adds a box to your local vagrant box collection. Takes a location which is the
87+
name, url, or path of the box
88+
89+
```go
90+
func (*VagrantClient) BoxAdd(location string) *BoxAddCommand
91+
```
92+
93+
Response:
94+
* **Error** - Set if an error occurred.
95+
96+
8597
### BoxList
8698
Return a list of available vagrant boxes.
8799

command_box_add.go

+98
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
package vagrant
2+
3+
import "errors"
4+
5+
type CheckSumType string
6+
7+
const (
8+
MD5 CheckSumType = "md5"
9+
SHA1 CheckSumType = "sha1"
10+
SHA256 CheckSumType = "sha256"
11+
)
12+
13+
// A BoxAddCommand specifies the options and output of vagrant box add.
14+
type BoxAddCommand struct {
15+
BaseCommand
16+
ErrorResponse
17+
18+
// Clean any temporary download files. This will prevent resuming a previously started download.
19+
Clean bool
20+
21+
// Overwrite an existing box if it exists
22+
Force bool
23+
24+
// Name, url, or path of the box.
25+
Location string
26+
27+
// Name of the box. Only has to be set if the box is provided as a path or url without metadata.
28+
Name string
29+
30+
// Checksum for the box
31+
Checksum string
32+
33+
// Type of the supplied Checksum. Allowed values are vagrant.MD5, vagrant.SHA1, vagrant.SHA256
34+
CheckSumType CheckSumType
35+
}
36+
37+
// BoxAdd adds a vagrant box to your local boxes.
38+
// Its parameter location is the name, url, or path of the box. After setting
39+
// options as appropriate, you must call Run() or Start() followed by Wait()
40+
// to execute. Errors will be recorded in Error.
41+
func (client *VagrantClient) BoxAdd(location string) *BoxAddCommand {
42+
return &BoxAddCommand{
43+
Location: location,
44+
BaseCommand: newBaseCommand(client),
45+
ErrorResponse: newErrorResponse(),
46+
}
47+
}
48+
49+
func (cmd *BoxAddCommand) buildArguments() ([]string, error) {
50+
args := []string{"add"}
51+
if cmd.Clean {
52+
args = append(args, "-c")
53+
}
54+
if cmd.Force {
55+
args = append(args, "-f")
56+
}
57+
if cmd.Name != "" {
58+
args = append(args, "--name", cmd.Name)
59+
}
60+
if cmd.Checksum != "" {
61+
args = append(args, "--checksum", cmd.Checksum)
62+
}
63+
if cmd.CheckSumType != "" {
64+
if cmd.Checksum == "" {
65+
return nil, errors.New("box add: no checksum set even though checksum type was set")
66+
}
67+
args = append(args, "--checksum-type", string(cmd.CheckSumType))
68+
}
69+
if cmd.Location == "" {
70+
return nil, errors.New("box add: location must be provided")
71+
}
72+
args = append(args, cmd.Location)
73+
return args, nil
74+
}
75+
76+
func (cmd *BoxAddCommand) init() error {
77+
args, err := cmd.buildArguments()
78+
if err != nil {
79+
return err
80+
}
81+
return cmd.BaseCommand.init(&cmd.ErrorResponse, "box", args...)
82+
}
83+
84+
// Run the command
85+
func (cmd *BoxAddCommand) Run() error {
86+
if err := cmd.Start(); err != nil {
87+
return err
88+
}
89+
return cmd.Wait()
90+
}
91+
92+
// Start the command. You must call Wait() to complete execution.
93+
func (cmd *BoxAddCommand) Start() error {
94+
if err := cmd.init(); err != nil {
95+
return err
96+
}
97+
return cmd.BaseCommand.Start()
98+
}

command_box_add_test.go

+101
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package vagrant
2+
3+
import "testing"
4+
5+
func init() {
6+
successfulOutput["box add"] = `
7+
1631018118,box,ui,output,==> box: Loading metadata for box 'ubuntu/trusty64'
8+
1631018118,box,ui,detail, box: URL: https://vagrantcloud.com/ubuntu/trusty64
9+
1631018119,box,ui,output,==> box: Adding box 'ubuntu/trusty64' (v20190514.0.0) for provider: virtualbox
10+
1631018119,box,ui,detail, box: Downloading: https://vagrantcloud.com/ubuntu/boxes/trusty64/versions/20190514.0.0/providers/virtualbox.box
11+
1631018119,,ui,detail,Progress: 0% (Rate: 0*/s%!(VAGRANT_COMMA) Estimated time remaining: --:--:--)
12+
1631018120,,ui,detail,Progress: 100% (Rate: 215/s%!(VAGRANT_COMMA) Estimated time remaining: --:--:--)
13+
1631018121,,ui,detail,Download redirected to host: cloud-images.ubuntu.com
14+
1631018121,,ui,detail,Progress: 100% (Rate: 121/s%!(VAGRANT_COMMA) Estimated time remaining: --:--:--)
15+
1631018121,,ui,detail,Progress: 0% (Rate: 0*/s%!(VAGRANT_COMMA) Estimated time remaining: --:--:--)
16+
1631018123,,ui,detail,Progress: 1% (Rate: 6429k/s%!(VAGRANT_COMMA) Estimated time remaining: 0:03:05)
17+
1631018124,,ui,detail,Progress: 8% (Rate: 17.4M/s%!(VAGRANT_COMMA) Estimated time remaining: 0:00:42)
18+
1631018125,,ui,detail,Progress: 15% (Rate: 21.2M/s%!(VAGRANT_COMMA) Estimated time remaining: 0:00:27)
19+
1631018126,,ui,detail,Progress: 21% (Rate: 23.5M/s%!(VAGRANT_COMMA) Estimated time remaining: 0:00:21)
20+
1631018127,,ui,detail,Progress: 28% (Rate: 24.7M/s%!(VAGRANT_COMMA) Estimated time remaining: 0:00:17)
21+
1631018128,,ui,detail,Progress: 35% (Rate: 29.2M/s%!(VAGRANT_COMMA) Estimated time remaining: 0:00:14)
22+
1631018129,,ui,detail,Progress: 42% (Rate: 29.2M/s%!(VAGRANT_COMMA) Estimated time remaining: 0:00:12)
23+
1631018130,,ui,detail,Progress: 49% (Rate: 29.6M/s%!(VAGRANT_COMMA) Estimated time remaining: 0:00:10)
24+
1631018131,,ui,detail,Progress: 56% (Rate: 29.3M/s%!(VAGRANT_COMMA) Estimated time remaining: 0:00:09)
25+
1631018132,,ui,detail,Progress: 63% (Rate: 29.5M/s%!(VAGRANT_COMMA) Estimated time remaining: 0:00:07)
26+
1631018133,,ui,detail,Progress: 67% (Rate: 27.6M/s%!(VAGRANT_COMMA) Estimated time remaining: 0:00:06)
27+
1631018134,,ui,detail,Progress: 74% (Rate: 27.4M/s%!(VAGRANT_COMMA) Estimated time remaining: 0:00:05)
28+
1631018135,,ui,detail,Progress: 81% (Rate: 27.4M/s%!(VAGRANT_COMMA) Estimated time remaining: 0:00:04)
29+
1631018136,,ui,detail,Progress: 88% (Rate: 27.2M/s%!(VAGRANT_COMMA) Estimated time remaining: 0:00:02)
30+
1631018137,,ui,detail,Progress: 94% (Rate: 27.1M/s%!(VAGRANT_COMMA) Estimated time remaining: 0:00:01)
31+
1631018138,box,ui,success,==> box: Successfully added box 'ubuntu/trusty64' (v20190514.0.0) for 'virtualbox'!
32+
`
33+
}
34+
func TestBoxAddCommand_buildArguments(t *testing.T) {
35+
client := newMockVagrantClient()
36+
37+
t.Run("error-on-missing-location", func(t *testing.T) {
38+
cmd := client.BoxAdd("")
39+
_, err := cmd.buildArguments()
40+
assertErr(t, err)
41+
})
42+
t.Run("default", func(t *testing.T) {
43+
cmd := client.BoxAdd("ubuntu/trusty64")
44+
args, err := cmd.buildArguments()
45+
assertNoErr(t, err)
46+
assertArguments(t, args, "add", "ubuntu/trusty64")
47+
})
48+
t.Run("checksum-type", func(t *testing.T) {
49+
cmd := client.BoxAdd("ubuntu/trusty64")
50+
cmd.Checksum = "test"
51+
cmd.CheckSumType = SHA1
52+
args, err := cmd.buildArguments()
53+
assertNoErr(t, err)
54+
assertArguments(t, args, "add", "--checksum", "test", "--checksum-type", "sha1", "ubuntu/trusty64")
55+
})
56+
t.Run("checksum", func(t *testing.T) {
57+
cmd := client.BoxAdd("ubuntu/trusty64")
58+
cmd.Checksum = "test"
59+
args, err := cmd.buildArguments()
60+
assertNoErr(t, err)
61+
assertArguments(t, args, "add", "--checksum", "test", "ubuntu/trusty64")
62+
})
63+
t.Run("error-on-checksum-type-without-checksum", func(t *testing.T) {
64+
cmd := client.BoxAdd("ubuntu/trusty64")
65+
cmd.CheckSumType = SHA1
66+
_, err := cmd.buildArguments()
67+
assertErr(t, err)
68+
})
69+
t.Run("name", func(t *testing.T) {
70+
cmd := client.BoxAdd("ubuntu/trusty64")
71+
cmd.Name = "myubuntu"
72+
args, err := cmd.buildArguments()
73+
assertNoErr(t, err)
74+
assertArguments(t, args, "add", "--name", "myubuntu", "ubuntu/trusty64")
75+
})
76+
t.Run("force", func(t *testing.T) {
77+
cmd := client.BoxAdd("ubuntu/trusty64")
78+
cmd.Force = true
79+
args, err := cmd.buildArguments()
80+
assertNoErr(t, err)
81+
assertArguments(t, args, "add", "-f", "ubuntu/trusty64")
82+
})
83+
t.Run("clean", func(t *testing.T) {
84+
cmd := client.BoxAdd("ubuntu/trusty64")
85+
cmd.Clean = true
86+
args, err := cmd.buildArguments()
87+
assertNoErr(t, err)
88+
assertArguments(t, args, "add", "-c", "ubuntu/trusty64")
89+
})
90+
}
91+
func TestBoxAddCommand_Run(t *testing.T) {
92+
client := newMockVagrantClient()
93+
cmd := client.BoxAdd("ubuntu/trusty64")
94+
cmd.Env = newEnvTestOutputKey("box add")
95+
if err := cmd.Run(); err != nil {
96+
t.Fatalf("Command failed to run: %v", err)
97+
}
98+
if cmd.Error != nil {
99+
t.Fatalf("Command returned error: %v", cmd.Error)
100+
}
101+
}

vagrant_client_test.go

+12
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,18 @@ func newMockVagrantClient() *VagrantClient {
1818
}
1919
}
2020

21+
func assertErr(t *testing.T, err error) {
22+
if err == nil {
23+
t.Fail()
24+
}
25+
}
26+
27+
func assertNoErr(t *testing.T, err error) {
28+
if err != nil {
29+
t.Fail()
30+
}
31+
}
32+
2133
func assertArguments(t *testing.T, args []string, expected ...string) {
2234
if len(args) != len(expected) {
2335
t.Fatalf("Expected %v args; got %v", len(expected), len(args))

0 commit comments

Comments
 (0)