Skip to content

Commit 7001129

Browse files
authored
feat: move offline flags out of experimental mode (#1664)
This PR moves offline flags out of experimental mode and removes the deprecated `experimental-call-analysis` flag
1 parent 40c8ac9 commit 7001129

File tree

6 files changed

+52
-67
lines changed

6 files changed

+52
-67
lines changed

cmd/osv-scanner/fix/main.go

+7-7
Original file line numberDiff line numberDiff line change
@@ -192,16 +192,16 @@ func Command(stdout, stderr io.Writer, r *reporter.Reporter) *cli.Command {
192192
},
193193
// Offline database flags, copied from osv-scanner scan
194194
&cli.BoolFlag{
195-
Name: "experimental-offline-vulnerabilities",
196-
Aliases: []string{"experimental-offline"},
195+
Name: "offline-vulnerabilities",
196+
Aliases: []string{"offline"},
197197
Usage: "checks for vulnerabilities using local databases that are already cached",
198198
},
199199
&cli.BoolFlag{
200-
Name: "experimental-download-offline-databases",
200+
Name: "download-offline-databases",
201201
Usage: "downloads vulnerability databases for offline comparison",
202202
},
203203
&cli.StringFlag{
204-
Name: "experimental-local-db-path",
204+
Name: "local-db-path",
205205
Usage: "sets the path that local databases should be stored",
206206
Hidden: true,
207207
},
@@ -308,12 +308,12 @@ func action(ctx *cli.Context, stdout, stderr io.Writer) (reporter.Reporter, erro
308308
}
309309

310310
userAgent := "osv-scanner_fix/" + version.OSVVersion
311-
if ctx.Bool("experimental-offline-vulnerabilities") {
311+
if ctx.Bool("offline-vulnerabilities") {
312312
matcher, err := localmatcher.NewLocalMatcher(
313313
r,
314-
ctx.String("experimental-local-db-path"),
314+
ctx.String("local-db-path"),
315315
userAgent,
316-
ctx.Bool("experimental-download-offline-databases"),
316+
ctx.Bool("download-offline-databases"),
317317
)
318318
if err != nil {
319319
return nil, err

cmd/osv-scanner/internal/helper/helper.go

+14-15
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,8 @@ import (
2121
// OfflineFlags is a map of flags which require network access to operate,
2222
// with the values to set them to in order to disable them
2323
var OfflineFlags = map[string]string{
24-
"include-git-root": "true",
25-
"experimental-offline-vulnerabilities": "true",
26-
"experimental-no-resolve": "true",
24+
"offline-vulnerabilities": "true",
25+
"experimental-no-resolve": "true",
2726
}
2827

2928
// sets default port(8000) as a global variable
@@ -95,7 +94,7 @@ var GlobalScanFlags = []cli.Flag{
9594
Value: "info",
9695
},
9796
&cli.BoolFlag{
98-
Name: "experimental-offline",
97+
Name: "offline",
9998
Usage: "run in offline mode, disabling any features requiring network access",
10099
Action: func(ctx *cli.Context, b bool) error {
101100
if !b {
@@ -105,7 +104,7 @@ var GlobalScanFlags = []cli.Flag{
105104
for flag, value := range OfflineFlags {
106105
// TODO(michaelkedar): do something if the flag was already explicitly set.
107106

108-
// Skip setting the flag if the current command doesn't have it."
107+
// Skip setting the flag if the current command doesn't have it.
109108
if !slices.ContainsFunc(ctx.Command.Flags, func(f cli.Flag) bool {
110109
return slices.Contains(f.Names(), flag)
111110
}) {
@@ -121,22 +120,22 @@ var GlobalScanFlags = []cli.Flag{
121120
},
122121
},
123122
&cli.BoolFlag{
124-
Name: "experimental-offline-vulnerabilities",
123+
Name: "offline-vulnerabilities",
125124
Usage: "checks for vulnerabilities using local databases that are already cached",
126125
},
127126
&cli.BoolFlag{
128-
Name: "experimental-download-offline-databases",
127+
Name: "download-offline-databases",
129128
Usage: "downloads vulnerability databases for offline comparison",
130129
},
131-
&cli.BoolFlag{
132-
Name: "experimental-no-resolve",
133-
Usage: "disable transitive dependency resolution of manifest files",
134-
},
135130
&cli.StringFlag{
136-
Name: "experimental-local-db-path",
131+
Name: "local-db-path",
137132
Usage: "sets the path that local databases should be stored",
138133
Hidden: true,
139134
},
135+
&cli.BoolFlag{
136+
Name: "experimental-no-resolve",
137+
Usage: "disable transitive dependency resolution of manifest files",
138+
},
140139
&cli.BoolFlag{
141140
Name: "experimental-all-packages",
142141
Usage: "when json output is selected, prints all packages",
@@ -234,7 +233,7 @@ func GetScanLicensesAllowlist(context *cli.Context) ([]string, error) {
234233
return nil, fmt.Errorf("--experimental-licenses requires comma-separated spdx licenses. The following license(s) are not recognized as spdx: %s", strings.Join(unrecognized, ","))
235234
}
236235

237-
if context.Bool("experimental-offline") {
236+
if context.Bool("offline") {
238237
allowlist = []string{}
239238
}
240239

@@ -244,8 +243,8 @@ func GetScanLicensesAllowlist(context *cli.Context) ([]string, error) {
244243
func GetExperimentalScannerActions(context *cli.Context, scanLicensesAllowlist []string) osvscanner.ExperimentalScannerActions {
245244
return osvscanner.ExperimentalScannerActions{
246245
LocalDBPath: context.String("experimental-local-db-path"),
247-
DownloadDatabases: context.Bool("experimental-download-offline-databases"),
248-
CompareOffline: context.Bool("experimental-offline-vulnerabilities"),
246+
DownloadDatabases: context.Bool("download-offline-databases"),
247+
CompareOffline: context.Bool("offline-vulnerabilities"),
249248
ShowAllPackages: context.Bool("experimental-all-packages"),
250249
ScanLicensesSummary: context.IsSet("experimental-licenses"),
251250
ScanLicensesAllowlist: scanLicensesAllowlist,

cmd/osv-scanner/main.go

+3
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,9 @@ EXAMPLES:
9797
# Scan a source directory
9898
$ {{.Name}} scan source -r <source_directory>
9999
100+
# Scan a source directory in offline mode
101+
$ {{.Name}} scan source --offline-vulnerabilities --download-offline-database -r <source_directory>
102+
100103
# Scan a container image
101104
$ {{.Name}} scan image <image_name>
102105

cmd/osv-scanner/main_test.go

+17-17
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ func Test_run(t *testing.T) {
232232
},
233233
{
234234
name: "PURL SBOM case sensitivity (local)",
235-
args: []string{"", "--config=./fixtures/osv-scanner-empty-config.toml", "--experimental-offline", "--experimental-download-offline-databases", "--format", "table", "./fixtures/sbom-insecure/alpine.cdx.xml"},
235+
args: []string{"", "--config=./fixtures/osv-scanner-empty-config.toml", "--offline", "--download-offline-databases", "--format", "table", "./fixtures/sbom-insecure/alpine.cdx.xml"},
236236
exit: 1,
237237
},
238238
// Go project with an overridden go version
@@ -481,62 +481,62 @@ func Test_run_LocalDatabases(t *testing.T) {
481481
tests := []cliTestCase{
482482
{
483483
name: "one specific supported lockfile",
484-
args: []string{"", "--experimental-offline", "--experimental-download-offline-databases", "./fixtures/locks-many/composer.lock"},
484+
args: []string{"", "--offline", "--download-offline-databases", "./fixtures/locks-many/composer.lock"},
485485
exit: 0,
486486
},
487487
{
488488
name: "one specific supported sbom with vulns",
489-
args: []string{"", "--experimental-offline", "--experimental-download-offline-databases", "--config=./fixtures/osv-scanner-empty-config.toml", "./fixtures/sbom-insecure/postgres-stretch.cdx.xml"},
489+
args: []string{"", "--offline", "--download-offline-databases", "--config=./fixtures/osv-scanner-empty-config.toml", "./fixtures/sbom-insecure/postgres-stretch.cdx.xml"},
490490
exit: 1,
491491
},
492492
{
493493
name: "one specific unsupported lockfile",
494-
args: []string{"", "--experimental-offline", "--experimental-download-offline-databases", "./fixtures/locks-many/not-a-lockfile.toml"},
494+
args: []string{"", "--offline", "--download-offline-databases", "./fixtures/locks-many/not-a-lockfile.toml"},
495495
exit: 128,
496496
},
497497
{
498498
name: "all supported lockfiles in the directory should be checked",
499-
args: []string{"", "--experimental-offline", "--experimental-download-offline-databases", "./fixtures/locks-many"},
499+
args: []string{"", "--offline", "--download-offline-databases", "./fixtures/locks-many"},
500500
exit: 0,
501501
},
502502
{
503503
name: "all supported lockfiles in the directory should be checked",
504-
args: []string{"", "--experimental-offline", "--experimental-download-offline-databases", "./fixtures/locks-many-with-invalid"},
504+
args: []string{"", "--offline", "--download-offline-databases", "./fixtures/locks-many-with-invalid"},
505505
exit: 127,
506506
},
507507
{
508508
name: "only the files in the given directories are checked by default (no recursion)",
509-
args: []string{"", "--experimental-offline", "--experimental-download-offline-databases", "./fixtures/locks-one-with-nested"},
509+
args: []string{"", "--offline", "--download-offline-databases", "./fixtures/locks-one-with-nested"},
510510
exit: 0,
511511
},
512512
{
513513
name: "nested directories are checked when `--recursive` is passed",
514-
args: []string{"", "--experimental-offline", "--experimental-download-offline-databases", "--recursive", "./fixtures/locks-one-with-nested"},
514+
args: []string{"", "--offline", "--download-offline-databases", "--recursive", "./fixtures/locks-one-with-nested"},
515515
exit: 0,
516516
},
517517
{
518518
name: ".gitignored files",
519-
args: []string{"", "--experimental-offline", "--experimental-download-offline-databases", "--recursive", "./fixtures/locks-gitignore"},
519+
args: []string{"", "--offline", "--download-offline-databases", "--recursive", "./fixtures/locks-gitignore"},
520520
exit: 0,
521521
},
522522
{
523523
name: "ignoring .gitignore",
524-
args: []string{"", "--experimental-offline", "--experimental-download-offline-databases", "--recursive", "--no-ignore", "./fixtures/locks-gitignore"},
524+
args: []string{"", "--offline", "--download-offline-databases", "--recursive", "--no-ignore", "./fixtures/locks-gitignore"},
525525
exit: 0,
526526
},
527527
{
528528
name: "output with json",
529-
args: []string{"", "--experimental-offline", "--experimental-download-offline-databases", "--format", "json", "./fixtures/locks-many/composer.lock"},
529+
args: []string{"", "--offline", "--download-offline-databases", "--format", "json", "./fixtures/locks-many/composer.lock"},
530530
exit: 0,
531531
},
532532
{
533533
name: "output format: markdown table",
534-
args: []string{"", "--experimental-offline", "--experimental-download-offline-databases", "--format", "markdown", "./fixtures/locks-many/composer.lock"},
534+
args: []string{"", "--offline", "--download-offline-databases", "--format", "markdown", "./fixtures/locks-many/composer.lock"},
535535
exit: 0,
536536
},
537537
{
538538
name: "database should be downloaded only when offline is set",
539-
args: []string{"", "--experimental-download-offline-databases", "./fixtures/locks-many"},
539+
args: []string{"", "--download-offline-databases", "./fixtures/locks-many"},
540540
exit: 127,
541541
},
542542
}
@@ -548,7 +548,7 @@ func Test_run_LocalDatabases(t *testing.T) {
548548
if testutility.IsAcceptanceTesting() {
549549
testDir := testutility.CreateTestDir(t)
550550
old := tt.args
551-
tt.args = []string{"", "--experimental-local-db-path", testDir}
551+
tt.args = []string{"", "--local-db-path", testDir}
552552
tt.args = append(tt.args, old[1:]...)
553553
}
554554

@@ -566,7 +566,7 @@ func Test_run_LocalDatabases_AlwaysOffline(t *testing.T) {
566566
tests := []cliTestCase{
567567
{
568568
name: "a bunch of different lockfiles and ecosystem",
569-
args: []string{"", "--config=./fixtures/osv-scanner-empty-config.toml", "--experimental-offline", "./fixtures/locks-requirements", "./fixtures/locks-many"},
569+
args: []string{"", "--config=./fixtures/osv-scanner-empty-config.toml", "--offline", "./fixtures/locks-requirements", "./fixtures/locks-many"},
570570
exit: 127,
571571
},
572572
}
@@ -577,7 +577,7 @@ func Test_run_LocalDatabases_AlwaysOffline(t *testing.T) {
577577

578578
testDir := testutility.CreateTestDir(t)
579579
old := tt.args
580-
tt.args = []string{"", "--experimental-local-db-path", testDir}
580+
tt.args = []string{"", "--local-db-path", testDir}
581581
tt.args = append(tt.args, old[1:]...)
582582

583583
// run each test twice since they should provide the same output,
@@ -983,7 +983,7 @@ func Test_run_MavenTransitive(t *testing.T) {
983983
{
984984
// Direct dependencies do not have any vulnerability.
985985
name: "does not scan transitive dependencies for pom.xml with offline mode",
986-
args: []string{"", "--config=./fixtures/osv-scanner-empty-config.toml", "--experimental-offline", "--experimental-download-offline-databases", "./fixtures/maven-transitive/pom.xml"},
986+
args: []string{"", "--config=./fixtures/osv-scanner-empty-config.toml", "--offline", "--download-offline-databases", "./fixtures/maven-transitive/pom.xml"},
987987
exit: 0,
988988
},
989989
{

cmd/osv-scanner/scan/source/main.go

+1-12
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,6 @@ var projectScanExperimentalFlags = []cli.Flag{
7070
Name: "experimental-maven-registry",
7171
Usage: "URL of the default registry to fetch Maven metadata",
7272
},
73-
&cli.BoolFlag{
74-
Name: "experimental-call-analysis",
75-
Usage: "[Deprecated] attempt call analysis on code to detect only active vulnerabilities",
76-
Value: false,
77-
},
7873
}
7974

8075
func Command(stdout, stderr io.Writer, r *reporter.Reporter) *cli.Command {
@@ -130,13 +125,7 @@ func action(context *cli.Context, stdout, stderr io.Writer) (reporter.Reporter,
130125
return nil, err
131126
}
132127

133-
var callAnalysisStates map[string]bool
134-
if context.IsSet("experimental-call-analysis") {
135-
callAnalysisStates = helper.CreateCallAnalysisStates([]string{"all"}, context.StringSlice("no-call-analysis"))
136-
r.Infof("Warning: the experimental-call-analysis flag has been replaced. Please use the call-analysis and no-call-analysis flags instead.\n")
137-
} else {
138-
callAnalysisStates = helper.CreateCallAnalysisStates(context.StringSlice("call-analysis"), context.StringSlice("no-call-analysis"))
139-
}
128+
callAnalysisStates := helper.CreateCallAnalysisStates(context.StringSlice("call-analysis"), context.StringSlice("no-call-analysis"))
140129

141130
experimentalScannerActions := helper.GetExperimentalScannerActions(context, scanLicensesAllowlist)
142131
// Add `source` specific experimental configs

docs/offline-mode.md

+10-16
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
11
---
22
layout: page
33
title: Offline Mode
4-
permalink: /experimental/offline-mode/
5-
parent: Experimental Features
4+
permalink: /usage/offline-mode/
5+
parent: Usage
66
nav_order: 1
77
---
88

99
# Offline Mode
1010

11-
Experimental
12-
{: .label }
13-
1411
{: .no_toc }
1512

1613
<details open markdown="block">
@@ -22,10 +19,7 @@ Experimental
2219
{:toc}
2320
</details>
2421

25-
OSV-Scanner now supports offline scanning as an experimental feature. Offline scanning checks your project against a local database instead of calling the OSV.dev API.
26-
27-
{: .note }
28-
This feature is experimental and might change or be removed with only a minor version update.
22+
OSV-Scanner now supports offline scanning as an official feature. Offline scanning checks your project against a local database instead of calling the OSV.dev API.
2923

3024
## Specify database location
3125

@@ -49,29 +43,29 @@ If the `OSV_SCANNER_LOCAL_DB_CACHE_DIRECTORY` environment variable is _not_ set,
4943
1. The location returned by [`os.UserCacheDir`](https://pkg.go.dev/os#UserCacheDir)
5044
2. The location returned by [`os.TempDir`](https://pkg.go.dev/os#TempDir)
5145

52-
The database can be [downloaded manually](#manual-database-download) or by using the [`--experimental-download-offline-databases` flag](#download-offline-databases-option).
46+
The database can be [downloaded manually](#manual-database-download) or by using the [`--download-offline-databases` flag](#download-offline-databases-option).
5347

5448
## Offline option
5549

56-
The offline database flag `--experimental-offline` causes OSV-Scanner to scan your project against a previously downloaded local database. OSV-Scanner will not download or update the local database, nor will it send any project or dependency information anywhere. When a local database is not present, you will get an error message. No network connection is required when using this flag.
50+
The offline database flag `--offline` causes OSV-Scanner to scan your project against a previously downloaded local database. OSV-Scanner will not download or update the local database, nor will it send any project or dependency information anywhere. When a local database is not present, you will get an error message. No network connection is required when using this flag.
5751

5852
```bash
59-
osv-scanner --experimental-offline ./path/to/your/dir
53+
osv-scanner --offline ./path/to/your/dir
6054
```
6155

62-
To use offline mode for just the vulnerability database, but allow other features to possibly make network requests (e.g. [transitive dependency scanning](./supported_languages_and_lockfiles.md/#transitive-dependency-scanning)), you can use the `--experimental-offline-vulnerabilities` flag instead.
56+
To use offline mode for just the vulnerability database, but allow other features to possibly make network requests (e.g. [transitive dependency scanning](./supported_languages_and_lockfiles.md/#transitive-dependency-scanning)), you can use the `--offline-vulnerabilities` flag instead.
6357

6458
## Download offline databases option
6559

66-
The download offline databases flag `--experimental-download-offline-databases` allows OSV-Scanner to download or update your local database when running in offline mode, to make it easier to get started. This option only works when you also set the offline flag.
60+
The download offline databases flag `--download-offline-databases` allows OSV-Scanner to download or update your local database when running in offline mode, to make it easier to get started. This option only works when you also set the offline flag.
6761

6862
```bash
69-
osv-scanner --experimental-offline --experimental-download-offline-databases ./path/to/your/dir
63+
osv-scanner --offline-vulnerabilities --download-offline-databases ./path/to/your/dir
7064
```
7165

7266
## Manual database download
7367

74-
Instead of using the `--experimental-download-offline-databases` flag to download the database, it is possible to manually download the database.
68+
Instead of using the `--download-offline-databases` flag to download the database, it is possible to manually download the database.
7569

7670
A downloadable copy of the OSV database is stored in a GCS bucket maintained by OSV:
7771
[`gs://osv-vulnerabilities`](https://osv-vulnerabilities.storage.googleapis.com)

0 commit comments

Comments
 (0)