@@ -19,7 +19,10 @@ import (
19
19
"fmt"
20
20
"log"
21
21
"os"
22
+ "os/user"
23
+ "path/filepath"
22
24
"regexp"
25
+ "runtime"
23
26
"sort"
24
27
"strings"
25
28
@@ -171,6 +174,82 @@ func saveOutput(filename, format string, issues []*gas.Issue, metrics *gas.Metri
171
174
return nil
172
175
}
173
176
177
+ func getenv (key , userDefault string ) string {
178
+ if val := os .Getenv (key ); val != "" {
179
+ return val
180
+ }
181
+ return userDefault
182
+ }
183
+
184
+ func gopath () []string {
185
+ defaultGoPath := runtime .GOROOT ()
186
+ if u , err := user .Current (); err == nil {
187
+ defaultGoPath = filepath .Join (u .HomeDir , "go" )
188
+ }
189
+ path := getenv ("GOPATH" , defaultGoPath )
190
+ paths := strings .Split (path , string (os .PathListSeparator ))
191
+ for idx , path := range paths {
192
+ if abs , err := filepath .Abs (path ); err == nil {
193
+ paths [idx ] = abs
194
+ }
195
+ }
196
+ return paths
197
+ }
198
+
199
+ func cleanPath (path string , gopaths []string ) (string , error ) {
200
+
201
+ cleanFailed := fmt .Errorf ("%s is not within the $GOPATH and cannot be processed" , path )
202
+ nonRecursivePath := strings .TrimSuffix (path , "/..." )
203
+ // do not attempt to clean directs that are resolvable on gopath
204
+ if _ , err := os .Stat (nonRecursivePath ); err != nil && os .IsNotExist (err ) {
205
+ log .Printf ("directory %s doesn't exist, checking if is a package on $GOPATH" , path )
206
+ for _ , basedir := range gopaths {
207
+ dir := filepath .Join (basedir , "src" , nonRecursivePath )
208
+ if st , err := os .Stat (dir ); err == nil && st .IsDir () {
209
+ log .Printf ("located %s in %s" , path , dir )
210
+ return path , nil
211
+ }
212
+ }
213
+ return "" , cleanFailed
214
+ }
215
+
216
+ // ensure we resolve package directory correctly based on $GOPATH
217
+ abspath , err := filepath .Abs (path )
218
+ if err != nil {
219
+ abspath = path
220
+ }
221
+ for _ , base := range gopaths {
222
+ projectRoot := filepath .FromSlash (fmt .Sprintf ("%s/src/" , base ))
223
+ if strings .HasPrefix (abspath , projectRoot ) {
224
+ return strings .TrimPrefix (abspath , projectRoot ), nil
225
+ }
226
+ }
227
+ return "" , cleanFailed
228
+ }
229
+
230
+ func cleanPaths (paths []string ) []string {
231
+ gopaths := gopath ()
232
+ var clean []string
233
+ for _ , path := range paths {
234
+ cleaned , err := cleanPath (path , gopaths )
235
+ if err != nil {
236
+ log .Fatal (err )
237
+ }
238
+ clean = append (clean , cleaned )
239
+ }
240
+ return clean
241
+ }
242
+
243
+ func resolvePackage (pkg string , searchPaths []string ) string {
244
+ for _ , basedir := range searchPaths {
245
+ dir := filepath .Join (basedir , "src" , pkg )
246
+ if st , err := os .Stat (dir ); err == nil && st .IsDir () {
247
+ return dir
248
+ }
249
+ }
250
+ return pkg
251
+ }
252
+
174
253
func main () {
175
254
176
255
// Setup usage description
@@ -218,13 +297,14 @@ func main() {
218
297
219
298
var packages []string
220
299
// Iterate over packages on the import paths
221
- for _ , pkg := range gotool .ImportPaths (flag .Args ()) {
300
+ gopaths := gopath ()
301
+ for _ , pkg := range gotool .ImportPaths (cleanPaths (flag .Args ())) {
222
302
223
303
// Skip vendor directory
224
304
if vendor .MatchString (pkg ) {
225
305
continue
226
306
}
227
- packages = append (packages , pkg )
307
+ packages = append (packages , resolvePackage ( pkg , gopaths ) )
228
308
}
229
309
230
310
if err := analyzer .Process (packages ... ); err != nil {
0 commit comments