@@ -3,6 +3,7 @@ package main
33import (
44 "encoding/json"
55 "fmt"
6+ "log"
67 "net/url"
78 "os"
89 "path/filepath"
@@ -16,15 +17,19 @@ import (
1617)
1718
1819type statsFlags struct {
19- from string
20+ from string
21+ customProjectRoot string
2022}
2123
2224func statsCommand () cli.Command {
2325 var statsFlags statsFlags
2426 stats := cli.Command {
2527 Name : "stats" ,
2628 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+ },
2833 Action : func (c * cli.Context ) error {
2934 return statsMain (statsFlags )
3035 },
@@ -36,15 +41,15 @@ func statsMain(flags statsFlags) error {
3641 from := flags .from
3742 index , err := readFromOption (from )
3843 if err != nil {
39- return err
44+ return errors . Wrap ( err , "error reading SCIP file" )
4045 }
4146 if index .Metadata == nil {
4247 return errors .Errorf ("Index.Metadata is nil (--from=%s)" , from )
4348 }
4449 output := map [string ]interface {}{}
45- indexStats , err := countStatistics (index )
50+ indexStats , err := countStatistics (index , flags . customProjectRoot )
4651 if err != nil {
47- return err
52+ return errors . Wrap ( err , "error counting stats" )
4853 }
4954 jsonBytes , err := json .MarshalIndent (indexStats , "" , " " )
5055 if err != nil {
@@ -61,8 +66,8 @@ type indexStatistics struct {
6166 Definitions int32 `json:"definitions"`
6267}
6368
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 )
6671 if err != nil {
6772 return nil , err
6873 }
@@ -83,22 +88,37 @@ func countStatistics(index *scip.Index) (*indexStatistics, error) {
8388 return stats , nil
8489}
8590
86- func countLinesOfCode (index * scip.Index ) (* gocloc.Result , error ) {
91+ func countLinesOfCode (index * scip.Index , customProjectRoot string ) (* gocloc.Result , error ) {
92+ var localSource string
8793 root , err := url .Parse (index .Metadata .ProjectRoot )
8894 if err != nil {
8995 return nil , errors .Wrapf (err , "failed to parse Index.Metadata.ProjectRoot as a URI %s" , index .Metadata .ProjectRoot )
9096 }
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 )
92112 if err != nil {
93113 return nil , err
94114 }
95115 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 )
97117 }
98118 processor := gocloc .NewProcessor (gocloc .NewDefinedLanguages (), gocloc .NewClocOptions ())
99119 var paths []string
100120 for _ , document := range index .Documents {
101- paths = append (paths , filepath .Join (root . Path , document .RelativePath ))
121+ paths = append (paths , filepath .Join (localSource , document .RelativePath ))
102122 }
103123 return processor .Analyze (paths )
104124}
0 commit comments