diff --git a/contrib/completion/bash/devtools.in b/contrib/completion/bash/devtools.in index f8b1c9f..11fa234 100644 --- a/contrib/completion/bash/devtools.in +++ b/contrib/completion/bash/devtools.in @@ -3,6 +3,8 @@ # SPDX-License-Identifier: GPL-3.0-or-later _DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} +# shellcheck source=src/lib/valid-build-install.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-build-install.sh # shellcheck source=src/lib/valid-tags.sh source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-tags.sh # shellcheck source=src/lib/valid-repos.sh @@ -179,6 +181,8 @@ _pkgctl_build_args=( -c --clean -w --worker --inspect + -I --install-to-chroot + -i --install-to-host --pkgver --pkgrel @@ -199,9 +203,16 @@ _pkgctl_build_args_w_opts() { _pkgctl_build_args__worker_opts; } _pkgctl_build_args__inspect_opts() { _devtools_completions_inspect; } _pkgctl_build_args__pkgver_opts() { :; } _pkgctl_build_args__pkgrel_opts() { :; } +_pkgctl_build_args__install_to_host_opts() { _pkgctl_build_completions_install_mode; } +_pkgctl_build_args_i_opts() { _pkgctl_build_args__install_to_host_opts; } +_pkgctl_build_args__install_to_chroot_opts() { _makechrootpkg_args_I_opts; } +_pkgctl_build_args_I_opts() { _pkgctl_build_args__install_to_chroot_opts; } _pkgctl_build_args__message_opts() { :; } _pkgctl_build_args_m_opts() { _pkgctl_build_args__message_opts; } _pkgctl_build_opts() { _filedir -d; } +_pkgctl_build_completions_install_mode() { + mapfile -t COMPREPLY < <(compgen -W "${DEVTOOLS_VALID_BUILD_INSTALL[*]}" -- "$cur") +} _pkgctl_db_cmds=( diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in index 34f90c6..24e57bf 100644 --- a/contrib/completion/zsh/_devtools.in +++ b/contrib/completion/zsh/_devtools.in @@ -3,6 +3,8 @@ # SPDX-License-Identifier: GPL-3.0-or-later _DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} +# shellcheck source=src/lib/valid-build-install.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-build-install.sh # shellcheck source=src/lib/valid-tags.sh source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-tags.sh # shellcheck source=src/lib/valid-repos.sh @@ -45,8 +47,9 @@ _pkgctl_build_args=( '(-t --testing)'{-t,--testing}'[Build against the testing counterpart of the auto-detected repo]' '(-o --offload)'{-o,--offload}'[Build on a remote server and transfer artifacts afterwards]' '(-c --clean)'{-c,--clean}'[Recreate the chroot before building]' - '(-I --install)'{-I,--install}'[Install a package into the working copy of the chroot]:target:_files -g "*.pkg.tar.*(.)"' "--inspect[Spawn an interactive shell to inspect the chroot (never, always, failure)]:inspect:($DEVTOOLS_VALID_INSPECT_MODES[*])" + '(-I --install-to-chroot)'{-I,--install-to-chroot}'[Install a package to the working copy of the chroot]:target:_files -g "*.pkg.tar.*(.)"' + '(-i --install-to-host)'{-i,--install-to-host}"[Install the built packages to the host system]:mode:($DEVTOOLS_VALID_BUILD_INSTALL[*])" '(-w --worker)'{-w,--worker}'[Name of the worker slot, useful for concurrent builds (disables auto-detection)]:slot:' '--nocheck[Do not run the check() function in the PKGBUILD]' '--pkgver=[Set pkgver, reset pkgrel and update checksums]:pkgver:' diff --git a/doc/man/pkgctl-build.1.asciidoc b/doc/man/pkgctl-build.1.asciidoc index 12deaaa..e7ec714 100644 --- a/doc/man/pkgctl-build.1.asciidoc +++ b/doc/man/pkgctl-build.1.asciidoc @@ -35,9 +35,6 @@ Build Options *-c, --clean*:: Recreate the chroot before building -*-I, --install* 'FILE':: - Install a package into the working copy of the chroot - *--inspect* 'WHEN':: Spawn an interactive shell to inspect the chroot after building. Useful to ease the debugging of a package build. + Possible values for 'WHEN' are `'never'`, `'always'` or `'failure'` @@ -51,6 +48,17 @@ Build Options *--nocheck*:: Do not run the check() function in the PKGBUILD +Install Options +--------------- + +*-I, --install-to-chroot* 'FILE':: + Install a package to the working copy of the chroot + +*-i, --install-to-host* 'MODE':: + Install the built packages to the host system. Useful when one wants to verify that the package works as intended. + * When 'MODE' is 'all', this installs all built packages + * When 'MODE' is 'auto', this installs all built packages which are currently installed + PKGBUILD Options ---------------- diff --git a/src/lib/build/build.sh b/src/lib/build/build.sh index 712be22..64a6ce3 100644 --- a/src/lib/build/build.sh +++ b/src/lib/build/build.sh @@ -20,6 +20,8 @@ source "${_DEVTOOLS_LIBRARY_DIR}"/lib/util/srcinfo.sh source "${_DEVTOOLS_LIBRARY_DIR}"/lib/util/pacman.sh # shellcheck source=src/lib/util/pkgbuild.sh source "${_DEVTOOLS_LIBRARY_DIR}"/lib/util/pkgbuild.sh +# shellcheck source=src/lib/valid-build-install.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-build-install.sh # shellcheck source=src/lib/valid-repos.sh source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-repos.sh # shellcheck source=src/lib/valid-tags.sh @@ -52,11 +54,14 @@ pkgctl_build_usage() { -t, --testing Build against the testing counterpart of the auto-detected repo -o, --offload Build on a remote server and transfer artifacts afterwards -c, --clean Recreate the chroot before building - -I, --install FILE Install a package into the working copy of the chroot --inspect WHEN Spawn an interactive shell to inspect the chroot (never, always, failure) -w, --worker SLOT Name of the worker slot, useful for concurrent builds (disables automatic names) --nocheck Do not run the check() function in the PKGBUILD + INSTALL OPTIONS + -I, --install-to-chroot FILE Install a package to the working copy of the chroot + -i, --install-to-host MODE Install the built package to the host system, possible modes are 'all' and 'auto' + PKGBUILD OPTIONS --pkgver=PKGVER Set pkgver, reset pkgrel and update checksums --pkgrel=PKGREL Set pkgrel to a given value @@ -119,6 +124,7 @@ pkgctl_build() { local TESTING=0 local RELEASE=0 local DB_UPDATE=0 + local INSTALL_TO_HOST=none local REPO= local PKGVER= @@ -131,12 +137,13 @@ pkgctl_build() { local MAKECHROOT_OPTIONS=() local RELEASE_OPTIONS=() local MAKEPKG_OPTIONS=() + local INSTALL_HOST_PACKAGES=() local WORKER= local WORKER_SLOT= # variables - local _arch path pkgbase pkgrepo source pkgbuild_checksum + local _arch path pkgbase pkgrepo source pkgbuild_checksum current_checksum while (( $# )); do case $1 in @@ -209,14 +216,22 @@ pkgctl_build() { BUILD_OPTIONS+=("-c") shift ;; - -I|--install) + -I|--install-to-chroot) (( $# <= 1 )) && die "missing argument for %s" "$1" if (( OFFLOAD )); then MAKECHROOT_OPTIONS+=("-I" "$2") else MAKECHROOT_OPTIONS+=("-I" "$(realpath "$2")") fi - warning 'installing packages into the chroot may break reproducible builds, use with caution!' + warning 'installing packages to the chroot may break reproducible builds, use with caution!' + shift 2 + ;; + -i|--install-to-host) + (( $# <= 1 )) && die "missing argument for %s" "$1" + if ! in_array "$2" "${DEVTOOLS_VALID_BUILD_INSTALL[@]}"; then + die 'invalid install mode: %s' "${2}" + fi + INSTALL_TO_HOST=$2 shift 2 ;; --nocheck) @@ -410,7 +425,9 @@ pkgctl_build() { fi # re-source the PKGBUILD if it changed - if [[ ${pkgbuild_checksum} != "$(b2sum PKGBUILD | awk '{print $1}')" ]]; then + current_checksum="$(b2sum PKGBUILD | awk '{print $1}')" + if [[ ${pkgbuild_checksum} != "${current_checksum}" ]]; then + pkgbuild_checksum=${current_checksum} # shellcheck source=contrib/makepkg/PKGBUILD.proto . ./PKGBUILD fi @@ -432,10 +449,38 @@ pkgctl_build() { fi done + # re-source the PKGBUILD if it changed + current_checksum="$(b2sum PKGBUILD | awk '{print $1}')" + if [[ ${pkgbuild_checksum} != "${current_checksum}" ]]; then + pkgbuild_checksum=${current_checksum} + # shellcheck source=contrib/makepkg/PKGBUILD.proto + . ./PKGBUILD + fi + # auto generate .SRCINFO # shellcheck disable=SC2119 write_srcinfo_file + # test-install (some of) the produced packages + if [[ ${INSTALL_TO_HOST} == auto ]] || [[ ${INSTALL_TO_HOST} == all ]]; then + # shellcheck disable=2119 + load_makepkg_config + + # this is inspired by print_all_package_names from libmakepkg + local version pkg_architecture pkg pkgfile + version=$(get_full_version) + + for pkg in "${pkgname[@]}"; do + pkg_architecture=$(get_pkg_arch "$pkg") + pkgfile=$(realpath "$(printf "%s/%s-%s-%s%s\n" "${PKGDEST:-.}" "$pkg" "$version" "$pkg_architecture" "$PKGEXT")") + + # check if we install all packages or if the (split-)package is already installed + if [[ ${INSTALL_TO_HOST} == all ]] || ( [[ ${INSTALL_TO_HOST} == auto ]] && pacman -Qq -- "$pkg" &>/dev/null ); then + INSTALL_HOST_PACKAGES+=("$pkgfile") + fi + done + fi + # release the build if (( RELEASE )); then pkgctl_release --repo "${pkgrepo}" "${RELEASE_OPTIONS[@]}" @@ -446,6 +491,12 @@ pkgctl_build() { popd >/dev/null done + # install all collected packages to the host system + if (( ${#INSTALL_HOST_PACKAGES[@]} )); then + msg "Installing built packages to the host system" + sudo pacman -U -- "${INSTALL_HOST_PACKAGES[@]}" + fi + # update the binary package repo db as last action if (( RELEASE )) && (( DB_UPDATE )); then # shellcheck disable=2119 diff --git a/src/lib/valid-build-install.sh b/src/lib/valid-build-install.sh new file mode 100644 index 0000000..9e98be2 --- /dev/null +++ b/src/lib/valid-build-install.sh @@ -0,0 +1,11 @@ +#!/hint/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later +: + +# shellcheck disable=2034 +DEVTOOLS_VALID_BUILD_INSTALL=( + none + auto + all +)