From 0b6241abda2b2a2da8cdef98f681bc1467085298 Mon Sep 17 00:00:00 2001 From: Erik Hennig Date: Fri, 8 Nov 2024 22:28:04 +0100 Subject: [PATCH] feat: generate auto-completion in flake build (#65) --- .github/workflows/ci.yml | 7 +++++ flake.nix | 7 +++++ tests/shell_completions.exp | 56 +++++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+) create mode 100755 tests/shell_completions.exp diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e5de8b0..ff9f53b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -77,6 +77,13 @@ jobs: run: ./result/bin/rip --version - name: Test default app run: nix run . -- --help + - name: Test shell completions + run: | + # pre-fetch bash-completion then get its path in the store + nix build nixpkgs#bash-completion + export BASH_COMPLETION_PKG=$(nix path-info nixpkgs#bash-completion) + # use bashInteractive from nixpkgs because default bash is too old for bash-completion on macOS + nix shell . nixpkgs#expect nixpkgs#bash-completion nixpkgs#bashInteractive -c tests/shell_completions.exp release-please: name: Execute release chores diff --git a/flake.nix b/flake.nix index 38c3f1c..2b92f8e 100644 --- a/flake.nix +++ b/flake.nix @@ -18,6 +18,13 @@ naersk' = pkgs.callPackage naersk {}; rip2 = naersk'.buildPackage { src = ./.; + nativeBuildInputs = [ pkgs.installShellFiles ]; + postInstall = '' + installShellCompletion --cmd rip \ + --bash <($out/bin/rip completions bash) \ + --fish <($out/bin/rip completions fish) \ + --zsh <($out/bin/rip completions zsh) + ''; }; in with pkgs; diff --git a/tests/shell_completions.exp b/tests/shell_completions.exp new file mode 100755 index 0000000..e01c1c3 --- /dev/null +++ b/tests/shell_completions.exp @@ -0,0 +1,56 @@ +#!/usr/bin/env expect + +# Script based on https://stackoverflow.com/a/42085887 +# If you are unfamiliar with expect scripts, this guide might be helpful: +# https://gist.github.com/ksafranski/6294378 + +# Disable debug options +log_user 0 +exp_internal 0 + +set prompt_success {0 /@} +set cmd "rip " +set bash_completion_pkg $::env(BASH_COMPLETION_PKG) + +proc line_count {str} { + regexp -all \n $str +} + +# start bash with no startup files for clean env +spawn env INPUTRC=/dev/null {PS1=$? /@} bash --norc --noprofile +expect $prompt_success +# set some readline variables for consistent completion output +send "bind 'set show-all-if-ambiguous on'\r" +expect $prompt_success +send "bind 'set bell-style none'\r" +expect $prompt_success +send "bind 'set completion-query-items -1'\r" +expect $prompt_success +send "bind 'set page-completions off'\r" +expect $prompt_success +send "bind 'set completion-display-width 0'\r" +expect $prompt_success + +# Source bash-completion's basic script which should load rip's completion (when first tab is pressed) +send "source $bash_completion_pkg/etc/profile.d/bash_completion.sh\r" +expect $prompt_success + +# Enter temporary folder to avoid listing files if completion is not loaded properly +set tmp_dir [exec "mktemp" "-d"] +send "cd $tmp_dir\r" +expect $prompt_success + +# run the completion +send "$cmd\t" +expect -re "^$cmd\r\n(.*)\r\n$prompt_success$cmd" { + puts "Completions:\n$expect_out(1,string)\n" + set completion_count [line_count $expect_out(1,string)] + puts "Found $completion_count completions, expecting at least 10" + if {$completion_count > 10} { + exit 0 + } +} + +puts "Failed to generate completions" + +exit 1