Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions .github/workflows/completion.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: Shell completion tests

on:
push:
branches: [ master ]
paths:
- 'contrib/completion/**'
- 'complete.go'
- 'completion_shell_test.go'
- 'commands.go'
- 'commands_generate.go'

pull_request:
types: [opened, synchronize, reopened]
paths:
- 'contrib/completion/**'
- 'complete.go'
- 'completion_shell_test.go'
- 'commands.go'
- 'commands_generate.go'

jobs:
completion:
name: bash / zsh / fish completion
runs-on: ubuntu-26.04

steps:
- name: Check out code into the Go module directory
uses: actions/checkout@v6

- name: Dotenv Action
id: dotenv
uses: falti/dotenv-action@v1
with:
path: .github/workflows/env
log-variables: true

- name: Set up Go ${{ steps.dotenv.outputs.go_version }}
uses: actions/setup-go@v6
with:
go-version: ${{ steps.dotenv.outputs.go_version }}
check-latest: true
cache: true

# bash 5.x is already present on ubuntu-latest; bash-completion provides the
# framework restic's bash completion relies on.
- name: Install shells and restic
run: sudo apt-get update && sudo apt-get install -y zsh fish bash-completion restic

- name: Run completion tests
run: make test-completion
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,10 @@ test-race: $(GOBIN)/gotestsum prepare_test test-helpers ## Run unit tests with r
@echo "[*] $@"
@$(GOBIN)/gotestsum -- -short -race -count=1 $(TESTS)

test-completion: test-helpers ## Run shell completion integration tests (needs bash 4+, zsh, fish and restic; each is skipped when absent)
@echo "[*] $@"
@$(GOTEST) -count=1 -v -run 'ShellCompletion' ./

test-ci: export TEST_HELPERS=$(BUILD)
test-ci: $(GOBIN)/gotestsum prepare_test test-helpers ## Run unit tests with coverage (for CI)
@echo "[*] $@"
Expand Down
18 changes: 17 additions & 1 deletion commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (
"fmt"
"io"
"maps"
"os"
"path/filepath"
"regexp"
"slices"
"strconv"
Expand Down Expand Up @@ -199,6 +201,8 @@ func completeCommand(ctx commandContext) error {
requester := "unknown"
requesterVersion := 0

debugCompletion(fmt.Sprintf("args: `%s`", strings.Join(args, "`, `")))

// Parse requester as first argument. Format "[kind]:v[version]", e.g. "bash:v1"
if len(args) > 0 {
matcher := regexp.MustCompile(`^(bash|zsh|fish):v(\d+)$`)
Expand All @@ -217,7 +221,7 @@ func completeCommand(ctx commandContext) error {
}

// Ensure newer completion scripts will not fail on outdated resticprofile
if requester == "zsh" || requesterVersion > 9 {
if requesterVersion > 9 {
return nil
}

Expand All @@ -228,10 +232,22 @@ func completeCommand(ctx commandContext) error {
for _, completion := range completions {
ctx.terminal.Println(completion)
}
debugCompletion(fmt.Sprintf("completions: `%s`", strings.Join(completions, "`, `")))
}
return nil
}

func debugCompletion(line string) {
debugFile := filepath.Clean(os.Getenv("RESTICPROFILE_DEBUG_COMPLETION"))
if debugFile != "" && debugFile != "." {
f, err := os.OpenFile(debugFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err == nil {
defer f.Close()
fmt.Fprintln(f, line)
}
}
}

func showProfileOrGroup(ctx commandContext) error {
c := ctx.config
flags := ctx.flags
Expand Down
2 changes: 1 addition & 1 deletion commands_generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const pathTemplates = "contrib/templates"
//go:embed contrib/completion/bash-completion.sh
var bashCompletionScript string

//go:embed contrib/completion/zsh-completion.sh
//go:embed contrib/completion/zsh-completion.zsh
var zshCompletionScript string

//go:embed contrib/completion/fish-completion.fish
Expand Down
4 changes: 2 additions & 2 deletions commands_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ func TestCompleteCall(t *testing.T) {
{args: []string{"bash:v1", "--"}, expected: expectedFlags},
{args: []string{"fish:v1", "--"}, expected: expectedFlagsWithDescriptions},
{args: []string{"bash:v10", "--"}, expected: ""},
{args: []string{"zsh:v1", "--"}, expected: ""},
{args: []string{"zsh:v1", "--"}, expected: expectedFlags},
}

for _, test := range testTable {
Expand Down Expand Up @@ -238,7 +238,7 @@ func TestGenerateCommand(t *testing.T) {
buffer.Reset()
assert.Nil(t, generateCommand(contextWithArguments([]string{"--zsh-completion"})))
assert.Equal(t, strings.TrimSpace(zshCompletionScript), strings.TrimSpace(buffer.String()))
assert.Contains(t, zshCompletionScript, "#!/usr/bin/env zsh")
assert.Contains(t, zshCompletionScript, "#compdef resticprofile")
})

t.Run("--fish-completion", func(t *testing.T) {
Expand Down
Loading
Loading