From e670ff34fa54cc45828eefde93c7ac5e8f9f4ab5 Mon Sep 17 00:00:00 2001 From: Wu Zhenyu Date: Tue, 11 Jul 2023 22:40:39 +0800 Subject: [PATCH 01/21] Fix shebang NixOS doesn't have /bin/bash. Replace it by `/usr/bin/env bash`. --- features/command_name.feature | 2 +- features/result_merging.feature | 2 +- spec/bashcov/runner_spec.rb | 2 +- spec/install_bash.sh | 4 +--- spec/test_app/never_called.sh | 2 +- spec/test_app/scripts/array.sh | 2 +- spec/test_app/scripts/case.sh | 2 +- spec/test_app/scripts/cd.sh | 2 +- spec/test_app/scripts/comments.sh | 2 +- spec/test_app/scripts/delete.sh | 4 ++-- spec/test_app/scripts/executable | 2 +- spec/test_app/scripts/exit_non_zero.sh | 2 +- spec/test_app/scripts/function.sh | 2 +- spec/test_app/scripts/long_line.sh | 2 +- spec/test_app/scripts/multiline.sh | 2 +- spec/test_app/scripts/multiline2.sh | 2 +- spec/test_app/scripts/multiline3.sh | 2 +- spec/test_app/scripts/multiline4.sh | 2 +- spec/test_app/scripts/nested/simple.sh | 2 +- spec/test_app/scripts/no_extension/bin_bash | 2 +- spec/test_app/scripts/no_extension/bin_bash_with_args | 2 +- spec/test_app/scripts/nounset.sh | 2 +- spec/test_app/scripts/one_liner.sh | 2 +- spec/test_app/scripts/process_substitution.sh | 2 +- spec/test_app/scripts/simple.sh | 2 +- spec/test_app/scripts/source.sh | 2 +- spec/test_app/scripts/sourced.txt | 2 +- spec/test_app/scripts/unicode.sh | 2 +- spec/test_app/test_suite.sh | 2 +- test.sh | 2 +- 30 files changed, 31 insertions(+), 33 deletions(-) diff --git a/features/command_name.feature b/features/command_name.feature index 4594624..c5b41d3 100644 --- a/features/command_name.feature +++ b/features/command_name.feature @@ -17,7 +17,7 @@ Feature: And a file named "test.sh" with mode "0755" and with: """ - #!/bin/bash + #!/usr/bin/env bash date """ diff --git a/features/result_merging.feature b/features/result_merging.feature index 839fda4..852643b 100644 --- a/features/result_merging.feature +++ b/features/result_merging.feature @@ -18,7 +18,7 @@ Feature: And a file named "simple.sh" with mode "0755" and with: """ - #!/bin/bash + #!/usr/bin/env bash tr '[[:lower:]]' '[[:upper:]]' <<<'shhh' """ diff --git a/spec/bashcov/runner_spec.rb b/spec/bashcov/runner_spec.rb index 0b8a254..8d295bf 100644 --- a/spec/bashcov/runner_spec.rb +++ b/spec/bashcov/runner_spec.rb @@ -86,7 +86,7 @@ # @note "with a temporary script" context expects +script_text+ to be defined. let(:script_text) do <<-BASH.gsub(/\A\s+/, "") - #!/bin/bash + #!/usr/bin/env bash echo "Hello, world!" LINENO= echo "What line is this?" diff --git a/spec/install_bash.sh b/spec/install_bash.sh index 9e95a73..c98a237 100755 --- a/spec/install_bash.sh +++ b/spec/install_bash.sh @@ -1,6 +1,4 @@ -#!/usr/bin/env bash - -set -ex +#!/usr/bin/env bash -ex if [ -z $INSTALL_BASH_VERSION ]; then echo "No \$INSTALL_BASH_VERSION, using default Bash" diff --git a/spec/test_app/never_called.sh b/spec/test_app/never_called.sh index 38c8e58..fbf795e 100755 --- a/spec/test_app/never_called.sh +++ b/spec/test_app/never_called.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash echo "I'm never executed by any script" diff --git a/spec/test_app/scripts/array.sh b/spec/test_app/scripts/array.sh index 3e23bf7..5ff1fd0 100755 --- a/spec/test_app/scripts/array.sh +++ b/spec/test_app/scripts/array.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash arr=( foo diff --git a/spec/test_app/scripts/case.sh b/spec/test_app/scripts/case.sh index 46b404f..891614b 100755 --- a/spec/test_app/scripts/case.sh +++ b/spec/test_app/scripts/case.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash function switch() { case $1 in diff --git a/spec/test_app/scripts/cd.sh b/spec/test_app/scripts/cd.sh index 7b92a4a..715ae2e 100755 --- a/spec/test_app/scripts/cd.sh +++ b/spec/test_app/scripts/cd.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash : "${this:=that}" : "${that:=thing}" && touch /dev/fd/1 diff --git a/spec/test_app/scripts/comments.sh b/spec/test_app/scripts/comments.sh index dd4b7c3..8242879 100755 --- a/spec/test_app/scripts/comments.sh +++ b/spec/test_app/scripts/comments.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash case "space" in space) # comment diff --git a/spec/test_app/scripts/delete.sh b/spec/test_app/scripts/delete.sh index df6e55c..0e007e2 100755 --- a/spec/test_app/scripts/delete.sh +++ b/spec/test_app/scripts/delete.sh @@ -1,7 +1,7 @@ -#!/bin/bash +#!/usr/bin/env bash cat > tmp.sh <<'BASH' -#!/bin/bash +#!/usr/bin/env bash rm -v $0 BASH diff --git a/spec/test_app/scripts/executable b/spec/test_app/scripts/executable index 0c03ca0..8dfeab2 100755 --- a/spec/test_app/scripts/executable +++ b/spec/test_app/scripts/executable @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash echo "Although I'm extension-less, I am an executable Bash script" diff --git a/spec/test_app/scripts/exit_non_zero.sh b/spec/test_app/scripts/exit_non_zero.sh index 197684e..21e156e 100755 --- a/spec/test_app/scripts/exit_non_zero.sh +++ b/spec/test_app/scripts/exit_non_zero.sh @@ -1,3 +1,3 @@ -#!/bin/bash +#!/usr/bin/env bash exit 21 diff --git a/spec/test_app/scripts/function.sh b/spec/test_app/scripts/function.sh index 895f7c7..2c8e171 100755 --- a/spec/test_app/scripts/function.sh +++ b/spec/test_app/scripts/function.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash function f1 { echo f1 # 2 diff --git a/spec/test_app/scripts/long_line.sh b/spec/test_app/scripts/long_line.sh index ddd9051..7d2cdc6 100755 --- a/spec/test_app/scripts/long_line.sh +++ b/spec/test_app/scripts/long_line.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash echo 1 && \ echo 2 \ diff --git a/spec/test_app/scripts/multiline.sh b/spec/test_app/scripts/multiline.sh index 2134b99..8a18696 100755 --- a/spec/test_app/scripts/multiline.sh +++ b/spec/test_app/scripts/multiline.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # nil if # nil [[ false = true ]] # 1 diff --git a/spec/test_app/scripts/multiline2.sh b/spec/test_app/scripts/multiline2.sh index 5f62c45..c3b8bef 100755 --- a/spec/test_app/scripts/multiline2.sh +++ b/spec/test_app/scripts/multiline2.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash echo ' hello diff --git a/spec/test_app/scripts/multiline3.sh b/spec/test_app/scripts/multiline3.sh index 487d87f..df200b9 100755 --- a/spec/test_app/scripts/multiline3.sh +++ b/spec/test_app/scripts/multiline3.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash echo 1 \ 2 \ diff --git a/spec/test_app/scripts/multiline4.sh b/spec/test_app/scripts/multiline4.sh index a232895..4c38189 100755 --- a/spec/test_app/scripts/multiline4.sh +++ b/spec/test_app/scripts/multiline4.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash var="foo \ bar" diff --git a/spec/test_app/scripts/nested/simple.sh b/spec/test_app/scripts/nested/simple.sh index 145ae81..4f0cdf8 100755 --- a/spec/test_app/scripts/nested/simple.sh +++ b/spec/test_app/scripts/nested/simple.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # basic test program diff --git a/spec/test_app/scripts/no_extension/bin_bash b/spec/test_app/scripts/no_extension/bin_bash index 9357191..0b4e2e9 100755 --- a/spec/test_app/scripts/no_extension/bin_bash +++ b/spec/test_app/scripts/no_extension/bin_bash @@ -1,3 +1,3 @@ -#!/bin/bash +#!/usr/bin/env bash echo "Hello from /bin/bash!" diff --git a/spec/test_app/scripts/no_extension/bin_bash_with_args b/spec/test_app/scripts/no_extension/bin_bash_with_args index cf87860..e4877ea 100755 --- a/spec/test_app/scripts/no_extension/bin_bash_with_args +++ b/spec/test_app/scripts/no_extension/bin_bash_with_args @@ -1,3 +1,3 @@ -#!/bin/bash -eux +#!/usr/bin/env bash -eux echo "Hello from /bin/bash -eux!" diff --git a/spec/test_app/scripts/nounset.sh b/spec/test_app/scripts/nounset.sh index 760bb6c..ac388e9 100755 --- a/spec/test_app/scripts/nounset.sh +++ b/spec/test_app/scripts/nounset.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -o nounset diff --git a/spec/test_app/scripts/one_liner.sh b/spec/test_app/scripts/one_liner.sh index 8e89200..6772369 100755 --- a/spec/test_app/scripts/one_liner.sh +++ b/spec/test_app/scripts/one_liner.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash [ "one" = "two" ] && echo nah || echo yup diff --git a/spec/test_app/scripts/process_substitution.sh b/spec/test_app/scripts/process_substitution.sh index b4be929..7ba9270 100755 --- a/spec/test_app/scripts/process_substitution.sh +++ b/spec/test_app/scripts/process_substitution.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash function print_to_stderr { echo "data" >&2 diff --git a/spec/test_app/scripts/simple.sh b/spec/test_app/scripts/simple.sh index 145ae81..4f0cdf8 100755 --- a/spec/test_app/scripts/simple.sh +++ b/spec/test_app/scripts/simple.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # basic test program diff --git a/spec/test_app/scripts/source.sh b/spec/test_app/scripts/source.sh index f3fd913..7d5b2fe 100755 --- a/spec/test_app/scripts/source.sh +++ b/spec/test_app/scripts/source.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash echo "I'm sourcing sourced.txt" diff --git a/spec/test_app/scripts/sourced.txt b/spec/test_app/scripts/sourced.txt index 3348904..4e25b56 100644 --- a/spec/test_app/scripts/sourced.txt +++ b/spec/test_app/scripts/sourced.txt @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash echo "I'm sourced.txt" diff --git a/spec/test_app/scripts/unicode.sh b/spec/test_app/scripts/unicode.sh index 1b57fc2..6c3993b 100755 --- a/spec/test_app/scripts/unicode.sh +++ b/spec/test_app/scripts/unicode.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # ¹²³ echo 'I am full of unicode characters! äéíóúü¿æ' diff --git a/spec/test_app/test_suite.sh b/spec/test_app/test_suite.sh index 61a071c..8125abc 100755 --- a/spec/test_app/test_suite.sh +++ b/spec/test_app/test_suite.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash echo "UID=${UID}" >&2 echo "PS4=${PS4}" >&2 diff --git a/test.sh b/test.sh index 4f8fb58..36ae173 100755 --- a/test.sh +++ b/test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -euo pipefail From f0bf0a4069f93fe1e05cb7ad4fa0c5c7913a2cd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20F=C3=A9lizard?= Date: Wed, 12 Jul 2023 03:23:03 +0000 Subject: [PATCH 02/21] Fix bugs introduced in https://github.com/infertux/bashcov/pull/72 On most OS, shebangs can only specify a single parameter. --- lib/bashcov/detective.rb | 4 ---- spec/install_bash.sh | 4 +++- spec/test_app/scripts/no_extension/bin_bash_with_args | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/lib/bashcov/detective.rb b/lib/bashcov/detective.rb index d41e27b..204dfd6 100644 --- a/lib/bashcov/detective.rb +++ b/lib/bashcov/detective.rb @@ -8,10 +8,6 @@ class Detective # [Set] Basenames of shell executables SHELL_BASENAMES = Set.new(%w[bash sh ash dash]).freeze - # [Set] Basenames of executables commonly used to +exec+ other - # processes, including shells - OTHER_BASENAMES = Set.new(%w[env]).freeze - # [Set] Filename extensions commonly used for shell scripts SHELLSCRIPT_EXTENSIONS = Set.new(%w[.bash .sh]).freeze diff --git a/spec/install_bash.sh b/spec/install_bash.sh index c98a237..9e95a73 100755 --- a/spec/install_bash.sh +++ b/spec/install_bash.sh @@ -1,4 +1,6 @@ -#!/usr/bin/env bash -ex +#!/usr/bin/env bash + +set -ex if [ -z $INSTALL_BASH_VERSION ]; then echo "No \$INSTALL_BASH_VERSION, using default Bash" diff --git a/spec/test_app/scripts/no_extension/bin_bash_with_args b/spec/test_app/scripts/no_extension/bin_bash_with_args index e4877ea..0c4efa6 100755 --- a/spec/test_app/scripts/no_extension/bin_bash_with_args +++ b/spec/test_app/scripts/no_extension/bin_bash_with_args @@ -1,3 +1,3 @@ -#!/usr/bin/env bash -eux +#!/usr/bin/env -S bash -eux echo "Hello from /bin/bash -eux!" From 1dbbd51664b648495645f96021ea6f32c37e665c Mon Sep 17 00:00:00 2001 From: Matt Schreiber Date: Tue, 28 Jan 2020 14:32:59 -0500 Subject: [PATCH 03/21] feat: initial commit of Nix resources including a definition of the `bashcov` derivation and a `numtide/devshell`-based development shell. --- .gitignore | 5 + Gemfile.lock | 131 ++++++++++++ Gemfile.nix.lock | 131 ++++++++++++ compat.nix | 26 +++ default.nix | 1 + flake.lock | 139 +++++++++++++ flake.nix | 196 ++++++++++++++++++ gemset.nix | 512 +++++++++++++++++++++++++++++++++++++++++++++++ shell.nix | 1 + 9 files changed, 1142 insertions(+) create mode 100644 Gemfile.lock create mode 100644 Gemfile.nix.lock create mode 100644 compat.nix create mode 100644 default.nix create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 gemset.nix create mode 100644 shell.nix diff --git a/.gitignore b/.gitignore index 950ed5b..87a0c6b 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,8 @@ spec/reports test/tmp test/version_tmp tmp + +# Nix output links +result +result-* +repl-result-* diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..dd745e1 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,131 @@ +PATH + remote: . + specs: + bashcov (3.0.3) + simplecov (~> 0.21.2) + +GEM + remote: https://rubygems.org/ + specs: + aruba (2.1.0) + bundler (>= 1.17, < 3.0) + childprocess (>= 2.0, < 5.0) + contracts (>= 0.16.0, < 0.18.0) + cucumber (>= 4.0, < 9.0) + rspec-expectations (~> 3.4) + thor (~> 1.0) + ast (2.4.2) + builder (3.2.4) + bundler-audit (0.9.1) + bundler (>= 1.2.0, < 3) + thor (~> 1.0) + childprocess (4.1.0) + contracts (0.17) + cucumber (8.0.0) + builder (~> 3.2, >= 3.2.4) + cucumber-ci-environment (~> 9.0, >= 9.0.4) + cucumber-core (~> 11.0, >= 11.0.0) + cucumber-cucumber-expressions (~> 15.1, >= 15.1.1) + cucumber-gherkin (~> 23.0, >= 23.0.1) + cucumber-html-formatter (~> 19.1, >= 19.1.0) + cucumber-messages (~> 18.0, >= 18.0.0) + diff-lcs (~> 1.5, >= 1.5.0) + mime-types (~> 3.4, >= 3.4.1) + multi_test (~> 1.1, >= 1.1.0) + sys-uname (~> 1.2, >= 1.2.2) + cucumber-ci-environment (9.2.0) + cucumber-core (11.0.0) + cucumber-gherkin (~> 23.0, >= 23.0.1) + cucumber-messages (~> 18.0, >= 18.0.0) + cucumber-tag-expressions (~> 4.1, >= 4.1.0) + cucumber-cucumber-expressions (15.2.0) + cucumber-gherkin (23.0.1) + cucumber-messages (~> 18.0, >= 18.0.0) + cucumber-html-formatter (19.2.0) + cucumber-messages (~> 18.0, >= 18.0.0) + cucumber-messages (18.0.0) + cucumber-tag-expressions (4.1.0) + diff-lcs (1.5.0) + docile (1.4.0) + ffi (1.15.5) + json (2.6.3) + language_server-protocol (3.17.0.3) + mime-types (3.4.1) + mime-types-data (~> 3.2015) + mime-types-data (3.2023.0218.1) + multi_test (1.1.0) + parallel (1.23.0) + parser (3.2.2.3) + ast (~> 2.4.1) + racc + racc (1.7.1) + rainbow (3.1.1) + rake (13.0.6) + regexp_parser (2.8.1) + rexml (3.2.5) + rspec (3.12.0) + rspec-core (~> 3.12.0) + rspec-expectations (~> 3.12.0) + rspec-mocks (~> 3.12.0) + rspec-core (3.12.2) + rspec-support (~> 3.12.0) + rspec-expectations (3.12.3) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.12.0) + rspec-mocks (3.12.6) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.12.0) + rspec-support (3.12.1) + rubocop (1.54.2) + json (~> 2.3) + language_server-protocol (>= 3.17.0) + parallel (~> 1.10) + parser (>= 3.2.2.3) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 1.8, < 3.0) + rexml (>= 3.2.5, < 4.0) + rubocop-ast (>= 1.28.0, < 2.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 2.4.0, < 3.0) + rubocop-ast (1.29.0) + parser (>= 3.2.1.0) + rubocop-capybara (2.18.0) + rubocop (~> 1.41) + rubocop-factory_bot (2.23.1) + rubocop (~> 1.33) + rubocop-rake (0.6.0) + rubocop (~> 1.0) + rubocop-rspec (2.22.0) + rubocop (~> 1.33) + rubocop-capybara (~> 2.17) + rubocop-factory_bot (~> 2.22) + ruby-progressbar (1.13.0) + simplecov (0.21.2) + docile (~> 1.1) + simplecov-html (~> 0.11) + simplecov_json_formatter (~> 0.1) + simplecov-html (0.12.3) + simplecov_json_formatter (0.1.4) + sys-uname (1.2.3) + ffi (~> 1.1) + thor (1.2.2) + unicode-display_width (2.4.2) + yard (0.9.34) + +PLATFORMS + x86_64-linux + +DEPENDENCIES + aruba + bashcov! + bundler-audit + cucumber + rake + rspec + rubocop + rubocop-rake + rubocop-rspec + yard + +BUNDLED WITH + 2.3.26 diff --git a/Gemfile.nix.lock b/Gemfile.nix.lock new file mode 100644 index 0000000..46edf87 --- /dev/null +++ b/Gemfile.nix.lock @@ -0,0 +1,131 @@ +PATH + remote: . + specs: + bashcov (3.0.3) + simplecov (~> 0.21.2) + +GEM + remote: https://rubygems.org/ + specs: + aruba (2.1.0) + bundler (>= 1.17, < 3.0) + childprocess (>= 2.0, < 5.0) + contracts (>= 0.16.0, < 0.18.0) + cucumber (>= 4.0, < 9.0) + rspec-expectations (~> 3.4) + thor (~> 1.0) + ast (2.4.2) + builder (3.2.4) + bundler-audit (0.9.1) + bundler (>= 1.2.0, < 3) + thor (~> 1.0) + childprocess (4.1.0) + contracts (0.17) + cucumber (8.0.0) + builder (~> 3.2, >= 3.2.4) + cucumber-ci-environment (~> 9.0, >= 9.0.4) + cucumber-core (~> 11.0, >= 11.0.0) + cucumber-cucumber-expressions (~> 15.1, >= 15.1.1) + cucumber-gherkin (~> 23.0, >= 23.0.1) + cucumber-html-formatter (~> 19.1, >= 19.1.0) + cucumber-messages (~> 18.0, >= 18.0.0) + diff-lcs (~> 1.5, >= 1.5.0) + mime-types (~> 3.4, >= 3.4.1) + multi_test (~> 1.1, >= 1.1.0) + sys-uname (~> 1.2, >= 1.2.2) + cucumber-ci-environment (9.2.0) + cucumber-core (11.0.0) + cucumber-gherkin (~> 23.0, >= 23.0.1) + cucumber-messages (~> 18.0, >= 18.0.0) + cucumber-tag-expressions (~> 4.1, >= 4.1.0) + cucumber-cucumber-expressions (15.2.0) + cucumber-gherkin (23.0.1) + cucumber-messages (~> 18.0, >= 18.0.0) + cucumber-html-formatter (19.2.0) + cucumber-messages (~> 18.0, >= 18.0.0) + cucumber-messages (18.0.0) + cucumber-tag-expressions (4.1.0) + diff-lcs (1.5.0) + docile (1.4.0) + ffi (1.15.5) + json (2.6.3) + language_server-protocol (3.17.0.3) + mime-types (3.4.1) + mime-types-data (~> 3.2015) + mime-types-data (3.2023.0218.1) + multi_test (1.1.0) + parallel (1.23.0) + parser (3.2.2.3) + ast (~> 2.4.1) + racc + racc (1.7.1) + rainbow (3.1.1) + rake (13.0.6) + regexp_parser (2.8.1) + rexml (3.2.6) + rspec (3.12.0) + rspec-core (~> 3.12.0) + rspec-expectations (~> 3.12.0) + rspec-mocks (~> 3.12.0) + rspec-core (3.12.2) + rspec-support (~> 3.12.0) + rspec-expectations (3.12.3) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.12.0) + rspec-mocks (3.12.6) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.12.0) + rspec-support (3.12.1) + rubocop (1.55.0) + json (~> 2.3) + language_server-protocol (>= 3.17.0) + parallel (~> 1.10) + parser (>= 3.2.2.3) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 1.8, < 3.0) + rexml (>= 3.2.5, < 4.0) + rubocop-ast (>= 1.28.1, < 2.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 2.4.0, < 3.0) + rubocop-ast (1.29.0) + parser (>= 3.2.1.0) + rubocop-capybara (2.18.0) + rubocop (~> 1.41) + rubocop-factory_bot (2.23.1) + rubocop (~> 1.33) + rubocop-rake (0.6.0) + rubocop (~> 1.0) + rubocop-rspec (2.22.0) + rubocop (~> 1.33) + rubocop-capybara (~> 2.17) + rubocop-factory_bot (~> 2.22) + ruby-progressbar (1.13.0) + simplecov (0.21.2) + docile (~> 1.1) + simplecov-html (~> 0.11) + simplecov_json_formatter (~> 0.1) + simplecov-html (0.12.3) + simplecov_json_formatter (0.1.4) + sys-uname (1.2.3) + ffi (~> 1.1) + thor (1.2.2) + unicode-display_width (2.4.2) + yard (0.9.34) + +PLATFORMS + x86_64-linux + +DEPENDENCIES + aruba + bashcov! + bundler-audit + cucumber + rake + rspec + rubocop + rubocop-rake + rubocop-rspec + yard + +BUNDLED WITH + 2.4.13 diff --git a/compat.nix b/compat.nix new file mode 100644 index 0000000..1e32e28 --- /dev/null +++ b/compat.nix @@ -0,0 +1,26 @@ +let + haveFlakeLock = builtins.pathExists ./flake.lock; + + lock = builtins.fromJSON (builtins.readFile ./flake.lock); + + ref = + if haveFlakeLock + then lock.nodes.flake-compat.locked.rev + else "master"; + + checksum = + if haveFlakeLock + then { + sha256 = lock.nodes.flake-compat.locked.narHash; + } + else {}; + + args = + { + url = "https://github.com/edolstra/flake-compat/archive/${ref}.tar.gz"; + } + // checksum; + + flakeCompat = fetchTarball args; +in + import flakeCompat {src = ./.;} diff --git a/default.nix b/default.nix new file mode 100644 index 0000000..10bfcb5 --- /dev/null +++ b/default.nix @@ -0,0 +1 @@ +(import ./compat.nix).defaultNix diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..29b233b --- /dev/null +++ b/flake.lock @@ -0,0 +1,139 @@ +{ + "nodes": { + "devshell": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ], + "systems": "systems" + }, + "locked": { + "lastModified": 1688380630, + "narHash": "sha256-8ilApWVb1mAi4439zS3iFeIT0ODlbrifm/fegWwgHjA=", + "owner": "numtide", + "repo": "devshell", + "rev": "f9238ec3d75cefbb2b42a44948c4e8fb1ae9a205", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "devshell", + "type": "github" + } + }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1673956053, + "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-parts": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib" + }, + "locked": { + "lastModified": 1688466019, + "narHash": "sha256-VeM2akYrBYMsb4W/MmBo1zmaMfgbL4cH3Pu8PGyIwJ0=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "8e8d955c22df93dbe24f19ea04f47a74adbdc5ec", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1689137672, + "narHash": "sha256-QZoHxr0a73x6rQcAo5CiwYpysHbSnk7lAR8/16um7mM=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "98da3dd0de6660d4abed7bb74e748694bd803413", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-23.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-lib": { + "locked": { + "dir": "lib", + "lastModified": 1688049487, + "narHash": "sha256-100g4iaKC9MalDjUW9iN6Jl/OocTDtXdeAj7pEGIRh4=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "4bc72cae107788bf3f24f30db2e2f685c9298dc9", + "type": "github" + }, + "original": { + "dir": "lib", + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "devshell": "devshell", + "flake-compat": "flake-compat", + "flake-parts": "flake-parts", + "nixpkgs": "nixpkgs", + "treefmt-nix": "treefmt-nix" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "treefmt-nix": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1689070229, + "narHash": "sha256-99VU2FTkEdO3/1Qr78fHWWlN5GaOGLaXDi26PNiUf+I=", + "owner": "numtide", + "repo": "treefmt-nix", + "rev": "3c54278bf7b8642eba174a22ca02d5552c21dc0b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "treefmt-nix", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..f6e6aed --- /dev/null +++ b/flake.nix @@ -0,0 +1,196 @@ +{ + description = "Code coverage tool for Bash"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.05"; + + devshell.url = "github:numtide/devshell"; + devshell.inputs.nixpkgs.follows = "nixpkgs"; + + flake-compat.url = "github:edolstra/flake-compat"; + flake-compat.flake = false; + + flake-parts.url = "github:hercules-ci/flake-parts"; + + treefmt-nix.url = "github:numtide/treefmt-nix"; + treefmt-nix.inputs.nixpkgs.follows = "nixpkgs"; + }; + + outputs = inputs @ { + self, + devshell, + flake-parts, + treefmt-nix, + ... + }: + flake-parts.lib.mkFlake {inherit inputs;} ({lib, ...}: { + systems = [ + "aarch64-darwin" + "aarch64-linux" + "x86_64-darwin" + "x86_64-linux" + ]; + + imports = [ + devshell.flakeModule + flake-parts.flakeModules.easyOverlay + treefmt-nix.flakeModule + ]; + + perSystem = { + config, + pkgs, + self', + system, + ... + }: let + newestRuby = let + rubies = lib.filterAttrs (name: value: let + hasRubyEngine = builtins.tryEval (value ? rubyEngine); + in + lib.hasPrefix "ruby" name && hasRubyEngine.success && hasRubyEngine.value) + pkgs; + + recentRubies = + lib.foldlAttrs ( + acc: name: value: let + v = toString value.version; + in + acc ++ (lib.optional (lib.versionAtLeast v "3" && lib.versionOlder v "4") {inherit name value;}) + ) [] + rubies; + + sortedRubies = lib.sort (x: y: lib.versionAtLeast (toString x.value.version) (toString y.value.version)) recentRubies; + in + if (lib.length sortedRubies) > 0 + then lib.head sortedRubies + else { + name = "ruby"; + value = pkgs.ruby; + }; + + ruby = newestRuby.value; + rubyName = newestRuby.name; + in { + # `nix run '.#devshell' -- update-deps`, etc. + apps.devshell = self'.devShells.default.flakeApp; + + devshells.default = { + commands = [ + { + name = "fmt"; + category = "linting"; + help = "Format the Nix code in this project"; + command = '' + exec ${config.treefmt.build.wrapper}/bin/treefmt "$@" + ''; + } + + { + package = ruby; + category = "development"; + } + + { + package = pkgs.bundix; + category = "maintenance"; + } + + { + name = "update-deps"; + category = "maintenance"; + help = "Update dependencies with Bundler and Bundix"; + command = '' + export NIX_PATH="nixpkgs=${toString pkgs.path}''${NIX_PATH:+:''${NIX_PATH}}" + lockfile="''${PRJ_ROOT:-.}/Gemfile.nix.lock" + bundle lock --lockfile "$lockfile" + exec bundix --ruby ${lib.escapeShellArg rubyName} --lockfile="$lockfile" "$@" + ''; + } + ]; + + # Needed for compiling native extensions + devshell.packages = with pkgs; [gcc gnumake]; + }; + + overlayAttrs = { + inherit (config.packages) bashcov; + }; + + packages = { + bashcov = pkgs.callPackage ({ + lib, + bash, + buildRubyGem, + makeWrapper, + ruby, + gems, + doCheck ? true, # Whether to run RSpec and Cucumber Rake tasks. + }: let + inherit (gems'.gems.bashcov) version; + gems' = gems.override {inherit ruby;}; + gemName = gems'.gems.bashcov.name; + in + assert lib.assertMsg (gems'.gems ? bashcov) "bashcov: gem set must contain `bashcov`"; + buildRubyGem { + inherit doCheck gemName version ruby; + + name = "${gemName}-${version}"; + + src = self; + + nativeBuildInputs = [bash makeWrapper]; + propagatedBuildInputs = [gems']; + + checkPhase = '' + ${config.packages.gems.wrappedRuby}/bin/rake cucumber spec + ''; + + # Replace shebangs like "#!/usr/bin/env bash" with Nix store + # paths. Note that we need to do this for `./bin/bashcov` + # itself, as otherwise running `bashcov` from Cucumber features + # during the check phase will fail because `/usr/bin/env` does + # not exist in the build sandbox. + doPatch = true; + postPatch = '' + patchShebangs ./bin ./features ./spec + ''; + + # Ensure that Bashcov can find Bash, but make this Bash + # low-precedence by placing its /bin/ at the end of PATH. + postInstall = '' + wrapProgram $out/bin/bashcov --suffix PATH : ${bash}/bin + ''; + }) { + inherit ruby; + inherit (config.packages) gems; + }; + + default = config.packages.bashcov; + + gems = pkgs.callPackage ({ + bundlerEnv, + ruby, + }: + bundlerEnv { + inherit ruby; + pname = "bashcov"; + gemdir = self; + lockfile = ./Gemfile.nix.lock; + version = "3.0.2"; + postBuild = '' + for gem in $out/${ruby.gemPath}/bundler/gems/*; do + ln -sfrT "$gem" $out/${ruby.gemPath}/gems/"''${gem##*/}" + done + ''; + }) {inherit ruby;}; + }; + + treefmt = { + programs.alejandra.enable = true; + flakeFormatter = true; + projectRootFile = "flake.nix"; + }; + }; + }); +} diff --git a/gemset.nix b/gemset.nix new file mode 100644 index 0000000..c45b4c2 --- /dev/null +++ b/gemset.nix @@ -0,0 +1,512 @@ +{ + aruba = { + dependencies = ["childprocess" "contracts" "cucumber" "rspec-expectations" "thor"]; + groups = ["development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0fjqhfjkx27h4p8nrhw7snaa4inn3pvjprha5iimjkzhw00xkgbm"; + type = "gem"; + }; + version = "2.1.0"; + }; + ast = { + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "04nc8x27hlzlrr5c2gn7mar4vdr0apw5xg22wp6m8dx3wqr04a0y"; + type = "gem"; + }; + version = "2.4.2"; + }; + bashcov = { + dependencies = ["simplecov"]; + groups = ["default"]; + platforms = []; + source = { + path = ./.; + type = "path"; + }; + version = "3.0.3"; + }; + builder = { + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "045wzckxpwcqzrjr353cxnyaxgf0qg22jh00dcx7z38cys5g1jlr"; + type = "gem"; + }; + version = "3.2.4"; + }; + bundler-audit = { + dependencies = ["thor"]; + groups = ["development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0gdx0019vj04n1512shhdx7hwphzqmdpw4vva2k551nd47y1dixx"; + type = "gem"; + }; + version = "0.9.1"; + }; + childprocess = { + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1lvcp8bsd35g57f7wz4jigcw2sryzzwrpcgjwwf3chmjrjcww5in"; + type = "gem"; + }; + version = "4.1.0"; + }; + contracts = { + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0gfybfsb6kqxvvcrv1q7bfjaxmq73pf3vqy4bbzarkbajil05ii5"; + type = "gem"; + }; + version = "0.17"; + }; + cucumber = { + dependencies = ["builder" "cucumber-ci-environment" "cucumber-core" "cucumber-cucumber-expressions" "cucumber-gherkin" "cucumber-html-formatter" "cucumber-messages" "diff-lcs" "mime-types" "multi_test" "sys-uname"]; + groups = ["development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1ahpifcqv0h5r9cgd97fwr73ps90h50jzi0h17zsaw4ksb3b6g2m"; + type = "gem"; + }; + version = "8.0.0"; + }; + cucumber-ci-environment = { + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0a11b6w6khjb7rw7ksxdw4bprmg9gfc8xdrsbgv8767ri891s4lq"; + type = "gem"; + }; + version = "9.2.0"; + }; + cucumber-core = { + dependencies = ["cucumber-gherkin" "cucumber-messages" "cucumber-tag-expressions"]; + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0drg9w5cz5mchh077y9ixsy7yiyrzg3cqc29mmkl3vjcwlkhn3rh"; + type = "gem"; + }; + version = "11.0.0"; + }; + cucumber-cucumber-expressions = { + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "14xkgpy69p24winh4p5q2b3534i02xxbxl5rn0capqv97qjyj63j"; + type = "gem"; + }; + version = "15.2.0"; + }; + cucumber-gherkin = { + dependencies = ["cucumber-messages"]; + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0dsvcjy78c114q3znacs25zhq3f49q9kkxq4j9iw8b6kwimrl8wj"; + type = "gem"; + }; + version = "23.0.1"; + }; + cucumber-html-formatter = { + dependencies = ["cucumber-messages"]; + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1gnmm1r4gyqqwzx482zsbahjyamnj0lxxky86zs4a376jv9bicyz"; + type = "gem"; + }; + version = "19.2.0"; + }; + cucumber-messages = { + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1i8abkxykq7ab15pirrrf0jz9200i3x3pda2ffyxmck6063lyjgv"; + type = "gem"; + }; + version = "18.0.0"; + }; + cucumber-tag-expressions = { + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0v1ssg4chkahck1ddl2j1hcifm0vlcn9sb104ywshw5gyv59s9qd"; + type = "gem"; + }; + version = "4.1.0"; + }; + diff-lcs = { + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0rwvjahnp7cpmracd8x732rjgnilqv2sx7d1gfrysslc3h039fa9"; + type = "gem"; + }; + version = "1.5.0"; + }; + docile = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1lxqxgq71rqwj1lpl9q1mbhhhhhhdkkj7my341f2889pwayk85sz"; + type = "gem"; + }; + version = "1.4.0"; + }; + ffi = { + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1862ydmclzy1a0cjbvm8dz7847d9rch495ib0zb64y84d3xd4bkg"; + type = "gem"; + }; + version = "1.15.5"; + }; + json = { + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0nalhin1gda4v8ybk6lq8f407cgfrj6qzn234yra4ipkmlbfmal6"; + type = "gem"; + }; + version = "2.6.3"; + }; + language_server-protocol = { + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0gvb1j8xsqxms9mww01rmdl78zkd72zgxaap56bhv8j45z05hp1x"; + type = "gem"; + }; + version = "3.17.0.3"; + }; + mime-types = { + dependencies = ["mime-types-data"]; + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0ipw892jbksbxxcrlx9g5ljq60qx47pm24ywgfbyjskbcl78pkvb"; + type = "gem"; + }; + version = "3.4.1"; + }; + mime-types-data = { + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1pky3vzaxlgm9gw5wlqwwi7wsw3jrglrfflrppvvnsrlaiz043z9"; + type = "gem"; + }; + version = "3.2023.0218.1"; + }; + multi_test = { + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "042d6a1416h3di57z107ygmjdgacrpyswi73ryz75yv3v36m1rg9"; + type = "gem"; + }; + version = "1.1.0"; + }; + parallel = { + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0jcc512l38c0c163ni3jgskvq1vc3mr8ly5pvjijzwvfml9lf597"; + type = "gem"; + }; + version = "1.23.0"; + }; + parser = { + dependencies = ["ast" "racc"]; + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1swigds85jddb5gshll1g8lkmbcgbcp9bi1d4nigwvxki8smys0h"; + type = "gem"; + }; + version = "3.2.2.3"; + }; + racc = { + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "11v3l46mwnlzlc371wr3x6yylpgafgwdf0q7hc7c1lzx6r414r5g"; + type = "gem"; + }; + version = "1.7.1"; + }; + rainbow = { + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0smwg4mii0fm38pyb5fddbmrdpifwv22zv3d3px2xx497am93503"; + type = "gem"; + }; + version = "3.1.1"; + }; + rake = { + groups = ["development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "15whn7p9nrkxangbs9hh75q585yfn66lv0v2mhj6q6dl6x8bzr2w"; + type = "gem"; + }; + version = "13.0.6"; + }; + regexp_parser = { + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "136br91alxdwh1s85z912dwz23qlhm212vy6i3wkinz3z8mkxxl3"; + type = "gem"; + }; + version = "2.8.1"; + }; + rexml = { + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "05i8518ay14kjbma550mv0jm8a6di8yp5phzrd8rj44z9qnrlrp0"; + type = "gem"; + }; + version = "3.2.6"; + }; + rspec = { + dependencies = ["rspec-core" "rspec-expectations" "rspec-mocks"]; + groups = ["development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "171rc90vcgjl8p1bdrqa92ymrj8a87qf6w20x05xq29mljcigi6c"; + type = "gem"; + }; + version = "3.12.0"; + }; + rspec-core = { + dependencies = ["rspec-support"]; + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0l95bnjxdabrn79hwdhn2q1n7mn26pj7y1w5660v5qi81x458nqm"; + type = "gem"; + }; + version = "3.12.2"; + }; + rspec-expectations = { + dependencies = ["diff-lcs" "rspec-support"]; + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "05j44jfqlv7j2rpxb5vqzf9hfv7w8ba46wwgxwcwd8p0wzi1hg89"; + type = "gem"; + }; + version = "3.12.3"; + }; + rspec-mocks = { + dependencies = ["diff-lcs" "rspec-support"]; + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1gq7gviwpck7fhp4y5ibljljvxgjklza18j62qf6zkm2icaa8lfy"; + type = "gem"; + }; + version = "3.12.6"; + }; + rspec-support = { + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1ky86j3ksi26ng9ybd7j0qsdf1lpr8mzrmn98yy9gzv801fvhsgr"; + type = "gem"; + }; + version = "3.12.1"; + }; + rubocop = { + dependencies = ["json" "language_server-protocol" "parallel" "parser" "rainbow" "regexp_parser" "rexml" "rubocop-ast" "ruby-progressbar" "unicode-display_width"]; + groups = ["development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "17c94wl2abqzf4fj469mdxzap1sd3410x421nl6mh2w49jsgvpki"; + type = "gem"; + }; + version = "1.55.0"; + }; + rubocop-ast = { + dependencies = ["parser"]; + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "188bs225kkhrb17dsf3likdahs2p1i1sqn0pr3pvlx50g6r2mnni"; + type = "gem"; + }; + version = "1.29.0"; + }; + rubocop-capybara = { + dependencies = ["rubocop"]; + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "01fn05a87g009ch1sh00abdmgjab87i995msap26vxq1a5smdck6"; + type = "gem"; + }; + version = "2.18.0"; + }; + rubocop-factory_bot = { + dependencies = ["rubocop"]; + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0kqchl8f67k2g56sq2h1sm2wb6br5gi47s877hlz94g5086f77n1"; + type = "gem"; + }; + version = "2.23.1"; + }; + rubocop-rake = { + dependencies = ["rubocop"]; + groups = ["development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1nyq07sfb3vf3ykc6j2d5yq824lzq1asb474yka36jxgi4hz5djn"; + type = "gem"; + }; + version = "0.6.0"; + }; + rubocop-rspec = { + dependencies = ["rubocop" "rubocop-capybara" "rubocop-factory_bot"]; + groups = ["development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "00rsflhijcr0q838fgbdmk7knm5kcjpimn6x0k9qmiw15hi96x1d"; + type = "gem"; + }; + version = "2.22.0"; + }; + ruby-progressbar = { + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0cwvyb7j47m7wihpfaq7rc47zwwx9k4v7iqd9s1xch5nm53rrz40"; + type = "gem"; + }; + version = "1.13.0"; + }; + simplecov = { + dependencies = ["docile" "simplecov-html" "simplecov_json_formatter"]; + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1hrv046jll6ad1s964gsmcq4hvkr3zzr6jc7z1mns22mvfpbc3cr"; + type = "gem"; + }; + version = "0.21.2"; + }; + simplecov-html = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0yx01bxa8pbf9ip4hagqkp5m0mqfnwnw2xk8kjraiywz4lrss6jb"; + type = "gem"; + }; + version = "0.12.3"; + }; + simplecov_json_formatter = { + groups = ["default"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0a5l0733hj7sk51j81ykfmlk2vd5vaijlq9d5fn165yyx3xii52j"; + type = "gem"; + }; + version = "0.1.4"; + }; + sys-uname = { + dependencies = ["ffi"]; + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "03j9qpqip89a0vk6s0gvhxzhbvafjcj5rss7i3jwha0831aivib3"; + type = "gem"; + }; + version = "1.2.3"; + }; + thor = { + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0k7j2wn14h1pl4smibasw0bp66kg626drxb59z7rzflch99cd4rg"; + type = "gem"; + }; + version = "1.2.2"; + }; + unicode-display_width = { + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "1gi82k102q7bkmfi7ggn9ciypn897ylln1jk9q67kjhr39fj043a"; + type = "gem"; + }; + version = "2.4.2"; + }; + yard = { + groups = ["development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "013yrnwx1zhzhn1fnc19zck22a1qgimsaglp2iwgf5bz9l8h93js"; + type = "gem"; + }; + version = "0.9.34"; + }; +} diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000..f248e88 --- /dev/null +++ b/shell.nix @@ -0,0 +1 @@ +(import ./compat.nix).shellNix From a5199a639d27d3211e4c17e2e56de2d3a4814817 Mon Sep 17 00:00:00 2001 From: Matt Schreiber Date: Thu, 13 Jul 2023 09:57:57 -0400 Subject: [PATCH 04/21] fix(gemspec): support Nix build sandbox by not requiring Git for listing the files that should be included in the gem. Instead assume that the entire build sandbox source directory should be included, minus the files in test/, spec/, and features/. --- bashcov.gemspec | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/bashcov.gemspec b/bashcov.gemspec index 219e2ad..17eb131 100644 --- a/bashcov.gemspec +++ b/bashcov.gemspec @@ -23,7 +23,14 @@ Gem::Specification.new do |spec| # Specify which files should be added to the gem when it is released. # The `git ls-files -z` loads the files in the RubyGem that have been added into git. spec.files = Dir.chdir(__dir__) do - `git ls-files -z`.split("\x0").reject do |f| + git_ls_files_z = `git ls-files -z 2>/dev/null` + + # Handle contexts (like the Nix build sandbox) where we are not in a git + # repository -- in such cases, include the entire current directory + # hierarchy. + files = $? == 0 ? git_ls_files_z.split("\x0") : Dir["**/*"] + + files.reject do |f| (File.expand_path(f) == __FILE__) || f.start_with?(*%w[test/ spec/ features/ .git]) end end From 154ae6addc5ccf0146dc431b07b0e0b27fe2e877 Mon Sep 17 00:00:00 2001 From: Matt Schreiber Date: Tue, 28 Jan 2020 14:34:30 -0500 Subject: [PATCH 05/21] fix: allow test scripts to run in Nix sandbox via the following: 1. cd.sh: replace use of HOME with OLDPWD, 2. delete.sh: Use `$BASH` rather than `/usr/bin/env bash` as the interpreter for `tmp.sh`, and 3. Use `-execdir` rather than `-exec` when executing scripts with `find`. --- spec/test_app/scripts/cd.sh | 2 +- spec/test_app/scripts/delete.sh | 6 +++--- spec/test_app/test_suite.sh | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/spec/test_app/scripts/cd.sh b/spec/test_app/scripts/cd.sh index 715ae2e..a16aedf 100755 --- a/spec/test_app/scripts/cd.sh +++ b/spec/test_app/scripts/cd.sh @@ -7,7 +7,7 @@ dir="$(cd "${BASH_SOURCE%/*}" || : ; pwd -P)" todir='' printf -v todir -- '%s' "$(find "$dir" -type d | head -n 1)" -(cd ../.. || : ; cd "$HOME" || : ) +(cd ../.. || : ; cd "$OLDPWD" || :) cd ../.. || : diff --git a/spec/test_app/scripts/delete.sh b/spec/test_app/scripts/delete.sh index 0e007e2..ff47db8 100755 --- a/spec/test_app/scripts/delete.sh +++ b/spec/test_app/scripts/delete.sh @@ -1,8 +1,8 @@ #!/usr/bin/env bash -cat > tmp.sh <<'BASH' -#!/usr/bin/env bash -rm -v $0 +cat > tmp.sh <&2 cd $(dirname $0) -find scripts -type f -perm -111 -print -exec '{}' \; +find scripts -type f -perm -111 -print -execdir '{}' \; From 4a139ff9ef086dc912bba67deda66d8339a91a56 Mon Sep 17 00:00:00 2001 From: Matt Schreiber Date: Thu, 13 Jul 2023 21:31:17 -0400 Subject: [PATCH 06/21] fix: use bash if /bin/bash is not available in order to support systems that do not provide /bin/bash. --- features/command_name.feature | 16 ++++++++++++++-- features/step_definitions/bashcov_steps.rb | 4 ++++ lib/bashcov.rb | 7 +++++-- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/features/command_name.feature b/features/command_name.feature index c5b41d3..03a491c 100644 --- a/features/command_name.feature +++ b/features/command_name.feature @@ -21,9 +21,10 @@ Feature: date """ - Scenario: no explicit command name is provided + Scenario: no explicit command name is provided and /bin/bash is executable + When `/bin/bash` is executable - When I run the following commands with bashcov: + And I run the following commands with bashcov: """ ./test.sh """ @@ -31,6 +32,17 @@ Feature: Then the results should contain the commands: | /bin/bash ./test.sh | + Scenario: no explicit command name is provided and /bin/bash is not executable + When `/bin/bash` is not executable + + And I run the following commands with bashcov: + """ + ./test.sh + """ + + Then the results should contain the commands: + | bash ./test.sh | + Scenario: the command name is set with `--command-name` When I run the following commands with bashcov using `--command-name hey-i-am-a-command`: diff --git a/features/step_definitions/bashcov_steps.rb b/features/step_definitions/bashcov_steps.rb index 53baf66..d490afd 100644 --- a/features/step_definitions/bashcov_steps.rb +++ b/features/step_definitions/bashcov_steps.rb @@ -67,6 +67,10 @@ def simplecov_merged_result ) end +When(/`([^`]+)` is (not )?executable/) do |command, negation| + skip_this_scenario unless !negation.nil? ^ File.executable?(command) +end + Then(/^the results should contain the commands:$/) do |table| commands = table.raw.flatten result_command_names = simplecov_results.map(&:command_name).map { |name| name.split(", ") }.flatten diff --git a/lib/bashcov.rb b/lib/bashcov.rb index df83421..536ffeb 100644 --- a/lib/bashcov.rb +++ b/lib/bashcov.rb @@ -78,8 +78,11 @@ def bash_path # Support the same `BASHCOV_BASH_PATH` environment variable used in the spec tests. return ENV.fetch("BASHCOV_BASH_PATH", nil) unless ENV.fetch("BASHCOV_BASH_PATH", "").empty? - # Fall back to standard Bash location. - "/bin/bash" + # Fall back to standard Bash location, if available. + return "/bin/bash" if File.executable?("/bin/bash") + + # Otherwise, try to execute a Bash from `PATH`. + "bash" end def bash_version From 217175a50d57b33d712c4007afd840d35bc82921 Mon Sep 17 00:00:00 2001 From: Matt Schreiber Date: Thu, 13 Jul 2023 21:33:43 -0400 Subject: [PATCH 07/21] fix: skip spec that needs /bin/bash if it /bin/bash does not exist. --- spec/bashcov_spec.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/bashcov_spec.rb b/spec/bashcov_spec.rb index 5195ff2..7bf3bbc 100644 --- a/spec/bashcov_spec.rb +++ b/spec/bashcov_spec.rb @@ -81,6 +81,7 @@ before { @args += ["--bash-path", "/bin/bash"] } it "sets it properly" do + skip("/bin/bash does not exist") unless File.executable?("/bin/bash") subject expect(described_class.bash_path).to eq("/bin/bash") end From 02efcb5a5bf5bd0c32c21ec6f5ed321df9cce77e Mon Sep 17 00:00:00 2001 From: Matt Schreiber Date: Fri, 14 Jul 2023 22:23:29 -0400 Subject: [PATCH 08/21] fix(detective): restore OTHER_BASENAMES --- lib/bashcov/detective.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/bashcov/detective.rb b/lib/bashcov/detective.rb index 204dfd6..d41e27b 100644 --- a/lib/bashcov/detective.rb +++ b/lib/bashcov/detective.rb @@ -8,6 +8,10 @@ class Detective # [Set] Basenames of shell executables SHELL_BASENAMES = Set.new(%w[bash sh ash dash]).freeze + # [Set] Basenames of executables commonly used to +exec+ other + # processes, including shells + OTHER_BASENAMES = Set.new(%w[env]).freeze + # [Set] Filename extensions commonly used for shell scripts SHELLSCRIPT_EXTENSIONS = Set.new(%w[.bash .sh]).freeze From 9536dfcdc60a753ef066c45e5f9a4defec72abcf Mon Sep 17 00:00:00 2001 From: Matt Schreiber Date: Fri, 14 Jul 2023 22:26:16 -0400 Subject: [PATCH 09/21] fix(features): use /bin/sh for running Aruba cmds as this is available in the Nix sandbox while /usr/bin/env (Aruba's default, used with `/usr/bin/env bash`) is not. --- Gemfile.lock | 131 --------------------- features/step_definitions/bashcov_steps.rb | 3 + 2 files changed, 3 insertions(+), 131 deletions(-) delete mode 100644 Gemfile.lock diff --git a/Gemfile.lock b/Gemfile.lock deleted file mode 100644 index dd745e1..0000000 --- a/Gemfile.lock +++ /dev/null @@ -1,131 +0,0 @@ -PATH - remote: . - specs: - bashcov (3.0.3) - simplecov (~> 0.21.2) - -GEM - remote: https://rubygems.org/ - specs: - aruba (2.1.0) - bundler (>= 1.17, < 3.0) - childprocess (>= 2.0, < 5.0) - contracts (>= 0.16.0, < 0.18.0) - cucumber (>= 4.0, < 9.0) - rspec-expectations (~> 3.4) - thor (~> 1.0) - ast (2.4.2) - builder (3.2.4) - bundler-audit (0.9.1) - bundler (>= 1.2.0, < 3) - thor (~> 1.0) - childprocess (4.1.0) - contracts (0.17) - cucumber (8.0.0) - builder (~> 3.2, >= 3.2.4) - cucumber-ci-environment (~> 9.0, >= 9.0.4) - cucumber-core (~> 11.0, >= 11.0.0) - cucumber-cucumber-expressions (~> 15.1, >= 15.1.1) - cucumber-gherkin (~> 23.0, >= 23.0.1) - cucumber-html-formatter (~> 19.1, >= 19.1.0) - cucumber-messages (~> 18.0, >= 18.0.0) - diff-lcs (~> 1.5, >= 1.5.0) - mime-types (~> 3.4, >= 3.4.1) - multi_test (~> 1.1, >= 1.1.0) - sys-uname (~> 1.2, >= 1.2.2) - cucumber-ci-environment (9.2.0) - cucumber-core (11.0.0) - cucumber-gherkin (~> 23.0, >= 23.0.1) - cucumber-messages (~> 18.0, >= 18.0.0) - cucumber-tag-expressions (~> 4.1, >= 4.1.0) - cucumber-cucumber-expressions (15.2.0) - cucumber-gherkin (23.0.1) - cucumber-messages (~> 18.0, >= 18.0.0) - cucumber-html-formatter (19.2.0) - cucumber-messages (~> 18.0, >= 18.0.0) - cucumber-messages (18.0.0) - cucumber-tag-expressions (4.1.0) - diff-lcs (1.5.0) - docile (1.4.0) - ffi (1.15.5) - json (2.6.3) - language_server-protocol (3.17.0.3) - mime-types (3.4.1) - mime-types-data (~> 3.2015) - mime-types-data (3.2023.0218.1) - multi_test (1.1.0) - parallel (1.23.0) - parser (3.2.2.3) - ast (~> 2.4.1) - racc - racc (1.7.1) - rainbow (3.1.1) - rake (13.0.6) - regexp_parser (2.8.1) - rexml (3.2.5) - rspec (3.12.0) - rspec-core (~> 3.12.0) - rspec-expectations (~> 3.12.0) - rspec-mocks (~> 3.12.0) - rspec-core (3.12.2) - rspec-support (~> 3.12.0) - rspec-expectations (3.12.3) - diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.12.0) - rspec-mocks (3.12.6) - diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.12.0) - rspec-support (3.12.1) - rubocop (1.54.2) - json (~> 2.3) - language_server-protocol (>= 3.17.0) - parallel (~> 1.10) - parser (>= 3.2.2.3) - rainbow (>= 2.2.2, < 4.0) - regexp_parser (>= 1.8, < 3.0) - rexml (>= 3.2.5, < 4.0) - rubocop-ast (>= 1.28.0, < 2.0) - ruby-progressbar (~> 1.7) - unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.29.0) - parser (>= 3.2.1.0) - rubocop-capybara (2.18.0) - rubocop (~> 1.41) - rubocop-factory_bot (2.23.1) - rubocop (~> 1.33) - rubocop-rake (0.6.0) - rubocop (~> 1.0) - rubocop-rspec (2.22.0) - rubocop (~> 1.33) - rubocop-capybara (~> 2.17) - rubocop-factory_bot (~> 2.22) - ruby-progressbar (1.13.0) - simplecov (0.21.2) - docile (~> 1.1) - simplecov-html (~> 0.11) - simplecov_json_formatter (~> 0.1) - simplecov-html (0.12.3) - simplecov_json_formatter (0.1.4) - sys-uname (1.2.3) - ffi (~> 1.1) - thor (1.2.2) - unicode-display_width (2.4.2) - yard (0.9.34) - -PLATFORMS - x86_64-linux - -DEPENDENCIES - aruba - bashcov! - bundler-audit - cucumber - rake - rspec - rubocop - rubocop-rake - rubocop-rspec - yard - -BUNDLED WITH - 2.3.26 diff --git a/features/step_definitions/bashcov_steps.rb b/features/step_definitions/bashcov_steps.rb index d490afd..f46d980 100644 --- a/features/step_definitions/bashcov_steps.rb +++ b/features/step_definitions/bashcov_steps.rb @@ -59,9 +59,12 @@ def simplecov_merged_result options << " --root ." end + # Use `/bin/sh` as the interpreter for maximum portability. None of the + # generated `bashcov` commands should require Bash-specific features. steps %( When I run the following commands: """ + #!/bin/sh #{commands.each_line.map { |command| "bashcov #{options} -- #{command}" }.join("\n")} """ ) From 5930f722ec7726c82861b82c011777f9f2180085 Mon Sep 17 00:00:00 2001 From: Matt Schreiber Date: Fri, 28 Jul 2023 08:40:57 -0400 Subject: [PATCH 10/21] feat(nix): add `bashcov` package to `checks` so that `nix flake check` builds and tests `bashcov`. --- flake.nix | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/flake.nix b/flake.nix index f6e6aed..b63ff8b 100644 --- a/flake.nix +++ b/flake.nix @@ -75,6 +75,10 @@ # `nix run '.#devshell' -- update-deps`, etc. apps.devshell = self'.devShells.default.flakeApp; + checks = { + inherit (config.packages) bashcov; + }; + devshells.default = { commands = [ { From 1a2f749c074d70fbf97c89158e52bab7fadc8926 Mon Sep 17 00:00:00 2001 From: Matt Schreiber Date: Fri, 28 Jul 2023 08:41:43 -0400 Subject: [PATCH 11/21] feat(ci): add `nix` job that runs flake checks --- .github/workflows/ci.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b40d8b8..db92c03 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -76,3 +76,13 @@ jobs: id: yard run: | bundle exec yard stats --list-undoc + nix: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: cachix/install-nix-action@v22 + with: + extra_nix_config: | + system-features = benchmark big-parallel kvm nixos-test uid-range + - name: run flake checks + run: nix flake check -L From 88e7a068eb7356c92e792911cadc59be5f7a524d Mon Sep 17 00:00:00 2001 From: Matt Schreiber Date: Fri, 28 Jul 2023 11:35:12 -0400 Subject: [PATCH 12/21] feat(gitignore): ignore Bundler hierarchy --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 87a0c6b..c7ac408 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,6 @@ tmp result result-* repl-result-* + +# Bundler-installed gems +/vendor/ From aa9e7ec8e9e3c231f341d9c37ebaf1c5e740f8a6 Mon Sep 17 00:00:00 2001 From: Matt Schreiber Date: Fri, 28 Jul 2023 11:35:33 -0400 Subject: [PATCH 13/21] feat(rubocop): ignore git-ignored files --- .rubocop.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/.rubocop.yml b/.rubocop.yml index f50d8ae..1a7853f 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -5,6 +5,26 @@ require: AllCops: TargetRubyVersion: 3.0 NewCops: enable + # Ignore files ignored by Git. Improved version of the template shown here: + # https://docs.rubocop.org/rubocop/configuration.html#pre-processing + # Properly handles symlinks-to-directories, which `git status --ignored + # --porcelain` displays without a trailing slash. + Exclude: + <% git_ignored_file_status = `git status --ignored --porcelain 2>/dev/null` %> + <% if $? == 0 %> + <% git_ignored_file_status.each_line(chomp: true).grep(/^!! /).map { |p| p.sub(/^!! /, '') }.each do |path| %> + <% if File.directory?(path) && ! path.end_with?('/') %> + - <%= path + '/**/*' %> + <% else %> + - <%= path.sub(/\/$/, '/**/*') %> + <% end %> + <% end %> + <% else %> + - 'vendor/**/*' + - 'result/**/*' + - 'result-*/**/*' + - 'repl-result-*/**/*' + <% end %> Metrics: Enabled: false From 63fb2da262588757852d4ef5f0e156c6b7c07f7f Mon Sep 17 00:00:00 2001 From: Matt Schreiber Date: Sun, 30 Jul 2023 09:26:18 -0400 Subject: [PATCH 14/21] docs(changelog): mention addition of Nix support --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a6e8d89..1c0725a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ ## Unreleased ([changes](https://github.com/infertux/bashcov/compare/v3.1.2...master)) - * TBD + * [FEATURE] Support building Bashcov with [the Nix package manager](https://nixos.org) (#78) ## v3.1.2, 2024-02-29 ([changes](https://github.com/infertux/bashcov/compare/v3.1.1...v3.1.2)) From 26ba4c272206173c214df4a5d975ca098516de30 Mon Sep 17 00:00:00 2001 From: Matt Schreiber Date: Sun, 6 Aug 2023 09:47:48 -0400 Subject: [PATCH 15/21] docs: add installation guide that includes information on running Bashcov with Nix --- INSTALL.md | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 2 + 2 files changed, 117 insertions(+) create mode 100644 INSTALL.md diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 0000000..0b7797a --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,115 @@ +# Installing Bashcov + +## Installation as a Ruby gem + +Bashcov is distributed as [a Ruby gem](https://guides.rubygems.org/) -- that +is, as a software package for [the Ruby programming language](https://www.ruby-lang.org/en/). It is hosted on +https://rubygems.org/ and is installable with tools distributed with Ruby +itself. + +### Prerequisites + +- Ruby (installation instructions [here](https://www.ruby-lang.org/en/documentation/installation/)). +- Development tools (primarily, a C compiler and `make`). These are needed + because certain of Bashcov's Ruby gem dependencies include native extensions + that must be compiled for your host platform. Installation instructions are + OS- and distribution-specific; please consult your OS and/or distribution's + documentation. + +### Installation with the `gem` command + +The `gem` executable is included with the Ruby distribution. To install +Bashcov for your current user, run: + +```shell-session +$ gem install bashcov +``` + +Now you can run Bashcov with: + +```shell-session +$ bashcov -- +``` + +### Installation with Bundler + +[Bundler](https://bundler.io/), an environment manager for Ruby, is included in +(quoting the https://bundler.io/ landing page) "[a]ny modern distribution of +Ruby". To install Bashcov with Bundler, create a file named `Gemfile` in your +project's top-level directory and ensure it contains the following: + +```ruby +source 'https://rubygems.org' +gem 'bashcov' +``` + +Then, run this to install Bashcov (and the other gems specified in your +`Gemfile`): + +```shell-session +$ bundle install +``` + +Finally, to run Bashcov, execute: + +```shell-session +$ bundle exec bashcov -- +``` + +For more on Bundler, please see [its "Getting Started" guide](https://bundler.io/guides/getting_started.html#getting-started). + +## Installation with the Nix package manager + +Bashcov is available using [the Nix package manager](https://nixos.org/). +Specifically, Bashcov exposes a [Nix flake](https://nixos.org/) (a sort of +supercharged package) consumable via various subcommands of the `nix` command +line tool. + +### Running Bashcov as [a Nix application](https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-run.html) + +You can use Nix to run Bashcov without first explicitly installing it: + +```shell-session +$ nix run 'github:infertux/bashcov' -- +``` + +### Adding Bashcov to [a Nix shell environment](https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-shell) + +You can start a shell with Bashcov available like so: + +```shell-session +$ command -v bashcov || echo ':(' 1>&2 +:( +$ nix shell 'github:infertux/bashcov' +$ command -v bashcov || echo ':(' 1>&2 +/nix/store/ns3phdbmfxkf6xqbz0lzha0846ngbmwc-bashcov-3.0.2/bin/bashcov +``` + +### Incorporating Bashcov into your Nix flake + +You can incorporate Bashcov into your own flake by declaring it as an input and +then referencing its output attribute `packages..bashcov`. For +instance, to include Bashcov in a [`nix develop` environment](https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-develop), +you could do something like the following: + +```nix +# flake.nix + +{ + inputs = { + bashcov.url = "github:infertux/bashcov"; + bashcov.inputs.nixpkgs.follows = "nixpkgs"; + }; + + outputs = inputs @ { nixpkgs, bashcov, ... }: let + system = "x86_64-linux"; + in { + devShells.${system}.default = nixpkgs.legacyPackages.${system}.mkShell { + packages = [inputs.bashcov.packages.${system}.bashcov]; + }; + }; +} +``` + +Now, when you execute `nix develop` from within your flake project, the +`bashcov` command will be available in your environment. diff --git a/README.md b/README.md index 6b637ac..8f9c439 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,8 @@ Here are example coverages generated by Bashcov: If the `gem` command is unavailable, you need to [install Ruby](https://www.ruby-lang.org/en/documentation/installation/) first. +For more information, including other installation methods, see [`INSTALL.md`](./INSTALL.md). + ## Usage `bashcov --help` prints all available options. Here are some examples: From 8c0337a454901ba2d53536fda97bc6c74e7fde45 Mon Sep 17 00:00:00 2001 From: Matt Schreiber Date: Sun, 6 Aug 2023 09:48:06 -0400 Subject: [PATCH 16/21] feat(devshell): add `update-deps-conservative` which updates `Gemfile.nix.lock` and `gemset.nix` if, and only if, doing so fixes errors running `nix build`. --- flake.nix | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/flake.nix b/flake.nix index b63ff8b..512a143 100644 --- a/flake.nix +++ b/flake.nix @@ -111,6 +111,28 @@ exec bundix --ruby ${lib.escapeShellArg rubyName} --lockfile="$lockfile" "$@" ''; } + + { + name = "update-deps-conservative"; + category = "maintenance"; + help = "Update dependencies with Bundler and Bundix (if necessary)"; + + # If `nix build` succeeds, then presume that the lockfiles do not + # need to be updated. If `nix build` fails after updating the + # lockfile, out-of-date dependencies weren't to blame for the + # build failure. + command = '' + export NIX_PATH="nixpkgs=${toString pkgs.path}''${NIX_PATH:+:''${NIX_PATH}}" + nix build && exit + if update-deps; then + nix build || { + rc="$?" + git restore "''${PRJ_ROOT}/Gemfile.nix.lock" "''${PRJ_ROOT}/gemset.nix" || rc="$?" + exit "$rc" + } + fi + ''; + } ]; # Needed for compiling native extensions From 6db2eaaed322cdda44cebb6d2ab5d3e0f8c1c662 Mon Sep 17 00:00:00 2001 From: Matt Schreiber Date: Sun, 6 Aug 2023 09:49:47 -0400 Subject: [PATCH 17/21] docs: add hacking-on-Bashcov guide --- HACKING.md | 166 +++++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 2 + 2 files changed, 168 insertions(+) create mode 100644 HACKING.md diff --git a/HACKING.md b/HACKING.md new file mode 100644 index 0000000..085426a --- /dev/null +++ b/HACKING.md @@ -0,0 +1,166 @@ +# Hacking on Bashcov + +[Nix development shell]: #entering-the-nix-development-shell +[`Gemfile.nix.lock`]: ./Gemfile.nix.lock +[`gemset.nix`]: ./gemset.nix +[`bashcov.gemspec`]: ./bashcov.gemspec + +## Nix flake usage + +This project supplies a [`flake.nix`](./flake.nix) file defining a Nix +flake[^nix-flakes] that makes it possible to build, test, run, and hack on +Bashcov using the [Nix package manager](https://nixos.org) + +[^nix-flakes]: See the [NixOS wiki](https://nixos.wiki/wiki/Flakes) and the + [`nix flake` page in the Nix package manager reference manual](https://nixos.org/manual/nix/unstable/command-ref/new-cli/nix3-flake.html) + for background on Nix flakes. + +This Nix flake defines three important important outputs: + +1. A [Nix package for Bashcov](#building-the-bashcov-package), +2. A [Nix flake check](#nix-flake-checks) (test) that runs Bashcov's + unit and feature tests, +3. A [Nix application](#running-the-nix-application),[^app] and +4. A [Nix development shell],[^devshell]. + +[^devshell]: Based on the [`numtide/devshell`](https://github.com/numtide/devshell) project. +[^app]: Runnable with `nix run`. + +In order to work on the Bashcov project's Nix features, +you'll need to [install the Nix package manager](https://nixos.org/download.html) and +[ensure that the `flakes` and `nix-command` experimental features are enabled](https://nixos.wiki/wiki/Flakes#Enable_flakes). + +### Building the Bashcov package + +To build the Bashcov package exposed by this flake, run the +following command:[^verbose-output] + +[^verbose-output]: Note that the `-L` flag can be omitted for terser output. + +```shell-session +$ nix build -L '.#' +``` + +Or: + +```shell-session +$ nix build -L '.#bashcov' +``` + +These two forms are functionally equivalent because the +Bashcov package is the default package. + +In addition to building the package, `nix build` will place a symbolic link to +its output path at `./result` (`ls -lAR ./result/`, `tree ./result/`, or +similar to see what the package contains). + +### Nix flake checks + +This project includes a test of Bashcov's functionality and features, exposed +as a Nix flake check. In essence, this runs the Bashcov test suite, but inside +the Nix build environment[^nix-builder-execution] (which may be +sandboxed[^nix-sandbox]). + +[^nix-builder-execution]: The Nix build environment is described [here](https://nixos.org/manual/nix/stable/language/derivations#builder-execution). +[^nix-sandbox]: The Nix sandbox is described [here](https://nixos.org/manual/nix/stable/command-ref/conf-file.html#conf-sandbox). + +This project also includes a test that Nix source files are properly +formatted.[^treefmt-nix-check] + +[^treefmt-nix-check]: Defined by [`treefmt-nix`](https://github.com/numtide/treefmt-nix#flakes). + +#### Running Nix flake checks + +To run Nix flake checks, execute the following command:[^verbose-output] + +```shell-session +$ nix flake check -L +``` + +If a check fails, `nix` will print a diagnostic message and exit with nonzero +status. + +##### Running a check for a specific system + +Running `nix flake check` will execute Nix flake checks for all supported +systems.[^supported-systems] To run a check for a particular system, instead +use the `nix build` command. For instance, to execute the Bashcov unit and +feature tests with Nix on the `x86_64-linux` system, run:[^verbose-output] + +```shell-session +$ nix build -L '.#checks.x86_64-linux.bashcov' +``` + +[^supported-systems]: Run `nix flake show` to view flake outputs namespaced by + all supported systems. + +### Running the Nix application + +To run Bashcov itself: + +```shell-session +$ nix run '.#' -- +``` + +To run commands from [the Nix development shell](#entering-the-nix-development-shell) +but without entering the shell: + +```shell-session +$ nix run '.#devshell' -- +``` + +For instance, to run [the `update-deps` shell command](#summary-of-available-commands): + +```shell-session +$ nix run '.#devshell' -- update-deps +``` + +### Entering the Nix development shell + +To enter the Nix development shell, run the following command: + +```shell-session +$ nix develop +``` + +You will be presented with a menu of commands available within the development +shell. + +#### Summary of available commands + +- `fmt`: format all Nix code in this project using + [`alejandra`](https://github.com/kamadorueda/alejandra). +- `bundix`: tool for managing Nix <=> Ruby integration assets (Bundix lives + [here](https://github.com/nix-community/bundix)). +- `update-deps`: update [the Nix-specific lockfile][`Gemfile.nix.lock`] and + [Nix gemset][`gemset.nix`]. +- `update-deps-conservative`: update [the Nix-specific lockfile][`Gemfile.nix.lock`] + and [Nix gemset][`gemset.nix`] if (and only if) `nix build` fails _without_ + updates to those assets **and** `nix build` succeeds _with_ updates to them. + +### Maintenance of Nix assets + +The Bashcov Nix package depends on [`nixpkgs`'s Ruby +integration](https://nixos.org/manual/nixpkgs/stable/#developing-with-ruby); +specifically, it uses the `bundlerEnv` function to create an environment with +all of Bashcov's Ruby gem dependencies present. `bundlerEnv` requires a +Bundler lockfile (here, [`Gemfile.nix.lock`]) and a Nix-specific [`gemset.nix`] +that acts as a sort of translation layer between Bundler and Nix. + +Both of these files must be updated from time to time in order to reflect +changes in [`bashcov.gemspec`], including certain changes to Bashcov itself +(e.g. version bumps). + +> **Note** +> If [`bashcov.gemspec`] is updated without updating the Bundler lockfile and +> [`gemset.nix`], the Bashcov Nix package will fail to build. + +The [Nix development shell] includes two convenience commands for managing +these assets: + +- `update-deps` unconditionally updates [`Gemfile.nix.lock`] with + [`bundle lock`](https://bundler.io/v2.4/man/bundle-lock.1.html), then updates + [`gemset.nix`] to reflect any changes to the Bundler lockfile. +- `update-deps-conservative` does the same, but if (and only if) doing so fixes + failures running `nix build`. That is, it updates the assets if it looks + like problems with those assets have broken the Bashcov Nix package. diff --git a/README.md b/README.md index 8f9c439..99f4eb5 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,8 @@ See [advanced usage](./USAGE.md) for more information. Bug reports and patches are most welcome. See the [contribution guidelines](https://github.com/infertux/bashcov/blob/master/CONTRIBUTING.md). +For development tips, see [the hacking guide](./HACKING.md). + ## Sponsorship Bashcov was [created in 2012](https://github.com/infertux/bashcov/commit/f65e65e5aa3377beb334beee9924136a34a913e8) and it needs your help. I have been maintaining the project for over a decade and keeping it working with new releases of Bash and Ruby takes time. If you use Bashcov professionally, please considerer supporting it on [Liberapay](https://liberapay.com/infertux) through your employer or directly. Thank you for supporting *Free and Open-Source Software*. From 72225792e7c697b27862dc39154b76f0ccf7f27c Mon Sep 17 00:00:00 2001 From: Matt Schreiber Date: Sun, 6 Aug 2023 09:50:17 -0400 Subject: [PATCH 18/21] feat(ci): add Nix deps update workflow that opens a PR with changes to `Gemfile.nix.lock` and `gemset.nix` if any were made by `update-deps-conservative`. --- .github/workflows/deps.yml | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 .github/workflows/deps.yml diff --git a/.github/workflows/deps.yml b/.github/workflows/deps.yml new file mode 100644 index 0000000..ebde41b --- /dev/null +++ b/.github/workflows/deps.yml @@ -0,0 +1,35 @@ +name: Update Nix dependencies + +on: + schedule: + # Sunday and Wednesday + - cron: '42 4 * * 0,3' + workflow_dispatch: + +jobs: + update-deps-conservative: + runs-on: ubuntu-latest + permissions: + # So that `create-pull-request` can... create a pull request :) + # https://github.com/peter-evans/create-pull-request#action-inputs + contents: write + pull-requests: write + steps: + - uses: actions/checkout@v3 + - uses: cachix/install-nix-action@v22 + with: + extra_nix_config: | + system-features = benchmark big-parallel kvm nixos-test uid-range + - name: update lockfiles + run: nix run '.#devshell' -- update-deps-conservative + - name: create PR + uses: peter-evans/create-pull-request@v5 + with: + branch: create-pull-request/update-nix-deps + title: '[create-pull-request] Update Nix dependencies' + body: | + Update Nix dependencies in `Gemfile.nix.lock` and `gemset.nix`. + + Auto-generated by [create-pull-request][1]. + + [1]: https://github.com/peter-evans/create-pull-request From 010e7318706a285bced7b75698e07333b6a97842 Mon Sep 17 00:00:00 2001 From: Matt Schreiber Date: Sun, 6 Aug 2023 09:51:10 -0400 Subject: [PATCH 19/21] fix(ci): don't fail the build if Nix checks fail as such failures may be due to an out-of-date `Gemfile.nix.lock` and/or `gemset.nix`. --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index db92c03..b276cc4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -78,6 +78,8 @@ jobs: bundle exec yard stats --list-undoc nix: runs-on: ubuntu-latest + # Don't fail the build if this job fails + continue-on-error: true steps: - uses: actions/checkout@v3 - uses: cachix/install-nix-action@v22 From e39c8d42320a78c7c80e3c1997cb64a32ee160c4 Mon Sep 17 00:00:00 2001 From: Matt Schreiber Date: Wed, 17 Apr 2024 23:38:05 -0400 Subject: [PATCH 20/21] chore: update gem dependencies --- Gemfile.nix.lock | 135 +++++++++++++++++------------------ gemset.nix | 181 ++++++++++++++++++++++++----------------------- 2 files changed, 159 insertions(+), 157 deletions(-) diff --git a/Gemfile.nix.lock b/Gemfile.nix.lock index 46edf87..cb7d726 100644 --- a/Gemfile.nix.lock +++ b/Gemfile.nix.lock @@ -1,106 +1,107 @@ PATH remote: . specs: - bashcov (3.0.3) - simplecov (~> 0.21.2) + bashcov (3.1.2) + simplecov (~> 0.22.0) GEM remote: https://rubygems.org/ specs: - aruba (2.1.0) + aruba (2.2.0) bundler (>= 1.17, < 3.0) - childprocess (>= 2.0, < 5.0) contracts (>= 0.16.0, < 0.18.0) - cucumber (>= 4.0, < 9.0) + cucumber (>= 8.0, < 10.0) rspec-expectations (~> 3.4) thor (~> 1.0) ast (2.4.2) + bigdecimal (3.1.7) builder (3.2.4) bundler-audit (0.9.1) bundler (>= 1.2.0, < 3) thor (~> 1.0) - childprocess (4.1.0) contracts (0.17) - cucumber (8.0.0) - builder (~> 3.2, >= 3.2.4) - cucumber-ci-environment (~> 9.0, >= 9.0.4) - cucumber-core (~> 11.0, >= 11.0.0) - cucumber-cucumber-expressions (~> 15.1, >= 15.1.1) - cucumber-gherkin (~> 23.0, >= 23.0.1) - cucumber-html-formatter (~> 19.1, >= 19.1.0) - cucumber-messages (~> 18.0, >= 18.0.0) - diff-lcs (~> 1.5, >= 1.5.0) - mime-types (~> 3.4, >= 3.4.1) - multi_test (~> 1.1, >= 1.1.0) - sys-uname (~> 1.2, >= 1.2.2) - cucumber-ci-environment (9.2.0) - cucumber-core (11.0.0) - cucumber-gherkin (~> 23.0, >= 23.0.1) - cucumber-messages (~> 18.0, >= 18.0.0) - cucumber-tag-expressions (~> 4.1, >= 4.1.0) - cucumber-cucumber-expressions (15.2.0) - cucumber-gherkin (23.0.1) - cucumber-messages (~> 18.0, >= 18.0.0) - cucumber-html-formatter (19.2.0) - cucumber-messages (~> 18.0, >= 18.0.0) - cucumber-messages (18.0.0) - cucumber-tag-expressions (4.1.0) - diff-lcs (1.5.0) + cucumber (9.2.0) + builder (~> 3.2) + cucumber-ci-environment (> 9, < 11) + cucumber-core (> 13, < 14) + cucumber-cucumber-expressions (~> 17.0) + cucumber-gherkin (> 24, < 28) + cucumber-html-formatter (> 20.3, < 22) + cucumber-messages (> 19, < 25) + diff-lcs (~> 1.5) + mini_mime (~> 1.1) + multi_test (~> 1.1) + sys-uname (~> 1.2) + cucumber-ci-environment (10.0.1) + cucumber-core (13.0.2) + cucumber-gherkin (>= 27, < 28) + cucumber-messages (>= 20, < 23) + cucumber-tag-expressions (> 5, < 7) + cucumber-cucumber-expressions (17.1.0) + bigdecimal + cucumber-gherkin (27.0.0) + cucumber-messages (>= 19.1.4, < 23) + cucumber-html-formatter (21.3.1) + cucumber-messages (> 19, < 25) + cucumber-messages (22.0.0) + cucumber-tag-expressions (6.1.0) + diff-lcs (1.5.1) docile (1.4.0) - ffi (1.15.5) - json (2.6.3) + ffi (1.16.3) + json (2.7.2) language_server-protocol (3.17.0.3) - mime-types (3.4.1) - mime-types-data (~> 3.2015) - mime-types-data (3.2023.0218.1) + mini_mime (1.1.5) multi_test (1.1.0) - parallel (1.23.0) - parser (3.2.2.3) + parallel (1.24.0) + parser (3.3.0.5) ast (~> 2.4.1) racc - racc (1.7.1) + racc (1.7.3) rainbow (3.1.1) - rake (13.0.6) - regexp_parser (2.8.1) + rake (13.2.1) + regexp_parser (2.9.0) rexml (3.2.6) - rspec (3.12.0) - rspec-core (~> 3.12.0) - rspec-expectations (~> 3.12.0) - rspec-mocks (~> 3.12.0) - rspec-core (3.12.2) - rspec-support (~> 3.12.0) - rspec-expectations (3.12.3) + rspec (3.13.0) + rspec-core (~> 3.13.0) + rspec-expectations (~> 3.13.0) + rspec-mocks (~> 3.13.0) + rspec-core (3.13.0) + rspec-support (~> 3.13.0) + rspec-expectations (3.13.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.12.0) - rspec-mocks (3.12.6) + rspec-support (~> 3.13.0) + rspec-mocks (3.13.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.12.0) - rspec-support (3.12.1) - rubocop (1.55.0) + rspec-support (~> 3.13.0) + rspec-support (3.13.1) + rubocop (1.63.2) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) - parser (>= 3.2.2.3) + parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 1.8, < 3.0) rexml (>= 3.2.5, < 4.0) - rubocop-ast (>= 1.28.1, < 2.0) + rubocop-ast (>= 1.31.1, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.29.0) - parser (>= 3.2.1.0) - rubocop-capybara (2.18.0) + rubocop-ast (1.31.2) + parser (>= 3.3.0.4) + rubocop-capybara (2.20.0) + rubocop (~> 1.41) + rubocop-factory_bot (2.25.1) rubocop (~> 1.41) - rubocop-factory_bot (2.23.1) - rubocop (~> 1.33) rubocop-rake (0.6.0) rubocop (~> 1.0) - rubocop-rspec (2.22.0) - rubocop (~> 1.33) + rubocop-rspec (2.29.1) + rubocop (~> 1.40) rubocop-capybara (~> 2.17) rubocop-factory_bot (~> 2.22) + rubocop-rspec_rails (~> 2.28) + rubocop-rspec_rails (2.28.3) + rubocop (~> 1.40) ruby-progressbar (1.13.0) - simplecov (0.21.2) + simplecov (0.22.0) docile (~> 1.1) simplecov-html (~> 0.11) simplecov_json_formatter (~> 0.1) @@ -108,9 +109,9 @@ GEM simplecov_json_formatter (0.1.4) sys-uname (1.2.3) ffi (~> 1.1) - thor (1.2.2) - unicode-display_width (2.4.2) - yard (0.9.34) + thor (1.3.1) + unicode-display_width (2.5.0) + yard (0.9.36) PLATFORMS x86_64-linux @@ -128,4 +129,4 @@ DEPENDENCIES yard BUNDLED WITH - 2.4.13 + 2.4.10 diff --git a/gemset.nix b/gemset.nix index c45b4c2..1a270a2 100644 --- a/gemset.nix +++ b/gemset.nix @@ -1,14 +1,14 @@ { aruba = { - dependencies = ["childprocess" "contracts" "cucumber" "rspec-expectations" "thor"]; + dependencies = ["contracts" "cucumber" "rspec-expectations" "thor"]; groups = ["development"]; platforms = []; source = { remotes = ["https://rubygems.org"]; - sha256 = "0fjqhfjkx27h4p8nrhw7snaa4inn3pvjprha5iimjkzhw00xkgbm"; + sha256 = "08rvdags0a0ipadiwg2xqn5ksqnf12jp2768r6g7cm0lhj5wlsdb"; type = "gem"; }; - version = "2.1.0"; + version = "2.2.0"; }; ast = { groups = ["default" "development"]; @@ -28,7 +28,17 @@ path = ./.; type = "path"; }; - version = "3.0.3"; + version = "3.1.2"; + }; + bigdecimal = { + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0cq1c29zbkcxgdihqisirhcw76xc768z2zpd5vbccpq0l1lv76g7"; + type = "gem"; + }; + version = "3.1.7"; }; builder = { groups = ["default" "development"]; @@ -51,16 +61,6 @@ }; version = "0.9.1"; }; - childprocess = { - groups = ["default" "development"]; - platforms = []; - source = { - remotes = ["https://rubygems.org"]; - sha256 = "1lvcp8bsd35g57f7wz4jigcw2sryzzwrpcgjwwf3chmjrjcww5in"; - type = "gem"; - }; - version = "4.1.0"; - }; contracts = { groups = ["default" "development"]; platforms = []; @@ -72,25 +72,25 @@ version = "0.17"; }; cucumber = { - dependencies = ["builder" "cucumber-ci-environment" "cucumber-core" "cucumber-cucumber-expressions" "cucumber-gherkin" "cucumber-html-formatter" "cucumber-messages" "diff-lcs" "mime-types" "multi_test" "sys-uname"]; + dependencies = ["builder" "cucumber-ci-environment" "cucumber-core" "cucumber-cucumber-expressions" "cucumber-gherkin" "cucumber-html-formatter" "cucumber-messages" "diff-lcs" "mini_mime" "multi_test" "sys-uname"]; groups = ["development"]; platforms = []; source = { remotes = ["https://rubygems.org"]; - sha256 = "1ahpifcqv0h5r9cgd97fwr73ps90h50jzi0h17zsaw4ksb3b6g2m"; + sha256 = "19qsfgahkah4k0pajxc04mjn8pig7g4n9nkcarg1nzs2612c29s8"; type = "gem"; }; - version = "8.0.0"; + version = "9.2.0"; }; cucumber-ci-environment = { groups = ["default" "development"]; platforms = []; source = { remotes = ["https://rubygems.org"]; - sha256 = "0a11b6w6khjb7rw7ksxdw4bprmg9gfc8xdrsbgv8767ri891s4lq"; + sha256 = "0cc6w7dqlmnp59ymi7pyspm3w4m7fn37x6b18pziv62wr373yvmv"; type = "gem"; }; - version = "9.2.0"; + version = "10.0.1"; }; cucumber-core = { dependencies = ["cucumber-gherkin" "cucumber-messages" "cucumber-tag-expressions"]; @@ -98,20 +98,21 @@ platforms = []; source = { remotes = ["https://rubygems.org"]; - sha256 = "0drg9w5cz5mchh077y9ixsy7yiyrzg3cqc29mmkl3vjcwlkhn3rh"; + sha256 = "0r00zcgr4lx1vimg7wz9q590bsyylx9i4nfzqzqj92jkp832pdpf"; type = "gem"; }; - version = "11.0.0"; + version = "13.0.2"; }; cucumber-cucumber-expressions = { + dependencies = ["bigdecimal"]; groups = ["default" "development"]; platforms = []; source = { remotes = ["https://rubygems.org"]; - sha256 = "14xkgpy69p24winh4p5q2b3534i02xxbxl5rn0capqv97qjyj63j"; + sha256 = "14fkk7bfzm9cyacgcyzgkjc3nblflz4rcnlyz0pzd1ypwpqrvgm1"; type = "gem"; }; - version = "15.2.0"; + version = "17.1.0"; }; cucumber-gherkin = { dependencies = ["cucumber-messages"]; @@ -119,10 +120,10 @@ platforms = []; source = { remotes = ["https://rubygems.org"]; - sha256 = "0dsvcjy78c114q3znacs25zhq3f49q9kkxq4j9iw8b6kwimrl8wj"; + sha256 = "063p0slf6fvigdn3jynp5pjf9b05byyyi0jhsyapy46hq4984sif"; type = "gem"; }; - version = "23.0.1"; + version = "27.0.0"; }; cucumber-html-formatter = { dependencies = ["cucumber-messages"]; @@ -130,40 +131,40 @@ platforms = []; source = { remotes = ["https://rubygems.org"]; - sha256 = "1gnmm1r4gyqqwzx482zsbahjyamnj0lxxky86zs4a376jv9bicyz"; + sha256 = "0bg0gskpmvhf91g01ywr03ihkv75jr2mk51hcp61wxpvvwp8z8dx"; type = "gem"; }; - version = "19.2.0"; + version = "21.3.1"; }; cucumber-messages = { groups = ["default" "development"]; platforms = []; source = { remotes = ["https://rubygems.org"]; - sha256 = "1i8abkxykq7ab15pirrrf0jz9200i3x3pda2ffyxmck6063lyjgv"; + sha256 = "06d7dnixz68ivngf6qflmi6xrjshjyi85gmyjrl07pbmhqi6r2nh"; type = "gem"; }; - version = "18.0.0"; + version = "22.0.0"; }; cucumber-tag-expressions = { groups = ["default" "development"]; platforms = []; source = { remotes = ["https://rubygems.org"]; - sha256 = "0v1ssg4chkahck1ddl2j1hcifm0vlcn9sb104ywshw5gyv59s9qd"; + sha256 = "1g0fl6v1677q71nkaib2g3p03jdzrwgfanpi96srb1743qd54bk1"; type = "gem"; }; - version = "4.1.0"; + version = "6.1.0"; }; diff-lcs = { groups = ["default" "development"]; platforms = []; source = { remotes = ["https://rubygems.org"]; - sha256 = "0rwvjahnp7cpmracd8x732rjgnilqv2sx7d1gfrysslc3h039fa9"; + sha256 = "1znxccz83m4xgpd239nyqxlifdb7m8rlfayk6s259186nkgj6ci7"; type = "gem"; }; - version = "1.5.0"; + version = "1.5.1"; }; docile = { groups = ["default"]; @@ -180,20 +181,20 @@ platforms = []; source = { remotes = ["https://rubygems.org"]; - sha256 = "1862ydmclzy1a0cjbvm8dz7847d9rch495ib0zb64y84d3xd4bkg"; + sha256 = "1yvii03hcgqj30maavddqamqy50h7y6xcn2wcyq72wn823zl4ckd"; type = "gem"; }; - version = "1.15.5"; + version = "1.16.3"; }; json = { groups = ["default" "development"]; platforms = []; source = { remotes = ["https://rubygems.org"]; - sha256 = "0nalhin1gda4v8ybk6lq8f407cgfrj6qzn234yra4ipkmlbfmal6"; + sha256 = "0b4qsi8gay7ncmigr0pnbxyb17y3h8kavdyhsh7nrlqwr35vb60q"; type = "gem"; }; - version = "2.6.3"; + version = "2.7.2"; }; language_server-protocol = { groups = ["default" "development"]; @@ -205,26 +206,15 @@ }; version = "3.17.0.3"; }; - mime-types = { - dependencies = ["mime-types-data"]; + mini_mime = { groups = ["default" "development"]; platforms = []; source = { remotes = ["https://rubygems.org"]; - sha256 = "0ipw892jbksbxxcrlx9g5ljq60qx47pm24ywgfbyjskbcl78pkvb"; + sha256 = "1vycif7pjzkr29mfk4dlqv3disc5dn0va04lkwajlpr1wkibg0c6"; type = "gem"; }; - version = "3.4.1"; - }; - mime-types-data = { - groups = ["default" "development"]; - platforms = []; - source = { - remotes = ["https://rubygems.org"]; - sha256 = "1pky3vzaxlgm9gw5wlqwwi7wsw3jrglrfflrppvvnsrlaiz043z9"; - type = "gem"; - }; - version = "3.2023.0218.1"; + version = "1.1.5"; }; multi_test = { groups = ["default" "development"]; @@ -241,10 +231,10 @@ platforms = []; source = { remotes = ["https://rubygems.org"]; - sha256 = "0jcc512l38c0c163ni3jgskvq1vc3mr8ly5pvjijzwvfml9lf597"; + sha256 = "15wkxrg1sj3n1h2g8jcrn7gcapwcgxr659ypjf75z1ipkgxqxwsv"; type = "gem"; }; - version = "1.23.0"; + version = "1.24.0"; }; parser = { dependencies = ["ast" "racc"]; @@ -252,20 +242,20 @@ platforms = []; source = { remotes = ["https://rubygems.org"]; - sha256 = "1swigds85jddb5gshll1g8lkmbcgbcp9bi1d4nigwvxki8smys0h"; + sha256 = "11r6kp8wam0nkfvnwyc1fmvky102r1vcfr84vi2p1a2wa0z32j3p"; type = "gem"; }; - version = "3.2.2.3"; + version = "3.3.0.5"; }; racc = { groups = ["default" "development"]; platforms = []; source = { remotes = ["https://rubygems.org"]; - sha256 = "11v3l46mwnlzlc371wr3x6yylpgafgwdf0q7hc7c1lzx6r414r5g"; + sha256 = "01b9662zd2x9bp4rdjfid07h09zxj7kvn7f5fghbqhzc625ap1dp"; type = "gem"; }; - version = "1.7.1"; + version = "1.7.3"; }; rainbow = { groups = ["default" "development"]; @@ -282,20 +272,20 @@ platforms = []; source = { remotes = ["https://rubygems.org"]; - sha256 = "15whn7p9nrkxangbs9hh75q585yfn66lv0v2mhj6q6dl6x8bzr2w"; + sha256 = "17850wcwkgi30p7yqh60960ypn7yibacjjha0av78zaxwvd3ijs6"; type = "gem"; }; - version = "13.0.6"; + version = "13.2.1"; }; regexp_parser = { groups = ["default" "development"]; platforms = []; source = { remotes = ["https://rubygems.org"]; - sha256 = "136br91alxdwh1s85z912dwz23qlhm212vy6i3wkinz3z8mkxxl3"; + sha256 = "1ndxm0xnv27p4gv6xynk6q41irckj76q1jsqpysd9h6f86hhp841"; type = "gem"; }; - version = "2.8.1"; + version = "2.9.0"; }; rexml = { groups = ["default" "development"]; @@ -313,10 +303,10 @@ platforms = []; source = { remotes = ["https://rubygems.org"]; - sha256 = "171rc90vcgjl8p1bdrqa92ymrj8a87qf6w20x05xq29mljcigi6c"; + sha256 = "14xrp8vq6i9zx37vh0yp4h9m0anx9paw200l1r5ad9fmq559346l"; type = "gem"; }; - version = "3.12.0"; + version = "3.13.0"; }; rspec-core = { dependencies = ["rspec-support"]; @@ -324,10 +314,10 @@ platforms = []; source = { remotes = ["https://rubygems.org"]; - sha256 = "0l95bnjxdabrn79hwdhn2q1n7mn26pj7y1w5660v5qi81x458nqm"; + sha256 = "0k252n7s80bvjvpskgfm285a3djjjqyjcarlh3aq7a4dx2s94xsm"; type = "gem"; }; - version = "3.12.2"; + version = "3.13.0"; }; rspec-expectations = { dependencies = ["diff-lcs" "rspec-support"]; @@ -335,10 +325,10 @@ platforms = []; source = { remotes = ["https://rubygems.org"]; - sha256 = "05j44jfqlv7j2rpxb5vqzf9hfv7w8ba46wwgxwcwd8p0wzi1hg89"; + sha256 = "0bhhjzwdk96vf3gq3rs7mln80q27fhq82hda3r15byb24b34h7b2"; type = "gem"; }; - version = "3.12.3"; + version = "3.13.0"; }; rspec-mocks = { dependencies = ["diff-lcs" "rspec-support"]; @@ -346,20 +336,20 @@ platforms = []; source = { remotes = ["https://rubygems.org"]; - sha256 = "1gq7gviwpck7fhp4y5ibljljvxgjklza18j62qf6zkm2icaa8lfy"; + sha256 = "0rkzkcfk2x0qjr5fxw6ib4wpjy0hqbziywplnp6pg3bm2l98jnkk"; type = "gem"; }; - version = "3.12.6"; + version = "3.13.0"; }; rspec-support = { groups = ["default" "development"]; platforms = []; source = { remotes = ["https://rubygems.org"]; - sha256 = "1ky86j3ksi26ng9ybd7j0qsdf1lpr8mzrmn98yy9gzv801fvhsgr"; + sha256 = "03z7gpqz5xkw9rf53835pa8a9vgj4lic54rnix9vfwmp2m7pv1s8"; type = "gem"; }; - version = "3.12.1"; + version = "3.13.1"; }; rubocop = { dependencies = ["json" "language_server-protocol" "parallel" "parser" "rainbow" "regexp_parser" "rexml" "rubocop-ast" "ruby-progressbar" "unicode-display_width"]; @@ -367,10 +357,10 @@ platforms = []; source = { remotes = ["https://rubygems.org"]; - sha256 = "17c94wl2abqzf4fj469mdxzap1sd3410x421nl6mh2w49jsgvpki"; + sha256 = "1dmj955zbvhlrzzag6hc77xdyyzn8ihvffpjalnzn5asxhz7jcdl"; type = "gem"; }; - version = "1.55.0"; + version = "1.63.2"; }; rubocop-ast = { dependencies = ["parser"]; @@ -378,10 +368,10 @@ platforms = []; source = { remotes = ["https://rubygems.org"]; - sha256 = "188bs225kkhrb17dsf3likdahs2p1i1sqn0pr3pvlx50g6r2mnni"; + sha256 = "1v3q8n48w8h809rqbgzihkikr4g3xk72m1na7s97jdsmjjq6y83w"; type = "gem"; }; - version = "1.29.0"; + version = "1.31.2"; }; rubocop-capybara = { dependencies = ["rubocop"]; @@ -389,10 +379,10 @@ platforms = []; source = { remotes = ["https://rubygems.org"]; - sha256 = "01fn05a87g009ch1sh00abdmgjab87i995msap26vxq1a5smdck6"; + sha256 = "0f5r9di123hc4x2h453a143986plfzz9935bwc7267wj8awl8s1a"; type = "gem"; }; - version = "2.18.0"; + version = "2.20.0"; }; rubocop-factory_bot = { dependencies = ["rubocop"]; @@ -400,10 +390,10 @@ platforms = []; source = { remotes = ["https://rubygems.org"]; - sha256 = "0kqchl8f67k2g56sq2h1sm2wb6br5gi47s877hlz94g5086f77n1"; + sha256 = "0d012phc7z5h1j1d2aisnbkmqlb95sld5jriia5qg2gpgbg1nxb2"; type = "gem"; }; - version = "2.23.1"; + version = "2.25.1"; }; rubocop-rake = { dependencies = ["rubocop"]; @@ -417,15 +407,26 @@ version = "0.6.0"; }; rubocop-rspec = { - dependencies = ["rubocop" "rubocop-capybara" "rubocop-factory_bot"]; + dependencies = ["rubocop" "rubocop-capybara" "rubocop-factory_bot" "rubocop-rspec_rails"]; groups = ["development"]; platforms = []; source = { remotes = ["https://rubygems.org"]; - sha256 = "00rsflhijcr0q838fgbdmk7knm5kcjpimn6x0k9qmiw15hi96x1d"; + sha256 = "04rfx0f0ns3vfz16fvbxgc9ivjh6gkpqfdi0qsg3grq660dfhkjk"; + type = "gem"; + }; + version = "2.29.1"; + }; + rubocop-rspec_rails = { + dependencies = ["rubocop"]; + groups = ["default" "development"]; + platforms = []; + source = { + remotes = ["https://rubygems.org"]; + sha256 = "0618lfncmvnvkwa1jb0kga1f2yiiw1809flkj4kg52nagh3z4scp"; type = "gem"; }; - version = "2.22.0"; + version = "2.28.3"; }; ruby-progressbar = { groups = ["default" "development"]; @@ -443,10 +444,10 @@ platforms = []; source = { remotes = ["https://rubygems.org"]; - sha256 = "1hrv046jll6ad1s964gsmcq4hvkr3zzr6jc7z1mns22mvfpbc3cr"; + sha256 = "198kcbrjxhhzca19yrdcd6jjj9sb51aaic3b0sc3pwjghg3j49py"; type = "gem"; }; - version = "0.21.2"; + version = "0.22.0"; }; simplecov-html = { groups = ["default"]; @@ -484,29 +485,29 @@ platforms = []; source = { remotes = ["https://rubygems.org"]; - sha256 = "0k7j2wn14h1pl4smibasw0bp66kg626drxb59z7rzflch99cd4rg"; + sha256 = "1vq1fjp45az9hfp6fxljhdrkv75cvbab1jfrwcw738pnsiqk8zps"; type = "gem"; }; - version = "1.2.2"; + version = "1.3.1"; }; unicode-display_width = { groups = ["default" "development"]; platforms = []; source = { remotes = ["https://rubygems.org"]; - sha256 = "1gi82k102q7bkmfi7ggn9ciypn897ylln1jk9q67kjhr39fj043a"; + sha256 = "1d0azx233nags5jx3fqyr23qa2rhgzbhv8pxp46dgbg1mpf82xky"; type = "gem"; }; - version = "2.4.2"; + version = "2.5.0"; }; yard = { groups = ["development"]; platforms = []; source = { remotes = ["https://rubygems.org"]; - sha256 = "013yrnwx1zhzhn1fnc19zck22a1qgimsaglp2iwgf5bz9l8h93js"; + sha256 = "1r0b8w58p7gy06wph1qdjv2p087hfnmhd9jk23vjdj803dn761am"; type = "gem"; }; - version = "0.9.34"; + version = "0.9.36"; }; } From c910eeb11b52d1cbd29a912fe61132178c63450c Mon Sep 17 00:00:00 2001 From: Matt Schreiber Date: Wed, 17 Apr 2024 23:42:39 -0400 Subject: [PATCH 21/21] feat(devshell): use `language.ruby` profile for (among other things) native extension compilation prerequisites. --- flake.nix | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/flake.nix b/flake.nix index 512a143..b8b9991 100644 --- a/flake.nix +++ b/flake.nix @@ -80,6 +80,12 @@ }; devshells.default = { + imports = [ + # Ruby support, including prerequisites for compiling native + # extensions. + "${inputs.devshell}/extra/language/ruby.nix" + ]; + commands = [ { name = "fmt"; @@ -134,9 +140,6 @@ ''; } ]; - - # Needed for compiling native extensions - devshell.packages = with pkgs; [gcc gnumake]; }; overlayAttrs = {