Temporary fix of SwiftPM Bug using task.sh
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
This commit is contained in:
@@ -8,10 +8,6 @@ let package = Package(
|
|||||||
.library(
|
.library(
|
||||||
name: "Inotify",
|
name: "Inotify",
|
||||||
targets: ["Inotify"]
|
targets: ["Inotify"]
|
||||||
),
|
|
||||||
.executable(
|
|
||||||
name: "task",
|
|
||||||
targets: ["TaskCLI"]
|
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
dependencies: [
|
dependencies: [
|
||||||
@@ -42,7 +38,7 @@ let package = Package(
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
.executableTarget(
|
.executableTarget(
|
||||||
name: "TaskCLI",
|
name: "InotifyTaskCLI",
|
||||||
dependencies: [
|
dependencies: [
|
||||||
.product(name: "ArgumentParser", package: "swift-argument-parser"),
|
.product(name: "ArgumentParser", package: "swift-argument-parser"),
|
||||||
.product(name: "AsyncAlgorithms", package: "swift-async-algorithms"),
|
.product(name: "AsyncAlgorithms", package: "swift-async-algorithms"),
|
||||||
@@ -50,7 +46,8 @@ let package = Package(
|
|||||||
.product(name: "_NIOFileSystem", package: "swift-nio"),
|
.product(name: "_NIOFileSystem", package: "swift-nio"),
|
||||||
.product(name: "Subprocess", package: "swift-subprocess"),
|
.product(name: "Subprocess", package: "swift-subprocess"),
|
||||||
.product(name: "Noora", package: "Noora")
|
.product(name: "Noora", package: "Noora")
|
||||||
]
|
],
|
||||||
|
path: "Sources/TaskCLI"
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -132,11 +132,14 @@ try inotify.removeWatch(wd)
|
|||||||
## Build Tool
|
## Build Tool
|
||||||
|
|
||||||
The package ships with a `task` executable (the `TaskCLI` target) that serves as the project's build tool. It automates running tests and generating documentation inside Linux Docker containers, so you can validate everything on the correct platform even when developing on macOS.
|
The package ships with a `task` executable (the `TaskCLI` target) that serves as the project's build tool. It automates running tests and generating documentation inside Linux Docker containers, so you can validate everything on the correct platform even when developing on macOS.
|
||||||
|
Because of a Swift Package Manager Bug in the [package dependency resolution][swiftpm-bug], the executable needs to be run using the `task.sh` shell script.
|
||||||
|
|
||||||
|
[swiftpm-bug]: https://github.com/swiftlang/swift-package-manager/issues/8482
|
||||||
|
|
||||||
### Tests
|
### Tests
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
swift run task test
|
./task.sh test
|
||||||
```
|
```
|
||||||
|
|
||||||
Use `-v`, `-vv`, or `-vvv` to increase log verbosity. The command runs two passes: first all tests except `InotifyLimitTests`, then only `InotifyLimitTests` (which manipulate system-level inotify limits and need to run in isolation).
|
Use `-v`, `-vv`, or `-vvv` to increase log verbosity. The command runs two passes: first all tests except `InotifyLimitTests`, then only `InotifyLimitTests` (which manipulate system-level inotify limits and need to run in isolation).
|
||||||
@@ -148,7 +151,7 @@ Docker must be installed and running on your machine.
|
|||||||
Full API documentation is available as DocC catalogs bundled with the package. Generate them locally with:
|
Full API documentation is available as DocC catalogs bundled with the package. Generate them locally with:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
swift run task generate-docs
|
./task.sh generate-docs
|
||||||
```
|
```
|
||||||
|
|
||||||
Then open the files in the newly created `public` folder.
|
Then open the files in the newly created `public` folder.
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
# ``TaskCLI``
|
# ``TaskCLI``
|
||||||
|
|
||||||
The build tool for the Swift Inotify project.
|
The build tool for the Swift Inotify project.
|
||||||
|
Because of a Swift Package Manager Bug in the [package dependency resolution][swiftpm-bug], the executable needs to be run using the `task.sh` shell script.
|
||||||
|
|
||||||
|
[swiftpm-bug]: https://github.com/swiftlang/swift-package-manager/issues/8482
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
@@ -9,7 +12,7 @@ The build tool for the Swift Inotify project.
|
|||||||
### Running the Tests
|
### Running the Tests
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
swift run task test
|
./task.sh test
|
||||||
```
|
```
|
||||||
|
|
||||||
This launches a `swift:latest` Docker container with the repository mounted at `/code`, then executes two test passes:
|
This launches a `swift:latest` Docker container with the repository mounted at `/code`, then executes two test passes:
|
||||||
@@ -22,7 +25,7 @@ The container is started with `--security-opt systempaths=unconfined` so that th
|
|||||||
### Generating Documentation
|
### Generating Documentation
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
swift run task generate-documentation
|
./task.sh generate-documentation
|
||||||
```
|
```
|
||||||
|
|
||||||
This copies the project to a temporary directory, injects the `swift-docc-plugin` dependency via `swift package add-dependency` (if absent), and runs documentation generation inside a `swift:latest` Docker container. The resulting static sites are written to `./public/inotify/` and `./public/taskcli/`, ready for deployment to GitHub Pages.
|
This copies the project to a temporary directory, injects the `swift-docc-plugin` dependency via `swift package add-dependency` (if absent), and runs documentation generation inside a `swift:latest` Docker container. The resulting static sites are written to `./public/inotify/` and `./public/taskcli/`, ready for deployment to GitHub Pages.
|
||||||
|
|||||||
58
task.sh
Executable file
58
task.sh
Executable file
@@ -0,0 +1,58 @@
|
|||||||
|
#!/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 "$@"
|
||||||
Reference in New Issue
Block a user