@@ -3,6 +3,7 @@ package main
3
3
import (
4
4
"encoding/json"
5
5
"fmt"
6
+ "log"
6
7
"net/url"
7
8
"os"
8
9
"path/filepath"
@@ -16,15 +17,19 @@ import (
16
17
)
17
18
18
19
type statsFlags struct {
19
- from string
20
+ from string
21
+ customProjectRoot string
20
22
}
21
23
22
24
func statsCommand () cli.Command {
23
25
var statsFlags statsFlags
24
26
stats := cli.Command {
25
27
Name : "stats" ,
26
28
Usage : "Output useful statistics about a SCIP index" ,
27
- Flags : []cli.Flag {fromFlag (& statsFlags .from )},
29
+ Flags : []cli.Flag {
30
+ fromFlag (& statsFlags .from ),
31
+ projectRootFlag (& statsFlags .customProjectRoot ),
32
+ },
28
33
Action : func (c * cli.Context ) error {
29
34
return statsMain (statsFlags )
30
35
},
@@ -36,15 +41,15 @@ func statsMain(flags statsFlags) error {
36
41
from := flags .from
37
42
index , err := readFromOption (from )
38
43
if err != nil {
39
- return err
44
+ return errors . Wrap ( err , "error reading SCIP file" )
40
45
}
41
46
if index .Metadata == nil {
42
47
return errors .Errorf ("Index.Metadata is nil (--from=%s)" , from )
43
48
}
44
49
output := map [string ]interface {}{}
45
- indexStats , err := countStatistics (index )
50
+ indexStats , err := countStatistics (index , flags . customProjectRoot )
46
51
if err != nil {
47
- return err
52
+ return errors . Wrap ( err , "error counting stats" )
48
53
}
49
54
jsonBytes , err := json .MarshalIndent (indexStats , "" , " " )
50
55
if err != nil {
@@ -61,8 +66,8 @@ type indexStatistics struct {
61
66
Definitions int32 `json:"definitions"`
62
67
}
63
68
64
- func countStatistics (index * scip.Index ) (* indexStatistics , error ) {
65
- loc , err := countLinesOfCode (index )
69
+ func countStatistics (index * scip.Index , customProjectRoot string ) (* indexStatistics , error ) {
70
+ loc , err := countLinesOfCode (index , customProjectRoot )
66
71
if err != nil {
67
72
return nil , err
68
73
}
@@ -83,22 +88,37 @@ func countStatistics(index *scip.Index) (*indexStatistics, error) {
83
88
return stats , nil
84
89
}
85
90
86
- func countLinesOfCode (index * scip.Index ) (* gocloc.Result , error ) {
91
+ func countLinesOfCode (index * scip.Index , customProjectRoot string ) (* gocloc.Result , error ) {
92
+ var localSource string
87
93
root , err := url .Parse (index .Metadata .ProjectRoot )
88
94
if err != nil {
89
95
return nil , errors .Wrapf (err , "failed to parse Index.Metadata.ProjectRoot as a URI %s" , index .Metadata .ProjectRoot )
90
96
}
91
- stat , err := os .Stat (root .Path )
97
+ if customProjectRoot != "" {
98
+ localSource = customProjectRoot
99
+ } else {
100
+ _ , err := os .Stat (root .Path )
101
+ if errors .Is (err , os .ErrNotExist ) {
102
+ cwd , _ := os .Getwd ()
103
+ log .Printf ("Project root [%s] doesn't exist, using current working directory [%s] instead. " +
104
+ "To override this behaviour, specify --project-root=<folder> option" , root .Path , cwd )
105
+ localSource = cwd
106
+ } else if err != nil {
107
+ return nil , err
108
+ }
109
+ }
110
+
111
+ stat , err := os .Stat (localSource )
92
112
if err != nil {
93
113
return nil , err
94
114
}
95
115
if ! stat .IsDir () {
96
- return nil , errors .Errorf ("index.Metadata.ProjectRoot is not a directory: %s " , root . Path )
116
+ return nil , errors .Errorf ("Project root [%s] is not a directory" , localSource )
97
117
}
98
118
processor := gocloc .NewProcessor (gocloc .NewDefinedLanguages (), gocloc .NewClocOptions ())
99
119
var paths []string
100
120
for _ , document := range index .Documents {
101
- paths = append (paths , filepath .Join (root . Path , document .RelativePath ))
121
+ paths = append (paths , filepath .Join (localSource , document .RelativePath ))
102
122
}
103
123
return processor .Analyze (paths )
104
124
}
0 commit comments