sbt: allow managing the ~/.sbt/repositories file

sbt allows overriding the default repositories to use to resolve
dependencies. This is often used with proxies and/or private
repositories to host internal packages.

This change adds a `repositories` attribute to `sbt` to allow
specifying the values that will go in `~/.sbt/repositories` file.

To support the above change we also deprecate the `baseConfigPath`
option in favour of `baseUserConfigPath` which points one level higher
by default. This allows not using relative paths to refer to the
top-level configuration directory.

Also adds tests for the new option and the deprecation of the previous
one.
This commit is contained in:
Philippe Laflamme 2022-10-02 22:52:33 -04:00 committed by Robert Helgesson
parent 6427ae9578
commit 599e22b1c7
No known key found for this signature in database
GPG key ID: 36BDAA14C2797E89
5 changed files with 167 additions and 6 deletions

View file

@ -16,6 +16,17 @@ let
import scala.sys.process._
${concatStrings (map renderCredential creds)}'';
renderRepository = value:
if isString value then ''
${value}
'' else ''
${concatStrings (mapAttrsToList (name: value: "${name}: ${value}") value)}
'';
renderRepositories = repos: ''
[repositories]
${concatStrings (map renderRepository cfg.repositories)}'';
sbtTypes = {
plugin = types.submodule {
options = {
@ -68,6 +79,11 @@ let
cfg = config.programs.sbt;
in {
imports = [
(mkRemovedOptionModule [ "programs" "sbt" "baseConfigPath" ]
"Use programs.sbt.baseUserConfigPath instead, but note that the semantics are slightly different.")
];
meta.maintainers = [ maintainers.kubukoz ];
options.programs.sbt = {
@ -80,10 +96,13 @@ in {
description = "The package with sbt to be installed.";
};
baseConfigPath = mkOption {
baseUserConfigPath = mkOption {
type = types.str;
default = ".sbt/1.0";
description = "Where the plugins and credentials should be located.";
default = ".sbt";
description = ''
Where the sbt configuration files should be located, relative
<envar>HOME</envar>.
'';
};
plugins = mkOption {
@ -123,19 +142,63 @@ in {
A list of credentials to define in the sbt configuration directory.
'';
};
repositories = mkOption {
type = with types;
listOf
(either (enum [ "local" "maven-central" "maven-local" ]) (attrsOf str));
default = [ ];
example = literalExpression ''
[
"local"
{ my-ivy-proxy-releases = "http://repo.company.com/ivy-releases/, [organization]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext]" }
{ my-maven-proxy-releases = "http://repo.company.com/maven-releases/" }
"maven-central"
]
'';
description = ''
A list of repositories to use when resolving dependencies. Defined as a
list of pre-defined repository or custom repository as a set of name to
URL. The list will be used populate the <code>~/.sbt/repositories</code>
file in the order specified.
</para><para>
Pre-defined repositories must be one of <code>local</code>,
<code>maven-local</code>, <code>maven-central</code>.
</para><para>
Custom repositories are defined as
<code language="nix">{ name-of-repo = "https://url.to.repo.com"}</code>.
</para><para>
See
<link xlink:href="https://www.scala-sbt.org/1.x/docs/Launcher-Configuration.html#3.+Repositories+Section"/>
about this configuration section and
<link xlink:href="https://www.scala-sbt.org/1.x/docs/Proxy-Repositories.html"/>
to read about proxy repositories.
'';
};
};
config = mkIf cfg.enable (mkMerge [
{ home.packages = [ cfg.package ]; }
(mkIf (cfg.plugins != [ ]) {
home.file."${cfg.baseConfigPath}/plugins/plugins.sbt".text =
home.file."${cfg.baseUserConfigPath}/1.0/plugins/plugins.sbt".text =
concatStrings (map renderPlugin cfg.plugins);
})
(mkIf (cfg.credentials != [ ]) {
home.file."${cfg.baseConfigPath}/credentials.sbt".text =
home.file."${cfg.baseUserConfigPath}/1.0/credentials.sbt".text =
renderCredentials cfg.credentials;
})
(mkIf (cfg.repositories != [ ]) {
home.file."${cfg.baseUserConfigPath}/repositories".text =
renderRepositories cfg.repositories;
})
]);
}