~nskaggs/+junk/xenial-test

« back to all changes in this revision

Viewing changes to src/github.com/juju/juju/cmd/juju/application/flags.go

  • Committer: Nicholas Skaggs
  • Date: 2016-10-24 20:56:05 UTC
  • Revision ID: nicholas.skaggs@canonical.com-20161024205605-z8lta0uvuhtxwzwl
Initi with beta15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2015 Canonical Ltd.
 
2
// Licensed under the AGPLv3, see LICENCE file for details.
 
3
 
 
4
package application
 
5
 
 
6
import (
 
7
        "fmt"
 
8
        "strings"
 
9
 
 
10
        "github.com/juju/errors"
 
11
 
 
12
        "github.com/juju/juju/storage"
 
13
)
 
14
 
 
15
type storageFlag struct {
 
16
        stores       *map[string]storage.Constraints
 
17
        bundleStores *map[string]map[string]storage.Constraints
 
18
}
 
19
 
 
20
// Set implements gnuflag.Value.Set.
 
21
func (f storageFlag) Set(s string) error {
 
22
        fields := strings.SplitN(s, "=", 2)
 
23
        if len(fields) < 2 {
 
24
                return errors.New("expected [<application>:]<store>=<constraints>")
 
25
        }
 
26
        var serviceName, storageName string
 
27
        if colon := strings.IndexRune(fields[0], ':'); colon >= 0 {
 
28
                serviceName = fields[0][:colon]
 
29
                storageName = fields[0][colon+1:]
 
30
        } else {
 
31
                storageName = fields[0]
 
32
        }
 
33
        cons, err := storage.ParseConstraints(fields[1])
 
34
        if err != nil {
 
35
                return errors.Annotate(err, "cannot parse disk constraints")
 
36
        }
 
37
        var stores map[string]storage.Constraints
 
38
        if serviceName != "" {
 
39
                if *f.bundleStores == nil {
 
40
                        *f.bundleStores = make(map[string]map[string]storage.Constraints)
 
41
                }
 
42
                stores = (*f.bundleStores)[serviceName]
 
43
                if stores == nil {
 
44
                        stores = make(map[string]storage.Constraints)
 
45
                        (*f.bundleStores)[serviceName] = stores
 
46
                }
 
47
        } else {
 
48
                if *f.stores == nil {
 
49
                        *f.stores = make(map[string]storage.Constraints)
 
50
                }
 
51
                stores = *f.stores
 
52
        }
 
53
        stores[storageName] = cons
 
54
        return nil
 
55
}
 
56
 
 
57
// String implements gnuflag.Value.String.
 
58
func (f storageFlag) String() string {
 
59
        strs := make([]string, 0, len(*f.stores)+len(*f.bundleStores))
 
60
        for store, cons := range *f.stores {
 
61
                strs = append(strs, fmt.Sprintf("%s=%v", store, cons))
 
62
        }
 
63
        for application, stores := range *f.bundleStores {
 
64
                for store, cons := range stores {
 
65
                        strs = append(strs, fmt.Sprintf("%s:%s=%v", application, store, cons))
 
66
                }
 
67
        }
 
68
        return strings.Join(strs, " ")
 
69
}
 
70
 
 
71
// stringMap is a type that deserializes a CLI string using gnuflag's Value
 
72
// semantics.  It expects a name=value pair, and supports multiple copies of the
 
73
// flag adding more pairs, though the names must be unique.
 
74
type stringMap struct {
 
75
        mapping *map[string]string
 
76
}
 
77
 
 
78
// Set implements gnuflag.Value's Set method.
 
79
func (m stringMap) Set(s string) error {
 
80
        if *m.mapping == nil {
 
81
                *m.mapping = map[string]string{}
 
82
        }
 
83
        // make a copy so the following code is less ugly with dereferencing.
 
84
        mapping := *m.mapping
 
85
 
 
86
        vals := strings.SplitN(s, "=", 2)
 
87
        if len(vals) != 2 {
 
88
                return errors.NewNotValid(nil, "badly formatted name value pair: "+s)
 
89
        }
 
90
        name, value := vals[0], vals[1]
 
91
        if _, ok := mapping[name]; ok {
 
92
                return errors.Errorf("duplicate name specified: %q", name)
 
93
        }
 
94
        mapping[name] = value
 
95
        return nil
 
96
}
 
97
 
 
98
// String implements gnuflag.Value's String method
 
99
func (m stringMap) String() string {
 
100
        pairs := make([]string, 0, len(*m.mapping))
 
101
        for name, value := range *m.mapping {
 
102
                pairs = append(pairs, name+"="+value)
 
103
        }
 
104
        return strings.Join(pairs, ";")
 
105
}