mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-04-26 07:18:59 +02:00
[cmake, docs, tools] update CPMUtil (#3183)
Rewrote the entire tooling scheme. That's about it, just make sure tooling works as expected everywhere. Signed-off-by: crueter <crueter@eden-emu.dev> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3183 Reviewed-by: MaranBr <maranbr@eden-emu.dev> Reviewed-by: CamilleLaVey <camillelavey99@gmail.com> Reviewed-by: Lizzie <lizzie@eden-emu.dev>
This commit is contained in:
parent
80327312dd
commit
966fcc0c30
37 changed files with 1297 additions and 868 deletions
79
tools/cpm/package/add.sh
Executable file
79
tools/cpm/package/add.sh
Executable file
|
|
@ -0,0 +1,79 @@
|
|||
#!/bin/sh -e
|
||||
|
||||
# SPDX-FileCopyrightText: Copyright 2025 crueter
|
||||
# SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
|
||||
RETURN=0
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: cpmutil.sh package add [-s|--sha] [-t|--tag]
|
||||
[-c|--cpmfile CPMFILE] [package name]
|
||||
|
||||
Add a new package to a cpmfile.
|
||||
|
||||
Options:
|
||||
-t, --tag Use tag versioning, instead of the default,
|
||||
commit sha versioning.
|
||||
-c, --cpmfile <CPMFILE> Use the specified cpmfile instead of the root cpmfile
|
||||
|
||||
Note that you are still responsible for integrating this into your CMake.
|
||||
|
||||
EOF
|
||||
|
||||
exit $RETURN
|
||||
}
|
||||
|
||||
die() {
|
||||
echo "-- $*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
_cpmfile() {
|
||||
[ -z "$1" ] && die "You must specify a valid cpmfile."
|
||||
CPMFILE="$1"
|
||||
}
|
||||
|
||||
while :; do
|
||||
case "$1" in
|
||||
-[a-z]*)
|
||||
opt=$(printf '%s' "$1" | sed 's/^-//')
|
||||
while [ -n "$opt" ]; do
|
||||
# cut out first char from the optstring
|
||||
char=$(echo "$opt" | cut -c1)
|
||||
opt=$(echo "$opt" | cut -c2-)
|
||||
|
||||
case "$char" in
|
||||
t) TAG=1 ;;
|
||||
c)
|
||||
_cpmfile "$2"
|
||||
shift
|
||||
;;
|
||||
h) usage ;;
|
||||
*) die "Invalid option -$char" ;;
|
||||
esac
|
||||
done
|
||||
;;
|
||||
--tag) TAG=1 ;;
|
||||
--cpmfile)
|
||||
_cpmfile "$2"
|
||||
shift
|
||||
;;
|
||||
--help) usage ;;
|
||||
"$0") break ;;
|
||||
"") break ;;
|
||||
*) PKG="$1" ;;
|
||||
esac
|
||||
|
||||
shift
|
||||
done
|
||||
|
||||
: "${CPMFILE:=$PWD/cpmfile.json}"
|
||||
|
||||
[ -z "$PKG" ] && die "You must specify a package name."
|
||||
|
||||
export PKG
|
||||
export CPMFILE
|
||||
export TAG
|
||||
|
||||
"$SCRIPTS"/util/interactive.sh
|
||||
46
tools/cpm/package/download.sh
Executable file
46
tools/cpm/package/download.sh
Executable file
|
|
@ -0,0 +1,46 @@
|
|||
#!/bin/sh -e
|
||||
|
||||
# SPDX-FileCopyrightText: Copyright 2025 crueter
|
||||
# SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: cpmutil.sh package download [-a|--all] [PACKAGE]...
|
||||
|
||||
Get the download URL for the specified packages.
|
||||
|
||||
Options:
|
||||
-a, --all Operate on all packages in this project.
|
||||
|
||||
EOF
|
||||
|
||||
exit 0
|
||||
}
|
||||
|
||||
while :; do
|
||||
case "$1" in
|
||||
-a | --all) ALL=1 ;;
|
||||
-h | --help) usage ;;
|
||||
"$0") break ;;
|
||||
"") break ;;
|
||||
*) packages="$packages $1" ;;
|
||||
esac
|
||||
|
||||
shift
|
||||
done
|
||||
|
||||
[ "$ALL" = 1 ] && packages="${LIBS:-$packages}"
|
||||
[ -z "$packages" ] && usage
|
||||
|
||||
for pkg in $packages; do
|
||||
PACKAGE="$pkg"
|
||||
export PACKAGE
|
||||
# shellcheck disable=SC1091
|
||||
. "$SCRIPTS"/vars.sh
|
||||
|
||||
if [ "$CI" = "true" ]; then
|
||||
echo "-- $PACKAGE: https://$GIT_HOST/$REPO"
|
||||
else
|
||||
echo -- "$PACKAGE: $DOWNLOAD"
|
||||
fi
|
||||
done
|
||||
156
tools/cpm/package/fetch.sh
Executable file
156
tools/cpm/package/fetch.sh
Executable file
|
|
@ -0,0 +1,156 @@
|
|||
#!/bin/sh -e
|
||||
|
||||
# SPDX-FileCopyrightText: Copyright 2025 crueter
|
||||
# SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
|
||||
: "${CPM_SOURCE_CACHE:=$PWD/.cache/cpm}"
|
||||
|
||||
mkdir -p "$CPM_SOURCE_CACHE"
|
||||
|
||||
ROOTDIR="$PWD"
|
||||
|
||||
TMP=$(mktemp -d)
|
||||
|
||||
download_package() {
|
||||
FILENAME=$(basename "$DOWNLOAD")
|
||||
|
||||
OUTFILE="$TMP/$FILENAME"
|
||||
|
||||
LOWER_PACKAGE=$(echo "$PACKAGE_NAME" | tr '[:upper:]' '[:lower:]')
|
||||
OUTDIR="${CPM_SOURCE_CACHE}/${LOWER_PACKAGE}/${KEY}"
|
||||
[ -d "$OUTDIR" ] && return
|
||||
|
||||
curl "$DOWNLOAD" -sS -L -o "$OUTFILE"
|
||||
|
||||
ACTUAL_HASH=$("${HASH_ALGO}"sum "$OUTFILE" | cut -d" " -f1)
|
||||
[ "$ACTUAL_HASH" != "$HASH" ] && echo "!! $FILENAME did not match expected hash; expected $HASH but got $ACTUAL_HASH" && exit 1
|
||||
|
||||
TMPDIR="$TMP/extracted"
|
||||
mkdir -p "$OUTDIR"
|
||||
mkdir -p "$TMPDIR"
|
||||
|
||||
PREVDIR="$PWD"
|
||||
mkdir -p "$TMPDIR"
|
||||
cd "$TMPDIR"
|
||||
|
||||
case "$FILENAME" in
|
||||
*.7z)
|
||||
7z x "$OUTFILE" >/dev/null
|
||||
;;
|
||||
*.tar*)
|
||||
tar xf "$OUTFILE" >/dev/null
|
||||
;;
|
||||
*.zip)
|
||||
unzip "$OUTFILE" >/dev/null
|
||||
;;
|
||||
esac
|
||||
|
||||
# basically if only one real item exists at the top we just move everything from there
|
||||
# since github and some vendors hate me
|
||||
DIRS=$(find . -maxdepth 1 -type d -o -type f)
|
||||
|
||||
# thanks gnu
|
||||
if [ "$(echo "$DIRS" | wc -l)" -eq 2 ]; then
|
||||
SUBDIR=$(find . -maxdepth 1 -type d -not -name ".")
|
||||
mv "$SUBDIR"/* "$OUTDIR"
|
||||
mv "$SUBDIR"/.* "$OUTDIR" 2>/dev/null || true
|
||||
rmdir "$SUBDIR"
|
||||
else
|
||||
mv ./* "$OUTDIR"
|
||||
mv ./.* "$OUTDIR" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
cd "$OUTDIR"
|
||||
|
||||
if echo "$JSON" | grep -e "patches" >/dev/null; then
|
||||
PATCHES=$(echo "$JSON" | jq -r '.patches | join(" ")')
|
||||
for patch in $PATCHES; do
|
||||
patch --binary -p1 <"$ROOTDIR/.patch/$PACKAGE/$patch"
|
||||
done
|
||||
fi
|
||||
|
||||
cd "$PREVDIR"
|
||||
}
|
||||
|
||||
ci_package() {
|
||||
[ "$REPO" = null ] && echo "-- ! No repo defined" && return
|
||||
|
||||
echo "-- CI package $PACKAGE_NAME"
|
||||
|
||||
for platform in windows-amd64 windows-arm64 \
|
||||
mingw-amd64 mingw-arm64 \
|
||||
android-aarch64 android-x86_64 \
|
||||
solaris-amd64 freebsd-amd64 openbsd-amd64 \
|
||||
linux-amd64 linux-aarch64 \
|
||||
macos-universal; do
|
||||
echo "-- * platform $platform"
|
||||
|
||||
case $DISABLED in
|
||||
*"$platform"*)
|
||||
echo "-- * -- disabled"
|
||||
continue
|
||||
;;
|
||||
*) ;;
|
||||
esac
|
||||
|
||||
FILENAME="${NAME}-${platform}-${VERSION}.${EXT}"
|
||||
DOWNLOAD="https://$GIT_HOST/${REPO}/releases/download/v${VERSION}/${FILENAME}"
|
||||
KEY="$platform-$VERSION"
|
||||
|
||||
LOWER_PACKAGE=$(echo "$PACKAGE_NAME" | tr '[:upper:]' '[:lower:]')
|
||||
OUTDIR="${CPM_SOURCE_CACHE}/${LOWER_PACKAGE}/${KEY}"
|
||||
[ -d "$OUTDIR" ] && continue
|
||||
|
||||
HASH_ALGO=$(echo "$JSON" | jq -r ".hash_algo")
|
||||
[ "$HASH_ALGO" = null ] && HASH_ALGO=sha512
|
||||
|
||||
HASH_SUFFIX="${HASH_ALGO}sum"
|
||||
HASH_URL="${DOWNLOAD}.${HASH_SUFFIX}"
|
||||
|
||||
HASH=$(curl "$HASH_URL" -sS -q -L -o -)
|
||||
|
||||
download_package
|
||||
done
|
||||
}
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: cpmutil.sh package fetch [a|--all] [PACKAGE]...
|
||||
|
||||
Fetch the specified package or packages from their defined download locations.
|
||||
If the package is already cached, it will not be re-fetched.
|
||||
|
||||
EOF
|
||||
|
||||
exit 0
|
||||
}
|
||||
|
||||
while :; do
|
||||
case "$1" in
|
||||
-h | --help) usage ;;
|
||||
-a | --all) ALL=1 ;;
|
||||
"$0") break ;;
|
||||
"") break ;;
|
||||
*) packages="$packages $1" ;;
|
||||
esac
|
||||
|
||||
shift
|
||||
done
|
||||
|
||||
[ "$ALL" = 1 ] && packages="${LIBS:-$packages}"
|
||||
[ -z "$packages" ] && usage
|
||||
|
||||
for PACKAGE in $packages; do
|
||||
export PACKAGE
|
||||
# shellcheck disable=SC1091
|
||||
. "$SCRIPTS"/vars.sh
|
||||
|
||||
if [ "$CI" = "true" ]; then
|
||||
ci_package
|
||||
else
|
||||
echo "-- Downloading regular package $PACKAGE, with key $KEY, from $DOWNLOAD"
|
||||
download_package
|
||||
fi
|
||||
done
|
||||
|
||||
rm -rf "$TMP"
|
||||
66
tools/cpm/package/hash.sh
Executable file
66
tools/cpm/package/hash.sh
Executable file
|
|
@ -0,0 +1,66 @@
|
|||
#!/bin/sh -e
|
||||
|
||||
# SPDX-FileCopyrightText: Copyright 2025 crueter
|
||||
# SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
|
||||
RETURN=0
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: cpmutil.sh package hash [-n|--dry-run] [-a|--all] [PACKAGE]...
|
||||
|
||||
Check the hash of a specific package or packages.
|
||||
If a hash mismatch occurs, this script will update the package's hash.
|
||||
|
||||
Options:
|
||||
-n, --dry-run Don't update the package's hash if it's a mismatch
|
||||
-a, --all Operate on all packages in this project.
|
||||
|
||||
Note that this procedure will usually take a long time
|
||||
depending on the number and size of dependencies.
|
||||
|
||||
EOF
|
||||
|
||||
exit $RETURN
|
||||
}
|
||||
|
||||
while :; do
|
||||
case "$1" in
|
||||
-[a-z]*)
|
||||
opt=$(printf '%s' "$1" | sed 's/^-//')
|
||||
while [ -n "$opt" ]; do
|
||||
# cut out first char from the optstring
|
||||
char=$(echo "$opt" | cut -c1)
|
||||
opt=$(echo "$opt" | cut -c2-)
|
||||
|
||||
case "$char" in
|
||||
a) ALL=1 ;;
|
||||
n) DRY=1 ;;
|
||||
h) usage ;;
|
||||
*) die "Invalid option -$char" ;;
|
||||
esac
|
||||
done
|
||||
;;
|
||||
--dry-run) DRY=1 ;;
|
||||
--all) ALL=1 ;;
|
||||
--help) usage ;;
|
||||
"$0") break ;;
|
||||
"") break ;;
|
||||
*) packages="$packages $1" ;;
|
||||
esac
|
||||
|
||||
shift
|
||||
done
|
||||
|
||||
[ "$ALL" = 1 ] && packages="${LIBS:-$packages}"
|
||||
[ "$DRY" = 1 ] && UPDATE=false || UPDATE=true
|
||||
[ -z "$packages" ] && usage
|
||||
|
||||
export UPDATE
|
||||
|
||||
for pkg in $packages; do
|
||||
echo "-- Package $pkg"
|
||||
"$SCRIPTS"/util/fix-hash.sh "$pkg" || RETURN=1
|
||||
done
|
||||
|
||||
exit $RETURN
|
||||
30
tools/cpm/package/rm.sh
Executable file
30
tools/cpm/package/rm.sh
Executable file
|
|
@ -0,0 +1,30 @@
|
|||
#!/bin/sh -e
|
||||
|
||||
# SPDX-FileCopyrightText: Copyright 2025 crueter
|
||||
# SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
|
||||
RETURN=0
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: cpmutil.sh package rm [PACKAGE]...
|
||||
|
||||
Delete a package or packages' cpmfile definition(s).
|
||||
|
||||
EOF
|
||||
|
||||
exit $RETURN
|
||||
}
|
||||
|
||||
[ $# -lt 1 ] && usage
|
||||
|
||||
for pkg in "$@"; do
|
||||
JSON=$("$SCRIPTS"/which.sh "$pkg") || {
|
||||
echo "!! No cpmfile definition for $pkg"
|
||||
continue
|
||||
}
|
||||
|
||||
jq --indent 4 "del(.\"$pkg\")" "$JSON" >"$JSON".tmp
|
||||
mv "$JSON".tmp "$JSON"
|
||||
echo "-- Removed $pkg from $JSON" || :
|
||||
done
|
||||
134
tools/cpm/package/update.sh
Executable file
134
tools/cpm/package/update.sh
Executable file
|
|
@ -0,0 +1,134 @@
|
|||
#!/bin/sh -e
|
||||
|
||||
# SPDX-FileCopyrightText: Copyright 2025 crueter
|
||||
# SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
|
||||
filter_out() {
|
||||
TAGS=$(echo "$TAGS" | jq "[.[] | select(.name | test(\"$1\"; \"i\") | not)]")
|
||||
}
|
||||
|
||||
filter_in() {
|
||||
TAGS=$(echo "$TAGS" | jq "[.[] | select(.name | test(\"$1\"; \"i\"))]")
|
||||
}
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: cpmutil.sh package update [-n|--dry-run] [-a|--all] [PACKAGE]...
|
||||
|
||||
Check a specific package or packages for updates.
|
||||
|
||||
Options:
|
||||
-n, --dry-run Do not update the package if it has an update available
|
||||
-a, --all Operate on all packages in this project.
|
||||
|
||||
EOF
|
||||
|
||||
exit 0
|
||||
}
|
||||
|
||||
while :; do
|
||||
case "$1" in
|
||||
-[a-z]*)
|
||||
opt=$(printf '%s' "$1" | sed 's/^-//')
|
||||
while [ -n "$opt" ]; do
|
||||
# cut out first char from the optstring
|
||||
char=$(echo "$opt" | cut -c1)
|
||||
opt=$(echo "$opt" | cut -c2-)
|
||||
|
||||
case "$char" in
|
||||
a) ALL=1 ;;
|
||||
n) DRY=1 ;;
|
||||
h) usage ;;
|
||||
*) die "Invalid option -$char" ;;
|
||||
esac
|
||||
done
|
||||
;;
|
||||
--dry-run) DRY=1 ;;
|
||||
--all) ALL=1 ;;
|
||||
--help) usage ;;
|
||||
"$0") break ;;
|
||||
"") break ;;
|
||||
*) packages="$packages $1" ;;
|
||||
esac
|
||||
|
||||
shift
|
||||
done
|
||||
|
||||
[ "$ALL" = 1 ] && packages="${LIBS:-$packages}"
|
||||
[ "$DRY" = 1 ] && UPDATE=false || UPDATE=true
|
||||
[ -z "$packages" ] && usage
|
||||
|
||||
for pkg in $packages; do
|
||||
PACKAGE="$pkg"
|
||||
export PACKAGE
|
||||
# shellcheck disable=SC1091
|
||||
. "$SCRIPTS"/vars.sh
|
||||
|
||||
SKIP=$(value "skip_updates")
|
||||
|
||||
[ "$SKIP" = "true" ] && continue
|
||||
|
||||
[ "$REPO" = null ] && continue
|
||||
[ "$GIT_HOST" != "github.com" ] && continue # TODO
|
||||
|
||||
[ "$CI" = "true" ] && continue
|
||||
|
||||
# shellcheck disable=SC2153
|
||||
[ "$TAG" = null ] && continue
|
||||
|
||||
echo "-- Package $PACKAGE"
|
||||
|
||||
# TODO(crueter): Support for Forgejo updates w/ forgejo_token
|
||||
# Use gh-cli to avoid ratelimits lmao
|
||||
TAGS=$(gh api --method GET "/repos/$REPO/tags")
|
||||
|
||||
# filter out some commonly known annoyances
|
||||
# TODO add more
|
||||
|
||||
if [ "$PACKAGE" = "vulkan-validation-layers" ]; then
|
||||
filter_in vulkan-sdk
|
||||
else
|
||||
filter_out vulkan-sdk
|
||||
fi
|
||||
|
||||
filter_out yotta # mbedtls
|
||||
|
||||
# ignore betas/alphas (remove if needed)
|
||||
filter_out alpha
|
||||
filter_out beta
|
||||
filter_out rc
|
||||
|
||||
# Add package-specific overrides here, e.g. here for fmt:
|
||||
[ "$PACKAGE" = fmt ] && filter_out v0.11
|
||||
|
||||
LATEST=$(echo "$TAGS" | jq -r '.[0].name')
|
||||
|
||||
[ "$LATEST" = "null" ] && echo "-- * Up-to-date" && continue
|
||||
[ "$LATEST" = "$TAG" ] && [ "$FORCE" != "true" ] && echo "-- * Up-to-date" && continue
|
||||
|
||||
if [ "$HAS_REPLACE" = "true" ]; then
|
||||
# this just extracts the tag prefix
|
||||
VERSION_PREFIX=$(echo "$ORIGINAL_TAG" | cut -d"%" -f1)
|
||||
|
||||
# then we strip out the prefix from the new tag, and make that our new git_version
|
||||
if [ -z "$VERSION_PREFIX" ]; then
|
||||
NEW_GIT_VERSION="$LATEST"
|
||||
else
|
||||
NEW_GIT_VERSION=$(echo "$LATEST" | sed "s/$VERSION_PREFIX//g")
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "-- * Version $LATEST available, current is $TAG"
|
||||
|
||||
if [ "$UPDATE" = "true" ]; then
|
||||
if [ "$HAS_REPLACE" = "true" ]; then
|
||||
NEW_JSON=$(echo "$JSON" | jq ".git_version = \"$NEW_GIT_VERSION\"")
|
||||
else
|
||||
NEW_JSON=$(echo "$JSON" | jq ".tag = \"$LATEST\"")
|
||||
fi
|
||||
|
||||
"$SCRIPTS"/util/replace.sh "$PACKAGE" "$NEW_JSON"
|
||||
|
||||
QUIET=true "$SCRIPTS"/util/fix-hash.sh
|
||||
fi
|
||||
done
|
||||
30
tools/cpm/package/util/fix-hash.sh
Executable file
30
tools/cpm/package/util/fix-hash.sh
Executable file
|
|
@ -0,0 +1,30 @@
|
|||
#!/bin/sh -e
|
||||
|
||||
# SPDX-FileCopyrightText: Copyright 2025 crueter
|
||||
# SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
|
||||
: "${PACKAGE:=$1}"
|
||||
|
||||
# shellcheck disable=SC1091
|
||||
. "$SCRIPTS"/vars.sh
|
||||
|
||||
[ "$CI" = null ] || exit 0
|
||||
|
||||
[ "$HASH_URL" = null ] || exit 0
|
||||
[ "$HASH_SUFFIX" = null ] || exit 0
|
||||
|
||||
[ "$HASH" = null ] && echo "-- * Package has no hash specified" && exit 0
|
||||
|
||||
ACTUAL=$("$SCRIPTS"/util/url-hash.sh "$DOWNLOAD")
|
||||
|
||||
if [ "$ACTUAL" != "$HASH" ] && [ "$QUIET" != true ]; then
|
||||
echo "-- * Expected $HASH"
|
||||
echo "-- * Got $ACTUAL"
|
||||
[ "$UPDATE" != "true" ] && exit 1
|
||||
fi
|
||||
|
||||
if [ "$UPDATE" = "true" ] && [ "$ACTUAL" != "$HASH" ]; then
|
||||
NEW_JSON=$(echo "$JSON" | jq ".hash = \"$ACTUAL\"")
|
||||
|
||||
"$SCRIPTS"/util/replace.sh "$PACKAGE" "$NEW_JSON"
|
||||
fi
|
||||
217
tools/cpm/package/util/interactive.sh
Executable file
217
tools/cpm/package/util/interactive.sh
Executable file
|
|
@ -0,0 +1,217 @@
|
|||
#!/bin/sh -e
|
||||
|
||||
# SPDX-FileCopyrightText: Copyright 2025 crueter
|
||||
# SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
|
||||
# This reads a single-line input from the user and also gives them
|
||||
# help if needed.
|
||||
# $1: The prompt itself, without any trailing spaces or whatever
|
||||
# $2: The help text that gets shown when the user types a question mark
|
||||
# $3: This is set to "required" if it's necessary,
|
||||
# otherwise it can continue without input.
|
||||
# Stores its output in the "reply" variable
|
||||
read_single() {
|
||||
while :; do
|
||||
printf -- "-- %s" "$1"
|
||||
[ -n "$2" ] && printf " (? for help, %s)" "$3"
|
||||
printf ": "
|
||||
if ! IFS= read -r reply; then
|
||||
echo
|
||||
[ "$3" = "required" ] && continue || reply=""
|
||||
fi
|
||||
case "$reply" in
|
||||
"?") echo "$2" ;;
|
||||
"") [ "$3" = "required" ] && continue || return 0 ;;
|
||||
*) return 0 ;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
# read_single, but optional
|
||||
optional() {
|
||||
read_single "$1" "$2" "optional"
|
||||
}
|
||||
|
||||
# a
|
||||
required() {
|
||||
read_single "$1" "$2" "required"
|
||||
}
|
||||
|
||||
# Basically the same as the single line function except multiline,
|
||||
# also it's never "required" so we don't need that handling.
|
||||
multi() {
|
||||
echo "-- $1"
|
||||
if [ -n "$2" ]; then
|
||||
echo "-- (? on first line for help, Ctrl-D to finish)"
|
||||
else
|
||||
echo "-- (Ctrl-D to finish)"
|
||||
fi
|
||||
while :; do
|
||||
reply=$(cat)
|
||||
if [ "$(echo "$reply" | head -n 1)" = "?" ] && [ -n "$2" ]; then
|
||||
echo "$2"
|
||||
continue
|
||||
fi
|
||||
|
||||
# removes trailing EOF and empty lines
|
||||
reply=$(printf '%s\n' "$reply" |
|
||||
sed 's/\x04$//' |
|
||||
sed '/^[[:space:]]*$/d')
|
||||
|
||||
break
|
||||
done
|
||||
}
|
||||
|
||||
# the actual inputs :)
|
||||
|
||||
required "Package repository (owner/repo)" \
|
||||
"The remote repository this is stored on.
|
||||
You shouldn't include the host, just owner/repo is enough."
|
||||
|
||||
REPO="$reply"
|
||||
|
||||
optional "Package name for find_package" \
|
||||
"When searching for system packages, this argument will be passed to find_package.
|
||||
For example, using \"Boost\" here will result in CPMUtil internally calling find_package(Boost)."
|
||||
|
||||
PACKAGE="$reply"
|
||||
|
||||
optional "Minimum required version" \
|
||||
"The minimum required version for this package if it's pulled in by the system."
|
||||
|
||||
MIN_VERSION="$reply"
|
||||
|
||||
optional "Additional find_package arguments, space-separated" \
|
||||
"Extra arguments passed to find_package(), (e.g. CONFIG)"
|
||||
|
||||
FIND_ARGS="$reply"
|
||||
|
||||
optional "Is this a CI package? [y/N]" \
|
||||
"Yes if the package is a prebuilt binary distribution (e.g. crueter-ci),
|
||||
no if the package is built from source if it's bundled."
|
||||
|
||||
case "$reply" in
|
||||
[Yy]*) CI=true ;;
|
||||
*) CI=false ;;
|
||||
esac
|
||||
|
||||
if [ "$CI" = "false" ]; then
|
||||
optional "Git host (default: github.com)" \
|
||||
"The hostname of the Git server, if not GitHub (e.g. codeberg.org, git.crueter.xyz)"
|
||||
|
||||
GIT_HOST="$reply"
|
||||
|
||||
if [ "$TAG" = "1" ]; then
|
||||
required "Numeric version of the bundled package" \
|
||||
"The semantic version of the bundled package. This is only used for package identification,
|
||||
and if you use tag/artifact fetching. Do not input the entire tag here; for example, if you're using
|
||||
tag v1.3.0, then set this to 1.3.0 and set the tag to v%VERSION%."
|
||||
|
||||
GIT_VERSION="$reply"
|
||||
|
||||
optional "Name of the upstream tag. %VERSION% is replaced by the numeric version (default: %VERSION%)" \
|
||||
"Most commonly this will be something like v%VERSION% or release-%VERSION%, or just %VERSION%."
|
||||
|
||||
TAGNAME="$reply"
|
||||
[ -z "$TAGNAME" ] && TAGNAME="%VERSION%"
|
||||
|
||||
optional "Name of the release artifact to download, if applicable.
|
||||
-- %VERSION% is replaced by the numeric version and %TAG% is replaced by the tag name" \
|
||||
"Download the specified artifact from the release with the previously specified tag.
|
||||
If unspecified, the source code at the specified tag will be used instead."
|
||||
|
||||
ARTIFACT="$reply"
|
||||
else
|
||||
required "Commit sha" \
|
||||
"The short Git commit sha to use. You're recommended to keep this short, e.g. 10 characters."
|
||||
|
||||
SHA="$reply"
|
||||
fi
|
||||
|
||||
multi "Fixed options, one per line (e.g. OPUS_BUILD_TESTING OFF)" \
|
||||
"Fixed options passed to the project's CMakeLists.txt. Variadic options
|
||||
should be set in CMake with AddJsonPackage's OPTIONS parameter."
|
||||
|
||||
OPTIONS="$reply"
|
||||
else
|
||||
required "Version of the CI package (e.g. 3.6.0-9eff87adb1)" \
|
||||
"CI artifacts are stored as <name>-<platform>-<version>.tar.zst. This option controls the version."
|
||||
|
||||
VERSION="$reply"
|
||||
|
||||
required "Name of the CI artifact" \
|
||||
"CI artifacts are stored as <name>-<platform>-<version>.tar.zst. This option controls the name."
|
||||
|
||||
ARTIFACT="$reply"
|
||||
|
||||
multi "Platforms without a package (one per line)" \
|
||||
"Valid platforms:
|
||||
windows-amd64 windows-arm64
|
||||
mingw-amd64 mingw-arm64
|
||||
android-aarch64 android-x86_64
|
||||
solaris-amd64 freebsd-amd64 openbsd-amd64
|
||||
linux-amd64 linux-aarch64
|
||||
macos-universal"
|
||||
|
||||
DISABLED_PLATFORMS="$reply"
|
||||
fi
|
||||
|
||||
# now time to construct the actual json
|
||||
jq_input='{repo: "'"$REPO"'"}'
|
||||
|
||||
# common trivial fields
|
||||
[ -n "$PACKAGE" ] && jq_input="$jq_input + {package: \"$PACKAGE\"}"
|
||||
[ -n "$MIN_VERSION" ] && jq_input="$jq_input + {min_version: \"$MIN_VERSION\"}"
|
||||
[ -n "$FIND_ARGS" ] && jq_input="$jq_input + {find_args: \"$FIND_ARGS\"}"
|
||||
|
||||
if [ "$CI" = "true" ]; then
|
||||
jq_input="$jq_input + {
|
||||
ci: true,
|
||||
version: \"$VERSION\",
|
||||
artifact: \"$ARTIFACT\"
|
||||
}"
|
||||
|
||||
# disabled platforms
|
||||
if [ -n "$DISABLED_PLATFORMS" ] && [ -n "$(printf '%s' "$DISABLED_PLATFORMS" | tr -d ' \t\n\r')" ]; then
|
||||
disabled_json=$(printf '%s\n' "$DISABLED_PLATFORMS" | jq -R . | jq -s .)
|
||||
jq_input="$jq_input + {disabled_platforms: $disabled_json}"
|
||||
fi
|
||||
else
|
||||
[ -n "$MIN_VERSION" ] && jq_input="$jq_input + {version: \"$MIN_VERSION\"}"
|
||||
jq_input="$jq_input + {hash: \"\"}"
|
||||
|
||||
# options
|
||||
if [ -n "$OPTIONS" ] && [ -n "$(printf '%s' "$OPTIONS" | tr -d ' \t\n\r')" ]; then
|
||||
options_json=$(printf '%s\n' "$OPTIONS" | jq -R . | jq -s .)
|
||||
jq_input="$jq_input + {options: $options_json}"
|
||||
fi
|
||||
|
||||
# Git host
|
||||
if [ -n "$GIT_HOST" ] && [ "$GIT_HOST" != "github.com" ]; then
|
||||
jq_input="$jq_input + {git_host: \"$GIT_HOST\"}"
|
||||
fi
|
||||
|
||||
# versioning stuff
|
||||
if [ -n "$GIT_VERSION" ]; then
|
||||
jq_input="$jq_input + {git_version: \"$GIT_VERSION\"}"
|
||||
[ -n "$TAGNAME" ] && jq_input="$jq_input + {tag: \"$TAGNAME\"}"
|
||||
[ -n "$ARTIFACT" ] && jq_input="$jq_input + {artifact: \"$ARTIFACT\"}"
|
||||
else
|
||||
jq_input="$jq_input + {sha: \"$SHA\"}"
|
||||
fi
|
||||
fi
|
||||
|
||||
new_json=$(jq -n "$jq_input")
|
||||
|
||||
jq --arg key "$PKG" --argjson new "$new_json" \
|
||||
'.[$key] = $new' "$CPMFILE" --indent 4 >"${CPMFILE}.tmp" &&
|
||||
mv "${CPMFILE}.tmp" "$CPMFILE"
|
||||
|
||||
# now correct the hash
|
||||
if [ "$CI" != true ]; then
|
||||
# shellcheck disable=SC1091
|
||||
. "$ROOTDIR"/common.sh
|
||||
QUIET=true UPDATE=true "$SCRIPTS"/util/fix-hash.sh "$PKG"
|
||||
fi
|
||||
|
||||
echo "Added package $PKG to $CPMFILE. Include it in your project with AddJsonPackage($PKG)"
|
||||
13
tools/cpm/package/util/replace.sh
Executable file
13
tools/cpm/package/util/replace.sh
Executable file
|
|
@ -0,0 +1,13 @@
|
|||
#!/bin/sh -e
|
||||
|
||||
# SPDX-FileCopyrightText: Copyright 2025 crueter
|
||||
# SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
|
||||
# Replace a specified package with a modified json.
|
||||
|
||||
FILE=$(echo "$CPMFILES" | xargs grep -l "\"$1\"")
|
||||
|
||||
jq --indent 4 --argjson repl "$2" ".\"$1\" *= \$repl" "$FILE" >"$FILE".new
|
||||
mv "$FILE".new "$FILE"
|
||||
|
||||
echo "-- * -- Updated $FILE"
|
||||
7
tools/cpm/package/util/url-hash.sh
Executable file
7
tools/cpm/package/util/url-hash.sh
Executable file
|
|
@ -0,0 +1,7 @@
|
|||
#!/bin/sh
|
||||
|
||||
# SPDX-FileCopyrightText: Copyright 2025 crueter
|
||||
# SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
|
||||
SUM=$(curl -Ls "$1" -o - | sha512sum)
|
||||
echo "$SUM" | cut -d " " -f1
|
||||
170
tools/cpm/package/vars.sh
Executable file
170
tools/cpm/package/vars.sh
Executable file
|
|
@ -0,0 +1,170 @@
|
|||
#!/bin/sh -e
|
||||
|
||||
# SPDX-FileCopyrightText: Copyright 2025 crueter
|
||||
# SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
|
||||
# shellcheck disable=SC1091
|
||||
|
||||
value() {
|
||||
echo "$JSON" | jq -r ".$1"
|
||||
}
|
||||
|
||||
[ -z "$PACKAGE" ] && echo "Package was not specified" && exit 0
|
||||
|
||||
# shellcheck disable=SC2153
|
||||
JSON=$(echo "$PACKAGES" | jq -r ".\"$PACKAGE\" | select( . != null )")
|
||||
|
||||
[ -z "$JSON" ] && echo "!! No cpmfile definition for $PACKAGE" >&2 && exit 1
|
||||
|
||||
# unset stuff
|
||||
export PACKAGE_NAME="null"
|
||||
export REPO="null"
|
||||
export CI="null"
|
||||
export GIT_HOST="null"
|
||||
export EXT="null"
|
||||
export NAME="null"
|
||||
export DISABLED="null"
|
||||
export TAG="null"
|
||||
export ARTIFACT="null"
|
||||
export SHA="null"
|
||||
export VERSION="null"
|
||||
export GIT_VERSION="null"
|
||||
export DOWNLOAD="null"
|
||||
export URL="null"
|
||||
export KEY="null"
|
||||
export HASH="null"
|
||||
export ORIGINAL_TAG="null"
|
||||
export HAS_REPLACE="null"
|
||||
export VERSION_REPLACE="null"
|
||||
export HASH_URL="null"
|
||||
export HASH_SUFFIX="null"
|
||||
export HASH_ALGO="null"
|
||||
|
||||
########
|
||||
# Meta #
|
||||
########
|
||||
|
||||
REPO=$(value "repo")
|
||||
CI=$(value "ci")
|
||||
|
||||
PACKAGE_NAME=$(value "package")
|
||||
[ "$PACKAGE_NAME" = null ] && PACKAGE_NAME="$PACKAGE"
|
||||
|
||||
GIT_HOST=$(value "git_host")
|
||||
[ "$GIT_HOST" = null ] && GIT_HOST=github.com
|
||||
|
||||
export PACKAGE_NAME
|
||||
export REPO
|
||||
export CI
|
||||
export GIT_HOST
|
||||
|
||||
######################
|
||||
# CI Package Parsing #
|
||||
######################
|
||||
|
||||
VERSION=$(value "version")
|
||||
|
||||
if [ "$CI" = "true" ]; then
|
||||
EXT=$(value "extension")
|
||||
[ "$EXT" = null ] && EXT="tar.zst"
|
||||
|
||||
NAME=$(value "name")
|
||||
DISABLED=$(echo "$JSON" | jq -j '.disabled_platforms')
|
||||
|
||||
[ "$NAME" = null ] && NAME="$PACKAGE_NAME"
|
||||
|
||||
export EXT
|
||||
export NAME
|
||||
export DISABLED
|
||||
export VERSION
|
||||
|
||||
return 0
|
||||
fi
|
||||
|
||||
##############
|
||||
# Versioning #
|
||||
##############
|
||||
|
||||
TAG=$(value "tag")
|
||||
ARTIFACT=$(value "artifact")
|
||||
SHA=$(value "sha")
|
||||
GIT_VERSION=$(value "git_version")
|
||||
|
||||
[ "$GIT_VERSION" = null ] && GIT_VERSION="$VERSION"
|
||||
|
||||
if [ "$GIT_VERSION" != null ]; then
|
||||
VERSION_REPLACE="$GIT_VERSION"
|
||||
else
|
||||
VERSION_REPLACE="$VERSION"
|
||||
fi
|
||||
|
||||
echo "$TAG" | grep -e "%VERSION%" >/dev/null &&
|
||||
HAS_REPLACE=true || HAS_REPLACE=false
|
||||
|
||||
ORIGINAL_TAG="$TAG"
|
||||
|
||||
TAG=$(echo "$TAG" | sed "s/%VERSION%/$VERSION_REPLACE/g")
|
||||
ARTIFACT=$(echo "$ARTIFACT" | sed "s/%VERSION%/$VERSION_REPLACE/g")
|
||||
ARTIFACT=$(echo "$ARTIFACT" | sed "s/%TAG%/$TAG/g")
|
||||
|
||||
export TAG
|
||||
export ARTIFACT
|
||||
export SHA
|
||||
export VERSION
|
||||
export GIT_VERSION
|
||||
export ORIGINAL_TAG
|
||||
export HAS_REPLACE
|
||||
export VERSION_REPLACE
|
||||
|
||||
###############
|
||||
# URL Parsing #
|
||||
###############
|
||||
|
||||
URL=$(value "url")
|
||||
BRANCH=$(value "branch")
|
||||
|
||||
export BRANCH
|
||||
export URL
|
||||
|
||||
. "$SCRIPTS"/vars/url.sh
|
||||
|
||||
export DOWNLOAD
|
||||
|
||||
###############
|
||||
# Key Parsing #
|
||||
###############
|
||||
|
||||
KEY=$(value "key")
|
||||
|
||||
. "$SCRIPTS"/vars/key.sh
|
||||
|
||||
export KEY
|
||||
|
||||
################
|
||||
# Hash Parsing #
|
||||
################
|
||||
|
||||
HASH_ALGO=$(value "hash_algo")
|
||||
[ "$HASH_ALGO" = null ] && HASH_ALGO=sha512
|
||||
|
||||
HASH=$(value "hash")
|
||||
|
||||
if [ "$HASH" = null ]; then
|
||||
HASH_SUFFIX="${HASH_ALGO}sum"
|
||||
HASH_URL=$(value "hash_url")
|
||||
|
||||
if [ "$HASH_URL" = null ]; then
|
||||
HASH_URL="${DOWNLOAD}.${HASH_SUFFIX}"
|
||||
fi
|
||||
|
||||
HASH=$(curl "$HASH_URL" -Ss -L -o -)
|
||||
else
|
||||
HASH_URL=null
|
||||
HASH_SUFFIX=null
|
||||
fi
|
||||
|
||||
export HASH_URL
|
||||
export HASH_SUFFIX
|
||||
export HASH
|
||||
export HASH_ALGO
|
||||
export JSON
|
||||
21
tools/cpm/package/vars/key.sh
Executable file
21
tools/cpm/package/vars/key.sh
Executable file
|
|
@ -0,0 +1,21 @@
|
|||
#!/bin/sh -e
|
||||
|
||||
# SPDX-FileCopyrightText: Copyright 2025 crueter
|
||||
# SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
|
||||
if [ "$KEY" = null ]; then
|
||||
if [ "$SHA" != null ]; then
|
||||
KEY=$(echo "$SHA" | cut -c1-4)
|
||||
elif [ "$GIT_VERSION" != null ]; then
|
||||
KEY="$GIT_VERSION"
|
||||
elif [ "$TAG" != null ]; then
|
||||
KEY="$TAG"
|
||||
elif [ "$VERSION" != null ]; then
|
||||
KEY="$VERSION"
|
||||
else
|
||||
echo "!! No valid key could be determined for $PACKAGE_NAME. Must define one of: key, sha, tag, version, git_version"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
export KEY
|
||||
32
tools/cpm/package/vars/url.sh
Executable file
32
tools/cpm/package/vars/url.sh
Executable file
|
|
@ -0,0 +1,32 @@
|
|||
#!/bin/sh
|
||||
|
||||
# SPDX-FileCopyrightText: Copyright 2025 crueter
|
||||
# SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
|
||||
# Required vars: URL, GIT_HOST, REPO, TAG, ARTIFACT, BRANCH, SHA
|
||||
if [ "$URL" != "null" ]; then
|
||||
DOWNLOAD="$URL"
|
||||
elif [ "$REPO" != "null" ]; then
|
||||
GIT_URL="https://$GIT_HOST/$REPO"
|
||||
|
||||
if [ "$TAG" != "null" ]; then
|
||||
if [ "$ARTIFACT" != "null" ]; then
|
||||
DOWNLOAD="${GIT_URL}/releases/download/${TAG}/${ARTIFACT}"
|
||||
else
|
||||
DOWNLOAD="${GIT_URL}/archive/refs/tags/${TAG}.tar.gz"
|
||||
fi
|
||||
elif [ "$SHA" != "null" ]; then
|
||||
DOWNLOAD="${GIT_URL}/archive/${SHA}.tar.gz"
|
||||
else
|
||||
if [ "$BRANCH" = null ]; then
|
||||
BRANCH=master
|
||||
fi
|
||||
|
||||
DOWNLOAD="${GIT_URL}/archive/refs/heads/${BRANCH}.tar.gz"
|
||||
fi
|
||||
else
|
||||
echo "!! No repo or URL defined for $PACKAGE_NAME"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
export DOWNLOAD
|
||||
60
tools/cpm/package/version.sh
Executable file
60
tools/cpm/package/version.sh
Executable file
|
|
@ -0,0 +1,60 @@
|
|||
#!/bin/sh -e
|
||||
|
||||
# SPDX-FileCopyrightText: Copyright 2025 crueter
|
||||
# SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
|
||||
# shellcheck disable=SC1091
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: cpmutil.sh package version [PACKAGE] [VERSION]
|
||||
|
||||
Update a package's version. If the package uses a sha, you must provide a sha,
|
||||
and if the package uses a tag, you must provide the fully qualified tag.
|
||||
|
||||
EOF
|
||||
|
||||
exit 0
|
||||
}
|
||||
|
||||
PACKAGE="$1"
|
||||
NEW_VERSION="$2"
|
||||
|
||||
[ -z "$PACKAGE" ] && usage
|
||||
[ -z "$NEW_VERSION" ] && usage
|
||||
|
||||
export PACKAGE
|
||||
|
||||
. "$SCRIPTS"/vars.sh
|
||||
|
||||
[ "$REPO" = null ] && exit 0
|
||||
|
||||
if [ "$HAS_REPLACE" = "true" ]; then
|
||||
# this just extracts the tag prefix
|
||||
VERSION_PREFIX=$(echo "$ORIGINAL_TAG" | cut -d"%" -f1)
|
||||
|
||||
# then we strip out the prefix from the new tag, and make that our new git_version
|
||||
if [ -z "$VERSION_PREFIX" ]; then
|
||||
NEW_GIT_VERSION="$NEW_VERSION"
|
||||
else
|
||||
NEW_GIT_VERSION=$(echo "$NEW_VERSION" | sed "s/$VERSION_PREFIX//g")
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$SHA" != null ]; then
|
||||
NEW_JSON=$(echo "$JSON" | jq ".sha = \"$NEW_VERSION\"")
|
||||
elif [ "$CI" = "true" ]; then
|
||||
NEW_JSON=$(echo "$JSON" | jq ".version = \"$NEW_VERSION\"")
|
||||
elif [ "$HAS_REPLACE" = "true" ]; then
|
||||
NEW_JSON=$(echo "$JSON" | jq ".git_version = \"$NEW_GIT_VERSION\"")
|
||||
else
|
||||
NEW_JSON=$(echo "$JSON" | jq ".tag = \"$NEW_VERSION\"")
|
||||
fi
|
||||
|
||||
echo "-- * -- Updating $PACKAGE to version $NEW_VERSION"
|
||||
"$SCRIPTS"/util/replace.sh "$PACKAGE" "$NEW_JSON"
|
||||
|
||||
[ "$CI" = "true" ] && exit 0
|
||||
echo "-- * -- Fixing hash"
|
||||
. "$ROOTDIR"/common.sh
|
||||
UPDATE=true QUIET=true "$SCRIPTS"/util/fix-hash.sh
|
||||
12
tools/cpm/package/which.sh
Executable file
12
tools/cpm/package/which.sh
Executable file
|
|
@ -0,0 +1,12 @@
|
|||
#!/bin/sh -e
|
||||
|
||||
# SPDX-FileCopyrightText: Copyright 2025 crueter
|
||||
# SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
|
||||
# check which file a package is in
|
||||
|
||||
JSON=$(echo "$CPMFILES" | xargs grep -l "\"$1\"")
|
||||
|
||||
[ -z "$JSON" ] && echo "!! No cpmfile definition for $1" >&2 && exit 1
|
||||
|
||||
echo "$JSON"
|
||||
Loading…
Add table
Add a link
Reference in a new issue