A minimalist dependency manager for shell scripts. It is designed to make shell scripts as much portable as possible, while including external dependencies.
Import.sh
is designed to easily load different assets for your shell projects:
- Load bash library: Will source the target into the current shell session
- Load binary: Will ensure the binary name is resolved in $PATH
- Load file: Will ensure the file is available and provide it's full path
It support both local assets, related to your project file or directory, and also remote
assets when an URL is provided. When import.sh need to fetch an asset from an external URL,
it will download it one time and put it in a cache directory (in $HOME/.local/share/import.sh
or /tmp
).
Less than 200 lines of code, portable, multi OS and POSIX compliant. Installable with shctl.
import.sh
is designed to work with single files instead of group of files. More features will
likely not be implemented in way to keep this piece of software simple.
Run the provided installation script:
curl -O - https://raw.githubusercontent.com/mrjk/import.sh/main/install.sh | bash
The script installed import.sh
in the first writable path of the $PATH
variable. If there is no available writable path, it will fail to install.
There is a very simplistic demo1.sh example with only remote libraries:
#!/bin/bash
# Load import.sh
source import.sh
# Import the tools or library you need
import lib https://raw.githubusercontent.com/qzb/is.sh/v1.1.0/is.sh
import bin https://raw.githubusercontent.com/TheLocehiliosan/yadm/3.2.2/yadm
import bin yadm-3.1.0 https://raw.githubusercontent.com/TheLocehiliosan/yadm/3.1.0/yadm
# Test is.sh library
command -v is || true
echo "is version: $(is --version)"
# Test yadm-3.1.0 binary
command -v yadm
echo "yadm version: $(yadm --version)"
# Test yadm-3.1.0 binary
command -v yadm-3.1.0
echo "yadm-3.1.0 version: $(yadm --version)"
There are more demonstration in tests/demos/ directory:
./tests/demos/demo_clish.sh -h
: Demonstration with clish library for blazing fast CLIs- More to come ...
Follow this walkthrough to quickly get started with import.sh
.
When import.sh
is correctly installed, it should be available in your $PATH
. So we can directly load the library without knowing it's full path. In it's simplest form, it takes:
source import.sh
Sometimes, it can be confusing to understand how files are loaded during run time. To get extensive output, you can set the environment variable SHLIB_TRACE=1
:
SHLIB_TRACE=1 ./myscript.sh
When import.sh need to fetch external resources, it will store cache in $HOME/.local/share/import.sh
or /tmp
, depending if directories are writable or not. It fails if it can't find a place to store files.
Note: TODO, store in ram as last case
TODO
To import and source a remote library:
import lib https://raw.githubusercontent.com/qzb/is.sh/v1.1.0/is.sh
declare -f is
It support target name, to avoid conflicts with URLs having the same file name:
import lib lib-prj1.sh https://raw.githubusercontent.com/user/project1/v0.0.9/main_lib.sh
import lib lib-prj2.sh https://raw.githubusercontent.com/user/project2/v17.2.0/main_lib.sh
Prefered way of importing local binary is by path, for example one bin
and one libexec
:
# Import bin in PATH
import.sh bin bin
# Import subdirectory in PATH
import.sh bin helper/tool/bin
Note: Use the import.sh bin script1 helper/tool/bin/script1
does not make sense and it is not tested.
Import import.sh
in your local scripts, then the command will be during script runtime:
import bin https://raw.githubusercontent.com/qzb/is.sh/v1.1.0/is.sh
command -v is.sh
It's possible to define the target file:
import bin is-1.0.1.sh https://raw.githubusercontent.com/qzb/is.sh/v1.0.1/is.sh
command -v is-1.0.1.sh
To fetch external files:
import bin repo_aria2 https://raw.githubusercontent.com/asdf-vm/asdf-plugins/master/plugins/aria2
import bin repo_desk https://raw.githubusercontent.com/asdf-vm/asdf-plugins/master/plugins/desk
echo "File repo for aria2: $(import get repo_aria2)"
echo "Repo for desk: $(import read repo_desk)"
Advanced documentation for import.sh
import.sh
support strict mode.
If import.sh
is not installed, you can throw an instruction message:
command -v import.sh >&/dev/null || {
>&2 echo "Can't find import.sh, please install it first: curl -sfL https://raw.githubusercontent.com/mrjk/import.sh/master/install.sh | bash"
exit 1
}
# Import import.sh
source import.sh
Or even directly install import.sh
without asking user consent:
# Ensure import.sh is always installed
command -v import.sh >&/dev/null || {
curl -sfL https://raw.githubusercontent.com/mrjk/import.sh/master/install.sh
| bash || exit $?
}
# Import import.sh
source import.sh
There is an example:
# In any binaries, you can mention the relative
# lookup path
source import.sh ../lib
import is.sh
import myapp_lib1.sh
import myapp_lib2.sh
Determine the library lookup path:
# Determine library inatallation path
export SHLIB_PATH_SHARED="$BASHER_PREFIX/lib/bash"
To embed this library, just past the content of bin/import.sh
it at the header of your script.
Another example project, with local libraries and an executable shell script bin/demo.sh
:
source import.sh ..
import lib lib_demo.sh
import lib lib_custom.sh
import bin demo-completion.sh
The directory structure woul look like:
$ tree shell_project/
demo_project/
|-- bin
| |-- demo-completion.sh
| `-- demo.sh
`-- lib
| |-- lib_demo.sh
| `-- lib_custom.sh
This software is under active development.