helpermethod

When writing a CLI application which operates on a file, you often want to look for that file in the current directory by default.

Let's say you have a --file parameter, which expect the full path to a pom.xml file, but looks for that file in the current directory if the parameter is not provided.

But how would you get the Path to the file in the current directory? Turns out, it's actually quite simple:

Paths.get("pom.xml").toAbsolutePath()

Bonus:

To get the Path for the current directory, you can just use:

Paths.get("").toAbsolutePath()

Sometimes you need to use a different username and email for a single pull request to impersonate a different user.

For that case, git provides the -c flag, which allows you to pass configuration parameters to the command you are about to execute.

The following command will create a commit with username silencer-bot and an empty email address.

git -c user.name=silencer-bot -c user.email= commit

Note that -c flags needs to be set right after the git command but before the subcommand (in this case, commit).

If you've ever wondered why SDKMAN! rarely breaks, the answer is simple: Loads and loads of tests!

Almost every single line of https://sdkman.io/ is covered by tests, often with varying inputs to account for some edge case.

But there has always been a stain on SDKMAN!'s shiny, test-plated armor: Its Bash completions. Because they are only tested manually, they regularly break, much to the regret of our users and of course us, the maintainers.

So after another breakage I've decided to roll up my sleeves and started writing some automated tests.

But how to test Bash completions?

To help you in creating those completions, Bash provides some predefined variables, namely COMP_WORDS, an array which contains the words on the command line, and COMP_CWORD, which gives you the index of the current word.

These variables are normally filled by Bash's completion facility but can also be set manually before calling the completion function.

So in order to test the completions for the sdk command, you can do something like this

COMP_WORDS=(sdk); COMP_CWORD=1; _sdk

where COMP_WORDS contains sdk (the words on the command line) and COMP_CWORD the index of the current word (here 1 because we are completing the word after sdk). _sdk is the shell function for generating the completions and looks similar to this

_sdk() {
    local -r current_word="${COMP_WORDS[$COMP_CWORD]}"

    # the logic for generating the list of completion candidates

    COMPREPLY=($(compgen -W "${candidates[*]}" -- "$current_word"))
}

After running the _sdk function, COMPREPLY will contain the list of all possible completions, which you can assert on

[[ ${COMPREPLY[*]} == 'install uninstall list use config default home env current upgrade version broadcast help offline selfupdate update flush' ]]

And that's it! To test other completions just modify COMP_WORDS and COMP_CWORD accordingly

COMP_WORDS=(sdk install); COMP_CWORD=2; _sdk

TLDR;

  • modify COMP_WORDS and COMP_CWORD
  • assert on the expanded value of COMPREPLY
COMP_WORDS=(sdk); COMP_CWORD=1; _sdk
[[ ${COMPREPLY[*]} == 'install uninstall list use config default home env current upgrade version broadcast help offline selfupdate update flush' ]]