#!/bin/sh -e # SPDX-FileCopyrightText: Copyright 2026 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" [ -z "$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 "Git host (default: github.com)" \ "The hostname of the Git server, if not GitHub (e.g. codeberg.org, git.crueter.xyz)" GIT_HOST="$reply" 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%." VERSION="$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 while :; do required "Use tag or commit sha versioning? [tag/sha]" \ "Tag versioning is compatible with auto-updating. Use sha versioning for projects with improper tagging practices" if [ "$reply" = "tag" ]; then TAG=1 break elif [ "$reply" = "sha" ]; then SHA=1 break else echo "-- Invalid choice $reply" fi done if [ "$TAG" = "1" ]; then optional "Name of the upstream tag. %VERSION% is replaced by the numeric version ($VERSION) (default: %VERSION%)" \ "Most commonly this will be something like v%VERSION% or release-%VERSION%, or just %VERSION%." TAGNAME="$reply" [ -n "$TAGNAME" ] || TAGNAME="%VERSION%" optional "Name of the release artifact to download, if applicable. -- %VERSION% is replaced by the numeric version ($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 "Name of the CI artifact" \ "CI artifacts are stored as --.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 linux-amd64 linux-aarch64 macos-universal ios-aarch64" DISABLED_PLATFORMS="$reply" fi # now time to construct the actual json jq_input='{repo: "'"$REPO"'"}' # common trivial fields [ -z "$PACKAGE" ] || jq_input="$jq_input + {package: \"$PACKAGE\"}" [ -z "$MIN_VERSION" ] || jq_input="$jq_input + {min_version: \"$MIN_VERSION\"}" [ -z "$FIND_ARGS" ] || jq_input="$jq_input + {find_args: \"$FIND_ARGS\"}" jq_input="$jq_input + {version: \"$VERSION\"}" if [ -n "$GIT_HOST" ] && [ "$GIT_HOST" != "github.com" ]; then jq_input="$jq_input + {git_host: \"$GIT_HOST\"}" fi if [ "$CI" = "true" ]; then jq_input="$jq_input + { ci: true, 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 [ -z "$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 # versioning stuff if [ "$TAG" = 1 ]; then jq_input="$jq_input + {tag: \"$TAGNAME\"}" [ -z "$ARTIFACT" ] || jq_input="$jq_input + {artifact: \"$ARTIFACT\"}" else jq_input="$jq_input + {sha: \"$SHA\"}" fi fi JSON=$(jq -n "$jq_input") # shellcheck disable=SC1091 . "$SCRIPTS"/vars.sh if [ "$CI" != true ]; then HASH=$("$SCRIPTS"/util/url-hash.sh "$DOWNLOAD") JSON=$(echo "$JSON" | jq ".hash = \"$HASH\"") fi jq --arg key "$PKG" --argjson new "$JSON" \ '.[$key] = $new' "cpmfile.json" --indent 4 >"cpmfile.json.tmp" && mv "cpmfile.json.tmp" cpmfile.json "$SCRIPTS"/format.sh echo "Added package $PKG to cpmfile.json. Include it in your project with AddJsonPackage($PKG)"