# USM Executable Scripts Reference ## Overview USM packages use executable scripts to handle different phases of package lifecycle. Scripts are defined in the `execs` section of MANIFEST.usm and receive specific arguments based on their purpose. ## Script Types ### build Required script that compiles source code into binaries. **Arguments**: `[build-directory]` - `build-directory`: Path where build output should be placed **Working Directory**: - By default: Source directory - With `simpleBuildEnvironment` flag: Build directory (source tree is copied first) **Environment Variables**: USM sets these non-prefixed variables for execs: - `DESTDIR`: Destination directory - `PREFIX`: Installation prefix - `BINDIR`: Binary directory - `INCLUDEDIR`: Include directory - `DATADIR`: Data directory - `INFODIR`: Info directory - `LIBDIR`: Library directory - `MANDIR`: Manual directory - `LIBEXECDIR`: Libexec directory - `LOCALEDIR`: Locale directory - `LOCALSTATEDIR`: Local state directory - `SBINDIR`: System binary directory - `SHAREDSTATEDIR`: Shared state directory - `SYSCONFIGDIR`: Configuration directory - `TAGSDIR`: Tags directory Note: The `USM_*` prefixed environment variables are for the USM process itself and should not be used in exec scripts. **Example**: ```bash #!/bin/bash set -e build_dir=$1 # With simpleBuildEnvironment flag, we're already in build directory # Without the flag, we need to change to build directory if [ ! -d "$build_dir" ]; then mkdir -p "$build_dir" fi cd ${build_dir} meson setup ${src_dir} --prefix=${PREFIX} --libdir=${LIBDIR} ninja ``` ### install Optional script that installs built files to destination directory. **Arguments**: `[build-directory] [install-directory] [install-type]` - `build-directory`: Path containing build output - `install-directory`: Path where files should be installed (DESTDIR) - `install-type`: "fresh", "upgrade", or "downgrade" **Working Directory**: - By default: Source directory - With `simpleBuildEnvironment` flag: Build directory **Environment Variables**: - `DESTDIR` is overridden to install-directory - Other USM variables are available **Example**: ```bash #!/bin/bash set -e build_dir=$1 install_dir=$2 install_type=$3 # With simpleBuildEnvironment flag, we're already in build directory # Without the flag, we need to change to build directory cd ${build_dir} meson install --destdir ${install_dir} ``` ### postInstall Optional script that runs after USM installs resources to system. **Arguments**: `[build-directory] [install-type]` - `build-directory`: Path containing build output - `install-type`: "fresh", "upgrade", or "downgrade" **Working Directory**: - By default: Source directory - With `simpleBuildEnvironment` flag: Build directory **Use Case**: System integration, cache generation, service registration **Example**: ```bash #!/bin/bash set -e build_dir=$1 install_type=$2 # Update desktop database update-desktop-database # Update icon cache gtk-update-icon-cache -f -t /usr/share/icons/hicolor ``` ### remove Optional script that runs before USM removes package resources. **Arguments**: `[remove-type]` - `remove-type`: "final", "upgrade", or "downgrade" **Use Case**: Cleanup, service stopping, data preservation **Example**: ```bash #!/bin/bash set -e remove_type=$1 # Stop service if being upgraded if [ "$remove_type" != "final" ]; then systemctl stop myapp || true fi # Remove user data only on final removal if [ "$remove_type" = "final" ]; then rm -rf /var/lib/myapp fi ``` ### acquire Optional script that downloads and extracts source code. **Arguments**: None **Working Directory**: Package root directory **Use Case**: Projects without native USM support, repository packaging **Dependencies**: Listed in `depends.acquire` section **Example**: ```bash #!/bin/bash set -e ARCHIVE_URL="https://github.com/example/myapp/archive/v1.0.0.tar.gz" ARCHIVE_NAME="source.tar.gz" EXTRACT_DIR="." echo "Downloading source..." wget -O ${ARCHIVE_NAME} ${ARCHIVE_URL} echo "Extracting archive..." tar -xzf ${ARCHIVE_NAME} --strip-components=1 echo "Cleaning up..." rm ${ARCHIVE_NAME} ``` ### test Optional script that runs tests after build but before installation. **Arguments**: `[build-directory]` - `build-directory`: Path containing build output **Working Directory**: - By default: Source directory - With `simpleBuildEnvironment` flag: Build directory **Environment Variables**: USM sets the same non-prefixed variables as described in the build script section: - `DESTDIR`, `PREFIX`, `BINDIR`, `INCLUDEDIR`, `DATADIR`, `INFODIR`, `LIBDIR`, `MANDIR`, `LIBEXECDIR`, `LOCALEDIR`, `LOCALSTATEDIR`, `SBINDIR`, `SHAREDSTATEDIR`, `SYSCONFIGDIR`, `TAGSDIR` **Use Case**: Unit tests, integration tests, validation of build artifacts **Example**: ```bash #!/bin/bash set -e build_dir=$1 # With simpleBuildEnvironment flag, we're already in build directory # Without the flag, we need to change to build directory cd ${build_dir} # Run unit tests ./test-suite # Run integration tests ./integration-tests echo "All tests passed" ``` ## Script Requirements ### Permissions All scripts must be executable: ```bash chmod +x usm-scripts/build.sh ``` ### Error Handling Scripts should: - Use `set -e` to exit on errors - Return appropriate exit codes - Handle cleanup on failure ### Environment Variables #### USM Process Variables (Internal Use) The following `USM_*` prefixed environment variables are used by the USM process itself to configure paths: - `USM_DESTDIR`: Destination directory - `USM_PREFIX`: Installation prefix - `USM_BINDIR`: Binary directory - `USM_INCLUDEDIR`: Include directory - `USM_DATADIR`: Data directory - `USM_INFODIR`: Info directory - `USM_LIBDIR`: Library directory - `USM_MANDIR`: Manual directory - `USM_LIBEXECDIR`: Libexec directory - `USM_LOCALEDIR`: Locale directory - `USM_LOCALSTATEDIR`: Local state directory - `USM_SBINDIR`: System binary directory - `USM_SHAREDSTATEDIR`: Shared state directory - `USM_SYSCONFIGDIR`: Configuration directory - `USM_TAGSDIR`: Tags directory - `USM_CONFIGDIR`: USM configuration directory #### Executable Script Variables (For Scripts) USM sets these non-prefixed variables for all executable scripts: - `DESTDIR`: Destination directory - `PREFIX`: Installation prefix - `BINDIR`: Binary directory - `INCLUDEDIR`: Include directory - `DATADIR`: Data directory - `INFODIR`: Info directory - `LIBDIR`: Library directory - `MANDIR`: Manual directory - `LIBEXECDIR`: Libexec directory - `LOCALEDIR`: Locale directory - `LOCALSTATEDIR`: Local state directory - `SBINDIR`: System binary directory - `SHAREDSTATEDIR`: Shared state directory - `SYSCONFIGDIR`: Configuration directory - `TAGSDIR`: Tags directory **Important**: Executable scripts should use the non-prefixed variables (e.g., `${PREFIX}`, `${LIBDIR}`) and NOT the `USM_*` prefixed variables, which are for internal USM process use only. ## Script Locations Scripts can be placed anywhere in the package, but common conventions: - `usm-scripts/`: Directory at package root (recommended) - `scripts/`: Directory at package root (legacy) - Package root: For simple packages ## Build System Integration ### Meson ```bash #!/bin/bash set -e src_dir=$(pwd) build_dir=$1 cd ${build_dir} meson setup ${src_dir} --prefix=${PREFIX} --libdir=${LIBDIR} --bindir=${BINDIR} --includedir=${INCLUDEDIR} ninja ``` ### Make ```bash #!/bin/bash set -e src_dir=$(pwd) build_dir=$1 cd ${build_dir} make PREFIX=${PREFIX} LIBDIR=${LIBDIR} ``` ### CMake ```bash #!/bin/bash set -e src_dir=$(pwd) build_dir=$1 cd ${build_dir} cmake ${src_dir} -DCMAKE_INSTALL_PREFIX=${PREFIX} -DCMAKE_INSTALL_LIBDIR=${LIBDIR} make ``` ## Special Manifest Flags ### simpleBuildEnvironment When the `simpleBuildEnvironment` flag is set in the manifest: - The full source tree is copied to the build directory before executing any build-related scripts - All build-related scripts (build, install, test, postInstall) are executed from the build directory instead of the source directory - This provides a clean, isolated build environment where scripts can safely write to the current directory This flag is particularly useful for: - Build systems that expect to run from the build directory - Projects that need to write temporary files during build - Simplifying build scripts by eliminating the need to change directories ## Progress Reporting When using `ninjaStyleProgress` flag, USM parses build output for progress: - Looks for pattern: `[current/total]` - Updates progress bar accordingly - Requires build system to output this format ## Best Practices ### Script Design - Keep scripts focused on single responsibility - Use absolute paths when available - Handle all required arguments - Validate environment before execution ### Error Handling - Check for required dependencies - Validate input arguments - Provide meaningful error messages - Clean up temporary files on exit ### Portability - Use POSIX-compliant shell syntax - Avoid bash-specific features when possible - Test on target systems - Consider different directory layouts ### Security - Validate input parameters - Use secure temporary directories - Avoid command injection vulnerabilities - Follow principle of least privilege --- This reference provides complete specification for USM executable scripts used throughout package lifecycle management.