Functions
- just_functions.bsh
A few functions are defined in a common. Sourced here for DRY
- DRYRUN
Print out some commands instead of executing.
${DRYRUN} <command>
Display key commands as they would be executed. This is conveniently set by using the -n
/--dryrun
argument. Default: <Null>
Example
function Docker()
{
${DRYRUN} docker "${@}"
}
Note
DRYRUN
doesn’t just echo out the command, it uses the print_command print_command
function to print out a command that can be copied and pasted in. This handles spaces correctly unlike echo.
See also
- JUST_SEPARATOR
Separator used for just_functions.bsh get_args
When passing an unknown number of arguments, the JUST_SEPARATOR can be used to begin and end a group of arguments. Default: –
See also
- JUST_SAFE_LOAD_DELIMITER
Separator used for safe_load
safe_load reads a key:value file, and this variable is used to separate the keys and values. Default: =
See also
just_plugins
Plugin system for just
Usage
Certain just targets can be used for many different projects, and rather then repeating this code, just_plugins give a way to expose the common code of these targets to many different projects.
To add plugins to your project, simply add the plugin filenames to your .justplugins
file.
When writing a new plugin, you need to follow a few rules:
A case statement in a defaultify function must be written. The case statement should have a unique name that is not likely to be used anywhere else. All plugin functions have to exist in the same namespace.
Add the case names to the array
JUST_DEFAULTIFY_FUNCTIONS
to allow the commonly used functionality to be added as targets for justAdd the plugin filename to the array
JUST_HELP_FILES
Must return non-zero if the argument is not matched, and return 0 on target match
Example
Source code of a just_example_functions.bsh, which looks something like:
JUST_DEFAULTIFY_FUNCTIONS+=(just_example_defaultify)
JUST_HELP_FILES+=("${BASH_SOURCE[0]}")
function just_example_defaultify()
{
arg="${1}"
shift 1
case "${arg}" in
foo|bar) #Foobar test
echo "Foo or bar: ${1}"
extra_args=1
;;
*)
plugin_not_found=1
;;
esac
return 0
}
- JUST_PLUGIN_FILE
Name of the just plugin file
Defaults to .justplugins
in the same directory as the Justfile, but can be overridden to another filename/path by exporting this variable
Note
Since plugins are loaded right before the project environment, you can not set the JUST_PLUGIN_FILE
in the project env file. If you are using a custom JUST_PLUGIN_FILE
, it will need to be set in the setup.env
See also
just safe_env
- JUST_DEFAULTIFY_FUNCTIONS
List of defaultify functions
The values of this array are executed as a command. Each plugin should have a unique name for the function, and is responsible for adding that function name to JUST_DEFAULTIFY_FUNCTIONS
- JUST_HELP_FILES
This should include just_functions.bsh, the Justfile, and any plugins. The plugin is responsible for adding itself to this array.
Usage
Every project should have a setup file, typically called setup.env
. This script’s location is stored in JUST_SETUP_SCRIPT
and is also where JUST_HELP_FILES
should be set.
See also
- JUST_PROJECT_PREFIX
Variable prefix for project
Some just functions need to know the prefix used for a project’s environment variables (e.g., in order to list all project env variables using compgen). This should be defined in your project’s settings env file, and does not need to be overridable.
- JUST_SETTINGS
Absolute path to the project settings env file; set automatically when you source just_env
JUST_SETTINGS is set automatically by just_env
, which is used to setup the project’s environment by sourcing the projects settings env file very early in the project’s Justfile.
Example
Typically, the Justfile will include a line like this very near the top:
source "${VSI_COMMON_DIR}/linux/just_files/just_env" "$(dirname "${BASH_SOURCE[0]}")"/'my_project.env'
Note
JUST_SETTINGS
supports multiple files using the JUST_SETTINGS_SEPARATOR
(default: ///
). The user and developer should not need to come up with this themselves, as it is automatically generated, unless they are manually overriding it.
- JUST_SETTINGS_SEPARATOR
Separator used between filenames of JUST_SETTINGS
- source_environment_files
Convenience function for sourcing environments
The just system works by sourcing environment files, aka settings files, and plugins
First, ${project_dir}/local.env. This file should never be added to version control. It should contain customizations for that particular install.
Then, the project’s settings env file. This file should ideally contain all the default values necessary to run without any local.env settings.
Last, ${project_dir}/local_post.env. This file should never be added to version control. It is rarely used, except in situations where the value of a variable is based off of another variable. This is why it is loaded last.
Any plugins that are identified, are also sourced
- Arguments:
$1
- The project settings filename (e.g., vsi_common.env)
- Parameters:
[
JUST_LOCAL_SETTINGS
] - Path to the local settings file. Default: ${same_dir}/local.env[
JUST_LOCAL_SETTINGS_POST
] - Path to the post local settings file. Default: ${same_dir}/local_post.env
Usage
JUST_LOCAL_SETTINGS
and JUST_LOCAL_SETTINGS_POST
must not be set in any of the the project’s settings files or plugins, as it will not have the desired effect. Instead, they should either be manually set in the environment or set in the setup script (see JUST_SETUP_SCRIPT
)
Note
Certain exceptions to not storing values in the project settings file make sense such as credentials, encryption keys, etc… information that should not be hard-coded ever.
Only require settings in local.env
when it cannot be avoided. For example, it might be reasonable to use openssl to create ssl certs in a default location (that is ignored by version control).
- create_local_settings_file
- Arguments:
$1
- Path to the settings file- Parameters:
[
JUST_LOCAL_SETTINGS
] - The location to create the local settings file [JUST_LOCAL_SETTINGS_POST
] - The location to create the post local local settings file- Return Value:
0
- Settings file was created1
- Settings file was not created
- Output:
[
JUST_LOCAL_SETTINGS
] - Path to the local settings file. Default: ${same_dir}/local.env [JUST_LOCAL_SETTINGS_POST
] - Path to the post local settings file. Default: ${same_dir}/local_post.env
Try to create the local.env settings file
Create the local.env settings file if a) it does not already exist and b) it will be owned by the correct user.
- translate_just_settings
Convert JUST_SETTINGS
to an array: JUST_SETTINGSS
, translating the paths to another filesystem
- Arguments:
$1
- Directory name to be translated from$2
- Directory name to translate to
- Output:
JUST_SETTINGSS
- Array of the translated paths
Useful for translating JUST_SETTINGS
from host to a container.
- auto_path_escape
Automatically add an escape character to paths that match a pattern
TODO: Explain
See also
- set_temp_array
- Arguments:
$1
- Name of array to check if it is already set$2...
- Default values of the array
- Output:
JUST_TEMP_ARRAY
- Destination for all the values set
DEPRECATED: Set array to default values if not already set.
In bash, when setting a variable to a default value if it has not already been set, it is typical to follow the pattern:
: ${MY_VAR=default}
However, this syntax does not work for an array. Bash 3.2 does not give an equivalent one line version of this. Instead, using set_temp_array
, JUST_TEMP_ARRAY can be set to a default value if not already set (albeit, in two lines).
It works by checking if an array is set. If it is, it copies all the values to the array JUST_TEMP_ARRAY. If it is not, it will copy the rest of the arguments (the default values) to JUST_TEMP_ARRAY
. When using this function with set -u turned on, it is best to reference JUST_TEMP_ARRAY
by (${JUST_TEMP_ARRAY[@]+”${JUST_TEMP_ARRAY[@]}”}) in case the array is empty, as this triggers bash’s unbound variable test.
Example
set_temp_array MY_ARRAY default1 default\ 2 "default 3"
MY_ARRAY=(${JUST_TEMP_ARRAY[@]+"${JUST_TEMP_ARRAY[@]}"})
# And when done, clean up
unset JUST_TEMP_ARRAY
See also
- set_array_default
- Arguments:
$1
- Name of array to check if it is already set$2...
- Default values of the array
Set array to default values if not already set.
In bash, when setting a variable to a default value, if it has not already been set, it is typical to follow the pattern:
: ${MY_VAR=default}
However, this syntax does not work for an array. Bash 3.2 does not give an equivalent one line version of this. Instead, using set_array_default
, an array can be set to a default value if not already set (albeit, in two lines).
It works by checking if an array is set. If it is set, nothing happens. If it is not set, it will copy the rest of the arguments (the default values) to the array named.
Note
An empty array counts as set
Example
set_array_default MY_ARRAY default1 default\ 2 "default 3"
- pretty_print_help
- Arguments:
stdin - Each line is an entry in the pretty printout, separated by ” ${
JUST_HELP_SEPARATOR
} ” (without the quotes, but with the spaces)- Parameters:
indent - How much the right side should be indented to make a uniform output
Restructures text to indent properly on wrap around
Each line consists of a command that will be printed on the left, and the indented description on the right. The description is wrapped around based on tput cols.
See also
- print_help
Prints the auto generated help info from Justfile
- is_powershell
Check if the current command window is powershell
Using a Window’s title trick, determine if the shell is running in powershell or some other shell (e.g., Windows command prompt, cygwin or git bash)
- need_tty
Check to see if a tty is missing. Normal tty checks do not work in mintty, as the pts appears to be a tty to native apps, but external apps will see a pipe. Checking to see if stdin has a name of “None” will tell us if we don’t have a piped stdin.
Calling this function is an expensive operation, and takes roughly 1-2 seconds (to call a new powershell). Setting JUST_IS_TTY to 1 will cause the function to return false instantly.
- Parameters:
[
JUST_IS_TTY
] - If set to 1`, need_tty automatically returns 1. If set to0
, thenneed_tty
will automatically returns 0 once.
If JUST_IS_TTY
is set in a local.env
file, then it should be set conditionally:
: ${JUST_IS_TTY=0}
This way it is triggered only once, instead of every time local.env
is source, which can be quite frequently.
One use case for this is “ssh from linux into windows, start git bash, . setup.env, and then run python”. This will detect a fake tty name, because it is piped. However, you still need a tty because in python up and down will not work. I do not know why in this case…
See also
- setup_tty
Pops up a new powershell window and runs just
Cygwin bash is pretty bad. The new git bash (MINGW64) does not have a tty. This is a problem for docker. Powershell does have a tty, but cannot run bash scrips natively. The solution is to run bash in powershell (which is not as straight forward as it sounds). This function is designed to re-execute in a new powershell on Windows if not in powershell
- Parameters:
[
JUST_PTY
] - PTY app to use create a psuedoterminal for windows apps. By default, useswinpty
. Set topowershell
for the old behavior
Usage
setup_tty ${@+”${@}”}
- defaultify
Default commands for just
Handles a few default commands for just:
Calls plugins specified in
JUST_DEFAULTIFY_FUNCTIONS
–dryrun|-n - Sets DRYRUN to
print_command print_command
. This way ${DRYRUN} can be put in front of any command and be printed instead of executed when in dryrun mode–separator - Used to override the
JUST_SEPARATOR
(default –) to anything else. This only affect commands that use get_args-h|–help|help - Prints out help using print_help
_null - A target that does nothing. This is seldom needed.
For all other commands not captured yet, called unknownify (which can be overridden for other behavior) to print an error message.
- unknownify
- Parameters:
JUST_FILE_NOT_FOUND
- Prints out a different message ifJUST_FILE_NOT_FOUND
is set to1
The function executed when an unknown target is specified
The default behavior is to print an error and exit 1. However, a custom unknownify can be declared in Justfile to override this behavior
- extra_args
The number of additional arguments consumed in a caseify target
When writing a caseify target, by default one argument is consumed. This is enough for any simple target. However some targets need additional arguments.
There are really three situation when extra arguments are needed
A fixed number of arguments. For example, if 3 arguments are needed, just use $1, $2, $3, and set
extra_args=3
The rest of the arguments are going to be consumed. In this case, use all the arguments (typically by $@) and set extra_args=${#}
An unknown number of arguments need to be used, and maybe multiple groups of unknown arguments. This is the case where JUST_SEPARATOR is used. (See EXAMPLE)
Example
# Lets say we call:
just test 11 22 33 -- aa bb cc dd -- _null
# test is called with 3 arguments
# aa is called with 3 arguments
# _null is called
The deprecated way
# Lets say we call:
just test -- 11 22 33 -- aa bb cc dd -- _null
# And I have a target test that takes two sets of arguments of unknown length
test)
get_args ${@+"${@}"}
first=${args[@]+"${args[@]}"}
get_additional_args ${@+"${@}"}
second=${args[@]+"${args[@]}"}
;;
In this case, there is no need to add extra_args
, get_args
does this already
- justify
- Arguments:
$1...
- list of targets
The main loop of just
Handles determining what subcommands are and calling commands and subcommands.
When one target is called from another target, justify should be used to do the calling, for example:
justify target2
- callify
Helper for consuming arguments and calling a function with them
Takes: cmd – $1 $2 $3 … $n – $m $m+1 … and calls: cmd $1 $2 $3 … $n and consumes n+2 args Trailing – is optional
Example
target)
callify python ${@+"${@}"}
;;
just target -- -c "print 1+3"
Note
Not sure this is worth keeping
- get_args
- Arguments:
Inputs
$@
- All the unconsumed arguments- Output:
args
- Array of unknown number of arguments consumedget_args_args_used
- Number of arguments used, including separator
Get and consume an unknown collection of arguments
Gets an unknown number of arguments. The ending of the collection of arguments is annotated with the JUST_SEPARATOR
. The trailing annotation is optional as long as there are no more just commands following
Bugs
This will conveniently update extra_args
inside of the Justfile caseify function. However, if you are calling from another function (i.e., not writing a caseify section), this will produce incorrect behavior; therefore, extra_args should be made a local variable in the calling function
Note
get_args_args_used
is a global variable. Unsetting it can cause unexpected
behavior
- get_additional_args
Get and consume additional collections of arguments
get_args
can only be called once, but get_additional_args
can be called continuously after the first call of get_args
Example
Must be called after get_args
with all arguments passed in. For example:
target)
get_args ${@+"${@}"}
args1=(${args[@]+"${args[@]}"})
get_additional_args ${@+"${@}"}
args2=(${args[@]+"${args[@]}"})
get_additional_args ${@+"${@}"}
args3=(${args[@]+"${args[@]}"})
;;
just target 11 22 33 -- aa bb cc -- '!!' '@@' '##'
#args1=(11 22 33)
#args2=(aa bb cc)
#args3=(!! @@ ##)
- safe_load
A non-eval method for loading and exporting a text file of keys/values
- Arguments:
Inputs
$1
- Filename of file to be loaded- Parameters:
[
JUST_SAFE_LOAD_DELIMITER
] - By default, = is used between key and value. If = is needed, then this environment variable can override the delimiter.- Output:
All keys are set as environment variables and exported
Example
key1=value_one
key2=this is another value
Note
Does not support comments, blank lines, or anything else other than key=value
Bugs
As with anything in a language like bash, it’s not guaranteed that an arbitrary command won’t be executed with this, but as far as is known, there are no known issues with this function.
- just_error
Helper function to be combined with calls to print a useful error message on error.
Errors captured by just_functions.bsh just_error
will not print out an error stack.
- Arguments:
Inputs
$1...
- Message to echo on error- Return Value:
Returns the same return value of the previously run command
- Output:
Echos message
Example
run_some_command || just_error "That command failed, here's some helpful advise"
- .justplugins
Plugin file
The filename defaults to .justplugins and sits next to your Justfile, but can be overridden by exporting the environment variable JUST_PLUGIN_FILE
.
Lists the various plugin files. Blank lines and # comment lines are allowed