Compare commits

..

2 Commits

Author SHA1 Message Date
Josephine Pfeiffer
c76fda0bf0 Merge branch 'gl-257-pkgctl-repo-sanity-check' into 'master'
[GL#257] add pkgctl repo sanity check

Closes #257

See merge request archlinux/devtools!303
2025-08-01 10:58:51 +00:00
Josephine Pfeiffer
d9ac6029d9 fix(repo): improve validation for repository configuration
The pkgctl repo configure command previously had no validation,
which could lead to accidental misconfiguration of unrelated
repositories. This change adds basic validation to ensure we're in a
git repository, while still preserving the ability to configure AUR
repositories and local git repositories for legitimate workflows.

This approach prevents accidental misconfiguration in non-git
directories while maintaining compatibility with important use cases:
- Configuring AUR repositories when promoting packages
- Configuring local git repositories during initial setup

Tests have been updated to use temporary directories with mktemp instead
of reusing existing fixtures, providing better isolation and preventing
side effects.

Fixes #257

Component: pkgctl repo configure
Signed-off-by: Josephine Pfeiffer <hi@josie.lol>
2025-03-13 18:08:05 +01:00
11 changed files with 108 additions and 71 deletions

View File

@@ -24,7 +24,7 @@ test:
stage: test stage: test
needs: [] needs: []
script: script:
- pacman -Syu --noconfirm m4 make openssh subversion rsync arch-install-scripts git bzr mercurial diffutils coreutils asciidoctor shellcheck nvchecker bats - pacman -Syu --noconfirm m4 make openssh subversion rsync arch-install-scripts git bzr mercurial diffutils coreutils asciidoctor shellcheck nvchecker bats bats-assert bats-support
- make test BATS_EXTRA_ARGS='--formatter junit' - make test BATS_EXTRA_ARGS='--formatter junit'
artifacts: artifacts:
reports: reports:
@@ -34,7 +34,7 @@ coverage:
stage: test stage: test
needs: [] needs: []
script: script:
- pacman -Syu --noconfirm m4 make openssh subversion rsync arch-install-scripts git bzr mercurial diffutils coreutils asciidoctor shellcheck nvchecker bats kcov jq - pacman -Syu --noconfirm m4 make openssh subversion rsync arch-install-scripts git bzr mercurial diffutils coreutils asciidoctor shellcheck nvchecker bats bats-assert bats-support kcov jq
- make coverage - make coverage
coverage: '/Percent covered\s+\d+\.\d+/' coverage: '/Percent covered\s+\d+\.\d+/'
artifacts: artifacts:

View File

@@ -150,7 +150,6 @@ _pkgctl_cmds=(
db db
diff diff
issue issue
license
release release
repo repo
search search

View File

@@ -312,7 +312,7 @@ pkgctl_build() {
# Update pacman cache for auto-detection # Update pacman cache for auto-detection
if [[ -z ${REPO} ]]; then if [[ -z ${REPO} ]]; then
update_pacman_repo_cache stable update_pacman_repo_cache multilib
# Check valid repos if not resolved dynamically # Check valid repos if not resolved dynamically
elif ! in_array "${REPO}" "${DEVTOOLS_VALID_REPOS[@]}"; then elif ! in_array "${REPO}" "${DEVTOOLS_VALID_REPOS[@]}"; then
die "Invalid repository target: %s" "${REPO}" die "Invalid repository target: %s" "${REPO}"

View File

@@ -51,6 +51,7 @@ pkgctl_db_remove() {
local partial=0 local partial=0
local confirm=1 local confirm=1
local dbscripts_options=() local dbscripts_options=()
local lookup_repo=multilib
local pkgname local pkgname
# option checking # option checking
@@ -105,13 +106,13 @@ pkgctl_db_remove() {
update_pacman_repo_cache unstable update_pacman_repo_cache unstable
;; ;;
*-staging) *-staging)
update_pacman_repo_cache staging update_pacman_repo_cache multilib-staging
;; ;;
*-testing) *-testing)
update_pacman_repo_cache testing update_pacman_repo_cache multilib-testing
;; ;;
*) *)
update_pacman_repo_cache stable update_pacman_repo_cache multilib
;; ;;
esac esac

View File

@@ -188,7 +188,6 @@ path = [
"README.md", "README.md",
"keys/**", "keys/**",
".SRCINFO", ".SRCINFO",
".gitignore",
".nvchecker.toml", ".nvchecker.toml",
"*.install", "*.install",
"*.sysusers", "*.sysusers",

View File

@@ -124,7 +124,7 @@ pkgctl_release() {
# Update pacman cache for auto-detection # Update pacman cache for auto-detection
if [[ -z ${REPO} ]]; then if [[ -z ${REPO} ]]; then
update_pacman_repo_cache stable update_pacman_repo_cache multilib
# Check valid repos if not resolved dynamically # Check valid repos if not resolved dynamically
elif ! in_array "${REPO}" "${DEVTOOLS_VALID_REPOS[@]}"; then elif ! in_array "${REPO}" "${DEVTOOLS_VALID_REPOS[@]}"; then
die "Invalid repository target: %s" "${REPO}" die "Invalid repository target: %s" "${REPO}"

View File

@@ -110,6 +110,11 @@ pkgctl_repo_configure() {
local path realpath pkgbase remote_url project_path hook local path realpath pkgbase remote_url project_path hook
local PACKAGER GPGKEY packager_name packager_email local PACKAGER GPGKEY packager_name packager_email
# Check if we're in a git repo
if ! git rev-parse --git-dir &>/dev/null; then
die "Not in a git repository"
fi
while (( $# )); do while (( $# )); do
case $1 in case $1 in
-h|--help) -h|--help)
@@ -150,7 +155,8 @@ pkgctl_repo_configure() {
# check if invoked without any path from within a packaging repo # check if invoked without any path from within a packaging repo
if (( ${#paths[@]} == 0 )); then if (( ${#paths[@]} == 0 )); then
if [[ -f PKGBUILD ]]; then if [[ -d .git ]] || git rev-parse --git-dir &>/dev/null; then
# We're in a git repository, so use current directory
paths=(".") paths=(".")
else else
pkgctl_repo_configure_usage pkgctl_repo_configure_usage
@@ -226,10 +232,19 @@ pkgctl_repo_configure() {
pushd "${path}" >/dev/null pushd "${path}" >/dev/null
project_path=$(gitlab_project_name_to_path "${pkgbase}") # Check if this is a packaging repository
remote_url="${GIT_REPO_BASE_URL}/${project_path}.git" local is_packaging_repo=0
if ! git remote add origin "${remote_url}" &>/dev/null; then if [[ -f PKGBUILD ]]; then
git remote set-url origin "${remote_url}" is_packaging_repo=1
fi
# Configure remote only for packaging repositories
if (( is_packaging_repo )); then
project_path=$(gitlab_project_name_to_path "${pkgbase}")
remote_url="${GIT_REPO_BASE_URL}/${project_path}.git"
if ! git remote add origin "${remote_url}" &>/dev/null; then
git remote set-url origin "${remote_url}"
fi
fi fi
# move the master branch to main # move the master branch to main
@@ -239,7 +254,7 @@ pkgctl_repo_configure() {
fi fi
# configure spec version and variant to avoid using development hooks in production # configure spec version and variant to avoid using development hooks in production
git config devtools.version "${GIT_REPO_SPEC_VERSION}" git config devtools.version "${GIT_REPO_SPEC_VERSION:-1.0.0}"
if [[ ${_DEVTOOLS_LIBRARY_DIR} == /usr/share/devtools ]]; then if [[ ${_DEVTOOLS_LIBRARY_DIR} == /usr/share/devtools ]]; then
git config devtools.variant canonical git config devtools.variant canonical
else else
@@ -249,8 +264,12 @@ pkgctl_repo_configure() {
git config pull.rebase true git config pull.rebase true
git config branch.autoSetupRebase always git config branch.autoSetupRebase always
git config branch.main.remote origin
git config branch.main.rebase true # Configure branch remote settings only for packaging repositories with remotes
if (( is_packaging_repo )) && git remote | grep -q "^origin$"; then
git config branch.main.remote origin
git config branch.main.rebase true
fi
git config transfer.fsckobjects true git config transfer.fsckobjects true
git config fetch.fsckobjects true git config fetch.fsckobjects true

View File

@@ -1,26 +0,0 @@
#!/hint/bash
#
# SPDX-License-Identifier: GPL-3.0-or-later
[[ -z ${DEVTOOLS_INCLUDE_UTIL_MACHINE_SH:-} ]] || return 0
DEVTOOLS_INCLUDE_UTIL_MACHINE_SH=1
_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@}
# shellcheck source=src/lib/common.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh
set -eo pipefail
machine_get_hardware_name() {
uname --machine
}
machine_has_multilib() {
case "$(machine_get_hardware_name)" in
x86_64*)
return 0
;;
esac
return 1
}

View File

@@ -8,8 +8,6 @@ DEVTOOLS_INCLUDE_UTIL_PACMAN_SH=1
_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} _DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@}
# shellcheck source=src/lib/common.sh # shellcheck source=src/lib/common.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh
# shellcheck source=src/lib/util/machine.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/util/machine.sh
set -e set -e
@@ -20,8 +18,7 @@ readonly _DEVTOOLS_MAKEPKG_CONF_DIR=${_DEVTOOLS_LIBRARY_DIR}/makepkg.conf.d
update_pacman_repo_cache() { update_pacman_repo_cache() {
local repo=${1:-stable} local repo=${1:-multilib}
repo=$(pacman_resolve_virtual_repo_name "${repo}")
mkdir -p "${_DEVTOOLS_PACMAN_CACHE_DIR}" mkdir -p "${_DEVTOOLS_PACMAN_CACHE_DIR}"
msg "Updating pacman database cache" msg "Updating pacman database cache"
@@ -35,8 +32,7 @@ update_pacman_repo_cache() {
get_pacman_repo_from_pkgbuild() { get_pacman_repo_from_pkgbuild() {
local path=${1:-PKGBUILD} local path=${1:-PKGBUILD}
local repo=${2:-stable} local repo=${2:-multilib}
repo=$(pacman_resolve_virtual_repo_name "${repo}")
local -a pkgnames local -a pkgnames
# shellcheck source=contrib/makepkg/PKGBUILD.proto # shellcheck source=contrib/makepkg/PKGBUILD.proto
@@ -76,7 +72,6 @@ get_pkgnames_from_repo_pkgbase() {
# update the pacman repo cache if it doesn't exist yet # update the pacman repo cache if it doesn't exist yet
if [[ ! -d "${_DEVTOOLS_PACMAN_CACHE_DIR}" ]]; then if [[ ! -d "${_DEVTOOLS_PACMAN_CACHE_DIR}" ]]; then
# TODO: universe includes multilib, switch for architecture
update_pacman_repo_cache universe update_pacman_repo_cache universe
fi fi
@@ -96,23 +91,3 @@ get_pkgnames_from_repo_pkgbase() {
printf "%s\n" "${pkgnames[@]}" printf "%s\n" "${pkgnames[@]}"
return 0 return 0
} }
pacman_resolve_virtual_repo_name() {
local repo=$1
local repo_class=extra
if machine_has_multilib; then
repo_class=multilib
fi
case "${repo}" in
stable)
repo=${repo_class}
;;
testing|staging)
repo="${repo_class}-${repo}"
;;
esac
printf "%s" "${repo}"
}

View File

@@ -6,7 +6,6 @@
# shellcheck disable=2034 # shellcheck disable=2034
DEVTOOLS_VALID_BINARY_ARCHES=( DEVTOOLS_VALID_BINARY_ARCHES=(
x86_64 x86_64
aarch64
) )
# shellcheck disable=2034 # shellcheck disable=2034

View File

@@ -0,0 +1,71 @@
#!/usr/bin/env bats
bats_require_minimum_version 1.5.0
# Load bats libraries
load "/usr/lib/bats/bats-support/load.bash"
load "/usr/lib/bats/bats-assert/load.bash"
export _DEVTOOLS_LIBRARY_DIR="${PWD}/src"
_pkgctl_repo_configure() {
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/repo/configure.sh
pkgctl_repo_configure "$@"
}
@test "repo-configure-valid-packaging" {
local tmpdir
tmpdir=$(mktemp -dt devtools.test.repo-configure.XXXXXX)
pushd "${tmpdir}"
git init
git remote add origin "https://gitlab.archlinux.org/archlinux/packaging/packages/devtools.git"
run _pkgctl_repo_configure
assert_success
popd
rm -rf "${tmpdir}"
}
@test "repo-configure-non-packaging" {
local tmpdir
tmpdir=$(mktemp -dt devtools.test.repo-configure.XXXXXX)
pushd "${tmpdir}"
git init
git remote add origin "https://gitlab.com/kicad/libraries/kicad-packages3D.git"
run _pkgctl_repo_configure
assert_success
popd
rm -rf "${tmpdir}"
}
@test "repo-configure-non-arch" {
local tmpdir
tmpdir=$(mktemp -dt devtools.test.repo-configure.XXXXXX)
pushd "${tmpdir}"
git init
git remote add origin "https://github.com/torvalds/linux.git"
run _pkgctl_repo_configure
assert_success
popd
rm -rf "${tmpdir}"
}
@test "repo-configure-no-git" {
local tmpdir
tmpdir=$(mktemp -dt devtools.test.repo-configure.XXXXXX)
pushd "${tmpdir}"
run ! _pkgctl_repo_configure
assert_failure
assert_output --partial "Not in a git repository"
popd
rm -rf "${tmpdir}"
}
@test "repo-configure-local-git" {
local tmpdir
tmpdir=$(mktemp -dt devtools.test.repo-configure.XXXXXX)
pushd "${tmpdir}"
git init
run _pkgctl_repo_configure
assert_success
popd
rm -rf "${tmpdir}"
}