diff --git a/projects/tuist.io/tuist/package.yml b/projects/tuist.io/tuist/package.yml new file mode 100644 index 0000000000..95289b6e46 --- /dev/null +++ b/projects/tuist.io/tuist/package.yml @@ -0,0 +1,105 @@ +# tuist — declarative Xcode project generator. +# +# Pure-Swift project built via Swift Package Manager. Tuist consumes +# its dependencies from the Tuist swift package registry +# (registry.tuist.dev), so the SPM resolve step needs network egress +# (anonymous reads are public). +# +# Upstream sed-patches `cli/Sources/TuistConstants/Constants.swift` +# at release-time to bake the version into the binary — the source +# tarball still carries an older string (the previous release). We +# replicate that sed in the build step so `tuist --version` prints +# the recipe's `{{version}}` rather than the stale TaskLocal default. +# +# At runtime tuist locates `libProjectDescription.dylib` and the +# `Templates` directory relative to the binary; the Homebrew layout +# is explicitly supported (`bin/tuist` + `lib/libProjectDescription.dylib` +# + `share/Templates`). See +# cli/Sources/TuistLoader/Utils/ResourceLocator.swift and +# TemplatesDirectoryLocator.swift in the source tree. +# +# Linux: pantry's swift.org is darwin-only (see its commented-out +# linux platforms — Ubuntu 22.04 toolchain not yet available in CI). +# Revisit when that lands. Upstream's own Linux release uses the +# musl static SDK, which is orthogonal to pkgx's approach anyway. + +distributable: + url: https://github.com/tuist/tuist/archive/refs/tags/{{version}}.tar.gz + strip-components: 1 + +versions: + github: tuist/tuist + +platforms: + - darwin/x86-64 + - darwin/aarch64 + +build: + dependencies: + # Package.swift declares swift-tools-version: 6.1. + swift.org: '>=6.1' + script: + # Bake the recipe version into Constants.swift (upstream does the + # same sed in its release workflow; the tarball string is stale). + # Wrapped in `run: |` because the sed pattern contains `: ` which + # YAML otherwise mis-parses as a mapping key/value separator. + - run: | + sed -i.bak -E 's/(@TaskLocal public static var version: String! = ")[^"]+(")/\1{{version}}\2/' cli/Sources/TuistConstants/Constants.swift + rm cli/Sources/TuistConstants/Constants.swift.bak + + # Resolve & build. `--replace-scm-with-registry` honours the + # registry-pinned Package.resolved (every pin is `kind: registry`, + # served by registry.tuist.dev anonymously). + # + # IMPORTANT: swift build's `--product` flag is SINGULAR — repeating + # it with two values silently keeps only the LAST one. Previous + # iteration (commit 4c2dd83f) used `--product tuist --product + # ProjectDescription` and only ProjectDescription got built; + # tuist itself was skipped, causing `install: cannot stat + # .swift-build/release/tuist`. Two separate invocations is the + # idiomatic SwiftPM pattern. + - run: | + swift build \ + --product ProjectDescription \ + --configuration release \ + --replace-scm-with-registry \ + --build-path "$PWD/.swift-build" + swift build \ + --product tuist \ + --configuration release \ + --replace-scm-with-registry \ + --build-path "$PWD/.swift-build" + + # Install in the Homebrew-shaped layout that tuist's ResourceLocator + # and TemplatesDirectoryLocator both look for: + # {{prefix}}/bin/tuist + # {{prefix}}/lib/libProjectDescription.dylib + # {{prefix}}/lib/Modules/ProjectDescription.swiftmodule (commandLine include path) + # {{prefix}}/share/Templates + - install -D -m755 .swift-build/release/tuist "{{prefix}}/bin/tuist" + - install -D -m755 .swift-build/release/libProjectDescription.dylib "{{prefix}}/lib/libProjectDescription.dylib" + # ProjectDescription.swiftmodule isn't always emitted by SwiftPM at + # the top-level release/ path (Swift 6.x sometimes nests it under + # arch-specific dirs, sometimes skips it in pure-library configurations). + # Search for it; skip gracefully if absent. The runtime cost is + # that downstream Swift code can't `import ProjectDescription` + # against this bottle — tuist's own CLI usage doesn't need it. + - run: | + mkdir -p "{{prefix}}/lib/Modules" + if [ -d .swift-build/release/ProjectDescription.swiftmodule ]; then + cp -R .swift-build/release/ProjectDescription.swiftmodule "{{prefix}}/lib/Modules/" + else + # Fallback: try arch-specific path (Swift 6.x layout) + find .swift-build -name 'ProjectDescription.swiftmodule' -type d -exec cp -R {} "{{prefix}}/lib/Modules/" \; -quit || true + fi + - mkdir -p "{{prefix}}/share" + - cp -R cli/Templates "{{prefix}}/share/Templates" + +provides: + - bin/tuist + +test: + # `tuist version` prints just the version string (see + # TuistVersionCommand/VersionService.swift — it passthrough's + # Constants.version with a trailing newline). + - tuist version 2>&1 | grep -q "{{version}}"