Skip to content
Merged
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
35 changes: 35 additions & 0 deletions .github/scripts/bleep-version.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/usr/bin/env bash
# Print the version this build will bake into the client, i.e. `model.BleepVersion.current`.
#
# Every publish in build.yml has to name this exact version. The client asks Coursier for `build.bleep:bleep-bsp` at the
# version compiled into it, so publishing under any other coordinate produces a binary that resolves nothing — and
# nothing fails until someone runs it.
#
# It is read out of the sourcegen output rather than recomputed with dynver, because recomputing is how the two drift:
# dynver appends a timestamp on a dirty tree, so a second derivation of "the same" version need not agree with the one
# already compiled in.
#
# This lives in one place because it previously did not. Four steps each carried their own copy of the grep, all naming
# the pre-1.0.0-M11 layout (`.bleep/generated-sources/<project>/...`), and when the bootstrap moved to a bleep that
# writes the current layout (`.bleep/projects/<project>/generated-sources/...`) every one of them silently matched
# nothing at once.

set -uo pipefail

version_file=".bleep/projects/bleep-model/generated-sources/bleep.scripts.GenerateResources/bleep/model/BleepVersion.scala"

if [ ! -f "$version_file" ]; then
echo "::error::$version_file does not exist — run 'bleep sourcegen' before this step. (If the layout moved again, this script is what needs updating.)" >&2
exit 1
fi

version=$(grep 'val current' "$version_file" | sed 's/.*BleepVersion("\(.*\)").*/\1/')

# An empty version is the dangerous case, not a loud one: passed to `--version ""` it publishes under whatever the
# fallback picks, and the mismatch only surfaces when a binary later fails to resolve its own server.
if [ -z "$version" ]; then
echo "::error::could not parse a version out of $version_file" >&2
exit 1
fi

echo "$version"
8 changes: 4 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
bleep sourcegen
bleep compile
# publish locally so the dev script's BSP server uses our code
bleep publish-local --groupId build.bleep --version "$(grep 'val current' .bleep/generated-sources/bleep-model/bleep.scripts.GenerateResources/bleep/model/BleepVersion.scala | sed 's/.*BleepVersion("\(.*\)").*/\1/')"
bleep publish-local --groupId build.bleep --version "$(bash .github/scripts/bleep-version.sh)"
bleep config compile-server stop-all
bleep setup-dev-script bleep-cli

Expand Down Expand Up @@ -78,7 +78,7 @@ jobs:
# Without it the version comes from dynver at runtime, which appends a timestamp when the working tree is
# dirty — and the artifact would then be published under a version no binary asks for. The jars are only
# useful paired with a binary that names them, so this cannot be left to depend on the tree being clean.
version=$(grep 'val current' .bleep/generated-sources/bleep-model/bleep.scripts.GenerateResources/bleep/model/BleepVersion.scala | sed 's/.*BleepVersion("\(.*\)").*/\1/')
version=$(bash .github/scripts/bleep-version.sh)
./bleep-cli.sh --dev publish local-ivy --to dev-jars --version "$version" --no-tui
echo "$version" > dev-jars/VERSION
echo "version: $version"
Expand Down Expand Up @@ -304,7 +304,7 @@ jobs:
run: |
bleep sourcegen
bleep compile bleep-cli
bleep publish-local --groupId build.bleep --version "$(grep 'val current' .bleep/generated-sources/bleep-model/bleep.scripts.GenerateResources/bleep/model/BleepVersion.scala | sed 's/.*BleepVersion("\(.*\)").*/\1/')"
bleep publish-local --groupId build.bleep --version "$(bash .github/scripts/bleep-version.sh)"
bleep config compile-server stop-all

# Windows-only and genuinely so: mandatory file locks. `compile-server stop-all` can fail to remove socket directories while a JVM still holds them,
Expand Down Expand Up @@ -425,7 +425,7 @@ jobs:
run: |
bleep sourcegen
bleep compile bleep-cli
bleep publish-local --groupId build.bleep --version "$(grep 'val current' .bleep/generated-sources/bleep-model/bleep.scripts.GenerateResources/bleep/model/BleepVersion.scala | sed 's/.*BleepVersion("\(.*\)").*/\1/')"
bleep publish-local --groupId build.bleep --version "$(bash .github/scripts/bleep-version.sh)"
bleep config compile-server stop-all
- name: Download artifacts
uses: actions/download-artifact@v8
Expand Down
25 changes: 2 additions & 23 deletions bleep-model/src/scala/bleep/BuildPaths.scala
Original file line number Diff line number Diff line change
Expand Up @@ -113,23 +113,6 @@ case class BuildPaths(cwd: Path, bleepYamlFile: Path, variant: model.BuildVarian
case None => if (scalaVersion.isDefined) model.SourceLayout.Normal else model.SourceLayout.Java
}

// Legacy v1 layout fallback for sourcegen outputs. A bleep build that's still on the released `build.bleep:bleep-core:<M9-or-older>` writes generated
// sources to `.bleep/generated-sources/<cross>/<folder>/`. The forked sourcegen subprocess fetches its bleep-core from Maven (per `BLEEP_VERSION`
// substitution), so during CI on a fresh checkout it gets the released M9 layout. The bleep-server in this PR uses v2 layout
// (`.bleep/projects/<cross>/generated-sources/<folder>/`). Without this fallback the v2-layout-aware source list misses the v1-written files and the
// compile fails with "Not found: type BleepVersion" or similar.
//
// Gated on `Files.isDirectory` so fresh builds (snapshot tests, `bleep new` workspaces) — which have no M9-generated content — don't see these phantom
// paths in their bloop.json. Once a v2-aware bleep is shipping everywhere and no v1 dirs survive bootstraps, this whole block can go.
def legacyGeneratedSourcesDir(folderName: String): Option[Path] = {
val p = dotBleepDir / "generated-sources" / crossName.value / folderName
if (java.nio.file.Files.isDirectory(p)) Some(p) else None
}
def legacyGeneratedResourcesDir(folderName: String): Option[Path] = {
val p = dotBleepDir / "generated-resources" / crossName.value / folderName
if (java.nio.file.Files.isDirectory(p)) Some(p) else None
}

val sources = {
val fromSourceLayout = sourceLayout.sources(scalaVersion, maybePlatformId, p.`sbt-scope`).values.map(dir / _)
val fromJson = p.sources.values.map(relPath => (relPath, dir / replacements.fill.relPath(relPath))).toMap
Expand All @@ -143,10 +126,7 @@ case class BuildPaths(cwd: Path, bleepYamlFile: Path, variant: model.BuildVarian
val base = generatedSourcesDir(crossName, "ksp")
List(base / "kotlin", base / "java")
}
// Append v1-layout sourcegen paths to ksp (which is just an opaque List[Path] in DirsByOrigin). Wrong field semantically, but it threads through .all
// without changing the ADT — the legacy fallback is temporary anyway.
val legacySourcegen = p.sourcegen.values.iterator.flatMap(s => legacyGeneratedSourcesDir(s.folderName)).toList
ProjectPaths.DirsByOrigin(fromSourceLayout, fromJson, generated, annotationProcessing, ksp ++ legacySourcegen)
ProjectPaths.DirsByOrigin(fromSourceLayout, fromJson, generated, annotationProcessing, ksp)
}

val resources = {
Expand All @@ -156,8 +136,7 @@ case class BuildPaths(cwd: Path, bleepYamlFile: Path, variant: model.BuildVarian
// KSP resources land at .bleep/projects/<cross>/generated-sources/ksp/resources/; expose them so they're packaged like normal resources.
val ksp: List[Path] =
p.kotlin.filter(_.hasSymbolProcessing).toList.map(_ => generatedSourcesDir(crossName, "ksp") / "resources")
val legacySourcegenResources = p.sourcegen.values.iterator.flatMap(s => legacyGeneratedResourcesDir(s.folderName)).toList
ProjectPaths.DirsByOrigin(fromSourceLayout, fromJson, generated, None, ksp ++ legacySourcegenResources)
ProjectPaths.DirsByOrigin(fromSourceLayout, fromJson, generated, None, ksp)
}

ProjectPaths(dir = dir, targetDir = targetDir, sourcesDirs = sources, resourcesDirs = resources, isTestProject = p.isTestProject.getOrElse(false))
Expand Down
15 changes: 13 additions & 2 deletions bleep.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
$schema: https://raw.githubusercontent.com/oyvindberg/bleep/master/schema.json
$version: 1.0.0-M9
$version: 1.0.0-M11
jvm:
# TODO: graalvm-community:25.0.2 is not available for macos-15-intel (x86_64) in coursier's JVM index.
# Need to either wait for index update, pin x86 macOS to 25.0.1, or drop x86 macOS CI.
Expand Down Expand Up @@ -375,7 +375,18 @@ projects:
enabled: false
sources: ./src/main/java
scripts-init:
dependencies: build.bleep::bleep-plugin-dynver:${BLEEP_VERSION}
# bleep-core is declared explicitly rather than arriving through the dynver plugin. Until 1.0.0-M11 it came for free,
# because bleep-plugin-dynver depended on bleep-core; #591 merged the sbt-pgp/sonatype/ci-release sources INTO
# bleep-core to break a cycle, which flipped that edge — bleep-core now depends on bleep-plugin-dynver. So the M11
# dynver POM lists no bleep-core at all, and GenerateResources died at fork time with
# `NoClassDefFoundError: bleep/BleepCodegenScript$Target` while still compiling cleanly, because the script's compile
# classpath and the forked runtime classpath are built from different things.
#
# This project cannot `dependsOn: bleep-core` like every other script project: it sourcegens BleepVersion.scala FOR
# bleep-model, which bleep-core depends on, so an in-tree edge would be circular. It has to resolve a published one.
dependencies:
- build.bleep::bleep-plugin-dynver:${BLEEP_VERSION}
- build.bleep::bleep-core:${BLEEP_VERSION}
extends:
- template-common
- template-scala-3
Expand Down
Loading