Merge branch 'dev'

# Conflicts:
#	README.md
This commit is contained in:
Raphael Reitzig 2023-06-27 00:19:01 +02:00
commit 09607e310b
21 changed files with 663 additions and 169 deletions

30
.github/workflows/release.yml vendored Normal file
View file

@ -0,0 +1,30 @@
name: Release
on:
push:
tags:
- 'v*'
jobs:
release:
name: "Create Release"
runs-on: ubuntu-latest
steps:
- name: Is pre-release?
id: is_pre_release
run: |
version="${GITHUB_REF#refs/tags/}"
if [[ "${version}" =~ -.*$ ]]; then
echo ::set-output name=IS_PRERELEASE::true
else
echo ::set-output name=IS_PRERELEASE::false
fi
- name: Release
uses: docker://antonyurchenko/git-release:v3
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DRAFT_RELEASE: "false"
PRE_RELEASE: ${{ steps.is_pre_release.outputs.IS_PRERELEASE }}
CHANGELOG_FILE: "CHANGELOG.md"
ALLOW_EMPTY_CHANGELOG: "false"
ALLOW_TAG_PREFIX: "true"

102
.github/workflows/test.yml vendored Normal file
View file

@ -0,0 +1,102 @@
name: Tests
on:
push:
pull_request:
types:
- opened
- synchronize
- reopened
jobs:
tests:
name: "Scenarios"
runs-on: ${{ matrix.os }}
strategy:
matrix:
os:
- 'ubuntu-latest'
- 'macos-latest'
steps:
- uses: actions/checkout@v3
# NB: We have a Docker setup for testing -- why do all this?
# Because we want to confirm it runs on macOS, and
# there are no Docker images based on frickin' macOS.
- uses: ruby/setup-ruby@v1
with:
ruby-version: 2.7
- name: Install Test Dependencies
working-directory: test
run: |
gem install bundler
bundle install
- name: Install SDKMAN!
run: |
curl -s "https://get.sdkman.io" | bash
source "$HOME/.sdkman/bin/sdkman-init.sh"
sdk version
- name: Install fish
uses: fish-actions/install-fish@v1.1.0
- name: Install sdkman-for-fish
shell: fish "{0}"
run: |
fish --version
curl -sL https://raw.githubusercontent.com/jorgebucaran/fisher/main/functions/fisher.fish | source \
&& fisher install jorgebucaran/fisher
fisher install .
- name: Confirm install
shell: fish "{0}"
run: |
cat /etc/os-release || sw_vers || true
fish --version
fisher --version
sdk version
- name: Run Tests
working-directory: test
run: |
cucumber --publish-quiet --tags "not @pending"
confirm-installation:
name: "Check fisher install"
runs-on: ${{ matrix.os }}
strategy:
matrix:
os:
- 'ubuntu-22.04'
- 'macos-latest'
steps:
- name: Install fish
uses: fish-actions/install-fish@v1.1.0
- name: Install SDKMAN!
run: |
curl -s "https://get.sdkman.io" | bash
- name: Install fisher
shell: fish "{0}"
run: |
fish --version
curl -sL https://raw.githubusercontent.com/jorgebucaran/fisher/main/functions/fisher.fish | source \
&& fisher install jorgebucaran/fisher
fisher --version
- name: Install sdkman-for-fish
shell: fish "{0}"
run: |
fisher install reitzig/sdkman-for-fish@${{ github.sha }}
- name: Confirm install
shell: fish "{0}"
run: |
cat /etc/os-release || sw_vers || true
fish --version
fisher ls
sdk version

View file

@ -3,12 +3,9 @@
<deployment type="dockerfile">
<settings>
<option name="imageTag" value="sdkman-for-fish-tests" />
<option name="buildCliOptions" value="" />
<option name="command" value="" />
<option name="containerName" value="" />
<option name="containerName" value="sdkman-for-fish-tests" />
<option name="contextFolderPath" value="." />
<option name="entrypoint" value="" />
<option name="commandLineOptions" value="--rm" />
<option name="commandLineOptions" value="" />
<option name="sourceFilePath" value="test/Dockerfile" />
</settings>
</deployment>

View file

@ -1,45 +0,0 @@
matrix:
include:
- dist: bionic
env: FISH=2
addons:
apt:
sources:
- sourceline: "ppa:fish-shell/release-2"
packages:
- fish
- dist: bionic
env: FISH=3
addons:
apt:
sources:
- sourceline: "ppa:fish-shell/release-3"
packages:
- fish
- os: osx
env: FISH=3
addons:
homebrew:
packages:
- fish # --> latest, i.e. >=3.1.2
update: true # TODO: build should be green without, but isn't
before_install:
- curl -s "https://get.sdkman.io" | bash
- bundle install --gemfile=test/Gemfile --no-cache
- |-
uname -a;
fish --version;
{ source ~/.bash_profile || source ~/.bashrc; } && sdk version;
ruby --version;
echo "cucumber $(cucumber --version)";
install:
- |-
mkdir -p "${HOME}"/.config/fish/{completions,conf.d,functions}
cp completions/* "${HOME}"/.config/fish/completions/
cp conf.d/* "${HOME}"/.config/fish/conf.d/
cp functions/* "${HOME}"/.config/fish/functions/
script:
- (cd test && cucumber)

62
CHANGELOG.md Normal file
View file

@ -0,0 +1,62 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and
this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [2.0.0] - upcoming
### Breaking
- Drop (explicit) support for Fish 2
### Features
- Support custom SDKMAN! install path (issue #34)
- Compatibility with SDKMAN! 5.18.2
- Completions for `env`, `home`, `flush` (issue #35)
- Correct behaviour of `env clear`.
- Honor `sdkman_auto_env=true` (issue #38)
- `broadcast` removed
- Compatibility with fisher 4 (PR #37, #39)
## [1.4.0] - 2019-11-06
### Features
- Compatibility with macOS (issue #29)
## [1.3.0] - 2019-11-05
### Features
- Install SDKMAN! if missing (issue #26)
## [1.2.0] - 2019-07-31
### Features
- Compatibility with fish 3 (issue #27)
## [1.1.2] - 2019-01-06
### Fixes
- Re-initialize if user has changed (issue #25)
## [1.1.1] - 2018-11-09
### Fixes
- Set `_HOME` environment variables (issue #24)
## [1.1.0] - 2018-10-08
### Features
- Compatibility with fisher 3 (PR #22)
## [1.0.0] - 2018-07-21
Initial release.

View file

@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2018 Raphael Reitzig
Copyright (c) 2018-2022 Raphael Reitzig
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View file

@ -9,30 +9,40 @@
Makes command `sdk` from [SDKMAN!] usable from [fish], including auto-completion.
Also adds binaries from installed SDKs to the PATH.
Version 1.4.0 tested with
Version 2.0.0 has been tested with
- fish 2.7.1 and 3.1.2, and
- SDKMAN! 5.8.2, on
- Ubuntu 18.04 LTS and macOS 10.13
- fish 3.6.1, and
- SDKMAN! 5.18.2, on
- Ubuntu 22.04 LTS and macOS 12.6
## Install
With [fisher] (install separately):
```
fisher install reitzig/sdkman-for-fish@v1.4.0
fisher install reitzig/sdkman-for-fish@v2.0.0
```
_Note:_
- Only compatible with fisher v3 upwards; v2 is no longer supported.
- Only compatible with fisher v4 upwards; v3 is no longer supported.
- You have to install [SDKMAN!] separately.
- If you have installed SDKMAN! at a custom location, you need to add
```fish
set -g __sdkman_custom_dir /your/path/to/sdkman
```
to a fish config file
[run _before_](https://fishshell.com/docs/current/language.html#configuration-files)
`.config/fish/conf.d/sdk.fish`;
for example, you can use `.config/fish/conf.d/config_sdk.fish`.
## Usage
It's all in the background; you should be able to run `sdk` and binaries installed
with `sdk` as you would expect.
## Contribute
When you make changes,
@ -65,6 +75,7 @@ done
wait
```
## Acknowledgements
* Completion originally by [Ted Wise](https://github.com/ctwise); see his
@ -81,5 +92,3 @@ wait
[SDKMAN!]: https://github.com/sdkman/sdkman-cli
[fish]: https://fishshell.com/
[fisher]: https://github.com/jorgebucaran/fisher
[travis-link]: https://travis-ci.org/reitzig/sdkman-for-fish
[travis-badge]: https://travis-ci.org/reitzig/sdkman-for-fish.svg?branch=master

View file

@ -1,11 +1,11 @@
# Defines autocompletion for SDKMAN!
# Copyright (c) 2018 Raphael Reitzig
# Copyright (c) 2018-2022 Raphael Reitzig
# MIT License (MIT)
# https://github.com/reitzig/sdkman-for-fish
# Guard: SDKMAN! needs to be installed
if not test -f "$HOME/.sdkman/bin/sdkman-init.sh"
if not test -f "$SDKMAN_DIR/bin/sdkman-init.sh"
exit 0
end
@ -165,16 +165,9 @@ complete -c sdk -f -n '__fish_sdkman_no_command' \
complete -c sdk -f -n '__fish_sdkman_command_has_enough_parameters 0 v version'
# block
# broadcast
complete -c sdk -f -n '__fish_sdkman_no_command' \
-a 'b broadcast' \
-d 'Display broadcast message'
complete -c sdk -f -n '__fish_sdkman_command_has_enough_parameters 0 b broadcast'
# block
# help
complete -c sdk -f -n '__fish_sdkman_no_command' \
-a 'h help' \
-a 'help' \
-d 'Display help message'
complete -c sdk -f -n '__fish_sdkman_command_has_enough_parameters 0 h help'
# block
@ -212,15 +205,39 @@ complete -c sdk -f -n '__fish_sdkman_command_has_enough_parameters 0 update'
# flush
complete -c sdk -f -n '__fish_sdkman_no_command' \
-a 'flush' \
-d 'Clear out caches'
complete -c sdk -f -n '__fish_sdkman_using_command flush' \
-a 'broadcast' \
-d 'Re-download news'
complete -c sdk -f -n '__fish_sdkman_using_command flush' \
-a 'archives' \
-d 'Remove downloads'
-d 'Clear out archives and temporary storage folders'
complete -c sdk -f -n '__fish_sdkman_using_command flush' \
-a 'temp' \
-d 'Clear installation prep folder'
-d 'Clear out staging work folder'
complete -c sdk -f -n '__fish_sdkman_using_command flush' \
-a 'version' \
-d 'Flush version file'
complete -c sdk -f -n '__fish_sdkman_command_has_enough_parameters 1 flush'
# block
# env
complete -c sdk -f -n '__fish_sdkman_no_command' \
-a 'e env' \
-d 'Load environment from .sdkmanrc file'
complete -c sdk -f -n '__fish_sdkman_using_command e env' \
-a 'init' \
-d 'Initialize .sdkmanrc file'
complete -c sdk -f -n '__fish_sdkman_using_command e env' \
-a 'install' \
-d 'Install all candidate versions listed in .sdkmanrc'
complete -c sdk -f -n '__fish_sdkman_using_command e env' \
-a 'clear' \
-d 'Unload currently loaded environment'
complete -c sdk -f -n '__fish_sdkman_command_has_enough_parameters 1 e env'
# block
# home
complete -c sdk -f -n '__fish_sdkman_no_command' \
-a 'h home' \
-d 'Show installation folder of given candidate'
complete -c sdk -f -n '__fish_sdkman_using_command h home' \
-a "(__fish_sdkman_candidates_with_versions)"
complete -c sdk -f -n '__fish_sdkman_specifying_candidate h home' \
-a "(__fish_sdkman_installed_versions)"
complete -c sdk -f -n '__fish_sdkman_command_has_enough_parameters 2 h home'
# block

View file

@ -3,12 +3,23 @@
# Makes command and binaries from SDKMAN! available in fish.
# Delegates to bash for the `sdk` command.
# Copyright (c) 2018 Raphael Reitzig
# Copyright (c) 2018-2022 Raphael Reitzig
# MIT License (MIT)
# https://github.com/reitzig/sdkman-for-fish
set __fish_sdkman_init "$HOME/.sdkman/bin/sdkman-init.sh"
set __fish_sdkman_noexport_init "$HOME/.config/fisher/github.com/reitzig/sdkman-for-fish/sdkman-noexport-init.sh"
# Account for custom install locations
if set -q __sdkman_custom_dir
set -gx SDKMAN_DIR "$__sdkman_custom_dir"
else
# This is the default location:
set -gx SDKMAN_DIR "$HOME/.sdkman"
end
set __fish_sdkman_init "$SDKMAN_DIR/bin/sdkman-init.sh"
# Copied from https://github.com/jorgebucaran/fisher/blob/main/functions/fisher.fish to be consistent:
set --query fisher_path || set --local fisher_path $__fish_config_dir
set __fish_sdkman_noexport_init "$fisher_path/functions/__sdkman-noexport-init.sh"
# Guard: SDKMAN! needs to be installed
if not test -f "$__fish_sdkman_init"
@ -42,7 +53,8 @@ function __fish_sdkman_run_in_bash
echo -e \"\$?\" > $pipe;
env | grep -e '^SDKMAN_\|^PATH' >> $pipe;
env | grep -i -E \"^(`echo \${SDKMAN_CANDIDATES_CSV} | sed 's/,/|/g'`)_HOME\" >> $pipe;
echo \"SDKMAN_OFFLINE_MODE=\${SDKMAN_OFFLINE_MODE}\" >> $pipe" # it's not an environment variable!
echo \"SDKMAN_OFFLINE_MODE=\${SDKMAN_OFFLINE_MODE}\" >> $pipe;
echo \"SDKMAN_ENV=\${SDKMAN_ENV}\" >> $pipe" # it's not an environment variable!
set bashDump (cat $pipe; rm $pipe)
set sdkStatus $bashDump[1]
@ -65,7 +77,7 @@ function __fish_sdkman_run_in_bash
if test -n value
set -gx $var $value
# Note: This makes SDKMAN_OFFLINE_MODE an environment variable.
# Note: This makes SDKMAN_{OFFLINE_MODE,ENV} environment variables.
# That gives it the behaviour we _want_!
end
end
@ -77,8 +89,16 @@ end
# If this is a subshell of a(n initialized) fish owned by the same user,
# no initialization necessary.
# Otherwise:
if not set -q SDKMAN_DIR; or test (ls -ld "$SDKMAN_DIR" | awk '{print $3}') != (whoami)
set -e SDKMAN_DIR
if not set -q SDKMAN_CANDIDATES_DIR; or test (ls -ld "$SDKMAN_CANDIDATES_DIR" | awk '{print $3}') != (whoami)
__fish_sdkman_run_in_bash "source $__fish_sdkman_init"
end
# Set up auto_env
if grep -q "^sdkman_auto_env=true" "$SDKMAN_DIR/etc/config"
function __fish_sdkman_autoenv --on-variable PWD
# Run the (modified) init script, which performs the checks and calls for us!
__fish_sdkman_run_in_bash "source \"$__fish_sdkman_noexport_init\""
set -x SDKMAN_OLD_PWD "$PWD" # needed by the Bash implementation
end
end

View file

@ -1,13 +1,19 @@
FROM ruby:2.5.8-slim-buster
FROM ubuntu
# Install dependencies
RUN apt-get update \
&& apt-get -y install \
fish \
build-essential \
curl \
fish \
nano \
ruby \
ruby-dev \
tree \
unzip \
zip \
&& apt-get clean
&& apt-get clean \
&& gem install bundler
WORKDIR app
COPY test/Gemfile ./
@ -22,11 +28,13 @@ USER test
RUN curl -s "https://get.sdkman.io" | bash
# To speed up tests, uncomment this shared setup:
#SHELL ["/bin/bash", "-c"]
#RUN source "$TEST_HOME/.sdkman/bin/sdkman-init.sh" \
# && sdk install ant 1.9.9 \
# && sdk install ant 1.10.1 \
# && sdk install crash
SHELL ["/bin/bash", "-c"]
RUN source "$TEST_HOME/.sdkman/bin/sdkman-init.sh" \
&& sdk install ant 1.9.7 \
&& sdk install ant 1.9.9 \
&& sdk install ant 1.10.1 \
&& sdk install kscript 1.5.0 \
&& sdk install kscript 1.6.0
# "Install" sdkman-for-fish
RUN mkdir -p $TEST_HOME/.config/fish/
@ -38,4 +46,4 @@ RUN ls -R $TEST_HOME/.config/fish/
# Run tests
COPY test ./
ENTRYPOINT ["cucumber"]
CMD []
CMD ["--publish-quiet", "--tags", "not @pending"]

View file

@ -1,6 +1,6 @@
source "https://rubygems.org"
group :test do
gem 'cucumber', '~> 3.1.0'
gem 'rspec', '~> 3.7.0'
gem 'cucumber', '~> 5'
gem 'rspec', '~> 3'
end

View file

@ -0,0 +1,84 @@
Feature: Support autoenv setting
When the user sets `sdkman_auto_env=true`, we should always `use` the
candidates specified in `./.sdkmanrc`, if any.
Background:
Given SDKMAN! candidate list is up to date
And candidate ant is installed at version 1.9.7
And candidate ant is installed at version 1.9.9
And candidate ant is installed at version 1.10.1
And candidate kscript is installed at version 1.5.0
And candidate kscript is installed at version 1.6.0
Scenario: No action if autoenv turned off
Given SDKMAN! config sets sdkman_auto_env to false
And file /tmp/autoenv-test/.sdkmanrc exists with content
"""
ant=1.9.9
"""
When we run fish script
"""
echo (basename (realpath $ANT_HOME)) > /tmp/autoenv-test.log
cd /tmp/autoenv-test
echo (basename (realpath $ANT_HOME)) >> /tmp/autoenv-test.log
cd ..
echo (basename (realpath $ANT_HOME)) >> /tmp/autoenv-test.log
"""
Then file /tmp/autoenv-test.log contains
"""
1.10.1
1.10.1
1.10.1
"""
Scenario: .sdkmanrc loaded if autoenv turned on
Given SDKMAN! config sets sdkman_auto_env to true
And file /tmp/autoenv-test/.sdkmanrc exists with content
"""
ant=1.9.9
"""
When we run fish script
"""
echo (basename (realpath $ANT_HOME)) > /tmp/autoenv-test.log
cd /tmp/autoenv-test
echo (basename (realpath $ANT_HOME)) >> /tmp/autoenv-test.log
cd ..
echo (basename (realpath $ANT_HOME)) >> /tmp/autoenv-test.log
"""
Then file /tmp/autoenv-test.log contains
"""
1.10.1
1.9.9
1.10.1
"""
# TODO: But that PR had been merged back when -- re-investigate
@pending # This one doesn't work due to a bug in sdkman. Track: https://github.com/sdkman/sdkman-cli/pull/878
Scenario: Switching between directories with .sdkmanrc
Given SDKMAN! config sets sdkman_auto_env to true
And file /tmp/autoenv-test-1/.sdkmanrc exists with content
"""
ant=1.9.9
kscript=1.5.0
"""
And file /tmp/autoenv-test-2/.sdkmanrc exists with content
"""
ant=1.9.7
"""
When we run fish script
"""
echo (basename (realpath $ANT_HOME)),(basename (realpath $KSCRIPT_HOME)) > /tmp/autoenv-test.log
cd /tmp/autoenv-test-1
echo (basename (realpath $ANT_HOME)),(basename (realpath $KSCRIPT_HOME)) >> /tmp/autoenv-test.log
cd ../autoenv-test-2
echo (basename (realpath $ANT_HOME)),(basename (realpath $KSCRIPT_HOME)) >> /tmp/autoenv-test.log
cd ..
echo (basename (realpath $ANT_HOME)),(basename (realpath $KSCRIPT_HOME)) >> /tmp/autoenv-test.log
"""
Then file /tmp/autoenv-test.log contains
"""
1.10.1,1.6.0
1.9.9,1.5.0
1.9.7,1.6.0
1.10.1,1.6.0
"""

View file

@ -5,11 +5,11 @@ Feature: Shell Completion
Given SDKMAN! candidate list is up to date
And candidate ant is installed at version 1.9.9
And candidate ant is installed at version 1.10.1
And candidate crash is installed
And candidate kscript is installed
Scenario: Command list correct
When the user enters " " into the prompt
Then completion should propose "b, broadcast, c, current, d, default, flush, h, help, i, install, list, ls, offline, rm, selfupdate, u, ug, uninstall, update, upgrade, use, v, version"
Then completion should propose "c, current, d, default, flush, h, help, i, install, list, ls, offline, rm, selfupdate, u, ug, uninstall, update, upgrade, use, v, version"
Scenario Outline: Commands complete
When the user enters "<cmd>" into the prompt
@ -17,11 +17,13 @@ Feature: Shell Completion
But completion should not propose <exclusions>
Examples:
| cmd | completions | exclusions |
| b | b, broadcast | /^[^b]+$/ |
| c | c, current | /^[^c]+$/ |
| d | d, default | /^[^d]+$/ |
| e | e, env | /^[^e]+$/ |
| f | flush | /^[^f]+$/ |
| h | h, help | /^[^h]+$/ |
| h | h, help, home | /^[^h]+$/ |
| he | help | |
| ho | home | |
| i | i, install | /^[^i]+$/ |
| in | install | |
| l | list, ls | /^[^l]+$/ |
@ -36,7 +38,7 @@ Feature: Shell Completion
# Currently uncovered (except by fuzzy matches);
# include negatives to prevent accidents:
| a | | /^a/ |
| e | | /^e/ |
| b | | /^b/ |
| g | | /^g/ |
| j | | /^j/ |
| k | | /^k/ |
@ -72,19 +74,19 @@ Feature: Shell Completion
Then completion should propose "<completions>"
But completion should not propose <exclusions>
Examples:
| cmd | completions | exclusions |
| | ant, crash | gradle |
| a | ant | gradle |
| j | | /.*/ |
| 1. | | /.*/ |
| an | ant | gradle, crash | # some installed
| gr | | /.*/ | # none installed
| xyz | | /.*/ | # no such candidate
| 'an ' | | /.*/ | # no such candidate installed
| 'ant 1' | 1.10.1, 1.9.9 | /^\w+$/ |
| 'ant 1.10.' | 1.10.1 | 1.9.9 |
| 'ant 2' | | /.*/ |
| 'ant 1.10.1 ' | | /.*/ | # only one version at a time
| cmd | completions | exclusions |
| | ant, kscript | gradle |
| a | ant | gradle |
| j | | /.*/ |
| 1. | | /.*/ |
| an | ant | gradle, kscript | # some installed
| gr | | /.*/ | # none installed
| xyz | | /.*/ | # no such candidate
| 'an ' | | /.*/ | # no such candidate installed
| 'ant 1' | 1.10.1, 1.9.9 | /^\w+$/ |
| 'ant 1.10.' | 1.10.1 | 1.9.9 |
| 'ant 2' | | /.*/ |
| 'ant 1.10.1 ' | | /.*/ | # only one version at a time
Scenario Outline: Completion for 'list'
When the user enters "list <cmd>" into the prompt
@ -92,7 +94,7 @@ Feature: Shell Completion
But completion should not propose <exclusions>
Examples:
| cmd | completions | exclusions |
| an | ant | crash |
| an | ant | kscript |
| xyz | | /.*/ |
| 1. | | /.*/ |
| 'ant ' | | /.*/ |
@ -102,26 +104,55 @@ Feature: Shell Completion
Then completion should propose "<completions>"
But completion should not propose <exclusions>
Examples:
| cmd | completions | exclusions |
| | ant, crash | gradle |
| an | ant | crash, gradle |
| j | | /.*/ |
| 1. | | /.*/ |
| 'ant ' | 1.10.1, 1.9.9 | /^\w+$/ |
| 'ant 1.10.1 ' | | /.*/ |
| cmd | completions | exclusions |
| | ant, kscript | gradle |
| an | ant | kscript, gradle |
| j | | /.*/ |
| 1. | | /.*/ |
| 'ant ' | 1.10.1, 1.9.9 | /^\w+$/ |
| 'ant 1.10.1 ' | | /.*/ |
Scenario Outline: Completion for 'default'
When the user enters "default <cmd>" into the prompt
Then completion should propose "<completions>"
But completion should not propose <exclusions>
Examples:
| cmd | completions | exclusions |
| | ant, crash | gradle |
| an | ant | crash, gradle |
| j | | /.*/ |
| 1. | | /.*/ |
| 'ant ' | 1.10.1, 1.9.9 | /^\w+$/ |
| 'ant 1.10.1 ' | | /.*/ |
| cmd | completions | exclusions |
| | ant, kscript | gradle |
| an | ant | kscript, gradle |
| j | | /.*/ |
| 1. | | /.*/ |
| 'ant ' | 1.10.1, 1.9.9 | /^\w+$/ |
| 'ant 1.10.1 ' | | /.*/ |
Scenario Outline: Completion for 'home'
When the user enters "home <cmd>" into the prompt
Then completion should propose "<completions>"
But completion should not propose <exclusions>
Examples:
| cmd | completions | exclusions |
| | ant, kscript | gradle |
| an | ant | kscript, gradle |
| j | | /.*/ |
| 1. | | /.*/ |
| 'ant ' | 1.10.1, 1.9.9 | /^\w+$/ |
| 'ant 1.10.1 ' | | /.*/ |
Scenario Outline: Completion for 'env'
When the user enters "env <cmd>" into the prompt
Then completion should propose "<completions>"
But completion should not propose <exclusions>
Examples:
| cmd | completions | exclusions |
| | init, install, clear | /^(?!init\|install\|clear).*$/ |
| i | init, install | /^(?!init\|install).*$/ |
| ini | init | /^(?!init).*$/ |
| ins | install | /^(?!install).*$/ |
| c | clear | /^(?!clear).*$/ |
| b | | /.*/ |
| 'init ' | | /.*/ |
| 'clear ' | | /.*/ |
| 'install ' | | /.*/ |
Scenario Outline: Completion for 'current'
When the user enters "current <cmd>" into the prompt
@ -140,12 +171,12 @@ Feature: Shell Completion
Then completion should propose "<completions>"
But completion should not propose <exclusions>
Examples:
| cmd | completions | exclusions |
| | ant, crash | gradle |
| an | ant | crash, gradle |
| j | | /.*/ |
| 1. | | /.*/ |
| 'ant ' | | /^\w+$/ |
| cmd | completions | exclusions |
| | ant, kscript | gradle |
| an | ant | kscript, gradle |
| j | | /.*/ |
| 1. | | /.*/ |
| 'ant ' | | /^\w+$/ |
Scenario Outline: Completion for 'offline'
When the user enters "offline <cmd>" into the prompt
@ -175,25 +206,21 @@ Feature: Shell Completion
Then completion should propose "<completions>"
But completion should not propose <exclusions>
Examples:
| cmd | completions | exclusions |
| | archives, broadcast, temp | /^(?!archives\|broadcast\|temp).*$/ |
| b | broadcast | /^(?!broadcast).*$/ |
| a | archives | /^(?!archives\|broadcast).*$/ |
| t | temp | /^(?!temp\|broadcast).*$/ |
| x | | /.*/ |
| 'temp ' | | /.*/ |
| cmd | completions | exclusions |
| | temp, version | /^(?!temp\|version).*$/ |
| t | temp | /^(?!temp).*$/ |
| v | version | /^(?!version).*$/ |
| x | | /.*/ |
| 'tmp ' | | /.*/ |
Scenario Outline: Completion for commands without parameters
When the user enters "<cmd>" into the prompt
Then completion should not propose /.*/
Examples:
| cmd |
| 'version ' |
| 'version a' |
| 'broadcast ' |
| 'broadcast a' |
| 'help ' |
| 'help a' |
| 'update ' |
| 'update a' |
| cmd |
| 'version ' |
| 'version a' |
| 'help ' |
| 'help a' |
| 'update ' |
| 'update a' |

View file

@ -6,13 +6,27 @@ Feature: Corner Cases
Then environment variable SDKMAN_DIR has the original value
Scenario: sdk initialized for another user in this shell
# Use any directory outside of the user's home directory
Given environment variable SDKMAN_DIR is set to "/"
When a new Fish shell is launched
Then environment variable SDKMAN_DIR has the original value
# TODO: add test that fails if `test` in conf.d/sdk.fish:80 errors (cf issue #28 et al.)
Scenario: Custom installation path
Given SDKMAN! is installed at /tmp/sdkman
And fish config file config_sdk.fish exists with content
"""
set -g __sdkman_custom_dir /tmp/sdkman
"""
When we run "sdk version" in Fish
Then the exit code is 0
And the output contains "SDKMAN!"
And environment variable SDKMAN_DIR has value "/tmp/sdkman"
And environment variable ANT_HOME has value "/tmp/sdkman/candidates/ant/current"
@pending # cf. issue #10
Scenario: PATH should contain only valid paths
Given candidate crash is installed
When candidate crash is uninstalled
Then environment variable PATH cannot contain "sdkman/candidates/crash/"
Given candidate kscript is installed
When candidate kscript is uninstalled
Then environment variable PATH cannot contain "sdkman/candidates/kscript/"
# TODO: add test that fails if `test` in conf.d/sdk.fish:80 errors (cf issue #28 et al.)

View file

@ -1,5 +1,7 @@
# frozen_string_literal: true
require 'fileutils'
Given('environment variable {env_name} is not set') do |name|
@name = name
@expect_intermediate_value = false
@ -22,6 +24,26 @@ Given('environment variable {env_name} is set to {string}') do |name, new_value|
BASH
end
$install_default = "#{ENV['HOME']}/.sdkman"
$install_custom = nil
$install_backup = "#{$install_default}_bak"
Given(/^SDKMAN! is installed at (.*)$/) do |path|
$install_custom = path
FileUtils.cp_r($install_default, $install_custom)
log "Backing up #{$install_default} at #{$install_backup}"
FileUtils.mv($install_default, $install_backup)
end
def _restore_install # called in After hook
unless $install_custom.nil?
log "Removing #{$install_custom}"
FileUtils.rm_rf($install_custom)
$install_custom = nil
log "Restoring #{$install_default} from #{$install_backup}"
FileUtils.mv($install_backup, $install_default)
end
end
When('a new Fish shell is launched') do
@command += <<~BASH
fish -lc "env | grep -E \\"^#{@name}=\\"" \\

View file

@ -0,0 +1,48 @@
# frozen_string_literal: true
require 'fileutils'
require 'tempfile'
module GeneralHelper
end
World GeneralHelper
When('we run fish script') do |script_content|
script_file = Tempfile.new('fish_script')
File.write(script_file, script_content)
out, status = Open3.capture2e("fish #{script_file.path}")
unless status.success?
warn(out)
raise "Fish command failed: #{out}"
end
@output_fish_script = out.strip
end
Then(/^the output is$/) do |text|
expect(@output_fish_script).to eq(text.strip)
end
When('we run {string} in Fish') do |command|
@response = run_fish_command(command)
end
Then('the exit code is {int}') do |code|
expect(@response[:status]).to eq(code)
end
Then(/^environment variable ([A-Z_]+) has value "([^"]+)"$/) do |key, value|
expect(@response[:env][key]).to eq(value)
end
And('the output contains {string}') do |content|
output = @response[:stdout]
.select { |line| !line.blank? }
.map { |line| line.strip }
expect(output).to include(content)
end
Then(/^file ([a-zA-Z0-9\-_.\/]+) contains$/) do |file,content|
expect(File.readlines(file).join("").strip).to eq(content.strip)
end

View file

@ -1,3 +1,6 @@
require 'fileutils'
require 'tempfile'
$index_updated = false # TODO: Hack since Cucumber doesn't have Feature-level hooks
Given(/^SDKMAN! candidate list is up to date$/) do
unless $index_updated
@ -32,21 +35,88 @@ def _uninstall_candidate_version(candidate_dir)
end
When(/^candidate (\w+) is uninstalled$/) do |candidate|
puts `ls ~/.sdkman/candidates/#{candidate}`
log `ls ~/.sdkman/candidates/#{candidate}`
Dir["#{ENV['HOME']}/.sdkman/candidates/#{candidate}/*"].each do |candidate_dir|
_uninstall_candidate_version(candidate_dir)
end
puts `ls ~/.sdkman/candidates/#{candidate}`
log `ls ~/.sdkman/candidates/#{candidate}`
end
# Uninstall all SDKMAN! candidates
# TODO: Run after every scenario, this makes tests very slow.
# Currently, Cucumber doesn't have Feature-level hooks, so we have to work around:
# --> install only if not already installed;
# if the test needs a candidate to _not_ be there, make it explicit.
# --> clean up after _all_ features at least
at_exit do
Dir["#{ENV['HOME']}/.sdkman/candidates/*/*"].each do |candidate_dir|
_uninstall_candidate_version(candidate_dir)
Given(/^file ([a-zA-Z0-9\-_.\/]+) exists with content/) do |filename,content|
FileUtils.mkdir_p(File.dirname(filename))
File.write(filename, content)
end
$fish_config_files = []
def _remove_fish_configs # called in After hook
$fish_config_files.each do |f|
log "Removing #{f}"
FileUtils.rm_f(f)
end
$fish_config_files = []
end
And(/^fish config file ([a-zA-Z0-9\-_.\/]+) exists with content$/) do |filename,content|
file = "#{ENV['HOME']}/.config/fish/conf.d/#{filename}"
FileUtils.mkdir_p(File.dirname(file))
File.write(file, content)
$fish_config_files << file
end
$config_file = "#{ENV['HOME']}/.sdkman/etc/config"
$backup_config_file = nil
def _restore_config # called in After hook
unless $backup_config_file.nil?
log "Restoring #{$config_file} from #{$backup_config_file.path}"
FileUtils.mv($backup_config_file, $config_file)
$backup_config_file = nil
end
end
Given(/^SDKMAN! config sets ([a-z_]+) to (.*)$/) do |key,value|
if $backup_config_file.nil?
$backup_config_file = Tempfile.new('sdkman_config_backup_')
log "Backing up #{$config_file} at #{$backup_config_file.path}"
FileUtils.cp($config_file, $backup_config_file)
end
config = File.readlines($config_file).map { |line| line.split("=").map { |v| v.strip } }.to_h
config[key] = value
new_config_string = config.map { |k,v| "#{k}=#{v}" }.join("\n")
File.write($config_file, new_config_string)
end
# TODO: create shared helper for both config files
#
$fish_config = "#{ENV['HOME']}/.config/fish/config.fish"
$backup_fish_config = nil
def _restore_fish_config # called in After hook
unless $backup_fish_config.nil?
if $backup_fish_config == :none
log "Deleting #{$fish_config}"
FileUtils.rm($fish_config)
else
log "Restoring #{$fish_config} from #{$backup_fish_config.path}"
FileUtils.mv($backup_fish_config, $fish_config)
end
$backup_fish_config = nil
end
end
And(/^fish config contains `([^`]+)`$/) do |line|
if $backup_fish_config.nil?
if File.exist?($fish_config)
$backup_fish_config = Tempfile.new('fish_config_backup_')
log "Backing up #{$fish_config} at #{$backup_fish_config.path}"
FileUtils.cp($fish_config, $backup_fish_config)
else
$backup_fish_config = :none
end
end
config = File.exist?($fish_config) ? File.readlines($fish_config) : ''
config << "\n\n# Added by sdkman-for-fish test\n#{line}"
File.write($fish_config, config.join("\n"))
end

View file

@ -64,7 +64,7 @@ def run_fish_command(cmd)
end.to_h
out, status = Open3.capture2e(<<~FISH
fish -c '#{cmd} > #{files[:stdout]} ^ #{files[:stderr]}; \
fish -c '#{cmd} > #{files[:stdout]} 2> #{files[:stderr]}; \
echo $status > #{files[:status]}; \
env > #{files[:env]}; \
'

View file

@ -0,0 +1,21 @@
require_relative '../step_definitions/setup'
require_relative '../step_definitions/corner_cases.rb'
After do |scenario|
_remove_fish_configs
_restore_fish_config
_restore_config
_restore_install
end
# Uninstall all SDKMAN! candidates
# TODO: Run after every scenario, this makes tests very slow.
# Currently, Cucumber doesn't have Feature-level hooks, so we have to work around:
# --> install only if not already installed;
# if the test needs a candidate to _not_ be there, make it explicit.
# --> clean up after _all_ features at least
at_exit do
Dir["#{ENV['HOME']}/.sdkman/candidates/*/*"].each do |candidate_dir|
_uninstall_candidate_version(candidate_dir)
end
end

View file

@ -6,6 +6,7 @@ ParameterType(
type: Array,
transformer: lambda do |*patterns|
patterns \
.select { |s| !s.nil? } # Huh? Well, if it helps...
.map(&:strip) \
.map do |s|
s = if %r{^/(.*)/$} =~ s

View file

@ -4,12 +4,16 @@ Feature: Wrapping of Bash
the effect sdk has on the Bash environment carries
over the current Fish session.
We verifiy equality of (standard) output, exit code, and environment variables.
We verify equality of (standard) output, exit code, and environment variables.
Background:
Given SDKMAN! candidate list is up to date
And candidate ant is installed at version 1.9.9
And candidate ant is installed at version 1.10.1
And file /tmp/env-test/.sdkmanrc exists with content
"""
ant=1.9.9
"""
Scenario Outline:
When we run "<command>" in Bash and Fish
@ -27,4 +31,7 @@ Feature: Wrapping of Bash
| sdk update |
| sdk use ant 1.9.9 |
| sdk offline enable > /dev/null; sdk install ant foo |
| sdk use ant 1.9.9 > /dev/null; sdk broadcast |
| sdk use ant 1.9.9 > /dev/null; sdk version |
| sdk home ant 1.9.9 |
| cd /tmp/env-test; sdk env |
| cd /tmp/env-test; sdk env; sdk env clear |