[pacman-dev,v2] Add fossil scm support to makepkg

Message ID 20201124221924.96479-1-escondida@iff.ink
State Superseded, archived
Headers show
Series [pacman-dev,v2] Add fossil scm support to makepkg | expand

Commit Message

Ivy Foster Nov. 24, 2020, 10:19 p.m. UTC
From: Ivy Foster <escondida@iff.ink>

Signed-off-by: Ivy Foster <escondida@iff.ink>
---
 doc/PKGBUILD.5.asciidoc                 |   3 +
 etc/makepkg.conf.in                     |   1 +
 scripts/libmakepkg/executable/vcs.sh.in |   2 +-
 scripts/libmakepkg/source/fossil.sh.in  | 126 ++++++++++++++++++++++++
 scripts/libmakepkg/source/meson.build   |   1 +
 scripts/libmakepkg/util/source.sh.in    |   5 +-
 6 files changed, 136 insertions(+), 2 deletions(-)
 create mode 100644 scripts/libmakepkg/source/fossil.sh.in

Comments

Eli Schwartz Nov. 24, 2020, 11:03 p.m. UTC | #1
On 11/24/20 5:19 PM, escondida@iff.ink wrote:
> From: Ivy Foster <escondida@iff.ink>
> 
> Signed-off-by: Ivy Foster <escondida@iff.ink>
> ---
>   doc/PKGBUILD.5.asciidoc                 |   3 +
>   etc/makepkg.conf.in                     |   1 +
>   scripts/libmakepkg/executable/vcs.sh.in |   2 +-
>   scripts/libmakepkg/source/fossil.sh.in  | 126 ++++++++++++++++++++++++
>   scripts/libmakepkg/source/meson.build   |   1 +
>   scripts/libmakepkg/util/source.sh.in    |   5 +-
>   6 files changed, 136 insertions(+), 2 deletions(-)
>   create mode 100644 scripts/libmakepkg/source/fossil.sh.in
> 
> diff --git a/doc/PKGBUILD.5.asciidoc b/doc/PKGBUILD.5.asciidoc
> index 2e2108a0..1db0b6c4 100644
> --- a/doc/PKGBUILD.5.asciidoc
> +++ b/doc/PKGBUILD.5.asciidoc
> @@ -499,6 +499,9 @@ The source URL is divided into four components:
>   	*bzr*;;
>   		revision (see `'bzr help revisionspec'` for details)
>   
> +	*fossil*;;
> +		branch, commit, tag
> +
>   	*git*;;
>   		branch, commit, tag
>   
> diff --git a/etc/makepkg.conf.in b/etc/makepkg.conf.in
> index e9582646..b13b1d5d 100644
> --- a/etc/makepkg.conf.in
> +++ b/etc/makepkg.conf.in
> @@ -24,6 +24,7 @@ DLAGENTS=('file::/usr/bin/curl -gqC - -o %o %u'
>   #-- The package required by makepkg to download VCS sources
>   #  Format: 'protocol::package'
>   VCSCLIENTS=('bzr::bzr'
> +            'fossil::fossil'
>               'git::git'
>               'hg::mercurial'
>               'svn::subversion')
> diff --git a/scripts/libmakepkg/executable/vcs.sh.in b/scripts/libmakepkg/executable/vcs.sh.in
> index 436b82db..756eeb81 100644
> --- a/scripts/libmakepkg/executable/vcs.sh.in
> +++ b/scripts/libmakepkg/executable/vcs.sh.in
> @@ -77,7 +77,7 @@ executable_vcs() {
>   		local proto=$(get_protocol "$netfile")
>   
>   		case $proto in
> -			bzr*|git*|hg*|svn*)
> +			bzr*|fossil*|git*|hg*|svn*)
>   				if ! type -p ${proto%%+*} > /dev/null; then
>   					local client
>   					client=$(get_vcsclient "$proto") || exit $?
> diff --git a/scripts/libmakepkg/source/fossil.sh.in b/scripts/libmakepkg/source/fossil.sh.in
> new file mode 100644
> index 00000000..74791878
> --- /dev/null
> +++ b/scripts/libmakepkg/source/fossil.sh.in
> @@ -0,0 +1,126 @@
> +#!/bin/bash
> +#
> +#   fossil.sh - function for handling the download and extraction of Fossil sources
> +#
> +#   Copyright (c) 2020 Pacman Development Team <pacman-dev@archlinux.org>
> +#
> +#   This program is free software; you can redistribute it and/or modify
> +#   it under the terms of the GNU General Public License as published by
> +#   the Free Software Foundation; either version 2 of the License, or
> +#   (at your option) any later version.
> +#
> +#   This program is distributed in the hope that it will be useful,
> +#   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +#   GNU General Public License for more details.
> +#
> +#   You should have received a copy of the GNU General Public License
> +#   along with this program.  If not, see <http://www.gnu.org/licenses/>.
> +#
> +
> +[[ -n "$LIBMAKEPKG_SOURCE_FOSSIL_SH" ]] && return
> +LIBMAKEPKG_SOURCE_FOSSIL_SH=1
> +
> +
> +LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
> +
> +source "$LIBRARY/util/message.sh"
> +source "$LIBRARY/util/pkgbuild.sh"
> +
> +download_fossil() {
> +	# abort early if parent says not to fetch
> +	if declare -p get_vcs > /dev/null 2>&1; then
> +		(( get_vcs )) || return
> +	fi
> +
> +	local netfile=$1
> +
> +	local db=$(get_filepath "$netfile")
> +	[[ -z "$db" ]] && db="$SRCDEST/$(get_filename "$netfile")"
> +
> +	local repo=$db
> +
> +	local url=$(get_url "$netfile")
> +	url=${url#fossil+}
> +	url=${url%%#*}
> +	url=${url%%\?*}
> +
> +	if [[ ! -f "$db" ]]; then
> +		msg2 "$(gettext "Cloning %s %s repo...")" "${repo}" "fossil"
> +		if ! fossil clone $url $db; then
> +			error "$(gettext "Failure while downloading %s %s repo")" "${repo}" "fossil"
> +			plainerr "$(gettext "Aborting...")"
> +			exit 1
> +		fi
> +	elif (( ! HOLDVER )); then
> +		# Make sure we are fetching the right repo
> +		if ! (fossil remote -R $db | grep "$url" >/dev/null); then

No need to surround the pipeline with () to run it in a subshell. () is 
not a requirement of either "if" or "!"

grep -q is preferable to grep > /dev/null, but I think you should 
imitate git here to do exact matching:

# Make sure we are fetching the right repo
if [[ "$url" != "$(git config --get remote.origin.url)" ]] ; then

So, if [[ $url != "$(fossil remote -R "$db")" ]]

Ensure $db is quoted (here and elsewhere), there's no reason $SRCDEST / 
$srcdir cannot contain whitespace.

> +			error "$(gettext "%s is not a clone of %s")" "$db" "$url"
> +			plainerr "$(gettext "Aborting...")"
> +			exit 1
> +		fi
> +		msg2 "$(gettext "Updating %s %s repo...")" "${repo}" "fossil"
> +		if ! fossil pull -R $db; then
> +			# only warn on failure to allow offline builds
> +			warning "$(gettext "Failure while updating %s %s repo")" "${repo}" "fossil"
> +		fi
> +	fi
> +}
> +
> +extract_fossil() {
> +	local netfile=$1 tagname
> +
> +	local fragment=$(get_uri_fragment "$netfile")
> +	local repo=$(get_filename "$netfile")
> +
> +	local db=$(get_filepath "$netfile")
> +	[[ -z "$db" ]] && db="$SRCDEST/$(get_filename "$netfile")"
> +	local dir=${db%%.fossil}
> +	dir=${dir##*/}
> +
> +	msg2 "$(gettext "Creating working copy of %s %s repo...")" "${repo}" "fossil"
> +	pushd "$srcdir" &>/dev/null
> +
> +	if [[ -d "$dir" ]]; then
> +		if [[ -f "$dir/.fslckout" ]]; then
> +			cd_safe "$dir"
> +			if ! (fossil info | awk '/^repository:/ {print $2}' | grep "$db" >/dev/null); then
> +				error "$(gettext "Failure while updating working copy of %s %s repo")" "${repo}" "fossil"

This seems to be a check for "<a> is not a working copy of <b>", you've 
moved up the check from the v1 patch and ensured it correctly checks, 
but the error message is no longer accurate.

Similar issue to above w.r.t. grep -q, () subshell, and [[

> +				plainerr "$(gettext "Aborting...")"
> +				exit 1
> +			fi
> +			cd_safe "$srcdir"
> +		else
> +			error "$(gettext "Failure while updating working copy of %s %s repo")" "${repo}" "fossil"
> +			plainerr "$(gettext "Aborting...")"
> +			exit 1

This seems to be correct now... the working copy doesn't strictly need 
to be updated like in git, but this line here will run whenever the 
working copy is not, in fact, a fossil repo at all. Which means we won't 
be able to update it down below since we fail early.

lgtm

> +		fi
> +	elif ! fossil open "$db" --workdir "$dir"; then
> +		error "$(gettext "Failure while creating working copy of %s %s repo")" "${repo}" "fossil"
> +		plainerr "$(gettext "Aborting...")"
> +		exit 1
> +	fi
> +
> +	cd_safe "${dir##*/}"
> +
> +	ref=tip
> +	if [[ -n $fragment ]]; then
> +		case ${fragment%%=*} in
> +			branch|commit|tag)
> +				ref=${fragment##*=}
> +				;;
> +			*)
> +				error "$(gettext "Unrecognized reference: %s")" "${fragment}"
> +				plainerr "$(gettext "Aborting...")"
> +				exit 1
> +		esac
> +	fi
> +
> +	if ! fossil update "$ref"; then
> +		error "$(gettext "Failure while creating working copy of %s %s repo")" "${repo}" "fossil"
> +		plainerr "$(gettext "Aborting...")"
> +		exit 1
> +	fi
> +
> +	popd &>/dev/null
> +}
> diff --git a/scripts/libmakepkg/source/meson.build b/scripts/libmakepkg/source/meson.build
> index 59326133..41b18c37 100644
> --- a/scripts/libmakepkg/source/meson.build
> +++ b/scripts/libmakepkg/source/meson.build
> @@ -3,6 +3,7 @@ libmakepkg_module = 'source'
>   sources = [
>     'bzr.sh.in',
>     'file.sh.in',
> +  'fossil.sh.in',
>     'git.sh.in',
>     'hg.sh.in',
>     'local.sh.in',
> diff --git a/scripts/libmakepkg/util/source.sh.in b/scripts/libmakepkg/util/source.sh.in
> index be7c15c2..029bf8ed 100644
> --- a/scripts/libmakepkg/util/source.sh.in
> +++ b/scripts/libmakepkg/util/source.sh.in
> @@ -65,7 +65,7 @@ get_filename() {
>   	local proto=$(get_protocol "$netfile")
>   
>   	case $proto in
> -		bzr|git|hg|svn)
> +		bzr|fossil|git|hg|svn)
>   			filename=${netfile%%#*}
>   			filename=${filename%%\?*}
>   			filename=${filename%/}
> @@ -73,6 +73,9 @@ get_filename() {
>   			if [[ $proto = bzr ]]; then
>   				filename=${filename#*lp:}
>   			fi
> +			if [[ $proto = fossil ]]; then
> +				filename=$filename.fossil
> +			fi
>   			if [[ $proto = git ]]; then
>   				filename=${filename%%.git*}
>   			fi
>

Patch

diff --git a/doc/PKGBUILD.5.asciidoc b/doc/PKGBUILD.5.asciidoc
index 2e2108a0..1db0b6c4 100644
--- a/doc/PKGBUILD.5.asciidoc
+++ b/doc/PKGBUILD.5.asciidoc
@@ -499,6 +499,9 @@  The source URL is divided into four components:
 	*bzr*;;
 		revision (see `'bzr help revisionspec'` for details)
 
+	*fossil*;;
+		branch, commit, tag
+
 	*git*;;
 		branch, commit, tag
 
diff --git a/etc/makepkg.conf.in b/etc/makepkg.conf.in
index e9582646..b13b1d5d 100644
--- a/etc/makepkg.conf.in
+++ b/etc/makepkg.conf.in
@@ -24,6 +24,7 @@  DLAGENTS=('file::/usr/bin/curl -gqC - -o %o %u'
 #-- The package required by makepkg to download VCS sources
 #  Format: 'protocol::package'
 VCSCLIENTS=('bzr::bzr'
+            'fossil::fossil'
             'git::git'
             'hg::mercurial'
             'svn::subversion')
diff --git a/scripts/libmakepkg/executable/vcs.sh.in b/scripts/libmakepkg/executable/vcs.sh.in
index 436b82db..756eeb81 100644
--- a/scripts/libmakepkg/executable/vcs.sh.in
+++ b/scripts/libmakepkg/executable/vcs.sh.in
@@ -77,7 +77,7 @@  executable_vcs() {
 		local proto=$(get_protocol "$netfile")
 
 		case $proto in
-			bzr*|git*|hg*|svn*)
+			bzr*|fossil*|git*|hg*|svn*)
 				if ! type -p ${proto%%+*} > /dev/null; then
 					local client
 					client=$(get_vcsclient "$proto") || exit $?
diff --git a/scripts/libmakepkg/source/fossil.sh.in b/scripts/libmakepkg/source/fossil.sh.in
new file mode 100644
index 00000000..74791878
--- /dev/null
+++ b/scripts/libmakepkg/source/fossil.sh.in
@@ -0,0 +1,126 @@ 
+#!/bin/bash
+#
+#   fossil.sh - function for handling the download and extraction of Fossil sources
+#
+#   Copyright (c) 2020 Pacman Development Team <pacman-dev@archlinux.org>
+#
+#   This program is free software; you can redistribute it and/or modify
+#   it under the terms of the GNU General Public License as published by
+#   the Free Software Foundation; either version 2 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#   GNU General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+[[ -n "$LIBMAKEPKG_SOURCE_FOSSIL_SH" ]] && return
+LIBMAKEPKG_SOURCE_FOSSIL_SH=1
+
+
+LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
+
+source "$LIBRARY/util/message.sh"
+source "$LIBRARY/util/pkgbuild.sh"
+
+download_fossil() {
+	# abort early if parent says not to fetch
+	if declare -p get_vcs > /dev/null 2>&1; then
+		(( get_vcs )) || return
+	fi
+
+	local netfile=$1
+
+	local db=$(get_filepath "$netfile")
+	[[ -z "$db" ]] && db="$SRCDEST/$(get_filename "$netfile")"
+
+	local repo=$db
+
+	local url=$(get_url "$netfile")
+	url=${url#fossil+}
+	url=${url%%#*}
+	url=${url%%\?*}
+
+	if [[ ! -f "$db" ]]; then
+		msg2 "$(gettext "Cloning %s %s repo...")" "${repo}" "fossil"
+		if ! fossil clone $url $db; then
+			error "$(gettext "Failure while downloading %s %s repo")" "${repo}" "fossil"
+			plainerr "$(gettext "Aborting...")"
+			exit 1
+		fi
+	elif (( ! HOLDVER )); then
+		# Make sure we are fetching the right repo
+		if ! (fossil remote -R $db | grep "$url" >/dev/null); then
+			error "$(gettext "%s is not a clone of %s")" "$db" "$url"
+			plainerr "$(gettext "Aborting...")"
+			exit 1
+		fi
+		msg2 "$(gettext "Updating %s %s repo...")" "${repo}" "fossil"
+		if ! fossil pull -R $db; then
+			# only warn on failure to allow offline builds
+			warning "$(gettext "Failure while updating %s %s repo")" "${repo}" "fossil"
+		fi
+	fi
+}
+
+extract_fossil() {
+	local netfile=$1 tagname
+
+	local fragment=$(get_uri_fragment "$netfile")
+	local repo=$(get_filename "$netfile")
+
+	local db=$(get_filepath "$netfile")
+	[[ -z "$db" ]] && db="$SRCDEST/$(get_filename "$netfile")"
+	local dir=${db%%.fossil}
+	dir=${dir##*/}
+
+	msg2 "$(gettext "Creating working copy of %s %s repo...")" "${repo}" "fossil"
+	pushd "$srcdir" &>/dev/null
+
+	if [[ -d "$dir" ]]; then
+		if [[ -f "$dir/.fslckout" ]]; then
+			cd_safe "$dir"
+			if ! (fossil info | awk '/^repository:/ {print $2}' | grep "$db" >/dev/null); then
+				error "$(gettext "Failure while updating working copy of %s %s repo")" "${repo}" "fossil"
+				plainerr "$(gettext "Aborting...")"
+				exit 1
+			fi
+			cd_safe "$srcdir"
+		else
+			error "$(gettext "Failure while updating working copy of %s %s repo")" "${repo}" "fossil"
+			plainerr "$(gettext "Aborting...")"
+			exit 1
+		fi
+	elif ! fossil open "$db" --workdir "$dir"; then
+		error "$(gettext "Failure while creating working copy of %s %s repo")" "${repo}" "fossil"
+		plainerr "$(gettext "Aborting...")"
+		exit 1
+	fi
+
+	cd_safe "${dir##*/}"
+
+	ref=tip
+	if [[ -n $fragment ]]; then
+		case ${fragment%%=*} in
+			branch|commit|tag)
+				ref=${fragment##*=}
+				;;
+			*)
+				error "$(gettext "Unrecognized reference: %s")" "${fragment}"
+				plainerr "$(gettext "Aborting...")"
+				exit 1
+		esac
+	fi
+
+	if ! fossil update "$ref"; then
+		error "$(gettext "Failure while creating working copy of %s %s repo")" "${repo}" "fossil"
+		plainerr "$(gettext "Aborting...")"
+		exit 1
+	fi
+
+	popd &>/dev/null
+}
diff --git a/scripts/libmakepkg/source/meson.build b/scripts/libmakepkg/source/meson.build
index 59326133..41b18c37 100644
--- a/scripts/libmakepkg/source/meson.build
+++ b/scripts/libmakepkg/source/meson.build
@@ -3,6 +3,7 @@  libmakepkg_module = 'source'
 sources = [
   'bzr.sh.in',
   'file.sh.in',
+  'fossil.sh.in',
   'git.sh.in',
   'hg.sh.in',
   'local.sh.in',
diff --git a/scripts/libmakepkg/util/source.sh.in b/scripts/libmakepkg/util/source.sh.in
index be7c15c2..029bf8ed 100644
--- a/scripts/libmakepkg/util/source.sh.in
+++ b/scripts/libmakepkg/util/source.sh.in
@@ -65,7 +65,7 @@  get_filename() {
 	local proto=$(get_protocol "$netfile")
 
 	case $proto in
-		bzr|git|hg|svn)
+		bzr|fossil|git|hg|svn)
 			filename=${netfile%%#*}
 			filename=${filename%%\?*}
 			filename=${filename%/}
@@ -73,6 +73,9 @@  get_filename() {
 			if [[ $proto = bzr ]]; then
 				filename=${filename#*lp:}
 			fi
+			if [[ $proto = fossil ]]; then
+				filename=$filename.fossil
+			fi
 			if [[ $proto = git ]]; then
 				filename=${filename%%.git*}
 			fi