diff --git a/action/package-lock.json b/action/package-lock.json index 27093ac26..d778c2293 100644 --- a/action/package-lock.json +++ b/action/package-lock.json @@ -159,6 +159,21 @@ "url": "https://opencollective.com/babel" } }, + "node_modules/@babel/core/node_modules/semver": { + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", + "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@babel/generator": { "version": "7.20.0", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.0.tgz", @@ -5549,7 +5564,18 @@ "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.1", - "semver": "^6.3.0" + "semver": "^7.5.2" + }, + "dependencies": { + "semver": { + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", + "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } } }, "@babel/generator": { diff --git a/commands/commands.go b/commands/commands.go index 938772029..a451da12c 100644 --- a/commands/commands.go +++ b/commands/commands.go @@ -1,11 +1,15 @@ package commands import ( + "errors" "fmt" "github.com/jfrog/frogbot/commands/utils" "github.com/jfrog/froggit-go/vcsclient" + "github.com/jfrog/jfrog-cli-core/v2/utils/coreutils" + "github.com/jfrog/jfrog-client-go/utils/io/fileutils" "github.com/jfrog/jfrog-client-go/utils/log" clitool "github.com/urfave/cli/v2" + "os" ) type FrogbotCommand interface { @@ -13,28 +17,47 @@ type FrogbotCommand interface { Run(config utils.RepoAggregator, client vcsclient.VcsClient) error } -func Exec(command FrogbotCommand, name string) error { - // Get frogbotUtils the contains the config, server and VCS client +func Exec(command FrogbotCommand, name string) (err error) { + // Get frogbotUtils that contains the config, server, and VCS client log.Info("Frogbot version:", utils.FrogbotVersion) frogbotUtils, err := utils.GetFrogbotUtils() if err != nil { return err } - // Download extractors if the jfrog releases repo environment variable is set - releasesRepo := frogbotUtils.Repositories[0].JfrogReleasesRepo - if err = utils.DownloadExtractorsFromRemoteIfNeeded(frogbotUtils.ServerDetails, "", releasesRepo); err != nil { + + // Build the server configuration file + originalJfrogHomeDir, tempJFrogHomeDir, err := utils.BuildServerConfigFile(frogbotUtils.ServerDetails) + if err != nil { return err } + defer func() { + err = errors.Join(err, os.Setenv(utils.JfrogHomeDirEnv, originalJfrogHomeDir), fileutils.RemoveTempDir(tempJFrogHomeDir)) + }() + + // Set releases remote repository env if needed + previousReleasesRepoEnv := os.Getenv(coreutils.ReleasesRemoteEnv) + if frogbotUtils.ReleasesRepo != "" { + if err = os.Setenv(coreutils.ReleasesRemoteEnv, fmt.Sprintf("frogbot/%s", frogbotUtils.ReleasesRepo)); err != nil { + return + } + defer func() { + err = errors.Join(err, os.Setenv(coreutils.ReleasesRemoteEnv, previousReleasesRepoEnv)) + }() + } + // Send a usage report usageReportSent := make(chan error) go utils.ReportUsage(name, frogbotUtils.ServerDetails, usageReportSent) + // Invoke the command interface log.Info(fmt.Sprintf("Running Frogbot %q command", name)) err = command.Run(frogbotUtils.Repositories, frogbotUtils.Client) + // Wait for a signal, letting us know that the usage reporting is done. <-usageReportSent + if err == nil { - log.Info(fmt.Sprintf("Frogbot %q command finished successfully ", name)) + log.Info(fmt.Sprintf("Frogbot %q command finished successfully", name)) } return err } diff --git a/commands/createfixpullrequests.go b/commands/createfixpullrequests.go index 2097bfecd..db3f67b4d 100644 --- a/commands/createfixpullrequests.go +++ b/commands/createfixpullrequests.go @@ -62,7 +62,6 @@ func (cfp *CreateFixPullRequestsCmd) scanAndFixRepository(repository *utils.Repo SetXrayGraphScanParams(repository.Watches, repository.JFrogProjectKey). SetFailOnInstallationErrors(*repository.FailOnSecurityIssues). SetBranch(branch). - SetReleasesRepo(repository.JfrogReleasesRepo). SetFixableOnly(repository.FixableOnly). SetMinSeverity(repository.MinSeverity) cfp.aggregateFixes = repository.Git.AggregateFixes diff --git a/commands/scanpullrequest.go b/commands/scanpullrequest.go index d9133151b..a19b1a88f 100644 --- a/commands/scanpullrequest.go +++ b/commands/scanpullrequest.go @@ -105,7 +105,6 @@ func auditPullRequest(repoConfig *utils.Repository, client vcsclient.VcsClient) for i := range repoConfig.Projects { scanDetails := utils.NewScanDetails(client, &repoConfig.Server, &repoConfig.Git). SetProject(&repoConfig.Projects[i]). - SetReleasesRepo(repoConfig.JfrogReleasesRepo). SetXrayGraphScanParams(repoConfig.Watches, repoConfig.JFrogProjectKey). SetMinSeverity(repoConfig.MinSeverity). SetFixableOnly(repoConfig.FixableOnly) @@ -291,8 +290,7 @@ func runInstallAndAudit(scanSetup *utils.ScanDetails, workDirs ...string) (audit SetUseWrapper(*scanSetup.UseWrapper). SetDepsRepo(scanSetup.Repository). SetIgnoreConfigFile(true). - SetServerDetails(scanSetup.ServerDetails). - SetReleasesRepo(scanSetup.ReleasesRepo()) + SetServerDetails(scanSetup.ServerDetails) auditParams := audit.NewAuditParams(). SetXrayGraphScanParams(scanSetup.XrayGraphScanParams). SetWorkingDirs(workDirs). diff --git a/commands/utils/extractors.go b/commands/utils/extractors.go deleted file mode 100644 index 4fd48b047..000000000 --- a/commands/utils/extractors.go +++ /dev/null @@ -1,77 +0,0 @@ -package utils - -import ( - "fmt" - "path/filepath" - - "github.com/jfrog/build-info-go/build" - "github.com/jfrog/jfrog-cli-core/v2/artifactory/utils" - "github.com/jfrog/jfrog-cli-core/v2/utils/config" - "github.com/jfrog/jfrog-cli-core/v2/utils/coreutils" - "github.com/jfrog/jfrog-client-go/utils/io/fileutils" - "github.com/jfrog/jfrog-client-go/utils/log" -) - -var extractorsRepositoryPath = "artifactory/oss-release-local" - -// extractorDetails holds the relevant details to download the build-info extractors. -// Build Info is Artifactory's open integration layer for the CI servers and build tools. -// The build information is sent to Artifactory in json format. -type extractorDetails struct { - extractorType string - localPath string - remotePath string - fileName string -} - -func (ed *extractorDetails) downloadToPath() string { - return filepath.Join(ed.localPath, ed.fileName) -} - -func (ed *extractorDetails) downloadFromPath() string { - return filepath.Join(extractorsRepositoryPath, ed.remotePath, ed.fileName) -} - -// DownloadExtractorsFromRemoteIfNeeded downloads build-info-extractors from a remote repository, if they do not yet exist on the file system. -func DownloadExtractorsFromRemoteIfNeeded(server *config.ServerDetails, extractorsLocalPath, releasesRepo string) (err error) { - if releasesRepo == "" { - return nil - } - log.Info("Checking whether the build-info extractors exist locally") - if extractorsLocalPath == "" { - extractorsLocalPath, err = config.GetJfrogDependenciesPath() - if err != nil { - return - } - } - mavenExtractorLocalPath := filepath.Join(extractorsLocalPath, "maven", build.MavenExtractorDependencyVersion) - mavenExtractor := extractorDetails{ - extractorType: coreutils.Maven.ToString(), - localPath: mavenExtractorLocalPath, - fileName: fmt.Sprintf(build.MavenExtractorFileName, build.MavenExtractorDependencyVersion), - remotePath: fmt.Sprintf(build.MavenExtractorRemotePath, build.MavenExtractorDependencyVersion), - } - return downloadExtractor(releasesRepo, server, mavenExtractor) -} - -func downloadExtractor(remoteRepoName string, server *config.ServerDetails, extractor extractorDetails) (err error) { - var alreadyExist bool - if alreadyExist, err = fileutils.IsDirExists(extractor.localPath, false); alreadyExist { - log.Debug(extractor.extractorType, "extractor already exists, no download required") - return - } - - log.Info("Downloading", extractor.extractorType, "extractor to path:", extractor.localPath) - remoteServer := getRemoteServer(server, remoteRepoName) - return utils.DownloadDependency(remoteServer, extractor.downloadFromPath(), extractor.downloadToPath(), false) -} - -func getRemoteServer(server *config.ServerDetails, remoteName string) *config.ServerDetails { - remoteURL := server.ArtifactoryUrl + remoteName + "/" - return &config.ServerDetails{ - ArtifactoryUrl: remoteURL, - AccessToken: server.AccessToken, - User: server.User, - Password: server.Password, - } -} diff --git a/commands/utils/extractors_test.go b/commands/utils/extractors_test.go deleted file mode 100644 index dc1cf2c84..000000000 --- a/commands/utils/extractors_test.go +++ /dev/null @@ -1,45 +0,0 @@ -package utils - -import ( - "fmt" - "github.com/jfrog/build-info-go/build" - "github.com/jfrog/jfrog-cli-core/v2/utils/config" - "github.com/jfrog/jfrog-client-go/utils/io/fileutils" - "github.com/stretchr/testify/assert" - "net/http" - "net/http/httptest" - "testing" -) - -func TestDownloadExtractorsFromRemoteIfNeeded(t *testing.T) { - serverDetails := &config.ServerDetails{ - AccessToken: "eyJ0eXAiOiJKV1QifQ.eyJzdWIiOiJmYWtlXC91c2Vy2323c1wvdGVzdCJ9.MTIzNDU2Nzg5MA", - } - tmpDir, err := fileutils.CreateTempDir() - assert.NoError(t, err) - restoreDir, err := Chdir(tmpDir) - assert.NoError(t, err) - defer func() { - assert.NoError(t, restoreDir()) - assert.NoError(t, fileutils.RemoveTempDir(tmpDir)) - }() - testServer := httptest.NewServer(createRemoteArtifactoryHandler()) - defer func() { - testServer.Close() - }() - serverDetails.ArtifactoryUrl = testServer.URL + "/artifactory/" - assert.NoError(t, DownloadExtractorsFromRemoteIfNeeded(serverDetails, tmpDir, "remote-repo")) -} - -// Create HTTP handler to mock remote artifactory server -func createRemoteArtifactoryHandler() http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - expectedMavenUri := fmt.Sprintf("/artifactory/remote-repo/artifactory/oss-release-local/%s/%s", - fmt.Sprintf(build.MavenExtractorRemotePath, build.MavenExtractorDependencyVersion), - fmt.Sprintf(build.MavenExtractorFileName, build.MavenExtractorDependencyVersion)) - if r.RequestURI == expectedMavenUri { - w.WriteHeader(http.StatusOK) - return - } - } -} diff --git a/commands/utils/params.go b/commands/utils/params.go index 03f8236c6..8bd174131 100644 --- a/commands/utils/params.go +++ b/commands/utils/params.go @@ -35,6 +35,7 @@ type FrogbotUtils struct { Repositories RepoAggregator ServerDetails *coreconfig.ServerDetails Client vcsclient.VcsClient + ReleasesRepo string } type RepoAggregator []Repository @@ -107,7 +108,6 @@ type Scan struct { FailOnSecurityIssues *bool `yaml:"failOnSecurityIssues,omitempty"` MinSeverity string `yaml:"minSeverity,omitempty"` Projects []Project `yaml:"projects,omitempty"` - JfrogReleasesRepo string } func (s *Scan) setDefaultsIfNeeded() (err error) { @@ -145,7 +145,6 @@ func (s *Scan) setDefaultsIfNeeded() (err error) { return } } - s.JfrogReleasesRepo = getTrimmedEnv(jfrogReleasesRepoEnv) return } @@ -276,7 +275,7 @@ func GetFrogbotUtils() (frogbotUtils *FrogbotUtils, err error) { if err != nil { return nil, err } - return &FrogbotUtils{Repositories: configAggregator, Client: client, ServerDetails: server}, err + return &FrogbotUtils{Repositories: configAggregator, Client: client, ServerDetails: server, ReleasesRepo: os.Getenv(jfrogReleasesRepoEnv)}, err } // getConfigAggregator returns a RepoAggregator based on frogbot-config.yml and environment variables. diff --git a/commands/utils/params_test.go b/commands/utils/params_test.go index fcdae5bae..2920cfb4c 100644 --- a/commands/utils/params_test.go +++ b/commands/utils/params_test.go @@ -198,7 +198,6 @@ func TestBuildRepoAggregatorWithEmptyScan(t *testing.T) { assert.False(t, scan.IncludeAllVulnerabilities) assert.False(t, scan.FixableOnly) assert.Empty(t, scan.MinSeverity) - assert.Empty(t, scan.JfrogReleasesRepo) assert.True(t, *scan.FailOnSecurityIssues) assert.Len(t, scan.Projects, 1) project := scan.Projects[0] diff --git a/commands/utils/scandetails.go b/commands/utils/scandetails.go index b93a73df2..df44a5115 100644 --- a/commands/utils/scandetails.go +++ b/commands/utils/scandetails.go @@ -16,7 +16,6 @@ type ScanDetails struct { fixableOnly bool minSeverityFilter string branch string - releasesRepo string } func NewScanDetails(client vcsclient.VcsClient, server *config.ServerDetails, git *Git) *ScanDetails { @@ -53,11 +52,6 @@ func (sc *ScanDetails) SetBranch(branch string) *ScanDetails { return sc } -func (sc *ScanDetails) SetReleasesRepo(releasesRepo string) *ScanDetails { - sc.releasesRepo = releasesRepo - return sc -} - func (sc *ScanDetails) Client() vcsclient.VcsClient { return sc.client } @@ -66,10 +60,6 @@ func (sc *ScanDetails) Branch() string { return sc.branch } -func (sc *ScanDetails) ReleasesRepo() string { - return sc.releasesRepo -} - func (sc *ScanDetails) FailOnInstallationErrors() bool { return sc.failOnInstallationErrors } diff --git a/commands/utils/utils.go b/commands/utils/utils.go index ce1a993c0..072c29a6d 100644 --- a/commands/utils/utils.go +++ b/commands/utils/utils.go @@ -10,6 +10,7 @@ import ( "github.com/jfrog/froggit-go/vcsutils" "github.com/jfrog/gofrog/version" "github.com/jfrog/jfrog-cli-core/v2/artifactory/utils" + "github.com/jfrog/jfrog-cli-core/v2/common/commands" "github.com/jfrog/jfrog-cli-core/v2/utils/config" "github.com/jfrog/jfrog-cli-core/v2/utils/coreutils" audit "github.com/jfrog/jfrog-cli-core/v2/xray/commands/audit/generic" @@ -37,6 +38,7 @@ const ( skipIndirectVulnerabilitiesMsg = "%s is an indirect dependency that will not be updated to version %s.\nFixing indirect dependencies can introduce conflicts with other dependencies that rely on the previous version.\nFrogbot skips this to avoid potential incompatibilities." skipBuildToolDependencyMsg = "Skipping vulnerable package %s since it is not defined in your package descriptor file. " + "Update %s version to %s to fix this vulnerability." + JfrogHomeDirEnv = "JFROG_CLI_HOME_DIR" ) var ( @@ -272,3 +274,20 @@ func validateBranchName(branchName string) error { } return nil } + +func BuildServerConfigFile(server *config.ServerDetails) (previousJFrogHomeDir, currentJFrogHomeDir string, err error) { + // Create temp dir to store server config inside + currentJFrogHomeDir, err = fileutils.CreateTempDir() + if err != nil { + return + } + // Save current JFrog Home dir + previousJFrogHomeDir = os.Getenv(JfrogHomeDirEnv) + // Set the temp dir as the JFrog Home dir + if err = os.Setenv(JfrogHomeDirEnv, currentJFrogHomeDir); err != nil { + return + } + cc := commands.NewConfigCommand(commands.AddOrEdit, "frogbot").SetDetails(server) + err = cc.Run() + return +} diff --git a/commands/utils/utils_test.go b/commands/utils/utils_test.go index de4482477..14656eb96 100644 --- a/commands/utils/utils_test.go +++ b/commands/utils/utils_test.go @@ -10,6 +10,7 @@ import ( "net/http" "net/http/httptest" "os" + "path" "path/filepath" "strings" "testing" @@ -296,3 +297,45 @@ func TestValidatedBranchName(t *testing.T) { }) } } + +func TestBuildServerConfigFile(t *testing.T) { + preTestJFrogHome := os.Getenv(JfrogHomeDirEnv) + defer func() { + assert.NoError(t, os.Setenv(JfrogHomeDirEnv, preTestJFrogHome)) + }() + assert.NoError(t, os.Setenv(JfrogHomeDirEnv, "path/to/nowhere")) + server := &config.ServerDetails{ + Url: "https://myserver.com", + ArtifactoryUrl: "https://myserver.com/artifactory", + DistributionUrl: "https://myserver.co/distribution", + XrayUrl: "https://myserver.com/xray", + MissionControlUrl: "https://myserver.com/missioncontrol", + PipelinesUrl: "https://myserver.com/pipelines", + AccessUrl: "https://myserver.com/access", + AccessToken: "abcdefg1234", + } + expectedConfigurationFile := + `{ + "servers": [ + { + "url": "https://myserver.com/", + "artifactoryUrl": "https://myserver.com/artifactory/", + "distributionUrl": "https://myserver.co/distribution/", + "xrayUrl": "https://myserver.com/xray/", + "missionControlUrl": "https://myserver.com/missioncontrol/", + "pipelinesUrl": "https://myserver.com/pipelines/", + "accessUrl": "https://myserver.com/access", + "accessToken": "abcdefg1234", + "serverId": "frogbot", + "isDefault": true + } + ], + "version": "6" +}` + previousJFrogHome, currentJFrogHome, err := BuildServerConfigFile(server) + assert.NoError(t, err) + assert.Equal(t, "path/to/nowhere", previousJFrogHome) + actualConfigurationFile, err := os.ReadFile(path.Join(currentJFrogHome, "jfrog-cli.conf.v6")) + assert.NoError(t, err) + assert.Equal(t, expectedConfigurationFile, string(actualConfigurationFile)) +} diff --git a/go.mod b/go.mod index 1b57aba3a..21527b4e0 100644 --- a/go.mod +++ b/go.mod @@ -8,8 +8,8 @@ require ( github.com/jfrog/build-info-go v1.9.6 github.com/jfrog/froggit-go v1.8.1 github.com/jfrog/gofrog v1.3.0 - github.com/jfrog/jfrog-cli-core/v2 v2.37.1 - github.com/jfrog/jfrog-client-go v1.31.0 + github.com/jfrog/jfrog-cli-core/v2 v2.38.0 + github.com/jfrog/jfrog-client-go v1.31.1 github.com/mholt/archiver/v3 v3.5.1 github.com/stretchr/testify v1.8.4 github.com/urfave/cli/v2 v2.25.1 @@ -76,6 +76,7 @@ require ( github.com/pelletier/go-toml/v2 v2.0.6 // indirect github.com/pierrec/lz4/v4 v4.1.2 // indirect github.com/pjbgf/sha1cd v0.3.0 // indirect + github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pkg/term v1.1.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect @@ -113,6 +114,6 @@ require ( gopkg.in/warnings.v0 v0.1.2 // indirect ) -// replace github.com/jfrog/jfrog-cli-core/v2 => github.com/jfrog/jfrog-cli-core/v2 v2.31.1-0.20230626054221-18f70e4c045e +// replace github.com/jfrog/jfrog-cli-core/v2 => github.com/jfrog/jfrog-cli-core/v2 dev // replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go v1.28.1-0.20230611131847-a3b84a9004c3 diff --git a/go.sum b/go.sum index 8167fc5d1..075a47bab 100644 --- a/go.sum +++ b/go.sum @@ -224,10 +224,10 @@ github.com/jfrog/froggit-go v1.8.1 h1:3eT1gQ7/Snft181Ig7EZlZSaXlr++tskdxgoCJKmAm github.com/jfrog/froggit-go v1.8.1/go.mod h1:XTFf4RqWwZsF9pdERt0Ra5gO1O3iqIq7Npx2tEQSGAQ= github.com/jfrog/gofrog v1.3.0 h1:o4zgsBZE4QyDbz2M7D4K6fXPTBJht+8lE87mS9bw7Gk= github.com/jfrog/gofrog v1.3.0/go.mod h1:IFMc+V/yf7rA5WZ74CSbXe+Lgf0iApEQLxRZVzKRUR0= -github.com/jfrog/jfrog-cli-core/v2 v2.37.1 h1:VE/6cagGor/5lWB7l+aU5FlhztoHM9q9M2FlWcn3ESo= -github.com/jfrog/jfrog-cli-core/v2 v2.37.1/go.mod h1:i62WcX9jQbH0dJjQdkmJAGridZgFVIK1B3yIPfXayHI= -github.com/jfrog/jfrog-client-go v1.31.0 h1:VIptdPkECaM0UDbKE2ZjFZh9i85W99xM65c6rFxDNj4= -github.com/jfrog/jfrog-client-go v1.31.0/go.mod h1:qEJxoe68sUtqHJ1YhXv/7pKYP/9p1D5tJrruzJKYeoI= +github.com/jfrog/jfrog-cli-core/v2 v2.38.0 h1:lHylMjp0+IbZAUKVWi++keVktpyvI/0UwewIdbCoI/A= +github.com/jfrog/jfrog-cli-core/v2 v2.38.0/go.mod h1:Ws5UvSUITSZGuVVNNb/lDFPG0UAyiwpKv5o86M8By9I= +github.com/jfrog/jfrog-client-go v1.31.1 h1:lmunA5ZpRsrWTXgEGvnvVPIfwEqB3gn6+eVNpV2VBzU= +github.com/jfrog/jfrog-client-go v1.31.1/go.mod h1:qEJxoe68sUtqHJ1YhXv/7pKYP/9p1D5tJrruzJKYeoI= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= @@ -299,6 +299,8 @@ github.com/pierrec/lz4/v4 v4.1.2 h1:qvY3YFXRQE/XB8MlLzJH7mSzBs74eA2gg52YTk6jUPM= github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= +github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= +github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.6.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18= @@ -553,6 +555,7 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=