index : devtools32 | |
Archlinux32 fork of devtools | gitolite user |
summaryrefslogtreecommitdiff |
author | Andreas Baumann <mail@andreasbaumann.cc> | 2024-08-16 08:06:08 +0200 |
---|---|---|
committer | Andreas Baumann <mail@andreasbaumann.cc> | 2024-08-16 08:06:08 +0200 |
commit | deffc1b87e86fffa8e4758a76a1912c6c8f69a85 (patch) | |
tree | 0f61a152c4c49d40de5042df2b25cdb8e0b0a82d | |
parent | 2994bca96781afd62104c1515532a9c479cb5bed (diff) | |
parent | 27eebe383d0b571c08cba991e4824768d7623602 (diff) |
diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..1b9d768 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,15 @@ +# EditorConfig configuration for devtools +# https://editorconfig.org + +# Top-most EditorConfig file +root = true + +# Unix-style newlines without trailing whitespaces, but with a newline +# ending every file, utf-8 charset, set indent to tabs +[*] +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +charset = utf-8 +indent_style = tab +tab_width = 4 @@ -71,6 +71,7 @@ Component: pkgctl db remove - coreutils - curl - diffutils +- expac - fakeroot - findutils - grep @@ -91,7 +92,6 @@ Component: pkgctl db remove - bat (pretty printing) - nvchecker (version checking) -- pacman-contrib (--update-checksums options for pkgctl build) ### Development Dependencies diff --git a/config/pacman/universe.conf b/config/pacman/universe.conf new file mode 100644 index 0000000..417114b --- /dev/null +++ b/config/pacman/universe.conf @@ -0,0 +1,112 @@ +# +# /etc/pacman.conf +# +# See the pacman.conf(5) manpage for option and repository directives + +# +# GENERAL OPTIONS +# +[options] +# The following paths are commented out with their default values listed. +# If you wish to use different paths, uncomment and update the paths. +#RootDir = / +#DBPath = /var/lib/pacman/ +#CacheDir = /var/cache/pacman/pkg/ +#LogFile = /var/log/pacman.log +#GPGDir = /etc/pacman.d/gnupg/ +#HookDir = /etc/pacman.d/hooks/ +HoldPkg = pacman glibc +#XferCommand = /usr/bin/curl -L -C - -f -o %o %u +#XferCommand = /usr/bin/wget --passive-ftp -c -O %o %u +#CleanMethod = KeepInstalled +Architecture = auto + +# Pacman won't upgrade packages listed in IgnorePkg and members of IgnoreGroup +#IgnorePkg = +#IgnoreGroup = + +#NoUpgrade = +#NoExtract = + +# Misc options +#UseSyslog +#Color +NoProgressBar +# We cannot check disk space from within a chroot environment +#CheckSpace +VerbosePkgLists +ParallelDownloads = 5 + +# By default, pacman accepts packages signed by keys that its local keyring +# trusts (see pacman-key and its man page), as well as unsigned packages. +SigLevel = Required DatabaseOptional +LocalFileSigLevel = Optional +#RemoteFileSigLevel = Required + +# NOTE: You must run `pacman-key --init` before first using pacman; the local +# keyring can then be populated with the keys of all official Arch Linux +# packagers with `pacman-key --populate archlinux`. + +# +# REPOSITORIES +# - can be defined here or included from another file +# - pacman will search repositories in the order defined here +# - local/custom mirrors can be added here or in separate files +# - repositories listed first will take precedence when packages +# have identical names, regardless of version number +# - URLs will have $repo replaced by the name of the current repo +# - URLs will have $arch replaced by the name of the architecture +# +# Repository entries are of the format: +# [repo-name] +# Server = ServerName +# Include = IncludePath +# +# The header [repo-name] is crucial - it must be present and +# uncommented to enable the repo. +# + +# The testing repositories are disabled by default. To enable, uncomment the +# repo name header and Include lines. You can add preferred servers immediately +# after the header, and they will be used before the default mirrors. + +[gnome-unstable] +Include = /etc/pacman.d/mirrorlist + +[kde-unstable] +Include = /etc/pacman.d/mirrorlist + +[core-staging] +Include = /etc/pacman.d/mirrorlist + +[core-testing] +Include = /etc/pacman.d/mirrorlist + +[core] +Include = /etc/pacman.d/mirrorlist + +[extra-staging] +Include = /etc/pacman.d/mirrorlist + +[extra-testing] +Include = /etc/pacman.d/mirrorlist + +[extra] +Include = /etc/pacman.d/mirrorlist + +# If you want to run 32 bit applications on your x86_64 system, +# enable the multilib repositories as required here. +[multilib-staging] +Include = /etc/pacman.d/mirrorlist + +[multilib-testing] +Include = /etc/pacman.d/mirrorlist + +[multilib] +Include = /etc/pacman.d/mirrorlist + +# An example of a custom package repository. See the pacman manpage for +# tips on creating your own repositories. +#[custom] +#SigLevel = Optional TrustAll +#Server = file:///home/custompkgs diff --git a/config/pacman/unstable.conf b/config/pacman/unstable.conf new file mode 100644 index 0000000..408d0ce --- /dev/null +++ b/config/pacman/unstable.conf @@ -0,0 +1,83 @@ +# +# /etc/pacman.conf +# +# See the pacman.conf(5) manpage for option and repository directives + +# +# GENERAL OPTIONS +# +[options] +# The following paths are commented out with their default values listed. +# If you wish to use different paths, uncomment and update the paths. +#RootDir = / +#DBPath = /var/lib/pacman/ +#CacheDir = /var/cache/pacman/pkg/ +#LogFile = /var/log/pacman.log +#GPGDir = /etc/pacman.d/gnupg/ +#HookDir = /etc/pacman.d/hooks/ +HoldPkg = pacman glibc +#XferCommand = /usr/bin/curl -L -C - -f -o %o %u +#XferCommand = /usr/bin/wget --passive-ftp -c -O %o %u +#CleanMethod = KeepInstalled +Architecture = auto + +# Pacman won't upgrade packages listed in IgnorePkg and members of IgnoreGroup +#IgnorePkg = +#IgnoreGroup = + +#NoUpgrade = +#NoExtract = + +# Misc options +#UseSyslog +#Color +NoProgressBar +# We cannot check disk space from within a chroot environment +#CheckSpace +VerbosePkgLists +ParallelDownloads = 5 + +# By default, pacman accepts packages signed by keys that its local keyring +# trusts (see pacman-key and its man page), as well as unsigned packages. +SigLevel = Required DatabaseOptional +LocalFileSigLevel = Optional +#RemoteFileSigLevel = Required + +# NOTE: You must run `pacman-key --init` before first using pacman; the local +# keyring can then be populated with the keys of all official Arch Linux +# packagers with `pacman-key --populate archlinux`. + +# +# REPOSITORIES +# - can be defined here or included from another file +# - pacman will search repositories in the order defined here +# - local/custom mirrors can be added here or in separate files +# - repositories listed first will take precedence when packages +# have identical names, regardless of version number +# - URLs will have $repo replaced by the name of the current repo +# - URLs will have $arch replaced by the name of the architecture +# +# Repository entries are of the format: +# [repo-name] +# Server = ServerName +# Include = IncludePath +# +# The header [repo-name] is crucial - it must be present and +# uncommented to enable the repo. +# + +# The testing repositories are disabled by default. To enable, uncomment the +# repo name header and Include lines. You can add preferred servers immediately +# after the header, and they will be used before the default mirrors. + +[gnome-unstable] +Include = /etc/pacman.d/mirrorlist + +[kde-unstable] +Include = /etc/pacman.d/mirrorlist + +# An example of a custom package repository. See the pacman manpage for +# tips on creating your own repositories. +#[custom] +#SigLevel = Optional TrustAll +#Server = file:///home/custompkgs diff --git a/contrib/completion/bash/devtools.in b/contrib/completion/bash/devtools.in index 136c80f..9025b46 100644 --- a/contrib/completion/bash/devtools.in +++ b/contrib/completion/bash/devtools.in @@ -14,7 +14,6 @@ source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-inspect.sh # shellcheck source=src/lib/valid-search.sh source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-search.sh -_binary_arch=${DEVTOOLS_VALID_ARCHES[*]:0:-1} _colors=(never always auto) @@ -28,6 +27,7 @@ _makechrootpkg_args=( -I -l -n + -t -T -U -x @@ -37,6 +37,7 @@ _makechrootpkg_args_D_opts() { _filedir -d; } _makechrootpkg_args_r_opts() { _filedir -d; } _makechrootpkg_args_I_opts() { _filedir '*.pkg.tar.*'; } _makechrootpkg_args_l_opts() { _filedir -d; } +_makechrootpkg_args_t_opts() { _filedir -d; } _makechrootpkg_args_U_opts() { :; } _makechrootpkg_args_x_opts() { _devtools_completions_inspect; } _makechrootpkg() { __devtools_complete _makechrootpkg; } @@ -62,12 +63,14 @@ _mkarchroot_args=( -C -M -c + -f -h ) _mkarchroot_args_U_opts() { _filedir '*.pkg.tar.*'; } _mkarchroot_args_C_opts() { _filedir '*.conf'; } _mkarchroot_args_M_opts() { _filedir '*.conf'; } _mkarchroot_args_c_opts() { _filedir -d; } +_mkarchroot_args_f_opts() { _filedir -d; } _mkarchroot_opts() { local args args=$(__pkgctl_word_count_after_subcommand) @@ -128,7 +131,7 @@ _offload_build_args=( ) _offload_build_args__repo_opts() { _devtools_completions_build_repo; } _offload_build_args_r_opts() { _offload_build_args__repo_opts; } -_offload_build_args__arch_opts() { _devtools_completions_arch; } +_offload_build_args__arch_opts() { _devtools_completions_binary_arch; } _offload_build_args_a_opts() { _offload_build_args__arch_opts; } _offload_build_args__server_opts() { :; } _offload_build_args_s_opts() { _offload_build_args__server_opts; } @@ -196,7 +199,7 @@ _pkgctl_build_args=( -h --help ) -_pkgctl_build_args__arch_opts() { _devtools_completions_arch; } +_pkgctl_build_args__arch_opts() { _devtools_completions_binary_arch; } _pkgctl_build_args__repo_opts() { _devtools_completions_repo; } _pkgctl_build_args__worker_opts() { :; } _pkgctl_build_args_w_opts() { _pkgctl_build_args__worker_opts; } @@ -241,9 +244,13 @@ _pkgctl_db_move_opts() { _pkgctl_db_remove_args=( + --partial + --noconfirm -a --arch -h --help ) +_pkgctl_db_remove_args__arch_opts() { _devtools_completions_binary_arch; } +_pkgctl_db_remove_args_a_opts() { _pkgctl_db_remove_args__arch_opts; } _pkgctl_db_remove_opts() { local subcommand args subcommand=(db remove) @@ -289,6 +296,7 @@ _pkgctl_aur_drop_from_repo_opts() { _filedir -d; } _pkgctl_repo_cmds=( + clean clone configure create @@ -314,6 +322,12 @@ _pkgctl_repo_clone_args__jobs_opts() { :; } _pkgctl_repo_clone_args_j_opts() { _pkgctl_repo_clone_args__jobs_opts; } _pkgctl_repo_clone_opts() { _devtools_completions_all_packages; } +_pkgctl_repo_clean_args=( + -i --interactive + -n --dry-run + -h --help +) +_pkgctl_repo_clean_opts() { _filedir -d; } _pkgctl_repo_configure_args=( --protocol @@ -373,6 +387,7 @@ _pkgctl_version_setup_opts() { _filedir -d; } _pkgctl_version_setup_args__url_opts() { :; } _pkgctl_version_upgrade_args=( + --no-update-checksums -v --verbose -h --help ) @@ -433,6 +448,9 @@ _devtools_completions_color() { _devtools_completions_arch() { mapfile -t COMPREPLY < <(compgen -W "${DEVTOOLS_VALID_ARCHES[*]}" -- "$cur") } +_devtools_completions_binary_arch() { + mapfile -t COMPREPLY < <(compgen -W "${DEVTOOLS_VALID_BINARY_ARCHES[*]}" -- "$cur") +} _devtools_completions_repo() { local optional=${1:-} mapfile -t COMPREPLY < <(compgen -W "${optional} ${DEVTOOLS_VALID_REPOS[*]}" -- "$cur") diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in index f430dae..5c1b264 100644 --- a/contrib/completion/zsh/_devtools.in +++ b/contrib/completion/zsh/_devtools.in @@ -14,7 +14,6 @@ source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-inspect.sh # shellcheck source=src/lib/valid-search.sh source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-search.sh -_binary_arch=${DEVTOOLS_VALID_ARCHES[*]:0:-1} _colors=(never always auto) _archbuild_args=( @@ -41,8 +40,8 @@ _pkgctl_auth_status_args=( ) _pkgctl_build_args=( - "--arch=[Specify architectures to build for (disables auto-detection)]:arch:($_arch[*])" - "--repo=[Specify a target repository (disables auto-detection)]:repo:($DEVTOOLS_VALID_REPOS[*])" + "--arch[Specify architectures to build for (disables auto-detection)]:arch:($DEVTOOLS_VALID_BINARY_ARCHES[*])" + "--repo[Specify a target repository (disables auto-detection)]:repo:($DEVTOOLS_VALID_REPOS[*])" '(-s --staging)'{-s,--staging}'[Build against the staging counterpart of the auto-detected repo]' '(-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]' @@ -79,7 +78,9 @@ _pkgctl_db_move_args=( ) _pkgctl_db_remove_args=( - '(-a --arch=)'{-a,--arch=}"[Override the architecture (disables auto-detection)]:arch:($_arch[*])" + '--partial[Remove only partial pkgnames from a split package]' + '--noconfirm[Bypass any confirmation messages, should only be used with caution]' + '(-a --arch)'{-a,--arch}"[Override the architecture (disables auto-detection)]:arch:($DEVTOOLS_VALID_BINARY_ARCHES[*])" '(-h --help)'{-h,--help}'[Display usage]' "1:repo:($DEVTOOLS_VALID_REPOS[*])" '*:pkgbase:_devtools_completions_all_packages' @@ -113,6 +114,7 @@ _pkgctl_aur_drop_from_repo_args=( _pkgctl_repo_cmds=( "pkgctl repo command" + "clean[Remove untracked files from the working tree]" "clone[Clone a package repository]" "configure[Configure a clone according to distro specs]" "create[Create a new GitLab package repository]" @@ -127,6 +129,13 @@ _pkgctl_repo_switch_args=( '*:git_dir:_files -/' ) +_pkgctl_repo_clean_args=( + '(-i --interactive)'{-i,--interactive}'[Show what would be done and clean files interactively]' + '(-n --dry-run)'{-n,--dry-run}"[Don't remove anything, just show what would be done]" + '(-h --help)'{-h,--help}'[Display usage]' + '*:git_dir:_files -/' +) + _pkgctl_repo_clone_args=( '(-m --maintainer=)'{-m,--maintainer=}'[Clone all packages of the named maintainer]:maintainer:' '--protocol[Clone the repository over https]:proto:(https)' @@ -213,6 +222,7 @@ _makechrootpkg_args=( '-c[Clean the chroot before building]' '*-d[Bind directory into build chroot as read-write]:bind_dir_rw:_files -/' '*-D[Bind directory into build chroot as read-only]:bind_dir_ro:_files -/' + '*-t[Mount a tmpfs at directory]:tmpfs_dir:_files -/' '-u[Update the working copy of the chroot before building]' '-r[The chroot dir to use]:chroot_dir:_files -/' '*-I[Install a package into the working copy]:target:_files -g "*.pkg.tar.*(.)"' @@ -228,6 +238,7 @@ _mkarchroot_args=( '-C[Location of a pacman config file]:pacman_config:_files -g "*.conf(.)"' '-M[Location of a makepkg config file]:makepkg_config:_files -g "*.conf(.)"' '-c[Set pacman cache]:pacman_cache:_files -/' + '-f[Copy src file from the host to the chroot]:target:_files -/' '-h[Display usage]' '1:working_dir:_files -/' '*:packages:_devtools_completions_all_packages' @@ -250,7 +261,7 @@ _sogrep_args=( _offload_build_args=( '(-r --repo)'{-r,--repo}'[Build against a specific repository]:repo:($DEVTOOLS_VALID_BUILDREPOS[*])' - '(-a --arch)'{-a,--arch}'[Build against a specific architecture]:arch:(${_binary_arch[*]})' + '(-a --arch)'{-a,--arch}'[Build against a specific architecture]:arch:(${DEVTOOLS_VALID_BINARY_ARCHES[*]})' '(-s --server)'{-s,--server}'[Offload to a specific Build server]:server:' '(-h --help)'{-h,--help}'[Display usage]' ) @@ -311,6 +322,7 @@ _pkgctl_version_setup_args=( ) _pkgctl_version_upgrade_args=( + '--no-update-checksums[Disable computation and update of the checksums]' '(-v --verbose)'{-v,--verbose}'[Display results including up-to-date versions]' '(-h --help)'{-h,--help}'[Display usage]' '*:git_dir:_files -/' diff --git a/doc/man/arch-nspawn.1.asciidoc b/doc/man/arch-nspawn.1.asciidoc index a3e8ec1..ae6532b 100644 --- a/doc/man/arch-nspawn.1.asciidoc +++ b/doc/man/arch-nspawn.1.asciidoc @@ -28,8 +28,9 @@ Options *-c* <dir>:: Set pacman cache, if no directory is specified the passed pacman.conf's cachedir is used with a fallback to '/etc/pacman.conf' -*-f* <file>:: - Copy file from the host to the chroot +*-f* <src>[:<dst>]:: + Copy file from the host to the chroot. + If 'dst' is not provided, it defaults to 'src' inside of the chroot. *-s*:: Do not run setarch diff --git a/doc/man/makechrootpkg.1.asciidoc b/doc/man/makechrootpkg.1.asciidoc index 3aa1be5..34ba199 100644 --- a/doc/man/makechrootpkg.1.asciidoc +++ b/doc/man/makechrootpkg.1.asciidoc @@ -45,6 +45,9 @@ Options *-D* <dir>:: Bind directory into build chroot as read-only +*-t* <dir>[:opts]:: + Mount a tmpfs at 'dir'. See the '--tmpfs' argument in systemd-nspawn(1) for more details. + *-u*:: Update the working copy of the chroot before building This is useful for rebuilds without dirtying the pristine @@ -76,5 +79,9 @@ Options *-x* <when>:: Inspect chroot after build, possible modes are 'never' (default), 'always' or 'failure' +See Also +-------- + +systemd-nspawn(1) include::include/footer.asciidoc[] diff --git a/doc/man/mkarchroot.1.asciidoc b/doc/man/mkarchroot.1.asciidoc index 99905c8..edbb17e 100644 --- a/doc/man/mkarchroot.1.asciidoc +++ b/doc/man/mkarchroot.1.asciidoc @@ -32,8 +32,9 @@ Options *-c* <dir>:: Set pacman cache. -*-f* <file>:: +*-f* <src>[:<dst>]:: Copy file from the host to the chroot. + If 'dst' is not provided, it defaults to 'src' inside of the chroot. *-s*:: Do not run setarch. diff --git a/doc/man/pkgctl-build.1.asciidoc b/doc/man/pkgctl-build.1.asciidoc index d36daff..beb6ee4 100644 --- a/doc/man/pkgctl-build.1.asciidoc +++ b/doc/man/pkgctl-build.1.asciidoc @@ -12,7 +12,8 @@ pkgctl build [OPTIONS] [PATH...] Description ----------- -TODO +Build packages in clean chroot environment, offering various options +and functionalities to customize the package building process. Build Options ------------- diff --git a/doc/man/pkgctl-db-remove.1.asciidoc b/doc/man/pkgctl-db-remove.1.asciidoc index a95766d..85f616b 100644 --- a/doc/man/pkgctl-db-remove.1.asciidoc +++ b/doc/man/pkgctl-db-remove.1.asciidoc @@ -12,13 +12,27 @@ pkgctl db remove [OPTIONS] [REPO] [PKGBASE]... Description ----------- -Remove packages from pacman repositories. +Remove packages from pacman repositories. By default passing a pkgbase removes +all split packages, debug packages as well as entries from the state repo for +all existing architectures. + +Beware when using the `--partial` option, as it may most likely lead to +undesired effects by leaving debug packages behind as well as dangling entries +in the state repository. Options ------- +*--partial*:: + Remove only partial pkgnames from a split package. This leaves debug + packages behind and pkgbase entries in the state repo. + *-a, --arch* 'ARCH':: - Override the architecture (disables auto-detection) + Remove only one specific architecture (disables auto-detection). + By default all architectures are removed when this option is not used. + +*--noconfirm*:: + Bypass any confirmation messages, should only be used with caution. *-h, --help*:: Show a help text diff --git a/doc/man/pkgctl-db.1.asciidoc b/doc/man/pkgctl-db.1.asciidoc new file mode 100644 index 0000000..d3296c6 --- /dev/null +++ b/doc/man/pkgctl-db.1.asciidoc @@ -0,0 +1,43 @@ +pkgctl-db(1) +============ + +NAME +---- +pkgctl-db - Pacman database modification utility for package updates, moves, and more. + +SYNOPSIS +-------- +pkgctl db [OPTIONS] [SUBCOMMAND] + +DESCRIPTION +----------- + +Managing the Pacman database and facilitate the modification of packages and their metadata +within the database + +OPTIONS +------- + +*-h, --help*:: + Display usage information and available options. + +Subcommands +----------- + +pkgctl db update:: + Update the binary repository as final release step + +pkgctl db move:: + Move packages between binary repositories + +pkgctl db remove:: + Remove packages from binary repositories + +SEE ALSO +-------- + +pkgctl-db-update(1) +pkgctl-db-move(1) +pkgctl-db-remove(1) + +include::include/footer.asciidoc[] diff --git a/doc/man/pkgctl-repo-clean.1.asciidoc b/doc/man/pkgctl-repo-clean.1.asciidoc new file mode 100644 index 0000000..b39693c --- /dev/null +++ b/doc/man/pkgctl-repo-clean.1.asciidoc @@ -0,0 +1,40 @@ +pkgctl-repo-clean(1) +==================== + +Name +---- + +pkgctl-repo-clean - Remove untracked files from the working tree + +Synopsis +-------- + +pkgctl repo clean [OPTION] [PATH]... + +Description +----------- + +Cleans the working tree by recursively removing files that are not under +version control, starting from the current directory. + +Files unknown to Git as well as ignored files are removed. This can, for +example, be useful to remove all build products. + +Options +------- + +*-i, --interactive*:: + Show what would be done and clean files interactively + +*-n, --dry-run*:: + Don't actually remove anything, just show what would be done + +*-h, --help*:: + Show a help text + +See Also +-------- + +git-clean(1) + +include::include/footer.asciidoc[] diff --git a/doc/man/pkgctl-repo.1.asciidoc b/doc/man/pkgctl-repo.1.asciidoc index 3d0f3f1..c1fd298 100644 --- a/doc/man/pkgctl-repo.1.asciidoc +++ b/doc/man/pkgctl-repo.1.asciidoc @@ -32,6 +32,9 @@ Options Subcommands ----------- +pkgctl repo clean:: + Remove untracked files from the working tree + pkgctl repo clone:: Clone a package repository @@ -50,6 +53,7 @@ pkgctl repo web:: See Also -------- +pkgctl-repo-clean(1) pkgctl-repo-clone(1) pkgctl-repo-configure(1) pkgctl-repo-create(1) diff --git a/doc/man/pkgctl-version-upgrade.1.asciidoc b/doc/man/pkgctl-version-upgrade.1.asciidoc index 044545d..0cec0b6 100644 --- a/doc/man/pkgctl-version-upgrade.1.asciidoc +++ b/doc/man/pkgctl-version-upgrade.1.asciidoc @@ -18,7 +18,7 @@ upstream versions. Upon execution, it automatically adjusts the PKGBUILD file, ensuring that the pkgver field is set to match the latest version available from the upstream source. In addition to updating the pkgver, this command also resets the pkgrel -to 1. +to 1 and updates checksums. Outputs a summary of upgraded packages, up-to-date packages, and any check failures. @@ -35,6 +35,9 @@ PKGBUILD. Refer to the configuration section in pkgctl-version(1). Options ------- +*--no-update-checksums*:: + Disable computation and update of the checksums + *-v, --verbose*:: Display results including up-to-date versions diff --git a/doc/man/pkgctl.1.asciidoc b/doc/man/pkgctl.1.asciidoc index e028e84..287a62a 100644 --- a/doc/man/pkgctl.1.asciidoc +++ b/doc/man/pkgctl.1.asciidoc @@ -12,7 +12,12 @@ pkgctl [SUBCOMMAND] [OPTIONS] Description ----------- -TODO +Command-line utility serving as a unified interface for multiple development tools. +This tool aims to simplify and optimize interactions with devtools by offering +various subcommands for executing tasks related to package management, repository management, +version control, among others. + +Utilizing pkgctl enables users to efficiently administer their development workflows. Options ------- diff --git a/src/arch-nspawn.in b/src/arch-nspawn.in index 8fcdead..54e474f 100644 --- a/src/arch-nspawn.in +++ b/src/arch-nspawn.in @@ -22,12 +22,13 @@ usage() { echo "A wrapper around systemd-nspawn. Provides support for pacman." echo echo ' options:' - echo ' -C <file> Location of a pacman config file' - echo ' -M <file> Location of a makepkg config file' - echo ' -c <dir> Set pacman cache' - echo ' -f <file> Copy file from the host to the chroot' - echo ' -s Do not run setarch' - echo ' -h This message' + echo ' -C <file> Location of a pacman config file' + echo ' -M <file> Location of a makepkg config file' + echo ' -c <dir> Set pacman cache' + echo ' -f <src>[:<dst>] Copy src file from the host to the chroot.' + echo ' If dst file is not provided, it defaults to src' + echo ' -s Do not run setarch' + echo ' -h This message' exit 1 } @@ -63,6 +64,7 @@ nspawn_args=( --slice="devtools-$(systemd-escape "${SUDO_USER:-$USER}")" --machine="arch-nspawn-$$" --as-pid2 + --console=autopipe ) if (( ${#cache_dirs[@]} == 0 )); then @@ -71,6 +73,7 @@ fi # shellcheck disable=2016 host_mirrors=($(pacman-conf --config "${pac_conf:-$working_dir/etc/pacman.conf}" --repo extra Server 2> /dev/null | sed -r 's#(.*/)extra/os/.*#\1$repo/os/$arch#;t;s#(.*/)[^/]+/extra(/?)$#\1$arch/$repo\2#')) +host_cachemirrors=($(pacman-conf --config "${pac_conf:-$working_dir/etc/pacman.conf}" --repo extra CacheServer 2> /dev/null | sed -r 's#(.*/)extra/os/.*#\1$repo/os/$arch#')) for host_mirror in "${host_mirrors[@]}"; do if [[ $host_mirror == *file://* ]]; then @@ -107,13 +110,17 @@ copy_hostconf () { tee "$working_dir/etc/pacman.d/mirrorlist" > \ "$working_dir/etc/pacman.d/mirrorlist32" + [[ -n $host_cachemirrors ]] && printf 'CacheServer = %s\n' "${host_cachemirrors[@]}" >>"$working_dir/etc/pacman.d/mirrorlist" + [[ -n $pac_conf ]] && cp "$pac_conf" "$working_dir/etc/pacman.conf" [[ -n $makepkg_conf ]] && cp "$makepkg_conf" "$working_dir/etc/makepkg.conf" local file for file in "${files[@]}"; do - mkdir -p "$(dirname "$working_dir$file")" - cp -T "$file" "$working_dir$file" + src="${file%%:*}" + dst="${file#*:}" + mkdir -p "$(dirname "$working_dir$dst")" + cp -T "$src" "$working_dir$dst" done sed -r "s|^#?\\s*CacheDir.+|CacheDir = ${cache_dirs[*]}|g" -i "$working_dir/etc/pacman.conf" diff --git a/src/checkpkg.in b/src/checkpkg.in index ccb7259..6ee18c6 100644 --- a/src/checkpkg.in +++ b/src/checkpkg.in @@ -140,7 +140,7 @@ for _pkgname in "${pkgname[@]}"; do bsdtar tf "$TEMPDIR/$oldpkg" | sort > "$TEMPDIR/filelist-$_pkgname-old" bsdtar tf "$pkgfile" | sort > "$TEMPDIR/filelist-$_pkgname" - sdiff -s "$TEMPDIR/filelist-$_pkgname-old" "$TEMPDIR/filelist-$_pkgname" + diff --side-by-side --suppress-common-lines --width="$COLUMNS" --color=auto "$TEMPDIR/filelist-$_pkgname-old" "$TEMPDIR/filelist-$_pkgname" find-libprovides "$TEMPDIR/$oldpkg" 2>/dev/null | sort > "$TEMPDIR/libraries-$_pkgname-old" find-libprovides "$pkgfile" 2>/dev/null | sort > "$TEMPDIR/libraries-$_pkgname" diff --git a/src/commitpkg.in b/src/commitpkg.in index e17b270..deb02be 100644 --- a/src/commitpkg.in +++ b/src/commitpkg.in @@ -151,7 +151,7 @@ fi server=${PACKAGING_REPO_RELEASE_HOST} -rsyncopts=(-e ssh -p '--chmod=ug=rw,o=r' -c -h -L --progress --partial -y) +rsyncopts=("${RSYNC_OPTS[@]}" --perms --chmod='ug=rw,o=r') archreleaseopts=() while getopts ':l:a:s:f' flag; do case $flag in diff --git a/src/lib/build/build.sh b/src/lib/build/build.sh index c35d70f..9f724dd 100644 --- a/src/lib/build/build.sh +++ b/src/lib/build/build.sh @@ -80,7 +80,7 @@ pkgctl_build_usage() { EXAMPLES $ ${COMMAND} $ ${COMMAND} --rebuild --staging --message 'libyay 0.42 rebuild' libfoo libbar - $ ${COMMAND} --pkgver 1.42 --release --db-update + $ ${COMMAND} --pkgver=1.42 --release --db-update _EOF_ } @@ -312,7 +312,7 @@ pkgctl_build() { # Update pacman cache for auto-detection if [[ -z ${REPO} ]]; then - update_pacman_repo_cache + update_pacman_repo_cache multilib # Check valid repos if not resolved dynamically elif ! in_array "${REPO}" "${DEVTOOLS_VALID_REPOS[@]}"; then die "Invalid repository target: %s" "${REPO}" @@ -437,10 +437,11 @@ pkgctl_build() { stat_done fi - # update checksums if any sources are declared if (( UPDATE_CHECKSUMS )) && (( ${#source[@]} >= 1 )); then - updpkgsums + if ! result=$(pkgbuild_update_checksums /dev/stderr); then + die "${result}" + fi fi # re-source the PKGBUILD if it changed diff --git a/src/lib/common.sh b/src/lib/common.sh index 00ece97..5416eaf 100644 --- a/src/lib/common.sh +++ b/src/lib/common.sh @@ -15,6 +15,9 @@ $DEVTOOLS_INCLUDE_COMMON_SH # Avoid any encoding problems export LANG=C.UTF-8 +# Avoid systemd trying to color the terminal on systemd-nspawn +export SYSTEMD_TINT_BACKGROUND=no + # Set buildtool properties export BUILDTOOL=devtools export BUILDTOOLVER=@buildtoolver@ @@ -31,6 +34,17 @@ export PACKAGING_REPO_RELEASE_HOST=repos.archlinux.org export PKGBASE_MAINTAINER_URL=https://archlinux.org/packages/pkgbase-maintainer export AUR_URL_SSH=aur@aur.archlinux.org +export RSYNC_OPTS=( + --rsh=ssh + --checksum + --copy-links + --human-readable + --progress + --partial + --partial-dir=.partial + --delay-updates +) + # ensure TERM is set with a fallback to dumb export TERM=${TERM:-dumb} @@ -106,6 +120,8 @@ print_workdir_error() { } _setup_workdir=false +# Ensure that there is no outside value for WORKDIR leaking in +unset WORKDIR setup_workdir() { [[ -z ${WORKDIR:-} ]] && WORKDIR=$(mktemp -d --tmpdir "${0##*/}.XXXXXXXXXX") _setup_workdir=true @@ -343,6 +359,14 @@ is_debug_package() { [[ ${pkgdesc} == "Detached debugging symbols for "* && ${pkgbase}-debug = "${pkgname}" ]] } +# Proxy function to check if a file exists. Using [[ -f ... ]] directly is not +# always wanted because we might want to expand bash globs first. This way we +# can pass unquoted globs to is_globfile() and have them expanded as function +# arguments before being checked. +is_globfile() { + [[ -f $1 ]] +} + join_by() { local IFS="$1" shift diff --git a/src/lib/db/remove.sh b/src/lib/db/remove.sh index ba21c83..cddcc1d 100644 --- a/src/lib/db/remove.sh +++ b/src/lib/db/remove.sh @@ -8,6 +8,12 @@ DEVTOOLS_INCLUDE_DB_REMOVE_SH=1 _DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} # shellcheck source=src/lib/common.sh source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh +# shellcheck source=src/lib/util/pacman.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/util/pacman.sh +# shellcheck source=src/lib/util/term.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/util/term.sh +# shellcheck source=src/lib/valid-repos.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-repos.sh set -e @@ -17,10 +23,19 @@ pkgctl_db_remove_usage() { cat <<- _EOF_ Usage: ${COMMAND} [OPTIONS] [REPO] [PKGBASE]... - Remove packages from binary repositories. + Remove packages from pacman repositories. By default passing a pkgbase removes + all split packages, debug packages as well as entries from the state repo for + all existing architectures. + + Beware when using the --partial option, as it may most likely lead to + undesired effects by leaving debug packages behind as well as dangling entries + in the state repository. OPTIONS - -a, --arch Override the architecture (disables auto-detection) + -a, --arch Remove only one specific architecture (disables auto-detection) + --partial Remove only partial pkgnames from a split package. This leaves + debug packages behind and pkgbase entries in the state repo. + --noconfirm Bypass any confirmation messages, should only be used with caution -h, --help Show this help text EXAMPLES @@ -31,8 +46,13 @@ _EOF_ pkgctl_db_remove() { local REPO="" - local ARCH=any local PKGBASES=() + local pkgnames=() + local partial=0 + local confirm=1 + local dbscripts_options=() + local lookup_repo=multilib + local pkgname # option checking while (( $# )); do @@ -41,11 +61,20 @@ pkgctl_db_remove() { pkgctl_db_remove_usage exit 0 ;; + --partial) + partial=1 + dbscripts_options+=(--partial) + shift + ;; -a|--arch) (( $# <= 1 )) && die "missing argument for %s" "$1" - ARCH=$2 + dbscripts_options+=(--arch "$2") shift 2 ;; + --noconfirm) + confirm=0 + shift + ;; -*) die "invalid argument: %s" "$1" ;; @@ -63,7 +92,62 @@ pkgctl_db_remove() { REPO=$1 shift PKGBASES+=("$@") + pkgnames=("${PKGBASES[@]}") + + # check if the target repo is valid + if ! in_array "${REPO}" "${DEVTOOLS_VALID_REPOS[@]}"; then + die "Invalid repository target: %s" "${REPO}" + fi + + # update pacman cache to query all pkgnames + if (( ! partial )); then + case ${REPO} in + *-unstable) + update_pacman_repo_cache unstable + ;; + *-staging) + update_pacman_repo_cache multilib-staging + ;; + *-testing) + update_pacman_repo_cache multilib-testing + ;; + *) + update_pacman_repo_cache multilib + ;; + esac + + # fetch the pkgnames of all pkgbase as present in the repo + mapfile -t pkgnames < <(get_pkgnames_from_repo_pkgbase "${REPO}" "${PKGBASES[@]}") + echo + + if (( ! ${#pkgnames[@]} )); then + error "Packages not found in %s" "${REPO}" + exit 1 + fi + fi + + # print list of packages + printf "%sRemoving packages from %s:%s\n" "${RED}" "${REPO}" "${ALL_OFF}" + for pkgname in "${pkgnames[@]}"; do + printf "• %s\n" "${pkgname}" + done + + # print explenation about partial removal + if (( partial )); then + echo + msg_warn "${YELLOW}Removing only partial pkgnames from a split package.${ALL_OFF}" + msg_warn "${YELLOW}This leaves debug packages and pkgbase entries in the state repo!${ALL_OFF}" + fi + + # ask for confirmation + if (( confirm )); then + echo + if ! prompt "${GREEN}${BOLD}?${ALL_OFF} Are you sure this is correct?"; then + exit 1 + fi + fi + echo # shellcheck disable=SC2029 - ssh "${PACKAGING_REPO_RELEASE_HOST}" db-remove "${REPO}" "${ARCH}" "${PKGBASES[@]}" + ssh "${PACKAGING_REPO_RELEASE_HOST}" db-remove "${dbscripts_options[@]}" "${REPO}" "${PKGBASES[@]}" } diff --git a/src/lib/release.sh b/src/lib/release.sh index acb3b54..ba21384 100644 --- a/src/lib/release.sh +++ b/src/lib/release.sh @@ -124,7 +124,7 @@ pkgctl_release() { # Update pacman cache for auto-detection if [[ -z ${REPO} ]]; then - update_pacman_repo_cache + update_pacman_repo_cache multilib # Check valid repos if not resolved dynamically elif ! in_array "${REPO}" "${DEVTOOLS_VALID_REPOS[@]}"; then die "Invalid repository target: %s" "${REPO}" diff --git a/src/lib/repo.sh b/src/lib/repo.sh index 9f545e9..8f8dd0a 100644 --- a/src/lib/repo.sh +++ b/src/lib/repo.sh @@ -27,6 +27,7 @@ pkgctl_repo_usage() { without SSH access using read-only HTTPS. COMMANDS + clean Remove untracked files from the working tree clone Clone a package repository configure Configure a clone according to distro specs create Create a new GitLab package repository @@ -37,6 +38,7 @@ pkgctl_repo_usage() { -h, --help Show this help text EXAMPLES + $ ${COMMAND} clean --interactive * $ ${COMMAND} clone libfoo linux libbar $ ${COMMAND} clone --maintainer mynickname $ ${COMMAND} configure * @@ -59,6 +61,14 @@ pkgctl_repo() { pkgctl_repo_usage exit 0 ;; + clean) + _DEVTOOLS_COMMAND+=" $1" + shift + # shellcheck source=src/lib/repo/clean.sh + source "${_DEVTOOLS_LIBRARY_DIR}"/lib/repo/clean.sh + pkgctl_repo_clean "$@" + exit 0 + ;; clone) _DEVTOOLS_COMMAND+=" $1" shift diff --git a/src/lib/repo/clean.sh b/src/lib/repo/clean.sh new file mode 100644 index 0000000..bb8980e --- /dev/null +++ b/src/lib/repo/clean.sh @@ -0,0 +1,114 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[[ -z ${DEVTOOLS_INCLUDE_REPO_CLEAN_SH:-} ]] || return 0 +DEVTOOLS_INCLUDE_REPO_CLEAN_SH=1 + +_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} +# shellcheck source=src/lib/common.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh + +source /usr/share/makepkg/util/message.sh + +set -eo pipefail + + +pkgctl_repo_clean_usage() { + local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}} + cat <<- _EOF_ + Usage: ${COMMAND} [OPTION] [PATH]... + + Cleans the working tree by recursively removing files that are not under + version control, starting from the current directory. + + Files unknown to Git as well as ignored files are removed. This can, for + example, be useful to remove all build products. + + OPTIONS + -i, --interactive Show what would be done and clean files interactively + -n, --dry-run Don't remove anything, just show what would be done + -h, --help Show this help text + + EXAMPLES + $ ${COMMAND} libfoo linux libbar + $ ${COMMAND} --interactive libfoo linux libbar + $ ${COMMAND} --dry-run * +_EOF_ +} + +pkgctl_repo_clean() { + # options + local git_clean_options=() + local paths + + local path pkgbase + + while (( $# )); do + case $1 in + -i|--interactive) + git_clean_options+=("$1") + shift + ;; + -n|--dry-run) + git_clean_options+=("$1") + shift + ;; + -h|--help) + pkgctl_repo_clean_usage + exit 0 + ;; + --) + shift + break + ;; + -*) + die "invalid argument: %s" "$1" + ;; + *) + paths=("$@") + break + ;; + esac + done + + # check if invoked without any path from within a packaging repo + if (( ${#paths[@]} == 0 )); then + paths=(".") + fi + + # print message about the work chunk + printf "🗑️ Removing untracked files from %s working trees\n" "${BOLD}${#paths[@]}${ALL_OFF}" + + for path in "${paths[@]}"; do + # skip paths that are not directories + if [[ ! -d "${path}" ]]; then + continue + fi + + if [[ ! -f "${path}/PKGBUILD" ]]; then + msg_error "Not a package repository: ${path}" + continue + fi + + if [[ ! -d "${path}/.git" ]]; then + msg_error "Not a Git repository: ${path}" + continue + fi + + pkgbase=$(basename "$(realpath "${path}")") + pkgbase=${pkgbase%.git} + + # run dry mode to see if git would clean any files + if [[ ! $(git -C "${path}" clean -x -d --dry-run 2>&1) ]]; then + continue + fi + + # git clean untracked files + msg_success "Cleaning ${BOLD}${pkgbase}${ALL_OFF}" + if ! git -C "${path}" clean -x -d --force "${git_clean_options[@]}"; then + msg_error "Failed to remove untracked files" + fi + echo + done +} diff --git a/src/lib/repo/configure.sh b/src/lib/repo/configure.sh index 0980fd1..e9ec5a4 100644 --- a/src/lib/repo/configure.sh +++ b/src/lib/repo/configure.sh @@ -271,6 +271,7 @@ pkgctl_repo_configure() { if [[ -n $GPGKEY ]]; then git config commit.gpgsign true git config user.signingKey "${GPGKEY}" + git config gpg.format openpgp fi # set default git exclude diff --git a/src/lib/util/makepkg.sh b/src/lib/util/makepkg.sh index 22df247..d7ec74c 100644 --- a/src/lib/util/makepkg.sh +++ b/src/lib/util/makepkg.sh @@ -22,9 +22,11 @@ makepkg_source_package() { return fi ( + # shellcheck disable=SC2030 disable=SC2031 export LIBMAKEPKG_LINT_PKGBUILD_SH=1 lint_pkgbuild() { :; } + # shellcheck disable=SC2030 disable=SC2031 export LIBMAKEPKG_SRCINFO_SH=1 write_srcinfo() { print_srcinfo; } @@ -35,3 +37,21 @@ makepkg_source_package() { source "$(command -v makepkg)" ) } + +makepkg_generate_integrity() { + if [[ -z ${DEVTOOLS_GENERATE_INTEGRITY} ]]; then + [[ -z ${WORKDIR:-} ]] && setup_workdir + export WORKDIR DEVTOOLS_INCLUDE_COMMON_SH + bash -$- -c "DEVTOOLS_GENERATE_INTEGRITY=1; source '${BASH_SOURCE[0]}' && ${FUNCNAME[0]}" + return + fi + ( + # shellcheck disable=SC2030 disable=SC2031 + export LIBMAKEPKG_LINT_PKGBUILD_SH=1 + lint_pkgbuild() { :; } + + set +e -- --geninteg + # shellcheck source=/usr/bin/makepkg + source "$(command -v makepkg)" + ) +} diff --git a/src/lib/util/pacman.sh b/src/lib/util/pacman.sh index 620e1a8..4637d28 100644 --- a/src/lib/util/pacman.sh +++ b/src/lib/util/pacman.sh @@ -18,10 +18,12 @@ readonly _DEVTOOLS_MAKEPKG_CONF_DIR=${_DEVTOOLS_LIBRARY_DIR}/makepkg.conf.d update_pacman_repo_cache() { + local repo=${1:-multilib} + mkdir -p "${_DEVTOOLS_PACMAN_CACHE_DIR}" msg "Updating pacman database cache" lock 10 "${_DEVTOOLS_PACMAN_CACHE_DIR}.lock" "Locking pacman database cache" - fakeroot -- pacman --config "${_DEVTOOLS_PACMAN_CONF_DIR}/multilib.conf" \ + fakeroot -- pacman --config "${_DEVTOOLS_PACMAN_CONF_DIR}/${repo}.conf" \ --dbpath "${_DEVTOOLS_PACMAN_CACHE_DIR}" \ -Sy lock_close 10 @@ -29,6 +31,7 @@ update_pacman_repo_cache() { get_pacman_repo_from_pkgbuild() { local path=${1:-PKGBUILD} + local repo=${2:-multilib} # shellcheck source=contrib/makepkg/PKGBUILD.proto mapfile -t pkgnames < <(source "${path}"; printf "%s\n" "${pkgname[@]}") @@ -40,12 +43,12 @@ get_pacman_repo_from_pkgbuild() { # update the pacman repo cache if it doesn't exist yet if [[ ! -d "${_DEVTOOLS_PACMAN_CACHE_DIR}" ]]; then - update_pacman_repo_cache + update_pacman_repo_cache "${repo}" fi slock 10 "${_DEVTOOLS_PACMAN_CACHE_DIR}.lock" "Locking pacman database cache" # query repo of passed pkgname, specify --nodeps twice to skip all dependency checks - mapfile -t repos < <(pacman --config "${_DEVTOOLS_PACMAN_CONF_DIR}/multilib.conf" \ + mapfile -t repos < <(pacman --config "${_DEVTOOLS_PACMAN_CONF_DIR}/${repo}.conf" \ --dbpath "${_DEVTOOLS_PACMAN_CACHE_DIR}" \ --sync \ --nodeps \ @@ -58,3 +61,30 @@ get_pacman_repo_from_pkgbuild() { printf "%s" "${repos[0]}" } + +get_pkgnames_from_repo_pkgbase() { + local repo=$1 + shift + local pkgbases=("$@") + + # update the pacman repo cache if it doesn't exist yet + if [[ ! -d "${_DEVTOOLS_PACMAN_CACHE_DIR}" ]]; then + update_pacman_repo_cache universe + fi + + slock 10 "${_DEVTOOLS_PACMAN_CACHE_DIR}.lock" "Locking pacman database cache" + # query pkgnames of passed pkgbase inside a repo + mapfile -t pkgnames < <(expac --config <(sed "s|#DBPath.*|DBPath = $(realpath "${_DEVTOOLS_PACMAN_CACHE_DIR}")|" < "${_DEVTOOLS_PACMAN_CONF_DIR}/universe.conf") \ + --sync '%r %e %n' 2>/dev/null \ + | sort | awk -v pkgbase="${pkgbases[*]}" \ + 'BEGIN { split(pkgbase, array); for (item in array) filter[array[item]]=1 } $1=="'"${repo}"'" && $2 in filter {print $3}' + ) + lock_close 10 + + if (( ! ${#pkgnames[@]} )); then + return 1 + fi + + printf "%s\n" "${pkgnames[@]}" + return 0 +} diff --git a/src/lib/util/pkgbuild.sh b/src/lib/util/pkgbuild.sh index ebf8e5f..245a82f 100644 --- a/src/lib/util/pkgbuild.sh +++ b/src/lib/util/pkgbuild.sh @@ -6,10 +6,13 @@ DEVTOOLS_INCLUDE_UTIL_PKGBUILD_SH=1 _DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} +# shellcheck source=src/lib/util/makepkg.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/util/makepkg.sh source /usr/share/makepkg/util/message.sh +source /usr/share/makepkg/util/schema.sh -set -e +set -eo pipefail # set the pkgver variable in a PKGBUILD @@ -41,3 +44,48 @@ pkgbuild_set_pkgrel() { sed --regexp-extended "s|^(pkgrel=)${pkgrel}$|\1${new_pkgrel}|g" --in-place PKGBUILD } +pkgbuild_update_checksums() { + local status_file=$1 + local builddir newbuildfile sumtypes newsums + + [[ -z ${WORKDIR:-} ]] && setup_workdir + + builddir=$(mktemp --tmpdir="${WORKDIR}" --directory update-checksums.XXXXXX) + newbuildfile="${builddir}/PKGBUILD" + + # generate new integrity checksums + if ! newsums=$(BUILDDIR=${builddir} makepkg_generate_integrity 2>"${status_file}"); then + printf 'Failed to generate new checksums' + return 1 + fi + + # early exit if no integrity checksums are needed + if [[ -z ${newsums} ]]; then + return 0 + fi + + # replace the integrity sums and write it to a temporary file + sumtypes=$(IFS='|'; echo "${known_hash_algos[*]}") + if ! awk --assign=sumtypes="${sumtypes}" --assign=newsums="${newsums}" ' + $0 ~"^[[:blank:]]*(" sumtypes ")sums(_[^=]+)?\\+?=", $0 ~ "\\)[[:blank:]]*(#.*)?$" { + if (!w) { + print newsums + w++ + } + next + } + + 1 + END { if (!w) print newsums }' PKGBUILD > "${newbuildfile}"; then + printf 'Failed to replace the generated checksums' + return 1 + fi + + # overwrite the original PKGBUILD while preserving permissions + if ! cat -- "${newbuildfile}" > PKGBUILD; then + printf "Failed to write to the PKGBUILD file" + return 1 + fi + + return 0 +} diff --git a/src/lib/util/term.sh b/src/lib/util/term.sh index 853dccf..08d044f 100644 --- a/src/lib/util/term.sh +++ b/src/lib/util/term.sh @@ -180,3 +180,19 @@ term_spinner_stop() { # show the cursor after stopping the spinner term_cursor_show } + +prompt() { + local message=$1 + local answer + + read -r -p "${message} (y/N) " answer + + case "${answer}" in + y|Y|yes|Yes|YES) + true + ;; + *) + false + ;; + esac +} diff --git a/src/lib/valid-tags.sh b/src/lib/valid-tags.sh index abca7ef..ef2c5bf 100644 --- a/src/lib/valid-tags.sh +++ b/src/lib/valid-tags.sh @@ -4,11 +4,15 @@ : # shellcheck disable=2034 -_arch=( +DEVTOOLS_VALID_BINARY_ARCHES=( pentium4 i686 i486 - x86_64 +) + +# shellcheck disable=2034 +DEVTOOLS_VALID_ARCHES=( + "${DEVTOOLS_VALID_BINARY_ARCHES[@]}" any ) diff --git a/src/lib/version/check.sh b/src/lib/version/check.sh index ec90eb4..4a2b5fa 100644 --- a/src/lib/version/check.sh +++ b/src/lib/version/check.sh @@ -114,10 +114,6 @@ pkgctl_version_check() { fi pushd "${path}" >/dev/null - if [[ ! -f "PKGBUILD" ]]; then - die "No PKGBUILD found for ${path}" - fi - # update the current terminal spinner status (( ++current_item )) pkgctl_version_check_spinner \ @@ -128,6 +124,13 @@ pkgctl_version_check() { "${current_item}" \ "${#pkgbases[@]}" + if [[ ! -f "PKGBUILD" ]]; then + result="${BOLD}${path}${ALL_OFF}: no PKGBUILD found" + failure+=("${result}") + popd >/dev/null + continue + fi + # reset common PKGBUILD variables unset pkgbase pkgname arch source pkgver pkgrel validpgpkeys # shellcheck source=contrib/makepkg/PKGBUILD.proto @@ -224,7 +227,7 @@ get_upstream_version() { fi if ! output=$(GIT_TERMINAL_PROMPT=0 nvchecker --file "${config}" --logger json "${opts[@]}" 2>&1 | \ - jq --raw-output 'select(.level != "debug")'); then + jq --raw-output 'select((.level != "debug") and (.event != "ignoring invalid version"))'); then printf "failed to run nvchecker: %s" "${output}" return 1 fi @@ -264,13 +267,13 @@ nvchecker_check_config() { done # check if the config contains a pkgbase section - if [[ -n ${pkgbase} ]] && ! grep --max-count=1 --extended-regexp --quiet "^\\[\"?${pkgbase}\"?\\]" < "${config}"; then + if [[ -n ${pkgbase} ]] && ! grep --max-count=1 --extended-regexp --quiet "^\\[\"?${pkgbase//+/\\+}\"?\\]" < "${config}"; then printf "missing pkgbase section in %s: %s" "${config}" "${pkgbase}" return 1 fi # check if the config contains any section other than pkgbase - if [[ -n ${pkgbase} ]] && property=$(grep --max-count=1 --perl-regexp "^\\[(?!\"?${pkgbase}\"?\\]).+\\]" < "${config}"); then + if [[ -n ${pkgbase} ]] && property=$(grep --max-count=1 --perl-regexp "^\\[(?!\"?${pkgbase//+/\\+}\"?\\]).+\\]" < "${config}"); then printf "non-pkgbase section not supported in %s: %s" "${config}" "${property}" return 1 fi diff --git a/src/lib/version/setup.sh b/src/lib/version/setup.sh index 123862c..cdfbeac 100644 --- a/src/lib/version/setup.sh +++ b/src/lib/version/setup.sh @@ -252,7 +252,7 @@ nvchecker_setup() { # escape the section if it contains toml subsection chars section="${pkgbase}" - if [[ ${section} == *.* ]]; then + if [[ ${section} == *.* ]] || [[ ${section} == *+* ]]; then section="\"${section}\"" fi diff --git a/src/lib/version/upgrade.sh b/src/lib/version/upgrade.sh index df3b77d..70a4659 100644 --- a/src/lib/version/upgrade.sh +++ b/src/lib/version/upgrade.sh @@ -30,14 +30,15 @@ pkgctl_version_upgrade_usage() { Upon execution, it automatically adjusts the PKGBUILD file, ensuring that the pkgver field is set to match the latest version available from the upstream source. In addition to updating the pkgver, this command also resets the pkgrel - to 1. + to 1 and updates checksums. Outputs a summary of upgraded packages, up-to-date packages, and any check failures. OPTIONS - -v, --verbose Display results including up-to-date versions - -h, --help Show this help text + --no-update-checksums Disable computation and update of the checksums + -v, --verbose Display results including up-to-date versions + -h, --help Show this help text EXAMPLES $ ${COMMAND} neovim vim @@ -50,6 +51,7 @@ pkgctl_version_upgrade() { local verbose=0 local exit_code=0 local current_item=0 + local update_checksums=1 while (( $# )); do case $1 in @@ -57,6 +59,10 @@ pkgctl_version_upgrade() { pkgctl_version_upgrade_usage exit 0 ;; + --no-update-checksums) + update_checksums=0 + shift + ;; -v|--verbose) verbose=1 shift @@ -105,25 +111,31 @@ pkgctl_version_upgrade() { fi pushd "${path}" >/dev/null + (( ++current_item )) + if [[ ! -f "PKGBUILD" ]]; then - die "No PKGBUILD found for ${path}" + result="${BOLD}${path}${ALL_OFF}: no PKGBUILD found" + failure+=("${result}") + popd >/dev/null + continue fi + # reset common PKGBUILD variables + unset pkgbase pkgname arch source pkgver pkgrel validpgpkeys + # shellcheck source=contrib/makepkg/PKGBUILD.proto + . ./PKGBUILD + pkgbase=${pkgbase:-$pkgname} + # update the current terminal spinner status - (( ++current_item )) pkgctl_version_upgrade_spinner \ "${status_dir}" \ "${#up_to_date[@]}" \ "${#out_of_date[@]}" \ "${#failure[@]}" \ "${current_item}" \ - "${#pkgbases[@]}" - - # reset common PKGBUILD variables - unset pkgbase pkgname arch source pkgver pkgrel validpgpkeys - # shellcheck source=contrib/makepkg/PKGBUILD.proto - . ./PKGBUILD - pkgbase=${pkgbase:-$pkgname} + "${#pkgbases[@]}" \ + "${pkgbase}" \ + "query latest version" if ! result=$(get_upstream_version); then result="${BOLD}${pkgbase}${ALL_OFF}: ${result}" @@ -153,6 +165,24 @@ pkgctl_version_upgrade() { # change the PKGBUILD pkgbuild_set_pkgver "${upstream_version}" pkgbuild_set_pkgrel 1 + + # download sources and update the checksums + if (( update_checksums )); then + pkgctl_version_upgrade_spinner \ + "${status_dir}" \ + "${#up_to_date[@]}" \ + "${#out_of_date[@]}" \ + "${#failure[@]}" \ + "${current_item}" \ + "${#pkgbases[@]}" \ + "${pkgbase}" \ + "updating checksums" + + if ! result=$(pkgbuild_update_checksums /dev/null); then + result="${BOLD}${pkgbase}${ALL_OFF}: failed to update checksums for version ${DARK_GREEN}${upstream_version}${ALL_OFF}" + failure+=("${result}") + fi + fi fi popd >/dev/null @@ -231,6 +261,8 @@ pkgctl_version_upgrade_spinner() { local failure_count=$4 local current=$5 local total=$6 + local pkgbase=$7 + local message=$8 local percentage=$(( 100 * current / total )) local tmp_file="${status_dir}/tmp" @@ -243,8 +275,10 @@ pkgctl_version_upgrade_spinner() { "${failure_count}" > "${tmp_file}" # print the progress status - printf "📡 Upgrading: %s/%s [%s] %%spinner%%" \ - "${BOLD}${current}" "${total}" "${percentage}%${ALL_OFF}" \ + printf "📡 %s: %s\n" \ + "${pkgbase}" "${BOLD}${message}${ALL_OFF}" >> "${tmp_file}" + printf "⌛ Upgrading: %s/%s [%s] %%spinner%%" \ + "${BOLD}${current}" "${total}" "${percentage}%${ALL_OFF}" \ >> "${tmp_file}" # swap the status file diff --git a/src/makechrootpkg.in b/src/makechrootpkg.in index 44b991b..30f78c8 100644 --- a/src/makechrootpkg.in +++ b/src/makechrootpkg.in @@ -38,6 +38,7 @@ inspect=never bindmounts_ro=() bindmounts_rw=() +bindmounts_tmpfs=() copy=$USER [[ -n ${SUDO_USER:-} ]] && copy=$SUDO_USER @@ -65,23 +66,24 @@ usage() { echo "Default makepkg args: ${default_makepkg_args[*]}" echo '' echo 'Flags:' - echo '-h This help' - echo '-c Clean the chroot before building' - echo '-d <dir> Bind directory into build chroot as read-write' - echo '-D <dir> Bind directory into build chroot as read-only' - echo '-u Update the working copy of the chroot before building' - echo ' This is useful for rebuilds without dirtying the pristine' - echo ' chroot' - echo '-r <dir> The chroot dir to use' - echo '-I <pkg> Install a package into the working copy of the chroot' - echo '-l <copy> The directory to use as the working copy of the chroot' - echo ' Useful for maintaining multiple copies' - echo " Default: $copy" - echo '-n Run namcap on the package' - echo '-C Run checkpkg on the package' - echo '-T Build in a temporary directory' - echo '-U Run makepkg as a specified user' - echo '-x <when> Inspect chroot after build (never, always, failure)' + echo '-h This help' + echo '-c Clean the chroot before building' + echo '-d <dir> Bind directory into build chroot as read-write' + echo '-D <dir> Bind directory into build chroot as read-only' + echo '-t <dir[:opts]> Mount a tmpfs at directory' + echo '-u Update the working copy of the chroot before building' + echo ' This is useful for rebuilds without dirtying the pristine' + echo ' chroot' + echo '-r <dir> The chroot dir to use' + echo '-I <pkg> Install a package into the working copy of the chroot' + echo '-l <copy> The directory to use as the working copy of the chroot' + echo ' Useful for maintaining multiple copies' + echo " Default: $copy" + echo '-n Run namcap on the package' + echo '-C Run checkpkg on the package' + echo '-T Build in a temporary directory' + echo '-U Run makepkg as a specified user' + echo '-x <when> Inspect chroot after build (never, always, failure)' exit 1 } @@ -148,8 +150,8 @@ install_packages() { pkgnames=("${install_pkgs[@]##*/}") cp -- "${install_pkgs[@]}" "$copydir/root/" - arch-nspawn "$copydir" "${bindmounts_ro[@]}" "${bindmounts_rw[@]}" \ - bash -c 'yes y | pacman -U -- "$@"' -bash "${pkgnames[@]/#//root/}" + arch-nspawn "$copydir" "${bindmounts_ro[@]}" "${bindmounts_rw[@]}" "${bindmounts_tmpfs[@]}" \ + pacman -U --noconfirm --ask=4 -- "${pkgnames[@]/#//root/}" ret=$? rm -- "${pkgnames[@]/#/$copydir/root/}" @@ -191,6 +193,11 @@ builduser ALL = NOPASSWD: /usr/bin/pacman EOF chmod 440 "$copydir/etc/sudoers.d/builduser-pacman" + cat > "$copydir/etc/gitconfig" <<EOF +[safe] + directory = * +EOF + # This is a little gross, but this way the script is recreated every time in the # working copy { @@ -295,11 +302,12 @@ move_products() { } # }}} -while getopts 'hcur:I:l:nCTD:d:U:x:' arg; do +while getopts 'hcur:I:l:nCTD:d:U:x:t:' arg; do case "$arg" in c) clean_first=1 ;; D) bindmounts_ro+=("--bind-ro=$OPTARG") ;; d) bindmounts_rw+=("--bind=$OPTARG") ;; + t) bindmounts_tmpfs+=("--tmpfs=$OPTARG") ;; u) update_first=1 ;; r) passeddir="$OPTARG" ;; I) install_pkgs+=("$OPTARG") ;; @@ -370,7 +378,7 @@ if [[ ! -d $copydir ]] || (( clean_first )); then fi (( update_first )) && arch-nspawn "$copydir" \ - "${bindmounts_ro[@]}" "${bindmounts_rw[@]}" \ + "${bindmounts_ro[@]}" "${bindmounts_rw[@]}" "${bindmounts_tmpfs[@]}" \ pacman -Syuu --noconfirm if [[ -n ${install_pkgs[*]:-} ]]; then @@ -395,6 +403,7 @@ nspawn_build_args=( --tmpfs="/tmp:${tmp_opts}" "${bindmounts_ro[@]}" "${bindmounts_rw[@]}" + "${bindmounts_tmpfs[@]}" ) if arch-nspawn "$copydir" \ diff --git a/src/mkarchroot.in b/src/mkarchroot.in index 2abe001..c59c26c 100644 --- a/src/mkarchroot.in +++ b/src/mkarchroot.in @@ -22,13 +22,14 @@ nspawn_args=() usage() { echo "Usage: ${0##*/} [options] working-dir package-list..." echo ' options:' - echo ' -U Use pacman -U to install packages' - echo ' -C <file> Location of a pacman config file' - echo ' -M <file> Location of a makepkg config file' - echo ' -c <dir> Set pacman cache' - echo ' -f <file> Copy file from the host to the chroot' - echo ' -s Do not run setarch' - echo ' -h This message' + echo ' -U Use pacman -U to install packages' + echo ' -C <file> Location of a pacman config file' + echo ' -M <file> Location of a makepkg config file' + echo ' -c <dir> Set pacman cache' + echo ' -f <src>[:<dst>] Copy src file from the host to the chroot.' + echo ' If dst file is not provided, it defaults to src' + echo ' -s Do not run setarch' + echo ' -h This message' exit 1 } @@ -84,8 +85,10 @@ if is_btrfs "$working_dir"; then fi for file in "${files[@]}"; do - mkdir -p "$(dirname "$working_dir$file")" - cp "$file" "$working_dir$file" + src="${file%%:*}" + dst="${file#*:}" + mkdir -p "$(dirname "$working_dir$dst")" + cp "$src" "$working_dir$dst" done unshare --mount pacstrap -${umode}Mc ${pac_conf:+-C "$pac_conf"} "$working_dir" \ diff --git a/src/offload-build.in b/src/offload-build.in index 7a8c1fd..f231ed1 100644 --- a/src/offload-build.in +++ b/src/offload-build.in @@ -23,7 +23,7 @@ fi repo=extra arch=x86_64 server=build.archlinux.org -rsyncopts=(-e ssh -c -h -L --progress --partial -y) +rsyncopts=("${RSYNC_OPTS[@]}") usage() { cat <<- _EOF_ @@ -107,6 +107,7 @@ mapfile -t files < <( cd "$temp" && { bsdtar --strip-components 1 -xvf - && + export LOGDEST="" && script -qefc "'"${archbuild_cmd[@]@Q}"'" /dev/null && printf "%s\n" "" "-> build complete" && printf "\t%s\n" "$temp"/* @@ -120,14 +121,25 @@ mapfile -t files < <( [[ -f "${file}" ]] && printf "%s\n" "${file}" ||: done < <(makepkg --config <(cat "${makepkg_user_config}" "${makepkg_config}" 2>/dev/null) --packagelist) && printf "%s\n" "${temp}/PKGBUILD" + + find "${temp}" -name "*.log" ') if (( ${#files[@]} )); then - printf '%s\n' '' '-> copying files...' + msg 'Downloading files...' rsync "${rsyncopts[@]}" "${files[@]/#/$server:}" "${TEMPDIR}/" || die - mv "${TEMPDIR}"/*.pkg.tar* "${PKGDEST:-${PWD}}/" + + if is_globfile "${TEMPDIR}"/*.log; then + mv "${TEMPDIR}"/*.log "${LOGDEST:-${PWD}}/" + fi + # missing PKGBUILD download means the build failed + if [[ ! -f "${TEMPDIR}/PKGBUILD" ]]; then + error "Build failed, check logs in ${LOGDEST:-${PWD}}" + exit 1 + fi mv "${TEMPDIR}/PKGBUILD" "${PWD}/" + mv "${TEMPDIR}"/*.pkg.tar* "${PKGDEST:-${PWD}}/" else exit 1 fi diff --git a/test/fixture/version/setup/github-tarball-as-platform/nvchecker.assert.toml b/test/fixture/version/setup/github-tarball-as-platform/nvchecker.assert.toml index b3c5db2..139f4b4 100644 --- a/test/fixture/version/setup/github-tarball-as-platform/nvchecker.assert.toml +++ b/test/fixture/version/setup/github-tarball-as-platform/nvchecker.assert.toml @@ -2,3 +2,4 @@ source = "github" github = "anthraxx/git-smash" use_max_tag = true +prefix = "v" diff --git a/test/fixture/version/setup/github-tarball/nvchecker.assert.toml b/test/fixture/version/setup/github-tarball/nvchecker.assert.toml index 65877ac..8008816 100644 --- a/test/fixture/version/setup/github-tarball/nvchecker.assert.toml +++ b/test/fixture/version/setup/github-tarball/nvchecker.assert.toml @@ -1,3 +1,4 @@ [git-smash] source = "git" git = "https://github.com/anthraxx/git-smash.git" +prefix = "v" diff --git a/test/fixture/version/setup/pkgbase-with-dot/nvchecker.assert.toml b/test/fixture/version/setup/pkgbase-with-dot/nvchecker.assert.toml index 38e881b..9d1fcd7 100644 --- a/test/fixture/version/setup/pkgbase-with-dot/nvchecker.assert.toml +++ b/test/fixture/version/setup/pkgbase-with-dot/nvchecker.assert.toml @@ -1,3 +1,4 @@ ["git.smash"] source = "git" git = "https://github.com/anthraxx/git-smash.git" +prefix = "v" |