gom.Parse   F
last analyzed

Complexity

Conditions 18

Size

Total Lines 69
Code Lines 37

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 18
eloc 37
nop 1
dl 0
loc 69
rs 1.2
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like gom.Parse often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
package gom
2
3
import (
4
	"errors"
5
	"os"
6
	"path/filepath"
7
8
	"github.com/Masterminds/glide/cfg"
9
	"github.com/Masterminds/glide/msg"
10
	gpath "github.com/Masterminds/glide/path"
11
	"github.com/Masterminds/glide/util"
12
)
13
14
// Has returns true if this dir has a Gomfile.
15
func Has(dir string) bool {
16
	path := filepath.Join(dir, "Gomfile")
17
	fi, err := os.Stat(path)
18
	return err == nil && !fi.IsDir()
19
}
20
21
// Parse parses a Gomfile.
22
func Parse(dir string) ([]*cfg.Dependency, error) {
23
	path := filepath.Join(dir, "Gomfile")
24
	if fi, err := os.Stat(path); err != nil || fi.IsDir() {
25
		return []*cfg.Dependency{}, nil
26
	}
27
28
	msg.Info("Found Gomfile in %s", gpath.StripBasepath(dir))
29
	msg.Info("--> Parsing Gomfile metadata...")
30
	buf := []*cfg.Dependency{}
31
32
	goms, err := parseGomfile(path)
33
	if err != nil {
34
		return []*cfg.Dependency{}, err
35
	}
36
37
	for _, gom := range goms {
38
		// Do we need to skip this dependency?
39
		if val, ok := gom.options["skipdep"]; ok && val.(string) == "true" {
40
			continue
41
		}
42
43
		// Check for custom cloning command
44
		if _, ok := gom.options["command"]; ok {
45
			return []*cfg.Dependency{}, errors.New("Glide does not support custom Gomfile commands")
46
		}
47
48
		// Check for groups/environments
49
		if val, ok := gom.options["group"]; ok {
50
			groups := toStringSlice(val)
51
			if !stringsContain(groups, "development") && !stringsContain(groups, "production") {
52
				// right now we only support development and production
53
				msg.Info("Skipping dependency '%s' because it isn't in the development or production group", gom.name)
54
				continue
55
			}
56
		}
57
58
		pkg, sub := util.NormalizeName(gom.name)
59
60
		dep := &cfg.Dependency{
61
			Name: pkg,
62
		}
63
64
		if len(sub) > 0 {
65
			dep.Subpackages = []string{sub}
66
		}
67
68
		// Check for a specific revision
69
		if val, ok := gom.options["commit"]; ok {
70
			dep.Reference = val.(string)
71
		}
72
		if val, ok := gom.options["tag"]; ok {
73
			dep.Reference = val.(string)
74
		}
75
		if val, ok := gom.options["branch"]; ok {
76
			dep.Reference = val.(string)
77
		}
78
79
		// Parse goos and goarch
80
		if val, ok := gom.options["goos"]; ok {
81
			dep.Os = toStringSlice(val)
82
		}
83
		if val, ok := gom.options["goarch"]; ok {
84
			dep.Arch = toStringSlice(val)
85
		}
86
87
		buf = append(buf, dep)
88
	}
89
90
	return buf, nil
91
}
92
93
func stringsContain(v []string, key string) bool {
94
	for _, s := range v {
95
		if s == key {
96
			return true
97
		}
98
	}
99
	return false
100
}
101
102
func toStringSlice(v interface{}) []string {
103
	if v, ok := v.(string); ok {
104
		return []string{v}
105
	}
106
107
	if v, ok := v.([]string); ok {
108
		return v
109
	}
110
111
	return []string{}
112
}
113