mirror of
https://github.com/aquasecurity/trivy.git
synced 2025-12-12 15:50:15 -08:00
refactor: use version-specific URLs for documentation references (#6966)
Signed-off-by: knqyf263 <knqyf263@gmail.com>
This commit is contained in:
@@ -3,6 +3,7 @@ package commands
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"slices"
|
||||
"sort"
|
||||
"strings"
|
||||
@@ -20,6 +21,7 @@ import (
|
||||
"github.com/aquasecurity/trivy/pkg/flag"
|
||||
"github.com/aquasecurity/trivy/pkg/log"
|
||||
"github.com/aquasecurity/trivy/pkg/types"
|
||||
"github.com/aquasecurity/trivy/pkg/version/doc"
|
||||
)
|
||||
|
||||
var allSupportedServicesFunc = awsScanner.AllSupportedServices
|
||||
@@ -140,7 +142,8 @@ func Run(ctx context.Context, opt flag.Options) error {
|
||||
var err error
|
||||
defer func() {
|
||||
if errors.Is(err, context.DeadlineExceeded) {
|
||||
log.Warn("Provide a higher timeout value, see https://aquasecurity.github.io/trivy/latest/docs/configuration/")
|
||||
// e.g. https://aquasecurity.github.io/trivy/latest/docs/configuration/
|
||||
log.WarnContext(ctx, fmt.Sprintf("Provide a higher timeout value, see %s", doc.URL("/docs/configuration/", "")))
|
||||
}
|
||||
}()
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ import (
|
||||
"github.com/spf13/viper"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/aquasecurity/go-version/pkg/semver"
|
||||
"github.com/aquasecurity/trivy-db/pkg/db"
|
||||
tcache "github.com/aquasecurity/trivy/pkg/cache"
|
||||
"github.com/aquasecurity/trivy/pkg/commands/operation"
|
||||
@@ -33,6 +32,7 @@ import (
|
||||
"github.com/aquasecurity/trivy/pkg/scanner"
|
||||
"github.com/aquasecurity/trivy/pkg/types"
|
||||
"github.com/aquasecurity/trivy/pkg/utils/fsutils"
|
||||
"github.com/aquasecurity/trivy/pkg/version/doc"
|
||||
)
|
||||
|
||||
// TargetKind represents what kind of artifact Trivy scans
|
||||
@@ -46,8 +46,6 @@ const (
|
||||
TargetImageArchive TargetKind = "archive"
|
||||
TargetSBOM TargetKind = "sbom"
|
||||
TargetVM TargetKind = "vm"
|
||||
|
||||
devVersion = "dev"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -397,7 +395,8 @@ func Run(ctx context.Context, opts flag.Options, targetKind TargetKind) (err err
|
||||
|
||||
defer func() {
|
||||
if errors.Is(err, context.DeadlineExceeded) {
|
||||
log.Warn("Provide a higher timeout value, see https://aquasecurity.github.io/trivy/latest/docs/configuration/")
|
||||
// e.g. https://aquasecurity.github.io/trivy/latest/docs/configuration/
|
||||
log.WarnContext(ctx, fmt.Sprintf("Provide a higher timeout value, see %s", doc.URL("/docs/configuration/", "")))
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -593,10 +592,10 @@ func initScannerConfig(opts flag.Options, cacheClient cache.Cache) (ScannerConfi
|
||||
|
||||
// Do not load config file for secret scanning
|
||||
if opts.Scanners.Enabled(types.SecretScanner) {
|
||||
ver := canonicalVersion(opts.AppVersion)
|
||||
log.Info("Secret scanning is enabled")
|
||||
log.Info("If your scanning is slow, please try '--scanners vuln' to disable secret scanning")
|
||||
log.Infof("Please see also https://aquasecurity.github.io/trivy/%s/docs/scanner/secret/#recommendation for faster secret detection", ver)
|
||||
// e.g. https://aquasecurity.github.io/trivy/latest/docs/scanner/secret/#recommendation
|
||||
log.Infof("Please see also %s for faster secret detection", doc.URL("/docs/scanner/secret/", "recommendation"))
|
||||
} else {
|
||||
opts.SecretConfigPath = ""
|
||||
}
|
||||
@@ -694,20 +693,3 @@ func scan(ctx context.Context, opts flag.Options, initializeScanner InitializeSc
|
||||
}
|
||||
return report, nil
|
||||
}
|
||||
|
||||
func canonicalVersion(ver string) string {
|
||||
if ver == devVersion {
|
||||
return ver
|
||||
}
|
||||
v, err := semver.Parse(ver)
|
||||
if err != nil {
|
||||
return devVersion
|
||||
}
|
||||
// Replace pre-release with "dev"
|
||||
// e.g. v0.34.0-beta1+snapshot-1
|
||||
if v.IsPreRelease() || v.Metadata() != "" {
|
||||
return devVersion
|
||||
}
|
||||
// Add "v" prefix and cut a patch number, "0.34.0" => "v0.34" for the url
|
||||
return fmt.Sprintf("v%d.%d", v.Major(), v.Minor())
|
||||
}
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
package artifact
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestCanonicalVersion(t *testing.T) {
|
||||
tests := []struct {
|
||||
title string
|
||||
input string
|
||||
want string
|
||||
}{
|
||||
{
|
||||
title: "good way",
|
||||
input: "0.34.0",
|
||||
want: "v0.34",
|
||||
},
|
||||
{
|
||||
title: "version with v - isn't right semver version",
|
||||
input: "v0.34.0",
|
||||
want: devVersion,
|
||||
},
|
||||
{
|
||||
title: "dev version",
|
||||
input: devVersion,
|
||||
want: devVersion,
|
||||
},
|
||||
{
|
||||
title: "pre-release",
|
||||
input: "v0.34.0-beta1+snapshot-1",
|
||||
want: devVersion,
|
||||
},
|
||||
{
|
||||
title: "no version",
|
||||
input: "",
|
||||
want: devVersion,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.title, func(t *testing.T) {
|
||||
got := canonicalVersion(test.input)
|
||||
require.Equal(t, test.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@ import (
|
||||
"github.com/aquasecurity/trivy/pkg/fanal/types"
|
||||
"github.com/aquasecurity/trivy/pkg/log"
|
||||
"github.com/aquasecurity/trivy/pkg/oci"
|
||||
"github.com/aquasecurity/trivy/pkg/version/doc"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -188,7 +189,8 @@ func (c *Client) initOCIArtifact(opt types.RegistryOptions) (*oci.Artifact, erro
|
||||
for _, diagnostic := range terr.Errors {
|
||||
// For better user experience
|
||||
if diagnostic.Code == transport.DeniedErrorCode || diagnostic.Code == transport.UnauthorizedErrorCode {
|
||||
log.Warn("See https://aquasecurity.github.io/trivy/latest/docs/references/troubleshooting/#db")
|
||||
// e.g. https://aquasecurity.github.io/trivy/latest/docs/references/troubleshooting/#db
|
||||
log.Warnf("See %s", doc.URL("/docs/references/troubleshooting/", "db"))
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package commands
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
"golang.org/x/xerrors"
|
||||
@@ -18,6 +19,7 @@ import (
|
||||
"github.com/aquasecurity/trivy/pkg/k8s/scanner"
|
||||
"github.com/aquasecurity/trivy/pkg/log"
|
||||
"github.com/aquasecurity/trivy/pkg/types"
|
||||
"github.com/aquasecurity/trivy/pkg/version/doc"
|
||||
)
|
||||
|
||||
// Run runs a k8s scan
|
||||
@@ -39,7 +41,8 @@ func Run(ctx context.Context, args []string, opts flag.Options) error {
|
||||
defer func() {
|
||||
cancel()
|
||||
if errors.Is(err, context.DeadlineExceeded) {
|
||||
log.WarnContext(ctx, "Provide a higher timeout value, see https://aquasecurity.github.io/trivy/latest/docs/configuration/")
|
||||
// e.g. https://aquasecurity.github.io/trivy/latest/docs/configuration
|
||||
log.WarnContext(ctx, fmt.Sprintf("Provide a higher timeout value, see %s", doc.URL("/docs/configuration/", "")))
|
||||
}
|
||||
}()
|
||||
opts.K8sVersion = cluster.GetClusterVersion()
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package app
|
||||
|
||||
var (
|
||||
ver = "dev"
|
||||
)
|
||||
var ver = "dev"
|
||||
|
||||
func Version() string {
|
||||
return ver
|
||||
|
||||
49
pkg/version/doc/doc.go
Normal file
49
pkg/version/doc/doc.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package doc
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/aquasecurity/go-version/pkg/semver"
|
||||
"github.com/aquasecurity/trivy/pkg/version/app"
|
||||
)
|
||||
|
||||
const devVersion = "dev"
|
||||
|
||||
// BaseURL returns the base URL for the versioned documentation
|
||||
func BaseURL(ver string) *url.URL {
|
||||
ver = canonicalVersion(ver)
|
||||
return &url.URL{
|
||||
Scheme: "https",
|
||||
Host: "aquasecurity.github.io",
|
||||
Path: path.Join("trivy", ver),
|
||||
}
|
||||
}
|
||||
|
||||
// URL returns the URL for the versioned documentation with the given path
|
||||
func URL(rawPath, fragment string) string {
|
||||
base := BaseURL(app.Version())
|
||||
base.Path = path.Join(base.Path, rawPath)
|
||||
base.Fragment = fragment
|
||||
return base.String()
|
||||
}
|
||||
|
||||
func canonicalVersion(ver string) string {
|
||||
if ver == devVersion {
|
||||
return ver
|
||||
}
|
||||
ver = strings.TrimPrefix(ver, "v")
|
||||
v, err := semver.Parse(ver)
|
||||
if err != nil {
|
||||
return devVersion
|
||||
}
|
||||
// Replace pre-release with "dev"
|
||||
// e.g. v0.34.0-beta1+snapshot-1
|
||||
if v.IsPreRelease() || v.Metadata() != "" {
|
||||
return devVersion
|
||||
}
|
||||
// Add "v" prefix and cut a patch number, "0.34.0" => "v0.34" for the URL
|
||||
return fmt.Sprintf("v%d.%d", v.Major(), v.Minor())
|
||||
}
|
||||
96
pkg/version/doc/doc_test.go
Normal file
96
pkg/version/doc/doc_test.go
Normal file
@@ -0,0 +1,96 @@
|
||||
package doc_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/aquasecurity/trivy/pkg/version/doc"
|
||||
)
|
||||
|
||||
func TestBaseURL(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
ver string
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "dev",
|
||||
ver: "dev",
|
||||
want: "https://aquasecurity.github.io/trivy/dev",
|
||||
},
|
||||
{
|
||||
name: "semver",
|
||||
ver: "0.52.0",
|
||||
want: "https://aquasecurity.github.io/trivy/v0.52",
|
||||
},
|
||||
{
|
||||
name: "with v prefix",
|
||||
ver: "v0.52.0",
|
||||
want: "https://aquasecurity.github.io/trivy/v0.52",
|
||||
},
|
||||
{
|
||||
name: "pre-release",
|
||||
ver: "0.52.0-beta1",
|
||||
want: "https://aquasecurity.github.io/trivy/dev",
|
||||
},
|
||||
{
|
||||
name: "non-semver",
|
||||
ver: "1",
|
||||
want: "https://aquasecurity.github.io/trivy/dev",
|
||||
},
|
||||
{
|
||||
name: "empty",
|
||||
ver: "",
|
||||
want: "https://aquasecurity.github.io/trivy/dev",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := doc.BaseURL(tt.ver)
|
||||
require.Equal(t, tt.want, got.String())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestURL(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
rawPath string
|
||||
fragment string
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "path without slash",
|
||||
rawPath: "foo",
|
||||
want: "https://aquasecurity.github.io/trivy/dev/foo",
|
||||
},
|
||||
{
|
||||
name: "path with leading slash",
|
||||
rawPath: "/foo",
|
||||
want: "https://aquasecurity.github.io/trivy/dev/foo",
|
||||
},
|
||||
{
|
||||
name: "path with slash",
|
||||
rawPath: "foo/bar",
|
||||
want: "https://aquasecurity.github.io/trivy/dev/foo/bar",
|
||||
},
|
||||
{
|
||||
name: "path with fragment",
|
||||
rawPath: "foo",
|
||||
fragment: "bar",
|
||||
want: "https://aquasecurity.github.io/trivy/dev/foo#bar",
|
||||
},
|
||||
{
|
||||
name: "empty",
|
||||
rawPath: "",
|
||||
want: "https://aquasecurity.github.io/trivy/dev",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := doc.URL(tt.rawPath, tt.fragment)
|
||||
require.Equal(t, tt.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"github.com/aquasecurity/trivy-db/pkg/vulnsrc/vulnerability"
|
||||
"github.com/aquasecurity/trivy/pkg/log"
|
||||
"github.com/aquasecurity/trivy/pkg/types"
|
||||
"github.com/aquasecurity/trivy/pkg/version/doc"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -51,7 +52,8 @@ var SuperSet = wire.NewSet(
|
||||
// Show warning if we use severity from another vendor
|
||||
// cf. https://github.com/aquasecurity/trivy/issues/6714
|
||||
var onceWarn = sync.OnceFunc(func() {
|
||||
log.Warn("Using severities from other vendors for some vulnerabilities. Read https://aquasecurity.github.io/trivy/latest/docs/scanner/vulnerability/#severity-selection for details.")
|
||||
// e.g. https://aquasecurity.github.io/trivy/latest/docs/scanner/vulnerability/#severity-selection
|
||||
log.Warnf("Using severities from other vendors for some vulnerabilities. Read %s for details.", doc.URL("/docs/scanner/vulnerability/", "severity-selection"))
|
||||
})
|
||||
|
||||
// Client manipulates vulnerabilities
|
||||
|
||||
Reference in New Issue
Block a user