mirror of
https://github.com/aquasecurity/trivy.git
synced 2025-12-22 23:26:39 -08:00
feat(repo): add support for branch, commit, & tag (#2494)
Co-authored-by: knqyf263 <knqyf263@gmail.com>
This commit is contained in:
committed by
GitHub
parent
783e7cfe0c
commit
30c9f90bf8
@@ -66,6 +66,11 @@ Client/Server Flags
|
|||||||
--token string for authentication in client/server mode
|
--token string for authentication in client/server mode
|
||||||
--token-header string specify a header name for token in client/server mode (default "Trivy-Token")
|
--token-header string specify a header name for token in client/server mode (default "Trivy-Token")
|
||||||
|
|
||||||
|
Repository Flags
|
||||||
|
--branch string pass the branch name to be scanned
|
||||||
|
--commit string pass the commit hash to be scanned
|
||||||
|
--tag string pass the tag name to be scanned
|
||||||
|
|
||||||
Global Flags:
|
Global Flags:
|
||||||
--cache-dir string cache directory (default "/Users/teppei/Library/Caches/trivy")
|
--cache-dir string cache directory (default "/Users/teppei/Library/Caches/trivy")
|
||||||
-c, --config string config path (default "trivy.yaml")
|
-c, --config string config path (default "trivy.yaml")
|
||||||
|
|||||||
@@ -240,6 +240,24 @@ kubernetes:
|
|||||||
namespace:
|
namespace:
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Repository Options
|
||||||
|
Available with git repository scanning (`trivy repo`)
|
||||||
|
|
||||||
|
```
|
||||||
|
repository:
|
||||||
|
# Same as '--branch'
|
||||||
|
# Default is empty
|
||||||
|
branch:
|
||||||
|
|
||||||
|
# Same as '--commit'
|
||||||
|
# Default is empty
|
||||||
|
commit:
|
||||||
|
|
||||||
|
# Same as '--tag'
|
||||||
|
# Default is empty
|
||||||
|
tag:
|
||||||
|
```
|
||||||
|
|
||||||
## Client/Server Options
|
## Client/Server Options
|
||||||
Available in client/server mode
|
Available in client/server mode
|
||||||
|
|
||||||
|
|||||||
@@ -147,6 +147,30 @@ Total: 20 (UNKNOWN: 3, LOW: 0, MEDIUM: 7, HIGH: 5, CRITICAL: 5)
|
|||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
## Scanning a Branch
|
||||||
|
|
||||||
|
Pass a `--branch` agrument with a valid branch name on the remote repository provided:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ trivy repo --branch <branch-name> <repo-name>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Scanning upto a Commit
|
||||||
|
|
||||||
|
Pass a `--commit` agrument with a valid commit hash on the remote repository provided:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ trivy repo --commit <commit-hash> <repo-name>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Scanning a Tag
|
||||||
|
|
||||||
|
Pass a `--tag` agrument with a valid tag on the remote repository provided:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ trivy repo --tag <tag-name> <repo-name>
|
||||||
|
```
|
||||||
|
|
||||||
## Scanning Private Repositories
|
## Scanning Private Repositories
|
||||||
|
|
||||||
In order to scan private GitHub or GitLab repositories, the environment variable `GITHUB_TOKEN` or `GITLAB_TOKEN` must be set, respectively, with a valid token that has access to the private repository being scanned.
|
In order to scan private GitHub or GitLab repositories, the environment variable `GITHUB_TOKEN` or `GITLAB_TOKEN` must be set, respectively, with a valid token that has access to the private repository being scanned.
|
||||||
|
|||||||
@@ -400,6 +400,7 @@ func NewRepositoryCommand(globalFlags *flag.GlobalFlagGroup) *cobra.Command {
|
|||||||
ScanFlagGroup: flag.NewScanFlagGroup(),
|
ScanFlagGroup: flag.NewScanFlagGroup(),
|
||||||
SecretFlagGroup: flag.NewSecretFlagGroup(),
|
SecretFlagGroup: flag.NewSecretFlagGroup(),
|
||||||
VulnerabilityFlagGroup: flag.NewVulnerabilityFlagGroup(),
|
VulnerabilityFlagGroup: flag.NewVulnerabilityFlagGroup(),
|
||||||
|
RepoFlagGroup: flag.NewRepoFlagGroup(),
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
|
|||||||
@@ -497,6 +497,9 @@ func initScannerConfig(opts flag.Options, cacheClient cache.Cache) (ScannerConfi
|
|||||||
InsecureSkipTLS: opts.Insecure,
|
InsecureSkipTLS: opts.Insecure,
|
||||||
Offline: opts.OfflineScan,
|
Offline: opts.OfflineScan,
|
||||||
NoProgress: opts.NoProgress || opts.Quiet,
|
NoProgress: opts.NoProgress || opts.Quiet,
|
||||||
|
RepoBranch: opts.RepoBranch,
|
||||||
|
RepoCommit: opts.RepoCommit,
|
||||||
|
RepoTag: opts.RepoTag,
|
||||||
|
|
||||||
// For misconfiguration scanning
|
// For misconfiguration scanning
|
||||||
MisconfScannerOption: configScannerOptions,
|
MisconfScannerOption: configScannerOptions,
|
||||||
|
|||||||
@@ -20,6 +20,9 @@ type Option struct {
|
|||||||
Offline bool
|
Offline bool
|
||||||
InsecureSkipTLS bool
|
InsecureSkipTLS bool
|
||||||
AppDirs []string
|
AppDirs []string
|
||||||
|
RepoBranch string
|
||||||
|
RepoCommit string
|
||||||
|
RepoTag string
|
||||||
|
|
||||||
MisconfScannerOption misconf.ScannerOption
|
MisconfScannerOption misconf.ScannerOption
|
||||||
SecretScannerOption secret.ScannerOption
|
SecretScannerOption secret.ScannerOption
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
|
|
||||||
git "github.com/go-git/go-git/v5"
|
git "github.com/go-git/go-git/v5"
|
||||||
|
"github.com/go-git/go-git/v5/plumbing"
|
||||||
"github.com/go-git/go-git/v5/plumbing/transport/http"
|
"github.com/go-git/go-git/v5/plumbing/transport/http"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
@@ -39,7 +40,6 @@ func NewArtifact(rawurl string, c cache.ArtifactCache, artifactOpt artifact.Opti
|
|||||||
URL: u.String(),
|
URL: u.String(),
|
||||||
Auth: gitAuth(),
|
Auth: gitAuth(),
|
||||||
Progress: os.Stdout,
|
Progress: os.Stdout,
|
||||||
Depth: 1,
|
|
||||||
InsecureSkipTLS: artifactOpt.InsecureSkipTLS,
|
InsecureSkipTLS: artifactOpt.InsecureSkipTLS,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,9 +48,37 @@ func NewArtifact(rawurl string, c cache.ArtifactCache, artifactOpt artifact.Opti
|
|||||||
cloneOptions.Progress = nil
|
cloneOptions.Progress = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = git.PlainClone(tmpDir, false, &cloneOptions)
|
if artifactOpt.RepoCommit == "" {
|
||||||
|
cloneOptions.Depth = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if artifactOpt.RepoBranch != "" {
|
||||||
|
cloneOptions.ReferenceName = plumbing.NewBranchReferenceName(artifactOpt.RepoBranch)
|
||||||
|
cloneOptions.SingleBranch = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if artifactOpt.RepoTag != "" {
|
||||||
|
cloneOptions.ReferenceName = plumbing.NewTagReferenceName(artifactOpt.RepoTag)
|
||||||
|
cloneOptions.SingleBranch = true
|
||||||
|
}
|
||||||
|
|
||||||
|
r, err := git.PlainClone(tmpDir, false, &cloneOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, cleanup, xerrors.Errorf("git error: %w", err)
|
return nil, cleanup, xerrors.Errorf("git clone error: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if artifactOpt.RepoCommit != "" {
|
||||||
|
w, err := r.Worktree()
|
||||||
|
if err != nil {
|
||||||
|
return nil, cleanup, xerrors.Errorf("git worktree error: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = w.Checkout(&git.CheckoutOptions{
|
||||||
|
Hash: plumbing.NewHash(artifactOpt.RepoCommit),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, cleanup, xerrors.Errorf("git checkout error: %w", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup = func() {
|
cleanup = func() {
|
||||||
|
|||||||
@@ -38,11 +38,14 @@ func TestNewArtifact(t *testing.T) {
|
|||||||
rawurl string
|
rawurl string
|
||||||
c cache.ArtifactCache
|
c cache.ArtifactCache
|
||||||
noProgress bool
|
noProgress bool
|
||||||
|
repoBranch string
|
||||||
|
repoTag string
|
||||||
|
repoCommit string
|
||||||
}
|
}
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
args args
|
args args
|
||||||
wantErr bool
|
assertion assert.ErrorAssertionFunc
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "happy path",
|
name: "happy path",
|
||||||
@@ -51,6 +54,7 @@ func TestNewArtifact(t *testing.T) {
|
|||||||
c: nil,
|
c: nil,
|
||||||
noProgress: false,
|
noProgress: false,
|
||||||
},
|
},
|
||||||
|
assertion: assert.NoError,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "happy noProgress",
|
name: "happy noProgress",
|
||||||
@@ -59,6 +63,34 @@ func TestNewArtifact(t *testing.T) {
|
|||||||
c: nil,
|
c: nil,
|
||||||
noProgress: true,
|
noProgress: true,
|
||||||
},
|
},
|
||||||
|
assertion: assert.NoError,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "branch",
|
||||||
|
args: args{
|
||||||
|
rawurl: ts.URL + "/test.git",
|
||||||
|
c: nil,
|
||||||
|
repoBranch: "valid-branch",
|
||||||
|
},
|
||||||
|
assertion: assert.NoError,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "tag",
|
||||||
|
args: args{
|
||||||
|
rawurl: ts.URL + "/test.git",
|
||||||
|
c: nil,
|
||||||
|
repoTag: "v1.0.0",
|
||||||
|
},
|
||||||
|
assertion: assert.NoError,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "commit",
|
||||||
|
args: args{
|
||||||
|
rawurl: ts.URL + "/test.git",
|
||||||
|
c: nil,
|
||||||
|
repoCommit: "6ac152fe2b87cb5e243414df71790a32912e778d",
|
||||||
|
},
|
||||||
|
assertion: assert.NoError,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "sad path",
|
name: "sad path",
|
||||||
@@ -67,7 +99,9 @@ func TestNewArtifact(t *testing.T) {
|
|||||||
c: nil,
|
c: nil,
|
||||||
noProgress: false,
|
noProgress: false,
|
||||||
},
|
},
|
||||||
wantErr: true,
|
assertion: func(t assert.TestingT, err error, args ...interface{}) bool {
|
||||||
|
return assert.ErrorContains(t, err, "repository not found")
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "invalid url",
|
name: "invalid url",
|
||||||
@@ -76,14 +110,54 @@ func TestNewArtifact(t *testing.T) {
|
|||||||
c: nil,
|
c: nil,
|
||||||
noProgress: false,
|
noProgress: false,
|
||||||
},
|
},
|
||||||
wantErr: true,
|
assertion: func(t assert.TestingT, err error, args ...interface{}) bool {
|
||||||
|
return assert.ErrorContains(t, err, "url parse error")
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "invalid branch",
|
||||||
|
args: args{
|
||||||
|
rawurl: ts.URL + "/test.git",
|
||||||
|
c: nil,
|
||||||
|
repoBranch: "invalid-branch",
|
||||||
|
},
|
||||||
|
assertion: func(t assert.TestingT, err error, args ...interface{}) bool {
|
||||||
|
return assert.ErrorContains(t, err, `couldn't find remote ref "refs/heads/invalid-branch"`)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "invalid tag",
|
||||||
|
args: args{
|
||||||
|
rawurl: ts.URL + "/test.git",
|
||||||
|
c: nil,
|
||||||
|
repoTag: "v1.0.9",
|
||||||
|
},
|
||||||
|
assertion: func(t assert.TestingT, err error, args ...interface{}) bool {
|
||||||
|
return assert.ErrorContains(t, err, `couldn't find remote ref "refs/tags/v1.0.9"`)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "invalid commit",
|
||||||
|
args: args{
|
||||||
|
rawurl: ts.URL + "/test.git",
|
||||||
|
c: nil,
|
||||||
|
repoCommit: "6ac152fe2b87cb5e243414df71790a32912e778e",
|
||||||
|
},
|
||||||
|
assertion: func(t assert.TestingT, err error, args ...interface{}) bool {
|
||||||
|
return assert.ErrorContains(t, err, "git checkout error: object not found")
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
_, cleanup, err := NewArtifact(tt.args.rawurl, tt.args.c, artifact.Option{NoProgress: tt.args.noProgress})
|
_, cleanup, err := NewArtifact(tt.args.rawurl, tt.args.c, artifact.Option{
|
||||||
assert.Equal(t, tt.wantErr, err != nil)
|
NoProgress: tt.args.noProgress,
|
||||||
|
RepoBranch: tt.args.repoBranch,
|
||||||
|
RepoTag: tt.args.repoTag,
|
||||||
|
RepoCommit: tt.args.repoCommit,
|
||||||
|
})
|
||||||
|
tt.assertion(t, err)
|
||||||
defer cleanup()
|
defer cleanup()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
1
pkg/fanal/artifact/remote/testdata/test
vendored
Submodule
1
pkg/fanal/artifact/remote/testdata/test
vendored
Submodule
Submodule pkg/fanal/artifact/remote/testdata/test added at 0d8bf3f07c
@@ -0,0 +1,2 @@
|
|||||||
|
x<01><>Aj<41>0s<>+<2B><08><><EFBFBD>X˲<58> <09><>`,<2C>"<22><>^<5E>c<EFBFBD><63>G<EFBFBD><47> Ї<><D087><EFBFBD><EFBFBD>{<7B>M<EFBFBD>G<EFBFBD><47><EFBFBD>xb<78><1C>$<24>nZӄ3<07>d<EFBFBD><64><EFBFBD>V<EFBFBD><56><12>ul|<7C>]!rv<72><17><>Ly <09>'<27>W<>Q<EFBFBD><51>>9/D<>j<EFBFBD>Ժ<1F>Yϥr<CFA5><72><EFBFBD>h1\<5C><><EFBFBD>~<7E>un<75>[<5B><>
|
||||||
|
\4[<5B><11><><06>f<EFBFBD><66><EFBFBD><EFBFBD><1C><08><05><>'<27><>}<7D>:<3A>*?
|
||||||
BIN
pkg/fanal/artifact/remote/testdata/test.git/objects/1c/1d7deed649fbecd66fab423ccd9d001bf9ff91
vendored
Normal file
BIN
pkg/fanal/artifact/remote/testdata/test.git/objects/1c/1d7deed649fbecd66fab423ccd9d001bf9ff91
vendored
Normal file
Binary file not shown.
BIN
pkg/fanal/artifact/remote/testdata/test.git/objects/27/aaec53f92314d9438a53c703f169d2cbf5001a
vendored
Normal file
BIN
pkg/fanal/artifact/remote/testdata/test.git/objects/27/aaec53f92314d9438a53c703f169d2cbf5001a
vendored
Normal file
Binary file not shown.
@@ -0,0 +1,3 @@
|
|||||||
|
x<01><>K<EFBFBD><4B>0Dg<44>S<EFBFBD>><10><>B<>r<><72><EFBFBD>5Xqp<71>$<24>mr<6D>@-<2D><><EFBFBD>Qym<79>
|
||||||
|
<18>~dc6.<2E>@<40><>&*<2A>&˔<>O<EFBFBD><<3C><>l
|
||||||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><1B><05>8<EFBFBD><38><1D>.S<12>c<>:<3A><><EFBFBD>%<1D><><EFBFBD>9*<2A>e^7<><37><EFBFBD>4c<34><63>e<EFBFBD>/\<10><>ǧ<EFBFBD><EFBFBD>u9<75><39>]@<1F>Х#o<07>i*<2A><>CF9<46><39><EFBFBD> =<08>o<EFBFBD>RV<><56><EFBFBD>R<EFBFBD>
|
||||||
BIN
pkg/fanal/artifact/remote/testdata/test.git/objects/c0/42cd14d2b999cade090785af47e9f8b8e342ff
vendored
Normal file
BIN
pkg/fanal/artifact/remote/testdata/test.git/objects/c0/42cd14d2b999cade090785af47e9f8b8e342ff
vendored
Normal file
Binary file not shown.
BIN
pkg/fanal/artifact/remote/testdata/test.git/objects/d7/937c5f0ce7f2054e4e3be65ab3cd0f9462dc1b
vendored
Normal file
BIN
pkg/fanal/artifact/remote/testdata/test.git/objects/d7/937c5f0ce7f2054e4e3be65ab3cd0f9462dc1b
vendored
Normal file
Binary file not shown.
BIN
pkg/fanal/artifact/remote/testdata/test.git/objects/e2/4866d1d31ddffdb27fbcf583d5deb4386d5145
vendored
Normal file
BIN
pkg/fanal/artifact/remote/testdata/test.git/objects/e2/4866d1d31ddffdb27fbcf583d5deb4386d5145
vendored
Normal file
Binary file not shown.
BIN
pkg/fanal/artifact/remote/testdata/test.git/objects/f4/836be6497e83e13dc0cfbce7e6b973b1ea511d
vendored
Normal file
BIN
pkg/fanal/artifact/remote/testdata/test.git/objects/f4/836be6497e83e13dc0cfbce7e6b973b1ea511d
vendored
Normal file
Binary file not shown.
@@ -1 +1 @@
|
|||||||
c906fc4a94762f8a2c77c718947143d16e4e9ec7
|
0d8bf3f07c3970b3e38c2cfb1c619cb86fae76d2
|
||||||
|
|||||||
1
pkg/fanal/artifact/remote/testdata/test.git/refs/heads/valid-branch
vendored
Normal file
1
pkg/fanal/artifact/remote/testdata/test.git/refs/heads/valid-branch
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
d7937c5f0ce7f2054e4e3be65ab3cd0f9462dc1b
|
||||||
1
pkg/fanal/artifact/remote/testdata/test.git/refs/tags/v1.0.0
vendored
Normal file
1
pkg/fanal/artifact/remote/testdata/test.git/refs/tags/v1.0.0
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
c906fc4a94762f8a2c77c718947143d16e4e9ec7
|
||||||
@@ -51,6 +51,7 @@ type Flags struct {
|
|||||||
LicenseFlagGroup *LicenseFlagGroup
|
LicenseFlagGroup *LicenseFlagGroup
|
||||||
MisconfFlagGroup *MisconfFlagGroup
|
MisconfFlagGroup *MisconfFlagGroup
|
||||||
RemoteFlagGroup *RemoteFlagGroup
|
RemoteFlagGroup *RemoteFlagGroup
|
||||||
|
RepoFlagGroup *RepoFlagGroup
|
||||||
ReportFlagGroup *ReportFlagGroup
|
ReportFlagGroup *ReportFlagGroup
|
||||||
SBOMFlagGroup *SBOMFlagGroup
|
SBOMFlagGroup *SBOMFlagGroup
|
||||||
ScanFlagGroup *ScanFlagGroup
|
ScanFlagGroup *ScanFlagGroup
|
||||||
@@ -68,6 +69,7 @@ type Options struct {
|
|||||||
LicenseOptions
|
LicenseOptions
|
||||||
MisconfOptions
|
MisconfOptions
|
||||||
RemoteOptions
|
RemoteOptions
|
||||||
|
RepoOptions
|
||||||
ReportOptions
|
ReportOptions
|
||||||
SBOMOptions
|
SBOMOptions
|
||||||
ScanOptions
|
ScanOptions
|
||||||
@@ -209,6 +211,9 @@ func (f *Flags) groups() []FlagGroup {
|
|||||||
if f.RemoteFlagGroup != nil {
|
if f.RemoteFlagGroup != nil {
|
||||||
groups = append(groups, f.RemoteFlagGroup)
|
groups = append(groups, f.RemoteFlagGroup)
|
||||||
}
|
}
|
||||||
|
if f.RepoFlagGroup != nil {
|
||||||
|
groups = append(groups, f.RepoFlagGroup)
|
||||||
|
}
|
||||||
return groups
|
return groups
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -302,6 +307,10 @@ func (f *Flags) ToOptions(appVersion string, args []string, globalFlags *GlobalF
|
|||||||
opts.RemoteOptions = f.RemoteFlagGroup.ToOptions()
|
opts.RemoteOptions = f.RemoteFlagGroup.ToOptions()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if f.RepoFlagGroup != nil {
|
||||||
|
opts.RepoOptions = f.RepoFlagGroup.ToOptions()
|
||||||
|
}
|
||||||
|
|
||||||
if f.ReportFlagGroup != nil {
|
if f.ReportFlagGroup != nil {
|
||||||
opts.ReportOptions, err = f.ReportFlagGroup.ToOptions(output)
|
opts.ReportOptions, err = f.ReportFlagGroup.ToOptions(output)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
58
pkg/flag/repo.go
Normal file
58
pkg/flag/repo.go
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
package flag
|
||||||
|
|
||||||
|
var (
|
||||||
|
FetchBranchFlag = Flag{
|
||||||
|
Name: "branch",
|
||||||
|
ConfigName: "repository.branch",
|
||||||
|
Value: "",
|
||||||
|
Usage: "pass the branch name to be scanned",
|
||||||
|
}
|
||||||
|
FetchCommitFlag = Flag{
|
||||||
|
Name: "commit",
|
||||||
|
ConfigName: "repository.commit",
|
||||||
|
Value: "",
|
||||||
|
Usage: "pass the commit hash to be scanned",
|
||||||
|
}
|
||||||
|
FetchTagFlag = Flag{
|
||||||
|
Name: "tag",
|
||||||
|
ConfigName: "repository.tag",
|
||||||
|
Value: "",
|
||||||
|
Usage: "pass the tag name to be scanned",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
type RepoFlagGroup struct {
|
||||||
|
Branch *Flag
|
||||||
|
Commit *Flag
|
||||||
|
Tag *Flag
|
||||||
|
}
|
||||||
|
|
||||||
|
type RepoOptions struct {
|
||||||
|
RepoBranch string
|
||||||
|
RepoCommit string
|
||||||
|
RepoTag string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRepoFlagGroup() *RepoFlagGroup {
|
||||||
|
return &RepoFlagGroup{
|
||||||
|
Branch: &FetchBranchFlag,
|
||||||
|
Commit: &FetchCommitFlag,
|
||||||
|
Tag: &FetchTagFlag,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *RepoFlagGroup) Name() string {
|
||||||
|
return "Repository"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *RepoFlagGroup) Flags() []*Flag {
|
||||||
|
return []*Flag{f.Branch, f.Commit, f.Tag}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *RepoFlagGroup) ToOptions() RepoOptions {
|
||||||
|
return RepoOptions{
|
||||||
|
RepoBranch: getString(f.Branch),
|
||||||
|
RepoCommit: getString(f.Commit),
|
||||||
|
RepoTag: getString(f.Tag),
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user