Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
e8e4aa553f
|
|||
|
d8b1038bd6
|
|||
|
f9a2dc9dbe
|
|||
|
e04adbf5e6
|
|||
|
af1514ad5f
|
|||
|
32925a05c4
|
|||
|
77017f8009
|
|||
|
645563b0c5
|
|||
|
fb8da6fedd
|
|||
|
c31acae021
|
|||
|
ca1082a8e5
|
|||
|
6f12273730
|
|||
|
b9b15f549d
|
|||
|
c81b643fb2
|
|||
|
4362707456
|
|||
|
5d8cdf19fe
|
|||
|
7084a086fa
|
|||
|
8744bb5355
|
|||
|
75747a7d9d
|
|||
|
75d1e7ce2a
|
28
.github/workflows/lint.yaml
vendored
Normal file
28
.github/workflows/lint.yaml
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
name: Artools shellcheck
|
||||
run-name: ${{ gitea.actor }}
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- ci
|
||||
tags:
|
||||
- 0.*
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: checkout repo
|
||||
uses: actions/checkout@main
|
||||
- name: Run ShellCheck shell-linter
|
||||
uses: azohra/shell-linter@latest
|
||||
with:
|
||||
path: "src/base/*.in,src/pkg/*.in,src/iso/*.in"
|
||||
severity: "error"
|
||||
- name: Run ShellCheck action-shellcheck
|
||||
uses: ludeeus/action-shellcheck@master
|
||||
env:
|
||||
SHELLCHECK_OPTS: -x -s bash
|
||||
with:
|
||||
additional_files: "src/base/*.in*"
|
||||
#scandir: 'src/base'
|
||||
|
||||
2
Makefile
2
Makefile
@@ -1,6 +1,6 @@
|
||||
SHELL=/bin/bash
|
||||
|
||||
V=0.31
|
||||
V=0.32
|
||||
BUILDTOOLVER ?= $(V)
|
||||
|
||||
CHROOTVER=0.12
|
||||
|
||||
@@ -44,7 +44,8 @@ CFLAGS="-march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions \
|
||||
-Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security \
|
||||
-fstack-clash-protection -fcf-protection"
|
||||
CXXFLAGS="$CFLAGS -Wp,-D_GLIBCXX_ASSERTIONS"
|
||||
LDFLAGS="-Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now"
|
||||
LDFLAGS="-Wl,-O1 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro -Wl,-z,now \
|
||||
-Wl,-z,pack-relative-relocs"
|
||||
LTOFLAGS="-flto=auto"
|
||||
RUSTFLAGS=""
|
||||
#-- Make Flags: change this for DistCC/SMP systems
|
||||
|
||||
@@ -43,7 +43,8 @@ artixpkg_git_config_usage() {
|
||||
|
||||
EXAMPLES
|
||||
$ ${COMMAND} --maintainer libfoo
|
||||
$ ${COMMAND} --agent galaxy libfoo
|
||||
$ ${COMMAND} --agent=galaxy libfoo
|
||||
$ ${COMMAND} -a galaxy libfoo
|
||||
$ ${COMMAND} --drop libfoo
|
||||
$ ${COMMAND} *
|
||||
_EOF_
|
||||
|
||||
@@ -11,31 +11,13 @@ source "${LIBDIR}"/pkg/db/db.sh
|
||||
set -e
|
||||
|
||||
|
||||
check_pkgbuild_validity() {
|
||||
# shellcheck source=contrib/makepkg/PKGBUILD.proto
|
||||
. ./PKGBUILD
|
||||
|
||||
# skip when there are no sources available
|
||||
if (( ! ${#source[@]} )); then
|
||||
return
|
||||
fi
|
||||
|
||||
# validate sources hash algo is at least > sha1
|
||||
local bad_algos=("cksums" "md5sums" "sha1sums")
|
||||
local good_hash_algo=false
|
||||
|
||||
# from makepkg libmakepkg/util/schema.sh
|
||||
for integ in "${known_hash_algos[@]}"; do
|
||||
local sumname="${integ}sums"
|
||||
if [[ -n ${!sumname} ]] && ! in_array "${sumname}" "${bad_algos[@]}"; then
|
||||
good_hash_algo=true
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if ! $good_hash_algo; then
|
||||
die "PKGBUILD lacks a secure cryptographic checksum, insecure algorithms: ${bad_algos[*]}"
|
||||
show_agent() {
|
||||
local agent="orion"
|
||||
msg "Checking agent ..."
|
||||
if grep @galaxy "${REPO_CI}" &>/dev/null; then
|
||||
agent="taurus"
|
||||
fi
|
||||
msg2 "agent: %s" "$agent"
|
||||
}
|
||||
|
||||
has_remote_changes() {
|
||||
|
||||
@@ -8,6 +8,30 @@ ARTOOLS_INCLUDE_REPO_ADD_SH=1
|
||||
set -e
|
||||
|
||||
|
||||
check_pkgbuild_validity() {
|
||||
# skip when there are no sources available
|
||||
if (( ! ${#source[@]} )); then
|
||||
return
|
||||
fi
|
||||
|
||||
# validate sources hash algo is at least > sha1
|
||||
local bad_algos=("cksums" "md5sums" "sha1sums")
|
||||
local good_hash_algo=false
|
||||
|
||||
# from makepkg libmakepkg/util/schema.sh
|
||||
for integ in "${known_hash_algos[@]}"; do
|
||||
local sumname="${integ}sums"
|
||||
if [[ -n ${!sumname} ]] && ! in_array "${sumname}" "${bad_algos[@]}"; then
|
||||
good_hash_algo=true
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if ! $good_hash_algo; then
|
||||
die "PKGBUILD lacks a secure cryptographic checksum, insecure algorithms: ${bad_algos[*]}"
|
||||
fi
|
||||
}
|
||||
|
||||
artixpkg_repo_add_usage() {
|
||||
local -r COMMAND=${_ARTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}}
|
||||
cat <<- _EOF_
|
||||
@@ -86,49 +110,57 @@ artixpkg_repo_add() {
|
||||
fi
|
||||
( cd "${pkgbase}" || return
|
||||
|
||||
if [[ ! -f PKGBUILD ]]; then
|
||||
die "No PKGBUILD found in (%s)" "${pkgbase}"
|
||||
fi
|
||||
if ! has_remote_changes; then
|
||||
|
||||
# shellcheck source=contrib/makepkg/PKGBUILD.proto
|
||||
source PKGBUILD
|
||||
|
||||
update_yaml_base
|
||||
update_yaml_add "${REBUILD}" "${ADD}" "${NOCHECK}" "${DEST}"
|
||||
|
||||
local commit_msg
|
||||
commit_msg=$(get_commit_msg 'add' "${DEST}")
|
||||
|
||||
if [[ -f .SRCINFO ]]; then
|
||||
rm .SRCINFO
|
||||
fi
|
||||
|
||||
if [[ -n $(git status --porcelain --untracked-files=no) ]]; then
|
||||
|
||||
stat_busy 'Staging files'
|
||||
for f in $(git ls-files --others); do
|
||||
git add "$f"
|
||||
done
|
||||
for f in $(git ls-files --modified); do
|
||||
git add "$f"
|
||||
done
|
||||
for f in $(git ls-files --deleted); do
|
||||
git rm "$f"
|
||||
done
|
||||
stat_done
|
||||
|
||||
msg 'Commit'
|
||||
git commit -m "${commit_msg}"
|
||||
|
||||
if (( PUSH )); then
|
||||
msg "Push (${pkgbase})"
|
||||
git push origin master
|
||||
if [[ ! -f PKGBUILD ]]; then
|
||||
die "No PKGBUILD found in (%s)" "${pkgbase}"
|
||||
fi
|
||||
|
||||
msg "Querying ${pkgbase} ..."
|
||||
if ! show_db; then
|
||||
warning "Could not query ${REPO_DB}"
|
||||
# shellcheck source=contrib/makepkg/PKGBUILD.proto
|
||||
source PKGBUILD
|
||||
|
||||
check_pkgbuild_validity
|
||||
|
||||
manage-pkgbuild-keys --export
|
||||
|
||||
update_yaml_base
|
||||
update_yaml_add "${REBUILD}" "${ADD}" "${NOCHECK}" "${DEST}"
|
||||
|
||||
local commit_msg
|
||||
commit_msg=$(get_commit_msg 'add' "${DEST}")
|
||||
|
||||
if [[ -f .SRCINFO ]]; then
|
||||
rm .SRCINFO
|
||||
fi
|
||||
|
||||
if [[ -n $(git status --porcelain --untracked-files=no) ]]; then
|
||||
|
||||
stat_busy 'Staging files'
|
||||
for f in $(git ls-files --others); do
|
||||
git add "$f"
|
||||
done
|
||||
for f in $(git ls-files --modified); do
|
||||
git add "$f"
|
||||
done
|
||||
for f in $(git ls-files --deleted); do
|
||||
git rm "$f"
|
||||
done
|
||||
stat_done
|
||||
|
||||
msg 'Commit'
|
||||
git commit -m "${commit_msg}"
|
||||
|
||||
if (( PUSH )); then
|
||||
msg "Push (${pkgbase})"
|
||||
git push origin master
|
||||
fi
|
||||
|
||||
msg "Querying ${pkgbase} ..."
|
||||
if ! show_db; then
|
||||
warning "Could not query ${REPO_DB}"
|
||||
fi
|
||||
fi
|
||||
|
||||
fi
|
||||
)
|
||||
fi
|
||||
|
||||
@@ -125,6 +125,7 @@ artixpkg_repo_import() {
|
||||
fi
|
||||
|
||||
if ! has_remote_changes; then
|
||||
show_agent
|
||||
msg "Querying ${pkgbase} ..."
|
||||
if ! show_db; then
|
||||
warning "Could not query ${REPO_DB}"
|
||||
|
||||
@@ -80,65 +80,69 @@ artixpkg_repo_move() {
|
||||
fi
|
||||
( cd "${pkgbase}" || return
|
||||
|
||||
if [[ ! -f PKGBUILD ]]; then
|
||||
die "No PKGBUILD found in (%s)" "${pkgbase}"
|
||||
fi
|
||||
|
||||
local commit_msg src_version dest_version
|
||||
commit_msg=$(get_commit_msg 'move' "${DEST}" "${SRC}")
|
||||
|
||||
src_version=$(version_from_yaml "${SRC}")
|
||||
dest_version=$(version_from_yaml "${DEST}")
|
||||
|
||||
if [[ "$src_version" != null ]]; then
|
||||
|
||||
local ret
|
||||
ret=$(vercmp "$src_version" "$dest_version")
|
||||
|
||||
if (( ret > 0 )); then
|
||||
|
||||
update_yaml_move "${SRC}" "${DEST}"
|
||||
|
||||
if [[ -f .SRCINFO ]]; then
|
||||
rm .SRCINFO
|
||||
fi
|
||||
|
||||
if [[ -n $(git status --porcelain --untracked-files=no) ]]; then
|
||||
|
||||
stat_busy 'Staging files'
|
||||
for f in $(git ls-files --modified); do
|
||||
if [[ "$f" == "${REPO_DB}" ]]; then
|
||||
git add "$f"
|
||||
fi
|
||||
done
|
||||
stat_done
|
||||
|
||||
msg 'Commit'
|
||||
git commit -m "${commit_msg}"
|
||||
|
||||
if (( PUSH )); then
|
||||
msg "Push (${pkgbase})"
|
||||
git push origin master
|
||||
fi
|
||||
|
||||
msg "Querying ${pkgbase} ..."
|
||||
if ! show_db; then
|
||||
warning "Could not query ${REPO_DB}"
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
elif (( ret < 0 )); then
|
||||
|
||||
error "invalid move: version $src_version < $dest_version!"
|
||||
|
||||
else
|
||||
error "invalid move: version $src_version = $dest_version!"
|
||||
if ! has_remote_changes; then
|
||||
|
||||
if [[ ! -f PKGBUILD ]]; then
|
||||
die "No PKGBUILD found in (%s)" "${pkgbase}"
|
||||
fi
|
||||
|
||||
local commit_msg src_version dest_version
|
||||
commit_msg=$(get_commit_msg 'move' "${DEST}" "${SRC}")
|
||||
|
||||
src_version=$(version_from_yaml "${SRC}")
|
||||
dest_version=$(version_from_yaml "${DEST}")
|
||||
|
||||
if [[ "$src_version" != null ]]; then
|
||||
|
||||
local ret
|
||||
ret=$(vercmp "$src_version" "$dest_version")
|
||||
|
||||
if (( ret > 0 )); then
|
||||
|
||||
update_yaml_move "${SRC}" "${DEST}"
|
||||
|
||||
if [[ -f .SRCINFO ]]; then
|
||||
rm .SRCINFO
|
||||
fi
|
||||
|
||||
if [[ -n $(git status --porcelain --untracked-files=no) ]]; then
|
||||
|
||||
stat_busy 'Staging files'
|
||||
for f in $(git ls-files --modified); do
|
||||
if [[ "$f" == "${REPO_DB}" ]]; then
|
||||
git add "$f"
|
||||
fi
|
||||
done
|
||||
stat_done
|
||||
|
||||
msg 'Commit'
|
||||
git commit -m "${commit_msg}"
|
||||
|
||||
if (( PUSH )); then
|
||||
msg "Push (${pkgbase})"
|
||||
git push origin master
|
||||
fi
|
||||
|
||||
msg "Querying ${pkgbase} ..."
|
||||
if ! show_db; then
|
||||
warning "Could not query ${REPO_DB}"
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
elif (( ret < 0 )); then
|
||||
|
||||
error "${pkgbase}: invalid move: version $src_version < $dest_version!"
|
||||
|
||||
else
|
||||
error "${pkgbase}: invalid move: version $src_version = $dest_version!"
|
||||
|
||||
fi
|
||||
|
||||
else
|
||||
error "${pkgbase}: invalid move: version $src_version!"
|
||||
fi
|
||||
|
||||
else
|
||||
error "invalid move: version $src_version!"
|
||||
fi
|
||||
|
||||
)
|
||||
|
||||
@@ -73,36 +73,40 @@ artixpkg_repo_remove() {
|
||||
fi
|
||||
( cd "${pkgbase}" || return
|
||||
|
||||
if [[ ! -f PKGBUILD ]]; then
|
||||
die "No PKGBUILD found in (%s)" "${pkgbase}"
|
||||
fi
|
||||
if ! has_remote_changes; then
|
||||
|
||||
local commit_msg
|
||||
commit_msg=$(get_commit_msg 'remove' "${DEST}")
|
||||
|
||||
update_yaml_remove "${DEST}"
|
||||
|
||||
if [[ -n $(git status --porcelain --untracked-files=no) ]]; then
|
||||
|
||||
stat_busy 'Staging files'
|
||||
for f in $(git ls-files --modified); do
|
||||
if [[ "$f" == "${REPO_DB}" ]]; then
|
||||
git add "$f"
|
||||
fi
|
||||
done
|
||||
stat_done
|
||||
|
||||
msg 'Commit'
|
||||
git commit -m "${commit_msg}"
|
||||
|
||||
if (( PUSH )); then
|
||||
msg "Push (${pkgbase})"
|
||||
git push origin master
|
||||
if [[ ! -f PKGBUILD ]]; then
|
||||
die "No PKGBUILD found in (%s)" "${pkgbase}"
|
||||
fi
|
||||
|
||||
msg "Querying ${pkgbase} ..."
|
||||
if ! show_db; then
|
||||
warning "Could not query ${REPO_DB}"
|
||||
local commit_msg
|
||||
commit_msg=$(get_commit_msg 'remove' "${DEST}")
|
||||
|
||||
update_yaml_remove "${DEST}"
|
||||
|
||||
if [[ -n $(git status --porcelain --untracked-files=no) ]]; then
|
||||
|
||||
stat_busy 'Staging files'
|
||||
for f in $(git ls-files --modified); do
|
||||
if [[ "$f" == "${REPO_DB}" ]]; then
|
||||
git add "$f"
|
||||
fi
|
||||
done
|
||||
stat_done
|
||||
|
||||
msg 'Commit'
|
||||
git commit -m "${commit_msg}"
|
||||
|
||||
if (( PUSH )); then
|
||||
msg "Push (${pkgbase})"
|
||||
git push origin master
|
||||
fi
|
||||
|
||||
msg "Querying ${pkgbase} ..."
|
||||
if ! show_db; then
|
||||
warning "Could not query ${REPO_DB}"
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
@@ -77,6 +77,8 @@ artixpkg_repo_show() {
|
||||
die "No PKGBUILD found in (%s)" "${pkgbase}"
|
||||
fi
|
||||
|
||||
show_agent
|
||||
|
||||
msg "Querying ${pkgbase} ..."
|
||||
if ! show_db; then
|
||||
warning "Could not query ${REPO_DB}"
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
LIBDIR=${LIBDIR:-'@libdir@'}
|
||||
|
||||
# shellcheck source=src/lib/base/message.sh
|
||||
source "${LIBDIR}"/base/message.sh
|
||||
|
||||
usage() {
|
||||
cat <<- _EOF_
|
||||
Usage: ${BASH_SOURCE[0]##*/}
|
||||
|
||||
Export the PGP keys from a PKGBUILDs validpgpkeys array into the keys/pgp/
|
||||
subdirectory. Useful for distributing packager validated source signing
|
||||
keys alongside PKGBUILDs.
|
||||
|
||||
OPTIONS
|
||||
-h, --help Show this help text
|
||||
_EOF_
|
||||
}
|
||||
|
||||
# option checking
|
||||
while (( $# )); do
|
||||
case $1 in
|
||||
-h|--help) usage; exit 0 ;;
|
||||
*) die "invalid argument: %s" "$1" ;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ ! -f PKGBUILD ]]; then
|
||||
die "This must be run a directory containing a PKGBUILD."
|
||||
fi
|
||||
|
||||
mapfile -t validpgpkeys < <(
|
||||
# shellcheck source=contrib/makepkg/PKGBUILD.proto
|
||||
. ./PKGBUILD
|
||||
if (( ${#validpgpkeys[@]} )); then
|
||||
printf "%s\n" "${validpgpkeys[@]}"
|
||||
fi
|
||||
)
|
||||
|
||||
msg "Exporting ${#validpgpkeys[@]} PGP keys..."
|
||||
if (( ${#validpgpkeys[@]} == 0 )); then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
trap 'rm -rf $TEMPDIR' EXIT INT TERM QUIT
|
||||
TEMPDIR=$(mktemp -d --tmpdir export-pkgbuild-keys.XXXXXXXXXX)
|
||||
|
||||
mkdir -p keys/pgp
|
||||
error=0
|
||||
|
||||
for key in "${validpgpkeys[@]}"; do
|
||||
gpg --output "$TEMPDIR/$key.asc" --armor --export --export-options export-minimal "$key" 2>/dev/null
|
||||
|
||||
# gpg does not give a non-zero return value if it fails to export...
|
||||
if [[ -f $TEMPDIR/$key.asc ]]; then
|
||||
msg2 "Exported $key"
|
||||
mv "$TEMPDIR/$key.asc" "keys/pgp/$key.asc"
|
||||
else
|
||||
if [[ -f keys/pgp/$key.asc ]]; then
|
||||
warning "Failed to update key: $key"
|
||||
else
|
||||
error "Key unavailable: $key"
|
||||
error=1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if (( error )); then
|
||||
die "Failed to export all \'validpgpkeys\' entries."
|
||||
fi
|
||||
97
src/pkg/manage-pkgbuild-keys.in
Normal file
97
src/pkg/manage-pkgbuild-keys.in
Normal file
@@ -0,0 +1,97 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
LIBDIR=${LIBDIR:-'@libdir@'}
|
||||
|
||||
# shellcheck source=src/lib/base/message.sh
|
||||
source "${LIBDIR}"/base/message.sh
|
||||
|
||||
|
||||
usage() {
|
||||
cat <<- _EOF_
|
||||
Usage: ${BASH_SOURCE[0]##*/}
|
||||
|
||||
Export or import the PGP keys from a PKGBUILDs validpgpkeys array into/from the keys/pgp/
|
||||
subdirectory. Useful for distributing packager validated source signing
|
||||
keys alongside PKGBUILDs.
|
||||
|
||||
OPTIONS
|
||||
-i, --import Import keys
|
||||
-e, --export Export keys
|
||||
-h, --help Show this help text
|
||||
_EOF_
|
||||
}
|
||||
|
||||
action=
|
||||
|
||||
# option checking
|
||||
while (( $# )); do
|
||||
case $1 in
|
||||
-i|--import) action="import"; shift ;;
|
||||
-e|--export) action="export"; shift ;;
|
||||
-h|--help) usage; exit 0 ;;
|
||||
*) die "invalid argument: %s" "$1" ;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ ! -f PKGBUILD ]]; then
|
||||
die "This must be run a directory containing a PKGBUILD."
|
||||
fi
|
||||
|
||||
mapfile -t validpgpkeys < <(
|
||||
# shellcheck source=contrib/makepkg/PKGBUILD.proto
|
||||
. ./PKGBUILD
|
||||
if (( ${#validpgpkeys[@]} )); then
|
||||
printf "%s\n" "${validpgpkeys[@]}"
|
||||
fi
|
||||
)
|
||||
|
||||
if [[ "$action" == 'export' ]]; then
|
||||
msg "Exporting ${#validpgpkeys[@]} PGP keys..."
|
||||
if (( ${#validpgpkeys[@]} == 0 )); then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
trap 'rm -rf $TEMPDIR' EXIT INT TERM QUIT
|
||||
TEMPDIR=$(mktemp -d --tmpdir export-pkgbuild-keys.XXXXXXXXXX)
|
||||
|
||||
mkdir -p keys/pgp
|
||||
error=0
|
||||
|
||||
|
||||
for key in "${validpgpkeys[@]}"; do
|
||||
gpg --output "$TEMPDIR/$key.asc" --armor --export --export-options export-minimal "$key" 2>/dev/null
|
||||
|
||||
# gpg does not give a non-zero return value if it fails to export...
|
||||
if [[ -f $TEMPDIR/$key.asc ]]; then
|
||||
msg2 "Exported $key"
|
||||
mv "$TEMPDIR/$key.asc" "keys/pgp/$key.asc"
|
||||
else
|
||||
if [[ -f keys/pgp/$key.asc ]]; then
|
||||
warning "Failed to update key: $key"
|
||||
else
|
||||
error "Key unavailable: $key"
|
||||
error=1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
elif [[ "$action" == 'import' ]]; then
|
||||
msg "Ensuring required PGP keys are present..."
|
||||
for key in "${validpgpkeys[@]}"; do
|
||||
msg2 "Checking for $key..."
|
||||
if ! gpg --recv-keys $key || gpg --fingerprint $key; then
|
||||
if [[ -f keys/pgp/$key.asc ]]; then
|
||||
msg2 "Importing key from local..."
|
||||
gpg --import keys/pgp/$key.asc
|
||||
else
|
||||
error "Key unavailable: $key"
|
||||
error=1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if (( error )); then
|
||||
die "Failed to $action all \'validpgpkeys\' entries."
|
||||
fi
|
||||
Reference in New Issue
Block a user