From e28ff4830423d73caf32c279f54087b4b6376b35 Mon Sep 17 00:00:00 2001 From: Tim Schumacher Date: Sat, 2 Sep 2023 09:18:50 +0200 Subject: [PATCH] Ports: Introduce support for Git repositories --- Ports/.port_include.sh | 76 ++++++++++++++++++++++++++++++++++++++---- Ports/README.md | 26 +++++++++++++-- 2 files changed, 94 insertions(+), 8 deletions(-) diff --git a/Ports/.port_include.sh b/Ports/.port_include.sh index 5c66ba2eaf8..2469df03672 100755 --- a/Ports/.port_include.sh +++ b/Ports/.port_include.sh @@ -119,6 +119,10 @@ cd "${PORT_BUILD_DIR}" # 2 = sha256sum FILES_SIMPLE_PATTERN='^(https?:\/\/.+)#([0-9a-f]{64})$' +# 1 = repository +# 2 = revision +FILES_GIT_PATTERN='^git\+(.+)#(.+)$' + cleanup_git() { echo "WARNING: Reverting changes to $workdir as we are in dev mode!" run git clean -xffd >/dev/null 2>&1 @@ -366,6 +370,38 @@ fetch_simple() { fi } +fetch_git() { + repository="${1}" + revision="${2}" + + directory="$(basename "${repository}")" + backing_copy="${PORT_META_DIR}/${directory}" + working_copy="${PORT_BUILD_DIR}/${directory}" + + run_nocd git init --bare "${backing_copy}" + run_nocd git -C "${backing_copy}" config core.autocrlf false + run_nocd git -C "${backing_copy}" worktree prune + run_nocd git -C "${backing_copy}" fetch --tags "${repository}" "${revision}" + + revision="$(git -C "${backing_copy}" rev-parse FETCH_HEAD)" + + if [ ! -e "${working_copy}/.git" ]; then + run_nocd git -C "${backing_copy}" worktree add "${working_copy}" "${revision}" + fi + + old_revision="" + if [ -e "${backing_copy}/refs/tags/source" ]; then + old_revision="$(git -C "${working_copy}" rev-parse refs/tags/source)" + fi + + if ! [ "${old_revision}" = "${revision}" ]; then + run_nocd git -C "${working_copy}" clean -ffdx + run_nocd git -C "${working_copy}" reset --hard + run_nocd git -C "${working_copy}" tag --no-sign -f source "${revision}" + run_nocd git -C "${working_copy}" checkout "${revision}" + fi +} + # FIXME: Don't allow overriding fetch, support multiple protocols instead. See #20004 func_defined fetch || fetch() { pre_fetch @@ -378,6 +414,13 @@ func_defined fetch || fetch() { continue fi + if [[ "${f}" =~ ${FILES_GIT_PATTERN} ]]; then + repository="${BASH_REMATCH[1]}" + revision="${BASH_REMATCH[2]}" + fetch_git "${repository}" "${revision}" + continue + fi + echo "error: Unknown syntax for files entry '${f}'" exit 1 done @@ -394,16 +437,30 @@ func_defined pre_patch || pre_patch() { } func_defined patch_internal || patch_internal() { + if [ -n "${IN_SERENITY_PORT_DEV:-}" ]; then + return + fi + # patch if it was not yet patched (applying patches multiple times doesn't work!) - if [ -z "${IN_SERENITY_PORT_DEV:-}" ] && [ -d "${PORT_META_DIR}/patches" ]; then + if [ -d "${PORT_META_DIR}/patches" ]; then for filepath in "${PORT_META_DIR}"/patches/*.patch; do filename=$(basename $filepath) - if [ ! -f "$workdir"/.${filename}_applied ]; then + if [ -f "$workdir"/.${filename}_applied ]; then + continue + fi + + if [ -e "${workdir}/.git" ]; then + run git am --keep-cr --keep-non-patch "${filepath}" + else run patch -p"$patchlevel" < "$filepath" run touch .${filename}_applied fi done fi + + if [ -e "${workdir}/.git" ]; then + run git tag --no-sign -f patched + fi } func_defined pre_configure || pre_configure() { : @@ -440,6 +497,13 @@ clean_dist() { continue fi + if [[ "${f}" =~ ${FILES_GIT_PATTERN} ]]; then + repository="${BASH_REMATCH[1]}" + directory=$(basename "$repository") + rm -rf "${PORT_META_DIR}/${directory}" + continue + fi + echo "error: Unknown syntax for files entry '${f}'" exit 1 done @@ -728,7 +792,7 @@ do_dev() { if [ "${1:-}" != "--no-depends" ]; then do_installdepends fi - if [ -d "$workdir" ] && [ ! -d "$workdir/.git" ]; then + if [ -d "$workdir" ] && [ ! -e "$workdir/.git" ]; then if prompt_yes_no "- Would you like to clean the working directory (i.e. ./package.sh clean)?"; then do_clean fi @@ -739,7 +803,7 @@ do_dev() { [ -d "$workdir" ] || { do_fetch pushd "$workdir" - if [ ! -d ".git" ]; then + if [ ! -e ".git" ]; then git init . git config core.autocrlf false git add --all --force @@ -770,12 +834,12 @@ do_dev() { done fi - git tag --no-sign patched + git tag --no-sign -f patched popd } - [ -d "$workdir/.git" ] || { + [ -e "$workdir/.git" ] || { >&2 echo "$workdir does not appear to be a git repository." >&2 echo "If you want to use './package.sh dev', please run './package.sh clean' first." exit 1 diff --git a/Ports/README.md b/Ports/README.md index f0dc15204bb..b80454e5773 100644 --- a/Ports/README.md +++ b/Ports/README.md @@ -190,8 +190,11 @@ depends=( #### `files` -An array of external files required by the port, one per line. The format of each -entry is as follows: +An array of external files required by the port, one per line. + +##### Simple downloads + +The format of each entry is as follows: ```text URL#HASH @@ -211,6 +214,25 @@ files=( If a file is a compressed tar archive, a gzip compressed file or a zip compressed file, it will be extracted. +##### Git repositories + +The format of each entry is as follows: + +```text +git+URL#REVISION +``` + +Where `URL` is the URL where the repository is located +and `REVISION` can be any revision qualifier that is accepted by `git fetch`. + +For example: + +```bash +files=( + 'git+https://gn.googlesource.com/gn#fae280eabe5d31accc53100137459ece19a7a295' +) +``` + #### `icon_file` The file to use for the port launcher icon. The icon file is assumed to have a