Universal Wrapper - an application installer and updater
This repository contains two scripts: one Bash script for Linux/macOS and one Batch script for Windows, designed to manage the installation, periodic checking, and execution of a single command-line application.
The primary goal is to provide an extremely simply, user-friendly wrapper that ensures the application is always present and up-to-date before it runs, without having to rely on traditional package managers.
These scripts handle the following responsibilities:
- First-Time Installation: If the application is not found, it performs a complete download and unpacks the binary into a hidden application directory in the user’s home directory.
- Conditional Updates: It checks for updates conditionally. If the local file is older than the remote one, it downloads and unpacks the new version, minimizing unnecessary data transfer.
- Lazy Update Checking: It only checks the remote server for updates if the last check was done after the configured time period has passed (default is 3 days).
- Execution Handover: The script acts as a self-installer/updater wrapper. After ensuring the application is ready, it hands over execution to the application to be started.
- Configuration Overrides: Key variables, like the update frequency, can be configured without editing the main script file.
These scripts do not handle:
- PATH Modification: They do not modify the system PATH or environment variables. The user must run the script from its location or add the application's bin directory to their PATH manually.
- Dependency Management: They do not install or manage dependencies for the application. It is assumed all required dependencies are part of the application package or already present on the system.
- Complex Versioning: They do not manage complex versioning schemes. The update check is based solely on file modification timestamps obtained from the download URL.
- Rollback Mechanism: There is no built-in rollback mechanism, or even an uninstaller, in case an update fails or introduces issues.
- Multi-User Installations: The installation is per-user and does not support system-wide installations.
Configuration is managed in two ways:
These variables are defined directly at the top of the scripts and should not be overridden by bootstrap.cfg.
| Variable | Default Value (Example) | Description |
|---|---|---|
| APP_NAME | APP |
The short name of the application. |
| APP_DIR | .APP |
The installation directory name of the application. |
| DOWNLOAD_URL | https://example.com/... |
The direct download URL for the release archive (.tgz for Bash, .zip or .tgz for Batch). |
These variables have defaults set within the script but can be overridden by placing them in one of the following configuration files (in order of precedence):
$HOME/<APP_DIR>/bootstrap.cfg(User-wide defaults)./<APP_DIR>/bootstrap.cfg(Local overrides)
The format for the configuration files is simple KEY=VALUE, with comments starting with #.
| Variable | Default Value | Description |
|---|---|---|
| UPDATE_PERIOD | 3 | The number of days after which an update check must be performed. If the last_checked file is older than this period, the script will attempt to contact the server. |
| LOG_LEVEL | <empty> | Logging level. Default empty/silent; set to anything, e.g., 'DEBUG', to enable logging |
Example bootstrap.cfg content:
# Configuration to override the default update period
UPDATE_PERIOD=7
# You can add other configurations here later
# LOG_LEVEL=DEBUG
- Requirements:
bash,curl,tar,findandstat.
- Requirements: Modern Windows (10/11) with
curlandtaravailable in the PATH.
You will need a hosting location for your application’s release archive (a .tgz file for the Bash script, and a .zip or .tgz file for the Batch script). This archive can contain any files you want but it should have at least the two script files in a bin folder.
This is the minimum contents of the archive:
bin/
APP
APP.cmd
but you can also include additional files and folders as needed. The following is an example of a more complete archive structure:
bin/
APP
APP.cmd
other_executable_files
lib/
supporting_libraries
docs/
documentation_files
README.md
IMPORTANT:
- Permissions: Ensure that the
APPfile inside thebinfolder has executable permissions set (especially for Linux/macOS). - Naming: It is required that scripts in the
binare named the same as the variableNAMEfound inside them (see Usage below). - No conflicts: Do not include the
bootstrap.cfgfile inside the archive, as it would override user configurations on each update. And no folder or file named_cacheshould exist either.
- Configure: Edit the
NAMEandDOWNLOAD_URLvariables (and possiblyAPP_DIRif you want a different name than the default) at the top of both scripts (APPandAPP.bat). - Rename: Rename the scripts to match your application's name.
- Upload: Upload the release archive to your hosting location and ensure the
DOWNLOAD_URLvariable points to it.
After the preparation has been completed and the release archive has been uploaded, you can use the scripts as follows:
- Copy: Take both scripts that you prepared in the previous step and make copies in any directory/project where you'd like these commands to be available without prior installation. A common usage is to have the name of the scripts end in the letter “w” to indicate they are “wrapper” scripts (e.g., if
APP_NAME=foo, rename tofoowandfoow.bat). - Execute: Now simply run the script from the command line, passing any arguments you want to forward to the application:
# On Linux/Mac (make sure it's executable: chmod +x foow)
./foow --some-argument
# On Windows
.\foow.cmd /flag
The first time you run it, the application will download and install itself to the user’s home directory ($HOME/$APP_DIR). Subsequent runs will check for updates if the configured period has passed.
To force an update check, you can delete the last_checked file located in the application's installation directory, eg:
rm $HOME/.APP/_cache/last_checked
Then the next execution of the script will check for updates.
To force a complete reinstallation of the application, delete the application's cache directory, eg:
rm -rf $HOME/.APP/_cache
Then the next execution of the script will download and install the application afresh.