SwiftPM has currently a bug, that products or targets of dependencies are taken into consideration when resolving names, regardless if they're used or not by the root package. This stops Swift PM from working on packages, that declare this package as a dependency and define their own TaskCLI target, as they collide with the definitions of this package. This is resolved, by prefixing TaskCLI with the package name. The product collision - which causes swift run - to run this package's task executable is resolved, by adding that product only temporarily during task execution using task.sh. See https://github.com/swiftlang/swift-package-manager/issues/8482
59 lines
1.8 KiB
Bash
Executable File
59 lines
1.8 KiB
Bash
Executable File
#!/usr/bin/env zsh
|
|
|
|
# task - Run the package's TaskCLI target via a transient "task" product.
|
|
#
|
|
# Works around https://github.com/swiftlang/swift-package-manager/issues/8482
|
|
# by temporarily adding an executable product named "task" to Package.swift,
|
|
# running it with `swift run`, and restoring the original manifest afterwards.
|
|
#
|
|
# Usage: task [arguments...]
|
|
#
|
|
# The script auto-detects the package name from Package.swift and expects an
|
|
# executable target named "<PackageName>TaskCLI" to exist.
|
|
|
|
set -euo pipefail
|
|
|
|
# --- Resolve the package root (search upward for Package.swift) -----------
|
|
|
|
package_root="${PWD}"
|
|
while [[ ! -f "${package_root}/Package.swift" ]]; do
|
|
package_root="${package_root:h}" # zsh dirname
|
|
if [[ "${package_root}" == "/" ]]; then
|
|
echo "error: Could not find Package.swift in any parent directory." >&2
|
|
exit 1
|
|
fi
|
|
done
|
|
|
|
manifest="${package_root}/Package.swift"
|
|
backup="${manifest}.task-backup"
|
|
|
|
# --- Extract the package name ---------------------------------------------
|
|
|
|
package_name=$(sed -n 's/^.*name:[[:space:]]*"\([^"]*\)".*/\1/p' "${manifest}" | head -1)
|
|
if [[ -z "${package_name}" ]]; then
|
|
echo "error: Could not determine package name from ${manifest}." >&2
|
|
exit 1
|
|
fi
|
|
|
|
target_name="${package_name}TaskCLI"
|
|
|
|
# --- Cleanup trap (runs on EXIT — covers success, failure, signals) -------
|
|
|
|
function cleanup {
|
|
if [[ -f "${backup}" ]]; then
|
|
mv -f "${backup}" "${manifest}"
|
|
fi
|
|
}
|
|
trap cleanup EXIT
|
|
|
|
# --- Inject the transient "task" product ----------------------------------
|
|
|
|
cp -f "${manifest}" "${backup}"
|
|
|
|
swift package --package-path "${package_root}" \
|
|
add-product task --type executable --targets "${target_name}"
|
|
|
|
# --- Run it (forward all script arguments) --------------------------------
|
|
|
|
swift run --package-path "${package_root}" task "$@"
|