From 01cb5bc0df991af80ad871d06dad6a4ea6148cc8 Mon Sep 17 00:00:00 2001 From: Shirley Leu Date: Tue, 9 Feb 2021 16:08:27 +0100 Subject: [PATCH 001/142] Improve error message 'not in workspace' for MacOS (#968) * Improve error message 'not in workspace' for MacOS Default installation of MacOS allows user to change directory insensitive of case. This commit wraps a supplemental error message for Mac users, including prints of the workspace and submit path. * go fmt * Update go version in travis.yml Authored-by: Shirley Leu --- .travis.yml | 3 +-- go.mod | 2 ++ workspace/workspace.go | 9 ++++++++- workspace/workspace_darwin_test.go | 25 +++++++++++++++++++++++++ 4 files changed, 36 insertions(+), 3 deletions(-) create mode 100644 workspace/workspace_darwin_test.go diff --git a/.travis.yml b/.travis.yml index a30fc6eca..a195a1099 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,8 +3,7 @@ language: go sudo: false go: - - "1.11.x" - - "1.12.x" + - "1.15.x" - tip matrix: diff --git a/go.mod b/go.mod index c0d986d0f..a3723bfad 100644 --- a/go.mod +++ b/go.mod @@ -1,5 +1,7 @@ module github.com/exercism/cli +go 1.15 + require ( github.com/blang/semver v3.5.1+incompatible github.com/davecgh/go-spew v1.1.0 diff --git a/workspace/workspace.go b/workspace/workspace.go index 71036f511..eb9875e8a 100644 --- a/workspace/workspace.go +++ b/workspace/workspace.go @@ -2,9 +2,11 @@ package workspace import ( "errors" + "fmt" "io/ioutil" "os" "path/filepath" + "runtime" "strings" ) @@ -121,7 +123,12 @@ func (ws Workspace) Exercises() ([]Exercise, error) { // This is the directory that contains the exercise metadata file. func (ws Workspace) ExerciseDir(s string) (string, error) { if !strings.HasPrefix(s, ws.Dir) { - return "", errors.New("not in workspace") + var err = fmt.Errorf("not in workspace") + if runtime.GOOS == "darwin" { + err = fmt.Errorf("%w: directory location may be case sensitive: workspace directory: %s, "+ + "submit path: %s", err, ws.Dir, s) + } + return "", err } path := s diff --git a/workspace/workspace_darwin_test.go b/workspace/workspace_darwin_test.go new file mode 100644 index 000000000..03794a795 --- /dev/null +++ b/workspace/workspace_darwin_test.go @@ -0,0 +1,25 @@ +package workspace + +import ( + "fmt" + "github.com/stretchr/testify/assert" + "path/filepath" + "runtime" + "strings" + "testing" +) + +func TestExerciseDir_case_insensitive(t *testing.T) { + _, cwd, _, _ := runtime.Caller(0) + root := filepath.Join(cwd, "..", "..", "fixtures", "solution-dir") + // configuration file was set with "workspace" - the directory that exists + configured := Workspace{Dir: filepath.Join(root, "workspace")} + // user changes into directory with "bad" case - "Workspace" + userPath := strings.Replace(configured.Dir, "workspace", "Workspace", 1) + + _, err := configured.ExerciseDir(filepath.Join(userPath, "exercise", "file.txt")) + + assert.Error(t, err) + assert.Equal(t, fmt.Sprintf("not in workspace: directory location may be case sensitive: "+ + "workspace directory: %s, submit path: %s/exercise/file.txt", configured.Dir, userPath), err.Error()) +} From aa9dcfaa6ba43a69e10a3792af43f9f313f4284a Mon Sep 17 00:00:00 2001 From: Eric Kingery Date: Tue, 9 Feb 2021 09:55:04 -0600 Subject: [PATCH 002/142] Allow read-write access to configuration and download directories when installed as a Snap (#980) * Allow read-write access to configuration and download directories. We need write access to the $HOME/.config/exercism/ directory for `exercism config` and $HOME/exercism is the default download directory so we need write access there as well. This should resolve issue #945 * Permit writes to any files in user's home directory Authored-by: Richard Neish --- .goreleaser.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index 564944e1a..19fb72b2a 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -97,4 +97,8 @@ snapcrafts: 386: i386 apps: exercism: - plugs: ["home", "network", "removable-media"] + plugs: ["home", "network", "removable-media","personal-files"] + plugs: + personal-files: + write: + - $HOME/ From ce8f497d2439a8094ee39e15aa72d5d62a54c759 Mon Sep 17 00:00:00 2001 From: Ali A <1076+haguro@users.noreply.github.com> Date: Wed, 10 Feb 2021 03:45:17 +1100 Subject: [PATCH 003/142] Protect existing solutions from being overwritten by 'download' (#979) Add an optional `--force` flag to the download command to overwrite an existing exercise directory. --- cmd/download.go | 14 +++++- cmd/download_test.go | 102 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+), 2 deletions(-) diff --git a/cmd/download.go b/cmd/download.go index e4c19377b..7bf278bff 100644 --- a/cmd/download.go +++ b/cmd/download.go @@ -64,6 +64,10 @@ func runDownload(cfg config.Config, flags *pflag.FlagSet, args []string) error { metadata := download.payload.metadata() dir := metadata.Exercise(usrCfg.GetString("workspace")).MetadataDir() + if _, err = os.Stat(dir); !download.forceoverwrite && err == nil { + return fmt.Errorf("directory '%s' already exists, use --force to overwrite", dir) + } + if err := os.MkdirAll(dir, os.FileMode(0755)); err != nil { return err } @@ -103,7 +107,6 @@ func runDownload(cfg config.Config, flags *pflag.FlagSet, args []string) error { continue } - // TODO: handle collisions path := sf.relativePath() dir := filepath.Join(metadata.Dir, filepath.Dir(path)) if err = os.MkdirAll(dir, os.FileMode(0755)); err != nil { @@ -133,7 +136,8 @@ type download struct { token, apibaseurl, workspace string // optional - track, team string + track, team string + forceoverwrite bool payload *downloadPayload } @@ -158,6 +162,11 @@ func newDownload(flags *pflag.FlagSet, usrCfg *viper.Viper) (*download, error) { return nil, err } + d.forceoverwrite, err = flags.GetBool("force") + if err != nil { + return nil, err + } + d.token = usrCfg.GetString("token") d.apibaseurl = usrCfg.GetString("apibaseurl") d.workspace = usrCfg.GetString("workspace") @@ -354,6 +363,7 @@ func setupDownloadFlags(flags *pflag.FlagSet) { flags.StringP("track", "t", "", "the track ID") flags.StringP("exercise", "e", "", "the exercise slug") flags.StringP("team", "T", "", "the team slug") + flags.BoolP("force", "F", false, "overwrite existing exercise directory") } func init() { diff --git a/cmd/download_test.go b/cmd/download_test.go index 2eb0418df..676d90518 100644 --- a/cmd/download_test.go +++ b/cmd/download_test.go @@ -209,6 +209,108 @@ func TestDownload(t *testing.T) { } } +func TestDownloadToExistingDirectory(t *testing.T) { + co := newCapturedOutput() + co.override() + defer co.reset() + + testCases := []struct { + exerciseDir string + flags map[string]string + }{ + { + exerciseDir: filepath.Join("bogus-track", "bogus-exercise"), + flags: map[string]string{"exercise": "bogus-exercise", "track": "bogus-track"}, + }, + { + exerciseDir: filepath.Join("teams", "bogus-team", "bogus-track", "bogus-exercise"), + flags: map[string]string{"exercise": "bogus-exercise", "track": "bogus-track", "team": "bogus-team"}, + }, + } + + for _, tc := range testCases { + tmpDir, err := ioutil.TempDir("", "download-cmd") + defer os.RemoveAll(tmpDir) + assert.NoError(t, err) + + err = os.MkdirAll(filepath.Join(tmpDir, tc.exerciseDir), os.FileMode(0755)) + assert.NoError(t, err) + + ts := fakeDownloadServer("true", "") + defer ts.Close() + + v := viper.New() + v.Set("workspace", tmpDir) + v.Set("apibaseurl", ts.URL) + v.Set("token", "abc123") + + cfg := config.Config{ + UserViperConfig: v, + } + flags := pflag.NewFlagSet("fake", pflag.PanicOnError) + setupDownloadFlags(flags) + for name, value := range tc.flags { + flags.Set(name, value) + } + + err = runDownload(cfg, flags, []string{}) + + if assert.Error(t, err) { + assert.Regexp(t, "directory '.+' already exists", err.Error()) + } + } +} + +func TestDownloadToExistingDirectoryWithForce(t *testing.T) { + co := newCapturedOutput() + co.override() + defer co.reset() + + testCases := []struct { + exerciseDir string + flags map[string]string + }{ + { + exerciseDir: filepath.Join("bogus-track", "bogus-exercise"), + flags: map[string]string{"exercise": "bogus-exercise", "track": "bogus-track"}, + }, + { + exerciseDir: filepath.Join("teams", "bogus-team", "bogus-track", "bogus-exercise"), + flags: map[string]string{"exercise": "bogus-exercise", "track": "bogus-track", "team": "bogus-team"}, + }, + } + + for _, tc := range testCases { + tmpDir, err := ioutil.TempDir("", "download-cmd") + defer os.RemoveAll(tmpDir) + assert.NoError(t, err) + + err = os.MkdirAll(filepath.Join(tmpDir, tc.exerciseDir), os.FileMode(0755)) + assert.NoError(t, err) + + ts := fakeDownloadServer("true", "") + defer ts.Close() + + v := viper.New() + v.Set("workspace", tmpDir) + v.Set("apibaseurl", ts.URL) + v.Set("token", "abc123") + + cfg := config.Config{ + UserViperConfig: v, + } + flags := pflag.NewFlagSet("fake", pflag.PanicOnError) + setupDownloadFlags(flags) + for name, value := range tc.flags { + flags.Set(name, value) + } + flags.Set("force", "true") + + err = runDownload(cfg, flags, []string{}) + assert.NoError(t, err) + } +} + func fakeDownloadServer(requestor, teamSlug string) *httptest.Server { mux := http.NewServeMux() server := httptest.NewServer(mux) From 09344267e352fd90b2be07f7f665b8f1502bf733 Mon Sep 17 00:00:00 2001 From: Ali A <1076+haguro@users.noreply.github.com> Date: Sun, 14 Feb 2021 10:20:29 +1100 Subject: [PATCH 004/142] Check if authorisation header is set before attempting to extract token (#981) * Check if authorisation header is set before attempting to extract token * Add unit tests for debug.DumpRequest and debug.DumpResponse. --- debug/debug.go | 8 ++--- debug/debug_test.go | 71 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 4 deletions(-) diff --git a/debug/debug.go b/debug/debug.go index dad0b629c..133681439 100644 --- a/debug/debug.go +++ b/debug/debug.go @@ -44,10 +44,10 @@ func DumpRequest(req *http.Request) { body := io.TeeReader(req.Body, &bodyCopy) req.Body = ioutil.NopCloser(body) - temp := req.Header.Get("Authorization") + authHeader := req.Header.Get("Authorization") - if !UnmaskAPIKey { - if token := strings.Split(temp, " ")[1]; token != "" { + if authParts := strings.Split(authHeader, " "); len(authParts) > 1 && !UnmaskAPIKey { + if token := authParts[1]; token != "" { req.Header.Set("Authorization", "Bearer "+Redact(token)) } } @@ -62,7 +62,7 @@ func DumpRequest(req *http.Request) { Println("========================= END DumpRequest =========================") Println("") - req.Header.Set("Authorization", temp) + req.Header.Set("Authorization", authHeader) req.Body = ioutil.NopCloser(&bodyCopy) } diff --git a/debug/debug_test.go b/debug/debug_test.go index 8bbe3a857..f9be5f864 100644 --- a/debug/debug_test.go +++ b/debug/debug_test.go @@ -2,6 +2,7 @@ package debug import ( "bytes" + "net/http" "testing" "github.com/stretchr/testify/assert" @@ -29,6 +30,76 @@ func TestVerboseDisabled(t *testing.T) { } } +func TestDumpRequest(t *testing.T) { + testCases := []struct { + desc string + auth string + verbose bool + unmask bool + }{ + { + desc: "Do not attempt to dump request if 'Verbose' is set to false", + auth: "", + verbose: false, + unmask: false, + }, + { + desc: "Dump request without authorization header", + auth: "", //not set + verbose: true, + unmask: false, + }, + { + desc: "Dump request with malformed 'Authorization' header", + auth: "malformed", + verbose: true, + unmask: true, + }, + { + desc: "Dump request with properly formed 'Authorization' header", + auth: "Bearer abc12-345abcde1234-5abc12", + verbose: true, + unmask: false, + }, + } + + b := &bytes.Buffer{} + output = b + for _, tc := range testCases { + Verbose = tc.verbose + UnmaskAPIKey = tc.unmask + r, _ := http.NewRequest("GET", "https://api.example.com/bogus", nil) + if tc.auth != "" { + r.Header.Set("Authorization", tc.auth) + } + + DumpRequest(r) + if tc.verbose { + assert.Regexp(t, "GET /bogus", b.String(), tc.desc) + assert.Equal(t, tc.auth, r.Header.Get("Authorization"), tc.desc) + if tc.unmask { + assert.Regexp(t, "Authorization: "+tc.auth, b.String(), tc.desc) + } + } else { + assert.NotRegexp(t, "GET /bogus", b.String(), tc.desc) + } + } +} + +func TestDumpResponse(t *testing.T) { + b := &bytes.Buffer{} + output = b + Verbose = true + r := &http.Response{ + StatusCode: 200, + ProtoMajor: 1, + ProtoMinor: 1, + } + + DumpResponse(r) + assert.Regexp(t, "HTTP/1.1 200 OK", b.String()) +} + func TestRedact(t *testing.T) { fakeToken := "1a11111aaaa111aa1a11111a11111aa1" expected := "1a11*************************aa1" From 7cc4e6cda6a85e355520dbe81f2291f2ccbf36b1 Mon Sep 17 00:00:00 2001 From: Stig Johan Berggren Date: Tue, 16 Mar 2021 13:07:48 +0100 Subject: [PATCH 005/142] Fix instructions for completion in Oh My Zsh (#881) * Fix instructions for completion in Oh My Zsh * Use the $ZSH_CUSTOM environment variable * Apply suggestions * Updated link to OMZ repository * title case in section title --- shell/README.md | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/shell/README.md b/shell/README.md index b4c1509ce..beee3c47a 100644 --- a/shell/README.md +++ b/shell/README.md @@ -30,9 +30,22 @@ and then add the directory to your `$fpath` in your `.zshrc`, `.zsh_profile` or autoload -U compinit && compinit -#### Oh my Zsh +#### Oh My Zsh -If you are using the popular [oh-my-zsh](https://github.com/robbyrussell/oh-my-zsh) framework to manage your zsh plugins, move the file `exercism_completion.zsh` into `~/.oh-my-zsh/custom`. +If you are using the popular [Oh My Zsh][oh-my-zsh] framework to manage your +zsh plugins, you need to move the file `exercism_completion.zsh` to a new +custom plugin: + +[oh-my-zsh]: https://github.com/ohmyzsh/ohmyzsh + + mkdir -p $ZSH_CUSTOM/plugins/exercism + cp exercism_completion.zsh $ZSH_CUSTOM/plugins/exercism/_exercism + +Then edit the file `~/.zshrc` to include `exercism` in the list of plugins. +Completions will be activated the next time you open a new shell. If the +completions do not work, you should update Oh My Zsh to the latest version with +`omz update`. Oh My Zsh now checks whether the plugin list has changed (more +accurately, `$fpath`) and resets the `zcompdump` file. ### Fish From 6d5db1597b0938b6a730d1e023a30a800328ba0d Mon Sep 17 00:00:00 2001 From: Eric Kingery Date: Mon, 17 May 2021 09:09:04 -0500 Subject: [PATCH 006/142] Fixed broken link to release documentation (#993) --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index df85ab2cf..cf13f1181 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -50,4 +50,4 @@ On Windows: - `testercism.exe —h` ### Releasing a new CLI version -Consult the [release documentation](https://github.com/exercism/cli/master/RELEASE.md). +Consult the [release documentation](RELEASE.md). From 6d398de33519fe3b5981432af06ad9f17c25839f Mon Sep 17 00:00:00 2001 From: Exercism Bot <66069679+exercism-bot@users.noreply.github.com> Date: Tue, 6 Jul 2021 12:19:19 +0100 Subject: [PATCH 007/142] =?UTF-8?q?=F0=9F=A4=96=20Sync=20org-wide=20files?= =?UTF-8?q?=20to=20upstream=20repo=20(#999)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit More info: https://github.com/exercism/org-wide-files/commit/53f167009e30c254dcf27cfd60a86c912088e36f --- .github/labels.yml | 140 ++++++++++++++++++++++++++++++ .github/workflows/sync-labels.yml | 21 +++++ 2 files changed, 161 insertions(+) create mode 100644 .github/labels.yml create mode 100644 .github/workflows/sync-labels.yml diff --git a/.github/labels.yml b/.github/labels.yml new file mode 100644 index 000000000..1e684c04d --- /dev/null +++ b/.github/labels.yml @@ -0,0 +1,140 @@ +# --------------------------------------------------------------- # +# This is an auto-generated file - Do not manually edit this file # +# --------------------------------------------------------------- # + +# This file is automatically generated by concatenating two files: +# +# 1. The Exercism-wide labels: defined in https://github.com/exercism/org-wide-files/blob/main/global-files/.github/labels.yml +# 2. The repository-specific labels: defined in the `.appends/.github/labels.yml` file within this repository. +# +# If any of these two files change, a pull request is automatically containing a re-generated version of this file. +# Consequently, to change repository-specific labels you should update the `.appends/.github/labels.yml` file and _not_ this file. +# +# When the pull request has been merged, the GitHub labels will be automatically updated by the "Sync labels" workflow. +# This typically takes 5-10 minutes. + +# --------------------------------------------------------------------- # +# These are the Exercism-wide labels which are shared across all repos. # +# --------------------------------------------------------------------- # + +# The following Exercism-wide labels are used to show "tasks" on the website, which will point users to things they can help contribute with. + +# The `x:action/` labels describe what sort of work the contributor will be engaged in when working on the issue +- name: "x:action/create" + description: "Work on something from scratch" + color: "6f60d2" + +- name: "x:action/fix" + description: "Fix an issue" + color: "6f60d2" + +- name: "x:action/improve" + description: "Improve existing functionality/content" + color: "6f60d2" + +- name: "x:action/proofread" + description: "Proofread text" + color: "6f60d2" + +- name: "x:action/sync" + description: "Sync content with its latest version" + color: "6f60d2" + +# The `x:knowledge/` labels describe how much Exercism knowledge is required by the contributor +- name: "x:knowledge/none" + description: "No existing Exercism knowledge required" + color: "604fcd" + +- name: "x:knowledge/elementary" + description: "Little Exercism knowledge required" + color: "604fcd" + +- name: "x:knowledge/intermediate" + description: "Quite a bit of Exercism knowledge required" + color: "604fcd" + +- name: "x:knowledge/advanced" + description: "Comprehensive Exercism knowledge required" + color: "604fcd" + +# The `x:module/` labels indicate what part of Exercism the contributor will be working on +- name: "x:module/analyzer" + description: "Work on Analyzers" + color: "5240c9" + +- name: "x:module/concept" + description: "Work on Concepts" + color: "5240c9" + +- name: "x:module/concept-exercise" + description: "Work on Concept Exercises" + color: "5240c9" + +- name: "x:module/generator" + description: "Work on Exercise generators" + color: "5240c9" + +- name: "x:module/practice-exercise" + description: "Work on Practice Exercises" + color: "5240c9" + +- name: "x:module/representer" + description: "Work on Representers" + color: "5240c9" + +- name: "x:module/test-runner" + description: "Work on Test Runners" + color: "5240c9" + +# The `x:size/` labels describe the expected amount of work for a contributor +- name: "x:size/tiny" + description: "Tiny amount of work" + color: "4836bf" + +- name: "x:size/small" + description: "Small amount of work" + color: "4836bf" + +- name: "x:size/medium" + description: "Medium amount of work" + color: "4836bf" + +- name: "x:size/large" + description: "Large amount of work" + color: "4836bf" + +- name: "x:size/massive" + description: "Massive amount of work" + color: "4836bf" + +# The `x:status/` label indicates if there is already someone working on the issue +- name: "x:status/claimed" + description: "Someone is working on this issue" + color: "4231af" + +# The `x:type/` labels describe what type of work the contributor will be engaged in +- name: "x:type/ci" + description: "Work on Continuous Integration (e.g. GitHub Actions workflows)" + color: "3c2d9f" + +- name: "x:type/coding" + description: "Write code that is not student-facing content (e.g. test-runners, generators, but not exercises)" + color: "3c2d9f" + +- name: "x:type/content" + description: "Work on content (e.g. exercises, concepts)" + color: "3c2d9f" + +- name: "x:type/docker" + description: "Work on Dockerfiles" + color: "3c2d9f" + +- name: "x:type/docs" + description: "Work on Documentation" + color: "3c2d9f" + +# This Exercism-wide label is added to all automatically created pull requests that help migrate/prepare a track for Exercism v3 +- name: "v3-migration 🤖" + description: "Preparing for Exercism v3" + color: "e99695" + diff --git a/.github/workflows/sync-labels.yml b/.github/workflows/sync-labels.yml new file mode 100644 index 000000000..d2d9bef93 --- /dev/null +++ b/.github/workflows/sync-labels.yml @@ -0,0 +1,21 @@ +name: Tools + +on: + push: + branches: [main] + paths: + - .github/labels.yml + - .github/workflows/sync-labels.yml + schedule: + - cron: 0 0 1 * * + workflow_dispatch: + +jobs: + sync-labels: + name: Sync labels + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f + - uses: micnncim/action-label-syncer@3abd5ab72fda571e69fffd97bd4e0033dd5f495c + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 4065e3a74a1f74d31140d2848fb2457ca8724cda Mon Sep 17 00:00:00 2001 From: Exercism Bot Date: Mon, 30 Aug 2021 11:35:31 +0100 Subject: [PATCH 008/142] =?UTF-8?q?=F0=9F=A4=96=20Sync=20org-wide=20files?= =?UTF-8?q?=20to=20upstream=20repo=20(#1006)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit More info: https://github.com/exercism/org-wide-files/commit/c8c2611771545c6b7a36d413c5571e958e0ee233 --- .github/labels.yml | 4 +-- CODE_OF_CONDUCT.md | 82 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 CODE_OF_CONDUCT.md diff --git a/.github/labels.yml b/.github/labels.yml index 1e684c04d..ba61b61dc 100644 --- a/.github/labels.yml +++ b/.github/labels.yml @@ -7,7 +7,7 @@ # 1. The Exercism-wide labels: defined in https://github.com/exercism/org-wide-files/blob/main/global-files/.github/labels.yml # 2. The repository-specific labels: defined in the `.appends/.github/labels.yml` file within this repository. # -# If any of these two files change, a pull request is automatically containing a re-generated version of this file. +# If any of these two files change, a pull request is automatically created containing a re-generated version of this file. # Consequently, to change repository-specific labels you should update the `.appends/.github/labels.yml` file and _not_ this file. # # When the pull request has been merged, the GitHub labels will be automatically updated by the "Sync labels" workflow. @@ -17,7 +17,7 @@ # These are the Exercism-wide labels which are shared across all repos. # # --------------------------------------------------------------------- # -# The following Exercism-wide labels are used to show "tasks" on the website, which will point users to things they can help contribute with. +# The following Exercism-wide labels are used to show "tasks" on the website, which will point users to things they can contribute to. # The `x:action/` labels describe what sort of work the contributor will be engaged in when working on the issue - name: "x:action/create" diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..368129a0b --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,82 @@ +# Code of Conduct + +## Introduction + +Exercism is a platform centered around empathetic conversation. We have a low tolerance for communication that makes anyone feel unwelcome, unsupported, insulted or discriminated against. + +## Seen or experienced something uncomfortable? + +If you see or experience abuse, harassment, discrimination, or feel unsafe or upset, please email abuse@exercism.io. We will take your report seriously. + +## Enforcement + +We actively monitor for Code of Conduct (CoC) violations and take any reports of violations extremely seriously. We have banned contributors, mentors and users due to violations. + +After we receive a report of a CoC violation, we view that person's conversation history on Exercism and related communication channels and attempt to understand whether someone has deliberately broken the CoC, or accidentally crossed a line. We generally reach out to the person who has been reported to discuss any concerns we have and warn them that repeated violations will result in a ban. Sometimes we decide that no violation has occurred and that no action is required and sometimes we will also ban people on a first offense. We strive to be fair, but will err on the side of protecting the culture of our community. + +Exercism's leadership reserve the right to take whatever action they feel appropriate with regards to CoC violations. + +## The simple version + +- Be empathetic +- Be welcoming +- Be kind +- Be honest +- Be supportive +- Be polite + +## The details + +Exercism should be a safe place for everybody regardless of + +- Gender, gender identity or gender expression +- Sexual orientation +- Disability +- Physical appearance (including but not limited to body size) +- Race +- Age +- Religion +- Anything else you can think of. + +As someone who is part of this community, you agree that: + +- We are collectively and individually committed to safety and inclusivity. +- We have zero tolerance for abuse, harassment, or discrimination. +- We respect people’s boundaries and identities. +- We refrain from using language that can be considered offensive or oppressive (systemically or otherwise), eg. sexist, racist, homophobic, transphobic, ableist, classist, etc. - this includes (but is not limited to) various slurs. +- We avoid using offensive topics as a form of humor. + +We actively work towards: + +- Being a safe community +- Cultivating a network of support & encouragement for each other +- Encouraging responsible and varied forms of expression + +We condemn: + +- Stalking, doxxing, or publishing private information +- Violence, threats of violence or violent language +- Anything that compromises people’s safety +- Conduct or speech which might be considered sexist, racist, homophobic, transphobic, ableist or otherwise discriminatory or offensive in nature. +- The use of unwelcome, suggestive, derogatory or inappropriate nicknames or terms. +- Disrespect towards others (jokes, innuendo, dismissive attitudes) and towards differences of opinion. +- Intimidation or harassment (online or in-person). Please read the [Citizen Code of Conduct](https://github.com/stumpsyn/policies/blob/master/citizen_code_of_conduct.md) for how we interpret harassment. +- Inappropriate attention or contact. +- Not understanding the differences between constructive criticism and disparagement. + +These things are NOT OK. + +Be aware of how your actions affect others. If it makes someone uncomfortable, stop. + +If you say something that is found offensive, and you are called out on it, try to: + +- Listen without interruption. +- Believe what the person is saying & do not attempt to disqualify what they have to say. +- Ask for tips / help with avoiding making the offense in the future. +- Apologize and ask forgiveness. + +## History + +This policy was initially adopted from the Front-end London Slack community and has been modified since. A version history can be seen on [GitHub](https://github.com/exercism/website-copy/edit/main/pages/code_of_conduct.md). + +_This policy is a "living" document, and subject to refinement and expansion in the future. This policy applies to the Exercism website, the Exercism GitHub organization, any other Exercism-related communication channels (e.g. Slack, Twitter, email) and any other Exercism entity or event._ From 0d998b978dc94c4564af2d0e9ce14e45615ec99c Mon Sep 17 00:00:00 2001 From: Johannes Werner Date: Mon, 18 Oct 2021 14:02:02 +0200 Subject: [PATCH 009/142] fixed broken link when metadata is missing (#1011) * fixed broken link when metadata is missing * fixed broken link when metadata is missing --- cmd/cmd.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/cmd.go b/cmd/cmd.go index 9fa48acdc..dcca08264 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -55,7 +55,7 @@ const msgRerunConfigure = ` const msgMissingMetadata = ` The exercise you are submitting doesn't have the necessary metadata. - Please see https://exercism.io/cli-v1-to-v2 for instructions on how to fix it. + Please see https://github.com/exercism/website-copy/blob/main/pages/cli_v1_to_v2.md for instructions on how to fix it. ` From d554b9b87ace9c276d452e5d9f71063fc3e13cee Mon Sep 17 00:00:00 2001 From: Sascha Mann Date: Fri, 18 Feb 2022 11:41:37 +0100 Subject: [PATCH 010/142] CI: Migrate to GHA (#1021) * CI: Migrate to GHA * Rename .travis.gofmt.sh to .gha.gofmt.sh * Delete .travis.yml * Delete appveyor.yml * Add caching * Test caching * Revert "Add caching" This reverts commit 0beee421e710916eab35c504690b07c1ab1e811c. --- .travis.gofmt.sh => .gha.gofmt.sh | 0 .github/workflows/ci.yml | 43 +++++++++++++++++++++++++++++++ .travis.yml | 15 ----------- appveyor.yml | 20 -------------- 4 files changed, 43 insertions(+), 35 deletions(-) rename .travis.gofmt.sh => .gha.gofmt.sh (100%) create mode 100644 .github/workflows/ci.yml delete mode 100644 .travis.yml delete mode 100644 appveyor.yml diff --git a/.travis.gofmt.sh b/.gha.gofmt.sh similarity index 100% rename from .travis.gofmt.sh rename to .gha.gofmt.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..890af0c5d --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,43 @@ +name: CI + +on: + workflow_dispatch: + push: + branches: + - main + pull_request: + +permissions: + contents: read + +jobs: + tests: + name: Go ${{ matrix.go-version }} - ${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + go-version: ["1.15"] + os: [ubuntu-latest, windows-latest, macOS-latest] + + steps: + - uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f + + - uses: actions/setup-go@bfdd3570ce990073878bf10f6b2d79082de49492 + with: + go-version: ${{ matrix.go-version }} + + - name: Run Tests + run: | + go test -cover ./... + shell: bash + + formatting: + name: Go Format + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f + + - name: Check formatting + run: ./.gha.gofmt.sh diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index a195a1099..000000000 --- a/.travis.yml +++ /dev/null @@ -1,15 +0,0 @@ -language: go - -sudo: false - -go: - - "1.15.x" - - tip - -matrix: - allow_failures: - - go: tip - -script: - - ./.travis.gofmt.sh - - go test -cover ./... diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index 114035734..000000000 --- a/appveyor.yml +++ /dev/null @@ -1,20 +0,0 @@ ---- -version: "{build}" - -clone_folder: c:\gopath\src\github.com\exercism\cli - -environment: - GOPATH: c:\gopath - GO111MODULE: on - -init: - - git config --global core.autocrlf input - -install: - - echo %PATH% - - echo %GOPATH% - - go version - - go env - -build_script: - - go test -cover ./... From 2e780d48077cc29c1eb45fe5c634b55b7ae27b24 Mon Sep 17 00:00:00 2001 From: Sascha Mann Date: Fri, 18 Feb 2022 12:50:23 +0100 Subject: [PATCH 011/142] Update CI badge in README (#1022) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fa1c45db8..c92650a85 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Exercism Command-line Interface (CLI) -[![Build Status](https://travis-ci.org/exercism/cli.svg?branch=master)](https://travis-ci.org/exercism/cli) +[![CI](https://github.com/exercism/cli/actions/workflows/ci.yml/badge.svg)](https://github.com/exercism/cli/actions/workflows/ci.yml) [![Go Report Card](https://goreportcard.com/badge/github.com/exercism/cli)](https://goreportcard.com/report/github.com/exercism/cli) The CLI is the link between the [Exercism][exercism] website and your local work environment. It lets you download exercises and submit your solution to the site. From 5563b647c46faf9dc7ea6f146b4d21072acd2d08 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 24 Feb 2022 12:04:42 +0100 Subject: [PATCH 012/142] Bump the printed version of Exercism to v3 (#1013) --- cmd/root.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/root.go b/cmd/root.go index aa97c4670..734c8d4b7 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -16,7 +16,7 @@ import ( var RootCmd = &cobra.Command{ Use: BinaryName, Short: "A friendly command-line interface to Exercism.", - Long: `A command-line interface for the v2 redesign of Exercism. + Long: `A command-line interface for the v3 redesign of Exercism. Download exercises and submit your solutions.`, SilenceUsage: true, From efe5e0bea5d20efd70157b8a1aa880d42d730b2b Mon Sep 17 00:00:00 2001 From: Faisal Afroz Date: Thu, 24 Feb 2022 16:37:26 +0530 Subject: [PATCH 013/142] Create dependabot.yml (#1015) Co-authored-by: Erik Schierboom --- .github/dependabot.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..eb2ead799 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,10 @@ +version: 2 + +updates: + # Keep dependencies for GitHub Actions up-to-date + - package-ecosystem: 'github-actions' + directory: '/' + schedule: + interval: 'daily' + labels: + - 'x:size/small' From d281c7a626231f8cf43eca23d6f41897091618fe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 24 Feb 2022 12:15:24 +0100 Subject: [PATCH 014/142] Bump actions/checkout from 2.3.4 to 2.4.0 (#1024) Bumps [actions/checkout](https://github.com/actions/checkout) from 2.3.4 to 2.4.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f...ec3a7ce113134d7a93b817d10a8272cb61118579) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 4 ++-- .github/workflows/sync-labels.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 890af0c5d..da039e413 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,7 @@ jobs: os: [ubuntu-latest, windows-latest, macOS-latest] steps: - - uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f + - uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579 - uses: actions/setup-go@bfdd3570ce990073878bf10f6b2d79082de49492 with: @@ -37,7 +37,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f + - uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579 - name: Check formatting run: ./.gha.gofmt.sh diff --git a/.github/workflows/sync-labels.yml b/.github/workflows/sync-labels.yml index d2d9bef93..095884ad5 100644 --- a/.github/workflows/sync-labels.yml +++ b/.github/workflows/sync-labels.yml @@ -15,7 +15,7 @@ jobs: name: Sync labels runs-on: ubuntu-latest steps: - - uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f + - uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579 - uses: micnncim/action-label-syncer@3abd5ab72fda571e69fffd97bd4e0033dd5f495c env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 1b72d9ebf7885d6f089860976baba5c666ac0c80 Mon Sep 17 00:00:00 2001 From: Francisco Miamoto Date: Thu, 24 Feb 2022 11:30:03 -0300 Subject: [PATCH 015/142] Update build instructions for *nix (#1005) --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index cf13f1181..7fa8422c1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -40,7 +40,7 @@ damaging your real Exercism submissions, or test different tokens, etc. On Unices: -- `cd /path/to/the/development/directory/cli && go build -o testercism main.go` +- `cd /path/to/the/development/directory/cli && go build -o testercism ./exercism/main.go` - `./testercism -h` On Windows: From eee729bb170aa6e4be6ac0c057c6392ead456bc1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 2 Mar 2022 09:23:27 +0100 Subject: [PATCH 016/142] Bump actions/checkout from 2.4.0 to 3 (#1027) Bumps [actions/checkout](https://github.com/actions/checkout) from 2.4.0 to 3. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/ec3a7ce113134d7a93b817d10a8272cb61118579...a12a3943b4bdde767164f792f33f40b04645d846) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 4 ++-- .github/workflows/sync-labels.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index da039e413..8f38a110d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,7 @@ jobs: os: [ubuntu-latest, windows-latest, macOS-latest] steps: - - uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579 + - uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846 - uses: actions/setup-go@bfdd3570ce990073878bf10f6b2d79082de49492 with: @@ -37,7 +37,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579 + - uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846 - name: Check formatting run: ./.gha.gofmt.sh diff --git a/.github/workflows/sync-labels.yml b/.github/workflows/sync-labels.yml index 095884ad5..c3e277eb9 100644 --- a/.github/workflows/sync-labels.yml +++ b/.github/workflows/sync-labels.yml @@ -15,7 +15,7 @@ jobs: name: Sync labels runs-on: ubuntu-latest steps: - - uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579 + - uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846 - uses: micnncim/action-label-syncer@3abd5ab72fda571e69fffd97bd4e0033dd5f495c env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 8f0655b9d23af3f9995a2b5689d4fd307d9a2bd4 Mon Sep 17 00:00:00 2001 From: Exercism Bot Date: Tue, 8 Mar 2022 15:16:10 +0000 Subject: [PATCH 017/142] =?UTF-8?q?=F0=9F=A4=96=20Sync=20org-wide=20files?= =?UTF-8?q?=20to=20upstream=20repo=20(#1028)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit More info: https://github.com/exercism/org-wide-files/commit/cc4bf900aaee77af9629a751dadc8092d82e379a --- .github/labels.yml | 59 +++++++++++++++++-------------- .github/workflows/sync-labels.yml | 18 +++++----- 2 files changed, 40 insertions(+), 37 deletions(-) diff --git a/.github/labels.yml b/.github/labels.yml index ba61b61dc..7a7915e56 100644 --- a/.github/labels.yml +++ b/.github/labels.yml @@ -22,116 +22,121 @@ # The `x:action/` labels describe what sort of work the contributor will be engaged in when working on the issue - name: "x:action/create" description: "Work on something from scratch" - color: "6f60d2" + color: "ffffff" - name: "x:action/fix" description: "Fix an issue" - color: "6f60d2" + color: "ffffff" - name: "x:action/improve" description: "Improve existing functionality/content" - color: "6f60d2" + color: "ffffff" - name: "x:action/proofread" description: "Proofread text" - color: "6f60d2" + color: "ffffff" - name: "x:action/sync" description: "Sync content with its latest version" - color: "6f60d2" + color: "ffffff" # The `x:knowledge/` labels describe how much Exercism knowledge is required by the contributor - name: "x:knowledge/none" description: "No existing Exercism knowledge required" - color: "604fcd" + color: "ffffff" - name: "x:knowledge/elementary" description: "Little Exercism knowledge required" - color: "604fcd" + color: "ffffff" - name: "x:knowledge/intermediate" description: "Quite a bit of Exercism knowledge required" - color: "604fcd" + color: "ffffff" - name: "x:knowledge/advanced" description: "Comprehensive Exercism knowledge required" - color: "604fcd" + color: "ffffff" # The `x:module/` labels indicate what part of Exercism the contributor will be working on - name: "x:module/analyzer" description: "Work on Analyzers" - color: "5240c9" + color: "ffffff" - name: "x:module/concept" description: "Work on Concepts" - color: "5240c9" + color: "ffffff" - name: "x:module/concept-exercise" description: "Work on Concept Exercises" - color: "5240c9" + color: "ffffff" - name: "x:module/generator" description: "Work on Exercise generators" - color: "5240c9" + color: "ffffff" - name: "x:module/practice-exercise" description: "Work on Practice Exercises" - color: "5240c9" + color: "ffffff" - name: "x:module/representer" description: "Work on Representers" - color: "5240c9" + color: "ffffff" - name: "x:module/test-runner" description: "Work on Test Runners" - color: "5240c9" + color: "ffffff" # The `x:size/` labels describe the expected amount of work for a contributor - name: "x:size/tiny" description: "Tiny amount of work" - color: "4836bf" + color: "ffffff" - name: "x:size/small" description: "Small amount of work" - color: "4836bf" + color: "ffffff" - name: "x:size/medium" description: "Medium amount of work" - color: "4836bf" + color: "ffffff" - name: "x:size/large" description: "Large amount of work" - color: "4836bf" + color: "ffffff" - name: "x:size/massive" description: "Massive amount of work" - color: "4836bf" + color: "ffffff" # The `x:status/` label indicates if there is already someone working on the issue - name: "x:status/claimed" description: "Someone is working on this issue" - color: "4231af" + color: "ffffff" # The `x:type/` labels describe what type of work the contributor will be engaged in - name: "x:type/ci" description: "Work on Continuous Integration (e.g. GitHub Actions workflows)" - color: "3c2d9f" + color: "ffffff" - name: "x:type/coding" description: "Write code that is not student-facing content (e.g. test-runners, generators, but not exercises)" - color: "3c2d9f" + color: "ffffff" - name: "x:type/content" description: "Work on content (e.g. exercises, concepts)" - color: "3c2d9f" + color: "ffffff" - name: "x:type/docker" description: "Work on Dockerfiles" - color: "3c2d9f" + color: "ffffff" - name: "x:type/docs" description: "Work on Documentation" - color: "3c2d9f" + color: "ffffff" + +# This label can be added to accept PRs as part of Hacktoberfest +- name: "hacktoberfest-accepted" + description: "Make this PR count for hacktoberfest" + color: "ff7518" # This Exercism-wide label is added to all automatically created pull requests that help migrate/prepare a track for Exercism v3 - name: "v3-migration 🤖" diff --git a/.github/workflows/sync-labels.yml b/.github/workflows/sync-labels.yml index c3e277eb9..e7b99e504 100644 --- a/.github/workflows/sync-labels.yml +++ b/.github/workflows/sync-labels.yml @@ -2,20 +2,18 @@ name: Tools on: push: - branches: [main] + branches: + - main paths: - .github/labels.yml - .github/workflows/sync-labels.yml - schedule: - - cron: 0 0 1 * * workflow_dispatch: + schedule: + - cron: 0 0 1 * * # First day of each month + +permissions: + issues: write jobs: sync-labels: - name: Sync labels - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846 - - uses: micnncim/action-label-syncer@3abd5ab72fda571e69fffd97bd4e0033dd5f495c - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: exercism/github-actions/.github/workflows/labels.yml@main From d3ef85576c42c1d52816bc743c211417608a1a9a Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Thu, 17 Mar 2022 09:35:18 +0100 Subject: [PATCH 018/142] Add a .appends/.github/labels.yml file. (#1030) The `.appends/.github/labels.yml` file contains all the labels that are currently used in this repo. The `.github/labels.yml` file will contain the full list of labels that this repo can use, which will be a combination of the `.appends/.github/labels.yml` file and a centrally-managed `labels.yml` file. We'll automatically sync any changes, which allows us to guarantee that all the track repositories will have a pre-determined set of labels, augmented with any custom labels defined in the `.appends/.github/labels.yml` file. --- .appends/.github/labels.yml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .appends/.github/labels.yml diff --git a/.appends/.github/labels.yml b/.appends/.github/labels.yml new file mode 100644 index 000000000..2bef75771 --- /dev/null +++ b/.appends/.github/labels.yml @@ -0,0 +1,8 @@ +# ----------------------------------------------------------------------------------------- # +# These are the repository-specific labels that augment the Exercise-wide labels defined in # +# https://github.com/exercism/org-wide-files/blob/main/global-files/.github/labels.yml. # +# ----------------------------------------------------------------------------------------- # + +- name: "bug?" + description: "" + color: "eb6420" From 68a08b96163d8f1f09a7c715a11cd7ca011b4be2 Mon Sep 17 00:00:00 2001 From: Exercism Bot Date: Thu, 17 Mar 2022 09:37:47 +0000 Subject: [PATCH 019/142] =?UTF-8?q?=F0=9F=A4=96=20Sync=20org-wide=20files?= =?UTF-8?q?=20to=20upstream=20repo=20(#1031)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit More info: https://github.com/exercism/org-wide-files/commit/4d7ccede08978ef000a784a756bb34edd1f10ed4 --- .github/labels.yml | 8 ++++++++ CODE_OF_CONDUCT.md | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/labels.yml b/.github/labels.yml index 7a7915e56..9e95c4201 100644 --- a/.github/labels.yml +++ b/.github/labels.yml @@ -143,3 +143,11 @@ description: "Preparing for Exercism v3" color: "e99695" +# ----------------------------------------------------------------------------------------- # +# These are the repository-specific labels that augment the Exercise-wide labels defined in # +# https://github.com/exercism/org-wide-files/blob/main/global-files/.github/labels.yml. # +# ----------------------------------------------------------------------------------------- # + +- name: "bug?" + description: "" + color: "eb6420" diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 368129a0b..16e94f493 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -6,7 +6,7 @@ Exercism is a platform centered around empathetic conversation. We have a low to ## Seen or experienced something uncomfortable? -If you see or experience abuse, harassment, discrimination, or feel unsafe or upset, please email abuse@exercism.io. We will take your report seriously. +If you see or experience abuse, harassment, discrimination, or feel unsafe or upset, please email abuse@exercism.org. We will take your report seriously. ## Enforcement From 4c1848878435b807252e4cfcff9f772fa41b816f Mon Sep 17 00:00:00 2001 From: Eric Kingery Date: Tue, 3 May 2022 09:11:56 -0400 Subject: [PATCH 020/142] ran go fmt ./... (#1038) --- cmd/configure_test.go | 1 + cmd/submit_symlink_test.go | 1 + config/config_notwin_test.go | 1 + config/config_windows_test.go | 1 + config/resolve_notwin_test.go | 1 + workspace/path_type_symlinks_test.go | 1 + 6 files changed, 6 insertions(+) diff --git a/cmd/configure_test.go b/cmd/configure_test.go index 8d3643522..7a0f28eac 100644 --- a/cmd/configure_test.go +++ b/cmd/configure_test.go @@ -1,3 +1,4 @@ +//go:build !windows // +build !windows package cmd diff --git a/cmd/submit_symlink_test.go b/cmd/submit_symlink_test.go index b2d30ac4c..e10fb4890 100644 --- a/cmd/submit_symlink_test.go +++ b/cmd/submit_symlink_test.go @@ -1,3 +1,4 @@ +//go:build !windows // +build !windows package cmd diff --git a/config/config_notwin_test.go b/config/config_notwin_test.go index f7e4564da..31ddf77f0 100644 --- a/config/config_notwin_test.go +++ b/config/config_notwin_test.go @@ -1,3 +1,4 @@ +//go:build !windows // +build !windows package config diff --git a/config/config_windows_test.go b/config/config_windows_test.go index e4374def3..da676739f 100644 --- a/config/config_windows_test.go +++ b/config/config_windows_test.go @@ -1,3 +1,4 @@ +//go:build windows // +build windows package config diff --git a/config/resolve_notwin_test.go b/config/resolve_notwin_test.go index d44b73714..eea7ae440 100644 --- a/config/resolve_notwin_test.go +++ b/config/resolve_notwin_test.go @@ -1,3 +1,4 @@ +//go:build !windows // +build !windows package config diff --git a/workspace/path_type_symlinks_test.go b/workspace/path_type_symlinks_test.go index 0b8421019..ace7b741d 100644 --- a/workspace/path_type_symlinks_test.go +++ b/workspace/path_type_symlinks_test.go @@ -1,3 +1,4 @@ +//go:build !windows // +build !windows package workspace From fbd552b334235d4537d55af45331107c3ad09c12 Mon Sep 17 00:00:00 2001 From: Exercism Bot Date: Tue, 24 May 2022 09:20:48 +0100 Subject: [PATCH 021/142] =?UTF-8?q?=F0=9F=A4=96=20Sync=20org-wide=20files?= =?UTF-8?q?=20to=20upstream=20repo=20(#1039)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit More info: https://github.com/exercism/org-wide-files/commit/f28daf625fa326fafdcf261db7699377c8d1ed37 --- .github/labels.yml | 24 ++++++++++++++++++++++++ CODE_OF_CONDUCT.md | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/.github/labels.yml b/.github/labels.yml index 9e95c4201..fcb7c3552 100644 --- a/.github/labels.yml +++ b/.github/labels.yml @@ -86,6 +86,30 @@ description: "Work on Test Runners" color: "ffffff" +# The `x:rep/` labels describe the amount of reputation to award +# +# For more information on reputation and how these labels should be used, +# check out https://exercism.org/docs/using/product/reputation +- name: "x:rep/tiny" + description: "Tiny amount of reputation" + color: "ffffff" + +- name: "x:rep/small" + description: "Small amount of reputation" + color: "ffffff" + +- name: "x:rep/medium" + description: "Medium amount of reputation" + color: "ffffff" + +- name: "x:rep/large" + description: "Large amount of reputation" + color: "ffffff" + +- name: "x:rep/massive" + description: "Massive amount of reputation" + color: "ffffff" + # The `x:size/` labels describe the expected amount of work for a contributor - name: "x:size/tiny" description: "Tiny amount of work" diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 16e94f493..9bb22baa7 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -6,7 +6,7 @@ Exercism is a platform centered around empathetic conversation. We have a low to ## Seen or experienced something uncomfortable? -If you see or experience abuse, harassment, discrimination, or feel unsafe or upset, please email abuse@exercism.org. We will take your report seriously. +If you see or experience abuse, harassment, discrimination, or feel unsafe or upset, please email [abuse@exercism.org](mailto:abuse@exercism.org?subject=%5BCoC%5D) and include \[CoC\] in the subject line. We will follow up with you as a priority. ## Enforcement From 8e73ec3131e8218c0ff31d5e0d1a050cabd6864d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Santos?= Date: Thu, 9 Jun 2022 07:41:31 +0100 Subject: [PATCH 022/142] Submit without specifying files (#1044) --- cmd/submit.go | 26 +++++++++++++++++++++++++- cmd/submit_test.go | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/cmd/submit.go b/cmd/submit.go index 4f2a8df72..aaf3a93c1 100644 --- a/cmd/submit.go +++ b/cmd/submit.go @@ -26,7 +26,6 @@ var submitCmd = &cobra.Command{ Call the command with the list of files you want to submit. `, - Args: cobra.MinimumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { cfg := config.NewConfig() @@ -45,6 +44,14 @@ var submitCmd = &cobra.Command{ // Ignore error. If the file doesn't exist, that is fine. _ = v.ReadInConfig() + if len(args) == 0 { + files, err := getExerciseSolutionFiles(".") + if err != nil { + return err + } + args = files + } + return runSubmit(cfg, cmd.Flags(), args) }, } @@ -114,6 +121,23 @@ func runSubmit(cfg config.Config, flags *pflag.FlagSet, args []string) error { return nil } +func getExerciseSolutionFiles(baseDir string) ([]string, error) { + v := viper.New() + v.AddConfigPath(filepath.Join(baseDir, ".exercism")) + v.SetConfigName("config") + v.SetConfigType("json") + err := v.ReadInConfig() + if err != nil { + return nil, errors.New("no files to submit") + } + solutionFiles := v.GetStringSlice("files.solution") + if len(solutionFiles) == 0 { + return nil, errors.New("no files to submit") + } + + return solutionFiles, nil +} + type submitCmdContext struct { usrCfg *viper.Viper flags *pflag.FlagSet diff --git a/cmd/submit_test.go b/cmd/submit_test.go index c20c47748..7286a19e6 100644 --- a/cmd/submit_test.go +++ b/cmd/submit_test.go @@ -108,6 +108,45 @@ func TestSubmitExerciseWithoutMetadataFile(t *testing.T) { } } +func TestGetExerciseSolutionFiles(t *testing.T) { + + tmpDir, err := ioutil.TempDir("", "dir-with-no-metadata") + defer os.RemoveAll(tmpDir) + assert.NoError(t, err) + + _, err = getExerciseSolutionFiles(tmpDir) + if assert.Error(t, err) { + assert.Regexp(t, "no files to submit", err.Error()) + } + + validTmpDir, err := ioutil.TempDir("", "dir-with-valid-metadata") + defer os.RemoveAll(validTmpDir) + assert.NoError(t, err) + + metadataDir := filepath.Join(validTmpDir, ".exercism") + err = os.MkdirAll(metadataDir, os.FileMode(0755)) + assert.NoError(t, err) + + err = ioutil.WriteFile( + filepath.Join(metadataDir, "config.json"), + []byte(` +{ + "files": { + "solution": [ + "expenses.go" + ] + } +} +`), os.FileMode(0755)) + assert.NoError(t, err) + + files, err := getExerciseSolutionFiles(validTmpDir) + assert.NoError(t, err) + if assert.Equal(t, len(files), 1) { + assert.Equal(t, files[0], "expenses.go") + } +} + func TestSubmitFilesAndDir(t *testing.T) { tmpDir, err := ioutil.TempDir("", "submit-no-such-file") defer os.RemoveAll(tmpDir) From 972305178d04a8532b68b94dfa46f8f45c793338 Mon Sep 17 00:00:00 2001 From: Katrina Owen Date: Mon, 3 Oct 2022 15:56:03 +0200 Subject: [PATCH 023/142] Update TLD in GoReleaser summary (#1057) We changed the default TLD of Exercism from .io to .org. --- .goreleaser.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index 19fb72b2a..ca7d2bbcb 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -83,7 +83,7 @@ snapcrafts: # Remember you need to `snapcraft login` first. # Defaults to false. # publish: true - summary: Command-line client for https://exercism.io + summary: Command-line client for https://exercism.org # https://snapcraft.io/docs/reference/confinement confinement: strict # A snap of type base to be used as the execution environment for this snap. From 3d37fefd190bf08c25f38d12171e363e20163a0e Mon Sep 17 00:00:00 2001 From: Katrina Owen Date: Tue, 4 Oct 2022 10:52:59 +0200 Subject: [PATCH 024/142] Bump version to v3.1.0 (#1060) I arbitrarily decided that today is a good day to move to 3.1x. This release adds a feature that has been requested since forever, i.e. the ability to submit without specifying files. Seems worth the minor version bump. --- CHANGELOG.md | 7 +++++++ cmd/version.go | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ccec41b11..110c6fe80 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ The exercism CLI follows [semantic versioning](http://semver.org/). ## Next Release * **Your contribution here** +## v3.1.0 (2022-10-04) +* [#979](https://github.com/exercism/cli/pull/979) Protect existing solutions from being overwritten by 'download' - [@harugo] +* [#981](https://github.com/exercism/cli/pull/981) Check if authorisation header is set before attempting to extract token - [@harugo] +* [#1044](https://github.com/exercism/cli/pull/1044) Submit without specifying files - [@andrerfcsantos] + ## v3.0.13 (2019-10-23) * [#866](https://github.com/exercism/cli/pull/866) The API token outputted during verbose will now be masked by default - [@Jrank2013] * [#873](https://github.com/exercism/cli/pull/873) Make all errors in cmd package checked - [@avegner] @@ -423,6 +428,7 @@ All changes by [@msgehard] * Build on Travis [@AlexWheeler]: https://github.com/AlexWheeler +[@andrerfcsantos]: https://github.com/andrerfcsantos [@avegner]: https://github.com/avegner [@Dparker1990]: https://github.com/Dparker1990 [@John-Goff]: https://github.com/John-Goff @@ -453,6 +459,7 @@ All changes by [@msgehard] [@farisj]: https://github.com/farisj [@glebedel]: https://github.com/glebedel [@harimp]: https://github.com/harimp +[@harugo]: https://github.com/harugo [@hjljo]: https://github.com/hjljo [@isbadawi]: https://github.com/isbadawi [@jbaiter]: https://github.com/jbaiter diff --git a/cmd/version.go b/cmd/version.go index 3b81f5897..069866b78 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -9,7 +9,7 @@ import ( // Version is the version of the current build. // It follows semantic versioning. -const Version = "3.0.13" +const Version = "3.1.0" // checkLatest flag for version command. var checkLatest bool From 45ccec2e2163ded09c461ad8e277a0f809bffd27 Mon Sep 17 00:00:00 2001 From: Katrina Owen Date: Tue, 4 Oct 2022 11:26:56 +0200 Subject: [PATCH 025/142] Add missing go.sum entry (#1061) The release failed, complaining about the wrong mousetrap library reference. This updates it, so we can try releasing again. --- go.sum | 1 + 1 file changed, 1 insertion(+) diff --git a/go.sum b/go.sum index 0a9864259..3f5f7852a 100644 --- a/go.sum +++ b/go.sum @@ -8,6 +8,7 @@ github.com/hashicorp/hcl v0.0.0-20170509225359-392dba7d905e h1:KJWs1uTCkN3E/J5of github.com/hashicorp/hcl v0.0.0-20170509225359-392dba7d905e/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w= github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf h1:WfD7VjIE6z8dIvMsI4/s+1qr5EL+zoIGev1BQj1eoJ8= github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf/go.mod h1:hyb9oH7vZsitZCiBt0ZvifOrB+qc8PS5IiilCIb87rg= +github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/magiconair/properties v1.7.3 h1:6AOjgCKyZFMG/1yfReDPDz3CJZPxnYk7DGmj2HtyF24= github.com/magiconair/properties v1.7.3/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= From 423aff554f512c48d5e6b72342ae7afe9d58a598 Mon Sep 17 00:00:00 2001 From: Katrina Owen Date: Tue, 4 Oct 2022 18:12:02 +0200 Subject: [PATCH 026/142] Rename master to main in release docs (#1059) We switched the default branch name a while back. This updates the release documentation to match the new state. --- RELEASE.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/RELEASE.md b/RELEASE.md index c8c1c92f0..b1200d882 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -15,7 +15,7 @@ release process. Make sure all the recent changes are reflected in the "next release" section of the CHANGELOG.md file. All the changes in the "next release" section should be moved to a new section that describes the version number, and gives it a date. You can view changes using the /compare/ view: -https://github.com/exercism/cli/compare/$PREVIOUS_RELEASE...master +https://github.com/exercism/cli/compare/$PREVIOUS_RELEASE...main GoReleaser supports the [auto generation of a changelog](https://goreleaser.com/customization/#customize-the-changelog) we will want to customize to meet our standards (not including refactors, test updates, etc). We should also consider using [the release notes feature](https://goreleaser.com/customization/#custom-release-notes). @@ -27,7 +27,7 @@ _Note: It's useful to add the version to the commit message when you bump it: e. In the future we will probably want to replace the hardcoded `Version` constant with [main.version](https://goreleaser.com/environment/#using-the-main-version). Here is a [stack overflow post on injecting to cmd/version.go](https://stackoverflow.com/a/47510909). -Commit this change on a branch along with the CHANGELOG updates in a single commit, and create a PR for merge to master. +Commit this change on a branch along with the CHANGELOG updates in a single commit, and create a PR for merge to main. ## Cut a release @@ -35,7 +35,7 @@ Commit this change on a branch along with the CHANGELOG updates in a single comm # Test run goreleaser --skip-publish --snapshot --rm-dist -# Create a new tag on the master branch and push it +# Create a new tag on the main branch and push it git tag -a v3.0.16 -m "Trying out GoReleaser" git push origin v3.0.16 From c811ef5ece3348f1478bf45c9365a12bab7bc4bb Mon Sep 17 00:00:00 2001 From: Katrina Owen Date: Tue, 4 Oct 2022 18:51:28 +0200 Subject: [PATCH 027/142] Fix broken links in release instructions (#1058) * Fix broken links in release instructions The GoReleaser docs have changed and they moved the information about the requirements for the GitHub API token as well as about signing releases. * Tracked down broken link to old main.version docs Co-authored-by: Eric Kingery --- RELEASE.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/RELEASE.md b/RELEASE.md index b1200d882..bf3e1c8bf 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -1,14 +1,14 @@ # Cutting a CLI Release The Exercism CLI uses [GoReleaser](https://goreleaser.com) to automate the -release process. +release process. ## Requirements 1. [Install GoReleaser](https://goreleaser.com/install/) 1. [Install snapcraft](https://snapcraft.io/docs/snapcraft-overview) -1. [Setup GitHub token](https://goreleaser.com/environment/#github-token) -1. Have a gpg key installed on your machine - it is [used for signing the artifacts](https://goreleaser.com/sign/) +1. [Setup GitHub token](https://goreleaser.com/scm/github/) +1. Have a gpg key installed on your machine - it is [used for signing the artifacts](https://goreleaser.com/customization/sign/) ## Confirm / Update the Changelog @@ -25,7 +25,7 @@ Edit the `Version` constant in `cmd/version.go` _Note: It's useful to add the version to the commit message when you bump it: e.g. `Bump version to v2.3.4`._ -In the future we will probably want to replace the hardcoded `Version` constant with [main.version](https://goreleaser.com/environment/#using-the-main-version). Here is a [stack overflow post on injecting to cmd/version.go](https://stackoverflow.com/a/47510909). +In the future we will probably want to replace the hardcoded `Version` constant with [main.version](https://goreleaser.com/cookbooks/using-main.version). Here is a [stack overflow post on injecting to cmd/version.go](https://stackoverflow.com/a/47510909). Commit this change on a branch along with the CHANGELOG updates in a single commit, and create a PR for merge to main. From 0513c81da2aba80852e3f8c16359707a9ea8718e Mon Sep 17 00:00:00 2001 From: Conor Fleming <32988273+Conor-Fleming@users.noreply.github.com> Date: Fri, 7 Oct 2022 13:32:27 -0700 Subject: [PATCH 028/142] removing broken links from contribution docs (#1064) --- CONTRIBUTING.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7fa8422c1..1936a39eb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -5,8 +5,6 @@ Exercism would be impossible without people like you being willing to spend time ## Documentation * [Exercism Documentation Repository](https://github.com/exercism/docs) -* [Exercism Glossary](https://github.com/exercism/docs/blob/master/about/glossary.md) -* [Exercism Architecture](https://github.com/exercism/docs/blob/master/about/architecture.md) ## Dependencies From 60a9ff8a0e3675957eabc94af58f58b621b3214f Mon Sep 17 00:00:00 2001 From: Exercism Bot Date: Wed, 23 Nov 2022 13:50:35 +0000 Subject: [PATCH 029/142] =?UTF-8?q?=F0=9F=A4=96=20Sync=20org-wide=20files?= =?UTF-8?q?=20to=20upstream=20repo=20(#1071)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit More info: https://github.com/exercism/org-wide-files/commit/ceface8fc48f8f8be135cecafe5ea8355aac9ad6 --- .github/labels.yml | 10 ++++---- CODE_OF_CONDUCT.md | 57 +++++++++++++++++++++++++++------------------- 2 files changed, 39 insertions(+), 28 deletions(-) diff --git a/.github/labels.yml b/.github/labels.yml index fcb7c3552..cd989c70f 100644 --- a/.github/labels.yml +++ b/.github/labels.yml @@ -157,16 +157,16 @@ description: "Work on Documentation" color: "ffffff" -# This label can be added to accept PRs as part of Hacktoberfest -- name: "hacktoberfest-accepted" - description: "Make this PR count for hacktoberfest" - color: "ff7518" - # This Exercism-wide label is added to all automatically created pull requests that help migrate/prepare a track for Exercism v3 - name: "v3-migration 🤖" description: "Preparing for Exercism v3" color: "e99695" +# This Exercism-wide label can be used to bulk-close issues in preparation for pausing community contributions +- name: "paused" + description: "Work paused until further notice" + color: "e4e669" + # ----------------------------------------------------------------------------------------- # # These are the repository-specific labels that augment the Exercise-wide labels defined in # # https://github.com/exercism/org-wide-files/blob/main/global-files/.github/labels.yml. # diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 9bb22baa7..df8e36761 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -2,17 +2,23 @@ ## Introduction -Exercism is a platform centered around empathetic conversation. We have a low tolerance for communication that makes anyone feel unwelcome, unsupported, insulted or discriminated against. +Exercism is a platform centered around empathetic conversation. +We have a low tolerance for communication that makes anyone feel unwelcome, unsupported, insulted or discriminated against. ## Seen or experienced something uncomfortable? -If you see or experience abuse, harassment, discrimination, or feel unsafe or upset, please email [abuse@exercism.org](mailto:abuse@exercism.org?subject=%5BCoC%5D) and include \[CoC\] in the subject line. We will follow up with you as a priority. +If you see or experience abuse, harassment, discrimination, or feel unsafe or upset, please email [abuse@exercism.org](mailto:abuse@exercism.org?subject=%5BCoC%5D) and include \[CoC\] in the subject line. +We will follow up with you as a priority. ## Enforcement -We actively monitor for Code of Conduct (CoC) violations and take any reports of violations extremely seriously. We have banned contributors, mentors and users due to violations. +We actively monitor for Code of Conduct (CoC) violations and take any reports of violations extremely seriously. +We have banned contributors, mentors and users due to violations. -After we receive a report of a CoC violation, we view that person's conversation history on Exercism and related communication channels and attempt to understand whether someone has deliberately broken the CoC, or accidentally crossed a line. We generally reach out to the person who has been reported to discuss any concerns we have and warn them that repeated violations will result in a ban. Sometimes we decide that no violation has occurred and that no action is required and sometimes we will also ban people on a first offense. We strive to be fair, but will err on the side of protecting the culture of our community. +After we receive a report of a CoC violation, we view that person's conversation history on Exercism and related communication channels and attempt to understand whether someone has deliberately broken the CoC, or accidentally crossed a line. +We generally reach out to the person who has been reported to discuss any concerns we have and warn them that repeated violations will result in a ban. +Sometimes we decide that no violation has occurred and that no action is required and sometimes we will also ban people on a first offense. +We strive to be fair, but will err on the side of protecting the culture of our community. Exercism's leadership reserve the right to take whatever action they feel appropriate with regards to CoC violations. @@ -36,15 +42,16 @@ Exercism should be a safe place for everybody regardless of - Race - Age - Religion -- Anything else you can think of. +- Anything else you can think of As someone who is part of this community, you agree that: -- We are collectively and individually committed to safety and inclusivity. -- We have zero tolerance for abuse, harassment, or discrimination. -- We respect people’s boundaries and identities. -- We refrain from using language that can be considered offensive or oppressive (systemically or otherwise), eg. sexist, racist, homophobic, transphobic, ableist, classist, etc. - this includes (but is not limited to) various slurs. -- We avoid using offensive topics as a form of humor. +- We are collectively and individually committed to safety and inclusivity +- We have zero tolerance for abuse, harassment, or discrimination +- We respect people’s boundaries and identities +- We refrain from using language that can be considered offensive or oppressive (systemically or otherwise), eg. sexist, racist, homophobic, transphobic, ableist, classist, etc. + - this includes (but is not limited to) various slurs. +- We avoid using offensive topics as a form of humor We actively work towards: @@ -57,26 +64,30 @@ We condemn: - Stalking, doxxing, or publishing private information - Violence, threats of violence or violent language - Anything that compromises people’s safety -- Conduct or speech which might be considered sexist, racist, homophobic, transphobic, ableist or otherwise discriminatory or offensive in nature. -- The use of unwelcome, suggestive, derogatory or inappropriate nicknames or terms. -- Disrespect towards others (jokes, innuendo, dismissive attitudes) and towards differences of opinion. -- Intimidation or harassment (online or in-person). Please read the [Citizen Code of Conduct](https://github.com/stumpsyn/policies/blob/master/citizen_code_of_conduct.md) for how we interpret harassment. -- Inappropriate attention or contact. -- Not understanding the differences between constructive criticism and disparagement. +- Conduct or speech which might be considered sexist, racist, homophobic, transphobic, ableist or otherwise discriminatory or offensive in nature +- The use of unwelcome, suggestive, derogatory or inappropriate nicknames or terms +- Disrespect towards others (jokes, innuendo, dismissive attitudes) and towards differences of opinion +- Intimidation or harassment (online or in-person). + Please read the [Citizen Code of Conduct](https://github.com/stumpsyn/policies/blob/master/citizen_code_of_conduct.md) for how we interpret harassment +- Inappropriate attention or contact +- Not understanding the differences between constructive criticism and disparagement These things are NOT OK. -Be aware of how your actions affect others. If it makes someone uncomfortable, stop. +Be aware of how your actions affect others. +If it makes someone uncomfortable, stop. If you say something that is found offensive, and you are called out on it, try to: -- Listen without interruption. -- Believe what the person is saying & do not attempt to disqualify what they have to say. -- Ask for tips / help with avoiding making the offense in the future. -- Apologize and ask forgiveness. +- Listen without interruption +- Believe what the person is saying & do not attempt to disqualify what they have to say +- Ask for tips / help with avoiding making the offense in the future +- Apologize and ask forgiveness ## History -This policy was initially adopted from the Front-end London Slack community and has been modified since. A version history can be seen on [GitHub](https://github.com/exercism/website-copy/edit/main/pages/code_of_conduct.md). +This policy was initially adopted from the Front-end London Slack community and has been modified since. +A version history can be seen on [GitHub](https://github.com/exercism/website-copy/edit/main/pages/code_of_conduct.md). -_This policy is a "living" document, and subject to refinement and expansion in the future. This policy applies to the Exercism website, the Exercism GitHub organization, any other Exercism-related communication channels (e.g. Slack, Twitter, email) and any other Exercism entity or event._ +_This policy is a "living" document, and subject to refinement and expansion in the future. +This policy applies to the Exercism website, the Exercism GitHub organization, any other Exercism-related communication channels (e.g. Slack, Twitter, email) and any other Exercism entity or event._ From e0dbcd1dbbf95836d6dc9bd634ac0d8c53b27525 Mon Sep 17 00:00:00 2001 From: Katrina Owen Date: Fri, 2 Dec 2022 09:37:16 +0100 Subject: [PATCH 030/142] Create autoresponder for pausing community contributions (#1072) * Create autoresponder for pausing community contributions We're going to take a step back and redesign the volunteering model for Exercism. Please see [this forum post](https://forum.exercism.org/t/freeing-our-maintainers-exercism-wide-changes-to-track-repositories/1109) for context. This PR adds an autoresponder that runs when an issue or PR is opened. If the person opening the issue is not a member of the Exercism organization, the autoresponder posts a comment and closes the issue. In the comment the author is directed to discuss the issue in the forum. If the discussion in the forum results in the issue/PR being approved, a maintainer or staff member will reopen it. Please feel free to merge this PR. It will be merged on December 1st, 2022. Please do not close it. If you wish to discuss this, please do so in [the forum post](https://forum.exercism.org/t/freeing-our-maintainers-exercism-wide-changes-to-track-repositories/1109) rather than here. * Update workflow for pausing community contributions This removes duplicated logic, relying on a shared workflow. --- .../pause-community-contributions.yml | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 .github/workflows/pause-community-contributions.yml diff --git a/.github/workflows/pause-community-contributions.yml b/.github/workflows/pause-community-contributions.yml new file mode 100644 index 000000000..055ff8676 --- /dev/null +++ b/.github/workflows/pause-community-contributions.yml @@ -0,0 +1,21 @@ +name: Pause Community Contributions + +on: + issues: + types: + - opened + pull_request_target: + types: + - opened + workflow_dispatch: + +permissions: + issues: write + pull-requests: write + +jobs: + pause: + if: github.repository_owner == 'exercism' # Stops this job from running on forks + uses: exercism/github-actions/.github/workflows/community-contributions.yml@main + with: + forum_category: support From b29b91d4d08051a8008611025c646fe1f9a5f31c Mon Sep 17 00:00:00 2001 From: ee7 <45465154+ee7@users.noreply.github.com> Date: Fri, 9 Dec 2022 09:04:41 +0100 Subject: [PATCH 031/142] goreleaser: add arm64 build for each OS (#1073) * goreleaser: add arm64 build for each OS The latest release of the Exercism CLI (3.1.0, 2022-10-04) includes these assets, via GoReleaser: exercism-3.1.0-darwin-x86_64.tar.gz exercism-3.1.0-freebsd-i386.tar.gz exercism-3.1.0-freebsd-x86_64.tar.gz exercism-3.1.0-linux-armv5.tar.gz exercism-3.1.0-linux-armv6.tar.gz exercism-3.1.0-linux-i386.tar.gz exercism-3.1.0-linux-ppc64.tar.gz exercism-3.1.0-linux-x86_64.tar.gz exercism-3.1.0-openbsd-i386.tar.gz exercism-3.1.0-openbsd-x86_64.tar.gz exercism-3.1.0-windows-armv5.zip exercism-3.1.0-windows-armv6.zip exercism-3.1.0-windows-i386.zip exercism-3.1.0-windows-x86_64.zip exercism_checksums.txt exercism_checksums.txt.sig For future releases, this commit configures GoReleaser to include an arm64 (also known as aarch64) release asset for each of the existing OSes. Note that we will have separate x86_64 and arm64 release assets for macOS; previously macOS users on arm64 had to run the x86_64 binary via Rosetta (or build the CLI themselves). At least for now, let's avoid adding a fat binary. But note that GoReleaser does support it [1]. [1] https://goreleaser.com/customization/universalbinaries/ Closes: #966 * go.mod, go.sum: bump `golang.org/x/sys` from 20170803 to 20201202 This commits the result of running go get golang.org/x/sys@v0.0.0-20201202213521-69691e467435 to fix a build failure for freebsd_arm64. This seems to be the minimum bump to fix that failure without introducing a build failure for darwin_arm64 and openbsd_arm64. We cannot bump to the latest release (0.3.0, 2022-12-03) because that causes the Linux and macOS CI jobs to fail with: Error: ../../../go/pkg/mod/golang.org/x/sys@v0.3.0/unix/syscall.go:83:16: undefined: unsafe.Slice Error: ../../../go/pkg/mod/golang.org/x/sys@v0.3.0/unix/syscall_darwin.go:95:8: undefined: unsafe.Slice Error: ../../../go/pkg/mod/golang.org/x/sys@v0.3.0/unix/syscall_unix.go:118:7: undefined: unsafe.Slice Error: ../../../go/pkg/mod/golang.org/x/sys@v0.3.0/unix/sysvshm_unix.go:33:7: undefined: unsafe.Slice note: module requires Go 1.17 and we need other changes in order to bump the minimum Go version. --- .goreleaser.yml | 1 + go.mod | 2 +- go.sum | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index ca7d2bbcb..cb55b79f4 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -15,6 +15,7 @@ builds: - amd64 - 386 - arm + - arm64 - ppc64 goarm: - 5 diff --git a/go.mod b/go.mod index a3723bfad..91e79ff1a 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/spf13/viper v0.0.0-20180507071007-15738813a09d github.com/stretchr/testify v1.1.4 golang.org/x/net v0.0.0-20170726083632-f5079bd7f6f7 - golang.org/x/sys v0.0.0-20170803140359-d8f5ea21b929 + golang.org/x/sys v0.0.0-20201202213521-69691e467435 golang.org/x/text v0.0.0-20170730040918-3bd178b88a81 gopkg.in/yaml.v2 v2.0.0-20170721122051-25c4ec802a7d ) diff --git a/go.sum b/go.sum index 3f5f7852a..7d53fd399 100644 --- a/go.sum +++ b/go.sum @@ -38,6 +38,8 @@ golang.org/x/net v0.0.0-20170726083632-f5079bd7f6f7 h1:1Pw+ZX4dmGORIwGkTwnUr7RFu golang.org/x/net v0.0.0-20170726083632-f5079bd7f6f7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/sys v0.0.0-20170803140359-d8f5ea21b929 h1:M4VPQYSW/nB4Bcg1XMD4yW2sprnwerD3Kb6apRphtZw= golang.org/x/sys v0.0.0-20170803140359-d8f5ea21b929/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20201202213521-69691e467435 h1:25AvDqqB9PrNqj1FLf2/70I4W0L19qqoaFq3gjNwbKk= +golang.org/x/sys v0.0.0-20201202213521-69691e467435/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.0.0-20170730040918-3bd178b88a81 h1:7aXI3TQ9sZ4JdDoIDGjxL6G2mQxlsPy9dySnJaL6Bdk= golang.org/x/text v0.0.0-20170730040918-3bd178b88a81/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= gopkg.in/yaml.v2 v2.0.0-20170721122051-25c4ec802a7d h1:2DX7x6HUDGZUyuEDAhUsQQNqkb1zvDyKTjVoTdzaEzo= From bfd0789e57da9b70155f23741eb56bd18b44f02f Mon Sep 17 00:00:00 2001 From: Katrina Owen Date: Tue, 13 Dec 2022 19:09:41 +0100 Subject: [PATCH 032/142] Add custom token to community contributions workflow (#1076) The pause-community-contributions workflow makes a call to the GitHub API to check if the person contributing is a member of the organization. However, this call currently fails if the contributor has set their membership to 'private'. This is because the default token provided for GitHub Actions only has permissions for the repository, not for the organization. With this token, we're not allowed to see private memberships. We've created a custom, org-wide secret containing a personal token that has permissions to read organization membership. Unfortunately the secret cannot be accessed directly by the shared workflow, it has to be passed in. We updated the shared workflow to use the token, if it is provided, and this PR updates the workflow in this repo to pass the secret. Until this is merged, contributions from people with private membership in the Exercism organization will be automatically closed. Note that this PR also removes the workflow_dispatch which fails if you try to use it. --- .github/workflows/pause-community-contributions.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/pause-community-contributions.yml b/.github/workflows/pause-community-contributions.yml index 055ff8676..46f0c60b4 100644 --- a/.github/workflows/pause-community-contributions.yml +++ b/.github/workflows/pause-community-contributions.yml @@ -7,7 +7,6 @@ on: pull_request_target: types: - opened - workflow_dispatch: permissions: issues: write @@ -19,3 +18,5 @@ jobs: uses: exercism/github-actions/.github/workflows/community-contributions.yml@main with: forum_category: support + secrets: + github_membership_token: ${{ secrets.COMMUNITY_CONTRIBUTIONS_WORKFLOW_TOKEN }} From 94755c68f030fac1f8bff3f112c83fe69d7fd8c4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Dec 2022 19:59:48 +0100 Subject: [PATCH 033/142] Bump actions/checkout from 3.0.0 to 3.2.0 (#1077) Bumps [actions/checkout](https://github.com/actions/checkout) from 3.0.0 to 3.2.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/a12a3943b4bdde767164f792f33f40b04645d846...755da8c3cf115ac066823e79a1e1788f8940201b) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8f38a110d..c396f2e2a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,7 @@ jobs: os: [ubuntu-latest, windows-latest, macOS-latest] steps: - - uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846 + - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - uses: actions/setup-go@bfdd3570ce990073878bf10f6b2d79082de49492 with: @@ -37,7 +37,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846 + - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - name: Check formatting run: ./.gha.gofmt.sh From edee2079639ae4e5f2e628eb689bf489ed10b389 Mon Sep 17 00:00:00 2001 From: Nate Eagleson Date: Mon, 13 Feb 2023 11:37:26 -0500 Subject: [PATCH 034/142] Explain auto-close policy in ISSUE_TEMPLATE.md (#1084) * Explain auto-close policy in ISSUE_TEMPLATE.md Per discussion in this forum thread: http://forum.exercism.org/t/update-github-issue-template-to-warn-users-new-issues-are-being-auto-closed/3676/2 * Ask people to use the forum instead in .github/ISSUE_TEMPLATE.md Co-authored-by: Jeremy Walker --------- Co-authored-by: Jeremy Walker --- .github/ISSUE_TEMPLATE.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 04f539626..73ac4bb57 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,7 +1,4 @@ From a8ffc316a462ea07a5e4cfbfb3df24eb0f9342eb Mon Sep 17 00:00:00 2001 From: David Brownman Date: Fri, 28 Jul 2023 00:44:39 -0700 Subject: [PATCH 035/142] Add `test` command to run any unit test (#1092) This commit adds a `test` command that allows the student to run the tests for an exercise without knowing the track-specific test command. This makes it easier for the student to get started. For debugging and education purposes, we print the command that is used to run the tests. --- CHANGELOG.md | 2 + cmd/cmd_test.go | 14 +- cmd/test.go | 84 +++++++++ workspace/exercise_config.go | 57 ++++++ workspace/exercise_config_test.go | 98 ++++++++++ workspace/test_configurations.go | 252 ++++++++++++++++++++++++++ workspace/test_configurations_test.go | 103 +++++++++++ 7 files changed, 604 insertions(+), 6 deletions(-) create mode 100644 cmd/test.go create mode 100644 workspace/exercise_config.go create mode 100644 workspace/exercise_config_test.go create mode 100644 workspace/test_configurations.go create mode 100644 workspace/test_configurations_test.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 110c6fe80..1c84fa0a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ The exercism CLI follows [semantic versioning](http://semver.org/). ---------------- ## Next Release +* [#1092](https://github.com/exercism/cli/pull/1092) Add `exercism test` command to run the unit tests for nearly any track (inspired by [universal-test-runner](https://github.com/xavdid/universal-test-runner)) - [@xavdid] * **Your contribution here** ## v3.1.0 (2022-10-04) @@ -489,5 +490,6 @@ All changes by [@msgehard] [@sfairchild]: https://github.com/sfairchild [@simonjefford]: https://github.com/simonjefford [@srt32]: https://github.com/srt32 +[@xavdid]: https://github.com/xavdid [@williandrade]: https://github.com/williandrade [@zabawaba99]: https://github.com/zabawaba99 diff --git a/cmd/cmd_test.go b/cmd/cmd_test.go index 76ed0634e..fee08cd98 100644 --- a/cmd/cmd_test.go +++ b/cmd/cmd_test.go @@ -26,12 +26,14 @@ const cfgHomeKey = "EXERCISM_CONFIG_HOME" // test, call the command by calling Execute on the App. // // Example: -// cmdTest := &CommandTest{ -// Cmd: myCmd, -// InitFn: initMyCmd, -// Args: []string{"fakeapp", "mycommand", "arg1", "--flag", "value"}, -// MockInteractiveResponse: "first-input\nsecond\n", -// } +// +// cmdTest := &CommandTest{ +// Cmd: myCmd, +// InitFn: initMyCmd, +// Args: []string{"fakeapp", "mycommand", "arg1", "--flag", "value"}, +// MockInteractiveResponse: "first-input\nsecond\n", +// } +// // cmdTest.Setup(t) // defer cmdTest.Teardown(t) // ... diff --git a/cmd/test.go b/cmd/test.go new file mode 100644 index 000000000..8f5b54e35 --- /dev/null +++ b/cmd/test.go @@ -0,0 +1,84 @@ +package cmd + +import ( + "fmt" + "log" + "os" + "os/exec" + "strings" + + "github.com/exercism/cli/workspace" + "github.com/spf13/cobra" +) + +var testCmd = &cobra.Command{ + Use: "test", + Aliases: []string{"t"}, + Short: "Run the exercise's tests.", + Long: `Run the exercise's tests. + + Run this command in an exercise's root directory.`, + RunE: func(cmd *cobra.Command, args []string) error { + return runTest(args) + }, +} + +func runTest(args []string) error { + track, err := getTrack() + if err != nil { + return err + } + + testConf, ok := workspace.TestConfigurations[track] + + if !ok { + return fmt.Errorf("the \"%s\" track does not yet support running tests using the Exercism CLI. Please see HELP.md for testing instructions", track) + } + + command, err := testConf.GetTestCommand() + if err != nil { + return err + } + cmdParts := strings.Split(command, " ") + + // pass args/flags to this command down to the test handler + if len(args) > 0 { + cmdParts = append(cmdParts, args...) + } + + fmt.Printf("Running tests via `%s`\n\n", strings.Join(cmdParts, " ")) + exerciseTestCmd := exec.Command(cmdParts[0], cmdParts[1:]...) + + // pipe output directly out, preserving any color + exerciseTestCmd.Stdout = os.Stdout + exerciseTestCmd.Stderr = os.Stderr + + err = exerciseTestCmd.Run() + if err != nil { + // unclear what other errors would pop up here, but it pays to be defensive + if exitErr, ok := err.(*exec.ExitError); ok { + exitCode := exitErr.ExitCode() + // if subcommand returned a non-zero exit code, exit with the same + os.Exit(exitCode) + } else { + log.Fatalf("Failed to get error from failed subcommand: %v", err) + } + } + return nil +} + +func getTrack() (string, error) { + metadata, err := workspace.NewExerciseMetadata(".") + if err != nil { + return "", err + } + if metadata.Track == "" { + return "", fmt.Errorf("no track found in exercise metadata") + } + + return metadata.Track, nil +} + +func init() { + RootCmd.AddCommand(testCmd) +} diff --git a/workspace/exercise_config.go b/workspace/exercise_config.go new file mode 100644 index 000000000..9b0164ebb --- /dev/null +++ b/workspace/exercise_config.go @@ -0,0 +1,57 @@ +package workspace + +import ( + "encoding/json" + "errors" + "io/ioutil" + "path/filepath" +) + +const configFilename = "config.json" + +var configFilepath = filepath.Join(ignoreSubdir, configFilename) + +// ExerciseConfig contains exercise metadata. +// Note: we only use a subset of its fields +type ExerciseConfig struct { + Files struct { + Solution []string `json:"solution"` + Test []string `json:"test"` + } `json:"files"` +} + +// NewExerciseConfig reads exercise metadata from a file in the given directory. +func NewExerciseConfig(dir string) (*ExerciseConfig, error) { + b, err := ioutil.ReadFile(filepath.Join(dir, configFilepath)) + if err != nil { + return nil, err + } + var config ExerciseConfig + if err := json.Unmarshal(b, &config); err != nil { + return nil, err + } + + return &config, nil +} + +// GetTestFiles finds returns the names of the file(s) that hold unit tests for this exercise, if any +func (c *ExerciseConfig) GetSolutionFiles() ([]string, error) { + result := c.Files.Solution + if result == nil { + // solution file(s) key was missing in config json, which is an error when calling this fuction + return []string{}, errors.New("no `files.solution` key in your `config.json`. Was it removed by mistake?") + } + + return result, nil +} + +// GetTestFiles finds returns the names of the file(s) that hold unit tests for this exercise, if any +func (c *ExerciseConfig) GetTestFiles() ([]string, error) { + result := c.Files.Test + if result == nil { + // test file(s) key was missing in config json, which is an error when calling this fuction + return []string{}, errors.New("no `files.test` key in your `config.json`. Was it removed by mistake?") + } + + return result, nil +} diff --git a/workspace/exercise_config_test.go b/workspace/exercise_config_test.go new file mode 100644 index 000000000..d07264c0d --- /dev/null +++ b/workspace/exercise_config_test.go @@ -0,0 +1,98 @@ +package workspace + +import ( + "io/ioutil" + "os" + "path/filepath" + "strings" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestExerciseConfig(t *testing.T) { + dir, err := ioutil.TempDir("", "exercise_config") + assert.NoError(t, err) + defer os.RemoveAll(dir) + + err = os.Mkdir(filepath.Join(dir, ".exercism"), os.ModePerm) + assert.NoError(t, err) + + f, err := os.Create(filepath.Join(dir, ".exercism", "config.json")) + assert.NoError(t, err) + defer f.Close() + + _, err = f.WriteString(`{ "blurb": "Learn about the basics of Ruby by following a lasagna recipe.", "authors": ["iHiD", "pvcarrera"], "files": { "solution": ["lasagna.rb"], "test": ["lasagna_test.rb"], "exemplar": [".meta/exemplar.rb"] } } `) + assert.NoError(t, err) + + ec, err := NewExerciseConfig(dir) + assert.NoError(t, err) + + assert.Equal(t, ec.Files.Solution, []string{"lasagna.rb"}) + solutionFiles, err := ec.GetSolutionFiles() + assert.NoError(t, err) + assert.Equal(t, solutionFiles, []string{"lasagna.rb"}) + + assert.Equal(t, ec.Files.Test, []string{"lasagna_test.rb"}) + testFiles, err := ec.GetTestFiles() + assert.NoError(t, err) + assert.Equal(t, testFiles, []string{"lasagna_test.rb"}) +} + +func TestExerciseConfigNoTestKey(t *testing.T) { + dir, err := ioutil.TempDir("", "exercise_config") + assert.NoError(t, err) + defer os.RemoveAll(dir) + + err = os.Mkdir(filepath.Join(dir, ".exercism"), os.ModePerm) + assert.NoError(t, err) + + f, err := os.Create(filepath.Join(dir, ".exercism", "config.json")) + assert.NoError(t, err) + defer f.Close() + + _, err = f.WriteString(`{ "blurb": "Learn about the basics of Ruby by following a lasagna recipe.", "authors": ["iHiD", "pvcarrera"], "files": { "exemplar": [".meta/exemplar.rb"] } } `) + assert.NoError(t, err) + + ec, err := NewExerciseConfig(dir) + assert.NoError(t, err) + + _, err = ec.GetSolutionFiles() + assert.Error(t, err, "no `files.solution` key in your `config.json`") + _, err = ec.GetTestFiles() + assert.Error(t, err, "no `files.test` key in your `config.json`") +} + +func TestMissingExerciseConfig(t *testing.T) { + dir, err := ioutil.TempDir("", "exercise_config") + assert.NoError(t, err) + defer os.RemoveAll(dir) + + _, err = NewExerciseConfig(dir) + assert.Error(t, err) + // any assertions about this error message have to work across all platforms, so be vague + // unix: ".exercism/config.json: no such file or directory" + // windows: "open .exercism\config.json: The system cannot find the path specified." + assert.Contains(t, err.Error(), filepath.Join(".exercism", "config.json:")) +} + +func TestInvalidExerciseConfig(t *testing.T) { + dir, err := ioutil.TempDir("", "exercise_config") + assert.NoError(t, err) + defer os.RemoveAll(dir) + + err = os.Mkdir(filepath.Join(dir, ".exercism"), os.ModePerm) + assert.NoError(t, err) + + f, err := os.Create(filepath.Join(dir, ".exercism", "config.json")) + assert.NoError(t, err) + defer f.Close() + + // invalid JSON + _, err = f.WriteString(`{ "blurb": "Learn about the basics of Ruby by following a lasagna recipe.", "authors": ["iHiD", "pvcarr `) + assert.NoError(t, err) + + _, err = NewExerciseConfig(dir) + assert.Error(t, err) + assert.True(t, strings.Contains(err.Error(), "unexpected end of JSON input")) +} diff --git a/workspace/test_configurations.go b/workspace/test_configurations.go new file mode 100644 index 000000000..32c6fbc3a --- /dev/null +++ b/workspace/test_configurations.go @@ -0,0 +1,252 @@ +package workspace + +import ( + "fmt" + "runtime" + "strings" +) + +type TestConfiguration struct { + // The static portion of the test Command, which will be run for every test on this track. Examples include `cargo test` or `go test`. + // Might be empty if there are platform-specific versions + Command string + + // Windows-specific test command. Mostly relevant for tests wrapped by shell invocations. Falls back to `Command` if we're not running windows or this is empty. + WindowsCommand string +} + +func (c *TestConfiguration) GetTestCommand() (string, error) { + var cmd string + if runtime.GOOS == "windows" && c.WindowsCommand != "" { + cmd = c.WindowsCommand + } else { + cmd = c.Command + } + + // pre-declare these so we can conditionally initialize them + var exerciseConfig *ExerciseConfig + var err error + + if strings.Contains(cmd, "{{") { + // only read exercise's config.json if we need it + exerciseConfig, err = NewExerciseConfig(".") + if err != nil { + return "", err + } + } + + if strings.Contains(cmd, "{{solution_files}}") { + if exerciseConfig == nil { + return "", fmt.Errorf("exerciseConfig not initialize before use") + } + solutionFiles, err := exerciseConfig.GetSolutionFiles() + if err != nil { + return "", err + } + cmd = strings.ReplaceAll(cmd, "{{solution_files}}", strings.Join(solutionFiles, " ")) + } + if strings.Contains(cmd, "{{test_files}}") { + if exerciseConfig == nil { + return "", fmt.Errorf("exerciseConfig not initialize before use") + } + testFiles, err := exerciseConfig.GetTestFiles() + if err != nil { + return "", err + } + cmd = strings.ReplaceAll(cmd, "{{test_files}}", strings.Join(testFiles, " ")) + } + + return cmd, nil +} + +// some tracks aren't (or won't be) implemented; every track is listed either way +var TestConfigurations = map[string]TestConfiguration{ + "8th": { + Command: "bash tester.sh", + WindowsCommand: "tester.bat", + }, + // abap: tests are run via "ABAP Development Tools", not the CLI + "awk": { + Command: "bats {{test_files}}", + }, + "ballerina": { + Command: "bal test", + }, + "bash": { + Command: "bats {{test_files}}", + }, + "c": { + Command: "make", + }, + "cfml": { + Command: "box task run TestRunner", + }, + "clojure": { + // chosen because the docs recommend `clj` by default and `lein` as optional + Command: "clj -X:test", + }, + "cobol": { + Command: "bash test.sh", + WindowsCommand: "pwsh test.ps1", + }, + "coffeescript": { + Command: "jasmine-node --coffee {{test_files}}", + }, + // common-lisp: tests are loaded into a "running Lisp implementation", not the CLI directly + "cpp": { + Command: "make", + }, + "crystal": { + Command: "crystal spec", + }, + "csharp": { + Command: "dotnet test", + }, + "d": { + // this always works even if the user installed DUB + Command: "dmd source/*.d -de -w -main -unittest", + }, + "dart": { + Command: "dart test", + }, + // delphi: tests are run via IDE + "elixir": { + Command: "mix test", + }, + "elm": { + Command: "elm-test", + }, + "emacs-lisp": { + Command: "emacs -batch -l ert -l *-test.el -f ert-run-tests-batch-and-exit", + }, + "erlang": { + Command: "rebar3 eunit", + }, + "fortran": { + Command: "make", + }, + "fsharp": { + Command: "dotnet test", + }, + "gleam": { + Command: "gleam test", + }, + "go": { + Command: "go test", + }, + "groovy": { + Command: "gradle test", + }, + "haskell": { + Command: "stack test", + }, + "java": { + Command: "gradle test", + }, + "javascript": { + Command: "npm run test", + }, + "jq": { + Command: "bats {{test_files}}", + }, + "julia": { + Command: "julia runtests.jl", + }, + "kotlin": { + Command: "./gradlew test", + WindowsCommand: "gradlew.bat test", + }, + "lfe": { + Command: "make test", + }, + "lua": { + Command: "busted", + }, + "mips": { + Command: "java -jar /path/to/mars.jar nc runner.mips impl.mips", + }, + "nim": { + Command: "nim r {{test_files}}", + }, + // objective-c: tests are run via XCode. There's a CLI option (ruby gem `objc`), but the docs note that this is an inferior experience + "ocaml": { + Command: "make", + }, + "perl5": { + Command: "prove .", + }, + // pharo-smalltalk: tests are run via IDE + "php": { + Command: "phpunit {{test_files}}", + }, + // plsql: test are run via a "mounted oracle db" + "powershell": { + Command: "Invoke-Pester", + }, + "prolog": { + Command: "swipl -f {{solution_files}} -s {{test_files}} -g run_tests,halt -t 'halt(1)'", + }, + "purescript": { + Command: "spago test", + }, + "python": { + Command: "python3 -m pytest -o markers=task {{test_files}}", + }, + "r": { + Command: "Rscript {{test_files}}", + }, + "racket": { + Command: "raco test {{test_files}}", + }, + "raku": { + Command: "prove6 {{test_files}}", + }, + "reasonml": { + Command: "npm run test", + }, + "red": { + Command: "red {{test_files}}", + }, + "ruby": { + Command: "ruby {{test_files}}", + }, + "rust": { + Command: "cargo test --", + }, + "scala": { + Command: "sbt test", + }, + // scheme: docs present 2 equally valid test methods (`make chez` and `make guile`). So I wasn't sure which to pick + "sml": { + Command: "poly -q --use {{test_files}}", + }, + "swift": { + Command: "swift test", + }, + "tcl": { + Command: "tclsh {{test_files}}", + }, + "typescript": { + Command: "yarn test", + }, + // unison: tests are run from an active UCM session + "vbnet": { + Command: "dotnet test", + }, + // vimscript: tests are run from inside a vim session + "vlang": { + Command: "v -stats test run_test.v", + }, + "wasm": { + Command: "npm run test", + }, + "wren": { + Command: "wrenc {{test_files}}", + }, + "x86-64-assembly": { + Command: "make", + }, + "zig": { + Command: "zig test {{test_files}}", + }, +} diff --git a/workspace/test_configurations_test.go b/workspace/test_configurations_test.go new file mode 100644 index 000000000..97ff40902 --- /dev/null +++ b/workspace/test_configurations_test.go @@ -0,0 +1,103 @@ +package workspace + +import ( + "os" + "path/filepath" + "runtime" + "strings" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestGetCommand(t *testing.T) { + testConfig, ok := TestConfigurations["elixir"] + assert.True(t, ok, "unexpectedly unable to find elixir test config") + + cmd, err := testConfig.GetTestCommand() + assert.NoError(t, err) + + assert.Equal(t, cmd, "mix test") +} + +func TestWindowsCommands(t *testing.T) { + testConfig, ok := TestConfigurations["cobol"] + assert.True(t, ok, "unexpectedly unable to find cobol test config") + + cmd, err := testConfig.GetTestCommand() + assert.NoError(t, err) + + if runtime.GOOS == "windows" { + assert.Contains(t, cmd, ".ps1") + assert.NotContains(t, cmd, ".sh") + } else { + assert.Contains(t, cmd, ".sh") + assert.NotContains(t, cmd, ".ps1") + } +} + +func TestGetCommandMissingConfig(t *testing.T) { + testConfig, ok := TestConfigurations["ruby"] + assert.True(t, ok, "unexpectedly unable to find ruby test config") + + _, err := testConfig.GetTestCommand() + assert.Error(t, err) + // any assertions about this error message have to work across all platforms, so be vague + // unix: ".exercism/config.json: no such file or directory" + // windows: "open .exercism\config.json: The system cannot find the path specified." + assert.Contains(t, err.Error(), filepath.Join(".exercism", "config.json:")) +} + +func TestIncludesSolutionAndTestFilesInCommand(t *testing.T) { + testConfig, ok := TestConfigurations["prolog"] + assert.True(t, ok, "unexpectedly unable to find prolog test config") + + // this creates a config file in the test directory and removes it + dir := filepath.Join(".", ".exercism") + defer os.RemoveAll(dir) + err := os.Mkdir(dir, os.ModePerm) + assert.NoError(t, err) + + f, err := os.Create(filepath.Join(dir, "config.json")) + assert.NoError(t, err) + defer f.Close() + + _, err = f.WriteString(`{ "blurb": "Learn about the basics of Prolog by following a lasagna recipe.", "authors": ["iHiD", "pvcarrera"], "files": { "solution": ["lasagna.pl"], "test": ["lasagna_tests.plt"] } } `) + assert.NoError(t, err) + + cmd, err := testConfig.GetTestCommand() + assert.NoError(t, err) + assert.Equal(t, cmd, "swipl -f lasagna.pl -s lasagna_tests.plt -g run_tests,halt -t 'halt(1)'") +} + +func TestIncludesTestFilesInCommand(t *testing.T) { + testConfig, ok := TestConfigurations["ruby"] + assert.True(t, ok, "unexpectedly unable to find ruby test config") + + // this creates a config file in the test directory and removes it + dir := filepath.Join(".", ".exercism") + defer os.RemoveAll(dir) + err := os.Mkdir(dir, os.ModePerm) + assert.NoError(t, err) + + f, err := os.Create(filepath.Join(dir, "config.json")) + assert.NoError(t, err) + defer f.Close() + + _, err = f.WriteString(`{ "blurb": "Learn about the basics of Ruby by following a lasagna recipe.", "authors": ["iHiD", "pvcarrera"], "files": { "solution": ["lasagna.rb"], "test": ["lasagna_test.rb", "some_other_file.rb"], "exemplar": [".meta/exemplar.rb"] } } `) + assert.NoError(t, err) + + cmd, err := testConfig.GetTestCommand() + assert.NoError(t, err) + assert.Equal(t, cmd, "ruby lasagna_test.rb some_other_file.rb") +} + +func TestRustHasTrailingDashes(t *testing.T) { + testConfig, ok := TestConfigurations["rust"] + assert.True(t, ok, "unexpectedly unable to find rust test config") + + cmd, err := testConfig.GetTestCommand() + assert.NoError(t, err) + + assert.True(t, strings.HasSuffix(cmd, "--"), "rust's test command should have trailing dashes") +} From 3551c62b2cc844255badd0b9926f5362741cf93c Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Fri, 28 Jul 2023 14:02:02 +0200 Subject: [PATCH 036/142] Bump version to 3.2.0 (#1093) --- CHANGELOG.md | 5 ++++- cmd/version.go | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c84fa0a3..a1dcca2ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,9 +5,12 @@ The exercism CLI follows [semantic versioning](http://semver.org/). ---------------- ## Next Release -* [#1092](https://github.com/exercism/cli/pull/1092) Add `exercism test` command to run the unit tests for nearly any track (inspired by [universal-test-runner](https://github.com/xavdid/universal-test-runner)) - [@xavdid] * **Your contribution here** +## v3.2.0 (2023-07-28) +* [#1092](https://github.com/exercism/cli/pull/1092) Add `exercism test` command to run the unit tests for nearly any track (inspired by [universal-test-runner](https://github.com/xavdid/universal-test-runner)) - [@xavdid] +* [#1073](https://github.com/exercism/cli/pull/1073) Add `arm64` build for each OS + ## v3.1.0 (2022-10-04) * [#979](https://github.com/exercism/cli/pull/979) Protect existing solutions from being overwritten by 'download' - [@harugo] * [#981](https://github.com/exercism/cli/pull/981) Check if authorisation header is set before attempting to extract token - [@harugo] diff --git a/cmd/version.go b/cmd/version.go index 069866b78..d8e287f4a 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -9,7 +9,7 @@ import ( // Version is the version of the current build. // It follows semantic versioning. -const Version = "3.1.0" +const Version = "3.2.0" // checkLatest flag for version command. var checkLatest bool From d0faf4c2fef579ac85012c74cb285b969c274ffa Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Fri, 28 Jul 2023 14:53:22 +0200 Subject: [PATCH 037/142] Fix deprecated argument to goreleaser (#1094) --- RELEASE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RELEASE.md b/RELEASE.md index bf3e1c8bf..fe41e37ea 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -33,7 +33,7 @@ Commit this change on a branch along with the CHANGELOG updates in a single comm ```bash # Test run -goreleaser --skip-publish --snapshot --rm-dist +goreleaser --skip-publish --snapshot --clean # Create a new tag on the main branch and push it git tag -a v3.0.16 -m "Trying out GoReleaser" From ca046ee7579aacac64b1a4f1390e5dd6084b9415 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Aug 2023 10:31:17 +0200 Subject: [PATCH 038/142] Bump actions/setup-go from 2.2.0 to 4.0.0 (#1088) Bumps [actions/setup-go](https://github.com/actions/setup-go) from 2.2.0 to 4.0.0. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](https://github.com/actions/setup-go/compare/bfdd3570ce990073878bf10f6b2d79082de49492...4d34df0c2316fe8122ab82dc22947d607c0c91f9) --- updated-dependencies: - dependency-name: actions/setup-go dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Erik Schierboom --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c396f2e2a..493acf702 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: steps: - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - - uses: actions/setup-go@bfdd3570ce990073878bf10f6b2d79082de49492 + - uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 with: go-version: ${{ matrix.go-version }} From 2ab0439a2cecf71ef418b470471b6dbe6ed238ba Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Aug 2023 10:31:29 +0200 Subject: [PATCH 039/142] Bump actions/checkout from 3.2.0 to 3.5.0 (#1091) Bumps [actions/checkout](https://github.com/actions/checkout) from 3.2.0 to 3.5.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/755da8c3cf115ac066823e79a1e1788f8940201b...8f4b7f84864484a7bf31766abe9204da3cbe65b3) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Erik Schierboom --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 493acf702..f3913210b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,7 @@ jobs: os: [ubuntu-latest, windows-latest, macOS-latest] steps: - - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b + - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 - uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 with: @@ -37,7 +37,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b + - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 - name: Check formatting run: ./.gha.gofmt.sh From eaf599b3a89125a9667800f77b8ba07473a07192 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Tue, 1 Aug 2023 11:27:35 +0200 Subject: [PATCH 040/142] Fix goreleaser name templates (#1095) --- .goreleaser.yml | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index cb55b79f4..c2f9886af 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -37,10 +37,14 @@ changelog: - '^test:' archives: - - name_template: "{{ .ProjectName }}-{{ .Version }}-{{ .Os }}-{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}" - replacements: - amd64: x86_64 - 386: i386 + - name_template: >- + {{- .ProjectName }}- + {{- .Version }}- + {{- .Os }}- + {{- if eq .Arch "amd64" }}x86_64 + {{- else if eq .Arch "386" }}i386 + {{- else }}{{- .Arch }}{{ end }} + {{- if .Arm }}v{{- .Arm }}{{ end }} format_overrides: - goos: windows format: zip @@ -92,10 +96,14 @@ snapcrafts: # https://snapcraft.io/docs/reference/channels grade: stable description: Exercism is an online platform designed to help you improve your coding skills through practice and mentorship. Exercism provides you with thousands of exercises spread across numerous language tracks. Each one is a fun and interesting challenge designed to teach you a little more about the features of a language. - name_template: "{{ .ProjectName }}-{{ .Version }}-{{ .Os }}-{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}" - replacements: - amd64: x86_64 - 386: i386 + name_template: >- + {{- .ProjectName }}- + {{- .Version }}- + {{- .Os }}- + {{- if eq .Arch "amd64" }}x86_64 + {{- else if eq .Arch "386" }}i386 + {{- else }}{{- .Arch }}{{ end }} + {{- if .Arm }}v{{- .Arm }}{{ end }} apps: exercism: plugs: ["home", "network", "removable-media","personal-files"] From 1464c3836b0a7204573f4726b47445309e466e32 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Tue, 1 Aug 2023 12:56:50 +0200 Subject: [PATCH 041/142] Fix link in release doc (#1096) --- RELEASE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RELEASE.md b/RELEASE.md index fe41e37ea..ce89b8503 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -97,6 +97,6 @@ For more information see [How To Open a Homebrew Pull Request](https://docs.brew ## Update the docs site If there are any significant changes, we should describe them on -[exercism.io/cli]([https://exercism.io/cli). +[exercism.io/cli](https://exercism.io/cli). The codebase lives at [exercism/website-copy](https://github.com/exercism/website-copy) in `pages/cli.md`. From cddc1228f3a515b4ee49442eebadc99329b156c2 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Tue, 1 Aug 2023 13:02:32 +0200 Subject: [PATCH 042/142] More release doc cleanup (#1097) --- RELEASE.md | 31 ++++++++----------------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/RELEASE.md b/RELEASE.md index ce89b8503..47645c282 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -12,7 +12,7 @@ release process. ## Confirm / Update the Changelog -Make sure all the recent changes are reflected in the "next release" section of the CHANGELOG.md file. All the changes in the "next release" section should be moved to a new section that describes the version number, and gives it a date. +Make sure all the recent changes are reflected in the "next release" section of the CHANGELOG.md file. All the changes in the "next release" section should be moved to a new section that describes the version number, and gives it a date. You can view changes using the /compare/ view: https://github.com/exercism/cli/compare/$PREVIOUS_RELEASE...main @@ -40,7 +40,7 @@ git tag -a v3.0.16 -m "Trying out GoReleaser" git push origin v3.0.16 # Build and release -goreleaser --rm-dist +goreleaser --clean # You must be logged into snapcraft to publish a new snap snapcraft login @@ -53,9 +53,8 @@ for f in `ls dist/*.snap`; do snapcraft push --release=stable $f; done ## Cut Release on GitHub -Run [exercism-cp-archive-hack.sh](https://gist.github.com/ekingery/961650fca4e2233098c8320f32736836) which takes the new archive files and renames them to match the old naming scheme for backward compatibility. Until mid to late 2020, we will need to manually upload the backward-compatible archive files generated in `/tmp/exercism_tmp_upload`. - -The generated archive files should be uploaded to the [draft release page created by GoReleaser](https://github.com/exercism/cli/releases). Describe the release, select a specific commit to target, paste the following release text, and describe the new changes. +At this point, Goreleaser will a created a draft PR at https://github.com/exercism/cli/releases/tag/vX.Y.Z. +On that page, update the release description to: ``` To install, follow the interactive installation instructions at https://exercism.io/cli-walkthrough @@ -64,32 +63,18 @@ To install, follow the interactive installation instructions at https://exercism [describe changes in this release] ``` - Lastly, test and publish the draft - +Lastly, test and publish the draft ## Update Homebrew -This is helpful for the (many) Mac OS X users. - -First, get a copy of the latest tarball of the source code: - -``` -cd ~/tmp && wget https://github.com/exercism/cli/archive/vX.Y.Z.tar.gz -``` - -Get the SHA256 of the tarball: - -``` -shasum -a 256 vX.Y.Z.tar.gz -``` - -Update the homebrew formula: +Next, we'll submit a PR to Homebrew to update the Exercism formula (which is how macOS users usually download the CLI): ``` +cd /tmp && curl -O https://github.com/exercism/cli/archive/vX.Y.Z.tar.gz cd $(brew --repository) git checkout master brew update -brew bump-formula-pr --strict exercism --url=https://github.com/exercism/cli/archive/vX.Y.Z.tar.gz --sha256=$SHA +brew bump-formula-pr --strict exercism --url=https://github.com/exercism/cli/archive/vX.Y.Z.tar.gz --sha256=$(shasum -a 256 /tmp/vX.Y.Z.tar.gz) ``` For more information see [How To Open a Homebrew Pull Request](https://docs.brew.sh/How-To-Open-a-Homebrew-Pull-Request). From ba0ea34a356fe43beed8765f3255a550f8e241d2 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Tue, 1 Aug 2023 14:12:12 +0200 Subject: [PATCH 043/142] Remove snapcraft (#1098) --- .goreleaser.yml | 32 -------------------------------- RELEASE.md | 7 ------- 2 files changed, 39 deletions(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index c2f9886af..ee029e45c 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -79,35 +79,3 @@ release: # brews: # We do not use the brew config, which is for taps, not core forumulas. - -snapcrafts: - - - name: exercism - license: MIT - # Whether to publish the snap to the snapcraft store. - # Remember you need to `snapcraft login` first. - # Defaults to false. - # publish: true - summary: Command-line client for https://exercism.org - # https://snapcraft.io/docs/reference/confinement - confinement: strict - # A snap of type base to be used as the execution environment for this snap. - base: core18 - # https://snapcraft.io/docs/reference/channels - grade: stable - description: Exercism is an online platform designed to help you improve your coding skills through practice and mentorship. Exercism provides you with thousands of exercises spread across numerous language tracks. Each one is a fun and interesting challenge designed to teach you a little more about the features of a language. - name_template: >- - {{- .ProjectName }}- - {{- .Version }}- - {{- .Os }}- - {{- if eq .Arch "amd64" }}x86_64 - {{- else if eq .Arch "386" }}i386 - {{- else }}{{- .Arch }}{{ end }} - {{- if .Arm }}v{{- .Arm }}{{ end }} - apps: - exercism: - plugs: ["home", "network", "removable-media","personal-files"] - plugs: - personal-files: - write: - - $HOME/ diff --git a/RELEASE.md b/RELEASE.md index 47645c282..1592c7519 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -6,7 +6,6 @@ release process. ## Requirements 1. [Install GoReleaser](https://goreleaser.com/install/) -1. [Install snapcraft](https://snapcraft.io/docs/snapcraft-overview) 1. [Setup GitHub token](https://goreleaser.com/scm/github/) 1. Have a gpg key installed on your machine - it is [used for signing the artifacts](https://goreleaser.com/customization/sign/) @@ -42,12 +41,6 @@ git push origin v3.0.16 # Build and release goreleaser --clean -# You must be logged into snapcraft to publish a new snap -snapcraft login - -# Push to snapcraft -for f in `ls dist/*.snap`; do snapcraft push --release=stable $f; done - # [TODO] Push to homebrew ``` From 8b850d25149a98bfe0cca84afc56160b0b5782e0 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Tue, 1 Aug 2023 14:52:18 +0200 Subject: [PATCH 044/142] Simplify release (#1099) * Remove snapcraft * Simply release process --- RELEASE.md | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/RELEASE.md b/RELEASE.md index 1592c7519..1819773af 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -20,23 +20,27 @@ GoReleaser supports the [auto generation of a changelog](https://goreleaser.com/ ## Bump the version -Edit the `Version` constant in `cmd/version.go` +1. Create a branch for the new version +1. Edit the `Version` constant in `cmd/version.go` +1. Update the `CHANGELOG.md` file +1. Commit the updated version +1. Create a PR _Note: It's useful to add the version to the commit message when you bump it: e.g. `Bump version to v2.3.4`._ -In the future we will probably want to replace the hardcoded `Version` constant with [main.version](https://goreleaser.com/cookbooks/using-main.version). Here is a [stack overflow post on injecting to cmd/version.go](https://stackoverflow.com/a/47510909). - -Commit this change on a branch along with the CHANGELOG updates in a single commit, and create a PR for merge to main. - ## Cut a release +Once the version bump PR has been merged, run the following commands: + ```bash +VERSION=$(sed -n -E 's/^const Version = "([0-9]+\.[0-9]+\.[0-9]+)"$/v\1/p' cmd/version.go) + # Test run goreleaser --skip-publish --snapshot --clean # Create a new tag on the main branch and push it -git tag -a v3.0.16 -m "Trying out GoReleaser" -git push origin v3.0.16 +git tag -a "${VERSION}" -m "Trying out GoReleaser" +git push origin "${VERSION}" # Build and release goreleaser --clean From 16b7d8f6d48309a8b2bb5bb6c32d51c3e1cbdcc8 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Fri, 11 Aug 2023 08:50:53 +0200 Subject: [PATCH 045/142] Update release instructions (#1104) --- RELEASE.md | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/RELEASE.md b/RELEASE.md index 1819773af..35c26bfba 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -33,24 +33,31 @@ _Note: It's useful to add the version to the commit message when you bump it: e. Once the version bump PR has been merged, run the following commands: ```bash -VERSION=$(sed -n -E 's/^const Version = "([0-9]+\.[0-9]+\.[0-9]+)"$/v\1/p' cmd/version.go) +VERSION=$(sed -n -E 's/^const Version = "([0-9]+\.[0-9]+\.[0-9]+)"$/\1/p' cmd/version.go) +TAG_NAME="v${VERSION}" # Test run goreleaser --skip-publish --snapshot --clean # Create a new tag on the main branch and push it -git tag -a "${VERSION}" -m "Trying out GoReleaser" -git push origin "${VERSION}" +git tag -a "${TAG_NAME}" -m "Trying out GoReleaser" +git push origin "${TAG_NAME}" # Build and release goreleaser --clean +# Upload copies of the Windows files for use by the Exercism Windows installer +cp "dist/exercism-${VERSION}-windows-i386.zip" dist/exercism-windows-32bit.zip +cp "dist/exercism-${VERSION}-windows-x86_64.zip" dist/exercism-windows-64bit.zip +gh release upload "${TAG_NAME}" dist/exercism-windows-32bit.zip +gh release upload "${TAG_NAME}" dist/exercism-windows-64bit.zip + # [TODO] Push to homebrew ``` ## Cut Release on GitHub -At this point, Goreleaser will a created a draft PR at https://github.com/exercism/cli/releases/tag/vX.Y.Z. +At this point, Goreleaser will have created a draft PR at https://github.com/exercism/cli/releases/tag/vX.Y.Z. On that page, update the release description to: ``` From bbd449ee91cb6ea4fa3d05605f38ea4281d8f8df Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Aug 2023 13:49:04 +0200 Subject: [PATCH 046/142] Bump actions/setup-go from 4.0.0 to 4.1.0 (#1105) Bumps [actions/setup-go](https://github.com/actions/setup-go) from 4.0.0 to 4.1.0. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](https://github.com/actions/setup-go/compare/4d34df0c2316fe8122ab82dc22947d607c0c91f9...93397bea11091df50f3d7e59dc26a7711a8bcfbe) --- updated-dependencies: - dependency-name: actions/setup-go dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f3913210b..688076d0c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: steps: - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 - - uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 + - uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe with: go-version: ${{ matrix.go-version }} From ecd826de4f64cc7a4f3167443701162d4451a09f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Aug 2023 13:49:13 +0200 Subject: [PATCH 047/142] Bump actions/checkout from 3.5.0 to 3.5.3 (#1101) Bumps [actions/checkout](https://github.com/actions/checkout) from 3.5.0 to 3.5.3. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/8f4b7f84864484a7bf31766abe9204da3cbe65b3...c85c95e3d7251135ab7dc9ce3241c5835cc595a9) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 688076d0c..63ee024b0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,7 @@ jobs: os: [ubuntu-latest, windows-latest, macOS-latest] steps: - - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 + - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 - uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe with: @@ -37,7 +37,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 + - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 - name: Check formatting run: ./.gha.gofmt.sh From 0fcf8c28f821728a0e4bbc533b04e1f4a8e0e495 Mon Sep 17 00:00:00 2001 From: Wilken Rivera Date: Wed, 6 Sep 2023 10:35:27 -0400 Subject: [PATCH 048/142] github/workflow/release.yml: Add automated release pipeline (#1106) --- .github/workflows/release.yml | 41 ++++++++++++++ .goreleaser.yml | 101 ++++++++++++++++++++++++---------- .release/header.md | 3 + RELEASE.md | 21 ++----- 4 files changed, 121 insertions(+), 45 deletions(-) create mode 100644 .github/workflows/release.yml create mode 100644 .release/header.md diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..c2c9aecad --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,41 @@ +name: release + +on: + push: + tags: + - 'v*.*.*' # semver release tags + - 'v*.*.*-*' # pre-release tags for testing + +permissions: + contents: write # needed by goreleaser/goreleaser-action for publishing release artifacts + +jobs: + goreleaser: + runs-on: ubuntu-22.04 + steps: + + - name: Checkout code + uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + with: + fetch-depth: 0 + + - name: Set up Go + uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0 + with: + go-version: '1.19' + + - name: Import GPG Key + id: import_gpg + uses: crazy-max/ghaction-import-gpg@72b6676b71ab476b77e676928516f6982eef7a41 # v5.3.0 + with: + gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} + passphrase: ${{ secrets.PASSPHRASE }} + + - name: Cut Release + uses: goreleaser/goreleaser-action@3fa32b8bb5620a2c1afe798654bbad59f9da4906 # v4.4.0 + with: + version: latest + args: release --clean --release-header .release/header.md --timeout 120m # default time is 30m + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }} diff --git a/.goreleaser.yml b/.goreleaser.yml index ee029e45c..8a5dccbd2 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -1,33 +1,48 @@ # You can find the GoReleaser documentation at http://goreleaser.com project_name: exercism +env: + - CGO_ENABLED=0 builds: -- env: - - CGO_ENABLED=0 - main: ./exercism/main.go - goos: - - darwin - - linux - - windows - - freebsd - - openbsd - goarch: - - amd64 - - 386 - - arm - - arm64 - - ppc64 - goarm: - - 5 - - 6 - ignore: - - goos: openbsd - goarch: arm - - goos: freebsd - goarch: arm - -checksum: - name_template: '{{ .ProjectName }}_checksums.txt' + - id: release-build + main: ./exercism/main.go + mod_timestamp: '{{ .CommitTimestamp }}' + flags: + - -trimpath # removes file system paths from compiled executable + ldflags: + - '-s -w' # strip debug symbols and DWARF debugging info + goos: + - darwin + - linux + - windows + - freebsd + - openbsd + goarch: + - amd64 + - 386 + - arm + - arm64 + - ppc64 + goarm: + - 5 + - 6 + ignore: + - goos: openbsd + goarch: arm + - goos: freebsd + goarch: arm + - id: installer-build + main: ./exercism/main.go + mod_timestamp: '{{ .CommitTimestamp }}' + flags: + - -trimpath # removes file system paths from compiled executable + ldflags: + - '-s -w' # strip debug symbols and DWARF debugging info + goos: + - windows + goarch: + - amd64 + - 386 changelog: sort: asc @@ -37,7 +52,10 @@ changelog: - '^test:' archives: - - name_template: >- + - id: release-archives + builds: + - release-build + name_template: >- {{- .ProjectName }}- {{- .Version }}- {{- .Os }}- @@ -49,12 +67,37 @@ archives: - goos: windows format: zip files: - - shell/**/* + - shell/** - LICENSE - README.md + - id: installer-archives + builds: + - installer-build + name_template: >- + {{- .ProjectName }}- + {{- .Version }}- + {{- .Os }}- + {{- if eq .Arch "amd64" }}64bit + {{- else if eq .Arch "386" }}32bit + {{- else }}{{- .Arch }}{{ end }} + {{- if .Arm }}v{{- .Arm }}{{ end }} + format_overrides: + - goos: windows + format: zip + files: + - shell/** + - LICENSE + - README.md + +checksum: + name_template: '{{ .ProjectName }}_checksums.txt' + ids: + - release-archives + - installer-archives signs: -- artifacts: checksum + - artifacts: checksum + args: ["--batch", "-u", "{{ .Env.GPG_FINGERPRINT }}", "--output", "${signature}", "--detach-sign", "${artifact}"] release: # Repo in which the release will be created. diff --git a/.release/header.md b/.release/header.md new file mode 100644 index 000000000..55027b78c --- /dev/null +++ b/.release/header.md @@ -0,0 +1,3 @@ +To install, follow the interactive installation instructions at https://exercism.io/cli-walkthrough + +--- diff --git a/RELEASE.md b/RELEASE.md index 35c26bfba..566db9f83 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -1,7 +1,6 @@ # Cutting a CLI Release -The Exercism CLI uses [GoReleaser](https://goreleaser.com) to automate the -release process. +The Exercism CLI uses [GoReleaser](https://goreleaser.com) to automate the release process. ## Requirements @@ -11,13 +10,12 @@ release process. ## Confirm / Update the Changelog -Make sure all the recent changes are reflected in the "next release" section of the CHANGELOG.md file. All the changes in the "next release" section should be moved to a new section that describes the version number, and gives it a date. +Make sure all the recent changes are reflected in the "next release" section of the CHANGELOG.md file. +All the changes in the "next release" section should be moved to a new section that describes the version number, and gives it a date. You can view changes using the /compare/ view: https://github.com/exercism/cli/compare/$PREVIOUS_RELEASE...main -GoReleaser supports the [auto generation of a changelog](https://goreleaser.com/customization/#customize-the-changelog) we will want to customize to meet our standards (not including refactors, test updates, etc). We should also consider using [the release notes feature](https://goreleaser.com/customization/#custom-release-notes). - ## Bump the version 1. Create a branch for the new version @@ -43,28 +41,19 @@ goreleaser --skip-publish --snapshot --clean git tag -a "${TAG_NAME}" -m "Trying out GoReleaser" git push origin "${TAG_NAME}" -# Build and release -goreleaser --clean - -# Upload copies of the Windows files for use by the Exercism Windows installer -cp "dist/exercism-${VERSION}-windows-i386.zip" dist/exercism-windows-32bit.zip -cp "dist/exercism-${VERSION}-windows-x86_64.zip" dist/exercism-windows-64bit.zip -gh release upload "${TAG_NAME}" dist/exercism-windows-32bit.zip -gh release upload "${TAG_NAME}" dist/exercism-windows-64bit.zip - # [TODO] Push to homebrew ``` ## Cut Release on GitHub -At this point, Goreleaser will have created a draft PR at https://github.com/exercism/cli/releases/tag/vX.Y.Z. +At this point, Goreleaser will have created a draft release at https://github.com/exercism/cli/releases/tag/vX.Y.Z. On that page, update the release description to: ``` To install, follow the interactive installation instructions at https://exercism.io/cli-walkthrough --- -[describe changes in this release] +[modify the generated release-notes to describe changes in this release] ``` Lastly, test and publish the draft From c763ea58ce341b19407e9e7ac403bf2efc22d25d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Sep 2023 16:58:05 +0200 Subject: [PATCH 049/142] Bump actions/checkout from 3.5.3 to 4.0.0 (#1108) --- .github/workflows/ci.yml | 4 ++-- .github/workflows/release.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 63ee024b0..511b27234 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,7 @@ jobs: os: [ubuntu-latest, windows-latest, macOS-latest] steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 + - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac - uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe with: @@ -37,7 +37,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 + - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac - name: Check formatting run: ./.gha.gofmt.sh diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c2c9aecad..0c827639a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,7 +15,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0 with: fetch-depth: 0 From 8f2c7caa030d42d6bfbd5c001b036995af10667e Mon Sep 17 00:00:00 2001 From: Wilken Rivera Date: Fri, 22 Sep 2023 09:38:11 -0400 Subject: [PATCH 050/142] cmd/submit_test.go: Update test server to use unmodified filename (#1115) Following RFC 7578, Go 1.17+ strips the directory information in fileHeader.Filename. This change updates the test server to use Header["Content-Disposition"] for obtaining the unmodified filename for validating the submitted files directory tree in the request. This work builds on the PR opened by @QuLogic https://github.com/exercism/cli/pull/1066 Co-authored-by: Erik Schierboom --- cmd/submit_test.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/cmd/submit_test.go b/cmd/submit_test.go index 7286a19e6..ea16b6543 100644 --- a/cmd/submit_test.go +++ b/cmd/submit_test.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" "io/ioutil" + "mime" "net/http" "net/http/httptest" "os" @@ -561,7 +562,16 @@ func fakeSubmitServer(t *testing.T, submittedFiles map[string]string) *httptest. if err != nil { t.Fatal(err) } - submittedFiles[fileHeader.Filename] = string(body) + // Following RFC 7578, Go 1.17+ strips the directory information in fileHeader.Filename. + // Validating the submitted files directory tree is important so Content-Disposition is used for + // obtaining the unmodified filename. + v := fileHeader.Header.Get("Content-Disposition") + _, dispositionParams, err := mime.ParseMediaType(v) + if err != nil { + t.Fatalf("failed to obtain submitted filename from multipart header: %s", err.Error()) + } + filename := dispositionParams["filename"] + submittedFiles[filename] = string(body) } fmt.Fprint(w, "{}") From 0e017aa3b5f72c8796609557c05f1308ce714d30 Mon Sep 17 00:00:00 2001 From: Wilken Rivera Date: Thu, 5 Oct 2023 02:46:02 -0400 Subject: [PATCH 051/142] Bump target Go version to 1.20 (#1118) * Bump minimum Go version to 1.18 This change bumps the minimum Go version to 1.18 to take advantage of a number of fixes to the language, while matching the minimum version for a number of key dependencies which have been moving away from Go 1.15. This change drops support for Go 1.15 in the Exercism CLI. * Bump minimum go version to 1.19 * fix: update build tags to Go 1.18 syntax ``` ~> go1.18.10 fix ./... ``` * Replace calls to deprecated io/ioutil pkg * fix(deps): update module github.com/spf13/viper to v1.15.0 This change bumps spf13/viper to address reported vulnerabilities in yaml.v2 ``` ~> govulncheck -test ./... Scanning your code and 210 packages across 21 dependent modules for known vulnerabilities... Vulnerability #1: GO-2022-0956 Excessive resource consumption in gopkg.in/yaml.v2 More info: https://pkg.go.dev/vuln/GO-2022-0956 Module: gopkg.in/yaml.v2 Found in: gopkg.in/yaml.v2@v2.0.0-20170721122051-25c4ec802a7d Fixed in: gopkg.in/yaml.v2@v2.2.4 Example traces found: #1: cmd/submit.go:129:23: cmd.getExerciseSolutionFiles calls viper.Viper.ReadInConfig, which eventually calls yaml.Unmarshal Vulnerability #2: GO-2021-0061 Denial of service in gopkg.in/yaml.v2 More info: https://pkg.go.dev/vuln/GO-2021-0061 Module: gopkg.in/yaml.v2 Found in: gopkg.in/yaml.v2@v2.0.0-20170721122051-25c4ec802a7d Fixed in: gopkg.in/yaml.v2@v2.2.3 Example traces found: #1: cmd/submit.go:129:23: cmd.getExerciseSolutionFiles calls viper.Viper.ReadInConfig, which eventually calls yaml.Unmarshal Vulnerability #3: GO-2020-0036 Excessive resource consumption in YAML parsing in gopkg.in/yaml.v2 More info: https://pkg.go.dev/vuln/GO-2020-0036 Module: gopkg.in/yaml.v2 Found in: gopkg.in/yaml.v2@v2.0.0-20170721122051-25c4ec802a7d Fixed in: gopkg.in/yaml.v2@v2.2.8 Example traces found: #1: cmd/submit.go:129:23: cmd.getExerciseSolutionFiles calls viper.Viper.ReadInConfig, which eventually calls yaml.Unmarshal ``` * deps: update module github.com/spf13/cobra to v1.7.0 * deps: update module github.com/stretchr/testify to v1.8.4 * workflows/ci.yml: Add multiple Go versions to testing matrix This change officially removes Go 1.15 from the testing matrix and adds the Go versions used for supporting the Exercism CLI. Namely Go 1.19, 1.20, and 1.21.x. * Bump minimum Go version to 1.20 * Bump Go tooling to use 1.20.x for release and testing. ``` Scanning your code and 207 packages across 19 dependent modules for known vulnerabilities... Vulnerability #1: GO-2023-2043 Improper handling of special tags within script contexts in html/template More info: https://pkg.go.dev/vuln/GO-2023-2043 Standard library Found in: html/template@go1.19.8 Fixed in: html/template@go1.21.1 Example traces found: #1: cmd/troubleshoot.go:127:20: cmd.Status.compile calls template.Template.Execute Vulnerability #2: GO-2023-2041 Improper handling of HTML-like comments in script contexts in html/template More info: https://pkg.go.dev/vuln/GO-2023-2041 Standard library Found in: html/template@go1.19.8 Fixed in: html/template@go1.21.1 Example traces found: #1: cmd/troubleshoot.go:127:20: cmd.Status.compile calls template.Template.Execute Vulnerability #3: GO-2023-1987 Large RSA keys can cause high CPU usage in crypto/tls More info: https://pkg.go.dev/vuln/GO-2023-1987 Standard library Found in: crypto/tls@go1.19.8 Fixed in: crypto/tls@go1.21rc4 Example traces found: #1: api/client.go:68:25: api.Client.Do calls http.Client.Do, which eventually calls tls.Conn.HandshakeContext #2: cli/cli.go:199:23: cli.extractBinary calls io.Copy, which eventually calls tls.Conn.Read #3: debug/debug.go:32:14: debug.Printf calls fmt.Fprintf, which calls tls.Conn.Write #4: api/client.go:68:25: api.Client.Do calls http.Client.Do, which eventually calls tls.Dialer.DialContext Vulnerability #4: GO-2023-1878 Insufficient sanitization of Host header in net/http More info: https://pkg.go.dev/vuln/GO-2023-1878 Standard library Found in: net/http@go1.19.8 Fixed in: net/http@go1.20.6 Example traces found: #1: api/client.go:68:25: api.Client.Do calls http.Client.Do #2: cmd/troubleshoot.go:206:32: cmd.apiPing.Call calls http.Client.Get Vulnerability #5: GO-2023-1840 Unsafe behavior in setuid/setgid binaries in runtime More info: https://pkg.go.dev/vuln/GO-2023-1840 Standard library Found in: runtime@go1.19.8 Fixed in: runtime@go1.20.5 Example traces found: #1: debug/debug.go:80:12: debug.DumpResponse calls log.Fatal, which eventually calls runtime.Caller #2: workspace/exercise_metadata.go:39:26: workspace.NewExerciseMetadata calls json.Unmarshal, which eventually calls runtime.Callers #3: workspace/exercise_metadata.go:39:26: workspace.NewExerciseMetadata calls json.Unmarshal, which eventually calls runtime.CallersFrames #4: workspace/exercise_metadata.go:39:26: workspace.NewExerciseMetadata calls json.Unmarshal, which eventually calls runtime.Frames.Next #5: cmd/root.go:39:27: cmd.Execute calls cobra.Command.Execute, which eventually calls runtime.GC #6: workspace/exercise_metadata.go:66:24: workspace.ExerciseMetadata.Write calls json.Marshal, which eventually calls runtime.GOMAXPROCS #7: config/config.go:57:18: config.Dir calls os.Getenv, which eventually calls runtime.GOROOT #8: cli/cli.go:202:29: cli.extractBinary calls os.File.Seek, which eventually calls runtime.KeepAlive #9: cli/cli.go:135:2: cli.CLI.Upgrade calls os.File.Close, which eventually calls runtime.SetFinalizer #10: debug/debug.go:32:14: debug.Printf calls fmt.Fprintf, which eventually calls runtime.Stack #11: cmd/root.go:39:27: cmd.Execute calls cobra.Command.Execute, which eventually calls runtime.TypeAssertionError.Error #12: workspace/test_configurations.go:5:2: workspace.init calls runtime.init, which calls runtime.defaultMemProfileRate #13: workspace/test_configurations.go:5:2: workspace.init calls runtime.init, which calls runtime.efaceOf #14: workspace/test_configurations.go:5:2: workspace.init calls runtime.init, which eventually calls runtime.findfunc #15: workspace/test_configurations.go:5:2: workspace.init calls runtime.init, which calls runtime.float64frombits #16: workspace/test_configurations.go:5:2: workspace.init calls runtime.init, which eventually calls runtime.forcegchelper #17: workspace/test_configurations.go:5:2: workspace.init calls runtime.init, which eventually calls runtime.funcMaxSPDelta #18: cmd/root.go:39:27: cmd.Execute calls cobra.Command.Execute, which eventually calls runtime.plainError.Error #19: workspace/test_configurations.go:5:2: workspace.init calls runtime.init, which eventually calls runtime.throw Vulnerability #6: GO-2023-1753 Improper handling of empty HTML attributes in html/template More info: https://pkg.go.dev/vuln/GO-2023-1753 Standard library Found in: html/template@go1.19.8 Fixed in: html/template@go1.20.4 Example traces found: #1: cmd/troubleshoot.go:127:20: cmd.Status.compile calls template.Template.Execute Vulnerability #7: GO-2023-1752 Improper handling of JavaScript whitespace in html/template More info: https://pkg.go.dev/vuln/GO-2023-1752 Standard library Found in: html/template@go1.19.8 Fixed in: html/template@go1.20.4 Example traces found: #1: cmd/troubleshoot.go:127:20: cmd.Status.compile calls template.Template.Execute Vulnerability #8: GO-2023-1751 Improper sanitization of CSS values in html/template More info: https://pkg.go.dev/vuln/GO-2023-1751 Standard library Found in: html/template@go1.19.8 Fixed in: html/template@go1.20.4 Example traces found: #1: cmd/troubleshoot.go:127:20: cmd.Status.compile calls template.Template.Execute ``` --- .github/workflows/ci.yml | 4 +- .github/workflows/release.yml | 2 +- CONTRIBUTING.md | 2 +- api/api.go | 4 +- cli/asset.go | 4 +- cli/cli.go | 8 +- cmd/cmd_test.go | 7 +- cmd/configure_test.go | 8 +- cmd/download.go | 5 +- cmd/download_test.go | 13 +- cmd/submit_symlink_test.go | 8 +- cmd/submit_test.go | 90 ++--- config/config_notwin_test.go | 1 - config/config_windows_test.go | 1 - config/resolve_notwin_test.go | 1 - debug/debug.go | 9 +- go.mod | 47 +-- go.sum | 524 +++++++++++++++++++++++++-- workspace/document_test.go | 5 +- workspace/exercise_config.go | 4 +- workspace/exercise_config_test.go | 9 +- workspace/exercise_metadata.go | 5 +- workspace/exercise_metadata_test.go | 3 +- workspace/exercise_test.go | 23 +- workspace/path_type_symlinks_test.go | 1 - workspace/workspace.go | 7 +- workspace/workspace_darwin_test.go | 3 +- workspace/workspace_test.go | 7 +- 28 files changed, 620 insertions(+), 185 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 511b27234..704eabdf9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,7 +17,9 @@ jobs: strategy: fail-fast: false matrix: - go-version: ["1.15"] + go-version: + - '1.20.x' + - '1.21.x' os: [ubuntu-latest, windows-latest, macOS-latest] steps: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0c827639a..06175aa06 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -22,7 +22,7 @@ jobs: - name: Set up Go uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0 with: - go-version: '1.19' + go-version: '1.20.x' - name: Import GPG Key id: import_gpg diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1936a39eb..1515a4fcb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -8,7 +8,7 @@ Exercism would be impossible without people like you being willing to spend time ## Dependencies -You'll need Go version 1.11 or higher. Follow the directions on http://golang.org/doc/install +You'll need Go version 1.20 or higher. Follow the directions on http://golang.org/doc/install ## Development diff --git a/api/api.go b/api/api.go index 342ce4230..25b5e9d14 100644 --- a/api/api.go +++ b/api/api.go @@ -2,7 +2,7 @@ package api import ( "bytes" - "io/ioutil" + "os" "golang.org/x/net/html/charset" "golang.org/x/text/transform" @@ -17,7 +17,7 @@ var ( ) func readFileAsUTF8String(filename string) (*string, error) { - b, err := ioutil.ReadFile(filename) + b, err := os.ReadFile(filename) if err != nil { return nil, err } diff --git a/cli/asset.go b/cli/asset.go index 246895faa..10bbab051 100644 --- a/cli/asset.go +++ b/cli/asset.go @@ -3,7 +3,7 @@ package cli import ( "bytes" "fmt" - "io/ioutil" + "io" "net/http" ) @@ -28,7 +28,7 @@ func (a *Asset) download() (*bytes.Reader, error) { } defer res.Body.Close() - bs, err := ioutil.ReadAll(res.Body) + bs, err := io.ReadAll(res.Body) if err != nil { return nil, err } diff --git a/cli/cli.go b/cli/cli.go index 4312eb018..fe113ec5b 100644 --- a/cli/cli.go +++ b/cli/cli.go @@ -8,8 +8,8 @@ import ( "encoding/json" "fmt" "io" - "io/ioutil" "net/http" + "os" "runtime" "strings" "time" @@ -161,8 +161,8 @@ func (c *CLI) fetchLatestRelease() error { return nil } -func extractBinary(source *bytes.Reader, os string) (binary io.ReadCloser, err error) { - if os == "windows" { +func extractBinary(source *bytes.Reader, platform string) (binary io.ReadCloser, err error) { + if platform == "windows" { zr, err := zip.NewReader(source, int64(source.Len())) if err != nil { return nil, err @@ -191,7 +191,7 @@ func extractBinary(source *bytes.Reader, os string) (binary io.ReadCloser, err e if err != nil { return nil, err } - tmpfile, err := ioutil.TempFile("", "temp-exercism") + tmpfile, err := os.CreateTemp("", "temp-exercism") if err != nil { return nil, err } diff --git a/cmd/cmd_test.go b/cmd/cmd_test.go index fee08cd98..782be18d2 100644 --- a/cmd/cmd_test.go +++ b/cmd/cmd_test.go @@ -2,7 +2,6 @@ package cmd import ( "io" - "io/ioutil" "os" "testing" @@ -63,7 +62,7 @@ type CommandTest struct { // The method takes a *testing.T as an argument, that way the method can // fail the test if the creation of the temporary directory fails. func (test *CommandTest) Setup(t *testing.T) { - dir, err := ioutil.TempDir("", "command-test") + dir, err := os.MkdirTemp("", "command-test") defer os.RemoveAll(dir) assert.NoError(t, err) @@ -104,8 +103,8 @@ func newCapturedOutput() capturedOutput { return capturedOutput{ oldOut: Out, oldErr: Err, - newOut: ioutil.Discard, - newErr: ioutil.Discard, + newOut: io.Discard, + newErr: io.Discard, } } diff --git a/cmd/configure_test.go b/cmd/configure_test.go index 7a0f28eac..df3542328 100644 --- a/cmd/configure_test.go +++ b/cmd/configure_test.go @@ -1,11 +1,9 @@ //go:build !windows -// +build !windows package cmd import ( "bytes" - "io/ioutil" "net/http" "net/http/httptest" "os" @@ -344,7 +342,7 @@ func TestConfigureDefaultWorkspaceWithoutClobbering(t *testing.T) { ts := httptest.NewServer(endpoint) defer ts.Close() - tmpDir, err := ioutil.TempDir("", "no-clobber") + tmpDir, err := os.MkdirTemp("", "no-clobber") defer os.RemoveAll(tmpDir) assert.NoError(t, err) @@ -379,7 +377,7 @@ func TestConfigureExplicitWorkspaceWithoutClobberingNonDirectory(t *testing.T) { co.override() defer co.reset() - tmpDir, err := ioutil.TempDir("", "no-clobber") + tmpDir, err := os.MkdirTemp("", "no-clobber") defer os.RemoveAll(tmpDir) assert.NoError(t, err) @@ -396,7 +394,7 @@ func TestConfigureExplicitWorkspaceWithoutClobberingNonDirectory(t *testing.T) { } // Create a file at the workspace directory's location - err = ioutil.WriteFile(filepath.Join(tmpDir, "workspace"), []byte("This is not a directory"), os.FileMode(0755)) + err = os.WriteFile(filepath.Join(tmpDir, "workspace"), []byte("This is not a directory"), os.FileMode(0755)) assert.NoError(t, err) flags := pflag.NewFlagSet("fake", pflag.PanicOnError) diff --git a/cmd/download.go b/cmd/download.go index 7bf278bff..f376e959b 100644 --- a/cmd/download.go +++ b/cmd/download.go @@ -6,7 +6,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net/http" netURL "net/url" "os" @@ -202,8 +201,8 @@ func newDownload(flags *pflag.FlagSet, usrCfg *viper.Viper) (*download, error) { return nil, decodedAPIError(res) } - body, _ := ioutil.ReadAll(res.Body) - res.Body = ioutil.NopCloser(bytes.NewReader(body)) + body, _ := io.ReadAll(res.Body) + res.Body = io.NopCloser(bytes.NewReader(body)) if err := json.Unmarshal(body, &d.payload); err != nil { return nil, decodedAPIError(res) diff --git a/cmd/download_test.go b/cmd/download_test.go index 676d90518..d95729719 100644 --- a/cmd/download_test.go +++ b/cmd/download_test.go @@ -3,7 +3,6 @@ package cmd import ( "encoding/json" "fmt" - "io/ioutil" "net/http" "net/http/httptest" "os" @@ -169,7 +168,7 @@ func TestDownload(t *testing.T) { } for _, tc := range testCases { - tmpDir, err := ioutil.TempDir("", "download-cmd") + tmpDir, err := os.MkdirTemp("", "download-cmd") defer os.RemoveAll(tmpDir) assert.NoError(t, err) @@ -197,7 +196,7 @@ func TestDownload(t *testing.T) { assertDownloadedCorrectFiles(t, targetDir) dir := filepath.Join(targetDir, "bogus-track", "bogus-exercise") - b, err := ioutil.ReadFile(workspace.NewExerciseFromDir(dir).MetadataFilepath()) + b, err := os.ReadFile(workspace.NewExerciseFromDir(dir).MetadataFilepath()) assert.NoError(t, err) var metadata workspace.ExerciseMetadata err = json.Unmarshal(b, &metadata) @@ -229,7 +228,7 @@ func TestDownloadToExistingDirectory(t *testing.T) { } for _, tc := range testCases { - tmpDir, err := ioutil.TempDir("", "download-cmd") + tmpDir, err := os.MkdirTemp("", "download-cmd") defer os.RemoveAll(tmpDir) assert.NoError(t, err) @@ -281,7 +280,7 @@ func TestDownloadToExistingDirectoryWithForce(t *testing.T) { } for _, tc := range testCases { - tmpDir, err := ioutil.TempDir("", "download-cmd") + tmpDir, err := os.MkdirTemp("", "download-cmd") defer os.RemoveAll(tmpDir) assert.NoError(t, err) @@ -363,7 +362,7 @@ func assertDownloadedCorrectFiles(t *testing.T, targetDir string) { for _, file := range expectedFiles { t.Run(file.desc, func(t *testing.T) { - b, err := ioutil.ReadFile(file.path) + b, err := os.ReadFile(file.path) assert.NoError(t, err) assert.Equal(t, file.contents, string(b)) }) @@ -383,7 +382,7 @@ func TestDownloadError(t *testing.T) { ts := httptest.NewServer(handler) defer ts.Close() - tmpDir, err := ioutil.TempDir("", "submit-err-tmp-dir") + tmpDir, err := os.MkdirTemp("", "submit-err-tmp-dir") defer os.RemoveAll(tmpDir) assert.NoError(t, err) diff --git a/cmd/submit_symlink_test.go b/cmd/submit_symlink_test.go index e10fb4890..093895fb3 100644 --- a/cmd/submit_symlink_test.go +++ b/cmd/submit_symlink_test.go @@ -1,10 +1,8 @@ //go:build !windows -// +build !windows package cmd import ( - "io/ioutil" "os" "path/filepath" "testing" @@ -25,12 +23,12 @@ func TestSubmitFilesInSymlinkedPath(t *testing.T) { ts := fakeSubmitServer(t, submittedFiles) defer ts.Close() - tmpDir, err := ioutil.TempDir("", "symlink-destination") + tmpDir, err := os.MkdirTemp("", "symlink-destination") defer os.RemoveAll(tmpDir) assert.NoError(t, err) dstDir := filepath.Join(tmpDir, "workspace") - srcDir, err := ioutil.TempDir("", "symlink-source") + srcDir, err := os.MkdirTemp("", "symlink-source") defer os.RemoveAll(srcDir) assert.NoError(t, err) @@ -53,7 +51,7 @@ func TestSubmitFilesInSymlinkedPath(t *testing.T) { } file := filepath.Join(dir, "file.txt") - err = ioutil.WriteFile(filepath.Join(dir, "file.txt"), []byte("This is a file."), os.FileMode(0755)) + err = os.WriteFile(filepath.Join(dir, "file.txt"), []byte("This is a file."), os.FileMode(0755)) assert.NoError(t, err) err = runSubmit(cfg, pflag.NewFlagSet("symlinks", pflag.PanicOnError), []string{file}) diff --git a/cmd/submit_test.go b/cmd/submit_test.go index ea16b6543..2a12d0bca 100644 --- a/cmd/submit_test.go +++ b/cmd/submit_test.go @@ -4,7 +4,7 @@ import ( "bytes" "encoding/json" "fmt" - "io/ioutil" + "io" "mime" "net/http" "net/http/httptest" @@ -49,7 +49,7 @@ func TestSubmitWithoutWorkspace(t *testing.T) { } func TestSubmitNonExistentFile(t *testing.T) { - tmpDir, err := ioutil.TempDir("", "submit-no-such-file") + tmpDir, err := os.MkdirTemp("", "submit-no-such-file") defer os.RemoveAll(tmpDir) assert.NoError(t, err) @@ -64,10 +64,10 @@ func TestSubmitNonExistentFile(t *testing.T) { DefaultBaseURL: "http://example.com", } - err = ioutil.WriteFile(filepath.Join(tmpDir, "file-1.txt"), []byte("This is file 1"), os.FileMode(0755)) + err = os.WriteFile(filepath.Join(tmpDir, "file-1.txt"), []byte("This is file 1"), os.FileMode(0755)) assert.NoError(t, err) - err = ioutil.WriteFile(filepath.Join(tmpDir, "file-2.txt"), []byte("This is file 2"), os.FileMode(0755)) + err = os.WriteFile(filepath.Join(tmpDir, "file-2.txt"), []byte("This is file 2"), os.FileMode(0755)) assert.NoError(t, err) files := []string{ filepath.Join(tmpDir, "file-1.txt"), @@ -81,7 +81,7 @@ func TestSubmitNonExistentFile(t *testing.T) { } func TestSubmitExerciseWithoutMetadataFile(t *testing.T) { - tmpDir, err := ioutil.TempDir("", "no-metadata-file") + tmpDir, err := os.MkdirTemp("", "no-metadata-file") defer os.RemoveAll(tmpDir) assert.NoError(t, err) @@ -89,7 +89,7 @@ func TestSubmitExerciseWithoutMetadataFile(t *testing.T) { os.MkdirAll(dir, os.FileMode(0755)) file := filepath.Join(dir, "file.txt") - err = ioutil.WriteFile(file, []byte("This is a file."), os.FileMode(0755)) + err = os.WriteFile(file, []byte("This is a file."), os.FileMode(0755)) assert.NoError(t, err) v := viper.New() @@ -111,7 +111,7 @@ func TestSubmitExerciseWithoutMetadataFile(t *testing.T) { func TestGetExerciseSolutionFiles(t *testing.T) { - tmpDir, err := ioutil.TempDir("", "dir-with-no-metadata") + tmpDir, err := os.MkdirTemp("", "dir-with-no-metadata") defer os.RemoveAll(tmpDir) assert.NoError(t, err) @@ -120,7 +120,7 @@ func TestGetExerciseSolutionFiles(t *testing.T) { assert.Regexp(t, "no files to submit", err.Error()) } - validTmpDir, err := ioutil.TempDir("", "dir-with-valid-metadata") + validTmpDir, err := os.MkdirTemp("", "dir-with-valid-metadata") defer os.RemoveAll(validTmpDir) assert.NoError(t, err) @@ -128,7 +128,7 @@ func TestGetExerciseSolutionFiles(t *testing.T) { err = os.MkdirAll(metadataDir, os.FileMode(0755)) assert.NoError(t, err) - err = ioutil.WriteFile( + err = os.WriteFile( filepath.Join(metadataDir, "config.json"), []byte(` { @@ -149,7 +149,7 @@ func TestGetExerciseSolutionFiles(t *testing.T) { } func TestSubmitFilesAndDir(t *testing.T) { - tmpDir, err := ioutil.TempDir("", "submit-no-such-file") + tmpDir, err := os.MkdirTemp("", "submit-no-such-file") defer os.RemoveAll(tmpDir) assert.NoError(t, err) @@ -164,10 +164,10 @@ func TestSubmitFilesAndDir(t *testing.T) { DefaultBaseURL: "http://example.com", } - err = ioutil.WriteFile(filepath.Join(tmpDir, "file-1.txt"), []byte("This is file 1"), os.FileMode(0755)) + err = os.WriteFile(filepath.Join(tmpDir, "file-1.txt"), []byte("This is file 1"), os.FileMode(0755)) assert.NoError(t, err) - err = ioutil.WriteFile(filepath.Join(tmpDir, "file-2.txt"), []byte("This is file 2"), os.FileMode(0755)) + err = os.WriteFile(filepath.Join(tmpDir, "file-2.txt"), []byte("This is file 2"), os.FileMode(0755)) assert.NoError(t, err) files := []string{ filepath.Join(tmpDir, "file-1.txt"), @@ -192,7 +192,7 @@ func TestDuplicateFiles(t *testing.T) { ts := fakeSubmitServer(t, submittedFiles) defer ts.Close() - tmpDir, err := ioutil.TempDir("", "duplicate-files") + tmpDir, err := os.MkdirTemp("", "duplicate-files") defer os.RemoveAll(tmpDir) assert.NoError(t, err) @@ -212,7 +212,7 @@ func TestDuplicateFiles(t *testing.T) { } file1 := filepath.Join(dir, "file-1.txt") - err = ioutil.WriteFile(file1, []byte("This is file 1."), os.FileMode(0755)) + err = os.WriteFile(file1, []byte("This is file 1."), os.FileMode(0755)) err = runSubmit(cfg, pflag.NewFlagSet("fake", pflag.PanicOnError), []string{file1, file1}) assert.NoError(t, err) @@ -232,7 +232,7 @@ func TestSubmitFiles(t *testing.T) { ts := fakeSubmitServer(t, submittedFiles) defer ts.Close() - tmpDir, err := ioutil.TempDir("", "submit-files") + tmpDir, err := os.MkdirTemp("", "submit-files") defer os.RemoveAll(tmpDir) assert.NoError(t, err) @@ -241,16 +241,16 @@ func TestSubmitFiles(t *testing.T) { writeFakeMetadata(t, dir, "bogus-track", "bogus-exercise") file1 := filepath.Join(dir, "file-1.txt") - err = ioutil.WriteFile(file1, []byte("This is file 1."), os.FileMode(0755)) + err = os.WriteFile(file1, []byte("This is file 1."), os.FileMode(0755)) assert.NoError(t, err) file2 := filepath.Join(dir, "subdir", "file-2.txt") - err = ioutil.WriteFile(file2, []byte("This is file 2."), os.FileMode(0755)) + err = os.WriteFile(file2, []byte("This is file 2."), os.FileMode(0755)) assert.NoError(t, err) // We don't filter *.md files if you explicitly pass the file path. readme := filepath.Join(dir, "README.md") - err = ioutil.WriteFile(readme, []byte("This is the readme."), os.FileMode(0755)) + err = os.WriteFile(readme, []byte("This is the readme."), os.FileMode(0755)) assert.NoError(t, err) v := viper.New() @@ -289,7 +289,7 @@ func TestLegacyMetadataMigration(t *testing.T) { ts := fakeSubmitServer(t, submittedFiles) defer ts.Close() - tmpDir, err := ioutil.TempDir("", "legacy-metadata-file") + tmpDir, err := os.MkdirTemp("", "legacy-metadata-file") defer os.RemoveAll(tmpDir) assert.NoError(t, err) @@ -306,11 +306,11 @@ func TestLegacyMetadataMigration(t *testing.T) { b, err := json.Marshal(metadata) assert.NoError(t, err) exercise := workspace.NewExerciseFromDir(dir) - err = ioutil.WriteFile(exercise.LegacyMetadataFilepath(), b, os.FileMode(0600)) + err = os.WriteFile(exercise.LegacyMetadataFilepath(), b, os.FileMode(0600)) assert.NoError(t, err) file := filepath.Join(dir, "file.txt") - err = ioutil.WriteFile(file, []byte("This is a file."), os.FileMode(0755)) + err = os.WriteFile(file, []byte("This is a file."), os.FileMode(0755)) assert.NoError(t, err) v := viper.New() @@ -352,7 +352,7 @@ func TestSubmitWithEmptyFile(t *testing.T) { ts := fakeSubmitServer(t, submittedFiles) defer ts.Close() - tmpDir, err := ioutil.TempDir("", "empty-file") + tmpDir, err := os.MkdirTemp("", "empty-file") defer os.RemoveAll(tmpDir) assert.NoError(t, err) @@ -372,9 +372,9 @@ func TestSubmitWithEmptyFile(t *testing.T) { } file1 := filepath.Join(dir, "file-1.txt") - err = ioutil.WriteFile(file1, []byte(""), os.FileMode(0755)) + err = os.WriteFile(file1, []byte(""), os.FileMode(0755)) file2 := filepath.Join(dir, "file-2.txt") - err = ioutil.WriteFile(file2, []byte("This is file 2."), os.FileMode(0755)) + err = os.WriteFile(file2, []byte("This is file 2."), os.FileMode(0755)) err = runSubmit(cfg, pflag.NewFlagSet("fake", pflag.PanicOnError), []string{file1, file2}) assert.NoError(t, err) @@ -393,7 +393,7 @@ func TestSubmitWithEnormousFile(t *testing.T) { ts := fakeSubmitServer(t, submittedFiles) defer ts.Close() - tmpDir, err := ioutil.TempDir("", "enormous-file") + tmpDir, err := os.MkdirTemp("", "enormous-file") defer os.RemoveAll(tmpDir) assert.NoError(t, err) @@ -413,7 +413,7 @@ func TestSubmitWithEnormousFile(t *testing.T) { } file := filepath.Join(dir, "file.txt") - err = ioutil.WriteFile(file, make([]byte, 65535), os.FileMode(0755)) + err = os.WriteFile(file, make([]byte, 65535), os.FileMode(0755)) if err != nil { t.Fatal(err) } @@ -435,7 +435,7 @@ func TestSubmitFilesForTeamExercise(t *testing.T) { ts := fakeSubmitServer(t, submittedFiles) defer ts.Close() - tmpDir, err := ioutil.TempDir("", "submit-files") + tmpDir, err := os.MkdirTemp("", "submit-files") assert.NoError(t, err) dir := filepath.Join(tmpDir, "teams", "bogus-team", "bogus-track", "bogus-exercise") @@ -443,11 +443,11 @@ func TestSubmitFilesForTeamExercise(t *testing.T) { writeFakeMetadata(t, dir, "bogus-track", "bogus-exercise") file1 := filepath.Join(dir, "file-1.txt") - err = ioutil.WriteFile(file1, []byte("This is file 1."), os.FileMode(0755)) + err = os.WriteFile(file1, []byte("This is file 1."), os.FileMode(0755)) assert.NoError(t, err) file2 := filepath.Join(dir, "subdir", "file-2.txt") - err = ioutil.WriteFile(file2, []byte("This is file 2."), os.FileMode(0755)) + err = os.WriteFile(file2, []byte("This is file 2."), os.FileMode(0755)) assert.NoError(t, err) v := viper.New() @@ -477,7 +477,7 @@ func TestSubmitOnlyEmptyFile(t *testing.T) { co.override() defer co.reset() - tmpDir, err := ioutil.TempDir("", "just-an-empty-file") + tmpDir, err := os.MkdirTemp("", "just-an-empty-file") defer os.RemoveAll(tmpDir) assert.NoError(t, err) @@ -497,7 +497,7 @@ func TestSubmitOnlyEmptyFile(t *testing.T) { } file := filepath.Join(dir, "file.txt") - err = ioutil.WriteFile(file, []byte(""), os.FileMode(0755)) + err = os.WriteFile(file, []byte(""), os.FileMode(0755)) err = runSubmit(cfg, pflag.NewFlagSet("fake", pflag.PanicOnError), []string{file}) if assert.Error(t, err) { @@ -506,7 +506,7 @@ func TestSubmitOnlyEmptyFile(t *testing.T) { } func TestSubmitFilesFromDifferentSolutions(t *testing.T) { - tmpDir, err := ioutil.TempDir("", "dir-1-submit") + tmpDir, err := os.MkdirTemp("", "dir-1-submit") defer os.RemoveAll(tmpDir) assert.NoError(t, err) @@ -519,11 +519,11 @@ func TestSubmitFilesFromDifferentSolutions(t *testing.T) { writeFakeMetadata(t, dir2, "bogus-track", "bogus-exercise-2") file1 := filepath.Join(dir1, "file-1.txt") - err = ioutil.WriteFile(file1, []byte("This is file 1."), os.FileMode(0755)) + err = os.WriteFile(file1, []byte("This is file 1."), os.FileMode(0755)) assert.NoError(t, err) file2 := filepath.Join(dir2, "file-2.txt") - err = ioutil.WriteFile(file2, []byte("This is file 2."), os.FileMode(0755)) + err = os.WriteFile(file2, []byte("This is file 2."), os.FileMode(0755)) assert.NoError(t, err) v := viper.New() @@ -558,7 +558,7 @@ func fakeSubmitServer(t *testing.T, submittedFiles map[string]string) *httptest. t.Fatal(err) } defer file.Close() - body, err := ioutil.ReadAll(file) + body, err := io.ReadAll(file) if err != nil { t.Fatal(err) } @@ -589,7 +589,7 @@ func TestSubmitRelativePath(t *testing.T) { ts := fakeSubmitServer(t, submittedFiles) defer ts.Close() - tmpDir, err := ioutil.TempDir("", "relative-path") + tmpDir, err := os.MkdirTemp("", "relative-path") defer os.RemoveAll(tmpDir) assert.NoError(t, err) @@ -608,7 +608,7 @@ func TestSubmitRelativePath(t *testing.T) { UserViperConfig: v, } - err = ioutil.WriteFile(filepath.Join(dir, "file.txt"), []byte("This is a file."), os.FileMode(0755)) + err = os.WriteFile(filepath.Join(dir, "file.txt"), []byte("This is a file."), os.FileMode(0755)) err = os.Chdir(dir) assert.NoError(t, err) @@ -629,7 +629,7 @@ func TestSubmitServerErr(t *testing.T) { ts := httptest.NewServer(handler) defer ts.Close() - tmpDir, err := ioutil.TempDir("", "submit-err-tmp-dir") + tmpDir, err := os.MkdirTemp("", "submit-err-tmp-dir") defer os.RemoveAll(tmpDir) assert.NoError(t, err) @@ -648,7 +648,7 @@ func TestSubmitServerErr(t *testing.T) { os.MkdirAll(filepath.Join(dir, "subdir"), os.FileMode(0755)) writeFakeMetadata(t, dir, "bogus-track", "bogus-exercise") - err = ioutil.WriteFile(filepath.Join(dir, "file-1.txt"), []byte("This is file 1"), os.FileMode(0755)) + err = os.WriteFile(filepath.Join(dir, "file-1.txt"), []byte("This is file 1"), os.FileMode(0755)) assert.NoError(t, err) files := []string{ @@ -668,7 +668,7 @@ func TestHandleErrorResponse(t *testing.T) { ts := httptest.NewServer(handler) defer ts.Close() - tmpDir, err := ioutil.TempDir("", "submit-nonsuccess") + tmpDir, err := os.MkdirTemp("", "submit-nonsuccess") defer os.RemoveAll(tmpDir) assert.NoError(t, err) @@ -687,7 +687,7 @@ func TestHandleErrorResponse(t *testing.T) { os.MkdirAll(filepath.Join(dir, "subdir"), os.FileMode(0755)) writeFakeMetadata(t, dir, "bogus-track", "bogus-exercise") - err = ioutil.WriteFile(filepath.Join(dir, "file-1.txt"), []byte("This is file 1"), os.FileMode(0755)) + err = os.WriteFile(filepath.Join(dir, "file-1.txt"), []byte("This is file 1"), os.FileMode(0755)) assert.NoError(t, err) files := []string{ @@ -703,7 +703,7 @@ func TestSubmissionNotConnectedToRequesterAccount(t *testing.T) { ts := fakeSubmitServer(t, submittedFiles) defer ts.Close() - tmpDir, err := ioutil.TempDir("", "submit-files") + tmpDir, err := os.MkdirTemp("", "submit-files") defer os.RemoveAll(tmpDir) assert.NoError(t, err) @@ -721,7 +721,7 @@ func TestSubmissionNotConnectedToRequesterAccount(t *testing.T) { assert.NoError(t, err) file1 := filepath.Join(dir, "file-1.txt") - err = ioutil.WriteFile(file1, []byte("This is file 1."), os.FileMode(0755)) + err = os.WriteFile(file1, []byte("This is file 1."), os.FileMode(0755)) assert.NoError(t, err) v := viper.New() @@ -746,7 +746,7 @@ func TestExerciseDirnameMatchesMetadataSlug(t *testing.T) { ts := fakeSubmitServer(t, submittedFiles) defer ts.Close() - tmpDir, err := ioutil.TempDir("", "submit-files") + tmpDir, err := os.MkdirTemp("", "submit-files") defer os.RemoveAll(tmpDir) assert.NoError(t, err) @@ -755,7 +755,7 @@ func TestExerciseDirnameMatchesMetadataSlug(t *testing.T) { writeFakeMetadata(t, dir, "bogus-track", "bogus-exercise") file1 := filepath.Join(dir, "file-1.txt") - err = ioutil.WriteFile(file1, []byte("This is file 1."), os.FileMode(0755)) + err = os.WriteFile(file1, []byte("This is file 1."), os.FileMode(0755)) assert.NoError(t, err) v := viper.New() diff --git a/config/config_notwin_test.go b/config/config_notwin_test.go index 31ddf77f0..33912cc9b 100644 --- a/config/config_notwin_test.go +++ b/config/config_notwin_test.go @@ -1,5 +1,4 @@ //go:build !windows -// +build !windows package config diff --git a/config/config_windows_test.go b/config/config_windows_test.go index da676739f..5757b783f 100644 --- a/config/config_windows_test.go +++ b/config/config_windows_test.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows package config diff --git a/config/resolve_notwin_test.go b/config/resolve_notwin_test.go index eea7ae440..fb70d5f69 100644 --- a/config/resolve_notwin_test.go +++ b/config/resolve_notwin_test.go @@ -1,5 +1,4 @@ //go:build !windows -// +build !windows package config diff --git a/debug/debug.go b/debug/debug.go index 133681439..a96d1f3bd 100644 --- a/debug/debug.go +++ b/debug/debug.go @@ -4,7 +4,6 @@ import ( "bytes" "fmt" "io" - "io/ioutil" "log" "net/http" "net/http/httputil" @@ -42,7 +41,7 @@ func DumpRequest(req *http.Request) { var bodyCopy bytes.Buffer body := io.TeeReader(req.Body, &bodyCopy) - req.Body = ioutil.NopCloser(body) + req.Body = io.NopCloser(body) authHeader := req.Header.Get("Authorization") @@ -63,7 +62,7 @@ func DumpRequest(req *http.Request) { Println("") req.Header.Set("Authorization", authHeader) - req.Body = ioutil.NopCloser(&bodyCopy) + req.Body = io.NopCloser(&bodyCopy) } // DumpResponse dumps out the provided http.Response @@ -74,7 +73,7 @@ func DumpResponse(res *http.Response) { var bodyCopy bytes.Buffer body := io.TeeReader(res.Body, &bodyCopy) - res.Body = ioutil.NopCloser(body) + res.Body = io.NopCloser(body) dump, err := httputil.DumpResponse(res, res.ContentLength > 0) if err != nil { @@ -86,7 +85,7 @@ func DumpResponse(res *http.Response) { Println("========================= END DumpResponse =========================") Println("") - res.Body = ioutil.NopCloser(body) + res.Body = io.NopCloser(body) } // Redact masks the given token by replacing part of the string with * diff --git a/go.mod b/go.mod index 91e79ff1a..c6a4a02a2 100644 --- a/go.mod +++ b/go.mod @@ -1,28 +1,33 @@ module github.com/exercism/cli -go 1.15 +go 1.20 require ( github.com/blang/semver v3.5.1+incompatible - github.com/davecgh/go-spew v1.1.0 - github.com/fsnotify/fsnotify v1.4.2 - github.com/hashicorp/hcl v0.0.0-20170509225359-392dba7d905e github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf - github.com/inconshreveable/mousetrap v1.0.0 - github.com/magiconair/properties v1.7.3 - github.com/mitchellh/mapstructure v0.0.0-20170523030023-d0303fe80992 - github.com/pelletier/go-buffruneio v0.2.0 - github.com/pelletier/go-toml v1.0.0 - github.com/pmezard/go-difflib v1.0.0 - github.com/spf13/afero v0.0.0-20170217164146-9be650865eab - github.com/spf13/cast v1.1.0 - github.com/spf13/cobra v0.0.0-20170731170427-b26b538f6930 - github.com/spf13/jwalterweatherman v0.0.0-20170523133247-0efa5202c046 - github.com/spf13/pflag v1.0.0 - github.com/spf13/viper v0.0.0-20180507071007-15738813a09d - github.com/stretchr/testify v1.1.4 - golang.org/x/net v0.0.0-20170726083632-f5079bd7f6f7 - golang.org/x/sys v0.0.0-20201202213521-69691e467435 - golang.org/x/text v0.0.0-20170730040918-3bd178b88a81 - gopkg.in/yaml.v2 v2.0.0-20170721122051-25c4ec802a7d + github.com/spf13/cobra v1.7.0 + github.com/spf13/pflag v1.0.5 + github.com/spf13/viper v1.15.0 + github.com/stretchr/testify v1.8.4 + golang.org/x/net v0.4.0 + golang.org/x/text v0.5.0 +) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/hashicorp/hcl v1.0.0 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/magiconair/properties v1.8.7 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/pelletier/go-toml/v2 v2.0.6 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/spf13/afero v1.9.3 // indirect + github.com/spf13/cast v1.5.0 // indirect + github.com/spf13/jwalterweatherman v1.1.0 // indirect + github.com/subosito/gotenv v1.4.2 // indirect + golang.org/x/sys v0.3.0 // indirect + gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect + gopkg.in/ini.v1 v1.67.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 7d53fd399..bc3b4c47c 100644 --- a/go.sum +++ b/go.sum @@ -1,46 +1,492 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/fsnotify/fsnotify v1.4.2 h1:v5tKwtf2hNhBV24eNYfQ5UmvFOGlOCmRqk7/P1olxtk= -github.com/fsnotify/fsnotify v1.4.2/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/hashicorp/hcl v0.0.0-20170509225359-392dba7d905e h1:KJWs1uTCkN3E/J5ofCH9Pf8KKsibTFc3fv0CA9+WsVo= -github.com/hashicorp/hcl v0.0.0-20170509225359-392dba7d905e/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf h1:WfD7VjIE6z8dIvMsI4/s+1qr5EL+zoIGev1BQj1eoJ8= github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf/go.mod h1:hyb9oH7vZsitZCiBt0ZvifOrB+qc8PS5IiilCIb87rg= -github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/magiconair/properties v1.7.3 h1:6AOjgCKyZFMG/1yfReDPDz3CJZPxnYk7DGmj2HtyF24= -github.com/magiconair/properties v1.7.3/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/mitchellh/mapstructure v0.0.0-20170523030023-d0303fe80992 h1:W7VHAEVflA5/eTyRvQ53Lz5j8bhRd1myHZlI/IZFvbU= -github.com/mitchellh/mapstructure v0.0.0-20170523030023-d0303fe80992/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/pelletier/go-buffruneio v0.2.0 h1:U4t4R6YkofJ5xHm3dJzuRpPZ0mr5MMCoAWooScCR7aA= -github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo= -github.com/pelletier/go-toml v1.0.0 h1:QFDlmAXZrfPXEF6c9+15fMqhQIS3O0pxszhnk936vg4= -github.com/pelletier/go-toml v1.0.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +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/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= +github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU= +github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/spf13/afero v0.0.0-20170217164146-9be650865eab h1:IVAbBHQR8rXL2Fc8Zba/lMF7KOnTi70lqdx91UTuAwQ= -github.com/spf13/afero v0.0.0-20170217164146-9be650865eab/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/cast v1.1.0 h1:0Rhw4d6C8J9VPu6cjZLIhZ8+aAOHcDvGeKn+cq5Aq3k= -github.com/spf13/cast v1.1.0/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg= -github.com/spf13/cobra v0.0.0-20170731170427-b26b538f6930 h1:uJND9FKkf5s8kdTQX1jDygtp/zV4BJQpYvOmXPCYWgc= -github.com/spf13/cobra v0.0.0-20170731170427-b26b538f6930/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/jwalterweatherman v0.0.0-20170523133247-0efa5202c046 h1:RpxSq53NruItMGgp6q5MsDYoZynisJgEpisQdWJ7PyM= -github.com/spf13/jwalterweatherman v0.0.0-20170523133247-0efa5202c046/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/pflag v1.0.0 h1:oaPbdDe/x0UncahuwiPxW1GYJyilRAdsPnq3e1yaPcI= -github.com/spf13/pflag v1.0.0/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/viper v0.0.0-20180507071007-15738813a09d h1:pIz+bbPLk78K39d3u77IlNpJvpS/f0ao8n3sdy82eCs= -github.com/spf13/viper v0.0.0-20180507071007-15738813a09d/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM= -github.com/stretchr/testify v1.1.4 h1:ToftOQTytwshuOSj6bDSolVUa3GINfJP/fg3OkkOzQQ= -github.com/stretchr/testify v1.1.4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -golang.org/x/net v0.0.0-20170726083632-f5079bd7f6f7 h1:1Pw+ZX4dmGORIwGkTwnUr7RFuMhfpCYHXRZNF04XPYs= -golang.org/x/net v0.0.0-20170726083632-f5079bd7f6f7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/sys v0.0.0-20170803140359-d8f5ea21b929 h1:M4VPQYSW/nB4Bcg1XMD4yW2sprnwerD3Kb6apRphtZw= -golang.org/x/sys v0.0.0-20170803140359-d8f5ea21b929/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20201202213521-69691e467435 h1:25AvDqqB9PrNqj1FLf2/70I4W0L19qqoaFq3gjNwbKk= -golang.org/x/sys v0.0.0-20201202213521-69691e467435/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.0.0-20170730040918-3bd178b88a81 h1:7aXI3TQ9sZ4JdDoIDGjxL6G2mQxlsPy9dySnJaL6Bdk= -golang.org/x/text v0.0.0-20170730040918-3bd178b88a81/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -gopkg.in/yaml.v2 v2.0.0-20170721122051-25c4ec802a7d h1:2DX7x6HUDGZUyuEDAhUsQQNqkb1zvDyKTjVoTdzaEzo= -gopkg.in/yaml.v2 v2.0.0-20170721122051-25c4ec802a7d/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/spf13/afero v1.9.3 h1:41FoI0fD7OR7mGcKE/aOiLkGreyf8ifIOQmJANWogMk= +github.com/spf13/afero v1.9.3/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= +github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= +github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= +github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= +github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= +github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= +github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU= +github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= +github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU= +golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= +golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/workspace/document_test.go b/workspace/document_test.go index 4e055df2f..50013ee73 100644 --- a/workspace/document_test.go +++ b/workspace/document_test.go @@ -1,7 +1,6 @@ package workspace import ( - "io/ioutil" "os" "path/filepath" "testing" @@ -10,7 +9,7 @@ import ( ) func TestNormalizedDocumentPath(t *testing.T) { - root, err := ioutil.TempDir("", "docpath") + root, err := os.MkdirTemp("", "docpath") assert.NoError(t, err) defer os.RemoveAll(root) @@ -32,7 +31,7 @@ func TestNormalizedDocumentPath(t *testing.T) { } for _, tc := range testCases { - err = ioutil.WriteFile(tc.filepath, []byte("a file"), os.FileMode(0600)) + err = os.WriteFile(tc.filepath, []byte("a file"), os.FileMode(0600)) assert.NoError(t, err) doc, err := NewDocument(root, tc.filepath) diff --git a/workspace/exercise_config.go b/workspace/exercise_config.go index 9b0164ebb..35ae7545c 100644 --- a/workspace/exercise_config.go +++ b/workspace/exercise_config.go @@ -3,7 +3,7 @@ package workspace import ( "encoding/json" "errors" - "io/ioutil" + "os" "path/filepath" ) @@ -22,7 +22,7 @@ type ExerciseConfig struct { // NewExerciseConfig reads exercise metadata from a file in the given directory. func NewExerciseConfig(dir string) (*ExerciseConfig, error) { - b, err := ioutil.ReadFile(filepath.Join(dir, configFilepath)) + b, err := os.ReadFile(filepath.Join(dir, configFilepath)) if err != nil { return nil, err } diff --git a/workspace/exercise_config_test.go b/workspace/exercise_config_test.go index d07264c0d..5d9847453 100644 --- a/workspace/exercise_config_test.go +++ b/workspace/exercise_config_test.go @@ -1,7 +1,6 @@ package workspace import ( - "io/ioutil" "os" "path/filepath" "strings" @@ -11,7 +10,7 @@ import ( ) func TestExerciseConfig(t *testing.T) { - dir, err := ioutil.TempDir("", "exercise_config") + dir, err := os.MkdirTemp("", "exercise_config") assert.NoError(t, err) defer os.RemoveAll(dir) @@ -40,7 +39,7 @@ func TestExerciseConfig(t *testing.T) { } func TestExerciseConfigNoTestKey(t *testing.T) { - dir, err := ioutil.TempDir("", "exercise_config") + dir, err := os.MkdirTemp("", "exercise_config") assert.NoError(t, err) defer os.RemoveAll(dir) @@ -64,7 +63,7 @@ func TestExerciseConfigNoTestKey(t *testing.T) { } func TestMissingExerciseConfig(t *testing.T) { - dir, err := ioutil.TempDir("", "exercise_config") + dir, err := os.MkdirTemp("", "exercise_config") assert.NoError(t, err) defer os.RemoveAll(dir) @@ -77,7 +76,7 @@ func TestMissingExerciseConfig(t *testing.T) { } func TestInvalidExerciseConfig(t *testing.T) { - dir, err := ioutil.TempDir("", "exercise_config") + dir, err := os.MkdirTemp("", "exercise_config") assert.NoError(t, err) defer os.RemoveAll(dir) diff --git a/workspace/exercise_metadata.go b/workspace/exercise_metadata.go index 0a0305576..729174258 100644 --- a/workspace/exercise_metadata.go +++ b/workspace/exercise_metadata.go @@ -3,7 +3,6 @@ package workspace import ( "encoding/json" "fmt" - "io/ioutil" "os" "path/filepath" "strings" @@ -32,7 +31,7 @@ type ExerciseMetadata struct { // NewExerciseMetadata reads exercise metadata from a file in the given directory. func NewExerciseMetadata(dir string) (*ExerciseMetadata, error) { - b, err := ioutil.ReadFile(filepath.Join(dir, metadataFilepath)) + b, err := os.ReadFile(filepath.Join(dir, metadataFilepath)) if err != nil { return nil, err } @@ -72,7 +71,7 @@ func (em *ExerciseMetadata) Write(dir string) error { if err = os.MkdirAll(filepath.Dir(metadataAbsoluteFilepath), os.FileMode(0755)); err != nil { return err } - if err = ioutil.WriteFile(metadataAbsoluteFilepath, b, os.FileMode(0600)); err != nil { + if err = os.WriteFile(metadataAbsoluteFilepath, b, os.FileMode(0600)); err != nil { return err } em.Dir = dir diff --git a/workspace/exercise_metadata_test.go b/workspace/exercise_metadata_test.go index e05ffeac3..0c3c7afa7 100644 --- a/workspace/exercise_metadata_test.go +++ b/workspace/exercise_metadata_test.go @@ -1,7 +1,6 @@ package workspace import ( - "io/ioutil" "os" "testing" "time" @@ -10,7 +9,7 @@ import ( ) func TestExerciseMetadata(t *testing.T) { - dir, err := ioutil.TempDir("", "solution") + dir, err := os.MkdirTemp("", "solution") assert.NoError(t, err) defer os.RemoveAll(dir) diff --git a/workspace/exercise_test.go b/workspace/exercise_test.go index 0a6d1d8fa..7dd15c583 100644 --- a/workspace/exercise_test.go +++ b/workspace/exercise_test.go @@ -1,7 +1,6 @@ package workspace import ( - "io/ioutil" "os" "path/filepath" "testing" @@ -10,7 +9,7 @@ import ( ) func TestHasMetadata(t *testing.T) { - ws, err := ioutil.TempDir("", "fake-workspace") + ws, err := os.MkdirTemp("", "fake-workspace") defer os.RemoveAll(ws) assert.NoError(t, err) @@ -22,7 +21,7 @@ func TestHasMetadata(t *testing.T) { err = os.MkdirAll(filepath.Dir(exerciseB.MetadataFilepath()), os.FileMode(0755)) assert.NoError(t, err) - err = ioutil.WriteFile(exerciseA.MetadataFilepath(), []byte{}, os.FileMode(0600)) + err = os.WriteFile(exerciseA.MetadataFilepath(), []byte{}, os.FileMode(0600)) assert.NoError(t, err) ok, err := exerciseA.HasMetadata() @@ -35,7 +34,7 @@ func TestHasMetadata(t *testing.T) { } func TestHasLegacyMetadata(t *testing.T) { - ws, err := ioutil.TempDir("", "fake-workspace") + ws, err := os.MkdirTemp("", "fake-workspace") defer os.RemoveAll(ws) assert.NoError(t, err) @@ -47,7 +46,7 @@ func TestHasLegacyMetadata(t *testing.T) { err = os.MkdirAll(filepath.Dir(exerciseB.LegacyMetadataFilepath()), os.FileMode(0755)) assert.NoError(t, err) - err = ioutil.WriteFile(exerciseA.LegacyMetadataFilepath(), []byte{}, os.FileMode(0600)) + err = os.WriteFile(exerciseA.LegacyMetadataFilepath(), []byte{}, os.FileMode(0600)) assert.NoError(t, err) ok, err := exerciseA.HasLegacyMetadata() @@ -76,7 +75,7 @@ func TestMigrationStatusString(t *testing.T) { } func TestMigrateLegacyMetadataFileWithoutLegacy(t *testing.T) { - ws, err := ioutil.TempDir("", "fake-workspace") + ws, err := os.MkdirTemp("", "fake-workspace") defer os.RemoveAll(ws) assert.NoError(t, err) @@ -85,7 +84,7 @@ func TestMigrateLegacyMetadataFileWithoutLegacy(t *testing.T) { err = os.MkdirAll(filepath.Dir(metadataFilepath), os.FileMode(0755)) assert.NoError(t, err) - err = ioutil.WriteFile(metadataFilepath, []byte{}, os.FileMode(0600)) + err = os.WriteFile(metadataFilepath, []byte{}, os.FileMode(0600)) assert.NoError(t, err) ok, _ := exercise.HasLegacyMetadata() @@ -104,7 +103,7 @@ func TestMigrateLegacyMetadataFileWithoutLegacy(t *testing.T) { } func TestMigrateLegacyMetadataFileWithLegacy(t *testing.T) { - ws, err := ioutil.TempDir("", "fake-workspace") + ws, err := os.MkdirTemp("", "fake-workspace") defer os.RemoveAll(ws) assert.NoError(t, err) @@ -113,7 +112,7 @@ func TestMigrateLegacyMetadataFileWithLegacy(t *testing.T) { err = os.MkdirAll(filepath.Dir(legacyMetadataFilepath), os.FileMode(0755)) assert.NoError(t, err) - err = ioutil.WriteFile(legacyMetadataFilepath, []byte{}, os.FileMode(0600)) + err = os.WriteFile(legacyMetadataFilepath, []byte{}, os.FileMode(0600)) assert.NoError(t, err) ok, _ := exercise.HasLegacyMetadata() @@ -132,7 +131,7 @@ func TestMigrateLegacyMetadataFileWithLegacy(t *testing.T) { } func TestMigrateLegacyMetadataFileWithLegacyAndModern(t *testing.T) { - ws, err := ioutil.TempDir("", "fake-workspace") + ws, err := os.MkdirTemp("", "fake-workspace") defer os.RemoveAll(ws) assert.NoError(t, err) @@ -144,9 +143,9 @@ func TestMigrateLegacyMetadataFileWithLegacyAndModern(t *testing.T) { err = os.MkdirAll(filepath.Dir(metadataFilepath), os.FileMode(0755)) assert.NoError(t, err) - err = ioutil.WriteFile(legacyMetadataFilepath, []byte{}, os.FileMode(0600)) + err = os.WriteFile(legacyMetadataFilepath, []byte{}, os.FileMode(0600)) assert.NoError(t, err) - err = ioutil.WriteFile(metadataFilepath, []byte{}, os.FileMode(0600)) + err = os.WriteFile(metadataFilepath, []byte{}, os.FileMode(0600)) assert.NoError(t, err) ok, _ := exercise.HasLegacyMetadata() diff --git a/workspace/path_type_symlinks_test.go b/workspace/path_type_symlinks_test.go index ace7b741d..a80b6171a 100644 --- a/workspace/path_type_symlinks_test.go +++ b/workspace/path_type_symlinks_test.go @@ -1,5 +1,4 @@ //go:build !windows -// +build !windows package workspace diff --git a/workspace/workspace.go b/workspace/workspace.go index eb9875e8a..0011d4be2 100644 --- a/workspace/workspace.go +++ b/workspace/workspace.go @@ -3,7 +3,6 @@ package workspace import ( "errors" "fmt" - "io/ioutil" "os" "path/filepath" "runtime" @@ -46,7 +45,7 @@ func New(dir string) (Workspace, error) { func (ws Workspace) PotentialExercises() ([]Exercise, error) { exercises := []Exercise{} - topInfos, err := ioutil.ReadDir(ws.Dir) + topInfos, err := os.ReadDir(ws.Dir) if err != nil { return nil, err } @@ -60,7 +59,7 @@ func (ws Workspace) PotentialExercises() ([]Exercise, error) { } if topInfo.Name() == "teams" { - subInfos, err := ioutil.ReadDir(filepath.Join(ws.Dir, "teams")) + subInfos, err := os.ReadDir(filepath.Join(ws.Dir, "teams")) if err != nil { return nil, err } @@ -81,7 +80,7 @@ func (ws Workspace) PotentialExercises() ([]Exercise, error) { continue } - subInfos, err := ioutil.ReadDir(filepath.Join(ws.Dir, topInfo.Name())) + subInfos, err := os.ReadDir(filepath.Join(ws.Dir, topInfo.Name())) if err != nil { return nil, err } diff --git a/workspace/workspace_darwin_test.go b/workspace/workspace_darwin_test.go index 03794a795..47bcab7ec 100644 --- a/workspace/workspace_darwin_test.go +++ b/workspace/workspace_darwin_test.go @@ -2,11 +2,12 @@ package workspace import ( "fmt" - "github.com/stretchr/testify/assert" "path/filepath" "runtime" "strings" "testing" + + "github.com/stretchr/testify/assert" ) func TestExerciseDir_case_insensitive(t *testing.T) { diff --git a/workspace/workspace_test.go b/workspace/workspace_test.go index 160c7cd0e..63053a5cd 100644 --- a/workspace/workspace_test.go +++ b/workspace/workspace_test.go @@ -1,7 +1,6 @@ package workspace import ( - "io/ioutil" "os" "path/filepath" "runtime" @@ -12,7 +11,7 @@ import ( ) func TestWorkspacePotentialExercises(t *testing.T) { - tmpDir, err := ioutil.TempDir("", "walk") + tmpDir, err := os.MkdirTemp("", "walk") defer os.RemoveAll(tmpDir) assert.NoError(t, err) @@ -54,7 +53,7 @@ func TestWorkspacePotentialExercises(t *testing.T) { } func TestWorkspaceExercises(t *testing.T) { - tmpDir, err := ioutil.TempDir("", "walk-with-metadata") + tmpDir, err := os.MkdirTemp("", "walk-with-metadata") defer os.RemoveAll(tmpDir) assert.NoError(t, err) @@ -69,7 +68,7 @@ func TestWorkspaceExercises(t *testing.T) { assert.NoError(t, err) if path != a2 { - err = ioutil.WriteFile(metadataAbsoluteFilepath, []byte{}, os.FileMode(0600)) + err = os.WriteFile(metadataAbsoluteFilepath, []byte{}, os.FileMode(0600)) assert.NoError(t, err) } } From 6e178aa57dc37967e950fefae72c9d4120fb5213 Mon Sep 17 00:00:00 2001 From: baduker Date: Thu, 23 Nov 2023 14:12:40 +0100 Subject: [PATCH 052/142] Setup goreleaser to update homebrew (#1121) --- .goreleaser.yml | 16 ++++++++++++++-- RELEASE.md | 6 ++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index 8a5dccbd2..1fa59b225 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -120,5 +120,17 @@ release: # Default is `{{.Tag}}` name_template: "{{.ProjectName}}-v{{.Version}} {{.Env.USER}}" -# brews: -# We do not use the brew config, which is for taps, not core forumulas. +brews: + - + name: exercism + repository: + owner: exercism + name: homebrew-exercism + commit_author: + name: Exercism Bot + email: 66069679+exercism-bot@users.noreply.github.com + folder: Formula + homepage: "https://exercism.org/" + description: "Command-line tool to interact with exercism.io" + test: | + system "exercism version" diff --git a/RELEASE.md b/RELEASE.md index 566db9f83..87155f4e8 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -40,9 +40,11 @@ goreleaser --skip-publish --snapshot --clean # Create a new tag on the main branch and push it git tag -a "${TAG_NAME}" -m "Trying out GoReleaser" git push origin "${TAG_NAME}" - -# [TODO] Push to homebrew ``` +Brew tap is now managed by `.goreleaser.yml` so no need to update it manually. +GoReleaser can generate and publish a homebrew-tap recipe into a repository +automatically. See [GoReleaser docs](https://goreleaser.com/customization/homebrew/) +for more details. ## Cut Release on GitHub From 90b4b86e8009a992bd1fa34d374418b07383e840 Mon Sep 17 00:00:00 2001 From: Tomas Norre Mikkelsen Date: Fri, 5 Jan 2024 10:44:59 +0100 Subject: [PATCH 053/142] Update FAQ link in Upgrade output (#1124) * Update FAQ link in Upgrade output * Update FAQ link in Upgrade output - update after feedback --- cmd/upgrade.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/upgrade.go b/cmd/upgrade.go index 4b78d4b6f..e4ec04508 100644 --- a/cmd/upgrade.go +++ b/cmd/upgrade.go @@ -32,7 +32,7 @@ We were not able to upgrade the cli because we encountered an error: Please check the FAQ for solutions to common upgrading issues. -https://exercism.io/faqs`, err) +https://exercism.org/faqs`, err) } return nil }, From 331bc718ba974f5f5aafedbc789c26b7533e0ae8 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Tue, 9 Jan 2024 14:45:14 +0100 Subject: [PATCH 054/142] Simplify the root command description (#1125) --- cmd/root.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/root.go b/cmd/root.go index 734c8d4b7..35d266356 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -16,7 +16,7 @@ import ( var RootCmd = &cobra.Command{ Use: BinaryName, Short: "A friendly command-line interface to Exercism.", - Long: `A command-line interface for the v3 redesign of Exercism. + Long: `A command-line interface for Exercism. Download exercises and submit your solutions.`, SilenceUsage: true, From 4950e3cc4a7a85f3cb8da3f005602e3f6c39824f Mon Sep 17 00:00:00 2001 From: Glenn Jackman Date: Wed, 14 Feb 2024 09:10:34 -0500 Subject: [PATCH 055/142] test: update 8th and emacs-lisp test commands (#1128) --- workspace/test_configurations.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/workspace/test_configurations.go b/workspace/test_configurations.go index 32c6fbc3a..176729e1b 100644 --- a/workspace/test_configurations.go +++ b/workspace/test_configurations.go @@ -62,8 +62,7 @@ func (c *TestConfiguration) GetTestCommand() (string, error) { // some tracks aren't (or won't be) implemented; every track is listed either way var TestConfigurations = map[string]TestConfiguration{ "8th": { - Command: "bash tester.sh", - WindowsCommand: "tester.bat", + Command: "8th -f test.8th", }, // abap: tests are run via "ABAP Development Tools", not the CLI "awk": { @@ -117,7 +116,7 @@ var TestConfigurations = map[string]TestConfiguration{ Command: "elm-test", }, "emacs-lisp": { - Command: "emacs -batch -l ert -l *-test.el -f ert-run-tests-batch-and-exit", + Command: "emacs -batch -l ert -l {{test_files}} -f ert-run-tests-batch-and-exit", }, "erlang": { Command: "rebar3 eunit", From 32aeac6c28d426a5149145813d14a3085f84ad1f Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Thu, 15 Feb 2024 09:14:35 +0100 Subject: [PATCH 056/142] Bump version to v3.3.0 (#1129) --- CHANGELOG.md | 5 +++++ cmd/version.go | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a1dcca2ff..9063d3e46 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ The exercism CLI follows [semantic versioning](http://semver.org/). ## Next Release * **Your contribution here** +## v3.3.0 (2024-02-15) +* [#1128](https://github.com/exercism/cli/pull/1128) Fix `exercism test` command not working for the `8th` and `emacs-lisp` tracks - [@glennj] +* [#1125](https://github.com/exercism/cli/pull/1125) Simplify root command description +* [#1124](https://github.com/exercism/cli/pull/1124) Use correct domain for FAQ link [@tomasnorre] + ## v3.2.0 (2023-07-28) * [#1092](https://github.com/exercism/cli/pull/1092) Add `exercism test` command to run the unit tests for nearly any track (inspired by [universal-test-runner](https://github.com/xavdid/universal-test-runner)) - [@xavdid] * [#1073](https://github.com/exercism/cli/pull/1073) Add `arm64` build for each OS diff --git a/cmd/version.go b/cmd/version.go index d8e287f4a..c143cc403 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -9,7 +9,7 @@ import ( // Version is the version of the current build. // It follows semantic versioning. -const Version = "3.2.0" +const Version = "3.3.0" // checkLatest flag for version command. var checkLatest bool From 0a8f77b21f57905722cf182909a71ab6ab0b05f4 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Thu, 15 Feb 2024 09:52:50 +0100 Subject: [PATCH 057/142] Add fingerprint export --- RELEASE.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/RELEASE.md b/RELEASE.md index 87155f4e8..bded12a2c 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -10,7 +10,7 @@ The Exercism CLI uses [GoReleaser](https://goreleaser.com) to automate the relea ## Confirm / Update the Changelog -Make sure all the recent changes are reflected in the "next release" section of the CHANGELOG.md file. +Make sure all the recent changes are reflected in the "next release" section of the CHANGELOG.md file. All the changes in the "next release" section should be moved to a new section that describes the version number, and gives it a date. You can view changes using the /compare/ view: @@ -33,6 +33,7 @@ Once the version bump PR has been merged, run the following commands: ```bash VERSION=$(sed -n -E 's/^const Version = "([0-9]+\.[0-9]+\.[0-9]+)"$/\1/p' cmd/version.go) TAG_NAME="v${VERSION}" +GPG_FINGERPRINT="" # Test run goreleaser --skip-publish --snapshot --clean @@ -41,6 +42,7 @@ goreleaser --skip-publish --snapshot --clean git tag -a "${TAG_NAME}" -m "Trying out GoReleaser" git push origin "${TAG_NAME}" ``` + Brew tap is now managed by `.goreleaser.yml` so no need to update it manually. GoReleaser can generate and publish a homebrew-tap recipe into a repository automatically. See [GoReleaser docs](https://goreleaser.com/customization/homebrew/) From d461855c5bb9a7d7dcce00e8abed53e4513d8288 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Thu, 15 Feb 2024 10:26:13 +0100 Subject: [PATCH 058/142] Format goreleaser.yml --- .goreleaser.yml | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index 1fa59b225..16e221e4a 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -6,11 +6,11 @@ env: builds: - id: release-build main: ./exercism/main.go - mod_timestamp: '{{ .CommitTimestamp }}' + mod_timestamp: "{{ .CommitTimestamp }}" flags: - -trimpath # removes file system paths from compiled executable ldflags: - - '-s -w' # strip debug symbols and DWARF debugging info + - "-s -w" # strip debug symbols and DWARF debugging info goos: - darwin - linux @@ -33,11 +33,11 @@ builds: goarch: arm - id: installer-build main: ./exercism/main.go - mod_timestamp: '{{ .CommitTimestamp }}' + mod_timestamp: "{{ .CommitTimestamp }}" flags: - -trimpath # removes file system paths from compiled executable ldflags: - - '-s -w' # strip debug symbols and DWARF debugging info + - "-s -w" # strip debug symbols and DWARF debugging info goos: - windows goarch: @@ -48,8 +48,8 @@ changelog: sort: asc filters: exclude: - - '^docs:' - - '^test:' + - "^docs:" + - "^test:" archives: - id: release-archives @@ -64,8 +64,8 @@ archives: {{- else }}{{- .Arch }}{{ end }} {{- if .Arm }}v{{- .Arm }}{{ end }} format_overrides: - - goos: windows - format: zip + - goos: windows + format: zip files: - shell/** - LICENSE @@ -82,22 +82,31 @@ archives: {{- else }}{{- .Arch }}{{ end }} {{- if .Arm }}v{{- .Arm }}{{ end }} format_overrides: - - goos: windows - format: zip + - goos: windows + format: zip files: - shell/** - LICENSE - README.md checksum: - name_template: '{{ .ProjectName }}_checksums.txt' + name_template: "{{ .ProjectName }}_checksums.txt" ids: - release-archives - installer-archives signs: - artifacts: checksum - args: ["--batch", "-u", "{{ .Env.GPG_FINGERPRINT }}", "--output", "${signature}", "--detach-sign", "${artifact}"] + args: + [ + "--batch", + "-u", + "{{ .Env.GPG_FINGERPRINT }}", + "--output", + "${signature}", + "--detach-sign", + "${artifact}", + ] release: # Repo in which the release will be created. @@ -121,8 +130,7 @@ release: name_template: "{{.ProjectName}}-v{{.Version}} {{.Env.USER}}" brews: - - - name: exercism + - name: exercism repository: owner: exercism name: homebrew-exercism From 8f1e8f296f7a08158a2f8138c810ddc95e39f279 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Thu, 15 Feb 2024 10:33:14 +0100 Subject: [PATCH 059/142] Fix homebrew repo name (#1130) --- .goreleaser.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index 16e221e4a..f3f965002 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -133,7 +133,7 @@ brews: - name: exercism repository: owner: exercism - name: homebrew-exercism + name: homebrew-core commit_author: name: Exercism Bot email: 66069679+exercism-bot@users.noreply.github.com From 7677e4b17c910ce22d47b39d7eac66052e3dd89d Mon Sep 17 00:00:00 2001 From: Exercism Bot Date: Fri, 1 Mar 2024 14:05:57 +0000 Subject: [PATCH 060/142] =?UTF-8?q?=F0=9F=A4=96=20Sync=20org-wide=20files?= =?UTF-8?q?=20to=20upstream=20repo=20(#1134)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit More info: https://github.com/exercism/org-wide-files/commit/0c0972d1df4cd18d98c7df316348315b06ef49b4 --- CODE_OF_CONDUCT.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index df8e36761..3f7813de1 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -90,4 +90,4 @@ This policy was initially adopted from the Front-end London Slack community and A version history can be seen on [GitHub](https://github.com/exercism/website-copy/edit/main/pages/code_of_conduct.md). _This policy is a "living" document, and subject to refinement and expansion in the future. -This policy applies to the Exercism website, the Exercism GitHub organization, any other Exercism-related communication channels (e.g. Slack, Twitter, email) and any other Exercism entity or event._ +This policy applies to the Exercism website, the Exercism GitHub organization, any other Exercism-related communication channels (e.g. Discord, Forum, Twitter, email) and any other Exercism entity or event._ From c0825fd32b4beba5956b004761d8386635d06942 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 27 Mar 2024 09:12:37 +0100 Subject: [PATCH 061/142] Bump actions/checkout from 4.0.0 to 4.1.0 (#1116) Bumps [actions/checkout](https://github.com/actions/checkout) from 4.0.0 to 4.1.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/3df4ab11eba7bda6032a0b82a6bb43b11571feac...8ade135a41bc03ea155e62e844d188df1ea18608) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 4 ++-- .github/workflows/release.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 704eabdf9..b4510d825 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: os: [ubuntu-latest, windows-latest, macOS-latest] steps: - - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 - uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe with: @@ -39,7 +39,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 - name: Check formatting run: ./.gha.gofmt.sh diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 06175aa06..b7b3c3a47 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,7 +15,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0 + uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 with: fetch-depth: 0 From 38961a652c31b2213fbef766d4c74e58d6cf19e7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Apr 2024 09:01:57 +0200 Subject: [PATCH 062/142] Bump golang.org/x/net from 0.4.0 to 0.23.0 (#1135) Bumps [golang.org/x/net](https://github.com/golang/net) from 0.4.0 to 0.23.0. - [Commits](https://github.com/golang/net/compare/v0.4.0...v0.23.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 6 +++--- go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index c6a4a02a2..e56c3f97a 100644 --- a/go.mod +++ b/go.mod @@ -9,8 +9,8 @@ require ( github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.15.0 github.com/stretchr/testify v1.8.4 - golang.org/x/net v0.4.0 - golang.org/x/text v0.5.0 + golang.org/x/net v0.23.0 + golang.org/x/text v0.14.0 ) require ( @@ -26,7 +26,7 @@ require ( github.com/spf13/cast v1.5.0 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/subosito/gotenv v1.4.2 // indirect - golang.org/x/sys v0.3.0 // indirect + golang.org/x/sys v0.18.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index bc3b4c47c..c042354a7 100644 --- a/go.sum +++ b/go.sum @@ -260,8 +260,8 @@ golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU= -golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= +golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -316,8 +316,8 @@ golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= -golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -325,8 +325,8 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= -golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= From 0b4ebdca31931e2198fa6ae7a25fad76db7a1af7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Apr 2024 09:09:24 +0200 Subject: [PATCH 063/142] Bump goreleaser/goreleaser-action from 4.4.0 to 5.0.0 (#1112) Bumps [goreleaser/goreleaser-action](https://github.com/goreleaser/goreleaser-action) from 4.4.0 to 5.0.0. - [Release notes](https://github.com/goreleaser/goreleaser-action/releases) - [Commits](https://github.com/goreleaser/goreleaser-action/compare/3fa32b8bb5620a2c1afe798654bbad59f9da4906...7ec5c2b0c6cdda6e8bbb49444bc797dd33d74dd8) --- updated-dependencies: - dependency-name: goreleaser/goreleaser-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b7b3c3a47..ef69cb37d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -32,7 +32,7 @@ jobs: passphrase: ${{ secrets.PASSPHRASE }} - name: Cut Release - uses: goreleaser/goreleaser-action@3fa32b8bb5620a2c1afe798654bbad59f9da4906 # v4.4.0 + uses: goreleaser/goreleaser-action@7ec5c2b0c6cdda6e8bbb49444bc797dd33d74dd8 # v5.0.0 with: version: latest args: release --clean --release-header .release/header.md --timeout 120m # default time is 30m From e6aeb01305d4717feb98ecb74097862a3054499a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Apr 2024 09:09:31 +0200 Subject: [PATCH 064/142] Bump crazy-max/ghaction-import-gpg from 5.3.0 to 6.0.0 (#1111) Bumps [crazy-max/ghaction-import-gpg](https://github.com/crazy-max/ghaction-import-gpg) from 5.3.0 to 6.0.0. - [Release notes](https://github.com/crazy-max/ghaction-import-gpg/releases) - [Commits](https://github.com/crazy-max/ghaction-import-gpg/compare/72b6676b71ab476b77e676928516f6982eef7a41...82a020f1f7f605c65dd2449b392a52c3fcfef7ef) --- updated-dependencies: - dependency-name: crazy-max/ghaction-import-gpg dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ef69cb37d..b74d61e58 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -26,7 +26,7 @@ jobs: - name: Import GPG Key id: import_gpg - uses: crazy-max/ghaction-import-gpg@72b6676b71ab476b77e676928516f6982eef7a41 # v5.3.0 + uses: crazy-max/ghaction-import-gpg@82a020f1f7f605c65dd2449b392a52c3fcfef7ef # v6.0.0 with: gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} passphrase: ${{ secrets.PASSPHRASE }} From d08e50e28f898c6b7a9a82e0c28206fcc5d4a074 Mon Sep 17 00:00:00 2001 From: Erivelton de Andrade Nascimento <85421753+eNascimento178@users.noreply.github.com> Date: Thu, 2 May 2024 03:25:37 -0300 Subject: [PATCH 065/142] Add support for j in test_configurations.go (#1136) * Add support for j in test_configurations.go * Exchange double quotes to backtick * Update test_configurations.go --- workspace/test_configurations.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/workspace/test_configurations.go b/workspace/test_configurations.go index 176729e1b..c6ac6fef8 100644 --- a/workspace/test_configurations.go +++ b/workspace/test_configurations.go @@ -139,6 +139,9 @@ var TestConfigurations = map[string]TestConfiguration{ "haskell": { Command: "stack test", }, + "j": { + Command: `jconsole -js "exit echo unittest {{test_files}} [ load {{solution_files}}"`, + }, "java": { Command: "gradle test", }, From 31bf0dc8a2f91516e201b363be2def059eb2477c Mon Sep 17 00:00:00 2001 From: Glenn Jackman Date: Thu, 2 May 2024 02:35:18 -0400 Subject: [PATCH 066/142] Update homebrew formula description to use "exercism.org" (#1131) Co-authored-by: Erik Schierboom --- .goreleaser.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index f3f965002..149fbd8e5 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -139,6 +139,6 @@ brews: email: 66069679+exercism-bot@users.noreply.github.com folder: Formula homepage: "https://exercism.org/" - description: "Command-line tool to interact with exercism.io" + description: "Command-line tool to interact with exercism.org" test: | system "exercism version" From 6bbd4146a822cf2931b2087cc9cbcb2e8858ecc1 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Thu, 2 May 2024 09:22:39 +0200 Subject: [PATCH 067/142] Add scripts (#1138) * Add test build script * Add test script * Ignore test binary --- .gitignore | 1 + bin/build.sh | 3 +++ bin/format.sh | 3 +++ bin/test.sh | 3 +++ 4 files changed, 10 insertions(+) create mode 100755 bin/build.sh create mode 100755 bin/format.sh create mode 100755 bin/test.sh diff --git a/.gitignore b/.gitignore index 1f3baf919..c7963cd6f 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,7 @@ _testmain.go out/ release/ go-exercism +testercism # Intellij /.idea diff --git a/bin/build.sh b/bin/build.sh new file mode 100755 index 000000000..f2ed29c5d --- /dev/null +++ b/bin/build.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +go build -o testercism ./exercism/main.go diff --git a/bin/format.sh b/bin/format.sh new file mode 100755 index 000000000..25c19b2e3 --- /dev/null +++ b/bin/format.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +go fmt ./... diff --git a/bin/test.sh b/bin/test.sh new file mode 100755 index 000000000..062c46972 --- /dev/null +++ b/bin/test.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +go test ./... From 664afb7aa437c85ac9f927551d0718ef87d7bd6e Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Thu, 2 May 2024 09:25:09 +0200 Subject: [PATCH 068/142] Add pyret support to `exercism test` (#1139) --- workspace/test_configurations.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/workspace/test_configurations.go b/workspace/test_configurations.go index c6ac6fef8..ebf9cb4b7 100644 --- a/workspace/test_configurations.go +++ b/workspace/test_configurations.go @@ -191,6 +191,9 @@ var TestConfigurations = map[string]TestConfiguration{ "purescript": { Command: "spago test", }, + "pyret": { + Command: "pyret {{test_files}}", + }, "python": { Command: "python3 -m pytest -o markers=task {{test_files}}", }, From f2ee85a948667cf7bf7275e2211ee48bab963cdd Mon Sep 17 00:00:00 2001 From: Glenn Jackman Date: Thu, 2 May 2024 03:28:44 -0400 Subject: [PATCH 069/142] troubleshoot command should not recommend creating a github issue (#1122) Co-authored-by: Erik Schierboom --- cmd/troubleshoot.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/troubleshoot.go b/cmd/troubleshoot.go index 5fd134d3c..8e5572794 100644 --- a/cmd/troubleshoot.go +++ b/cmd/troubleshoot.go @@ -26,7 +26,7 @@ var troubleshootCmd = &cobra.Command{ Long: `Provides output to help with troubleshooting. If you're running into trouble, copy and paste the output from the troubleshoot -command into a GitHub issue so we can help figure out what's going on. +command into a topic on the Exercism forum so we can help figure out what's going on. `, RunE: func(cmd *cobra.Command, args []string) error { cli.TimeoutInSeconds = cli.TimeoutInSeconds * 2 @@ -255,8 +255,8 @@ API Reachability * {{ .Latency }} {{ end }} -If you are having trouble please file a GitHub issue at -https://github.com/exercism/exercism.io/issues and include +If you are having trouble, please create a new topic in the Exercism forum +at https://forum.exercism.org/c/support/cli/10 and include this information. {{ if not .Censor }} Don't share your API key. Keep that private. From 33ce248e28d29ed1bac7704448c57d505f0541f4 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Thu, 2 May 2024 09:48:21 +0200 Subject: [PATCH 070/142] Fix the release notes link (#1140) --- cmd/troubleshoot.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/troubleshoot.go b/cmd/troubleshoot.go index 8e5572794..4ea5b1444 100644 --- a/cmd/troubleshoot.go +++ b/cmd/troubleshoot.go @@ -227,7 +227,7 @@ Latest: {{ with .Version.Latest }}{{ . }}{{ else }}{{ end }} {{ end -}} {{ if not .Version.UpToDate }} Call 'exercism upgrade' to get the latest version. -See the release notes at https://github.com/exercism/cli/releases/tag/{{ .Version.Latest }} for details. +See the release notes at https://github.com/exercism/cli/releases/tag/v{{ .Version.Latest }} for details. {{ end }} Operating System From 13d89051e6e6cd516715880481501a3c0ad7b22a Mon Sep 17 00:00:00 2001 From: Fabian Becker Date: Thu, 2 May 2024 12:14:15 +0200 Subject: [PATCH 071/142] Change open cmd to default to current directory (#1070) fixes #1069 Co-authored-by: Erik Schierboom --- cmd/open.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/cmd/open.go b/cmd/open.go index dd41a3cf6..627eac639 100644 --- a/cmd/open.go +++ b/cmd/open.go @@ -15,9 +15,13 @@ var openCmd = &cobra.Command{ Pass the path to the directory that contains the solution you want to see on the website. `, - Args: cobra.ExactArgs(1), + Args: cobra.MaximumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - metadata, err := workspace.NewExerciseMetadata(args[0]) + path := "." + if len(args) == 1 { + path = args[0] + } + metadata, err := workspace.NewExerciseMetadata(path) if err != nil { return err } From 0d2cbbd77b6ecc931fa6920b85b9b7028203dcb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Santos?= Date: Tue, 7 May 2024 09:05:10 +0100 Subject: [PATCH 072/142] Fix submit command usage (#1065) * Fix submit command usage * Update cmd/submit.go Co-authored-by: Victor Goff * Update cmd/submit.go * Update cmd/submit.go * Another format --------- Co-authored-by: Erik Schierboom Co-authored-by: Victor Goff --- cmd/submit.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cmd/submit.go b/cmd/submit.go index aaf3a93c1..eb00aa1f4 100644 --- a/cmd/submit.go +++ b/cmd/submit.go @@ -19,12 +19,14 @@ import ( // submitCmd lets people upload a solution to the website. var submitCmd = &cobra.Command{ - Use: "submit FILE1 [FILE2 ...]", + Use: "submit [ ...]", Aliases: []string{"s"}, Short: "Submit your solution to an exercise.", Long: `Submit your solution to an Exercism exercise. Call the command with the list of files you want to submit. + If you omit the list of files, the CLI will submit the + default solution files for the exercise. `, RunE: func(cmd *cobra.Command, args []string) error { cfg := config.NewConfig() From db9c0e8c231f27bbadd24e40bfa59081e72e789e Mon Sep 17 00:00:00 2001 From: Sander Ploegsma Date: Tue, 7 May 2024 16:14:38 +0200 Subject: [PATCH 073/142] test: use Gradle wrapper for Java track (#1126) Co-authored-by: Erik Schierboom --- workspace/test_configurations.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/workspace/test_configurations.go b/workspace/test_configurations.go index ebf9cb4b7..d09863762 100644 --- a/workspace/test_configurations.go +++ b/workspace/test_configurations.go @@ -143,7 +143,8 @@ var TestConfigurations = map[string]TestConfiguration{ Command: `jconsole -js "exit echo unittest {{test_files}} [ load {{solution_files}}"`, }, "java": { - Command: "gradle test", + Command: "./gradlew test", + WindowsCommand: "gradlew.bat test", }, "javascript": { Command: "npm run test", From be487d803709203385390c896bdacf700ef4e22e Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Thu, 9 May 2024 09:12:46 +0200 Subject: [PATCH 074/142] Update the release instructions (#1141) --- RELEASE.md | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/RELEASE.md b/RELEASE.md index bded12a2c..efcd648cc 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -8,19 +8,12 @@ The Exercism CLI uses [GoReleaser](https://goreleaser.com) to automate the relea 1. [Setup GitHub token](https://goreleaser.com/scm/github/) 1. Have a gpg key installed on your machine - it is [used for signing the artifacts](https://goreleaser.com/customization/sign/) -## Confirm / Update the Changelog - -Make sure all the recent changes are reflected in the "next release" section of the CHANGELOG.md file. -All the changes in the "next release" section should be moved to a new section that describes the version number, and gives it a date. - -You can view changes using the /compare/ view: -https://github.com/exercism/cli/compare/$PREVIOUS_RELEASE...main - ## Bump the version 1. Create a branch for the new version -1. Edit the `Version` constant in `cmd/version.go` -1. Update the `CHANGELOG.md` file +1. Bump the `Version` constant in `cmd/version.go` +1. Update the `CHANGELOG.md` file to include a section for the new version and its changes. + Hint: you can view changes using the compare view: https://github.com/exercism/cli/compare/$PREVIOUS_RELEASE...main. 1. Commit the updated version 1. Create a PR From 95f08f3010a600635afb448f6b96db15329814e1 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Thu, 9 May 2024 09:41:13 +0200 Subject: [PATCH 075/142] Bump version to v3.4.0 (#1142) --- CHANGELOG.md | 9 +++++++++ cmd/version.go | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9063d3e46..86d07e2bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,15 @@ The exercism CLI follows [semantic versioning](http://semver.org/). ## Next Release * **Your contribution here** +## v3.4.0 (2024-05-09) +* [#1126](https://github.com/exercism/cli/pull/1126) Update `exercism test` to use Gradle wrapper to test Java exercise - [@sanderploegsma] +* [#1139](https://github.com/exercism/cli/pull/1139) Add support for Pyret to `exercism test` +* [#1136](https://github.com/exercism/cli/pull/1136) Add support for J to `exercism test` - [@enascimento178] +* [#1070](https://github.com/exercism/cli/pull/1070) `exercism open` does not require specifying the directory (defaults to current directory) - [@halfdan] +* [#1122](https://github.com/exercism/cli/pull/1122) Troubleshoot command suggest to open forum post instead of GitHub issue - [@glennj] +* [#1065](https://github.com/exercism/cli/pull/1065) Update help text for `exercism submit` to indicate specifying files is optional - [@andrerfcsantos] +* [#1140](https://github.com/exercism/cli/pull/1140) Fix release notes link + ## v3.3.0 (2024-02-15) * [#1128](https://github.com/exercism/cli/pull/1128) Fix `exercism test` command not working for the `8th` and `emacs-lisp` tracks - [@glennj] * [#1125](https://github.com/exercism/cli/pull/1125) Simplify root command description diff --git a/cmd/version.go b/cmd/version.go index c143cc403..260afbb79 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -9,7 +9,7 @@ import ( // Version is the version of the current build. // It follows semantic versioning. -const Version = "3.3.0" +const Version = "3.4.0" // checkLatest flag for version command. var checkLatest bool From 66b78b6bfb8bbc2c044d68356eb609e7fbc65d6c Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Thu, 9 May 2024 10:07:18 +0200 Subject: [PATCH 076/142] Fix homebrew (#1143) --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b74d61e58..6b72a309e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -37,5 +37,5 @@ jobs: version: latest args: release --clean --release-header .release/header.md --timeout 120m # default time is 30m env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ secrets.CLI_GITHUB_TOKEN }} GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }} From 9cf9401592058bb960e1c0dd9d2b054a54e328e4 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Thu, 9 May 2024 14:19:22 +0200 Subject: [PATCH 077/142] Fix goreleaser deprecations (#1144) --- .goreleaser.yml | 2 +- RELEASE.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index 149fbd8e5..972d4e704 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -137,7 +137,7 @@ brews: commit_author: name: Exercism Bot email: 66069679+exercism-bot@users.noreply.github.com - folder: Formula + directory: Formula homepage: "https://exercism.org/" description: "Command-line tool to interact with exercism.org" test: | diff --git a/RELEASE.md b/RELEASE.md index efcd648cc..5c65318d3 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -29,7 +29,7 @@ TAG_NAME="v${VERSION}" GPG_FINGERPRINT="" # Test run -goreleaser --skip-publish --snapshot --clean +goreleaser --skip=publish --snapshot --clean # Create a new tag on the main branch and push it git tag -a "${TAG_NAME}" -m "Trying out GoReleaser" From 0509b1bd8c866d3dafc2adb50c317c826116f15a Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Thu, 9 May 2024 15:14:25 +0200 Subject: [PATCH 078/142] Add release script (#1145) --- RELEASE.md | 36 ++++-------------------------------- bin/release.sh | 26 ++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 32 deletions(-) create mode 100755 bin/release.sh diff --git a/RELEASE.md b/RELEASE.md index 5c65318d3..ec956744b 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -14,33 +14,19 @@ The Exercism CLI uses [GoReleaser](https://goreleaser.com) to automate the relea 1. Bump the `Version` constant in `cmd/version.go` 1. Update the `CHANGELOG.md` file to include a section for the new version and its changes. Hint: you can view changes using the compare view: https://github.com/exercism/cli/compare/$PREVIOUS_RELEASE...main. -1. Commit the updated version +1. Commit the updated files 1. Create a PR _Note: It's useful to add the version to the commit message when you bump it: e.g. `Bump version to v2.3.4`._ ## Cut a release -Once the version bump PR has been merged, run the following commands: +Once the version bump PR has been merged, run the following command to cut a release: -```bash -VERSION=$(sed -n -E 's/^const Version = "([0-9]+\.[0-9]+\.[0-9]+)"$/\1/p' cmd/version.go) -TAG_NAME="v${VERSION}" -GPG_FINGERPRINT="" - -# Test run -goreleaser --skip=publish --snapshot --clean - -# Create a new tag on the main branch and push it -git tag -a "${TAG_NAME}" -m "Trying out GoReleaser" -git push origin "${TAG_NAME}" +```shell +GPG_FINGERPINT="" ./bin/release.sh ``` -Brew tap is now managed by `.goreleaser.yml` so no need to update it manually. -GoReleaser can generate and publish a homebrew-tap recipe into a repository -automatically. See [GoReleaser docs](https://goreleaser.com/customization/homebrew/) -for more details. - ## Cut Release on GitHub At this point, Goreleaser will have created a draft release at https://github.com/exercism/cli/releases/tag/vX.Y.Z. @@ -55,20 +41,6 @@ To install, follow the interactive installation instructions at https://exercism Lastly, test and publish the draft -## Update Homebrew - -Next, we'll submit a PR to Homebrew to update the Exercism formula (which is how macOS users usually download the CLI): - -``` -cd /tmp && curl -O https://github.com/exercism/cli/archive/vX.Y.Z.tar.gz -cd $(brew --repository) -git checkout master -brew update -brew bump-formula-pr --strict exercism --url=https://github.com/exercism/cli/archive/vX.Y.Z.tar.gz --sha256=$(shasum -a 256 /tmp/vX.Y.Z.tar.gz) -``` - -For more information see [How To Open a Homebrew Pull Request](https://docs.brew.sh/How-To-Open-a-Homebrew-Pull-Request). - ## Update the docs site If there are any significant changes, we should describe them on diff --git a/bin/release.sh b/bin/release.sh new file mode 100755 index 000000000..05f228455 --- /dev/null +++ b/bin/release.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash + +set -euo pipefail + +if [[ -z "${GPG_FINGERPRINT}" ]]; then + echo "GPG_FINGERPRINT environment variable is not set" + exit 1 +fi + +echo "Syncing repo with latest main..." +git checkout main +git pull + +VERSION=$(sed -n -E 's/^const Version = "([0-9]+\.[0-9]+\.[0-9]+)"$/\1/p' cmd/version.go) +TAG_NAME="v${VERSION}" + +echo "Verify release can be built..." +goreleaser --skip=publish --snapshot --clean + +echo "Pushing tag..." +git tag -a "${TAG_NAME}" -m "Release ${TAG_NAME}" +git push origin "${TAG_NAME}" + +echo "Tag pushed" +echo "The release CI workflow will automatically create a draft release." +echo "Once created, edit the release notes and publish it." From 753a4eb927d8602c785d09a82068237762f66f76 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Thu, 9 May 2024 16:07:05 +0200 Subject: [PATCH 079/142] Remove homebrew references (#1146) --- .github/workflows/release.yml | 2 +- .goreleaser.yml | 14 -------------- RELEASE.md | 6 +++++- 3 files changed, 6 insertions(+), 16 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6b72a309e..b74d61e58 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -37,5 +37,5 @@ jobs: version: latest args: release --clean --release-header .release/header.md --timeout 120m # default time is 30m env: - GITHUB_TOKEN: ${{ secrets.CLI_GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }} diff --git a/.goreleaser.yml b/.goreleaser.yml index 972d4e704..b7491e0b8 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -128,17 +128,3 @@ release: # You can change the name of the GitHub release. # Default is `{{.Tag}}` name_template: "{{.ProjectName}}-v{{.Version}} {{.Env.USER}}" - -brews: - - name: exercism - repository: - owner: exercism - name: homebrew-core - commit_author: - name: Exercism Bot - email: 66069679+exercism-bot@users.noreply.github.com - directory: Formula - homepage: "https://exercism.org/" - description: "Command-line tool to interact with exercism.org" - test: | - system "exercism version" diff --git a/RELEASE.md b/RELEASE.md index ec956744b..35a02dbf1 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -39,7 +39,11 @@ To install, follow the interactive installation instructions at https://exercism [modify the generated release-notes to describe changes in this release] ``` -Lastly, test and publish the draft +Lastly, test and then publish the draft. + +## Homebrew + +Homebrew will automatically bump the version, no manual action is required. ## Update the docs site From ee8414b12d980e8594d3ccc44e83cfdf3e8dc9f1 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Thu, 6 Jun 2024 21:04:38 +0200 Subject: [PATCH 080/142] Add arturo to tests (#1147) --- workspace/test_configurations.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/workspace/test_configurations.go b/workspace/test_configurations.go index d09863762..14b838be1 100644 --- a/workspace/test_configurations.go +++ b/workspace/test_configurations.go @@ -65,6 +65,9 @@ var TestConfigurations = map[string]TestConfiguration{ Command: "8th -f test.8th", }, // abap: tests are run via "ABAP Development Tools", not the CLI + "arturo": { + Command: "arturo tester.art", + }, "awk": { Command: "bats {{test_files}}", }, From 72e984f02e8684d686478e71321a067ca39b2836 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nenad=20Misi=C4=87?= Date: Tue, 23 Jul 2024 12:57:05 +0200 Subject: [PATCH 081/142] Add cairo to test config (#1151) --- workspace/test_configurations.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/workspace/test_configurations.go b/workspace/test_configurations.go index 14b838be1..72b359edf 100644 --- a/workspace/test_configurations.go +++ b/workspace/test_configurations.go @@ -80,6 +80,9 @@ var TestConfigurations = map[string]TestConfiguration{ "c": { Command: "make", }, + "cairo": { + Command: "scarb cairo-test", + }, "cfml": { Command: "box task run TestRunner", }, From def312e0b1512846e8d8b53d2e0e774b22b978a2 Mon Sep 17 00:00:00 2001 From: isberg Date: Fri, 2 Aug 2024 14:32:10 +0200 Subject: [PATCH 082/142] Add idris test configuration (#1152) --- workspace/test_configurations.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/workspace/test_configurations.go b/workspace/test_configurations.go index 72b359edf..f5bb29019 100644 --- a/workspace/test_configurations.go +++ b/workspace/test_configurations.go @@ -145,6 +145,9 @@ var TestConfigurations = map[string]TestConfiguration{ "haskell": { Command: "stack test", }, + "idris": { + Command: "pack test `basename *.ipkg .ipkg`", + }, "j": { Command: `jconsole -js "exit echo unittest {{test_files}} [ load {{solution_files}}"`, }, From 743afdfe32390cdec0e4855e1cb8c5b13341adc2 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Thu, 15 Aug 2024 15:35:02 +0200 Subject: [PATCH 083/142] Bump version to v3.4.1 (#1154) --- CHANGELOG.md | 526 ++++++++++++++++++++++++++----------------------- cmd/version.go | 2 +- 2 files changed, 278 insertions(+), 250 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 86d07e2bd..6398a756a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,448 +2,476 @@ The exercism CLI follows [semantic versioning](http://semver.org/). ----------------- +--- ## Next Release -* **Your contribution here** + +- **Your contribution here** + +## v3.4.1 (2024-08-15) + +- [#1152](https://github.com/exercism/cli/pull/1152) Add support for Idris to `exercism test` - + [@isberg] +- [#1151](https://github.com/exercism/cli/pull/1151) Add support for Cairo to `exercism test` - [@isberg] +- [#1147](https://github.com/exercism/cli/pull/1147) Add support for Arturo to `exercism test` - [@erikschierboom] ## v3.4.0 (2024-05-09) -* [#1126](https://github.com/exercism/cli/pull/1126) Update `exercism test` to use Gradle wrapper to test Java exercise - [@sanderploegsma] -* [#1139](https://github.com/exercism/cli/pull/1139) Add support for Pyret to `exercism test` -* [#1136](https://github.com/exercism/cli/pull/1136) Add support for J to `exercism test` - [@enascimento178] -* [#1070](https://github.com/exercism/cli/pull/1070) `exercism open` does not require specifying the directory (defaults to current directory) - [@halfdan] -* [#1122](https://github.com/exercism/cli/pull/1122) Troubleshoot command suggest to open forum post instead of GitHub issue - [@glennj] -* [#1065](https://github.com/exercism/cli/pull/1065) Update help text for `exercism submit` to indicate specifying files is optional - [@andrerfcsantos] -* [#1140](https://github.com/exercism/cli/pull/1140) Fix release notes link + +- [#1126](https://github.com/exercism/cli/pull/1126) Update `exercism test` to use Gradle wrapper to test Java exercise - [@sanderploegsma] +- [#1139](https://github.com/exercism/cli/pull/1139) Add support for Pyret to `exercism test` +- [#1136](https://github.com/exercism/cli/pull/1136) Add support for J to `exercism test` - [@enascimento178] +- [#1070](https://github.com/exercism/cli/pull/1070) `exercism open` does not require specifying the directory (defaults to current directory) - [@halfdan] +- [#1122](https://github.com/exercism/cli/pull/1122) Troubleshoot command suggest to open forum post instead of GitHub issue - [@glennj] +- [#1065](https://github.com/exercism/cli/pull/1065) Update help text for `exercism submit` to indicate specifying files is optional - [@andrerfcsantos] +- [#1140](https://github.com/exercism/cli/pull/1140) Fix release notes link ## v3.3.0 (2024-02-15) -* [#1128](https://github.com/exercism/cli/pull/1128) Fix `exercism test` command not working for the `8th` and `emacs-lisp` tracks - [@glennj] -* [#1125](https://github.com/exercism/cli/pull/1125) Simplify root command description -* [#1124](https://github.com/exercism/cli/pull/1124) Use correct domain for FAQ link [@tomasnorre] + +- [#1128](https://github.com/exercism/cli/pull/1128) Fix `exercism test` command not working for the `8th` and `emacs-lisp` tracks - [@glennj] +- [#1125](https://github.com/exercism/cli/pull/1125) Simplify root command description +- [#1124](https://github.com/exercism/cli/pull/1124) Use correct domain for FAQ link [@tomasnorre] ## v3.2.0 (2023-07-28) -* [#1092](https://github.com/exercism/cli/pull/1092) Add `exercism test` command to run the unit tests for nearly any track (inspired by [universal-test-runner](https://github.com/xavdid/universal-test-runner)) - [@xavdid] -* [#1073](https://github.com/exercism/cli/pull/1073) Add `arm64` build for each OS + +- [#1092](https://github.com/exercism/cli/pull/1092) Add `exercism test` command to run the unit tests for nearly any track (inspired by [universal-test-runner](https://github.com/xavdid/universal-test-runner)) - [@xavdid] +- [#1073](https://github.com/exercism/cli/pull/1073) Add `arm64` build for each OS ## v3.1.0 (2022-10-04) -* [#979](https://github.com/exercism/cli/pull/979) Protect existing solutions from being overwritten by 'download' - [@harugo] -* [#981](https://github.com/exercism/cli/pull/981) Check if authorisation header is set before attempting to extract token - [@harugo] -* [#1044](https://github.com/exercism/cli/pull/1044) Submit without specifying files - [@andrerfcsantos] + +- [#979](https://github.com/exercism/cli/pull/979) Protect existing solutions from being overwritten by 'download' - [@harugo] +- [#981](https://github.com/exercism/cli/pull/981) Check if authorisation header is set before attempting to extract token - [@harugo] +- [#1044](https://github.com/exercism/cli/pull/1044) Submit without specifying files - [@andrerfcsantos] ## v3.0.13 (2019-10-23) -* [#866](https://github.com/exercism/cli/pull/866) The API token outputted during verbose will now be masked by default - [@Jrank2013] -* [#873](https://github.com/exercism/cli/pull/873) Make all errors in cmd package checked - [@avegner] -* [#871](https://github.com/exercism/cli/pull/871) Error message returned if the track is locked - [@Jrank2013] -* [#886](https://github.com/exercism/cli/pull/886) Added GoReleaser config, updated docs, made archive naming adjustments - [@ekingery] + +- [#866](https://github.com/exercism/cli/pull/866) The API token outputted during verbose will now be masked by default - [@Jrank2013] +- [#873](https://github.com/exercism/cli/pull/873) Make all errors in cmd package checked - [@avegner] +- [#871](https://github.com/exercism/cli/pull/871) Error message returned if the track is locked - [@Jrank2013] +- [#886](https://github.com/exercism/cli/pull/886) Added GoReleaser config, updated docs, made archive naming adjustments - [@ekingery] ## v3.0.12 (2019-07-07) -* [#770](https://github.com/exercism/cli/pull/770) Print API error messages in submit command - [@Smarticles101] -* [#763](https://github.com/exercism/cli/pull/763) Add Fish shell tab completions - [@John-Goff] -* [#806](https://github.com/exercism/cli/pull/806) Make Zsh shell tab completions work on $fpath - [@QuLogic] -* [#797](https://github.com/exercism/cli/pull/797) Fix panic when submit command is not given args - [@jdsutherland] -* [#828](https://github.com/exercism/cli/pull/828) Remove duplicate files before submitting - [@larson004] -* [#793](https://github.com/exercism/cli/pull/793) Submit handles non 2xx responses - [@jdsutherland] + +- [#770](https://github.com/exercism/cli/pull/770) Print API error messages in submit command - [@Smarticles101] +- [#763](https://github.com/exercism/cli/pull/763) Add Fish shell tab completions - [@John-Goff] +- [#806](https://github.com/exercism/cli/pull/806) Make Zsh shell tab completions work on $fpath - [@QuLogic] +- [#797](https://github.com/exercism/cli/pull/797) Fix panic when submit command is not given args - [@jdsutherland] +- [#828](https://github.com/exercism/cli/pull/828) Remove duplicate files before submitting - [@larson004] +- [#793](https://github.com/exercism/cli/pull/793) Submit handles non 2xx responses - [@jdsutherland] ## v3.0.11 (2018-11-18) -* [#752](https://github.com/exercism/cli/pull/752) Improve error message on upgrade command - [@farisj] -* [#759](https://github.com/exercism/cli/pull/759) Update shell tab completion for bash and zsh - [@nywilken] -* [#762](https://github.com/exercism/cli/pull/762) Improve usage documentation - [@Smarticles101] -* [#766](https://github.com/exercism/cli/pull/766) Tweak messaging to work for teams edition - [@kytrinyx] + +- [#752](https://github.com/exercism/cli/pull/752) Improve error message on upgrade command - [@farisj] +- [#759](https://github.com/exercism/cli/pull/759) Update shell tab completion for bash and zsh - [@nywilken] +- [#762](https://github.com/exercism/cli/pull/762) Improve usage documentation - [@Smarticles101] +- [#766](https://github.com/exercism/cli/pull/766) Tweak messaging to work for teams edition - [@kytrinyx] ## v3.0.10 (2018-10-03) -* official release of v3.0.10-alpha.1 - [@nywilken] + +- official release of v3.0.10-alpha.1 - [@nywilken] ## v3.0.10-alpha.1 (2018-09-21) -* [#739](https://github.com/exercism/cli/pull/739) update maxFileSize error to include filename - [@nywilken] -* [#736](https://github.com/exercism/cli/pull/736) Metadata file .solution.json renamed to metadata.json - [@jdsutherland] -* [#738](https://github.com/exercism/cli/pull/738) Add missing contributor URLs to CHANGELOG - [@nywilken] -* [#737](https://github.com/exercism/cli/pull/737) Remove unused solutions type - [@jdsutherland] -* [#729](https://github.com/exercism/cli/pull/729) Update Oh My Zsh instructions - [@katrinleinweber] -* [#725](https://github.com/exercism/cli/pull/725) Do not allow submission of enormous files - [@sfairchild] -* [#724](https://github.com/exercism/cli/pull/724) Update submit error message when submitting a directory - [@sfairchild] -* [#723](https://github.com/exercism/cli/pull/720) Move .solution.json to hidden subdirectory - [@jdsutherland] + +- [#739](https://github.com/exercism/cli/pull/739) update maxFileSize error to include filename - [@nywilken] +- [#736](https://github.com/exercism/cli/pull/736) Metadata file .solution.json renamed to metadata.json - [@jdsutherland] +- [#738](https://github.com/exercism/cli/pull/738) Add missing contributor URLs to CHANGELOG - [@nywilken] +- [#737](https://github.com/exercism/cli/pull/737) Remove unused solutions type - [@jdsutherland] +- [#729](https://github.com/exercism/cli/pull/729) Update Oh My Zsh instructions - [@katrinleinweber] +- [#725](https://github.com/exercism/cli/pull/725) Do not allow submission of enormous files - [@sfairchild] +- [#724](https://github.com/exercism/cli/pull/724) Update submit error message when submitting a directory - [@sfairchild] +- [#723](https://github.com/exercism/cli/pull/720) Move .solution.json to hidden subdirectory - [@jdsutherland] ## v3.0.9 (2018-08-29) -* [#720](https://github.com/exercism/cli/pull/720) Make the timeout configurable globally - [@kytrinyx] -* [#721](https://github.com/exercism/cli/pull/721) Handle windows filepaths that accidentally got submitted to the server - [@kytrinyx] -* [#722](https://github.com/exercism/cli/pull/722) Handle exercise directories with numeric suffixes - [@kytrinyx] + +- [#720](https://github.com/exercism/cli/pull/720) Make the timeout configurable globally - [@kytrinyx] +- [#721](https://github.com/exercism/cli/pull/721) Handle windows filepaths that accidentally got submitted to the server - [@kytrinyx] +- [#722](https://github.com/exercism/cli/pull/722) Handle exercise directories with numeric suffixes - [@kytrinyx] ## v3.0.8 (2018-08-22) -* [#713](https://github.com/exercism/cli/pull/713) Fix broken support for uuid flag on download command - [@nywilken] + +- [#713](https://github.com/exercism/cli/pull/713) Fix broken support for uuid flag on download command - [@nywilken] ## v3.0.7 (2018-08-21) -* [#705](https://github.com/exercism/cli/pull/705) Fix confusion about path and filepath - [@kytrinyx] -* [#650](https://github.com/exercism/cli/pull/650) Fix encoding problem in filenames - [@williandrade] + +- [#705](https://github.com/exercism/cli/pull/705) Fix confusion about path and filepath - [@kytrinyx] +- [#650](https://github.com/exercism/cli/pull/650) Fix encoding problem in filenames - [@williandrade] ## v3.0.6 (2018-07-17) -* [#652](https://github.com/exercism/cli/pull/652) Add support for teams feature - [@kytrinyx] -* [#683](https://github.com/exercism/cli/pull/683) Fix typo in welcome message - [@glebedel] -* [#675](https://github.com/exercism/cli/pull/675) Improve output of troubleshoot command when CLI is unconfigured - [@kytrinyx] -* [#679](https://github.com/exercism/cli/pull/679) Improve error message for failed /ping on configure - [@kytrinyx] -* [#669](https://github.com/exercism/cli/pull/669) Add debug as alias for troubleshoot - [@kytrinyx] -* [#647](https://github.com/exercism/cli/pull/647) Ensure welcome message has full link to settings page - [@kytrinyx] -* [#667](https://github.com/exercism/cli/pull/667) Improve bash completion script - [@cookrn] + +- [#652](https://github.com/exercism/cli/pull/652) Add support for teams feature - [@kytrinyx] +- [#683](https://github.com/exercism/cli/pull/683) Fix typo in welcome message - [@glebedel] +- [#675](https://github.com/exercism/cli/pull/675) Improve output of troubleshoot command when CLI is unconfigured - [@kytrinyx] +- [#679](https://github.com/exercism/cli/pull/679) Improve error message for failed /ping on configure - [@kytrinyx] +- [#669](https://github.com/exercism/cli/pull/669) Add debug as alias for troubleshoot - [@kytrinyx] +- [#647](https://github.com/exercism/cli/pull/647) Ensure welcome message has full link to settings page - [@kytrinyx] +- [#667](https://github.com/exercism/cli/pull/667) Improve bash completion script - [@cookrn] ## v3.0.5 (2018-07-17) -* [#646](https://github.com/exercism/cli/pull/646) Fix issue with upgrading on Windows - [@nywilken] + +- [#646](https://github.com/exercism/cli/pull/646) Fix issue with upgrading on Windows - [@nywilken] ## v3.0.4 (2018-07-15) -* [#644](https://github.com/exercism/cli/pull/644) Add better error messages when solution metadata is missing - [@kytrinyx] + +- [#644](https://github.com/exercism/cli/pull/644) Add better error messages when solution metadata is missing - [@kytrinyx] ## v3.0.3 (2018-07-14) -* [#642](https://github.com/exercism/cli/pull/642) Add better error messages when configuration is needed before download - [@kytrinyx] -* [#641](https://github.com/exercism/cli/pull/641) Fix broken download for uuid flag - [@kytrinyx] -* [#618](https://github.com/exercism/cli/pull/618) Fix broken test in Windows build for relative paths - [@nywilken] -* [#631](https://github.com/exercism/cli/pull/631) Stop accepting token flag on download command - [@kytrinyx] -* [#616](https://github.com/exercism/cli/pull/616) Add shell completion scripts to build artifacts - [@jdsutherland] -* [#624](https://github.com/exercism/cli/pull/624) Tweak command documentation to reflect reality - [@kytrinyx] -* [#625](https://github.com/exercism/cli/pull/625) Fix wildly excessive whitespace in error messages - [@kytrinyx] + +- [#642](https://github.com/exercism/cli/pull/642) Add better error messages when configuration is needed before download - [@kytrinyx] +- [#641](https://github.com/exercism/cli/pull/641) Fix broken download for uuid flag - [@kytrinyx] +- [#618](https://github.com/exercism/cli/pull/618) Fix broken test in Windows build for relative paths - [@nywilken] +- [#631](https://github.com/exercism/cli/pull/631) Stop accepting token flag on download command - [@kytrinyx] +- [#616](https://github.com/exercism/cli/pull/616) Add shell completion scripts to build artifacts - [@jdsutherland] +- [#624](https://github.com/exercism/cli/pull/624) Tweak command documentation to reflect reality - [@kytrinyx] +- [#625](https://github.com/exercism/cli/pull/625) Fix wildly excessive whitespace in error messages - [@kytrinyx] ## v3.0.2 (2018-07-13) -* [#622](https://github.com/exercism/cli/pull/622) Fix bug with multi-file submission - [@kytrinyx] + +- [#622](https://github.com/exercism/cli/pull/622) Fix bug with multi-file submission - [@kytrinyx] ## v3.0.1 (2018-07-13) -* [#619](https://github.com/exercism/cli/pull/619) Improve error message for successful configuration - [@kytrinyx] + +- [#619](https://github.com/exercism/cli/pull/619) Improve error message for successful configuration - [@kytrinyx] ## v3.0.0 (2018-07-13) This is a complete rewrite from the ground up to work against the new https://exercism.io site. ## v2.4.1 (2017-07-01) -* [#385](https://github.com/exercism/cli/pull/385) Fix broken upgrades for Windows - [@Tonkpils] + +- [#385](https://github.com/exercism/cli/pull/385) Fix broken upgrades for Windows - [@Tonkpils] ## v2.4.0 (2017-03-24) -* [#344](https://github.com/exercism/cli/pull/344) Make the CLI config paths more XDG friendly - [@narqo] -* [#346](https://github.com/exercism/cli/pull/346) Fallback to UTF-8 if encoding is uncertain - [@petertseng] -* [#350](https://github.com/exercism/cli/pull/350) Add ARMv8 binaries to CLI releases - [@Tonkpils] -* [#352](https://github.com/exercism/cli/pull/352) Fix case sensitivity on slug and track ID - [@Tonkpils] -* [#353](https://github.com/exercism/cli/pull/353) Print confirmation when fetching --all - [@neslom] -* [#356](https://github.com/exercism/cli/pull/356) Resolve symlinks before attempting to read files - [@lcowell] -* [#358](https://github.com/exercism/cli/pull/358) Redact API key from debug output - [@Tonkpils] -* [#359](https://github.com/exercism/cli/pull/359) Add short flag `-m` for submit comment flag - [@jgsqware] -* [#366](https://github.com/exercism/cli/pull/366) Allow obfuscation on configure command - [@dmmulroy] -* [#367](https://github.com/exercism/cli/pull/367) Use supplied confirmation text from API on submit - [@nilbus] +- [#344](https://github.com/exercism/cli/pull/344) Make the CLI config paths more XDG friendly - [@narqo] +- [#346](https://github.com/exercism/cli/pull/346) Fallback to UTF-8 if encoding is uncertain - [@petertseng] +- [#350](https://github.com/exercism/cli/pull/350) Add ARMv8 binaries to CLI releases - [@Tonkpils] +- [#352](https://github.com/exercism/cli/pull/352) Fix case sensitivity on slug and track ID - [@Tonkpils] +- [#353](https://github.com/exercism/cli/pull/353) Print confirmation when fetching --all - [@neslom] +- [#356](https://github.com/exercism/cli/pull/356) Resolve symlinks before attempting to read files - [@lcowell] +- [#358](https://github.com/exercism/cli/pull/358) Redact API key from debug output - [@Tonkpils] +- [#359](https://github.com/exercism/cli/pull/359) Add short flag `-m` for submit comment flag - [@jgsqware] +- [#366](https://github.com/exercism/cli/pull/366) Allow obfuscation on configure command - [@dmmulroy] +- [#367](https://github.com/exercism/cli/pull/367) Use supplied confirmation text from API on submit - [@nilbus] ## v2.3.0 (2016-08-07) -* [#339](https://github.com/exercism/cli/pull/339) Don't run status command if API key is missing - [@ests] -* [#336](https://github.com/exercism/cli/pull/336) Add '--all' flag to fetch command - [@neslom] -* [#333](https://github.com/exercism/cli/pull/333) Update references of codegangsta/cli -> urfave/cli - [@manusajith], [@blackerby] -* [#331](https://github.com/exercism/cli/pull/331) Improve usage/help text of submit command - [@manusajith] +- [#339](https://github.com/exercism/cli/pull/339) Don't run status command if API key is missing - [@ests] +- [#336](https://github.com/exercism/cli/pull/336) Add '--all' flag to fetch command - [@neslom] +- [#333](https://github.com/exercism/cli/pull/333) Update references of codegangsta/cli -> urfave/cli - [@manusajith], [@blackerby] +- [#331](https://github.com/exercism/cli/pull/331) Improve usage/help text of submit command - [@manusajith] ## v2.2.6 (2016-05-30) -* [#306](https://github.com/exercism/cli/pull/306) Don't use Fatal to print usage - [@broady] -* [#307](https://github.com/exercism/cli/pull/307) Pass API key when fetching individual exercises - [@kytrinyx] -* [#312](https://github.com/exercism/cli/pull/312) Add missing newline on usage string - [@jppunnett] -* [#318](https://github.com/exercism/cli/pull/318) Show activity stream URL after submitting - [@lcowell] -* [4710640](https://github.com/exercism/cli/commit/4710640751c7a01deb1b5bf8a9a65b611b078c05) - [@lcowell] -* Update codegangsta/cli dependency - [@manusajith], [@lcowell] -* [#320](https://github.com/exercism/cli/pull/320) Add missing newlines to usage strings - [@hjljo] -* [#328](https://github.com/exercism/cli/pull/328) Append solution URL path consistently - [@Tonkpils] +- [#306](https://github.com/exercism/cli/pull/306) Don't use Fatal to print usage - [@broady] +- [#307](https://github.com/exercism/cli/pull/307) Pass API key when fetching individual exercises - [@kytrinyx] +- [#312](https://github.com/exercism/cli/pull/312) Add missing newline on usage string - [@jppunnett] +- [#318](https://github.com/exercism/cli/pull/318) Show activity stream URL after submitting - [@lcowell] +- [4710640](https://github.com/exercism/cli/commit/4710640751c7a01deb1b5bf8a9a65b611b078c05) - [@lcowell] +- Update codegangsta/cli dependency - [@manusajith], [@lcowell] +- [#320](https://github.com/exercism/cli/pull/320) Add missing newlines to usage strings - [@hjljo] +- [#328](https://github.com/exercism/cli/pull/328) Append solution URL path consistently - [@Tonkpils] ## v2.2.5 (2016-04-02) -* [#284](https://github.com/exercism/cli/pull/284) Update release instructions - [@kytrinyx] -* [#285](https://github.com/exercism/cli/pull/285) Create a copy/pastable release text - [@kytrinyx] -* [#289](https://github.com/exercism/cli/pull/289) Fix a typo in the usage statement - [@AlexWheeler] -* [#290](https://github.com/exercism/cli/pull/290) Fix upgrade command for Linux systems - [@jbaiter] -* [#292](https://github.com/exercism/cli/pull/292) Vendor dependencies - [@Tonkpils] -* [#293](https://github.com/exercism/cli/pull/293) Remove extraneous/distracting details from README - [@Tonkpils] -* [#294](https://github.com/exercism/cli/pull/294) Improve usage statement: alphabetize commands - [@beanieboi] -* [#297](https://github.com/exercism/cli/pull/297) Improve debug output when API key is unconfigured - [@mrageh] -* [#299](https://github.com/exercism/cli/pull/299) List output uses track ID and problem from list - [@Tonkpils] -* [#301](https://github.com/exercism/cli/pull/301) Return error message for unknown track status - [@neslom] -* [#302](https://github.com/exercism/cli/pull/302) Add helpful error message when user tries to submit a directory - [@alebaffa] +- [#284](https://github.com/exercism/cli/pull/284) Update release instructions - [@kytrinyx] +- [#285](https://github.com/exercism/cli/pull/285) Create a copy/pastable release text - [@kytrinyx] +- [#289](https://github.com/exercism/cli/pull/289) Fix a typo in the usage statement - [@AlexWheeler] +- [#290](https://github.com/exercism/cli/pull/290) Fix upgrade command for Linux systems - [@jbaiter] +- [#292](https://github.com/exercism/cli/pull/292) Vendor dependencies - [@Tonkpils] +- [#293](https://github.com/exercism/cli/pull/293) Remove extraneous/distracting details from README - [@Tonkpils] +- [#294](https://github.com/exercism/cli/pull/294) Improve usage statement: alphabetize commands - [@beanieboi] +- [#297](https://github.com/exercism/cli/pull/297) Improve debug output when API key is unconfigured - [@mrageh] +- [#299](https://github.com/exercism/cli/pull/299) List output uses track ID and problem from list - [@Tonkpils] +- [#301](https://github.com/exercism/cli/pull/301) Return error message for unknown track status - [@neslom] +- [#302](https://github.com/exercism/cli/pull/302) Add helpful error message when user tries to submit a directory - [@alebaffa] ## v2.2.4 (2016-01-28) -* [#270](https://github.com/exercism/cli/pull/270) Allow commenting on submission with --comment - [@Tonkpils] -* [#271](https://github.com/exercism/cli/pull/271) Increase timeout to 20 seconds - [@Tonkpils] -* [#273](https://github.com/exercism/cli/pull/273) Guard against submitting spec files and README - [@daveyarwood] -* [#278](https://github.com/exercism/cli/pull/278) Create files with 0644 mode, create missing directories for downloaded solutions - [@petertseng] -* [#281](https://github.com/exercism/cli/pull/281) Create missing directories for downloaded problems - [@petertseng] -* [#282](https://github.com/exercism/cli/pull/282) Remove random encouragement after submitting - [@kytrinyx] -* [#283](https://github.com/exercism/cli/pull/283) Print current configuration after calling configure command - [@kytrinyx] +- [#270](https://github.com/exercism/cli/pull/270) Allow commenting on submission with --comment - [@Tonkpils] +- [#271](https://github.com/exercism/cli/pull/271) Increase timeout to 20 seconds - [@Tonkpils] +- [#273](https://github.com/exercism/cli/pull/273) Guard against submitting spec files and README - [@daveyarwood] +- [#278](https://github.com/exercism/cli/pull/278) Create files with 0644 mode, create missing directories for downloaded solutions - [@petertseng] +- [#281](https://github.com/exercism/cli/pull/281) Create missing directories for downloaded problems - [@petertseng] +- [#282](https://github.com/exercism/cli/pull/282) Remove random encouragement after submitting - [@kytrinyx] +- [#283](https://github.com/exercism/cli/pull/283) Print current configuration after calling configure command - [@kytrinyx] ## v2.2.3 (2015-12-27) -* [#264](https://github.com/exercism/cli/pull/264) Fix version flag to use --version and --v - [@Tonkpils] + +- [#264](https://github.com/exercism/cli/pull/264) Fix version flag to use --version and --v - [@Tonkpils] ## v2.2.2 (2015-12-26) -* [#212](https://github.com/exercism/cli/pull/212) extract path related code from config - [@lcowell] -* [#215](https://github.com/exercism/cli/pull/215) use $XDG_CONFIG_HOME if available - [@lcowell] -* [#248](https://github.com/exercism/cli/pull/248) [#253](https://github.com/exercism/cli/pull/253) add debugging output - [@lcowell] -* [#256](https://github.com/exercism/cli/pull/256) clean up build scripts - [@lcowell] -* [#258](https://github.com/exercism/cli/pull/258) reduce filesystem noise on fetch [@devonestes] -* [#261](https://github.com/exercism/cli/pull/261) improve error message when track and exercise can't be identified on submit - [@anxiousmodernman] -* [#262](https://github.com/exercism/cli/pull/262) encourage iterating to improve after first submission on an exercise - [@eToThePiIPower] +- [#212](https://github.com/exercism/cli/pull/212) extract path related code from config - [@lcowell] +- [#215](https://github.com/exercism/cli/pull/215) use $XDG_CONFIG_HOME if available - [@lcowell] +- [#248](https://github.com/exercism/cli/pull/248) [#253](https://github.com/exercism/cli/pull/253) add debugging output - [@lcowell] +- [#256](https://github.com/exercism/cli/pull/256) clean up build scripts - [@lcowell] +- [#258](https://github.com/exercism/cli/pull/258) reduce filesystem noise on fetch [@devonestes] +- [#261](https://github.com/exercism/cli/pull/261) improve error message when track and exercise can't be identified on submit - [@anxiousmodernman] +- [#262](https://github.com/exercism/cli/pull/262) encourage iterating to improve after first submission on an exercise - [@eToThePiIPower] ## v2.2.1 (2015-08-11) -* [#200](https://github.com/exercism/cli/pull/200): Add guard to unsubmit command - [@kytrinyx] -* [#204](https://github.com/exercism/cli/pull/204): Improve upgrade failure messages and increase timeout - [@Tonkpils] -* [#206](https://github.com/exercism/cli/pull/207): Fix verbose flag and removed short `-v` - [@zabawaba99] -* [#208](https://github.com/exercism/cli/pull/208): avoid ambiguous or unresolvable exercism paths - [@lcowell] +- [#200](https://github.com/exercism/cli/pull/200): Add guard to unsubmit command - [@kytrinyx] +- [#204](https://github.com/exercism/cli/pull/204): Improve upgrade failure messages and increase timeout - [@Tonkpils] +- [#206](https://github.com/exercism/cli/pull/207): Fix verbose flag and removed short `-v` - [@zabawaba99] +- [#208](https://github.com/exercism/cli/pull/208): avoid ambiguous or unresolvable exercism paths - [@lcowell] ## v2.2.0 (2015-06-27) -* [b3c3d6f](https://github.com/exercism/cli/commit/b3c3d6fe54c622fc0ee07fdd221c8e8e5b73c8cd): Improve error message on Internal Server Error - [@Tonkpils] -* [#196](https://github.com/exercism/cli/pull/196): Add upgrade command - [@Tonkpils] -* [#194](https://github.com/exercism/cli/pull/194): Fix home expansion on configure update - [@Tonkpils] -* [523c5bd](https://github.com/exercism/cli/commit/523c5bdec5ef857f07b39de738a764589660cd5a): Document release process - [@kytrinyx] +- [b3c3d6f](https://github.com/exercism/cli/commit/b3c3d6fe54c622fc0ee07fdd221c8e8e5b73c8cd): Improve error message on Internal Server Error - [@Tonkpils] +- [#196](https://github.com/exercism/cli/pull/196): Add upgrade command - [@Tonkpils] +- [#194](https://github.com/exercism/cli/pull/194): Fix home expansion on configure update - [@Tonkpils] +- [523c5bd](https://github.com/exercism/cli/commit/523c5bdec5ef857f07b39de738a764589660cd5a): Document release process - [@kytrinyx] ## v2.1.1 (2015-05-13) -* [#192](https://github.com/exercism/cli/pull/192): Loosen up restrictions on --test flag for submissions - [@Tonkpils] -* [#190](https://github.com/exercism/cli/pull/190): Fix bug in home directory expansion for Windows - [@Tonkpils] +- [#192](https://github.com/exercism/cli/pull/192): Loosen up restrictions on --test flag for submissions - [@Tonkpils] +- [#190](https://github.com/exercism/cli/pull/190): Fix bug in home directory expansion for Windows - [@Tonkpils] ## v2.1.0 (2015-05-08) -* [1a2fd1b](https://github.com/exercism/cli/commit/1a2fd1bfb2dba358611a7c3266f935cccaf924b5): Handle config as either directory or file - [@lcowell] -* [#177](https://github.com/exercism/cli/pull/177): Improve JSON error handling and reporting - [@Tonkpils] -* [#178](https://github.com/exercism/cli/pull/178): Add support for $XDG_CONFIG_HOME - [@lcowell] -* [#184](https://github.com/exercism/cli/pull/184): Handle different file encodings in submissions - [@ambroff] -* [#179](https://github.com/exercism/cli/pull/179): Pretty print the JSON config - [@Tonkpils] -* [#181](https://github.com/exercism/cli/pull/181): Fix path issue when downloading problems - [@Tonkpils] -* [#186](https://github.com/exercism/cli/pull/186): Allow people to specify a target directory for the demo - [@Tonkpils] -* [#189](https://github.com/exercism/cli/pull/189): Implement `--test` flag to allow submitting a test file in the solution - [@pminten] +- [1a2fd1b](https://github.com/exercism/cli/commit/1a2fd1bfb2dba358611a7c3266f935cccaf924b5): Handle config as either directory or file - [@lcowell] +- [#177](https://github.com/exercism/cli/pull/177): Improve JSON error handling and reporting - [@Tonkpils] +- [#178](https://github.com/exercism/cli/pull/178): Add support for $XDG_CONFIG_HOME - [@lcowell] +- [#184](https://github.com/exercism/cli/pull/184): Handle different file encodings in submissions - [@ambroff] +- [#179](https://github.com/exercism/cli/pull/179): Pretty print the JSON config - [@Tonkpils] +- [#181](https://github.com/exercism/cli/pull/181): Fix path issue when downloading problems - [@Tonkpils] +- [#186](https://github.com/exercism/cli/pull/186): Allow people to specify a target directory for the demo - [@Tonkpils] +- [#189](https://github.com/exercism/cli/pull/189): Implement `--test` flag to allow submitting a test file in the solution - [@pminten] ## v2.0.2 (2015-04-01) -* [#174](https://github.com/exercism/cli/issues/174): Fix panic during fetch - [@kytrinyx] -* Refactor handling of ENV vars - [@lcowell] +- [#174](https://github.com/exercism/cli/issues/174): Fix panic during fetch - [@kytrinyx] +- Refactor handling of ENV vars - [@lcowell] ## v2.0.1 (2015-03-25) -* [#167](https://github.com/exercism/cli/pull/167): Fixes misspelling of exercism list command - [@queuebit] -* Tweak output from `fetch` so that languages are scannable. -* [#35](https://github.com/exercism/cli/issues/35): Add support for submitting multiple-file solutions -* [#171](https://github.com/exercism/cli/pull/171): Implement `skip` command to bypass individual exercises - [@Tonkpils] +- [#167](https://github.com/exercism/cli/pull/167): Fixes misspelling of exercism list command - [@queuebit] +- Tweak output from `fetch` so that languages are scannable. +- [#35](https://github.com/exercism/cli/issues/35): Add support for submitting multiple-file solutions +- [#171](https://github.com/exercism/cli/pull/171): Implement `skip` command to bypass individual exercises - [@Tonkpils] ## v2.0.0 (2015-03-05) Added: -* [#154](https://github.com/exercism/cli/pull/154): Add 'list' command to list available exercises for a language - [@lcowell] -* [3551884](https://github.com/exercism/cli/commit/3551884e9f38d6e563b99dae7b28a18d4525455d): Add host connectivity status to debug output. - [@lcowell] -* [#162](https://github.com/exercism/cli/pull/162): Allow users to open the browser from the terminal. - [@zabawaba99] +- [#154](https://github.com/exercism/cli/pull/154): Add 'list' command to list available exercises for a language - [@lcowell] +- [3551884](https://github.com/exercism/cli/commit/3551884e9f38d6e563b99dae7b28a18d4525455d): Add host connectivity status to debug output. - [@lcowell] +- [#162](https://github.com/exercism/cli/pull/162): Allow users to open the browser from the terminal. - [@zabawaba99] Removed: -* Stop supporting legacy config files (`~/.exercism.go`) -* Deleted deprecated login/logout commands -* Deleted deprecated key names in config +- Stop supporting legacy config files (`~/.exercism.go`) +- Deleted deprecated login/logout commands +- Deleted deprecated key names in config Fixed: -* [#151](https://github.com/exercism/cli/pull/151): Expand '~' in config path to home directory - [@lcowell] -* [#155](https://github.com/exercism/cli/pull/155): Display problems not yet submitted on fetch API - [@Tonkpils] -* [f999e69](https://github.com/exercism/cli/commit/f999e69e5290cec6c5c9933aecc6fddfad8cf019): Disambiguate debug and verbose flags. - [@lcowell] -* Report 'new' at the bottom after fetching, it's going to be more relevant than 'unchanged', which includes all the languages they don't care about. +- [#151](https://github.com/exercism/cli/pull/151): Expand '~' in config path to home directory - [@lcowell] +- [#155](https://github.com/exercism/cli/pull/155): Display problems not yet submitted on fetch API - [@Tonkpils] +- [f999e69](https://github.com/exercism/cli/commit/f999e69e5290cec6c5c9933aecc6fddfad8cf019): Disambiguate debug and verbose flags. - [@lcowell] +- Report 'new' at the bottom after fetching, it's going to be more relevant than 'unchanged', which includes all the languages they don't care about. Tweaked: -* Set environment variable in build script -* [#153](https://github.com/exercism/cli/pull/153): Refactored configuration package - [@kytrinyx] -* [#157](https://github.com/exercism/cli/pull/157): Refactored API package - [@Tonkpils] +- Set environment variable in build script +- [#153](https://github.com/exercism/cli/pull/153): Refactored configuration package - [@kytrinyx] +- [#157](https://github.com/exercism/cli/pull/157): Refactored API package - [@Tonkpils] ## v1.9.2 (2015-01-11) -* [exercism.io#2155](https://github.com/exercism/exercism.io/issues/2155): Fixed problem with passed in config file being ignored. -* Added first version of changelog +- [exercism.io#2155](https://github.com/exercism/exercism.io/issues/2155): Fixed problem with passed in config file being ignored. +- Added first version of changelog ## v1.9.1 (2015-01-10) -* [#147](https://github.com/exercism/cli/pull/147): added `--api` option to exercism configure - [@morphatic] +- [#147](https://github.com/exercism/cli/pull/147): added `--api` option to exercism configure - [@morphatic] ## v1.9.0 (2014-11-27) -* [#143](https://github.com/exercism/cli/pull/143): added command for downloading a specific solution - [@harimp] -* [#142](https://github.com/exercism/cli/pull/142): fixed command name to be `exercism` rather than `cli` on `go get` - [@Tonkpils] +- [#143](https://github.com/exercism/cli/pull/143): added command for downloading a specific solution - [@harimp] +- [#142](https://github.com/exercism/cli/pull/142): fixed command name to be `exercism` rather than `cli` on `go get` - [@Tonkpils] ## v1.8.2 (2014-10-24) -* [9cbd069](https://github.com/exercism/cli/commit/9cbd06916cc05bbb165e8c2cb00d5e03cb4dbb99): Made path comparison case insensitive +- [9cbd069](https://github.com/exercism/cli/commit/9cbd06916cc05bbb165e8c2cb00d5e03cb4dbb99): Made path comparison case insensitive ## v1.8.1 (2014-10-23) -* [0ccc7a4](https://github.com/exercism/cli/commit/0ccc7a479940d2d7bb5e12eab41c91105519f135): Implemented debug flag on submit command +- [0ccc7a4](https://github.com/exercism/cli/commit/0ccc7a479940d2d7bb5e12eab41c91105519f135): Implemented debug flag on submit command ## v1.8.0 (2014-10-15) -* [#138](https://github.com/exercism/cli/pull/138): Added conversion to line endings for submissions on Windows - [@rprouse] -* [#116](https://github.com/exercism/cli/issues/116): Added support for setting name of config file in an environment variable -* [47d6fd4](https://github.com/exercism/cli/commit/47d6fd407fd0410f5c81d60172e01e8624608f53): Added a `track` command to list the problems in a given language -* [#126](https://github.com/exercism/cli/issues/126): Added explanation in `submit` response about fetching the next problems -* [#133](https://github.com/exercism/cli/pull/133): Changed config command to create the exercism directory, rather than waiting until the first time problems are fetched - [@Tonkpils] +- [#138](https://github.com/exercism/cli/pull/138): Added conversion to line endings for submissions on Windows - [@rprouse] +- [#116](https://github.com/exercism/cli/issues/116): Added support for setting name of config file in an environment variable +- [47d6fd4](https://github.com/exercism/cli/commit/47d6fd407fd0410f5c81d60172e01e8624608f53): Added a `track` command to list the problems in a given language +- [#126](https://github.com/exercism/cli/issues/126): Added explanation in `submit` response about fetching the next problems +- [#133](https://github.com/exercism/cli/pull/133): Changed config command to create the exercism directory, rather than waiting until the first time problems are fetched - [@Tonkpils] ## v1.7.5 (2014-10-5) -* [88cf1a1fbc884545dfc10e98535f667e4a43e693](https://github.com/exercism/cli/commit/88cf1a1fbc884545dfc10e98535f667e4a43e693): Added ARMv6 to build -* [12672c4](https://github.com/exercism/cli/commit/12672c4f695cfe3891f96467619a3615e6d57c34): Added an error message when people submit a file that is not within the exercism directory tree -* [#128](https://github.com/exercism/cli/pull/128): Made paths os-agnostic in tests - [@ccnp123] +- [88cf1a1fbc884545dfc10e98535f667e4a43e693](https://github.com/exercism/cli/commit/88cf1a1fbc884545dfc10e98535f667e4a43e693): Added ARMv6 to build +- [12672c4](https://github.com/exercism/cli/commit/12672c4f695cfe3891f96467619a3615e6d57c34): Added an error message when people submit a file that is not within the exercism directory tree +- [#128](https://github.com/exercism/cli/pull/128): Made paths os-agnostic in tests - [@ccnp123] ## v1.7.4 (2014-09-27) -* [4ca3e97](https://github.com/exercism/cli/commit/4ca3e9743f6d421903c91dfa27f4747fb1081392): Fixed incorrect HOME directory on Windows -* [8bd1a25](https://github.com/exercism/cli/commit/4ca3e9743f6d421903c91dfa27f4747fb1081392): Added ARMv5 to build -* [#117](https://github.com/exercism/cli/pull/117): Archive windows binaries using zip rather than tar and gzip - [@LegalizeAdulthood] +- [4ca3e97](https://github.com/exercism/cli/commit/4ca3e9743f6d421903c91dfa27f4747fb1081392): Fixed incorrect HOME directory on Windows +- [8bd1a25](https://github.com/exercism/cli/commit/4ca3e9743f6d421903c91dfa27f4747fb1081392): Added ARMv5 to build +- [#117](https://github.com/exercism/cli/pull/117): Archive windows binaries using zip rather than tar and gzip - [@LegalizeAdulthood] ## v1.7.3 (2014-09-26) -* [8bec393](https://github.com/exercism/cli/commit/8bec39387094680990af7cf438ada1780cf87129): Fixed submit so it can handle symlinks +- [8bec393](https://github.com/exercism/cli/commit/8bec39387094680990af7cf438ada1780cf87129): Fixed submit so it can handle symlinks ## v1.7.2 (2014-09-24) -* [#111](https://github.com/exercism/cli/pull/111): Don't clobber existing config values when adding more - [@jish] +- [#111](https://github.com/exercism/cli/pull/111): Don't clobber existing config values when adding more - [@jish] ## v1.7.1 (2014-09-19) -* Completely reorganized the code, separating each command into a separate handler -* [17fc164](https://github.com/exercism/cli/commit/17fc1644e9fc9ee5aa4e136de11556e65a7b6036): Fixed paths to be platform-independent -* [8b174e2](https://github.com/exercism/cli/commit/17fc1644e9fc9ee5aa4e136de11556e65a7b6036): Made the output of demo command more helpful -* [8b174e2](https://github.com/exercism/cli/commit/8b174e2fd8c7a545ea5c47c998ac10c5a7ab371f): Deleted the 'current' command +- Completely reorganized the code, separating each command into a separate handler +- [17fc164](https://github.com/exercism/cli/commit/17fc1644e9fc9ee5aa4e136de11556e65a7b6036): Fixed paths to be platform-independent +- [8b174e2](https://github.com/exercism/cli/commit/17fc1644e9fc9ee5aa4e136de11556e65a7b6036): Made the output of demo command more helpful +- [8b174e2](https://github.com/exercism/cli/commit/8b174e2fd8c7a545ea5c47c998ac10c5a7ab371f): Deleted the 'current' command ## v1.7.0 (2014-08-28) -* [ac6dbfd](https://github.com/exercism/cli/commit/ac6dbfd81a86e7a9a5a9b68521b0226c40d8e813): Added os and architecture to the user agent -* [5d58fd1](https://github.com/exercism/cli/commit/5d58fd14b9db84fb752b3bf6112123cd6f04c532): Fixed bug in detecting user's home directory -* [#100](https://github.com/exercism/cli/pull/100): Added 'debug' command, which supersedes the 'info' command - [@Tonkpils] -* Extracted a couple of commands into separate handlers -* [6ec5876](https://github.com/exercism/cli/commit/6ec5876bde0b02206cacbe685bb8aedcbdba25d4): Added a hack to rename old config files to the new default name -* [bb7d0d6](https://github.com/exercism/cli/commit/bb7d0d6151a950c92590dc771ec3ff5fdd1c83b0): Rename 'home' command to 'info' -* [#95](https://github.com/exercism/cli/issues/95): Added 'home' command -* Deprecate login/logout commands -* [1a39134](https://github.com/exercism/cli/commit/1a391342da93aa32ae398f1500a3981aa65b9f41): Changed demo to write exercises to the default exercism problems directory -* [07cc334](https://github.com/exercism/cli/commit/07cc334739465b21d6eb5d973e16e1c88f67758e): Deleted the whoami command, we weren't using github usernames for anything -* [#97](https://github.com/exercism/cli/pull/97): Changed default exercism directory to ~/exercism - [@lcowell] -* [#94](https://github.com/exercism/cli/pull/94): Updated language detection to handle C++ - [@LegalizeAdulthood] -* [#92](https://github.com/exercism/cli/pull/92): Renamed config json file to .exercism.json instead of .exercism.go - [@lcowell] -* [f55653f](https://github.com/exercism/cli/commit/f55653f35863914086a54375afb0898e142c1638): Deleted go vet from travis build temporarily until the codebase can be cleaned up -* [#91](https://github.com/exercism/cli/pull/91): Replaced temp file usage with encode/decode - [@lcowell] -* [#90](https://github.com/exercism/cli/pull/90): Added sanitization to config values to trim whitespace before writing it - [@lcowell] -* Did a fair amount of cleanup to make code a bit more idiomatic -* [#86](https://github.com/exercism/cli/pull/86): Triggered interactive login command for commands that require auth - [@Tonkpils] +- [ac6dbfd](https://github.com/exercism/cli/commit/ac6dbfd81a86e7a9a5a9b68521b0226c40d8e813): Added os and architecture to the user agent +- [5d58fd1](https://github.com/exercism/cli/commit/5d58fd14b9db84fb752b3bf6112123cd6f04c532): Fixed bug in detecting user's home directory +- [#100](https://github.com/exercism/cli/pull/100): Added 'debug' command, which supersedes the 'info' command - [@Tonkpils] +- Extracted a couple of commands into separate handlers +- [6ec5876](https://github.com/exercism/cli/commit/6ec5876bde0b02206cacbe685bb8aedcbdba25d4): Added a hack to rename old config files to the new default name +- [bb7d0d6](https://github.com/exercism/cli/commit/bb7d0d6151a950c92590dc771ec3ff5fdd1c83b0): Rename 'home' command to 'info' +- [#95](https://github.com/exercism/cli/issues/95): Added 'home' command +- Deprecate login/logout commands +- [1a39134](https://github.com/exercism/cli/commit/1a391342da93aa32ae398f1500a3981aa65b9f41): Changed demo to write exercises to the default exercism problems directory +- [07cc334](https://github.com/exercism/cli/commit/07cc334739465b21d6eb5d973e16e1c88f67758e): Deleted the whoami command, we weren't using github usernames for anything +- [#97](https://github.com/exercism/cli/pull/97): Changed default exercism directory to ~/exercism - [@lcowell] +- [#94](https://github.com/exercism/cli/pull/94): Updated language detection to handle C++ - [@LegalizeAdulthood] +- [#92](https://github.com/exercism/cli/pull/92): Renamed config json file to .exercism.json instead of .exercism.go - [@lcowell] +- [f55653f](https://github.com/exercism/cli/commit/f55653f35863914086a54375afb0898e142c1638): Deleted go vet from travis build temporarily until the codebase can be cleaned up +- [#91](https://github.com/exercism/cli/pull/91): Replaced temp file usage with encode/decode - [@lcowell] +- [#90](https://github.com/exercism/cli/pull/90): Added sanitization to config values to trim whitespace before writing it - [@lcowell] +- Did a fair amount of cleanup to make code a bit more idiomatic +- [#86](https://github.com/exercism/cli/pull/86): Triggered interactive login command for commands that require auth - [@Tonkpils] ## v1.6.2 (2014-06-02) -* [a5b7a55](https://github.com/exercism/cli/commit/a5b7a55f52c23ac5ce2c6bd1826ea7767aea38c4): Update login prompt +- [a5b7a55](https://github.com/exercism/cli/commit/a5b7a55f52c23ac5ce2c6bd1826ea7767aea38c4): Update login prompt ## v1.6.1 (2014-05-16) -* [#84](https://github.com/exercism/cli/pull/84): Change hard-coded filepath so that it will work on any platform - [@simonjefford] +- [#84](https://github.com/exercism/cli/pull/84): Change hard-coded filepath so that it will work on any platform - [@simonjefford] ## v1.6.0 (2014-05-10) -* [#82](https://github.com/exercism/cli/pull/82): Fixed typo in tests - [@srt32] -* [aa7446d](https://github.com/exercism/cli/commit/aa7446d598fc894ef329756555c48ef358baf676): Clarified output to user after they fetch -* [#79](https://github.com/exercism/cli/pull/79): Updated development instructions to fix permissions problem - [@andrewsardone] -* [#78](https://github.com/exercism/cli/pull/78): Deleted deprecated action `peek` - [@djquan] -* [#74](https://github.com/exercism/cli/pull/74): Implemented new option on `fetch` to get a single language - [@Tonkpils] -* [#75](https://github.com/exercism/cli/pull/75): Improved feedback to user after logging in - [@Tonkpils] -* [#72](https://github.com/exercism/cli/pull/72): Optimized use of temp file - [@Dparker1990] -* [#70](https://github.com/exercism/cli/pull/70): Fixed a panic - [@Tonkpils] -* [#68](https://github.com/exercism/cli/pull/68): Fixed how user input is read so that it doesn't stop at the first space - [@Tonkpils] +- [#82](https://github.com/exercism/cli/pull/82): Fixed typo in tests - [@srt32] +- [aa7446d](https://github.com/exercism/cli/commit/aa7446d598fc894ef329756555c48ef358baf676): Clarified output to user after they fetch +- [#79](https://github.com/exercism/cli/pull/79): Updated development instructions to fix permissions problem - [@andrewsardone] +- [#78](https://github.com/exercism/cli/pull/78): Deleted deprecated action `peek` - [@djquan] +- [#74](https://github.com/exercism/cli/pull/74): Implemented new option on `fetch` to get a single language - [@Tonkpils] +- [#75](https://github.com/exercism/cli/pull/75): Improved feedback to user after logging in - [@Tonkpils] +- [#72](https://github.com/exercism/cli/pull/72): Optimized use of temp file - [@Dparker1990] +- [#70](https://github.com/exercism/cli/pull/70): Fixed a panic - [@Tonkpils] +- [#68](https://github.com/exercism/cli/pull/68): Fixed how user input is read so that it doesn't stop at the first space - [@Tonkpils] ## v1.5.1 (2014-03-14) -* [5b672ee](https://github.com/exercism/cli/commit/5b672ee7bf26859c41de9eed83396b7454286063 ): Provided a visual mark next to new problems that get fetched +- [5b672ee](https://github.com/exercism/cli/commit/5b672ee7bf26859c41de9eed83396b7454286063): Provided a visual mark next to new problems that get fetched ## v1.5.0 (2014-02-28) -* [#63](https://github.com/exercism/cli/pull/63): Implemeted `fetch` for a single language - [@Tonkpils] -* [#62](https://github.com/exercism/cli/pull/62): Expose error message from API to user on `fetch` - [@Tonkpils] -* [#59](https://github.com/exercism/cli/pull/59): Added global flag to pass the path to the config file instead of relying on default - [@isbadawi] -* [#57](https://github.com/exercism/cli/pull/57): Added description to the restore command - [@rcode5] -* [#56](https://github.com/exercism/cli/pull/56): Updated developer instructions in README based on real-life experience - [@rcode5] +- [#63](https://github.com/exercism/cli/pull/63): Implemeted `fetch` for a single language - [@Tonkpils] +- [#62](https://github.com/exercism/cli/pull/62): Expose error message from API to user on `fetch` - [@Tonkpils] +- [#59](https://github.com/exercism/cli/pull/59): Added global flag to pass the path to the config file instead of relying on default - [@isbadawi] +- [#57](https://github.com/exercism/cli/pull/57): Added description to the restore command - [@rcode5] +- [#56](https://github.com/exercism/cli/pull/56): Updated developer instructions in README based on real-life experience - [@rcode5] ## v1.4.0 (2014-01-13) -* [#47](https://github.com/exercism/cli/pull/47): Added 'restore' command to download all of a user's existing solutions with their corresponding problems - [@ebautistabar] -* Numerous small fixes and cleanup to code and documentation - [@dpritchett], [@TrevorBramble], [@elimisteve] +- [#47](https://github.com/exercism/cli/pull/47): Added 'restore' command to download all of a user's existing solutions with their corresponding problems - [@ebautistabar] +- Numerous small fixes and cleanup to code and documentation - [@dpritchett], [@TrevorBramble], [@elimisteve] ## v1.3.2 (2013-12-14) -* [f8dd974](https://github.com/exercism/cli/commit/f8dd9748078b1b191629eae385aaeda8af94305b): Fixed content-type header when posting to API -* Fixed user-agent string +- [f8dd974](https://github.com/exercism/cli/commit/f8dd9748078b1b191629eae385aaeda8af94305b): Fixed content-type header when posting to API +- Fixed user-agent string ## v1.3.1 (2013-12-01) -* [exercism.io#1039](https://github.com/exercism/exercism.io/issues/1039): Stopped clobbering existing files on fetch +- [exercism.io#1039](https://github.com/exercism/exercism.io/issues/1039): Stopped clobbering existing files on fetch ## v1.3.0 (2013-11-16) -* [7f39ee4](https://github.com/exercism/cli/commit/7f39ee4802752925466bc2715790dc965026b09d): Allow users to specify a particular problem when fetching. +- [7f39ee4](https://github.com/exercism/cli/commit/7f39ee4802752925466bc2715790dc965026b09d): Allow users to specify a particular problem when fetching. ## v1.2.3 (2013-11-13) -* [exercism.io#998](https://github.com/exercism/exercism.io/issues/998): Fix problem with writing an empty config file under certain circumstances. +- [exercism.io#998](https://github.com/exercism/exercism.io/issues/998): Fix problem with writing an empty config file under certain circumstances. ## v1.2.2 (2013-11-12) -* [#28](https://github.com/exercism/cli/issues/28): Create exercism directory immediately upon logging in. -* Upgrade to newer version of [codegangsta/cli](https://github.com/codegansta/cli) library, which returns an error from the main Run() function. +- [#28](https://github.com/exercism/cli/issues/28): Create exercism directory immediately upon logging in. +- Upgrade to newer version of [codegangsta/cli](https://github.com/codegansta/cli) library, which returns an error from the main Run() function. ## v1.2.1 (2013-11-09) -* [371521f](https://github.com/exercism/cli/commit/371521fd97460aa92269831f10dadd467cb06592): Add support for nested directories under the language track directory allowing us to create idiomatic scala, clojure, and other exercises. +- [371521f](https://github.com/exercism/cli/commit/371521fd97460aa92269831f10dadd467cb06592): Add support for nested directories under the language track directory allowing us to create idiomatic scala, clojure, and other exercises. ## v1.2.0 (2013-11-07) -* [371521f](https://github.com/exercism/cli/commit/371521fd97460aa92269831f10dadd467cb06592): Consume the new hash of filename => content that the problem API returns. +- [371521f](https://github.com/exercism/cli/commit/371521fd97460aa92269831f10dadd467cb06592): Consume the new hash of filename => content that the problem API returns. ## v1.1.1 (2013-10-20) -* [371521f](https://github.com/exercism/cli/commit/371521fd97460aa92269831f10dadd467cb06592): Add output when fetching to tell the user where the files where created. +- [371521f](https://github.com/exercism/cli/commit/371521fd97460aa92269831f10dadd467cb06592): Add output when fetching to tell the user where the files where created. ## v1.1.0 (2013-10-24) -* Refactor to extract config package -* Delete stray binary **TODO** we might rewrite history on this one, see [#102](https://github.com/exercism/xgo/issues/102). -* [#22](https://github.com/exercism/cli/pull/22): Display submission url after submitting solution - [@Tonkpils] -* [#21](https://github.com/exercism/cli/pull/21): Add unsubmit command - [@Tonkpils] -* [#20](https://github.com/exercism/cli/pull/20): Add current command - [@Tonkpils] -* Inline refactoring experiment, various cleanup +- Refactor to extract config package +- Delete stray binary **TODO** we might rewrite history on this one, see [#102](https://github.com/exercism/xgo/issues/102). +- [#22](https://github.com/exercism/cli/pull/22): Display submission url after submitting solution - [@Tonkpils] +- [#21](https://github.com/exercism/cli/pull/21): Add unsubmit command - [@Tonkpils] +- [#20](https://github.com/exercism/cli/pull/20): Add current command - [@Tonkpils] +- Inline refactoring experiment, various cleanup ## v1.0.1 (2013-09-27) -* [#11](https://github.com/exercism/cli/pull/11): Don't require authentication for demo - [@msgehard] -* [#14](https://github.com/exercism/cli/pull/14): Print out fetched assignments - [@Tonkpils] -* [#16](https://github.com/exercism/cli/pull/16): Fix broken submit for relative path names - [@nf] -* Create a separate demo directory if there's no configured exercism directory +- [#11](https://github.com/exercism/cli/pull/11): Don't require authentication for demo - [@msgehard] +- [#14](https://github.com/exercism/cli/pull/14): Print out fetched assignments - [@Tonkpils] +- [#16](https://github.com/exercism/cli/pull/16): Fix broken submit for relative path names - [@nf] +- Create a separate demo directory if there's no configured exercism directory ## v1.0.0 (2013-09-22) -* [#7](https://github.com/exercism/cli/pull/7): Recognize haskell test files -* [#5](https://github.com/exercism/cli/pull/5): Fix typo - [@simonjefford] -* [#1](https://github.com/exercism/cli/pull/1): Output the location of the config file - [@msgehard] -* Recognize more language test files - [@msgehard] +- [#7](https://github.com/exercism/cli/pull/7): Recognize haskell test files +- [#5](https://github.com/exercism/cli/pull/5): Fix typo - [@simonjefford] +- [#1](https://github.com/exercism/cli/pull/1): Output the location of the config file - [@msgehard] +- Recognize more language test files - [@msgehard] ## v0.0.27.beta (2013-08-25) All changes by [@msgehard] -* Clean up homedir -* Add dev instructions to README +- Clean up homedir +- Add dev instructions to README ## v0.0.26.beta (2013-08-24) All changes by [@msgehard] -* Ensure that ruby gem's config file doesn't get clobbered -* Add cross-compilation -* Set proper User-Agent so server doesn't blow up. -* Implement `submit` -* Implement `demo` -* Implement `peek` -* Expand ~ in config -* Implement `fetch` -* Implement `current` -* Implement `whoami` -* Implement login and logout -* Build on Travis +- Ensure that ruby gem's config file doesn't get clobbered +- Add cross-compilation +- Set proper User-Agent so server doesn't blow up. +- Implement `submit` +- Implement `demo` +- Implement `peek` +- Expand ~ in config +- Implement `fetch` +- Implement `current` +- Implement `whoami` +- Implement login and logout +- Build on Travis [@AlexWheeler]: https://github.com/AlexWheeler [@andrerfcsantos]: https://github.com/andrerfcsantos diff --git a/cmd/version.go b/cmd/version.go index 260afbb79..300ba8f72 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -9,7 +9,7 @@ import ( // Version is the version of the current build. // It follows semantic versioning. -const Version = "3.4.0" +const Version = "3.4.1" // checkLatest flag for version command. var checkLatest bool From b43bd3724601780363c5069f14cec286c47a2c62 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Thu, 15 Aug 2024 15:42:10 +0200 Subject: [PATCH 084/142] Add version to goreleaser file (#1155) --- .goreleaser.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.goreleaser.yml b/.goreleaser.yml index b7491e0b8..1995cf6b4 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -1,4 +1,5 @@ # You can find the GoReleaser documentation at http://goreleaser.com +version: 2 project_name: exercism env: From 20d58b1faedf346f3a0135ccd44fd8c8121415ee Mon Sep 17 00:00:00 2001 From: Yukai Chou Date: Tue, 20 Aug 2024 19:03:44 +0800 Subject: [PATCH 085/142] Add `test` command to Shell completions (#1156) `test` command was supported since v3.2.0, see a8ffc31 (Add `test` command to run any unit test (\#1092), 2023-07-28) --- shell/exercism.fish | 6 +++++- shell/exercism_completion.bash | 2 +- shell/exercism_completion.zsh | 1 + 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/shell/exercism.fish b/shell/exercism.fish index dc20fdce0..28702a48f 100644 --- a/shell/exercism.fish +++ b/shell/exercism.fish @@ -15,7 +15,7 @@ complete -f -c exercism -n "__fish_seen_subcommand_from download" -s u -l uuid - # Help complete -f -c exercism -n "__fish_use_subcommand" -a "help" -d "Shows a list of commands or help for one command" -complete -f -c exercism -n "__fish_seen_subcommand_from help" -a "configure download help open submit troubleshoot upgrade version workspace" +complete -f -c exercism -n "__fish_seen_subcommand_from help" -a "configure download help open submit test troubleshoot upgrade version workspace" # Open complete -f -c exercism -n "__fish_use_subcommand" -a "open" -d "Opens a browser to exercism.io for the specified submission." @@ -25,6 +25,10 @@ complete -f -c exercism -n "__fish_seen_subcommand_from open" -s h -l help -d "h complete -f -c exercism -n "__fish_use_subcommand" -a "submit" -d "Submits a new iteration to a problem on exercism.io." complete -f -c exercism -n "__fish_seen_subcommand_from submit" -s h -l help -d "help for submit" +# Test +complete -f -c exercism -n "__fish_use_subcommand" -a "test" -d "Run the exercise's tests." +complete -f -c exercism -n "__fish_seen_subcommand_from submit" -s h -l help -d "help for test" + # Troubleshoot complete -f -c exercism -n "__fish_use_subcommand" -a "troubleshoot" -d "Outputs useful debug information." complete -f -c exercism -n "__fish_seen_subcommand_from troubleshoot" -s f -l full-api-key -d "display full API key (censored by default)" diff --git a/shell/exercism_completion.bash b/shell/exercism_completion.bash index f5f4e9010..6864ec153 100644 --- a/shell/exercism_completion.bash +++ b/shell/exercism_completion.bash @@ -7,7 +7,7 @@ _exercism () { opts="--verbose --timeout" commands="configure download open - submit troubleshoot upgrade version workspace help" + submit test troubleshoot upgrade version workspace help" config_opts="--show" version_opts="--latest" diff --git a/shell/exercism_completion.zsh b/shell/exercism_completion.zsh index 424b24e67..5d476ac66 100644 --- a/shell/exercism_completion.zsh +++ b/shell/exercism_completion.zsh @@ -8,6 +8,7 @@ options=(configure:"Writes config values to a JSON file." download:"Downloads and saves a specified submission into the local system" open:"Opens a browser to exercism.io for the specified submission." submit:"Submits a new iteration to a problem on exercism.io." + test:"Run the exercise's tests." troubleshoot:"Outputs useful debug information." upgrade:"Upgrades to the latest available version." version:"Outputs version information." From 9c0b6c5f3d8d5dd6fd242d5ec07a1a86c39dc405 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Tue, 20 Aug 2024 13:08:20 +0200 Subject: [PATCH 086/142] Bump version to v3.4.2 (#1158) --- CHANGELOG.md | 5 +++++ cmd/version.go | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6398a756a..959baeab4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,11 @@ The exercism CLI follows [semantic versioning](http://semver.org/). - **Your contribution here** +## v3.4.2 (2024-08-20) + +- [#1156](https://github.com/exercism/cli/pull/1156) Add `test` command to Shell completions - + [@muzimuzhi] + ## v3.4.1 (2024-08-15) - [#1152](https://github.com/exercism/cli/pull/1152) Add support for Idris to `exercism test` - diff --git a/cmd/version.go b/cmd/version.go index 300ba8f72..147c8e0b9 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -9,7 +9,7 @@ import ( // Version is the version of the current build. // It follows semantic versioning. -const Version = "3.4.1" +const Version = "3.4.2" // checkLatest flag for version command. var checkLatest bool From e3f9fecbdc9180504d40cc6ea5e5446d207eedc3 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Tue, 20 Aug 2024 13:32:23 +0200 Subject: [PATCH 087/142] Fix env variable typo in release doc (#1160) --- RELEASE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RELEASE.md b/RELEASE.md index 35a02dbf1..d5ba8ad4a 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -24,7 +24,7 @@ _Note: It's useful to add the version to the commit message when you bump it: e. Once the version bump PR has been merged, run the following command to cut a release: ```shell -GPG_FINGERPINT="" ./bin/release.sh +GPG_FINGERPRINT="" ./bin/release.sh ``` ## Cut Release on GitHub From f47c9b412d66e9432d15676bc540af098684c49a Mon Sep 17 00:00:00 2001 From: Murat Kirazkaya <77299279+GroophyLifefor@users.noreply.github.com> Date: Wed, 21 Aug 2024 09:16:07 +0300 Subject: [PATCH 088/142] Updated test_configurations.go for new batch track (#1157) * Update test_configurations.go * Update test_configurations.go --------- Co-authored-by: Erik Schierboom --- workspace/test_configurations.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/workspace/test_configurations.go b/workspace/test_configurations.go index f5bb29019..f0cbd174b 100644 --- a/workspace/test_configurations.go +++ b/workspace/test_configurations.go @@ -74,6 +74,9 @@ var TestConfigurations = map[string]TestConfiguration{ "ballerina": { Command: "bal test", }, + "batch": { + WindowsCommand: "call {{test_files}}", + }, "bash": { Command: "bats {{test_files}}", }, From 8951e55dddf1e3482ec8ff1cc6e00862c6e8b27b Mon Sep 17 00:00:00 2001 From: Yukai Chou Date: Wed, 21 Aug 2024 18:24:14 +0800 Subject: [PATCH 089/142] Fix dup alias "t", keep it for "test" only (#1159) Command alias "t" was registered by both "troubleshoot" and "test" commands. This PR drops it from "troubleshoot" aliases. Co-authored-by: Erik Schierboom --- cmd/troubleshoot.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/troubleshoot.go b/cmd/troubleshoot.go index 4ea5b1444..2c599d6d5 100644 --- a/cmd/troubleshoot.go +++ b/cmd/troubleshoot.go @@ -21,7 +21,7 @@ var fullAPIKey bool // troubleshootCmd does a diagnostic self-check. var troubleshootCmd = &cobra.Command{ Use: "troubleshoot", - Aliases: []string{"t", "debug"}, + Aliases: []string{"debug"}, Short: "Troubleshoot does a diagnostic self-check.", Long: `Provides output to help with troubleshooting. From bdbcc49fac3496ef92d1ac24d715a6d3ec76384e Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Thu, 22 Aug 2024 15:56:35 +0200 Subject: [PATCH 090/142] Bump to version 3.5.0 (#1161) --- CHANGELOG.md | 15 +++++++++++++++ cmd/version.go | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 959baeab4..03cd7ed6b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,12 @@ The exercism CLI follows [semantic versioning](http://semver.org/). - **Your contribution here** +## v3.5.0 (2024-08-22) + +- [#1157](https://github.com/exercism/cli/pull/1157) Add support for Batch to `exercism test` - [@GroophyLifefor] +- [#1159](https://github.com/exercism/cli/pull/1159) Fix duplicated `t` alias - + [@muzimuzhi] + ## v3.4.2 (2024-08-20) - [#1156](https://github.com/exercism/cli/pull/1156) Add `test` command to Shell completions - @@ -543,3 +549,12 @@ All changes by [@msgehard] [@xavdid]: https://github.com/xavdid [@williandrade]: https://github.com/williandrade [@zabawaba99]: https://github.com/zabawaba99 +[@GroophyLifefor]: https://github.com/GroophyLifefor +[@muzimuzhi]: https://github.com/muzimuzhi +[@isberg]: https://github.com/isberg +[@erikschierboom]: https://github.com/erikschierboom +[@sanderploegsma]: https://github.com/sanderploegsma +[@enascimento178]: https://github.com/enascimento178 +[@halfdan]: https://github.com/halfdan +[@glennj]: https://github.com/glennj +[@tomasnorre]: https://github.com/tomasnorre diff --git a/cmd/version.go b/cmd/version.go index 147c8e0b9..cc6644b4c 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -9,7 +9,7 @@ import ( // Version is the version of the current build. // It follows semantic versioning. -const Version = "3.4.2" +const Version = "3.5.0" // checkLatest flag for version command. var checkLatest bool From 28d1c6d1b6ce675581662d9faf6434a7e9f1d801 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Geron?= Date: Wed, 28 Aug 2024 21:40:03 +1200 Subject: [PATCH 091/142] Add support for the Roc language (#1162) --- workspace/test_configurations.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/workspace/test_configurations.go b/workspace/test_configurations.go index f0cbd174b..9fd549e26 100644 --- a/workspace/test_configurations.go +++ b/workspace/test_configurations.go @@ -225,6 +225,9 @@ var TestConfigurations = map[string]TestConfiguration{ "red": { Command: "red {{test_files}}", }, + "roc": { + Command: "roc test {{test_files}}", + }, "ruby": { Command: "ruby {{test_files}}", }, From fe08d1879e820d4133ea87e9e8b2a913fb53727d Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Wed, 28 Aug 2024 11:45:25 +0200 Subject: [PATCH 092/142] Bump version to v3.5.1 (#1163) --- CHANGELOG.md | 5 +++++ cmd/version.go | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 03cd7ed6b..83f6c0443 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ The exercism CLI follows [semantic versioning](http://semver.org/). - **Your contribution here** +## v3.5.1 (2024-08-28) + +- [#1162](https://github.com/exercism/cli/pull/1162) Add support for Roc to `exercism test` - [@ageron] + ## v3.5.0 (2024-08-22) - [#1157](https://github.com/exercism/cli/pull/1157) Add support for Batch to `exercism test` - [@GroophyLifefor] @@ -558,3 +562,4 @@ All changes by [@msgehard] [@halfdan]: https://github.com/halfdan [@glennj]: https://github.com/glennj [@tomasnorre]: https://github.com/tomasnorre +[@ageron]: https://github.com/ageron diff --git a/cmd/version.go b/cmd/version.go index cc6644b4c..9d2e226bb 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -9,7 +9,7 @@ import ( // Version is the version of the current build. // It follows semantic versioning. -const Version = "3.5.0" +const Version = "3.5.1" // checkLatest flag for version command. var checkLatest bool From 7428fd467247169deada18979eb5ee0a4c69318f Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Wed, 28 Aug 2024 12:27:15 +0200 Subject: [PATCH 093/142] Add release workflow to release document (#1164) --- RELEASE.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/RELEASE.md b/RELEASE.md index d5ba8ad4a..8feda68f0 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -29,8 +29,9 @@ GPG_FINGERPRINT="" ./bin/release.sh ## Cut Release on GitHub -At this point, Goreleaser will have created a draft release at https://github.com/exercism/cli/releases/tag/vX.Y.Z. -On that page, update the release description to: +Once the `./bin/release.sh` command finishes, the [release workflow](https://github.com/exercism/cli/actions/workflows/release.yml) will automatically run. +This workflow will create a draft release at https://github.com/exercism/cli/releases/tag/vX.Y.Z. +Once created, go that page to update the release description to: ``` To install, follow the interactive installation instructions at https://exercism.io/cli-walkthrough From 102aeb8f07d691b352412c8a80f7626656ae2f7e Mon Sep 17 00:00:00 2001 From: 521337 <57076905+521337@users.noreply.github.com> Date: Sun, 15 Sep 2024 00:55:50 +0000 Subject: [PATCH 094/142] Fix URL in no token error message (#1166) Update Exercism API endpoint URL. --- cmd/download_test.go | 2 +- cmd/submit_test.go | 2 +- config/config.go | 6 +++--- config/config_test.go | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/cmd/download_test.go b/cmd/download_test.go index d95729719..a3e565831 100644 --- a/cmd/download_test.go +++ b/cmd/download_test.go @@ -26,7 +26,7 @@ func TestDownloadWithoutToken(t *testing.T) { if assert.Error(t, err) { assert.Regexp(t, "Welcome to Exercism", err.Error()) // It uses the default base API url to infer the host - assert.Regexp(t, "exercism.io/my/settings", err.Error()) + assert.Regexp(t, "exercism.org/settings/api_cli", err.Error()) } } diff --git a/cmd/submit_test.go b/cmd/submit_test.go index 2a12d0bca..c974794c8 100644 --- a/cmd/submit_test.go +++ b/cmd/submit_test.go @@ -28,7 +28,7 @@ func TestSubmitWithoutToken(t *testing.T) { err := runSubmit(cfg, pflag.NewFlagSet("fake", pflag.PanicOnError), []string{}) if assert.Error(t, err) { assert.Regexp(t, "Welcome to Exercism", err.Error()) - assert.Regexp(t, "exercism.io/my/settings", err.Error()) + assert.Regexp(t, "exercism.org/settings/api_cli", err.Error()) } } diff --git a/config/config.go b/config/config.go index b9b1883ba..e70595054 100644 --- a/config/config.go +++ b/config/config.go @@ -12,7 +12,7 @@ import ( ) var ( - defaultBaseURL = "https://api.exercism.io/v1" + defaultBaseURL = "https://exercism.org" // DefaultDirName is the default name used for config and workspace directories. DefaultDirName string @@ -122,7 +122,7 @@ func InferSiteURL(apiURL string) string { apiURL = defaultBaseURL } if apiURL == "https://api.exercism.io/v1" { - return "https://exercism.io" + return "https://exercism.org" } re := regexp.MustCompile("^(https?://[^/]*).*") return re.ReplaceAllString(apiURL, "$1") @@ -130,5 +130,5 @@ func InferSiteURL(apiURL string) string { // SettingsURL provides a link to where the user can find their API token. func SettingsURL(apiURL string) string { - return fmt.Sprintf("%s%s", InferSiteURL(apiURL), "/my/settings") + return fmt.Sprintf("%s%s", InferSiteURL(apiURL), "/settings/api_cli") } diff --git a/config/config_test.go b/config/config_test.go index e9d29f97f..2df6ce1fd 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -10,11 +10,11 @@ func TestInferSiteURL(t *testing.T) { testCases := []struct { api, url string }{ - {"https://api.exercism.io/v1", "https://exercism.io"}, + {"https://api.exercism.io/v1", "https://exercism.org"}, {"https://v2.exercism.io/api/v1", "https://v2.exercism.io"}, {"https://mentors-beta.exercism.io/api/v1", "https://mentors-beta.exercism.io"}, {"http://localhost:3000/api/v1", "http://localhost:3000"}, - {"", "https://exercism.io"}, // use the default + {"", "https://exercism.org"}, // use the default {"http://whatever", "http://whatever"}, // you're on your own, pal } From c3738a8dd583c7257f459af288837b3139599613 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Tue, 17 Sep 2024 08:41:04 +0200 Subject: [PATCH 095/142] Change the interval for dependabot updates to monthly (#1167) --- .github/dependabot.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index eb2ead799..5c6cb5943 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -5,6 +5,6 @@ updates: - package-ecosystem: 'github-actions' directory: '/' schedule: - interval: 'daily' + interval: 'monthly' labels: - 'x:size/small' From 62d9851793d31968909af9ecf839973acde2007e Mon Sep 17 00:00:00 2001 From: Isaac Good Date: Wed, 18 Sep 2024 11:03:28 -0700 Subject: [PATCH 096/142] Revert "Fix URL in no token error message (#1166)" (#1173) This reverts commit 102aeb8f07d691b352412c8a80f7626656ae2f7e. --- cmd/download_test.go | 2 +- cmd/submit_test.go | 2 +- config/config.go | 6 +++--- config/config_test.go | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/cmd/download_test.go b/cmd/download_test.go index a3e565831..d95729719 100644 --- a/cmd/download_test.go +++ b/cmd/download_test.go @@ -26,7 +26,7 @@ func TestDownloadWithoutToken(t *testing.T) { if assert.Error(t, err) { assert.Regexp(t, "Welcome to Exercism", err.Error()) // It uses the default base API url to infer the host - assert.Regexp(t, "exercism.org/settings/api_cli", err.Error()) + assert.Regexp(t, "exercism.io/my/settings", err.Error()) } } diff --git a/cmd/submit_test.go b/cmd/submit_test.go index c974794c8..2a12d0bca 100644 --- a/cmd/submit_test.go +++ b/cmd/submit_test.go @@ -28,7 +28,7 @@ func TestSubmitWithoutToken(t *testing.T) { err := runSubmit(cfg, pflag.NewFlagSet("fake", pflag.PanicOnError), []string{}) if assert.Error(t, err) { assert.Regexp(t, "Welcome to Exercism", err.Error()) - assert.Regexp(t, "exercism.org/settings/api_cli", err.Error()) + assert.Regexp(t, "exercism.io/my/settings", err.Error()) } } diff --git a/config/config.go b/config/config.go index e70595054..b9b1883ba 100644 --- a/config/config.go +++ b/config/config.go @@ -12,7 +12,7 @@ import ( ) var ( - defaultBaseURL = "https://exercism.org" + defaultBaseURL = "https://api.exercism.io/v1" // DefaultDirName is the default name used for config and workspace directories. DefaultDirName string @@ -122,7 +122,7 @@ func InferSiteURL(apiURL string) string { apiURL = defaultBaseURL } if apiURL == "https://api.exercism.io/v1" { - return "https://exercism.org" + return "https://exercism.io" } re := regexp.MustCompile("^(https?://[^/]*).*") return re.ReplaceAllString(apiURL, "$1") @@ -130,5 +130,5 @@ func InferSiteURL(apiURL string) string { // SettingsURL provides a link to where the user can find their API token. func SettingsURL(apiURL string) string { - return fmt.Sprintf("%s%s", InferSiteURL(apiURL), "/settings/api_cli") + return fmt.Sprintf("%s%s", InferSiteURL(apiURL), "/my/settings") } diff --git a/config/config_test.go b/config/config_test.go index 2df6ce1fd..e9d29f97f 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -10,11 +10,11 @@ func TestInferSiteURL(t *testing.T) { testCases := []struct { api, url string }{ - {"https://api.exercism.io/v1", "https://exercism.org"}, + {"https://api.exercism.io/v1", "https://exercism.io"}, {"https://v2.exercism.io/api/v1", "https://v2.exercism.io"}, {"https://mentors-beta.exercism.io/api/v1", "https://mentors-beta.exercism.io"}, {"http://localhost:3000/api/v1", "http://localhost:3000"}, - {"", "https://exercism.org"}, // use the default + {"", "https://exercism.io"}, // use the default {"http://whatever", "http://whatever"}, // you're on your own, pal } From a581e6a2c7285e57209205d341b9978369777be8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Sep 2024 19:36:11 -0700 Subject: [PATCH 097/142] Bump actions/setup-go from 4.1.0 to 5.0.2 (#1168) Bumps [actions/setup-go](https://github.com/actions/setup-go) from 4.1.0 to 5.0.2. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](https://github.com/actions/setup-go/compare/93397bea11091df50f3d7e59dc26a7711a8bcfbe...0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32) --- updated-dependencies: - dependency-name: actions/setup-go dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- .github/workflows/release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b4510d825..fbf2b030d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,7 +25,7 @@ jobs: steps: - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 - - uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe + - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 with: go-version: ${{ matrix.go-version }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b74d61e58..e946c5100 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -20,7 +20,7 @@ jobs: fetch-depth: 0 - name: Set up Go - uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0 + uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 with: go-version: '1.20.x' From 50e8b0eab2f0f9ea032d2c643bab884e50643330 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Sep 2024 19:40:02 -0700 Subject: [PATCH 098/142] Bump goreleaser/goreleaser-action from 5.0.0 to 6.0.0 (#1169) Bumps [goreleaser/goreleaser-action](https://github.com/goreleaser/goreleaser-action) from 5.0.0 to 6.0.0. - [Release notes](https://github.com/goreleaser/goreleaser-action/releases) - [Commits](https://github.com/goreleaser/goreleaser-action/compare/7ec5c2b0c6cdda6e8bbb49444bc797dd33d74dd8...286f3b13b1b49da4ac219696163fb8c1c93e1200) --- updated-dependencies: - dependency-name: goreleaser/goreleaser-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e946c5100..b5bd2b21c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -32,7 +32,7 @@ jobs: passphrase: ${{ secrets.PASSPHRASE }} - name: Cut Release - uses: goreleaser/goreleaser-action@7ec5c2b0c6cdda6e8bbb49444bc797dd33d74dd8 # v5.0.0 + uses: goreleaser/goreleaser-action@286f3b13b1b49da4ac219696163fb8c1c93e1200 # v6.0.0 with: version: latest args: release --clean --release-header .release/header.md --timeout 120m # default time is 30m From 6779bed32e700182f7efb68bac575366053f1a5a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Sep 2024 19:42:53 -0700 Subject: [PATCH 099/142] Bump actions/checkout from 4.1.0 to 4.1.7 (#1171) Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.0 to 4.1.7. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/8ade135a41bc03ea155e62e844d188df1ea18608...692973e3d937129bcbf40652eb9f2f61becf3332) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 4 ++-- .github/workflows/release.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fbf2b030d..05aa6a748 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: os: [ubuntu-latest, windows-latest, macOS-latest] steps: - - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 with: @@ -39,7 +39,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 - name: Check formatting run: ./.gha.gofmt.sh diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b5bd2b21c..a8d026f7a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,7 +15,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 with: fetch-depth: 0 From 3daad45b111a17ab7f20b4e6ea88795e5a2d96c2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Sep 2024 19:50:12 -0700 Subject: [PATCH 100/142] Bump crazy-max/ghaction-import-gpg from 6.0.0 to 6.1.0 (#1170) Bumps [crazy-max/ghaction-import-gpg](https://github.com/crazy-max/ghaction-import-gpg) from 6.0.0 to 6.1.0. - [Release notes](https://github.com/crazy-max/ghaction-import-gpg/releases) - [Commits](https://github.com/crazy-max/ghaction-import-gpg/compare/82a020f1f7f605c65dd2449b392a52c3fcfef7ef...01dd5d3ca463c7f10f7f4f7b4f177225ac661ee4) --- updated-dependencies: - dependency-name: crazy-max/ghaction-import-gpg dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a8d026f7a..599f23bdb 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -26,7 +26,7 @@ jobs: - name: Import GPG Key id: import_gpg - uses: crazy-max/ghaction-import-gpg@82a020f1f7f605c65dd2449b392a52c3fcfef7ef # v6.0.0 + uses: crazy-max/ghaction-import-gpg@01dd5d3ca463c7f10f7f4f7b4f177225ac661ee4 # v6.1.0 with: gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} passphrase: ${{ secrets.PASSPHRASE }} From 0706bdbd7f2a5a1df57e2e5419e3647a6366077b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20B=20Nagy?= <20251272+BNAndras@users.noreply.github.com> Date: Fri, 20 Sep 2024 00:33:55 -0700 Subject: [PATCH 101/142] Fix batch command (#1172) Co-authored-by: Isaac Good Co-authored-by: Erik Schierboom --- workspace/test_configurations.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workspace/test_configurations.go b/workspace/test_configurations.go index 9fd549e26..6c5caff62 100644 --- a/workspace/test_configurations.go +++ b/workspace/test_configurations.go @@ -75,7 +75,7 @@ var TestConfigurations = map[string]TestConfiguration{ Command: "bal test", }, "batch": { - WindowsCommand: "call {{test_files}}", + WindowsCommand: "cmd /c {{test_files}}", }, "bash": { Command: "bats {{test_files}}", From d3b5d7f6ed706ebf0c2d11327c81aad9b25cbe80 Mon Sep 17 00:00:00 2001 From: PetreM Date: Wed, 9 Oct 2024 13:35:38 +0300 Subject: [PATCH 102/142] Fix BinaryName initialization from args (#1174) Fixes an issue with `completion bash` where the command name is not present in the completion output. --- cmd/root.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/cmd/root.go b/cmd/root.go index 35d266356..d94d5c847 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -14,7 +14,7 @@ import ( // RootCmd represents the base command when called without any subcommands. var RootCmd = &cobra.Command{ - Use: BinaryName, + Use: getCommandName(), Short: "A friendly command-line interface to Exercism.", Long: `A command-line interface for Exercism. @@ -41,8 +41,12 @@ func Execute() { } } +func getCommandName() string { + return os.Args[0] +} + func init() { - BinaryName = os.Args[0] + BinaryName = getCommandName() config.SetDefaultDirName(BinaryName) Out = os.Stdout Err = os.Stderr From 24276b7dba306ade75404b998017911ac7600569 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Wed, 9 Oct 2024 12:41:18 +0200 Subject: [PATCH 103/142] Bump version to v.3.5.2 (#1176) --- CHANGELOG.md | 7 +++++++ cmd/version.go | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 83f6c0443..5d98f969a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,11 @@ The exercism CLI follows [semantic versioning](http://semver.org/). - **Your contribution here** +## v3.5.2 (2024-10-09) + +- [#1174](https://github.com/exercism/cli/pull/1174) Fix an issue with `exercism completion bash` where the command name is not present in the completion output. - [@petrem] +- [#1172](https://github.com/exercism/cli/pull/1172) Fix `exercism test` command for Batch track - [@bnandras] + ## v3.5.1 (2024-08-28) - [#1162](https://github.com/exercism/cli/pull/1162) Add support for Roc to `exercism test` - [@ageron] @@ -563,3 +568,5 @@ All changes by [@msgehard] [@glennj]: https://github.com/glennj [@tomasnorre]: https://github.com/tomasnorre [@ageron]: https://github.com/ageron +[@petrem]: https://github.com/petrem +[@bnandras]: https://github.com/bnandras diff --git a/cmd/version.go b/cmd/version.go index 9d2e226bb..73a20bf04 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -9,7 +9,7 @@ import ( // Version is the version of the current build. // It follows semantic versioning. -const Version = "3.5.1" +const Version = "3.5.2" // checkLatest flag for version command. var checkLatest bool From 0a329255e8ce989b3168525d04384926215b8b1b Mon Sep 17 00:00:00 2001 From: keiravillekode Date: Sat, 26 Oct 2024 11:07:24 +1100 Subject: [PATCH 104/142] Add arm64-assembly test configuration (#1178) --- workspace/test_configurations.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/workspace/test_configurations.go b/workspace/test_configurations.go index 6c5caff62..a1fe1cccb 100644 --- a/workspace/test_configurations.go +++ b/workspace/test_configurations.go @@ -65,6 +65,9 @@ var TestConfigurations = map[string]TestConfiguration{ Command: "8th -f test.8th", }, // abap: tests are run via "ABAP Development Tools", not the CLI + "arm64-assembly": { + Command: "make", + }, "arturo": { Command: "arturo tester.art", }, From efd43c4e794a1bb7f658ecf0f73ed29bb861ac6d Mon Sep 17 00:00:00 2001 From: Patrick Kodal <6306551+ladokp@users.noreply.github.com> Date: Sun, 3 Nov 2024 16:17:07 +0100 Subject: [PATCH 105/142] refactored exercism.io to exercism.org (#1177) * refactored exercism.io to exercism.org * refactored exercism.io github references --- .release/header.md | 2 +- CHANGELOG.md | 8 ++++---- README.md | 2 +- RELEASE.md | 4 ++-- cmd/download_test.go | 2 +- cmd/submit_test.go | 2 +- config/config.go | 6 +++--- config/config_test.go | 8 ++++---- exercism/doc.go | 2 +- shell/exercism.fish | 4 ++-- shell/exercism_completion.zsh | 4 ++-- 11 files changed, 22 insertions(+), 22 deletions(-) diff --git a/.release/header.md b/.release/header.md index 55027b78c..c648e2d8b 100644 --- a/.release/header.md +++ b/.release/header.md @@ -1,3 +1,3 @@ -To install, follow the interactive installation instructions at https://exercism.io/cli-walkthrough +To install, follow the interactive installation instructions at https://exercism.org/cli-walkthrough --- diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d98f969a..b12f04f2c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -153,7 +153,7 @@ The exercism CLI follows [semantic versioning](http://semver.org/). ## v3.0.0 (2018-07-13) -This is a complete rewrite from the ground up to work against the new https://exercism.io site. +This is a complete rewrite from the ground up to work against the new https://exercism.org site. ## v2.4.1 (2017-07-01) @@ -299,7 +299,7 @@ Tweaked: ## v1.9.2 (2015-01-11) -- [exercism.io#2155](https://github.com/exercism/exercism.io/issues/2155): Fixed problem with passed in config file being ignored. +- [exercism#2155](https://github.com/exercism/exercism/issues/2155): Fixed problem with passed in config file being ignored. - Added first version of changelog ## v1.9.1 (2015-01-10) @@ -419,7 +419,7 @@ Tweaked: ## v1.3.1 (2013-12-01) -- [exercism.io#1039](https://github.com/exercism/exercism.io/issues/1039): Stopped clobbering existing files on fetch +- [exercism#1039](https://github.com/exercism/exercism/issues/1039): Stopped clobbering existing files on fetch ## v1.3.0 (2013-11-16) @@ -427,7 +427,7 @@ Tweaked: ## v1.2.3 (2013-11-13) -- [exercism.io#998](https://github.com/exercism/exercism.io/issues/998): Fix problem with writing an empty config file under certain circumstances. +- [exercism#998](https://github.com/exercism/exercism/issues/998): Fix problem with writing an empty config file under certain circumstances. ## v1.2.2 (2013-11-12) diff --git a/README.md b/README.md index c92650a85..8b0fa92c6 100644 --- a/README.md +++ b/README.md @@ -15,5 +15,5 @@ Instructions can be found at [exercism/cli/releases](https://github.com/exercism If you wish to help improve the CLI, please see the [Contributing guide][contributing]. -[exercism]: http://exercism.io +[exercism]: http://exercism.org [contributing]: /CONTRIBUTING.md diff --git a/RELEASE.md b/RELEASE.md index 8feda68f0..289c78822 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -34,7 +34,7 @@ This workflow will create a draft release at https://github.com/exercism/cli/rel Once created, go that page to update the release description to: ``` -To install, follow the interactive installation instructions at https://exercism.io/cli-walkthrough +To install, follow the interactive installation instructions at https://exercism.org/cli-walkthrough --- [modify the generated release-notes to describe changes in this release] @@ -49,6 +49,6 @@ Homebrew will automatically bump the version, no manual action is required. ## Update the docs site If there are any significant changes, we should describe them on -[exercism.io/cli](https://exercism.io/cli). +[exercism.org/cli](https://exercism.org/cli). The codebase lives at [exercism/website-copy](https://github.com/exercism/website-copy) in `pages/cli.md`. diff --git a/cmd/download_test.go b/cmd/download_test.go index d95729719..aadcf84aa 100644 --- a/cmd/download_test.go +++ b/cmd/download_test.go @@ -26,7 +26,7 @@ func TestDownloadWithoutToken(t *testing.T) { if assert.Error(t, err) { assert.Regexp(t, "Welcome to Exercism", err.Error()) // It uses the default base API url to infer the host - assert.Regexp(t, "exercism.io/my/settings", err.Error()) + assert.Regexp(t, "exercism.org/my/settings", err.Error()) } } diff --git a/cmd/submit_test.go b/cmd/submit_test.go index 2a12d0bca..9b645965b 100644 --- a/cmd/submit_test.go +++ b/cmd/submit_test.go @@ -28,7 +28,7 @@ func TestSubmitWithoutToken(t *testing.T) { err := runSubmit(cfg, pflag.NewFlagSet("fake", pflag.PanicOnError), []string{}) if assert.Error(t, err) { assert.Regexp(t, "Welcome to Exercism", err.Error()) - assert.Regexp(t, "exercism.io/my/settings", err.Error()) + assert.Regexp(t, "exercism.org/my/settings", err.Error()) } } diff --git a/config/config.go b/config/config.go index b9b1883ba..e1cc37e08 100644 --- a/config/config.go +++ b/config/config.go @@ -12,7 +12,7 @@ import ( ) var ( - defaultBaseURL = "https://api.exercism.io/v1" + defaultBaseURL = "https://api.exercism.org/v1" // DefaultDirName is the default name used for config and workspace directories. DefaultDirName string @@ -121,8 +121,8 @@ func InferSiteURL(apiURL string) string { if apiURL == "" { apiURL = defaultBaseURL } - if apiURL == "https://api.exercism.io/v1" { - return "https://exercism.io" + if apiURL == "https://api.exercism.org/v1" { + return "https://exercism.org" } re := regexp.MustCompile("^(https?://[^/]*).*") return re.ReplaceAllString(apiURL, "$1") diff --git a/config/config_test.go b/config/config_test.go index e9d29f97f..40ecb0c36 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -10,11 +10,11 @@ func TestInferSiteURL(t *testing.T) { testCases := []struct { api, url string }{ - {"https://api.exercism.io/v1", "https://exercism.io"}, - {"https://v2.exercism.io/api/v1", "https://v2.exercism.io"}, - {"https://mentors-beta.exercism.io/api/v1", "https://mentors-beta.exercism.io"}, + {"https://api.exercism.org/v1", "https://exercism.org"}, + {"https://v2.exercism.org/api/v1", "https://v2.exercism.org"}, + {"https://mentors-beta.exercism.org/api/v1", "https://mentors-beta.exercism.org"}, {"http://localhost:3000/api/v1", "http://localhost:3000"}, - {"", "https://exercism.io"}, // use the default + {"", "https://exercism.org"}, // use the default {"http://whatever", "http://whatever"}, // you're on your own, pal } diff --git a/exercism/doc.go b/exercism/doc.go index a60d6e7b2..3e00d9015 100644 --- a/exercism/doc.go +++ b/exercism/doc.go @@ -1,5 +1,5 @@ /* -Command exercism allows users to interact with the exercism.io platform. +Command exercism allows users to interact with the exercism.org platform. The primary actions are to fetch problems to be solved, and submit iterations of these problems. diff --git a/shell/exercism.fish b/shell/exercism.fish index 28702a48f..c2c7c0811 100644 --- a/shell/exercism.fish +++ b/shell/exercism.fish @@ -18,11 +18,11 @@ complete -f -c exercism -n "__fish_use_subcommand" -a "help" -d "Shows a list of complete -f -c exercism -n "__fish_seen_subcommand_from help" -a "configure download help open submit test troubleshoot upgrade version workspace" # Open -complete -f -c exercism -n "__fish_use_subcommand" -a "open" -d "Opens a browser to exercism.io for the specified submission." +complete -f -c exercism -n "__fish_use_subcommand" -a "open" -d "Opens a browser to exercism.org for the specified submission." complete -f -c exercism -n "__fish_seen_subcommand_from open" -s h -l help -d "help for open" # Submit -complete -f -c exercism -n "__fish_use_subcommand" -a "submit" -d "Submits a new iteration to a problem on exercism.io." +complete -f -c exercism -n "__fish_use_subcommand" -a "submit" -d "Submits a new iteration to a problem on exercism.org." complete -f -c exercism -n "__fish_seen_subcommand_from submit" -s h -l help -d "help for submit" # Test diff --git a/shell/exercism_completion.zsh b/shell/exercism_completion.zsh index 5d476ac66..542c8a576 100644 --- a/shell/exercism_completion.zsh +++ b/shell/exercism_completion.zsh @@ -6,8 +6,8 @@ typeset -A opt_args local -a options options=(configure:"Writes config values to a JSON file." download:"Downloads and saves a specified submission into the local system" - open:"Opens a browser to exercism.io for the specified submission." - submit:"Submits a new iteration to a problem on exercism.io." + open:"Opens a browser to exercism.org for the specified submission." + submit:"Submits a new iteration to a problem on exercism.org." test:"Run the exercise's tests." troubleshoot:"Outputs useful debug information." upgrade:"Upgrades to the latest available version." From 26c5d34b1e301e7ef289d6f06d5dcde6c049313a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ingy=20d=C3=B6t=20Net?= Date: Sun, 3 Nov 2024 08:35:53 -0800 Subject: [PATCH 106/142] Add support for the YAMLScript language (#1165) Co-authored-by: Glenn Jackman --- workspace/test_configurations.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/workspace/test_configurations.go b/workspace/test_configurations.go index a1fe1cccb..90a7a1670 100644 --- a/workspace/test_configurations.go +++ b/workspace/test_configurations.go @@ -270,6 +270,9 @@ var TestConfigurations = map[string]TestConfiguration{ "x86-64-assembly": { Command: "make", }, + "yamlscript": { + Command: "make test", + }, "zig": { Command: "zig test {{test_files}}", }, From 3f1db64571a3348441204d2997589a8274a585b9 Mon Sep 17 00:00:00 2001 From: Glenn Jackman Date: Mon, 4 Nov 2024 12:30:25 -0500 Subject: [PATCH 107/142] Bump version to v.3.5.3 (#1182) * Bump version to v.3.5.3 * add yamlscript pr --- CHANGELOG.md | 6 ++++++ cmd/version.go | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b12f04f2c..d88ba59e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,12 @@ The exercism CLI follows [semantic versioning](http://semver.org/). - **Your contribution here** +## v3.5.3 (2024-11-03) + +- [#1178](https://github.com/exercism/cli/pull/1178) Add arm64-assembly test configuration [@keiravillekode] +- [#1177](https://github.com/exercism/cli/pull/1177) refactored exercism.io links to exercism.org [@ladokp] +- [#1165](https://github.com/exercism/cli/pull/1165) Add support for the YAMLScript language [@ingydotnet] + ## v3.5.2 (2024-10-09) - [#1174](https://github.com/exercism/cli/pull/1174) Fix an issue with `exercism completion bash` where the command name is not present in the completion output. - [@petrem] diff --git a/cmd/version.go b/cmd/version.go index 73a20bf04..bac407e01 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -9,7 +9,7 @@ import ( // Version is the version of the current build. // It follows semantic versioning. -const Version = "3.5.2" +const Version = "3.5.3" // checkLatest flag for version command. var checkLatest bool From 24504cc373bb19d75ba7bdcd672dce43e34ceb27 Mon Sep 17 00:00:00 2001 From: Christian Willner <34183939+vaeng@users.noreply.github.com> Date: Fri, 15 Nov 2024 09:23:28 +0100 Subject: [PATCH 108/142] feat: add uiua test command (#1183) --- workspace/test_configurations.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/workspace/test_configurations.go b/workspace/test_configurations.go index 90a7a1670..497100818 100644 --- a/workspace/test_configurations.go +++ b/workspace/test_configurations.go @@ -253,6 +253,9 @@ var TestConfigurations = map[string]TestConfiguration{ "typescript": { Command: "yarn test", }, + "uiua": { + Command: "uiua test {{test_files}}", + }, // unison: tests are run from an active UCM session "vbnet": { Command: "dotnet test", From 7580d02cbb5b0904d0e72e9e9782e61c734265a3 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Fri, 15 Nov 2024 09:27:28 +0100 Subject: [PATCH 109/142] Bump version to 3.5.4 (#1184) --- CHANGELOG.md | 9 +++++++-- cmd/version.go | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d88ba59e2..3ec666ab6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,11 +8,15 @@ The exercism CLI follows [semantic versioning](http://semver.org/). - **Your contribution here** +## v3.5.4 (2024-11-15) + +- [#1183](https://github.com/exercism/cli/pull/1183) Add support for Uiua track to `exercism test` - [@vaeng] + ## v3.5.3 (2024-11-03) - [#1178](https://github.com/exercism/cli/pull/1178) Add arm64-assembly test configuration [@keiravillekode] -- [#1177](https://github.com/exercism/cli/pull/1177) refactored exercism.io links to exercism.org [@ladokp] -- [#1165](https://github.com/exercism/cli/pull/1165) Add support for the YAMLScript language [@ingydotnet] +- [#1177](https://github.com/exercism/cli/pull/1177) refactored exercism.io links to exercism.org [@ladokp] +- [#1165](https://github.com/exercism/cli/pull/1165) Add support for the YAMLScript language [@ingydotnet] ## v3.5.2 (2024-10-09) @@ -576,3 +580,4 @@ All changes by [@msgehard] [@ageron]: https://github.com/ageron [@petrem]: https://github.com/petrem [@bnandras]: https://github.com/bnandras +[@vaeng]: https://github.com/vaeng diff --git a/cmd/version.go b/cmd/version.go index bac407e01..ed54b885c 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -9,7 +9,7 @@ import ( // Version is the version of the current build. // It follows semantic versioning. -const Version = "3.5.3" +const Version = "3.5.4" // checkLatest flag for version command. var checkLatest bool From 4a57aa74143ba686d1f6d972a0f57fd02277e6d0 Mon Sep 17 00:00:00 2001 From: keiravillekode Date: Tue, 27 May 2025 16:44:08 +1000 Subject: [PATCH 110/142] idris uses slug (#1192) * idris uses slug * Obtain exercise slug from metadata * TestIdrisUsesExerciseSlug --- workspace/test_configurations.go | 9 +++++- workspace/test_configurations_test.go | 40 +++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/workspace/test_configurations.go b/workspace/test_configurations.go index 497100818..d07a62f0e 100644 --- a/workspace/test_configurations.go +++ b/workspace/test_configurations.go @@ -55,6 +55,13 @@ func (c *TestConfiguration) GetTestCommand() (string, error) { } cmd = strings.ReplaceAll(cmd, "{{test_files}}", strings.Join(testFiles, " ")) } + if strings.Contains(cmd, "{{slug}}") { + metadata, err := NewExerciseMetadata(".") + if err != nil { + return "", err + } + cmd = strings.ReplaceAll(cmd, "{{slug}}", metadata.ExerciseSlug) + } return cmd, nil } @@ -152,7 +159,7 @@ var TestConfigurations = map[string]TestConfiguration{ Command: "stack test", }, "idris": { - Command: "pack test `basename *.ipkg .ipkg`", + Command: "pack test {{slug}}", }, "j": { Command: `jconsole -js "exit echo unittest {{test_files}} [ load {{solution_files}}"`, diff --git a/workspace/test_configurations_test.go b/workspace/test_configurations_test.go index 97ff40902..b8a8097ee 100644 --- a/workspace/test_configurations_test.go +++ b/workspace/test_configurations_test.go @@ -101,3 +101,43 @@ func TestRustHasTrailingDashes(t *testing.T) { assert.True(t, strings.HasSuffix(cmd, "--"), "rust's test command should have trailing dashes") } + +func TestIdrisUsesExerciseSlug(t *testing.T) { + currentDir, err := os.Getwd() + assert.NoError(t, err) + + tmpDir, err := os.MkdirTemp("", "solution") + assert.NoError(t, err) + defer os.RemoveAll(tmpDir) + + em := &ExerciseMetadata{ + Track: "idris", + ExerciseSlug: "bogus-exercise", + ID: "abc", + URL: "http://example.com", + Handle: "alice", + IsRequester: true, + Dir: tmpDir, + } + err = em.Write(tmpDir) + assert.NoError(t, err) + + defer os.Chdir(currentDir) + err = os.Chdir(tmpDir) + assert.NoError(t, err) + + exercismDir := filepath.Join(".", ".exercism") + f, err := os.Create(filepath.Join(exercismDir, "config.json")) + assert.NoError(t, err) + defer f.Close() + + _, err = f.WriteString(`{ "files": { "solution": [ "src/BogusExercise.idr" ], "test": [ "test/src/Main.idr" ] } }`) + assert.NoError(t, err) + + testConfig, ok := TestConfigurations["idris"] + assert.True(t, ok, "unexpectedly unable to find idris test config") + + cmd, err := testConfig.GetTestCommand() + assert.NoError(t, err) + assert.Equal(t, cmd, "pack test bogus-exercise") +} From 14f2349edc8cd1e2ad7393c14e17ceca06969ef9 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Fri, 30 May 2025 14:51:19 +0200 Subject: [PATCH 111/142] Bump version to 3.5.5 (#1194) --- CHANGELOG.md | 5 +++++ cmd/version.go | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ec666ab6..606588690 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ The exercism CLI follows [semantic versioning](http://semver.org/). - **Your contribution here** +## v3.5.5 (2025-05-30) + +- [#1192](https://github.com/exercism/cli/pull/1192) Change Idris test command to use slug - [@keiravillekode] + ## v3.5.4 (2024-11-15) - [#1183](https://github.com/exercism/cli/pull/1183) Add support for Uiua track to `exercism test` - [@vaeng] @@ -581,3 +585,4 @@ All changes by [@msgehard] [@petrem]: https://github.com/petrem [@bnandras]: https://github.com/bnandras [@vaeng]: https://github.com/vaeng +[@keiravillekode]: https://github.com/keiravillekode diff --git a/cmd/version.go b/cmd/version.go index ed54b885c..a0bb6abbe 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -9,7 +9,7 @@ import ( // Version is the version of the current build. // It follows semantic versioning. -const Version = "3.5.4" +const Version = "3.5.5" // checkLatest flag for version command. var checkLatest bool From 05260ea2e699f45f2728ecea703a4af84a8f2d9b Mon Sep 17 00:00:00 2001 From: Isaac Good Date: Fri, 13 Jun 2025 22:20:54 -0700 Subject: [PATCH 112/142] Check HTTP response content type before trying to decode it as JSON (#1196) --- cmd/cmd.go | 10 ++++++++ cmd/cmd_test.go | 54 ++++++++++++++++++++++++++++++++++++++++++++ cmd/download_test.go | 2 +- cmd/submit_test.go | 2 +- 4 files changed, 66 insertions(+), 2 deletions(-) diff --git a/cmd/cmd.go b/cmd/cmd.go index dcca08264..91597b5b1 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "net/http" + "regexp" "strings" "io" @@ -23,6 +24,8 @@ var ( Out io.Writer // Err is used to write errors. Err io.Writer + // jsonContentTypeRe is used to match Content-Type which contains JSON. + jsonContentTypeRe = regexp.MustCompile(`^application/([[:alpha:]]+\+)?json$`) ) const msgWelcomePleaseConfigure = ` @@ -77,6 +80,13 @@ func validateUserConfig(cfg *viper.Viper) error { // decodedAPIError decodes and returns the error message from the API response. // If the message is blank, it returns a fallback message with the status code. func decodedAPIError(resp *http.Response) error { + if contentType := resp.Header.Get("Content-Type"); !jsonContentTypeRe.MatchString(contentType) { + return fmt.Errorf( + "expected response with Content-Type \"application/json\" but got status %q with Content-Type %q", + resp.Status, + contentType, + ) + } var apiError struct { Error struct { Type string `json:"type"` diff --git a/cmd/cmd_test.go b/cmd/cmd_test.go index 782be18d2..101c52c87 100644 --- a/cmd/cmd_test.go +++ b/cmd/cmd_test.go @@ -2,7 +2,10 @@ package cmd import ( "io" + "io/ioutil" + "net/http" "os" + "strings" "testing" "github.com/spf13/cobra" @@ -119,3 +122,54 @@ func (co capturedOutput) reset() { Out = co.oldOut Err = co.oldErr } + +func errorResponse(contentType string, body string) *http.Response { + response := &http.Response{ + Status: "418 I'm a teapot", + StatusCode: 418, + Header: make(http.Header), + Body: ioutil.NopCloser(strings.NewReader(body)), + ContentLength: int64(len(body)), + } + response.Header.Set("Content-Type", contentType) + return response +} + +func TestDecodeErrorResponse(t *testing.T) { + testCases := []struct { + response *http.Response + wantMessage string + }{ + { + response: errorResponse("text/html", "Time for tea"), + wantMessage: `expected response with Content-Type "application/json" but got status "418 I'm a teapot" with Content-Type "text/html"`, + }, + { + response: errorResponse("application/json", `{"error": {"type": "json", "valid": no}}`), + wantMessage: "failed to parse API error response: invalid character 'o' in literal null (expecting 'u')", + }, + { + response: errorResponse("application/json", `{"error": {"type": "track_ambiguous", "message": "message", "possible_track_ids": ["a", "b"]}}`), + wantMessage: "message: a, b", + }, + { + response: errorResponse("application/json", `{"error": {"message": "message"}}`), + wantMessage: "message", + }, + { + response: errorResponse("application/problem+json", `{"error": {"message": "new json format"}}`), + wantMessage: "new json format", + }, + { + response: errorResponse("application/json", `{"error": {}}`), + wantMessage: "unexpected API response: 418", + }, + } + tc := testCases[0] + got := decodedAPIError(tc.response) + assert.Equal(t, tc.wantMessage, got.Error()) + for _, tc = range testCases { + got := decodedAPIError(tc.response) + assert.Equal(t, tc.wantMessage, got.Error()) + } +} diff --git a/cmd/download_test.go b/cmd/download_test.go index aadcf84aa..791be4230 100644 --- a/cmd/download_test.go +++ b/cmd/download_test.go @@ -403,7 +403,7 @@ func TestDownloadError(t *testing.T) { err = runDownload(cfg, flags, []string{}) - assert.Equal(t, "test error", err.Error()) + assert.Equal(t, `expected response with Content-Type "application/json" but got status "400 Bad Request" with Content-Type "text/plain; charset=utf-8"`, err.Error()) } diff --git a/cmd/submit_test.go b/cmd/submit_test.go index 9b645965b..7db152a75 100644 --- a/cmd/submit_test.go +++ b/cmd/submit_test.go @@ -657,7 +657,7 @@ func TestSubmitServerErr(t *testing.T) { err = runSubmit(cfg, pflag.NewFlagSet("fake", pflag.PanicOnError), files) - assert.Regexp(t, "test error", err.Error()) + assert.Regexp(t, `expected response with Content-Type "application/json" but got status "400 Bad Request" with Content-Type "text/plain; charset=utf-8"`, err.Error()) } func TestHandleErrorResponse(t *testing.T) { From 19a7972fecaecf3d9c24425ee27b3e611fc7f957 Mon Sep 17 00:00:00 2001 From: Isaac Good Date: Thu, 19 Jun 2025 10:18:14 -0700 Subject: [PATCH 113/142] cmd error parsing: show a "try again after" message when a response sets a Retry-After header (#1198) --- cmd/cmd.go | 17 +++++++++++++++++ cmd/cmd_test.go | 36 +++++++++++++++++++++++++++++------- 2 files changed, 46 insertions(+), 7 deletions(-) diff --git a/cmd/cmd.go b/cmd/cmd.go index 91597b5b1..61fe9c047 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -5,6 +5,7 @@ import ( "fmt" "net/http" "regexp" + "strconv" "strings" "io" @@ -80,6 +81,22 @@ func validateUserConfig(cfg *viper.Viper) error { // decodedAPIError decodes and returns the error message from the API response. // If the message is blank, it returns a fallback message with the status code. func decodedAPIError(resp *http.Response) error { + // First and foremost, handle Retry-After headers; if set, show this to the user. + if retryAfter := resp.Header.Get("Retry-After"); retryAfter != "" { + // The Retry-After header can be an HTTP Date or delay seconds. + // The date can be used as-is. The delay seconds should have "seconds" appended. + if delay, err := strconv.Atoi(retryAfter); err == nil { + retryAfter = fmt.Sprintf("%d seconds", delay) + } + return fmt.Errorf( + "request failed with status %s; please try again after %s", + resp.Status, + retryAfter, + ) + } + + // Check for JSON data. On non-JSON data, show the status and content type then bail. + // Otherwise, extract the message details from the JSON. if contentType := resp.Header.Get("Content-Type"); !jsonContentTypeRe.MatchString(contentType) { return fmt.Errorf( "expected response with Content-Type \"application/json\" but got status %q with Content-Type %q", diff --git a/cmd/cmd_test.go b/cmd/cmd_test.go index 101c52c87..a4d8b9fe2 100644 --- a/cmd/cmd_test.go +++ b/cmd/cmd_test.go @@ -123,7 +123,7 @@ func (co capturedOutput) reset() { Err = co.oldErr } -func errorResponse(contentType string, body string) *http.Response { +func errorResponse418(contentType string, body string) *http.Response { response := &http.Response{ Status: "418 I'm a teapot", StatusCode: 418, @@ -135,35 +135,57 @@ func errorResponse(contentType string, body string) *http.Response { return response } +func errorResponse429(retryAfter string) *http.Response { + body := "" + response := &http.Response{ + Status: "429 Too Many Requests", + StatusCode: 429, + Header: make(http.Header), + Body: ioutil.NopCloser(strings.NewReader(body)), + ContentLength: int64(len(body)), + } + response.Header.Set("Content-Type", "text/plain") + response.Header.Set("Retry-After", retryAfter) + return response +} + func TestDecodeErrorResponse(t *testing.T) { testCases := []struct { response *http.Response wantMessage string }{ { - response: errorResponse("text/html", "Time for tea"), + response: errorResponse418("text/html", "Time for tea"), wantMessage: `expected response with Content-Type "application/json" but got status "418 I'm a teapot" with Content-Type "text/html"`, }, { - response: errorResponse("application/json", `{"error": {"type": "json", "valid": no}}`), + response: errorResponse418("application/json", `{"error": {"type": "json", "valid": no}}`), wantMessage: "failed to parse API error response: invalid character 'o' in literal null (expecting 'u')", }, { - response: errorResponse("application/json", `{"error": {"type": "track_ambiguous", "message": "message", "possible_track_ids": ["a", "b"]}}`), + response: errorResponse418("application/json", `{"error": {"type": "track_ambiguous", "message": "message", "possible_track_ids": ["a", "b"]}}`), wantMessage: "message: a, b", }, { - response: errorResponse("application/json", `{"error": {"message": "message"}}`), + response: errorResponse418("application/json", `{"error": {"message": "message"}}`), wantMessage: "message", }, { - response: errorResponse("application/problem+json", `{"error": {"message": "new json format"}}`), + response: errorResponse418("application/problem+json", `{"error": {"message": "new json format"}}`), wantMessage: "new json format", }, { - response: errorResponse("application/json", `{"error": {}}`), + response: errorResponse418("application/json", `{"error": {}}`), wantMessage: "unexpected API response: 418", }, + { + response: errorResponse429("30"), + wantMessage: "request failed with status 429 Too Many Requests; please try again after 30 seconds", + }, + { + response: errorResponse429("Wed, 21 Oct 2015 07:28:00 GMT"), + wantMessage: "request failed with status 429 Too Many Requests; please try again after Wed, 21 Oct 2015 07:28:00 GMT", + }, } tc := testCases[0] got := decodedAPIError(tc.response) From f8a1087d1620888e6162ad8d8219cf7a544850f0 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Sun, 6 Jul 2025 20:39:51 +0200 Subject: [PATCH 114/142] Support for Futhark in `exercism test` (#1199) --- workspace/test_configurations.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/workspace/test_configurations.go b/workspace/test_configurations.go index d07a62f0e..d3e237817 100644 --- a/workspace/test_configurations.go +++ b/workspace/test_configurations.go @@ -146,6 +146,9 @@ var TestConfigurations = map[string]TestConfiguration{ "fsharp": { Command: "dotnet test", }, + "futhark": { + Command: "futhark test test.fut", + }, "gleam": { Command: "gleam test", }, From c9e0237f5da1be2adce4b2afd8a7369399e03fbd Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Sun, 6 Jul 2025 20:46:32 +0200 Subject: [PATCH 115/142] Bump version to 3.5.6 (#1200) --- CHANGELOG.md | 30 +++++++++++++++++++----------- cmd/version.go | 2 +- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 606588690..e5693792d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,12 @@ The exercism CLI follows [semantic versioning](http://semver.org/). - **Your contribution here** +## v3.5.6 (2025-07-06) + +- [#1199](https://github.com/exercism/cli/pull/1199) Support for Futhark in exercism test - [@erikschierboom] +- [#1198](https://github.com/exercism/cli/pull/1198) Show a "try again after" message when a response sets a Retry-After header - [@isaacg] +- [#1196](https://github.com/exercism/cli/pull/1196) Check HTTP response content type before trying to decode it as JSON - [@isaacg] + ## v3.5.5 (2025-05-30) - [#1192](https://github.com/exercism/cli/pull/1192) Change Idris test command to use slug - [@keiravillekode] @@ -507,16 +513,16 @@ All changes by [@msgehard] - Implement login and logout - Build on Travis -[@AlexWheeler]: https://github.com/AlexWheeler +[@alexwheeler]: https://github.com/AlexWheeler [@andrerfcsantos]: https://github.com/andrerfcsantos [@avegner]: https://github.com/avegner -[@Dparker1990]: https://github.com/Dparker1990 -[@John-Goff]: https://github.com/John-Goff -[@LegalizeAdulthood]: https://github.com/LegalizeAdulthood -[@QuLogic]: https://github.com/QuLogic -[@Smarticles101]: https://github.com/Smarticles101 -[@Tonkpils]: https://github.com/Tonkpils -[@TrevorBramble]: https://github.com/TrevorBramble +[@dparker1990]: https://github.com/Dparker1990 +[@john-goff]: https://github.com/John-Goff +[@legalizeadulthood]: https://github.com/LegalizeAdulthood +[@qulogic]: https://github.com/QuLogic +[@smarticles101]: https://github.com/Smarticles101 +[@tonkpils]: https://github.com/Tonkpils +[@trevorbramble]: https://github.com/TrevorBramble [@alebaffa]: https://github.com/alebaffa [@ambroff]: https://github.com/ambroff [@andrewsardone]: https://github.com/andrewsardone @@ -531,22 +537,24 @@ All changes by [@msgehard] [@djquan]: https://github.com/djquan [@dmmulroy]: https://github.com/dmmulroy [@dpritchett]: https://github.com/dpritchett -[@eToThePiIPower]: https://github.com/eToThePiIPower +[@etothepiipower]: https://github.com/eToThePiIPower [@ebautistabar]: https://github.com/ebautistabar [@ekingery]: https://github.com/ekingery [@elimisteve]: https://github.com/elimisteve +[@erikschierboom]: https://github.com/erikschierboom [@ests]: https://github.com/ests [@farisj]: https://github.com/farisj [@glebedel]: https://github.com/glebedel [@harimp]: https://github.com/harimp [@harugo]: https://github.com/harugo [@hjljo]: https://github.com/hjljo +[@isaacg]: https://github.com/isaacg [@isbadawi]: https://github.com/isbadawi [@jbaiter]: https://github.com/jbaiter [@jdsutherland]: https://github.com/jdsutherland [@jgsqware]: https://github.com/jgsqware [@jish]: https://github.com/jish -[@Jrank2013]: https://github.com/Jrank2013 +[@jrank2013]: https://github.com/Jrank2013 [@jppunnett]: https://github.com/jppunnett [@katrinleinweber]: https://github.com/katrinleinweber [@kytrinyx]: https://github.com/kytrinyx @@ -572,7 +580,7 @@ All changes by [@msgehard] [@xavdid]: https://github.com/xavdid [@williandrade]: https://github.com/williandrade [@zabawaba99]: https://github.com/zabawaba99 -[@GroophyLifefor]: https://github.com/GroophyLifefor +[@groophylifefor]: https://github.com/GroophyLifefor [@muzimuzhi]: https://github.com/muzimuzhi [@isberg]: https://github.com/isberg [@erikschierboom]: https://github.com/erikschierboom diff --git a/cmd/version.go b/cmd/version.go index a0bb6abbe..02f9c955b 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -9,7 +9,7 @@ import ( // Version is the version of the current build. // It follows semantic versioning. -const Version = "3.5.5" +const Version = "3.5.6" // checkLatest flag for version command. var checkLatest bool From c84b33cfb9b0f8e71f7b2031714d98d092a00640 Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Sun, 6 Jul 2025 21:00:19 +0200 Subject: [PATCH 116/142] Fix goreleaser deprecations (#1201) 1. https://goreleaser.com/deprecations/#archivesformat_overridesformat 2. https://goreleaser.com/deprecations/#archivesbuilds --- .goreleaser.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index 1995cf6b4..6e9a9d182 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -54,7 +54,7 @@ changelog: archives: - id: release-archives - builds: + ids: - release-build name_template: >- {{- .ProjectName }}- @@ -66,7 +66,7 @@ archives: {{- if .Arm }}v{{- .Arm }}{{ end }} format_overrides: - goos: windows - format: zip + formats: ["zip"] files: - shell/** - LICENSE @@ -84,7 +84,7 @@ archives: {{- if .Arm }}v{{- .Arm }}{{ end }} format_overrides: - goos: windows - format: zip + formats: ["zip"] files: - shell/** - LICENSE From de0cf3eff4fc3f2e978e1004df99c9de865d1e17 Mon Sep 17 00:00:00 2001 From: Isaac Good Date: Mon, 14 Jul 2025 09:30:17 -0700 Subject: [PATCH 117/142] Add error decoding support for content type parameters such as charset (#1202) --- cmd/cmd.go | 5 +++-- cmd/cmd_test.go | 4 ++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/cmd/cmd.go b/cmd/cmd.go index 61fe9c047..b0c7a8310 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -2,6 +2,7 @@ package cmd import ( "encoding/json" + "errors" "fmt" "net/http" "regexp" @@ -26,7 +27,7 @@ var ( // Err is used to write errors. Err io.Writer // jsonContentTypeRe is used to match Content-Type which contains JSON. - jsonContentTypeRe = regexp.MustCompile(`^application/([[:alpha:]]+\+)?json$`) + jsonContentTypeRe = regexp.MustCompile(`^application/([[:alpha:]]+\+)?json($|;)`) ) const msgWelcomePleaseConfigure = ` @@ -122,7 +123,7 @@ func decodedAPIError(resp *http.Response) error { strings.Join(apiError.Error.PossibleTrackIDs, ", "), ) } - return fmt.Errorf(apiError.Error.Message) + return errors.New(apiError.Error.Message) } return fmt.Errorf("unexpected API response: %d", resp.StatusCode) } diff --git a/cmd/cmd_test.go b/cmd/cmd_test.go index a4d8b9fe2..d712e742b 100644 --- a/cmd/cmd_test.go +++ b/cmd/cmd_test.go @@ -162,6 +162,10 @@ func TestDecodeErrorResponse(t *testing.T) { response: errorResponse418("application/json", `{"error": {"type": "json", "valid": no}}`), wantMessage: "failed to parse API error response: invalid character 'o' in literal null (expecting 'u')", }, + { + response: errorResponse418("application/json; charset=utf-8", `{"error": {"type": "track_ambiguous", "message": "message", "possible_track_ids": ["a", "b"]}}`), + wantMessage: "message: a, b", + }, { response: errorResponse418("application/json", `{"error": {"type": "track_ambiguous", "message": "message", "possible_track_ids": ["a", "b"]}}`), wantMessage: "message: a, b", From 0038ab5ef3299c23e007228464ac815029b48ad6 Mon Sep 17 00:00:00 2001 From: Isaac Good Date: Tue, 15 Jul 2025 08:11:58 -0700 Subject: [PATCH 118/142] Add version bump from v3.5.6 to v3.5.7 (#1204) --- CHANGELOG.md | 5 +++++ cmd/version.go | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e5693792d..3be77cb6c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,11 @@ The exercism CLI follows [semantic versioning](http://semver.org/). - **Your contribution here** +## v3.5.7 (2025-07-14) + +- [#1202](https://github.com/exercism/cli/pull/1202) Add error decoding support for content type parameters such as charset - [@isaacg] +- [#1201](https://github.com/exercism/cli/pull/1201) Fix goreleaser deprecations - [@erikschierboom] + ## v3.5.6 (2025-07-06) - [#1199](https://github.com/exercism/cli/pull/1199) Support for Futhark in exercism test - [@erikschierboom] diff --git a/cmd/version.go b/cmd/version.go index 02f9c955b..7ab4ff377 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -9,7 +9,7 @@ import ( // Version is the version of the current build. // It follows semantic versioning. -const Version = "3.5.6" +const Version = "3.5.7" // checkLatest flag for version command. var checkLatest bool From 8d0bdbedeb07339bec7e5a9d5e822f19210ff521 Mon Sep 17 00:00:00 2001 From: Isaac Good Date: Tue, 12 Aug 2025 08:56:37 -0700 Subject: [PATCH 119/142] Drop team-specific logic from the CLI (#1206) --- cmd/download.go | 24 +++++------------ cmd/download_test.go | 30 +++++----------------- cmd/submit.go | 2 +- cmd/submit_test.go | 47 ---------------------------------- shell/exercism.fish | 1 - workspace/exercise_metadata.go | 4 --- workspace/workspace.go | 22 ---------------- workspace/workspace_test.go | 8 ++---- 8 files changed, 16 insertions(+), 122 deletions(-) diff --git a/cmd/download.go b/cmd/download.go index f376e959b..d42771f58 100644 --- a/cmd/download.go +++ b/cmd/download.go @@ -135,7 +135,7 @@ type download struct { token, apibaseurl, workspace string // optional - track, team string + track string forceoverwrite bool payload *downloadPayload @@ -156,7 +156,6 @@ func newDownload(flags *pflag.FlagSet, usrCfg *viper.Viper) (*download, error) { if err != nil { return nil, err } - d.team, err = flags.GetString("team") if err != nil { return nil, err } @@ -176,7 +175,7 @@ func newDownload(flags *pflag.FlagSet, usrCfg *viper.Viper) (*download, error) { if err = d.needsUserConfigValues(); err != nil { return nil, err } - if err = d.needsSlugWhenGivenTrackOrTeam(); err != nil { + if err = d.needsSlugWhenGivenTrack(); err != nil { return nil, err } @@ -226,9 +225,6 @@ func (d download) buildQueryParams(url *netURL.URL) { if d.track != "" { query.Add("track_id", d.track) } - if d.team != "" { - query.Add("team_id", d.team) - } } url.RawQuery = query.Encode() } @@ -256,11 +252,11 @@ func (d download) needsUserConfigValues() error { return nil } -// needsSlugWhenGivenTrackOrTeam ensures that track/team arguments are also given with a slug. -// (track/team meaningless when given a uuid). -func (d download) needsSlugWhenGivenTrackOrTeam() error { - if (d.team != "" || d.track != "") && d.slug == "" { - return errors.New("--track or --team requires --exercise (not --uuid)") +// needsSlugWhenGivenTrack ensures that track arguments are also given with a slug. +// (track meaningless when given a uuid). +func (d download) needsSlugWhenGivenTrack() error { + if d.track != "" && d.slug == "" { + return errors.New("--track or requires --exercise (not --uuid)") } return nil } @@ -269,10 +265,6 @@ type downloadPayload struct { Solution struct { ID string `json:"id"` URL string `json:"url"` - Team struct { - Name string `json:"name"` - Slug string `json:"slug"` - } `json:"team"` User struct { Handle string `json:"handle"` IsRequester bool `json:"is_requester"` @@ -303,7 +295,6 @@ func (dp downloadPayload) metadata() workspace.ExerciseMetadata { return workspace.ExerciseMetadata{ AutoApprove: dp.Solution.Exercise.AutoApprove, Track: dp.Solution.Exercise.Track.ID, - Team: dp.Solution.Team.Slug, ExerciseSlug: dp.Solution.Exercise.ID, ID: dp.Solution.ID, URL: dp.Solution.URL, @@ -361,7 +352,6 @@ func setupDownloadFlags(flags *pflag.FlagSet) { flags.StringP("uuid", "u", "", "the solution UUID") flags.StringP("track", "t", "", "the track ID") flags.StringP("exercise", "e", "", "the exercise slug") - flags.StringP("team", "T", "", "the team slug") flags.BoolP("force", "F", false, "overwrite existing exercise directory") } diff --git a/cmd/download_test.go b/cmd/download_test.go index 791be4230..03d2b1eed 100644 --- a/cmd/download_test.go +++ b/cmd/download_test.go @@ -160,11 +160,6 @@ func TestDownload(t *testing.T) { expectedDir: filepath.Join("users", "alice"), flags: map[string]string{"uuid": "bogus-id"}, }, - { - requester: true, - expectedDir: filepath.Join("teams", "bogus-team"), - flags: map[string]string{"exercise": "bogus-exercise", "track": "bogus-track", "team": "bogus-team"}, - }, } for _, tc := range testCases { @@ -172,7 +167,7 @@ func TestDownload(t *testing.T) { defer os.RemoveAll(tmpDir) assert.NoError(t, err) - ts := fakeDownloadServer(strconv.FormatBool(tc.requester), tc.flags["team"]) + ts := fakeDownloadServer(strconv.FormatBool(tc.requester)) defer ts.Close() v := viper.New() @@ -221,10 +216,6 @@ func TestDownloadToExistingDirectory(t *testing.T) { exerciseDir: filepath.Join("bogus-track", "bogus-exercise"), flags: map[string]string{"exercise": "bogus-exercise", "track": "bogus-track"}, }, - { - exerciseDir: filepath.Join("teams", "bogus-team", "bogus-track", "bogus-exercise"), - flags: map[string]string{"exercise": "bogus-exercise", "track": "bogus-track", "team": "bogus-team"}, - }, } for _, tc := range testCases { @@ -235,7 +226,7 @@ func TestDownloadToExistingDirectory(t *testing.T) { err = os.MkdirAll(filepath.Join(tmpDir, tc.exerciseDir), os.FileMode(0755)) assert.NoError(t, err) - ts := fakeDownloadServer("true", "") + ts := fakeDownloadServer("true") defer ts.Close() v := viper.New() @@ -273,10 +264,6 @@ func TestDownloadToExistingDirectoryWithForce(t *testing.T) { exerciseDir: filepath.Join("bogus-track", "bogus-exercise"), flags: map[string]string{"exercise": "bogus-exercise", "track": "bogus-track"}, }, - { - exerciseDir: filepath.Join("teams", "bogus-team", "bogus-track", "bogus-exercise"), - flags: map[string]string{"exercise": "bogus-exercise", "track": "bogus-track", "team": "bogus-team"}, - }, } for _, tc := range testCases { @@ -287,7 +274,7 @@ func TestDownloadToExistingDirectoryWithForce(t *testing.T) { err = os.MkdirAll(filepath.Join(tmpDir, tc.exerciseDir), os.FileMode(0755)) assert.NoError(t, err) - ts := fakeDownloadServer("true", "") + ts := fakeDownloadServer("true") defer ts.Close() v := viper.New() @@ -310,7 +297,7 @@ func TestDownloadToExistingDirectoryWithForce(t *testing.T) { } } -func fakeDownloadServer(requestor, teamSlug string) *httptest.Server { +func fakeDownloadServer(requestor string) *httptest.Server { mux := http.NewServeMux() server := httptest.NewServer(mux) @@ -327,15 +314,11 @@ func fakeDownloadServer(requestor, teamSlug string) *httptest.Server { }) mux.HandleFunc("/solutions/latest", func(w http.ResponseWriter, r *http.Request) { - team := "null" - if teamSlug := r.FormValue("team_id"); teamSlug != "" { - team = fmt.Sprintf(`{"name": "Bogus Team", "slug": "%s"}`, teamSlug) - } - payloadBody := fmt.Sprintf(payloadTemplate, requestor, team, server.URL+"/") + payloadBody := fmt.Sprintf(payloadTemplate, requestor, server.URL+"/") fmt.Fprint(w, payloadBody) }) mux.HandleFunc("/solutions/bogus-id", func(w http.ResponseWriter, r *http.Request) { - payloadBody := fmt.Sprintf(payloadTemplate, requestor, "null", server.URL+"/") + payloadBody := fmt.Sprintf(payloadTemplate, requestor, server.URL+"/") fmt.Fprint(w, payloadBody) }) @@ -415,7 +398,6 @@ const payloadTemplate = ` "handle": "alice", "is_requester": %s }, - "team": %s, "exercise": { "id": "bogus-exercise", "instructions_url": "http://example.com/bogus-exercise", diff --git a/cmd/submit.go b/cmd/submit.go index eb00aa1f4..3135f65ae 100644 --- a/cmd/submit.go +++ b/cmd/submit.go @@ -312,7 +312,7 @@ func (s *submitCmdContext) printResult(metadata *workspace.ExerciseMetadata) { %s ` suffix := "View it at:\n\n " - if metadata.AutoApprove && metadata.Team == "" { + if metadata.AutoApprove { suffix = "You can complete the exercise and unlock the next core exercise at:\n" } fmt.Fprintf(Err, msg, suffix) diff --git a/cmd/submit_test.go b/cmd/submit_test.go index 7db152a75..4e1349953 100644 --- a/cmd/submit_test.go +++ b/cmd/submit_test.go @@ -425,53 +425,6 @@ func TestSubmitWithEnormousFile(t *testing.T) { } } -func TestSubmitFilesForTeamExercise(t *testing.T) { - co := newCapturedOutput() - co.override() - defer co.reset() - - // The fake endpoint will populate this when it receives the call from the command. - submittedFiles := map[string]string{} - ts := fakeSubmitServer(t, submittedFiles) - defer ts.Close() - - tmpDir, err := os.MkdirTemp("", "submit-files") - assert.NoError(t, err) - - dir := filepath.Join(tmpDir, "teams", "bogus-team", "bogus-track", "bogus-exercise") - os.MkdirAll(filepath.Join(dir, "subdir"), os.FileMode(0755)) - writeFakeMetadata(t, dir, "bogus-track", "bogus-exercise") - - file1 := filepath.Join(dir, "file-1.txt") - err = os.WriteFile(file1, []byte("This is file 1."), os.FileMode(0755)) - assert.NoError(t, err) - - file2 := filepath.Join(dir, "subdir", "file-2.txt") - err = os.WriteFile(file2, []byte("This is file 2."), os.FileMode(0755)) - assert.NoError(t, err) - - v := viper.New() - v.Set("token", "abc123") - v.Set("workspace", tmpDir) - v.Set("apibaseurl", ts.URL) - - cfg := config.Config{ - Dir: tmpDir, - UserViperConfig: v, - } - - files := []string{ - file1, file2, - } - err = runSubmit(cfg, pflag.NewFlagSet("fake", pflag.PanicOnError), files) - assert.NoError(t, err) - - assert.Equal(t, 2, len(submittedFiles)) - - assert.Equal(t, "This is file 1.", submittedFiles["file-1.txt"]) - assert.Equal(t, "This is file 2.", submittedFiles["subdir/file-2.txt"]) -} - func TestSubmitOnlyEmptyFile(t *testing.T) { co := newCapturedOutput() co.override() diff --git a/shell/exercism.fish b/shell/exercism.fish index c2c7c0811..4abe9b21e 100644 --- a/shell/exercism.fish +++ b/shell/exercism.fish @@ -9,7 +9,6 @@ complete -f -c exercism -n "__fish_seen_subcommand_from configure" -s s -l show complete -f -c exercism -n "__fish_use_subcommand" -a "download" -d "Downloads and saves a specified submission into the local system" complete -f -c exercism -n "__fish_seen_subcommand_from download" -s e -l exercise -d "the exercise slug" complete -f -c exercism -n "__fish_seen_subcommand_from download" -s h -l help -d "help for download" -complete -f -c exercism -n "__fish_seen_subcommand_from download" -s T -l team -d "the team slug" complete -f -c exercism -n "__fish_seen_subcommand_from download" -s t -l track -d "the track ID" complete -f -c exercism -n "__fish_seen_subcommand_from download" -s u -l uuid -d "the solution UUID" diff --git a/workspace/exercise_metadata.go b/workspace/exercise_metadata.go index 729174258..3ec902c1b 100644 --- a/workspace/exercise_metadata.go +++ b/workspace/exercise_metadata.go @@ -20,7 +20,6 @@ type ExerciseMetadata struct { Track string `json:"track"` ExerciseSlug string `json:"exercise"` ID string `json:"id"` - Team string `json:"team,omitempty"` URL string `json:"url"` Handle string `json:"handle"` IsRequester bool `json:"is_requester"` @@ -98,9 +97,6 @@ func (em *ExerciseMetadata) Exercise(workspace string) Exercise { // root represents the root of the exercise. func (em *ExerciseMetadata) root(workspace string) string { - if em.Team != "" { - return filepath.Join(workspace, "teams", em.Team) - } if !em.IsRequester { return filepath.Join(workspace, "users", em.Handle) } diff --git a/workspace/workspace.go b/workspace/workspace.go index 0011d4be2..dbd0604f1 100644 --- a/workspace/workspace.go +++ b/workspace/workspace.go @@ -58,28 +58,6 @@ func (ws Workspace) PotentialExercises() ([]Exercise, error) { continue } - if topInfo.Name() == "teams" { - subInfos, err := os.ReadDir(filepath.Join(ws.Dir, "teams")) - if err != nil { - return nil, err - } - - for _, subInfo := range subInfos { - teamWs, err := New(filepath.Join(ws.Dir, "teams", subInfo.Name())) - if err != nil { - return nil, err - } - - teamExercises, err := teamWs.PotentialExercises() - if err != nil { - return nil, err - } - - exercises = append(exercises, teamExercises...) - } - continue - } - subInfos, err := os.ReadDir(filepath.Join(ws.Dir, topInfo.Name())) if err != nil { return nil, err diff --git a/workspace/workspace_test.go b/workspace/workspace_test.go index 63053a5cd..8614ddc2c 100644 --- a/workspace/workspace_test.go +++ b/workspace/workspace_test.go @@ -19,16 +19,13 @@ func TestWorkspacePotentialExercises(t *testing.T) { b1 := filepath.Join(tmpDir, "track-b", "exercise-one") b2 := filepath.Join(tmpDir, "track-b", "exercise-two") - // It should find teams exercises - team := filepath.Join(tmpDir, "teams", "some-team", "track-c", "exercise-one") - // It should ignore other people's exercises. alice := filepath.Join(tmpDir, "users", "alice", "track-a", "exercise-one") // It should ignore nested dirs within exercises. nested := filepath.Join(a1, "subdir", "deeper-dir", "another-deep-dir") - for _, path := range []string{a1, b1, b2, team, alice, nested} { + for _, path := range []string{a1, b1, b2, alice, nested} { err := os.MkdirAll(path, os.FileMode(0755)) assert.NoError(t, err) } @@ -38,7 +35,7 @@ func TestWorkspacePotentialExercises(t *testing.T) { exercises, err := ws.PotentialExercises() assert.NoError(t, err) - if assert.Equal(t, 4, len(exercises)) { + if assert.Equal(t, 3, len(exercises)) { paths := make([]string, len(exercises)) for i, e := range exercises { paths[i] = e.Path() @@ -48,7 +45,6 @@ func TestWorkspacePotentialExercises(t *testing.T) { assert.Equal(t, paths[0], "track-a/exercise-one") assert.Equal(t, paths[1], "track-b/exercise-one") assert.Equal(t, paths[2], "track-b/exercise-two") - assert.Equal(t, paths[3], "track-c/exercise-one") } } From 2599e0b8c3cc974d1ed4f2634df2d08f16984f68 Mon Sep 17 00:00:00 2001 From: Isaac Good Date: Sat, 30 Aug 2025 20:39:18 -0700 Subject: [PATCH 120/142] Include empty files in downloads (#1213) --- cmd/download.go | 4 ---- cmd/download_test.go | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/cmd/download.go b/cmd/download.go index d42771f58..0e74c49ed 100644 --- a/cmd/download.go +++ b/cmd/download.go @@ -101,10 +101,6 @@ func runDownload(cfg config.Config, flags *pflag.FlagSet, args []string) error { // TODO: deal with it continue } - // Don't bother with empty files. - if res.Header.Get("Content-Length") == "0" { - continue - } path := sf.relativePath() dir := filepath.Join(metadata.Dir, filepath.Dir(path)) diff --git a/cmd/download_test.go b/cmd/download_test.go index 03d2b1eed..b297e4be9 100644 --- a/cmd/download_test.go +++ b/cmd/download_test.go @@ -353,7 +353,7 @@ func assertDownloadedCorrectFiles(t *testing.T, targetDir string) { path := filepath.Join(targetDir, "bogus-track", "bogus-exercise", "file-3.txt") _, err := os.Lstat(path) - assert.True(t, os.IsNotExist(err), "It should not write the file if empty.") + assert.NoError(t, err) } func TestDownloadError(t *testing.T) { From bfa07bdfc1148a24ff621f0d2b727ff5a21aaea7 Mon Sep 17 00:00:00 2001 From: Isaac Good Date: Sun, 31 Aug 2025 07:58:48 -0700 Subject: [PATCH 121/142] goreleaser: update deprecated archives.builds to new archives.ids (#1205) See [goreleaser docs](https://goreleaser.com/deprecations/#archivesbuilds) for details. --- .goreleaser.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index 6e9a9d182..86f2100cc 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -72,7 +72,7 @@ archives: - LICENSE - README.md - id: installer-archives - builds: + ids: - installer-build name_template: >- {{- .ProjectName }}- From c1fb1037ad9751d40879e62a6a628998e3be811d Mon Sep 17 00:00:00 2001 From: Isaac Good Date: Sun, 31 Aug 2025 08:08:54 -0700 Subject: [PATCH 122/142] Use mode 0700 for the config dir, not 0755; other users should not have access to the config (#1210) --- config/persister.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/persister.go b/config/persister.go index 1ad046f0d..1b29dc720 100644 --- a/config/persister.go +++ b/config/persister.go @@ -25,7 +25,7 @@ func (p FilePersister) Save(v *viper.Viper, basename string) error { v.SetConfigName(basename) if _, err := os.Stat(p.Dir); os.IsNotExist(err) { - if err := os.MkdirAll(p.Dir, os.FileMode(0755)); err != nil { + if err := os.MkdirAll(p.Dir, os.FileMode(0700)); err != nil { return err } } From efc3ce2c86fb961744e6f18335c0417b88b72c7c Mon Sep 17 00:00:00 2001 From: Isaac Good Date: Tue, 23 Sep 2025 17:50:02 -0700 Subject: [PATCH 123/142] Update the token URL to point to the API settings page (#1215) --- cmd/cmd.go | 2 +- cmd/configure.go | 4 ++-- cmd/troubleshoot.go | 2 +- config/config.go | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/cmd/cmd.go b/cmd/cmd.go index b0c7a8310..ac28286a7 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -69,7 +69,7 @@ func validateUserConfig(cfg *viper.Viper) error { if cfg.GetString("token") == "" { return fmt.Errorf( msgWelcomePleaseConfigure, - config.SettingsURL(cfg.GetString("apibaseurl")), + config.TokenURL(cfg.GetString("apibaseurl")), BinaryName, ) } diff --git a/cmd/configure.go b/cmd/configure.go index dd1c47ed8..57aabc04c 100644 --- a/cmd/configure.go +++ b/cmd/configure.go @@ -60,7 +60,7 @@ func runConfigure(configuration config.Config, flags *pflag.FlagSet) error { // If the command is run 'bare' and we have no token, // explain how to set the token. if flags.NFlag() == 0 && cfg.GetString("token") == "" { - tokenURL := config.SettingsURL(cfg.GetString("apibaseurl")) + tokenURL := config.TokenURL(cfg.GetString("apibaseurl")) return fmt.Errorf("There is no token configured. Find your token on %s, and call this command again with --token=.", tokenURL) } @@ -107,7 +107,7 @@ func runConfigure(configuration config.Config, flags *pflag.FlagSet) error { token = cfg.GetString("token") } - tokenURL := config.SettingsURL(cfg.GetString("apibaseurl")) + tokenURL := config.TokenURL(cfg.GetString("apibaseurl")) // If we don't have a token then explain how to set it and bail. if token == "" { diff --git a/cmd/troubleshoot.go b/cmd/troubleshoot.go index 2c599d6d5..f83d5cc96 100644 --- a/cmd/troubleshoot.go +++ b/cmd/troubleshoot.go @@ -191,7 +191,7 @@ func newConfigurationStatus(status *Status) configurationStatus { Workspace: workspace, Dir: status.cfg.Dir, Token: v.GetString("token"), - TokenURL: config.SettingsURL(v.GetString("apibaseurl")), + TokenURL: config.TokenURL(v.GetString("apibaseurl")), } if status.Censor && cs.Token != "" { cs.Token = debug.Redact(cs.Token) diff --git a/config/config.go b/config/config.go index e1cc37e08..d52e3fd97 100644 --- a/config/config.go +++ b/config/config.go @@ -128,7 +128,7 @@ func InferSiteURL(apiURL string) string { return re.ReplaceAllString(apiURL, "$1") } -// SettingsURL provides a link to where the user can find their API token. -func SettingsURL(apiURL string) string { - return fmt.Sprintf("%s%s", InferSiteURL(apiURL), "/my/settings") +// TokenURL provides a link to where the user can find their API token. +func TokenURL(apiURL string) string { + return fmt.Sprintf("%s%s", InferSiteURL(apiURL), "/my/settings/api_cli") } From 282894b3e484c81a6e4646bb95a85ce3adf7ec50 Mon Sep 17 00:00:00 2001 From: Isaac Good Date: Wed, 24 Sep 2025 00:03:58 -0700 Subject: [PATCH 124/142] Bump version to v3.5.8 (#1216) --- CHANGELOG.md | 8 ++++++++ RELEASE.md | 2 +- cmd/version.go | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3be77cb6c..9de216f5e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,14 @@ The exercism CLI follows [semantic versioning](http://semver.org/). - **Your contribution here** +## v3.5.8 (2025-09-24) + +- [#1215](https://github.com/exercism/cli/pull/1215) Update the token URL to point to the API settings page [@isaacg] +- [#1210](https://github.com/exercism/cli/pull/1210) Use mode 0700 for the config dir, not 0755; other users should not have access to the config [@isaacg] +- [#1205](https://github.com/exercism/cli/pull/1205) goreleaser: update deprecated archives.builds to new archives.ids [@isaacg] +- [#1213](https://github.com/exercism/cli/pull/1213) Include empty files in downloads [@isaacg] +- [#1206](https://github.com/exercism/cli/pull/1206) Drop team-specific logic from the CLI [@isaacg] + ## v3.5.7 (2025-07-14) - [#1202](https://github.com/exercism/cli/pull/1202) Add error decoding support for content type parameters such as charset - [@isaacg] diff --git a/RELEASE.md b/RELEASE.md index 289c78822..17182f601 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -17,7 +17,7 @@ The Exercism CLI uses [GoReleaser](https://goreleaser.com) to automate the relea 1. Commit the updated files 1. Create a PR -_Note: It's useful to add the version to the commit message when you bump it: e.g. `Bump version to v2.3.4`._ +_Note: It's useful to add the version to the commit message when you bump it: e.g. `Bump version to v3.5.9`._ ## Cut a release diff --git a/cmd/version.go b/cmd/version.go index 7ab4ff377..7eec21d45 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -9,7 +9,7 @@ import ( // Version is the version of the current build. // It follows semantic versioning. -const Version = "3.5.7" +const Version = "3.5.8" // checkLatest flag for version command. var checkLatest bool From 3c2804bcf2e9f9352cf194fb1f494da5fdb22d66 Mon Sep 17 00:00:00 2001 From: Isaac Good Date: Wed, 24 Sep 2025 08:21:29 -0700 Subject: [PATCH 125/142] Fix the API settings URL: remove the `/my/` prefix (#1217) --- cmd/download_test.go | 2 +- cmd/submit_test.go | 2 +- config/config.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/download_test.go b/cmd/download_test.go index b297e4be9..fb18cfc86 100644 --- a/cmd/download_test.go +++ b/cmd/download_test.go @@ -26,7 +26,7 @@ func TestDownloadWithoutToken(t *testing.T) { if assert.Error(t, err) { assert.Regexp(t, "Welcome to Exercism", err.Error()) // It uses the default base API url to infer the host - assert.Regexp(t, "exercism.org/my/settings", err.Error()) + assert.Regexp(t, "exercism.org/settings", err.Error()) } } diff --git a/cmd/submit_test.go b/cmd/submit_test.go index 4e1349953..38caf9d93 100644 --- a/cmd/submit_test.go +++ b/cmd/submit_test.go @@ -28,7 +28,7 @@ func TestSubmitWithoutToken(t *testing.T) { err := runSubmit(cfg, pflag.NewFlagSet("fake", pflag.PanicOnError), []string{}) if assert.Error(t, err) { assert.Regexp(t, "Welcome to Exercism", err.Error()) - assert.Regexp(t, "exercism.org/my/settings", err.Error()) + assert.Regexp(t, "exercism.org/settings", err.Error()) } } diff --git a/config/config.go b/config/config.go index d52e3fd97..f16b2b6ce 100644 --- a/config/config.go +++ b/config/config.go @@ -130,5 +130,5 @@ func InferSiteURL(apiURL string) string { // TokenURL provides a link to where the user can find their API token. func TokenURL(apiURL string) string { - return fmt.Sprintf("%s%s", InferSiteURL(apiURL), "/my/settings/api_cli") + return fmt.Sprintf("%s%s", InferSiteURL(apiURL), "/settings/api_cli") } From 9e52305d14e83ed4e4bbb0ea0afc47cea641daf3 Mon Sep 17 00:00:00 2001 From: keiravillekode Date: Sun, 28 Dec 2025 01:12:58 +1100 Subject: [PATCH 126/142] Support for Free Pascal in `exercism test` (#1219) --- workspace/test_configurations.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/workspace/test_configurations.go b/workspace/test_configurations.go index d3e237817..2e3e31d08 100644 --- a/workspace/test_configurations.go +++ b/workspace/test_configurations.go @@ -143,6 +143,9 @@ var TestConfigurations = map[string]TestConfiguration{ "fortran": { Command: "make", }, + "free-pascal": { + Command: "make test=all", + }, "fsharp": { Command: "dotnet test", }, From 1a6aad5e53facf1c7003b7ab7869e183f9a187d8 Mon Sep 17 00:00:00 2001 From: Glenn Jackman Date: Mon, 12 Jan 2026 09:55:01 -0500 Subject: [PATCH 127/142] Add Odin support to `exercism test` (#1220) Co-authored-by: Erik Schierboom --- workspace/test_configurations.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/workspace/test_configurations.go b/workspace/test_configurations.go index 2e3e31d08..7d3731e83 100644 --- a/workspace/test_configurations.go +++ b/workspace/test_configurations.go @@ -203,6 +203,9 @@ var TestConfigurations = map[string]TestConfiguration{ "ocaml": { Command: "make", }, + "odin": { + Command: "odin test .", + }, "perl5": { Command: "prove .", }, From 9c1e805bc08bc0a2f8205782ab6556c9695f2eaf Mon Sep 17 00:00:00 2001 From: Glenn Jackman Date: Mon, 12 Jan 2026 09:57:42 -0500 Subject: [PATCH 128/142] Add moonscript for `exercism test` (#1222) --- workspace/test_configurations.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/workspace/test_configurations.go b/workspace/test_configurations.go index 7d3731e83..3c989d2c7 100644 --- a/workspace/test_configurations.go +++ b/workspace/test_configurations.go @@ -196,6 +196,9 @@ var TestConfigurations = map[string]TestConfiguration{ "mips": { Command: "java -jar /path/to/mars.jar nc runner.mips impl.mips", }, + "moonscript": { + Command: "busted", + }, "nim": { Command: "nim r {{test_files}}", }, From 47588cb78733d60cf45aa33c52790adff9d562a4 Mon Sep 17 00:00:00 2001 From: Tim Date: Tue, 13 Jan 2026 11:16:21 -0500 Subject: [PATCH 129/142] Add Lean test command to test configurations (#1224) --- workspace/test_configurations.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/workspace/test_configurations.go b/workspace/test_configurations.go index 3c989d2c7..85479f30c 100644 --- a/workspace/test_configurations.go +++ b/workspace/test_configurations.go @@ -187,6 +187,9 @@ var TestConfigurations = map[string]TestConfiguration{ Command: "./gradlew test", WindowsCommand: "gradlew.bat test", }, + "lean": { + Command: "lake test", + }, "lfe": { Command: "make test", }, From 0e04a92133e826bc11d53d8004e1158f02fa9313 Mon Sep 17 00:00:00 2001 From: keiravillekode Date: Tue, 5 May 2026 21:18:07 +1000 Subject: [PATCH 130/142] Add factor support to `exercism test` (#1228) --- workspace/test_configurations.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/workspace/test_configurations.go b/workspace/test_configurations.go index 85479f30c..7d5672f69 100644 --- a/workspace/test_configurations.go +++ b/workspace/test_configurations.go @@ -140,6 +140,9 @@ var TestConfigurations = map[string]TestConfiguration{ "erlang": { Command: "rebar3 eunit", }, + "factor": { + Command: "factor -roots=. -run=exercism-tools {{slug}}", + }, "fortran": { Command: "make", }, From 8d6322f3a78a135fcea558477bdd70939923e664 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 May 2026 13:24:15 -0700 Subject: [PATCH 131/142] Bump goreleaser/goreleaser-action from 6.0.0 to 6.2.1 (#1190) Bumps [goreleaser/goreleaser-action](https://github.com/goreleaser/goreleaser-action) from 6.0.0 to 6.2.1. - [Release notes](https://github.com/goreleaser/goreleaser-action/releases) - [Commits](https://github.com/goreleaser/goreleaser-action/compare/286f3b13b1b49da4ac219696163fb8c1c93e1200...90a3faa9d0182683851fbfa97ca1a2cb983bfca3) --- updated-dependencies: - dependency-name: goreleaser/goreleaser-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Isaac Good --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 599f23bdb..37e84f205 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -32,7 +32,7 @@ jobs: passphrase: ${{ secrets.PASSPHRASE }} - name: Cut Release - uses: goreleaser/goreleaser-action@286f3b13b1b49da4ac219696163fb8c1c93e1200 # v6.0.0 + uses: goreleaser/goreleaser-action@90a3faa9d0182683851fbfa97ca1a2cb983bfca3 # v6.2.1 with: version: latest args: release --clean --release-header .release/header.md --timeout 120m # default time is 30m From 651bb359317c9b78460ab289b2b078a7cca18755 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 May 2026 13:30:19 -0700 Subject: [PATCH 132/142] Bump actions/setup-go from 5.0.2 to 5.3.0 (#1189) Bumps [actions/setup-go](https://github.com/actions/setup-go) from 5.0.2 to 5.3.0. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](https://github.com/actions/setup-go/compare/0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32...f111f3307d8850f501ac008e886eec1fd1932a34) --- updated-dependencies: - dependency-name: actions/setup-go dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Isaac Good --- .github/workflows/ci.yml | 2 +- .github/workflows/release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 05aa6a748..8d23a6ace 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,7 +25,7 @@ jobs: steps: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 - - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 + - uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 with: go-version: ${{ matrix.go-version }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 37e84f205..c0ca0e7b8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -20,7 +20,7 @@ jobs: fetch-depth: 0 - name: Set up Go - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 + uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0 with: go-version: '1.20.x' From 5c9703a7eeeda787d131fb7a69193f844ef402a9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 May 2026 13:32:23 -0700 Subject: [PATCH 133/142] Bump actions/checkout from 4.1.7 to 4.2.2 (#1181) Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.7 to 4.2.2. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/692973e3d937129bcbf40652eb9f2f61becf3332...11bd71901bbe5b1630ceea73d27597364c9af683) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Erik Schierboom Co-authored-by: Isaac Good --- .github/workflows/ci.yml | 4 ++-- .github/workflows/release.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8d23a6ace..173de5bf4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: os: [ubuntu-latest, windows-latest, macOS-latest] steps: - - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 with: @@ -39,7 +39,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - name: Check formatting run: ./.gha.gofmt.sh diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c0ca0e7b8..59b76b4f5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,7 +15,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: fetch-depth: 0 From 447d5dff80a43c0ed805a125780e4c3f914814b0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 May 2026 13:39:53 -0700 Subject: [PATCH 134/142] Bump crazy-max/ghaction-import-gpg from 6.1.0 to 6.2.0 (#1179) Bumps [crazy-max/ghaction-import-gpg](https://github.com/crazy-max/ghaction-import-gpg) from 6.1.0 to 6.2.0. - [Release notes](https://github.com/crazy-max/ghaction-import-gpg/releases) - [Commits](https://github.com/crazy-max/ghaction-import-gpg/compare/01dd5d3ca463c7f10f7f4f7b4f177225ac661ee4...cb9bde2e2525e640591a934b1fd28eef1dcaf5e5) --- updated-dependencies: - dependency-name: crazy-max/ghaction-import-gpg dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Isaac Good --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 59b76b4f5..5fe7350bb 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -26,7 +26,7 @@ jobs: - name: Import GPG Key id: import_gpg - uses: crazy-max/ghaction-import-gpg@01dd5d3ca463c7f10f7f4f7b4f177225ac661ee4 # v6.1.0 + uses: crazy-max/ghaction-import-gpg@cb9bde2e2525e640591a934b1fd28eef1dcaf5e5 # v6.2.0 with: gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} passphrase: ${{ secrets.PASSPHRASE }} From 7dc21d16c9843501a612dec295071eaa606ee8d7 Mon Sep 17 00:00:00 2001 From: Isaac Good Date: Fri, 29 May 2026 12:46:18 -0700 Subject: [PATCH 135/142] Bump CLI go version to 1.26 and update lib versions (#1231) --- .github/workflows/ci.yml | 3 +- .github/workflows/release.yml | 2 +- CONTRIBUTING.md | 2 +- cli/cli.go | 5 +- cmd/submit.go | 2 +- go.mod | 38 ++- go.sum | 526 +++------------------------------- 7 files changed, 72 insertions(+), 506 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 173de5bf4..6824c353d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,8 +18,7 @@ jobs: fail-fast: false matrix: go-version: - - '1.20.x' - - '1.21.x' + - '1.26.x' os: [ubuntu-latest, windows-latest, macOS-latest] steps: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5fe7350bb..ce6585b11 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -22,7 +22,7 @@ jobs: - name: Set up Go uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0 with: - go-version: '1.20.x' + go-version: '1.26.x' - name: Import GPG Key id: import_gpg diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1515a4fcb..471c48688 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -8,7 +8,7 @@ Exercism would be impossible without people like you being willing to spend time ## Dependencies -You'll need Go version 1.20 or higher. Follow the directions on http://golang.org/doc/install +You'll need Go version 1.26 or higher. Follow the directions on http://golang.org/doc/install ## Development diff --git a/cli/cli.go b/cli/cli.go index fe113ec5b..d8b9bf4d3 100644 --- a/cli/cli.go +++ b/cli/cli.go @@ -6,6 +6,7 @@ import ( "bytes" "compress/gzip" "encoding/json" + "errors" "fmt" "io" "net/http" @@ -14,7 +15,7 @@ import ( "strings" "time" - "github.com/blang/semver" + semver "github.com/blang/semver/v4" "github.com/exercism/cli/debug" update "github.com/inconshreveable/go-update" ) @@ -150,7 +151,7 @@ func (c *CLI) fetchLatestRelease() error { for k, v := range resp.Header { msg += fmt.Sprintf("\n %s:\n %s", k, v) } - return fmt.Errorf(msg) + return errors.New(msg) } var rel Release diff --git a/cmd/submit.go b/cmd/submit.go index 3135f65ae..005cb8cc4 100644 --- a/cmd/submit.go +++ b/cmd/submit.go @@ -208,7 +208,7 @@ func (s *submitCmdContext) migrateLegacyMetadata(exercise workspace.Exercise) er return err } if verbose, _ := s.flags.GetBool("verbose"); verbose { - fmt.Fprintf(Err, migrationStatus.String()) + Err.Write([]byte(migrationStatus.String())) } return nil } diff --git a/go.mod b/go.mod index e56c3f97a..41f9d07a5 100644 --- a/go.mod +++ b/go.mod @@ -1,33 +1,31 @@ module github.com/exercism/cli -go 1.20 +go 1.26.0 require ( - github.com/blang/semver v3.5.1+incompatible + github.com/blang/semver/v4 v4.0.0 github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf - github.com/spf13/cobra v1.7.0 - github.com/spf13/pflag v1.0.5 - github.com/spf13/viper v1.15.0 - github.com/stretchr/testify v1.8.4 - golang.org/x/net v0.23.0 - golang.org/x/text v0.14.0 + github.com/spf13/cobra v1.10.0 + github.com/spf13/pflag v1.0.10 + github.com/spf13/viper v1.21.0 + github.com/stretchr/testify v1.11.1 + golang.org/x/net v0.55.0 + golang.org/x/text v0.37.0 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect - github.com/fsnotify/fsnotify v1.6.0 // indirect - github.com/hashicorp/hcl v1.0.0 // indirect + github.com/fsnotify/fsnotify v1.9.0 // indirect + github.com/go-viper/mapstructure/v2 v2.4.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/magiconair/properties v1.8.7 // indirect - github.com/mitchellh/mapstructure v1.5.0 // indirect - github.com/pelletier/go-toml/v2 v2.0.6 // indirect + github.com/pelletier/go-toml/v2 v2.2.4 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/spf13/afero v1.9.3 // indirect - github.com/spf13/cast v1.5.0 // indirect - github.com/spf13/jwalterweatherman v1.1.0 // indirect - github.com/subosito/gotenv v1.4.2 // indirect - golang.org/x/sys v0.18.0 // indirect - gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect - gopkg.in/ini.v1 v1.67.0 // indirect + github.com/sagikazarmark/locafero v0.11.0 // indirect + github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect + github.com/spf13/afero v1.15.0 // indirect + github.com/spf13/cast v1.10.0 // indirect + github.com/subosito/gotenv v1.6.0 // indirect + go.yaml.in/yaml/v3 v3.0.4 // indirect + golang.org/x/sys v0.45.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index c042354a7..0bb204f45 100644 --- a/go.sum +++ b/go.sum @@ -1,492 +1,60 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= -cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= -cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= -cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= -github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= +github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= +github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= -github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= -github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= +github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= +github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf h1:WfD7VjIE6z8dIvMsI4/s+1qr5EL+zoIGev1BQj1eoJ8= github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf/go.mod h1:hyb9oH7vZsitZCiBt0ZvifOrB+qc8PS5IiilCIb87rg= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -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/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= -github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= -github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= -github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU= -github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= +github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/spf13/afero v1.9.3 h1:41FoI0fD7OR7mGcKE/aOiLkGreyf8ifIOQmJANWogMk= -github.com/spf13/afero v1.9.3/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= -github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= -github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= -github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= -github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= -github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= -github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU= -github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= -github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= -golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= -google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= -google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= -google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc= +github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik= +github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw= +github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U= +github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I= +github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg= +github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY= +github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo= +github.com/spf13/cobra v1.10.0 h1:a5/WeUlSDCvV5a45ljW2ZFtV0bTDpkfSAj3uqB6Sc+0= +github.com/spf13/cobra v1.10.0/go.mod h1:9dhySC7dnTtEiqzmqfkLj47BslqLCUPMXjG2lj/NgoE= +github.com/spf13/pflag v1.0.8/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= +github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU= +github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= +github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= +golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= +golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= +golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc= +golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= -gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= From 68f7d69a01a87b371f607df5f881601adb6d8b09 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 7 Jun 2026 17:14:14 -0700 Subject: [PATCH 136/142] Bump actions/checkout from 4.2.2 to 6.0.2 (#1235) Bumps [actions/checkout](https://github.com/actions/checkout) from 4.2.2 to 6.0.2. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/11bd71901bbe5b1630ceea73d27597364c9af683...de0fac2e4500dabe0009e67214ff5f5447ce83dd) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: 6.0.2 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 4 ++-- .github/workflows/release.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6824c353d..eb44bd266 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,7 +22,7 @@ jobs: os: [ubuntu-latest, windows-latest, macOS-latest] steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd - uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 with: @@ -38,7 +38,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd - name: Check formatting run: ./.gha.gofmt.sh diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ce6585b11..70ec892ab 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,7 +15,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 From 5c86303c757ffae63f0cfd361dd777d03dbf62b0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 7 Jun 2026 17:17:28 -0700 Subject: [PATCH 137/142] Bump goreleaser/goreleaser-action from 6.2.1 to 7.2.2 (#1234) Bumps [goreleaser/goreleaser-action](https://github.com/goreleaser/goreleaser-action) from 6.2.1 to 7.2.2. - [Release notes](https://github.com/goreleaser/goreleaser-action/releases) - [Commits](https://github.com/goreleaser/goreleaser-action/compare/90a3faa9d0182683851fbfa97ca1a2cb983bfca3...5daf1e915a5f0af01ddbcd89a43b8061ff4f1a89) --- updated-dependencies: - dependency-name: goreleaser/goreleaser-action dependency-version: 7.2.2 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 70ec892ab..36f5e1c08 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -32,7 +32,7 @@ jobs: passphrase: ${{ secrets.PASSPHRASE }} - name: Cut Release - uses: goreleaser/goreleaser-action@90a3faa9d0182683851fbfa97ca1a2cb983bfca3 # v6.2.1 + uses: goreleaser/goreleaser-action@5daf1e915a5f0af01ddbcd89a43b8061ff4f1a89 # v7.2.2 with: version: latest args: release --clean --release-header .release/header.md --timeout 120m # default time is 30m From 8eccd59dea06f7c84b256dd3263c9b201b32dd1b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 7 Jun 2026 17:19:27 -0700 Subject: [PATCH 138/142] Bump actions/setup-go from 5.3.0 to 6.4.0 (#1232) Bumps [actions/setup-go](https://github.com/actions/setup-go) from 5.3.0 to 6.4.0. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](https://github.com/actions/setup-go/compare/f111f3307d8850f501ac008e886eec1fd1932a34...4a3601121dd01d1626a1e23e37211e3254c1c06c) --- updated-dependencies: - dependency-name: actions/setup-go dependency-version: 6.4.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- .github/workflows/release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index eb44bd266..383e5a5f3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,7 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd - - uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 + - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c with: go-version: ${{ matrix.go-version }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 36f5e1c08..e9c50ad5a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -20,7 +20,7 @@ jobs: fetch-depth: 0 - name: Set up Go - uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0 + uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 with: go-version: '1.26.x' From ae2fcb5d59b8973f6aba179b06e0da6efbd33338 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 7 Jun 2026 17:21:42 -0700 Subject: [PATCH 139/142] Bump crazy-max/ghaction-import-gpg from 6.2.0 to 7.0.0 (#1233) Bumps [crazy-max/ghaction-import-gpg](https://github.com/crazy-max/ghaction-import-gpg) from 6.2.0 to 7.0.0. - [Release notes](https://github.com/crazy-max/ghaction-import-gpg/releases) - [Commits](https://github.com/crazy-max/ghaction-import-gpg/compare/cb9bde2e2525e640591a934b1fd28eef1dcaf5e5...2dc316deee8e90f13e1a351ab510b4d5bc0c82cd) --- updated-dependencies: - dependency-name: crazy-max/ghaction-import-gpg dependency-version: 7.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e9c50ad5a..889725197 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -26,7 +26,7 @@ jobs: - name: Import GPG Key id: import_gpg - uses: crazy-max/ghaction-import-gpg@cb9bde2e2525e640591a934b1fd28eef1dcaf5e5 # v6.2.0 + uses: crazy-max/ghaction-import-gpg@2dc316deee8e90f13e1a351ab510b4d5bc0c82cd # v7.0.0 with: gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} passphrase: ${{ secrets.PASSPHRASE }} From cc1f013b6e905549130fb2c58a0d2f159fd41ad9 Mon Sep 17 00:00:00 2001 From: Isaac Good Date: Wed, 22 Jul 2026 11:39:27 -0700 Subject: [PATCH 140/142] Bump GHA Ubuntu workflow runners to Ubuntu 26.04 (#1241) --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 889725197..d0803ad5b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -11,7 +11,7 @@ permissions: jobs: goreleaser: - runs-on: ubuntu-22.04 + runs-on: ubuntu-26.04 steps: - name: Checkout code From cfe98f5455b8e4f3263a2b4fbf7bfed8c65b82b9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 6 Aug 2026 12:24:41 +0200 Subject: [PATCH 141/142] Bump actions/checkout from 6.0.2 to 7.0.1 (#1243) Bumps [actions/checkout](https://github.com/actions/checkout) from 6.0.2 to 7.0.1. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/de0fac2e4500dabe0009e67214ff5f5447ce83dd...3d3c42e5aac5ba805825da76410c181273ba90b1) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: 7.0.1 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 4 ++-- .github/workflows/release.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 383e5a5f3..71a87467f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,7 +22,7 @@ jobs: os: [ubuntu-latest, windows-latest, macOS-latest] steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c with: @@ -38,7 +38,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - name: Check formatting run: ./.gha.gofmt.sh diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d0803ad5b..3843976de 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,7 +15,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 From a6e2c53bb97e24c8b30e0b9b91f3e4aeb7508359 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 6 Aug 2026 12:24:56 +0200 Subject: [PATCH 142/142] Bump actions/setup-go from 6.4.0 to 7.0.0 (#1242) Bumps [actions/setup-go](https://github.com/actions/setup-go) from 6.4.0 to 7.0.0. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](https://github.com/actions/setup-go/compare/4a3601121dd01d1626a1e23e37211e3254c1c06c...b7ad1dad31e06c5925ef5d2fc7ad053ef454303e) --- updated-dependencies: - dependency-name: actions/setup-go dependency-version: 7.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- .github/workflows/release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 71a87467f..c6f903425 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,7 @@ jobs: steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c + - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e with: go-version: ${{ matrix.go-version }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3843976de..a28848ea2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -20,7 +20,7 @@ jobs: fetch-depth: 0 - name: Set up Go - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 + uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 with: go-version: '1.26.x'