@@ -21,27 +21,39 @@ import (
2121	"fmt" 
2222	"os" 
2323	"path/filepath" 
24+ 	"runtime" 
25+ 	"strings" 
2426
2527	"github.com/cgi-fr/rimo/internal/infra" 
2628	"github.com/cgi-fr/rimo/pkg/model" 
2729	"github.com/cgi-fr/rimo/pkg/rimo" 
30+ 	"github.com/mattn/go-isatty" 
2831	"github.com/rs/zerolog" 
2932	"github.com/rs/zerolog/log" 
3033	"github.com/spf13/cobra" 
3134)
3235
33- // Provisioned by ldflags. 
36+ const  DefaultSampleSize  =  uint (5 )
37+ 
38+ //nolint:gochecknoglobals 
3439var  (
35- 	name       string  //nolint: gochecknoglobals 
36- 	version    string  //nolint: gochecknoglobals 
37- 	commit     string  //nolint: gochecknoglobals 
38- 	buildDate  string  //nolint: gochecknoglobals 
39- 	builtBy    string  //nolint: gochecknoglobals 
40+ 	name       string  // provisioned by ldflags 
41+ 	version    string  // provisioned by ldflags 
42+ 	commit     string  // provisioned by ldflags 
43+ 	buildDate  string  // provisioned by ldflags 
44+ 	builtBy    string  // provisioned by ldflags 
45+ 
46+ 	verbosity  string 
47+ 	jsonlog    bool 
48+ 	debug      bool 
49+ 	colormode  string 
50+ 
51+ 	sampleSize  uint 
52+ 	distinct    bool  //nolint: gochecknoglobals 
4053)
4154
4255func  main () { //nolint:funlen 
43- 	log .Logger  =  log .Output (zerolog.ConsoleWriter {Out : os .Stderr }) //nolint: exhaustruct 
44- 
56+ 	cobra .OnInitialize (initLog )
4557	log .Info ().Msgf ("%v %v (commit=%v date=%v by=%v)" , name , version , commit , buildDate , builtBy )
4658
4759	rootCmd  :=  & cobra.Command { //nolint:exhaustruct 
@@ -54,6 +66,12 @@ func main() { //nolint:funlen
5466		There is NO WARRANTY, to the extent permitted by law.` , version , commit , buildDate , builtBy ),
5567	}
5668
69+ 	rootCmd .PersistentFlags ().StringVarP (& verbosity , "verbosity" , "v" , "warn" ,
70+ 		"set level of log verbosity : none (0), error (1), warn (2), info (3), debug (4), trace (5)" )
71+ 	rootCmd .PersistentFlags ().BoolVar (& debug , "debug" , false , "add debug information to logs (very slow)" )
72+ 	rootCmd .PersistentFlags ().BoolVar (& jsonlog , "log-json" , false , "output logs in JSON format" )
73+ 	rootCmd .PersistentFlags ().StringVar (& colormode , "color" , "auto" , "use colors in log outputs : yes, no or auto" )
74+ 
5775	rimoSchemaCmd  :=  & cobra.Command { //nolint:exhaustruct 
5876		Use :   "jsonschema" ,
5977		Short : "Return rimo jsonschema" ,
@@ -77,32 +95,21 @@ func main() { //nolint:funlen
7795			outputDir  :=  args [1 ]
7896
7997			// Reader 
80- 
81- 			inputList , err  :=  BuildFilepathList (inputDir , ".jsonl" )
82- 			if  err  !=  nil  {
83- 				log .Fatal ().Msgf ("error listing files: %v" , err )
84- 			}
85- 
86- 			reader , err  :=  infra .FilesReaderFactory (inputList )
98+ 			reader , err  :=  infra .NewJSONLFolderReader (inputDir )
8799			if  err  !=  nil  {
88100				log .Fatal ().Msgf ("error creating reader: %v" , err )
89101			}
90102
91- 			// Writer 
92- 			// (could be relocated to infra.FilesReader) 
93- 			baseName , _ , err  :=  infra .ExtractName (inputList [0 ])
94- 			if  err  !=  nil  {
95- 				log .Fatal ().Msgf ("error extracting base name: %v" , err )
96- 			}
97- 
98- 			outputPath  :=  filepath .Join (outputDir , fmt .Sprintf ("%s.yaml" , baseName ))
103+ 			outputPath  :=  filepath .Join (outputDir , fmt .Sprintf ("%s.yaml" , reader .BaseName ()))
99104
100105			writer , err  :=  infra .YAMLWriterFactory (outputPath )
101106			if  err  !=  nil  {
102107				log .Fatal ().Msgf ("error creating writer: %v" , err )
103108			}
104109
105- 			err  =  rimo .AnalyseBase (reader , writer )
110+ 			driver  :=  rimo.Driver {SampleSize : sampleSize , Distinct : distinct }
111+ 
112+ 			err  =  driver .AnalyseBase (reader , writer )
106113			if  err  !=  nil  {
107114				log .Fatal ().Msgf ("error generating rimo.yaml: %v" , err )
108115			}
@@ -111,6 +118,9 @@ func main() { //nolint:funlen
111118		},
112119	}
113120
121+ 	rimoAnalyseCmd .Flags ().UintVar (& sampleSize , "sample-size" , DefaultSampleSize , "number of sample value to collect" )
122+ 	rimoAnalyseCmd .Flags ().BoolVarP (& distinct , "distinct" , "d" , false , "count distinct values" )
123+ 
114124	rootCmd .AddCommand (rimoAnalyseCmd )
115125	rootCmd .AddCommand (rimoSchemaCmd )
116126
@@ -120,54 +130,44 @@ func main() { //nolint:funlen
120130	}
121131}
122132
123- func  FilesList ( path   string ,  extension   string ) ([] string ,  error ) {
124- 	pattern  :=  filepath . Join ( path ,  "*" + extension ) 
133+ func  initLog ( ) {
134+ 	color  :=  false 
125135
126- 	files , err  :=  filepath .Glob (pattern )
127- 	if  err  !=  nil  {
128- 		return  nil , fmt .Errorf ("error listing files: %w" , err )
136+ 	switch  strings .ToLower (colormode ) {
137+ 	case  "auto" :
138+ 		if  isatty .IsTerminal (os .Stdout .Fd ()) &&  runtime .GOOS  !=  "windows"  {
139+ 			color  =  true 
140+ 		}
141+ 	case  "yes" , "true" , "1" , "on" , "enable" :
142+ 		color  =  true 
129143	}
130144
131- 	return  files , nil 
132- }
133- 
134- var  ErrNoFile  =  fmt .Errorf ("no file found" )
135- 
136- func  BuildFilepathList (path  string , extension  string ) ([]string , error ) {
137- 	err  :=  ValidateDirPath (path )
138- 	if  err  !=  nil  {
139- 		return  nil , fmt .Errorf ("failed to validate input directory: %w" , err )
140- 	}
141- 
142- 	pattern  :=  filepath .Join (path , "*" + extension )
143- 
144- 	files , err  :=  filepath .Glob (pattern )
145- 	if  err  !=  nil  {
146- 		return  nil , fmt .Errorf ("error listing files: %w" , err )
145+ 	if  jsonlog  {
146+ 		log .Logger  =  zerolog .New (os .Stderr )
147+ 	} else  {
148+ 		log .Logger  =  log .Output (zerolog.ConsoleWriter {Out : os .Stderr , NoColor : ! color }) //nolint:exhaustruct 
147149	}
148150
149- 	if  len ( files )  ==   0  {
150- 		return   nil ,  fmt . Errorf ( "%w : no %s files found in %s" ,  ErrNoFile ,  extension ,  path )
151+ 	if  debug  {
152+ 		log . Logger   =   log . Logger . With (). Caller (). Logger ( )
151153	}
152154
153- 	return   files ,  nil 
155+ 	setVerbosity () 
154156}
155157
156- func  ValidateDirPath (path  string ) error  {
157- 	fileInfo , err  :=  os .Stat (path )
158- 	if  os .IsNotExist (err ) {
159- 		return  fmt .Errorf ("%w: %s" , infra .ErrDirDoesNotExist , path )
160- 	} else  if  err  !=  nil  {
161- 		return  fmt .Errorf ("failed to get directory info: %w" , err )
158+ func  setVerbosity () {
159+ 	switch  verbosity  {
160+ 	case  "trace" , "5" :
161+ 		zerolog .SetGlobalLevel (zerolog .TraceLevel )
162+ 	case  "debug" , "4" :
163+ 		zerolog .SetGlobalLevel (zerolog .DebugLevel )
164+ 	case  "info" , "3" :
165+ 		zerolog .SetGlobalLevel (zerolog .InfoLevel )
166+ 	case  "warn" , "2" :
167+ 		zerolog .SetGlobalLevel (zerolog .WarnLevel )
168+ 	case  "error" , "1" :
169+ 		zerolog .SetGlobalLevel (zerolog .ErrorLevel )
170+ 	default :
171+ 		zerolog .SetGlobalLevel (zerolog .Disabled )
162172	}
163- 
164- 	if  ! fileInfo .IsDir () {
165- 		return  fmt .Errorf ("%w: %s" , infra .ErrPathIsNotDir , path )
166- 	}
167- 
168- 	if  fileInfo .Mode ().Perm ()& infra .WriteDirPerm  !=  infra .WriteDirPerm  {
169- 		return  fmt .Errorf ("%w: %s" , infra .ErrWriteDirPermission , path )
170- 	}
171- 
172- 	return  nil 
173173}
0 commit comments