strip.rewriteGodepfilesHandler   F
last analyzed

Complexity

Conditions 16

Size

Total Lines 63
Code Lines 42

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 16
eloc 42
nop 3
dl 0
loc 63
rs 2.4
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 strip.rewriteGodepfilesHandler 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 strip removes Godeps/_workspace and undoes the Godep rewrites. This
2
// essentially removes the old style (pre-vendor) Godep vendoring.
3
//
4
// Note, this functionality is deprecated. Once more projects use the Godep
5
// support for the core vendoring this will no longer be needed.
6
package strip
7
8
import (
9
	"bytes"
10
	"go/ast"
11
	"go/parser"
12
	"go/printer"
13
	"go/token"
14
	"os"
15
	"path/filepath"
16
	"strconv"
17
	"strings"
18
19
	"github.com/Masterminds/glide/msg"
20
)
21
22
var godepMark = map[string]bool{}
23
24
var vPath = "vendor"
25
26
// GodepWorkspace removes any Godeps/_workspace directories and makes sure
27
// any rewrites are undone.
28
// Note, this is not concuccency safe.
29
func GodepWorkspace(v string) error {
30
	vPath = v
31
	if _, err := os.Stat(vPath); err != nil {
32
		if os.IsNotExist(err) {
33
			msg.Debug("Vendor directory does not exist.")
34
		}
35
36
		return err
37
	}
38
39
	err := filepath.Walk(vPath, stripGodepWorkspaceHandler)
40
	if err != nil {
41
		return err
42
	}
43
44
	// Walk the marked projects to make sure rewrites are undone.
45
	for k := range godepMark {
46
		msg.Info("Removing Godep rewrites for %s", k)
47
		err := filepath.Walk(k, rewriteGodepfilesHandler)
48
		if err != nil {
49
			return err
50
		}
51
	}
52
53
	return nil
54
}
55
56
func stripGodepWorkspaceHandler(path string, info os.FileInfo, err error) error {
57
	// Skip the base vendor directory
58
	if path == vPath {
59
		return nil
60
	}
61
62
	name := info.Name()
63
	p := filepath.Dir(path)
64
	pn := filepath.Base(p)
65
	if name == "_workspace" && pn == "Godeps" {
66
		if _, err := os.Stat(path); err == nil {
67
			if info.IsDir() {
68
				// Marking this location to make sure rewrites are undone.
69
				pp := filepath.Dir(p)
70
				godepMark[pp] = true
71
72
				msg.Info("Removing: %s", path)
73
				return os.RemoveAll(path)
74
			}
75
76
			msg.Debug("%s is not a directory. Skipping removal", path)
77
			return nil
78
		}
79
	}
80
	return nil
81
}
82
83
func rewriteGodepfilesHandler(path string, info os.FileInfo, err error) error {
84
	name := info.Name()
85
86
	if info.IsDir() {
87
		if name == "testdata" || name == "vendor" {
88
			return filepath.SkipDir
89
		}
90
		return nil
91
	}
92
93
	if e := filepath.Ext(path); e != ".go" {
94
		return nil
95
	}
96
97
	fset := token.NewFileSet()
98
	f, err := parser.ParseFile(fset, path, nil, parser.ParseComments)
99
	if err != nil {
100
		return err
101
	}
102
103
	var changed bool
104
	for _, s := range f.Imports {
105
		n, err := strconv.Unquote(s.Path.Value)
106
		if err != nil {
107
			return err
108
		}
109
		q := rewriteGodepImport(n)
110
		if q != name {
111
			s.Path.Value = strconv.Quote(q)
112
			changed = true
113
		}
114
	}
115
	if !changed {
116
		return nil
117
	}
118
119
	printerConfig := &printer.Config{Mode: printer.TabIndent | printer.UseSpaces, Tabwidth: 8}
120
	var buffer bytes.Buffer
121
	if err = printerConfig.Fprint(&buffer, fset, f); err != nil {
122
		return err
123
	}
124
	fset = token.NewFileSet()
125
	f, err = parser.ParseFile(fset, name, &buffer, parser.ParseComments)
126
	ast.SortImports(fset, f)
127
	tpath := path + ".temp"
128
	t, err := os.Create(tpath)
129
	if err != nil {
130
		return err
131
	}
132
	if err = printerConfig.Fprint(t, fset, f); err != nil {
133
		return err
134
	}
135
	if err = t.Close(); err != nil {
136
		return err
137
	}
138
139
	msg.Debug("Rewriting Godep imports for %s", path)
140
141
	// This is required before the rename on windows.
142
	if err = os.Remove(path); err != nil {
143
		return err
144
	}
145
	return os.Rename(tpath, path)
146
}
147
148
func rewriteGodepImport(n string) string {
149
	if !strings.Contains(n, "Godeps/_workspace/src") {
150
		return n
151
	}
152
153
	i := strings.LastIndex(n, "Godeps/_workspace/src")
154
155
	return strings.TrimPrefix(n[i:], "Godeps/_workspace/src/")
156
}
157