- CacheUrlConversion: normalize paths for comparison (forward slashes)
and strip leading slash on Windows file URIs so cache matching works.
- Apply scalafmt to touched files.
- Add CacheUrlConversion in lm-coursier internal to convert cache file
paths back to original repository URLs (single place for logic).
- CoursierDependencyResolution delegates to CacheUrlConversion.
- DependencyLockManager.createFromUpdateReport now accepts optional
cacheDir; when an artifact has a file URL it either converts via
cache dir (Coursier layout) or fails with a clear message.
- dependencyLock task passes csrCacheDirectory so lock file gets
portable HTTPS URLs instead of machine-specific cache paths.
Expectation 1: Lock file contains original Maven Central (or repo) URLs.
Expectation 2: If conversion is not possible, lock creation fails.
**Problem**
When platform is set, it incorrectly adds the platform suffix to implicit Scala library dependencies even though they explicitly set platform to jvm. This causes resolution errors.
**Solution**
Modified addPlatformSuffix to prioritize explicit platform settings on dependencies. If a dependency has an explicit platform, use that instead of the project platform. The project platform should only apply to dependencies without an explicit platform.
Fixes#8665
Generated-by: Claude Sonnet 4.5
**Consuming BOMs**
- You can declare a BOM with `.pomOnly()` and versionless deps with `"*"`:
- `libraryDependencies += ("com.fasterxml.jackson" % "jackson-bom" % "2.21.0").pomOnly()`
- `libraryDependencies += "com.fasterxml.jackson.core" % "jackson-core" % "*"`
- BOMs are passed to Coursier via `Resolve.addBom()`; version `"*"` is resolved from the BOM.
**makePom**
- POM-only dependencies are emitted under `<dependencyManagement><dependencies>...</dependencies></dependencyManagement>` with `<type>pom</type>` and `<scope>import</scope>`.
- Dependencies with version `"*"` are emitted without a `<version>` element so Maven uses the BOM-managed version.
**Ivy / publishLocal emulation**
- When publishing to Ivy (e.g. `publishLocal`), BOM-resolved versions (deps that had `"*"`) are written into the published `ivy.xml` as forced dependencies (`force="true"`), so consumers that depend on this module get those versions.
**What it does**
When you run `dependencyLock`, sbt generates a `deps.lock` file that captures your resolved dependencies. This file can be checked into version control to ensure reproducible builds across different machines and CI environments.
**New tasks**
- **`dependencyLock`** - Generates the lock file from the current resolution
- **`dependencyLockCheck`** - Validates the lock file is up-to-date (fails build if stale)
**How it works**
The lock file stores a hash of your declared dependencies and resolvers. When dependencies change, the hash changes, and `dependencyLockCheck` will fail until you regenerate the lock file.
If no lock file exists, `dependencyLockCheck` passes silently - this allows gradual adoption.
This adds a new setting that allows users to
configure Coursier's FileCache to cache local file:// artifacts. When enabled,
artifacts from local repositories are copied to the cache directory, which is
useful for scenarios like bundling compiler artifacts in a local repo for
offline use.
Fixes#7547
**Problem**
When project A's dependencies changed and A was compiled in one command, project B (depending on A) would not invalidate its update cache in a subsequent command. This caused stale classpaths.
The root cause was that `depsUpdated` only checked `!stats.cached`, which only detected fresh resolves within the same command. When a dependency was served from cache (even if resolved fresh in a previous command), `cached` was marked `true`, causing incorrect cache reuse.
Debug scenario from issue:
sbt:aaa> clean
sbt:aaa> a/compile
sbt:aaa> show itTests/depsUpdated
[info] * false <-- BUG: should be true
**Solution**
Added `stamp: String` field to `UpdateStats` that records when the update was resolved. This stamp persists across commands and enables accurate cross-command comparison:
- If any dependency's stamp > our cached stamp, we re-resolve
- Falls back to `!cached` check for backwards compatibility with old caches
- Using `String` type allows future transition from timestamps to content hashes