11 Commits

Author SHA1 Message Date
99027f71d1 fix: make scripts/pre-push.d/check_for_request.sh executable 2025-05-19 07:35:04 +00:00
38736b34b2 feat(check_for_request): inform number of concurrent pull requests
Fixes: https://github.com/dmach/git-obs-hooks/issues/4
2025-04-28 08:08:32 +02:00
ba673ad5b3 fix(install): make shellcheck happy 2025-04-14 09:19:09 +02:00
b77a2f181b fix(template): simplify the script
trap EXIT is just too brittle, use plain || die

Suggested-by: geirha on #bash IRC channel
2025-04-14 09:19:09 +02:00
46cd9a1f68 fix(template): for cycle doesn't work with empty dirs, use find instead 2025-04-03 17:51:37 +02:00
eca735b640 fix(spec): run spec-cleaner -i *.spec 2025-04-03 17:51:37 +02:00
267f3655b6 feat: add subpackage git-obs-hooks-script-convert-changes
Add subpackage with a working script, which causes `git commit`
to generate default commit message based on the last record in
the `*.changes` file.
2025-04-03 17:51:37 +02:00
537c4f6bfd fix(template): make shellcheck happy
Also, GIT_OBS_HOOKS_DEBUG was meant to be initialized with a
default value 0, if nothing is set, not expanded with substring
from position 0, right?
2025-02-11 13:05:58 +01:00
efed568cad fix(template): run only *.sh files and only if they are executable
This is just copying what user expects from the similar runners
in the system. User needs to have an option to temporarily
disable some scripts for testing or debugging purposes.
2025-02-11 13:05:58 +01:00
4141bfd8e4 Merge pull request #1 from mcepl/patch-1
Update README.md
2025-02-11 13:04:04 +01:00
b19aecda90 Update README.md
Mark paths as code, so they are correctly displayed.
2025-02-10 23:28:47 +01:00
6 changed files with 201 additions and 43 deletions

View File

@@ -2,8 +2,8 @@
Framework for running git hooks in git-obs and osc
To install the hooks on the system, place executables under:
- /usr/share/git-obs-hooks/<git-hook>.d/<filename>
- ~/.local/share/git-obs-hooks/<git-hook>.d/<filename>
- `/usr/share/git-obs-hooks/<git-hook>.d/<filename>`
- `~/.local/share/git-obs-hooks/<git-hook>.d/<filename>`
To enable git-obs-hooks in the current git repo, run: install-git-obs-hooks
See githooks(5) man page for more help on the hooks.

55
git-obs-hook-template Normal file → Executable file
View File

@@ -1,51 +1,40 @@
#!/bin/sh
# Framework for running git hooks in git-obs and osc
#
# To install the hooks on the system, place executables under:
# - /usr/local/share/git-obs-hooks/<git-hook>.d/<filename>
# - /usr/share/git-obs-hooks/<git-hook>.d/<filename>
# - ~/.local/share/git-obs-hooks/<git-hook>.d/<filename>
# To enable git-obs-hooks in the current git repo, run: install-git-obs-hooks
#
# See githooks(5) man page for more help on the hooks.
set -eu
XDG_DATA_HOME=${XDG_DATA_HOME:-$HOME/.local/share}
GIT_OBS_HOOKS_DEBUG=${GIT_OBS_HOOKS_DEBUG:-${GIT_TRACE:-0}}
XDG_DATA_HOME="${XDG_DATA_HOME:-${HOME}/.local/share}"
GIT_OBS_HOOKS_DEBUG="${GIT_OBS_HOOKS_DEBUG:0}"
HOOK_NAME="$(basename $0)"
HOOK_DIR="$(readlink -f $0).d"
HOME_HOOK_DIR="${XDG_DATA_HOME}/git-obs-hooks/${HOOK_NAME}"
hook_name=${0##*/}
trap_exit() {
exit_code=$?
if [ ${exit_code} -ne 0 ]; then
echo "ERROR: ${HOOK_NAME} hook '${hook}' failed with exit code ${exit_code}"
fi
exit $exit_code
die() {
exit_code=$?
printf >&2 '%s\n' "$1"
exit "$exit_code"
}
trap "trap_exit" EXIT
debug_msg() {
if [ "${GIT_OBS_HOOKS_DEBUG}" != "1" ]; then
return
fi
echo "$@" >&1
if [ "$GIT_OBS_HOOKS_DEBUG" = 1 ]; then
printf >&2 '%s\n' "$1"
fi
}
debug_msg "Running ${HOOK_NAME} hooks:"
for hook in "${HOOK_DIR}"/*; do
debug_msg " - Running ${hook}"
${hook} "$@"
debug_msg "Running $hook_name hooks:"
for hook in \
"$XDG_DATA_HOME/git-obs-hooks/$hook_name.d"/* \
"/usr/local/share/git-obs-hooks/$hook_name.d"/* \
"/usr/share/git-obs-hooks/$hook_name.d"/*
do
if [ -f "$hook" ] && [ -x "$hook" ] ; then
debug_msg " - Running $hook"
"$hook" "$@" || die "ERROR: '$hook' failed with exit status $?"
fi
done
if [ -d "${HOME_HOOK_DIR}" ]; then
for hook in "${HOME_HOOK_DIR}"/*; do
debug_msg " - Running ${hook}"
${hook} "$@"
done
fi

View File

@@ -1,3 +1,4 @@
%define hook_dir %{_datadir}/git-obs-hooks
Name: git-obs-hooks
Version: 0.1.0
Release: 0
@@ -6,11 +7,8 @@ License: GPL-2.0-or-later
Group: Development/Tools/Other
URL: https://github.com/dmach/git-obs-hooks
Source: https://github.com/dmach/git-obs-hooks/archive/refs/tags/%{version}.tar.gz#/%{name}-%{version}.tar.gz
BuildRequires: fdupes
BuildArch: noarch
BuildRoot: %{_tmppath}/%{name}-%{version}-build
%define hook_dir %{_datarootdir}/git-obs-hooks
%description
Framework for running git hooks in git-obs and osc.
@@ -22,9 +20,21 @@ To enable git-obs-hooks in the current git repo, run: install-git-obs-hooks
See githooks(5) man page for more help on the hooks.
%package script-convert-changes
Summary: working script for %{name} converting last record of *.changes to git commit
Requires: %{name} = %{version}
%description script-convert-changes
Working script for %{name}, which causes `git commit` to generate
default commit message based on the last last record in the
`*.changes`.
%prep
%autosetup -p1
%build
:
%install
install -D install-git-obs-hooks %{buildroot}%{_bindir}/install-git-obs-hooks
@@ -70,8 +80,13 @@ install -D git-obs-hook-template %{buildroot}%{hook_dir}/sendemail-validate
install -d %{buildroot}%{hook_dir}/update.d
install -D git-obs-hook-template %{buildroot}%{hook_dir}/update
for scriptlet in scripts/*/*.sh ; do
cp -p "${scriptlet}" "%{buildroot}%{hook_dir}/${scriptlet#*/}"
done
%fdupes %{buildroot}%{hook_dir}
%files
%defattr(-,root,root,-)
%attr(0755, root, root) %{_bindir}/install-git-obs-hooks
%dir %{hook_dir}
%dir %{hook_dir}/*.d
@@ -92,4 +107,7 @@ install -D git-obs-hook-template %{buildroot}%{hook_dir}/update
%license LICENSE
%doc README.md
%files script-convert-changes
%{hook_dir}/prepare-commit-msg.d
%changelog

View File

@@ -2,12 +2,12 @@
GIT_TOPDIR=$(git rev-parse --show-toplevel 2>/dev/null)
# shellcheck disable=SC2181
if [ $? -ne 0 ]; then
echo "ERROR: Couldn't determine git top directory"
exit 1
fi
debug_msg() {
if [ "${GIT_OBS_HOOKS_DEBUG}" != "1" ]; then
return
@@ -20,11 +20,11 @@ HOOKS_TOPDIR="/usr/share/git-obs-hooks"
for hook_path in "${HOOKS_TOPDIR}"/*; do
if [ ! -x "${hook_path}" -o -d "${hook_path}" ]; then
if [ ! -x "${hook_path}" ] || [ -d "${hook_path}" ]; then
continue
fi
hook_name=$(basename ${hook_path})
hook_name=$(basename "${hook_path}")
git_hook_path="${GIT_TOPDIR}/.git/hooks/${hook_name}"
debug_msg "Installing hook ${hook_path} -> ${git_hook_path}"
ln -s --no-target-directory "${hook_path}" "${git_hook_path}"

View File

@@ -0,0 +1,117 @@
#!/bin/sh
set -eu
# REMOTE_NAME="$1" # This argument remains unused in the logic below
REMOTE_URL="$2"
parsed_output=$(echo "$REMOTE_URL" | awk '
{
url = $0
host = ""
path = ""
# Handle SCP-like syntax: user@host:path/repo.git
# Match user@hostname:path_part
if (match(url, /@([^:]+):(.*)/)) {
# Extract host (part between @ and :)
host_part = url
sub(/:.*/, "", host_part) # Keep only user@host
sub(/^[^@]+@/, "", host_part) # Keep only host
host = host_part
# Extract path (part after :)
path_part = url
sub(/^[^:]+:/, "", path_part) # Keep only path
path = path_part
}
# Handle standard URL syntax: scheme://user@host[:port]/path/repo.git
# Match :// followed by host part (non-slash) / path part
else if (match(url, /:\/\/([^/]+)\/(.*)/)) {
# Extract host part (might include user@ and :port)
host_part = url
sub(/^[^:]+:\/\//, "", host_part) # Remove scheme://
sub(/\/.*/, "", host_part) # Remove path onwards (/...)
# Isolate host from user@host[:port]
sub(/^[^@]+@/, "", host_part) # Remove user@ prefix if present
sub(/:[0-9]+$/, "", host_part) # Remove :port suffix if present
host = host_part
# Extract path part
path_part = url
# Keep only the part after the first slash following the scheme://host
sub(/^[^:]+:\/\/[^/]+\//, "", path_part)
path = path_part
} else {
# Fallback: Cannot determine host/path from format
path = url # Treat whole input as path
host = "" # Host unknown
}
# Clean path: Remove trailing .git if present
sub(/\.git$/, "", path)
# Clean path: Remove leading slash if present (important for API URL construction)
sub(/^\//, "", path)
# Output host and path separated by a pipe "|"
print host "|" path
}')
host=$(echo "$parsed_output" | cut -d'|' -f1)
path=$(echo "$parsed_output" | cut -d'|' -f2-)
# Check if hostname extraction was successful
if [ -z "$host" ]; then
echo "Error(awk): Could not extract hostname from URL: $REMOTE_URL" >&2
# Exit code 6: Hostname extraction failed
exit 6
fi
api_url="https://${host}/api/v1/repos/${path}"
count=""
api_response=""
# Make the API call. Handle potential curl errors gracefully with set -e.
api_response=$(curl --fail -s "$api_url" -H 'accept: application/json' || echo "curl_error")
if [ "$api_response" != "curl_error" ] && [ -n "$api_response" ]; then
count=$(echo "$api_response" | awk '
BEGIN { result = "awk_error" } # Default value if parsing fails
{
# Try to match the key, colon, and a number
if (match($0, /"open_pr_counter"[[:space:]]*:[[:space:]]*[0-9]+/)) {
matched_part = substr($0, RSTART, RLENGTH)
gsub(/[^0-9]/, "", matched_part) # Remove non-digits
if (matched_part != "") {
result = matched_part
exit # Found it
}
}
}
END { print result } # Print the found number or "awk_error"
')
elif [ "$api_response" = "curl_error" ]; then
echo "Error(curl): Failed fetching or received error from API: $api_url" >&2
exit 5
else
echo "Warning: Received empty response from API (but no HTTP error): $api_url" >&2
count="awk_error"
fi
case "$count" in
awk_error|curl_error)
echo "Warning: Could not determine open PR count (API/parse error)." >&2
;;
*[!0-9]*)
echo "Warning: Invalid non-numeric count value obtained: '$count'." >&2
;;
0)
# Count is 0, optionally print confirmation
# echo "Info: Repository has 0 open pull requests."
;;
*)
echo "Remote repository ($host/$path) has $count open pull requests."
;;
esac
exit 0

View File

@@ -0,0 +1,34 @@
#!/bin/sh
set -e
COMMIT_MSG_FILE="$1"
COMMIT_SOURCE="$2"
SHA1="${3:-HEAD}"
# {
# printf "COMMIT_MSG_FILE: %s\n" "$COMMIT_MSG_FILE" >>/tmp/prepare-commit-msg-log.txt
# printf "COMMIT_SOURCE: %s\n" "$COMMIT_SOURCE" >>/tmp/prepare-commit-msg-log.txt
# printf "SHA1: %s\n" "$SHA1" >>/tmp/prepare-commit-msg-log.txt
# printf "\n"
# } >>/tmp/prepare-commit-msg-log.txt
if test -z "$COMMIT_SOURCE"; then
if ! git add -- *.changes; then
echo "Error: Failed to add *.changes files." >&2
exit 1
fi
diff=$(git diff --no-color "$SHA1" -- *.changes \
| sed -E -n -e '/^\+[^+]/s/^\+//p' \
| sed -e '/^-\{4,\}/,+1d' \
| sed -e 's/^- *//')
if test -n "$diff"
then # Check if diff is not empty
TEMP_COMMIT_MSG=$(mktemp /tmp/moddiff.XXXXXX.msg)
trap 'rm -f $TEMP_COMMIT_MSG' EXIT
printf "%s\n" "$diff" >"$TEMP_COMMIT_MSG"
cat "$COMMIT_MSG_FILE" >>"$TEMP_COMMIT_MSG"
mv "$TEMP_COMMIT_MSG" "$COMMIT_MSG_FILE"
fi
fi