Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion .github/workflows/auto-update.yml
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,14 @@ jobs:
require_sha "MODULE_SHA" "$MODULE_SHA"
echo "module_sha=$MODULE_SHA" >> "$GITHUB_OUTPUT"

# Framework-source zip — required so `wheels new` can boot the scaffold.
# See wheels-dev/wheels PR 2294 for the release-workflow fix that
# started publishing this artifact on snapshots.
curl -sfL "https://github.com/wheels-dev/wheels/releases/download/v${MODULE_VER}/wheels-core-${MODULE_VER}.zip" -o /tmp/wheels-core.zip
CORE_SHA=$(shasum -a 256 /tmp/wheels-core.zip | awk '{print $1}')
require_sha "CORE_SHA" "$CORE_SHA"
echo "core_sha=$CORE_SHA" >> "$GITHUB_OUTPUT"

- name: Update formula
if: steps.check.outputs.needs_update == 'true'
env:
Expand All @@ -108,12 +116,13 @@ jobs:
MACOS_SHA: ${{ steps.hashes.outputs.macos_sha }}
LINUX_SHA: ${{ steps.hashes.outputs.linux_sha }}
MODULE_SHA: ${{ steps.hashes.outputs.module_sha }}
CORE_SHA: ${{ steps.hashes.outputs.core_sha }}
run: |
set -euo pipefail

# Belt-and-suspenders: reject empty inputs here too, in case upstream steps
# are edited in the future and the earlier guards get weakened.
for var in LUCLI_VER MODULE_VER MACOS_SHA LINUX_SHA MODULE_SHA; do
for var in LUCLI_VER MODULE_VER MACOS_SHA LINUX_SHA MODULE_SHA CORE_SHA; do
val="${!var}"
if [ -z "${val// }" ] || [ "$val" = "null" ]; then
echo "::error::$var is empty or null; refusing to write formula." >&2
Expand All @@ -129,6 +138,7 @@ jobs:
macos_sha = os.environ["MACOS_SHA"]
linux_sha = os.environ["LINUX_SHA"]
module_sha = os.environ["MODULE_SHA"]
core_sha = os.environ["CORE_SHA"]

with open("Formula/wheels.rb", "r") as f:
content = f.read()
Expand All @@ -138,6 +148,16 @@ jobs:
content = content[:shas[1].start()] + f'sha256 "{linux_sha}"' + content[shas[1].end():]
content = content[:shas[0].start()] + f'sha256 "{macos_sha}"' + content[shas[0].end():]

# Keep the wheels_core sha256 in sync. The resource block is always
# present in the formula; only the sha256 value rotates per release.
# Match [^"]+ to also catch the "PLACEHOLDER_CORE_SHA" sentinel on
# the first auto-update run after this PR lands.
core_block_re = re.compile(
r'(resource "wheels_core" do\s*\n\s*url "[^"]+"\s*\n\s*sha256 ")[^"]+(")',
re.MULTILINE,
)
content = core_block_re.sub(r'\g<1>' + core_sha + r'\g<2>', content)

if module_sha:
content = re.sub(
r'#\s*sha256 "PLACEHOLDER_MODULE_SHA"',
Expand Down
59 changes: 58 additions & 1 deletion Formula/wheels.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ class Wheels < Formula

LUCLI_VERSION = "0.3.7"
MODULE_VERSION = "4.0.0-SNAPSHOT+1523"
SQLITE_JDBC_VERSION = "3.49.1.0"

if OS.mac?
url "https://github.com/cybersonic/LuCLI/releases/download/v#{LUCLI_VERSION}/lucli-#{LUCLI_VERSION}-macos"
Expand All @@ -19,6 +20,23 @@ class Wheels < Formula
sha256 "4aa7dc5e7dafa5b6bd521807c8c81ca7f9174e4e4840927f921bc89f34c20313"
end

resource "wheels_core" do
url "https://github.com/wheels-dev/wheels/releases/download/v#{MODULE_VERSION}/wheels-core-#{MODULE_VERSION}.zip"
sha256 "PLACEHOLDER_CORE_SHA"
end

# SQLite JDBC driver — shipped with the bottle so fresh installs can run the
# default zero-config SQLite datasource on first `wheels start`. Without this,
# Lucee 7's BundleProvider tries to fetch the OSGi bundle from update.lucee.org
# at runtime and fails (the bundle is not on that update provider, and the
# fallback S3 listing currently contains malformed entries that crash the
# version parser). The wrapper copies this JAR into Lucee Express's lib/ext
# on first invocation so the driver is on the classpath when migrations run.
resource "sqlite_jdbc" do
url "https://repo1.maven.org/maven2/org/xerial/sqlite-jdbc/#{SQLITE_JDBC_VERSION}/sqlite-jdbc-#{SQLITE_JDBC_VERSION}.jar"
sha256 "5c8609d2ca341deb8c6f71778974b5ba4995c7d32d7c7c89d9392a3e72c39291"
end

depends_on "openjdk@21"

def install
Expand All @@ -30,6 +48,18 @@ def install
(share/"wheels/module").install Dir["*"]
end

# Framework source (vendor/wheels/) is shipped as a companion zip. Extracting
# it into share/wheels/framework/wheels/ matches the wheels-core zip's own
# internal layout (top-level "wheels/" directory, verified against the
# release workflow's smoke-test at tools/ci/smoke-test-module.sh).
resource("wheels_core").stage do
(share/"wheels/framework").install Dir["*"]
end

resource("sqlite_jdbc").stage do
(share/"wheels/jdbc").install "sqlite-jdbc-#{SQLITE_JDBC_VERSION}.jar"
end

(share/"wheels").mkpath
(share/"wheels/.module-version").write MODULE_VERSION

Expand All @@ -44,8 +74,11 @@ def install
BREW_PREFIX="#{HOMEBREW_PREFIX}/opt/wheels"
WHEELS_MODULE_SRC="$BREW_PREFIX/share/wheels/module"
WHEELS_MODULE_DST="$HOME/.wheels/modules/wheels"
WHEELS_FRAMEWORK_SRC="$BREW_PREFIX/share/wheels/framework/wheels"
WHEELS_FRAMEWORK_DST="$HOME/.wheels/modules/wheels/vendor/wheels"
WHEELS_VERSION_SRC="$BREW_PREFIX/share/wheels/.module-version"
WHEELS_VERSION_DST="$HOME/.wheels/modules/wheels/.module-version"
WHEELS_JDBC_SRC="$BREW_PREFIX/share/wheels/jdbc"

if [ -f "$WHEELS_VERSION_SRC" ]; then
src_ver=$(cat "$WHEELS_VERSION_SRC")
Expand All @@ -54,10 +87,30 @@ def install
if [ "$src_ver" != "$dst_ver" ]; then
mkdir -p "$WHEELS_MODULE_DST"
cp -R "$WHEELS_MODULE_SRC/"* "$WHEELS_MODULE_DST/"
if [ -d "$WHEELS_FRAMEWORK_SRC" ]; then
mkdir -p "$WHEELS_FRAMEWORK_DST"
cp -R "$WHEELS_FRAMEWORK_SRC/"* "$WHEELS_FRAMEWORK_DST/"
fi
cp "$WHEELS_VERSION_SRC" "$WHEELS_VERSION_DST"
fi
fi

# Seed the SQLite JDBC driver into every Lucee Express install under
# ~/.wheels/express/. Lucee 7's BundleProvider can't fetch this bundle
# from update.lucee.org (the bundle isn't on that provider, and the
# fallback S3 listing parser currently chokes on malformed entries).
# Without it, the default zero-config SQLite datasource fails on first
# use — `wheels migrate latest` exits 0 but no schema is created.
# Idempotent: skipped per-express-version once the file is present.
if [ -d "$WHEELS_JDBC_SRC" ] && [ -d "$HOME/.wheels/express" ]; then
for express_dir in "$HOME/.wheels/express"/*/; do
ext_dir="${express_dir}lib/ext"
if [ -d "$ext_dir" ] && ! ls "$ext_dir"/sqlite-jdbc*.jar >/dev/null 2>&1; then
cp "$WHEELS_JDBC_SRC"/sqlite-jdbc-*.jar "$ext_dir/" 2>/dev/null || true
fi
done
fi

export JAVA_HOME="#{java_home}"
export LUCLI_HOME="$HOME/.wheels"
exec "$BREW_PREFIX/libexec/wheels" "$@"
Expand All @@ -69,8 +122,10 @@ def caveats
<<~EOS
Java 21 is required and has been installed as a dependency.

On first run, the Wheels module will be initialized in:
On first run, the Wheels module and framework source will be
initialized in:
~/.wheels/modules/wheels/
~/.wheels/modules/wheels/vendor/wheels/

The wrapper sets LUCLI_HOME=~/.wheels so all runtime state
(modules, servers, deps, secrets) lives under that directory
Expand All @@ -82,6 +137,8 @@ def caveats
assert_predicate bin/"wheels", :executable?
assert_predicate libexec/"wheels", :executable?
assert_predicate share/"wheels/module/Module.cfc", :exist?
assert_predicate share/"wheels/framework/wheels", :exist?
assert_predicate share/"wheels/jdbc/sqlite-jdbc-#{SQLITE_JDBC_VERSION}.jar", :exist?
assert_match(/\d+\.\d+\.\d+/, shell_output("#{bin}/wheels --version"))
end
end