forked from juju/juju
/
addbranch.go
128 lines (107 loc) · 3.38 KB
/
addbranch.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// Copyright 2018 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.
package model
import (
"fmt"
"github.com/juju/cmd/v3"
"github.com/juju/errors"
"github.com/juju/gnuflag"
"github.com/DavinZhang/juju/api/modelgeneration"
jujucmd "github.com/DavinZhang/juju/cmd"
"github.com/DavinZhang/juju/cmd/modelcmd"
"github.com/DavinZhang/juju/core/model"
)
const (
addBranchSummary = "Adds a new branch to the model."
addBranchDoc = `
A branch is a mechanism by which changes can be applied to units gradually at
the operator's discretion. When changes are made to charm configuration under
a branch, only units set to track the branch will realise such changes.
Once the changes are assessed and deemed acceptable, the branch can be
committed, applying the changes to the model and affecting all units.
The branch name "master" is reserved for primary model-based settings and is
not valid for new branches.
Examples:
juju add-branch upgrade-postgresql
See also:
track
branch
commit
abort
diff
`
)
// NewAddBranchCommand wraps addBranchCommand with sane model settings.
func NewAddBranchCommand() cmd.Command {
return modelcmd.Wrap(&addBranchCommand{})
}
// addBranchCommand supplies the "add-branch" CLI command used to add a new branch to
// the current model.
type addBranchCommand struct {
modelcmd.ModelCommandBase
api AddBranchCommandAPI
branchName string
}
// AddBranchCommandAPI describes API methods required
// to execute the branch command.
//go:generate go run github.com/golang/mock/mockgen -package mocks -destination ./mocks/addbranch_mock.go github.com/DavinZhang/juju/cmd/juju/model AddBranchCommandAPI
type AddBranchCommandAPI interface {
Close() error
// AddBranch adds a new branch to the model.
AddBranch(branchName string) error
}
// Info implements part of the cmd.Command interface.
func (c *addBranchCommand) Info() *cmd.Info {
info := &cmd.Info{
Name: "add-branch",
Args: "<branch name>",
Purpose: addBranchSummary,
Doc: addBranchDoc,
}
return jujucmd.Info(info)
}
// SetFlags implements part of the cmd.Command interface.
func (c *addBranchCommand) SetFlags(f *gnuflag.FlagSet) {
c.ModelCommandBase.SetFlags(f)
}
// Init implements part of the cmd.Command interface.
func (c *addBranchCommand) Init(args []string) error {
if len(args) != 1 {
return errors.Errorf("expected a branch name")
}
if err := model.ValidateBranchName(args[0]); err != nil {
return err
}
c.branchName = args[0]
return nil
}
// getAPI returns the API that supplies methods
// required to execute this command.
func (c *addBranchCommand) getAPI() (AddBranchCommandAPI, error) {
if c.api != nil {
return c.api, nil
}
api, err := c.NewAPIRoot()
if err != nil {
return nil, errors.Annotate(err, "opening API connection")
}
client := modelgeneration.NewClient(api)
return client, nil
}
// Run implements the meaty part of the cmd.Command interface.
func (c *addBranchCommand) Run(ctx *cmd.Context) error {
client, err := c.getAPI()
if err != nil {
return err
}
defer func() { _ = client.Close() }()
if err = client.AddBranch(c.branchName); err != nil {
return err
}
// Update the model store with the new active branch for this model.
if err = c.SetActiveBranch(c.branchName); err != nil {
return err
}
_, err = ctx.Stdout.Write([]byte(fmt.Sprintf("Created branch %q and set active\n", c.branchName)))
return err
}