commit 42c7d9f51d552a6b9c25d22940de0fb16def587a
parent 2af6fff5d5b5fc48f62848a7d99d9561632e73a7
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Tue, 10 Jun 2025 21:49:34 +0200
git-publish: unpublish repositories
Add the -d option to unpublish repositories, i.e. to delete the data
that makes them public.
Diffstat:
| M | git-publish | | | 129 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------- |
| M | git-publish.1 | | | 12 | +++++++++--- |
2 files changed, 112 insertions(+), 29 deletions(-)
diff --git a/git-publish b/git-publish
@@ -41,7 +41,7 @@ die()
synopsis()
{
>&2 printf \
-'usage: %s [-f] [-g dir_git] [-u base_url] [-w dir_www] repository ...\n' \
+'usage: %s [-df] [-g dir_git] [-u base_url] [-w dir_www] repository ...\n' \
"${0##*/}"
}
@@ -122,12 +122,11 @@ publish_repo()
cd "${OLDPWD}"
}
+# Returns 0 if the repository has no receive hook or if it is the one
+# configured by git-publish, and >0 otherwise.
# Inputs:
-# - base_url: base URL under which the git HTML repository is exposed
-# - dir_git: directory where to publish the git repository
-# - dir_www: directory where to publish the git repository's HTML pages
-# - repo: git bare repository
-setup_post_receive_hook()
+# - 1: repository
+check_post_receive_hook()
{
hook="${GIT_PUBLISH_RESOURCES_PATH}/post-receive.in"
@@ -135,15 +134,28 @@ setup_post_receive_hook()
digest="$(cksum "${hook}" | cut -d' ' -f1)"
header='# git-publish '"${digest}"
- if [ -e "${repo}/hooks/post-receive" ]; then
- # Don't overwrite the repository's already configured post-receive
- # hook if it hasn't been configured by git-publish.
- header2="$(sed -n '2p' "${repo}/hooks/post-receive")"
+ if [ -e "$1/hooks/post-receive" ]; then
+ header2="$(sed -n '2p' "$1/hooks/post-receive")"
if [ ! "${header}" = "${header2}" ]; then
- >&2 printf 'another post-receive hook already exist\n'
return 1
fi
fi
+}
+
+# Inputs:
+# - base_url: base URL under which the git HTML repository is exposed
+# - dir_git: directory where to publish the git repository
+# - dir_www: directory where to publish the git repository's HTML pages
+# - repo: git bare repository
+setup_post_receive_hook()
+{
+ # shellcheck disable=SC2310
+ if ! check_post_receive_hook "${repo}"; then
+ # Don't overwrite the repository's already configured post-receive
+ # hook if it hasn't been configured by git-publish.
+ >&2 printf 'another post-receive hook already exist\n'
+ return 1
+ fi
sed "2i ${header}" "${hook}" \
| sed -e "s#@DIR_GIT@#${dir_git}#g" \
@@ -188,13 +200,65 @@ make_index()
repo_list=$(find "${dir_git}" -path "${dir_git}/*.git" -prune | sort \
| join - "${tmpfile}" | tr '\n' ' ')
- # Generate the index
- # shellcheck disable=SC2086
- stagit-index ${repo_list} > "${dir_www}/index.html"
+ if [ -z "${repo_list}" ]; then
+ # No repo to index. Delete index file if any
+ rm -f "${dir_www}/index.html"
+ else
+ # Generate the index
+ # shellcheck disable=SC2086
+ stagit-index ${repo_list} > "${dir_www}/index.html"
+ fi
rm -f "${tmpfile}"
}
+
+# Inputs:
+# - @: repository list
+# - base_url: base URL under which the git HTML repository is exposed
+# - dir_git: directory where to publish the git repository
+# - dir_www: directory where to publish the git repository's HTML pages
+# - force: force generation of HTML pages from scratch
+publish() # list of repositories
+{
+ printf '%s\n' "$@" | while read -r repo; do
+ printf '%s: ' "${repo}"
+ check_repo
+ publish_repo
+ setup_post_receive_hook
+ printf 'done\n'
+ done
+}
+
+# Inputs:
+# - @ : repository list
+# - base_url: base URL under which the git HTML repositories are exposed
+# - dir_git: directory where to publish the git repositories
+# - dir_www: directory where to publish the git repositories' HTML pages
+# - force: force generation of HTML pages from scratch
+unpublish()
+{
+ printf '%s\n' "$@" | while read -r repo; do
+ printf '%s: ' "${repo}"
+
+ check_repo
+
+ repo_name=$(basename "${repo}" ".git")
+ repo_www="${dir_www}/${repo_name}"
+ repo_git="${dir_git}/${repo_name}.git"
+
+ rm -rf "${repo_www}" # Remove HTML pages
+ rm -f "${repo_git}" # Remove link in the publicly exposed directory
+
+ # shellcheck disable=SC2310
+ if check_post_receive_hook "${repo}"; then
+ rm -f "${repo}/hooks/post-receive"
+ fi
+
+ printf 'done\n'
+ done
+}
+
########################################################################
# The script
########################################################################
@@ -202,11 +266,13 @@ base_url="${GIT_PUBLISH_BASE_URL:-}"
dir_git="${GIT_PUBLISH_DIR_GIT:-/srv/git}"
dir_www="${GIT_PUBLISH_DIR_WWW:-/srv/www/git}"
force=0 # Force HTML generation
+delete=0 # Delete publication
# Parse input arguments
OPTIND=1
-while getopts ":fg:u:w:" opt; do
+while getopts ":dfg:u:w:" opt; do
case "${opt}" in
+ d) delete=1 ;;
f) force=1 ;;
u) base_url="${OPTARG}" ;;
g) dir_git="${OPTARG}" ;; # git directory
@@ -217,24 +283,35 @@ done
# Check mandatory options
[ "${OPTIND}" -le $# ] || { synopsis; die; }
-[ -n "${base_url}" ] || { >&2 printf 'Base url is missing\n'; die; }
-[ -n "${dir_git}" ] || { >&2 printf 'git directory is missing\n'; die; }
-[ -n "${dir_www}" ] || { >&2 printf 'WWW directory is missing\n'; die; }
+
+if [ -z "${dir_git}" ]; then
+ >&2 printf 'git directory is missing\n'
+ die
+fi
+if [ -z "${dir_www}" ]; then
+ >&2 printf 'WWW directory is missing\n'
+ die
+fi
+if [ -z "${base_url}" ] && [ "${delete}" -eq 0 ]; then
+ >&2 printf 'Base url is missing\n'
+ die
+fi
check_directory "${dir_git}"
check_directory "${dir_www}"
-check_resources "${dir_www}"
+
+if [ ! "${delete}" -eq 0 ]; then
+ check_resources "${dir_www}"
+fi
# Skip parsed arguments
shift $((OPTIND - 1))
-printf '%s\n' "$@" | while read -r repo; do
- printf '%s: ' "${repo}"
- check_repo
- publish_repo
- setup_post_receive_hook
- printf 'done\n'
-done
+if [ "${delete}" -eq 0 ]; then
+ publish "$@"
+else
+ unpublish "$@"
+fi
# [Re]generate index of publicly exposed repositories
make_index
diff --git a/git-publish.1 b/git-publish.1
@@ -12,7 +12,7 @@
.\"
.\" You should have received a copy of the GNU General Public License
.\" along with this program. If not, see <http://www.gnu.org/licenses/>.
-.Dd May 30, 2025
+.Dd June 10, 2025
.Dt GIT-PUBLISH 1
.Os
.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
@@ -22,7 +22,7 @@
.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
.Sh SYNOPSIS
.Nm
-.Op Fl f
+.Op Fl df
.Op Fl g Ar dir_git
.Op Fl u Ar base_url
.Op Fl w Ar dir_www
@@ -46,6 +46,11 @@ published repositories to update HTML pages on new commits
.Pp
The options are as follows:
.Bl -tag -width Ds
+.It Fl c
+Unpublish repositories: their link in the publicly exposed directory is
+removed, as are their HTML pages and the post-receive hook that updates
+them.
+In other words, the publication process is cancelled.
.It Fl f
Force HTML generation from scratch.
Enabling this option ensures that HTML pages take into account any
@@ -95,7 +100,8 @@ The default is
Base URL to make links in the ATOM feed absolute.
It has no default value and must be explicitly defined if the
.Fl u
-option is not used.
+option is not used, unless publications are to be deleted
+.Pq option Fl c .
.It Ev GIT_PUBLISH_DIR_WWW
Directory where public repository HTML pages are stored.
The default is