77 "github.com/fatih/color"
88 "os"
99 "osv-detector/internal"
10+ "osv-detector/internal/configer"
1011 "osv-detector/internal/database"
1112 "osv-detector/internal/lockfile"
1213 "osv-detector/internal/reporter"
@@ -185,11 +186,27 @@ func (s *stringsFlag) Set(value string) error {
185186 return nil
186187}
187188
189+ func allIgnores (global , local []string ) []string {
190+ ignores := make (
191+ []string ,
192+ 0 ,
193+ // len cannot return negative numbers, but the types can't reflect that
194+ uint64 (len (global ))+ uint64 (len (local )),
195+ )
196+
197+ ignores = append (ignores , global ... )
198+ ignores = append (ignores , local ... )
199+
200+ return ignores
201+ }
202+
188203func run () int {
189204 var ignores stringsFlag
190205
191206 offline := flag .Bool ("offline" , false , "Perform checks using only the cached databases on disk" )
192207 parseAs := flag .String ("parse-as" , "" , "Name of a supported lockfile to parse the input files as" )
208+ configPath := flag .String ("config" , "" , "Path to a config file to use for all lockfiles" )
209+ noConfig := flag .Bool ("no-config" , false , "Disable loading of any config files" )
193210 printVersion := flag .Bool ("version" , false , "Print version information" )
194211 listEcosystems := flag .Bool ("list-ecosystems" , false , "List all of the known ecosystems that are supported by the detector" )
195212 listPackages := flag .Bool ("list-packages" , false , "List the packages that are parsed from the input files" )
@@ -254,11 +271,41 @@ This flag can be passed multiple times to ignore different vulnerabilities`)
254271
255272 exitCode := 0
256273
274+ var config configer.Config
275+
276+ if ! * noConfig && * configPath != "" {
277+ con , err := configer .Load (* configPath )
278+
279+ if err != nil {
280+ r .PrintError (fmt .Sprintf ("Error, %s\n " , err ))
281+
282+ return 127
283+ }
284+
285+ config = con
286+ }
287+
257288 for i , pathToLock := range pathsToLocks {
289+ config := config
290+
258291 if i >= 1 {
259292 r .PrintText ("\n " )
260293 }
261294
295+ if ! * noConfig && * configPath == "" {
296+ base := path .Dir (pathToLock )
297+ con , err := configer .Find (base )
298+
299+ if err != nil {
300+ r .PrintError (fmt .Sprintf ("Error, %s\n " , err ))
301+ exitCode = 127
302+
303+ continue
304+ }
305+
306+ config = con
307+ }
308+
262309 lockf , err := lockfile .Parse (pathToLock , * parseAs )
263310
264311 if err != nil {
@@ -281,6 +328,18 @@ This flag can be passed multiple times to ignore different vulnerabilities`)
281328 continue
282329 }
283330
331+ // an empty FilePath means we didn't load a config
332+ if config .FilePath != "" {
333+ r .PrintText (fmt .Sprintf (
334+ " Using config at %s (%s)\n " ,
335+ color .MagentaString (config .FilePath ),
336+ color .YellowString ("%d %s" ,
337+ len (config .Ignore ),
338+ reporter .Form (len (config .Ignore ), "ignore" , "ignores" ),
339+ ),
340+ ))
341+ }
342+
284343 dbs , err := loadEcosystemDatabases (r , lockf .Packages .Ecosystems (), * offline )
285344
286345 if err != nil {
@@ -290,7 +349,7 @@ This flag can be passed multiple times to ignore different vulnerabilities`)
290349 continue
291350 }
292351
293- report := dbs .check (lockf , ignores )
352+ report := dbs .check (lockf , allIgnores ( config . Ignore , ignores ) )
294353
295354 r .PrintResult (report )
296355
0 commit comments