[pacman-dev] Add fossil scm support to makepkg

Message ID 20201105035059.73936-1-escondida@iff.ink
State Superseded, archived
Headers show
Series
  • [pacman-dev] Add fossil scm support to makepkg
Related show

Commit Message

escondida@iff.ink Nov. 5, 2020, 3:50 a.m. UTC
From: Ivy Foster <escondida@iff.ink>

Signed-off-by: Ivy Foster <escondida@iff.ink>
---
 doc/PKGBUILD.5.asciidoc                |   3 +
 scripts/libmakepkg/source/fossil.sh.in | 124 +++++++++++++++++++++++++
 scripts/libmakepkg/util/source.sh.in   |   5 +-
 3 files changed, 131 insertions(+), 1 deletion(-)
 create mode 100644 scripts/libmakepkg/source/fossil.sh.in

Comments

Eli Schwartz Nov. 5, 2020, 4:42 a.m. UTC | #1
On 11/4/20 10:50 PM, escondida@iff.ink wrote:
> From: Ivy Foster <escondida@iff.ink>

Please extend libmakepkg/executable/vcs.sh.in to check for fossil source
urls and verify that the registered VCSCLIENTS=() in etc/makepkg.conf.in
is consulted to see if it is installed.

> 
> Signed-off-by: Ivy Foster <escondida@iff.ink>
> ---
>  doc/PKGBUILD.5.asciidoc                |   3 +
>  scripts/libmakepkg/source/fossil.sh.in | 124 +++++++++++++++++++++++++
>  scripts/libmakepkg/util/source.sh.in   |   5 +-
>  3 files changed, 131 insertions(+), 1 deletion(-)
>  create mode 100644 scripts/libmakepkg/source/fossil.sh.in
> 
> diff --git a/doc/PKGBUILD.5.asciidoc b/doc/PKGBUILD.5.asciidoc
> index 2e2108a0..54bb7775 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, checkin, ci, commit, tag (checkin, ci, and commit are synomymous)

We don't need the synonymity, please stick to one. I prefer commit for
symmetry with git.

> +
>  	*git*;;
>  		branch, commit, tag
>  
> diff --git a/scripts/libmakepkg/source/fossil.sh.in b/scripts/libmakepkg/source/fossil.sh.in
> new file mode 100644
> index 00000000..a0fe0480
> --- /dev/null
> +++ b/scripts/libmakepkg/source/fossil.sh.in
> @@ -0,0 +1,124 @@
> +#!/bin/bash
> +#
> +#   fossil.sh - function for handling the download and extraction of Fossil sources
> +#
> +#   Copyright (c) 2015-2020 Pacman Development Team <pacman-dev@archlinux.org>

This file can start in 2002, probably. :)

> +#
> +#   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 list -R $db | grep "$url"); then
> +			error "$(gettext "%s is not a clone of %s")" "$db" "$url"
> +			plainerr "$(gettext "Aborting...")"
> +			exit 1

If this has multiple remotes but the current default is not the one we
want, this seems like it would pass...

> +		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 [[ -f "$dir/.fslckout" ]]; then
> +		cd_safe "$dir"
> +		if ! (fossil revert && fossil clean --verily); then
> +			error "$(gettext "Failure while updating working copy of %s %s repo")" "${repo}" "fossil"
> +			plainerr "$(gettext "Aborting...")"
> +			exit 1
> +		fi

This entire block feels terribly wrong. In git, we fetch the $SRCDEST
version into the $srcdir one, since they're different git repos wired
together as remotes. In fossil, it looks like this is unnecessary and
should be skipped (the metadata is directly referenced and opened in
$srcdir).

Instead, what this is doing is trying to break incremental builds by
deleting all untracked files (we do not do this for other sources, but
let you use makepkg -C to nuke $srcdir for this purpose), but not
modifying the potential revision at all, then declaring this to be the
"updating working copy" step of the extraction.



> +		cd_safe "$srcdir"
> +	elif [[ -d "$dir" && ! -f "$dir/.fslckout" ]]; then
> +		error "$(gettext "%s is not a working copy of %s")" "$dir" "$db"
> +		plainerr "$(gettext "Aborting...")"
> +		exit 1

This string is new. Shouldn't fossil detect this automatically? How does
checking for the existence of the metadata file tell you which repo it
is a clone of?

> +	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|checkin|ci|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" "$ref"
> +		plainerr "$(gettext "Aborting...")"
> +		exit 1
> +	fi
> +
> +	popd &>/dev/null
> +}
> 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..54bb7775 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, checkin, ci, commit, tag (checkin, ci, and commit are synomymous)
+
 	*git*;;
 		branch, commit, tag
 
diff --git a/scripts/libmakepkg/source/fossil.sh.in b/scripts/libmakepkg/source/fossil.sh.in
new file mode 100644
index 00000000..a0fe0480
--- /dev/null
+++ b/scripts/libmakepkg/source/fossil.sh.in
@@ -0,0 +1,124 @@ 
+#!/bin/bash
+#
+#   fossil.sh - function for handling the download and extraction of Fossil sources
+#
+#   Copyright (c) 2015-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 list -R $db | grep "$url"); 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 [[ -f "$dir/.fslckout" ]]; then
+		cd_safe "$dir"
+		if ! (fossil revert && fossil clean --verily); then
+			error "$(gettext "Failure while updating working copy of %s %s repo")" "${repo}" "fossil"
+			plainerr "$(gettext "Aborting...")"
+			exit 1
+		fi
+		cd_safe "$srcdir"
+	elif [[ -d "$dir" && ! -f "$dir/.fslckout" ]]; then
+		error "$(gettext "%s is not a working copy of %s")" "$dir" "$db"
+		plainerr "$(gettext "Aborting...")"
+		exit 1
+	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|checkin|ci|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" "$ref"
+		plainerr "$(gettext "Aborting...")"
+		exit 1
+	fi
+
+	popd &>/dev/null
+}
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