Skip to content

[2.x] feat: repositories_force support#8761

Merged
eed3si9n merged 17 commits intosbt:developfrom
bitloi:feature/1870-force-proxy-repos
Feb 20, 2026
Merged

[2.x] feat: repositories_force support#8761
eed3si9n merged 17 commits intosbt:developfrom
bitloi:feature/1870-force-proxy-repos

Conversation

@bitloi
Copy link
Copy Markdown
Contributor

@bitloi bitloi commented Feb 18, 2026

Summary

Adds support for forcing dependency resolution through proxy repositories by placing a repositories_force file under the sbt global base (e.g. ~/.sbt/repositories_force). When this file exists, sbt sets overrideBuildResolvers := true so resolution uses the proxy repos (e.g. from sbtopts) instead of the build’s resolvers.

Useful in locked-down or corporate environments where all artifact access must go through a proxy.

Changes

  • Read repositories_force under sbt.global.base (or $SBT_OPTS / sbtopts) and enable override when present.
  • Add scripted test dependency-management/force-proxy-repos-file to cover the behavior.

Closes #1870

…ixes sbt#1870)

- Add Classpaths.shouldOverrideBuildResolvers: true when launcher flag,
  SBT_OVERRIDE_BUILD_REPOS env, or sbt.override.build.repos property,
  or when ~/.sbt/repositories_force (or sbt.global.base/repositories_force) exists
- Use global base from sbt.global.base or default ~/.sbt for file check
- Handle SecurityException on file existence check
- overrideBuildResolvers now uses shouldOverrideBuildResolvers
…sbt#1870)

- dependency-management/force-proxy-repos-file: with global/repositories_force
  present (and -Dsbt.global.base=<testDir>/global from scripted), check task
  asserts overrideBuildResolvers is true
Copy link
Copy Markdown
Member

@eed3si9n eed3si9n left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this needs to be implemented in sbt/launcher because the resolution of sbt artifact itself needs to be overridden if you're behind the firewall - https://github.com/search?q=repo%3Asbt%2Flauncher%20overrideRepos&type=code

…erride

Avoid enabling override when only the sentinel file exists (e.g. scripted
test dirs), which broke dependency-management tests that use custom
resolvers (ivyless-publish-maven-http, pom-advanced, transitive-excludes).
Add global/repositories to force-proxy-repos-file test.
@bitloi bitloi requested a review from eed3si9n February 18, 2026 09:56
Prevents force-proxy-repos-file's repositories_force/repositories from
leaking into later tests in the same batch (e.g. ivyless-publish-maven-http).
Use find -exec instead of rm $(find ...) so rm is only invoked when
there are matches; quoted paths and suppress stderr for robustness.
The sbt launcher does not support a 'repository-override' label in the [ivy]
section, causing 'Invalid label(s): repository-override' errors during scripted
tests. This label needs to be implemented in sbt/launcher first before it can
be used here.

The Scala implementation in Defaults.scala that checks for repositories_force
file existence at runtime remains valid and functional.
@bitloi bitloi force-pushed the feature/1870-force-proxy-repos branch from b44dec1 to 8662e77 Compare February 18, 2026 23:49
Always remove leftover repositories_force and repositories files
from the previous test BEFORE copying the new test content. This
prevents force proxy repos from leaking between batched tests while
preserving the boot/ directory containing compiler core libraries.

If the current test provides these files (e.g. force-proxy-repos-file),
IO.copyDirectory restores them after the cleanup.
@bitloi bitloi force-pushed the feature/1870-force-proxy-repos branch from 8662e77 to cd60198 Compare February 18, 2026 23:51
@bitloi
Copy link
Copy Markdown
Contributor Author

bitloi commented Feb 19, 2026

@eed3si9n Would you mind reviewing the changes again?

@eed3si9n
Copy link
Copy Markdown
Member

I just released launcher 1.6.0 with your change. I think you just need to update the launcher and update https://github.com/sbt/sbt/blob/develop/launch/src/main/input_resources/sbt/sbt.boot.properties.

…erties

- Bump launcherVersion to 1.6.0 (launcher-interface, launcher)
- Add repository-override to [ivy] in default boot properties for
  force-proxy-repos support (repositories_force file)
@bitloi
Copy link
Copy Markdown
Contributor Author

bitloi commented Feb 19, 2026

I just released launcher 1.6.0 with your change. I think you just need to update the launcher and update https://github.com/sbt/sbt/blob/develop/launch/src/main/input_resources/sbt/sbt.boot.properties.

@eed3si9n I've just updated them. Please check again.

…efaults

The launcher (1.6.0+) sets override from repository-override and passes it
via isOverrideRepositories(). No need to duplicate the file check in sbt.
@bitloi bitloi requested a review from eed3si9n February 19, 2026 16:46
Launcher uses repository-override file as the repo list when present, so
we only need global/repositories_force (with content); remove global/repositories.
When scripted uses RunFromSourceBased (e.g. CI), isOverrideRepositories()
was hardcoded to false. Check sbt.global.base/repositories_force so
force-proxy-repos-file test passes.
@eed3si9n
Copy link
Copy Markdown
Member

One thing I forgot to tell you is that scripted by default runs in parallel, so testing the launcher requires a different configuration. Luckily we have a skeleton setup already in https://github.com/sbt/sbt/tree/develop/sbt-app/src/repo-override-test.

step 1: uncomment repo override test

# ./sbt -v "repoOverrideTest:scripted dependency-management/*"

step 2: replace the existing override scripted test

You can move your new scripted test into https://github.com/sbt/sbt/tree/develop/sbt-app/src/repo-override-test, and feel free to delete the existing one in there.

steps 3: fix the configuration

sbt/build.sbt

Lines 1042 to 1058 in b634e1b

) ++ inConfig(Scripted.RepoOverrideTest)(
Seq(
scriptedLaunchOpts := List(
"-Xmx1500M",
"-Xms512M",
"-server",
"-Dsbt.override.build.repos=true",
s"""-Dsbt.repository.config=${scriptedSource.value / "repo.config"}"""
) :::
(sys.props.get("sbt.ivy.home") match {
case Some(home) => List(s"-Dsbt.ivy.home=$home")
case _ => Nil
}),
scripted := scriptedTask(true).evaluated,
scriptedUnpublished := scriptedTask(true).evaluated,
scriptedSource := (sbtProj / sourceDirectory).value / "repo-override-test"
)
The repoOverride specific configuration is done here. Feel free to change whatever you have to there.

- Uncomment repoOverrideTest in CI job 4: run force-proxy-repos-file/* with launcher
- Replace default-resolvers with force-proxy-repos-file under repo-override-test
- Remove -Dsbt.override.build.repos and -Dsbt.repository.config from
  RepoOverrideTest so the test asserts launcher/repositories_force behavior
- Delete force-proxy-repos-file from dependency-management (parallel scripted)
@bitloi
Copy link
Copy Markdown
Contributor Author

bitloi commented Feb 19, 2026

One thing I forgot to tell you is that scripted by default runs in parallel, so testing the launcher requires a different configuration. Luckily we have a skeleton setup already in https://github.com/sbt/sbt/tree/develop/sbt-app/src/repo-override-test.

step 1: uncomment repo override test

# ./sbt -v "repoOverrideTest:scripted dependency-management/*"

step 2: replace the existing override scripted test

You can move your new scripted test into https://github.com/sbt/sbt/tree/develop/sbt-app/src/repo-override-test, and feel free to delete the existing one in there.

steps 3: fix the configuration

sbt/build.sbt

Lines 1042 to 1058 in b634e1b

) ++ inConfig(Scripted.RepoOverrideTest)(
Seq(
scriptedLaunchOpts := List(
"-Xmx1500M",
"-Xms512M",
"-server",
"-Dsbt.override.build.repos=true",
s"""-Dsbt.repository.config=${scriptedSource.value / "repo.config"}"""
) :::
(sys.props.get("sbt.ivy.home") match {
case Some(home) => List(s"-Dsbt.ivy.home=$home")
case _ => Nil
}),
scripted := scriptedTask(true).evaluated,
scriptedUnpublished := scriptedTask(true).evaluated,
scriptedSource := (sbtProj / sourceDirectory).value / "repo-override-test"
)

The repoOverride specific configuration is done here. Feel free to change whatever you have to there.

I've fixed it. Would you mind reviewing it again?

The launcher 1.6.0 bool() default for override-build-repos uses
repository-override file existence, but only when the label is absent.
The explicit 'override-build-repos: false' line was preventing this
auto-detection. sbt.override.build.repos is still checked by
shouldOverrideBuildResolvers in Defaults.scala.
@bitloi
Copy link
Copy Markdown
Contributor Author

bitloi commented Feb 20, 2026

@eed3si9n Do you have any other feedback?

Copy link
Copy Markdown
Member

@eed3si9n eed3si9n left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@eed3si9n eed3si9n changed the title feat/Force proxy repos via file [2.x] feat: repositories_force support Feb 20, 2026
@eed3si9n eed3si9n merged commit c045c72 into sbt:develop Feb 20, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Some way of forcing proxy repositories

2 participants