Resolve and apply settings buildscript dependencies

This commit is contained in:
Tad Fisher
2020-11-24 16:35:48 -08:00
parent a99b5f40e3
commit fd6a6f4693
20 changed files with 951 additions and 41 deletions

View File

@@ -32,12 +32,12 @@
let
inherit (builtins)
filter sort replaceStrings attrValues match fromJSON
concatStringsSep;
attrValues concatStringsSep filter fromJSON match replaceStrings sort;
inherit (stdenv.lib)
versionOlder unique mapAttrs mapAttrsToList last concatMapStringsSep
removeSuffix optionalString groupBy' readFile hasSuffix;
assertMsg concatMapStringsSep groupBy' hasSuffix last mapAttrs
mapAttrsToList optionalString readFile removeSuffix unique versionAtLeast
versionOlder;
mkDep = depSpec: stdenv.mkDerivation {
inherit (depSpec) name;
@@ -176,10 +176,20 @@ let
paths = map mkDep deps ++ mkModuleMetadata deps ++ mkSnapshotMetadata deps;
};
mkInitScript = projectSpec:
mkInitScript = projectSpec: gradle:
let
repos = mapAttrs (mkRepo projectSpec.name) projectSpec.dependencies;
hasDependencies = mapAttrs (type: deps: deps != []) projectSpec.dependencies;
in
assert (assertMsg (hasDependencies.settings -> versionAtLeast gradle.version "6.0") ''
Project `${projectSpec.name}' has settings script dependencies, such as settings
plugins, which are not supported by gradle2nix for Gradle versions prior to 6.0.
Potential remedies:
- Pass `--gradle-version=<version>' to the gradle2nix command.
- Patch the `settings.gradle[.kts]' file to remove script dependencies.
'');
writeText "init.gradle" ''
static def offlineRepo(RepositoryHandler repositories, String env, String path) {
repositories.clear()
@@ -204,18 +214,35 @@ let
}
}
gradle.settingsEvaluated {
offlineRepo(it.pluginManagement.repositories, "plugin", "${repos.plugin}")
}
${optionalString (hasDependencies.settings && (versionAtLeast gradle.version "6.0")) ''
gradle.beforeSettings {
offlineRepo(it.buildscript.repositories, "settings", "${repos.settings}")
}
''}
gradle.projectsLoaded {
allprojects {
buildscript {
offlineRepo(repositories, "buildscript", "${repos.buildscript}")
}
offlineRepo(repositories, "project", "${repos.project}")
}
}
${optionalString (hasDependencies.plugin) ''
gradle.settingsEvaluated {
offlineRepo(it.pluginManagement.repositories, "plugin", "${repos.plugin}")
}
''}
${optionalString (hasDependencies.buildscript) ''
gradle.projectsLoaded {
allprojects {
buildscript {
offlineRepo(repositories, "buildscript", "${repos.buildscript}")
}
}
}
''}
${optionalString (hasDependencies.project) ''
gradle.projectsLoaded {
allprojects {
offlineRepo(repositories, "project", "${repos.project}")
}
}
''}
'';
mkGradle = gradleSpec:
@@ -227,12 +254,14 @@ let
src = fetchurl {
inherit (gradleSpec) url sha256;
};
} // {
inherit (gradleSpec) version;
};
mkProjectEnv = projectSpec: {
mkProjectEnv = projectSpec: rec {
inherit (projectSpec) name path version;
initScript = mkInitScript projectSpec;
gradle = args.gradlePackage or mkGradle projectSpec.gradle;
initScript = mkInitScript projectSpec gradle;
};
gradleEnv = mapAttrs

View File

@@ -19,6 +19,7 @@ fun buildEnv(builds: Map<String, DefaultBuild>): Map<String, NixGradleEnv> =
path = path,
gradle = build.gradle,
dependencies = mapOf(
"settings" to build.settingsDependencies,
"plugin" to build.pluginDependencies,
"buildscript" to build.rootProject.collectDependencies(DefaultProject::buildscriptDependencies),
"project" to build.rootProject.collectDependencies(DefaultProject::projectDependencies)

View File

@@ -0,0 +1 @@
version = '1.1.0'

View File

@@ -0,0 +1,9 @@
with (import <nixpkgs> {});
let
buildGradle = callPackage ./gradle-env.nix {};
in
buildGradle {
envSpec = ./gradle-env.json;
src = ./.;
gradleFlags = [ "tasks" ];
}

View File

@@ -0,0 +1,456 @@
{
"": {
"name": "settings-buildscript",
"version": "1.1.0",
"path": "",
"gradle": {
"version": "5.0",
"type": "bin",
"url": "https://services.gradle.org/distributions/gradle-5.0-bin.zip",
"sha256": "6157ac9f3410bc63644625b3b3e9e96c963afd7910ae0697792db57813ee79a6",
"nativeVersion": "0.14"
},
"dependencies": {
"settings": [
{
"id": {
"group": "com.googlecode.javaewah",
"name": "JavaEWAH",
"version": "1.1.6",
"type": "jar",
"extension": "jar"
},
"name": "JavaEWAH-1.1.6.jar",
"path": "com/googlecode/javaewah/JavaEWAH/1.1.6",
"urls": [
"https://plugins.gradle.org/m2/com/googlecode/javaewah/JavaEWAH/1.1.6/JavaEWAH-1.1.6.jar"
],
"sha256": "f78d44a1e3877f1ce748b4a85df5171e5e8e9a5c3c6f63bb9003db6f84cce952"
},
{
"id": {
"group": "com.googlecode.javaewah",
"name": "JavaEWAH",
"version": "1.1.6",
"type": "pom",
"extension": "pom"
},
"name": "JavaEWAH-1.1.6.pom",
"path": "com/googlecode/javaewah/JavaEWAH/1.1.6",
"urls": [
"https://plugins.gradle.org/m2/com/googlecode/javaewah/JavaEWAH/1.1.6/JavaEWAH-1.1.6.pom"
],
"sha256": "7f4ff919b1ee17bf3776e058a3f20e6173db23a5e44cf2d107ec7570c186abf0"
},
{
"id": {
"group": "com.jcraft",
"name": "jsch",
"version": "0.1.54",
"type": "jar",
"extension": "jar"
},
"name": "jsch-0.1.54.jar",
"path": "com/jcraft/jsch/0.1.54",
"urls": [
"https://plugins.gradle.org/m2/com/jcraft/jsch/0.1.54/jsch-0.1.54.jar"
],
"sha256": "92eb273a3316762478fdd4fe03a0ce1842c56f496c9c12fe1235db80450e1fdb"
},
{
"id": {
"group": "com.jcraft",
"name": "jsch",
"version": "0.1.54",
"type": "pom",
"extension": "pom"
},
"name": "jsch-0.1.54.pom",
"path": "com/jcraft/jsch/0.1.54",
"urls": [
"https://plugins.gradle.org/m2/com/jcraft/jsch/0.1.54/jsch-0.1.54.pom"
],
"sha256": "ab8f512039be7f6ae20e18e743b4a9d8a20958494431917da58ae5aaef8a3478"
},
{
"id": {
"group": "commons-codec",
"name": "commons-codec",
"version": "1.6",
"type": "jar",
"extension": "jar"
},
"name": "commons-codec-1.6.jar",
"path": "commons-codec/commons-codec/1.6",
"urls": [
"https://plugins.gradle.org/m2/commons-codec/commons-codec/1.6/commons-codec-1.6.jar"
],
"sha256": "54b34e941b8e1414bd3e40d736efd3481772dc26db3296f6aa45cec9f6203d86"
},
{
"id": {
"group": "commons-codec",
"name": "commons-codec",
"version": "1.6",
"type": "pom",
"extension": "pom"
},
"name": "commons-codec-1.6.pom",
"path": "commons-codec/commons-codec/1.6",
"urls": [
"https://plugins.gradle.org/m2/commons-codec/commons-codec/1.6/commons-codec-1.6.pom"
],
"sha256": "a06e35d3fff3a6b813d94894ebf3e498f9540c864c5b39ae783907e3a6c72889"
},
{
"id": {
"group": "commons-logging",
"name": "commons-logging",
"version": "1.1.3",
"type": "jar",
"extension": "jar"
},
"name": "commons-logging-1.1.3.jar",
"path": "commons-logging/commons-logging/1.1.3",
"urls": [
"https://plugins.gradle.org/m2/commons-logging/commons-logging/1.1.3/commons-logging-1.1.3.jar"
],
"sha256": "70903f6fc82e9908c8da9f20443f61d90f0870a312642991fe8462a0b9391784"
},
{
"id": {
"group": "commons-logging",
"name": "commons-logging",
"version": "1.1.3",
"type": "pom",
"extension": "pom"
},
"name": "commons-logging-1.1.3.pom",
"path": "commons-logging/commons-logging/1.1.3",
"urls": [
"https://plugins.gradle.org/m2/commons-logging/commons-logging/1.1.3/commons-logging-1.1.3.pom"
],
"sha256": "3250ac3ac6bd60ed0631f5cd0335032b2993d63e405a6ae0555d27a7e4865849"
},
{
"id": {
"group": "gradle.plugin.net.vivin",
"name": "gradle-semantic-build-versioning",
"version": "4.0.0",
"type": "jar",
"extension": "jar"
},
"name": "gradle-semantic-build-versioning-4.0.0.jar",
"path": "gradle/plugin/net/vivin/gradle-semantic-build-versioning/4.0.0",
"urls": [
"https://plugins.gradle.org/m2/gradle/plugin/net/vivin/gradle-semantic-build-versioning/4.0.0/gradle-semantic-build-versioning-4.0.0.jar"
],
"sha256": "5138e67ce8e019437800b93c9f6f9d0fcbebefadc96fbc4ebc0975c99a261ef8"
},
{
"id": {
"group": "gradle.plugin.net.vivin",
"name": "gradle-semantic-build-versioning",
"version": "4.0.0",
"type": "pom",
"extension": "pom"
},
"name": "gradle-semantic-build-versioning-4.0.0.pom",
"path": "gradle/plugin/net/vivin/gradle-semantic-build-versioning/4.0.0",
"urls": [
"https://plugins.gradle.org/m2/gradle/plugin/net/vivin/gradle-semantic-build-versioning/4.0.0/gradle-semantic-build-versioning-4.0.0.pom"
],
"sha256": "4f2828741607ed102d95eb5f189d496c7840ed463acea89f1e51a60567714ef7"
},
{
"id": {
"group": "org.apache",
"name": "apache",
"version": "9",
"type": "pom",
"extension": "pom"
},
"name": "apache-9.pom",
"path": "org/apache/apache/9",
"urls": [
"https://plugins.gradle.org/m2/org/apache/apache/9/apache-9.pom"
],
"sha256": "4946e60a547c8eda69f3bc23c5b6f0dadcf8469ea49b1d1da7de34aecfcf18dd"
},
{
"id": {
"group": "org.apache",
"name": "apache",
"version": "13",
"type": "pom",
"extension": "pom"
},
"name": "apache-13.pom",
"path": "org/apache/apache/13",
"urls": [
"https://plugins.gradle.org/m2/org/apache/apache/13/apache-13.pom"
],
"sha256": "ff513db0361fd41237bef4784968bc15aae478d4ec0a9496f811072ccaf3841d"
},
{
"id": {
"group": "org.apache.commons",
"name": "commons-parent",
"version": "22",
"type": "pom",
"extension": "pom"
},
"name": "commons-parent-22.pom",
"path": "org/apache/commons/commons-parent/22",
"urls": [
"https://plugins.gradle.org/m2/org/apache/commons/commons-parent/22/commons-parent-22.pom"
],
"sha256": "fb8c5e55e30a7addb4ff210858a0e8d2494ed6757bbe19012da99d51586c3cbb"
},
{
"id": {
"group": "org.apache.commons",
"name": "commons-parent",
"version": "28",
"type": "pom",
"extension": "pom"
},
"name": "commons-parent-28.pom",
"path": "org/apache/commons/commons-parent/28",
"urls": [
"https://plugins.gradle.org/m2/org/apache/commons/commons-parent/28/commons-parent-28.pom"
],
"sha256": "14733a68e8b120b69de60cd96d222146dcf32f03c1c6cc6a750b1269bafe86c7"
},
{
"id": {
"group": "org.apache.httpcomponents",
"name": "httpclient",
"version": "4.3.6",
"type": "jar",
"extension": "jar"
},
"name": "httpclient-4.3.6.jar",
"path": "org/apache/httpcomponents/httpclient/4.3.6",
"urls": [
"https://plugins.gradle.org/m2/org/apache/httpcomponents/httpclient/4.3.6/httpclient-4.3.6.jar"
],
"sha256": "79838d9eaef73d4f852c63a480830c3a2d4b590f0ab3ae815a489463e4714004"
},
{
"id": {
"group": "org.apache.httpcomponents",
"name": "httpclient",
"version": "4.3.6",
"type": "pom",
"extension": "pom"
},
"name": "httpclient-4.3.6.pom",
"path": "org/apache/httpcomponents/httpclient/4.3.6",
"urls": [
"https://plugins.gradle.org/m2/org/apache/httpcomponents/httpclient/4.3.6/httpclient-4.3.6.pom"
],
"sha256": "d02634f6131e914961c02aa836711ebac72704b27e26c5bd223bbad89b1b64c3"
},
{
"id": {
"group": "org.apache.httpcomponents",
"name": "httpcomponents-client",
"version": "4.3.6",
"type": "pom",
"extension": "pom"
},
"name": "httpcomponents-client-4.3.6.pom",
"path": "org/apache/httpcomponents/httpcomponents-client/4.3.6",
"urls": [
"https://plugins.gradle.org/m2/org/apache/httpcomponents/httpcomponents-client/4.3.6/httpcomponents-client-4.3.6.pom"
],
"sha256": "4ada2827b496339826891c7c81dceba647029de6fc1888b16b3cab5650abcc63"
},
{
"id": {
"group": "org.apache.httpcomponents",
"name": "httpcomponents-core",
"version": "4.3.3",
"type": "pom",
"extension": "pom"
},
"name": "httpcomponents-core-4.3.3.pom",
"path": "org/apache/httpcomponents/httpcomponents-core/4.3.3",
"urls": [
"https://plugins.gradle.org/m2/org/apache/httpcomponents/httpcomponents-core/4.3.3/httpcomponents-core-4.3.3.pom"
],
"sha256": "c16e2fc0d49ba7a02cef5b5e2600585a9f673553328a6f9e58f24296df1dd031"
},
{
"id": {
"group": "org.apache.httpcomponents",
"name": "httpcore",
"version": "4.3.3",
"type": "jar",
"extension": "jar"
},
"name": "httpcore-4.3.3.jar",
"path": "org/apache/httpcomponents/httpcore/4.3.3",
"urls": [
"https://plugins.gradle.org/m2/org/apache/httpcomponents/httpcore/4.3.3/httpcore-4.3.3.jar"
],
"sha256": "5285de80af1651c489313b91a9f40c65a4cdcb6b3bde716fcc028d16869a5a93"
},
{
"id": {
"group": "org.apache.httpcomponents",
"name": "httpcore",
"version": "4.3.3",
"type": "pom",
"extension": "pom"
},
"name": "httpcore-4.3.3.pom",
"path": "org/apache/httpcomponents/httpcore/4.3.3",
"urls": [
"https://plugins.gradle.org/m2/org/apache/httpcomponents/httpcore/4.3.3/httpcore-4.3.3.pom"
],
"sha256": "b427f7cf67c75a4e3f9e2108d35bf45303573c145ec778fcadcffacef17a1264"
},
{
"id": {
"group": "org.apache.httpcomponents",
"name": "project",
"version": "7",
"type": "pom",
"extension": "pom"
},
"name": "project-7.pom",
"path": "org/apache/httpcomponents/project/7",
"urls": [
"https://plugins.gradle.org/m2/org/apache/httpcomponents/project/7/project-7.pom"
],
"sha256": "3d6eba428555a558de046b5d76eacc1f5a54b4f5f20b84d636ed7aff18aa48c3"
},
{
"id": {
"group": "org.eclipse.jgit",
"name": "org.eclipse.jgit",
"version": "4.8.0.201706111038-r",
"type": "jar",
"extension": "jar"
},
"name": "org.eclipse.jgit-4.8.0.201706111038-r.jar",
"path": "org/eclipse/jgit/org.eclipse.jgit/4.8.0.201706111038-r",
"urls": [
"https://plugins.gradle.org/m2/org/eclipse/jgit/org.eclipse.jgit/4.8.0.201706111038-r/org.eclipse.jgit-4.8.0.201706111038-r.jar"
],
"sha256": "49d912e8d5cce0dd08dca3d390189db8692a8f7e3363cdbbe182581462000aba"
},
{
"id": {
"group": "org.eclipse.jgit",
"name": "org.eclipse.jgit",
"version": "4.8.0.201706111038-r",
"type": "pom",
"extension": "pom"
},
"name": "org.eclipse.jgit-4.8.0.201706111038-r.pom",
"path": "org/eclipse/jgit/org.eclipse.jgit/4.8.0.201706111038-r",
"urls": [
"https://plugins.gradle.org/m2/org/eclipse/jgit/org.eclipse.jgit/4.8.0.201706111038-r/org.eclipse.jgit-4.8.0.201706111038-r.pom"
],
"sha256": "a556a9f5adfc6af49b2a12e72dc3cd7e43db8fdc216c0f35885972a2f5ada27d"
},
{
"id": {
"group": "org.eclipse.jgit",
"name": "org.eclipse.jgit-parent",
"version": "4.8.0.201706111038-r",
"type": "pom",
"extension": "pom"
},
"name": "org.eclipse.jgit-parent-4.8.0.201706111038-r.pom",
"path": "org/eclipse/jgit/org.eclipse.jgit-parent/4.8.0.201706111038-r",
"urls": [
"https://plugins.gradle.org/m2/org/eclipse/jgit/org.eclipse.jgit-parent/4.8.0.201706111038-r/org.eclipse.jgit-parent-4.8.0.201706111038-r.pom"
],
"sha256": "396a4cc894206873ff107d066a996252b0b47f585b88cf57fc3b31e93d492878"
},
{
"id": {
"group": "org.slf4j",
"name": "slf4j-api",
"version": "1.7.2",
"type": "jar",
"extension": "jar"
},
"name": "slf4j-api-1.7.2.jar",
"path": "org/slf4j/slf4j-api/1.7.2",
"urls": [
"https://plugins.gradle.org/m2/org/slf4j/slf4j-api/1.7.2/slf4j-api-1.7.2.jar"
],
"sha256": "3bae789b401333b2a1d1603b7fa573e19908628191707203f6eb708cdee2c052"
},
{
"id": {
"group": "org.slf4j",
"name": "slf4j-api",
"version": "1.7.2",
"type": "pom",
"extension": "pom"
},
"name": "slf4j-api-1.7.2.pom",
"path": "org/slf4j/slf4j-api/1.7.2",
"urls": [
"https://plugins.gradle.org/m2/org/slf4j/slf4j-api/1.7.2/slf4j-api-1.7.2.pom"
],
"sha256": "2eaca71afe0a1516f4abd8e9ff907838d268f38c81c3a542cce8d7f3b87c5d4c"
},
{
"id": {
"group": "org.slf4j",
"name": "slf4j-parent",
"version": "1.7.2",
"type": "pom",
"extension": "pom"
},
"name": "slf4j-parent-1.7.2.pom",
"path": "org/slf4j/slf4j-parent/1.7.2",
"urls": [
"https://plugins.gradle.org/m2/org/slf4j/slf4j-parent/1.7.2/slf4j-parent-1.7.2.pom"
],
"sha256": "1d8e084a6f2384ade42685332b52a0ece090478641dc14c0fa8c52e1e2984425"
},
{
"id": {
"group": "org.sonatype.oss",
"name": "oss-parent",
"version": "5",
"type": "pom",
"extension": "pom"
},
"name": "oss-parent-5.pom",
"path": "org/sonatype/oss/oss-parent/5",
"urls": [
"https://plugins.gradle.org/m2/org/sonatype/oss/oss-parent/5/oss-parent-5.pom"
],
"sha256": "1678d4120a585d8a630131aeec4c524d928398583b7eab616ee7d5a87f520d3d"
},
{
"id": {
"group": "org.sonatype.oss",
"name": "oss-parent",
"version": "6",
"type": "pom",
"extension": "pom"
},
"name": "oss-parent-6.pom",
"path": "org/sonatype/oss/oss-parent/6",
"urls": [
"https://plugins.gradle.org/m2/org/sonatype/oss/oss-parent/6/oss-parent-6.pom"
],
"sha256": "b4306d13e8f5392458a1b30866f1cff161b3d2e6999a88d059eea3932c8a8499"
}
],
"plugin": [],
"buildscript": [],
"project": []
}
}
}

View File

@@ -0,0 +1,318 @@
# This file is generated by gradle2nix.
#
# Example usage (e.g. in default.nix):
#
# with (import <nixpkgs> {});
# let
# buildGradle = callPackage ./gradle-env.nix {};
# in
# buildGradle {
# envSpec = ./gradle-env.json;
#
# src = ./.;
#
# gradleFlags = [ "installDist" ];
#
# installPhase = ''
# mkdir -p $out
# cp -r app/build/install/myproject $out
# '';
# }
{ stdenv, buildEnv, fetchurl, gradleGen, writeText, writeTextDir }:
{ envSpec
, pname ? null
, version ? null
, enableParallelBuilding ? true
, gradleFlags ? [ "build" ]
, gradlePackage ? null
, enableDebug ? false
, ... } @ args:
let
inherit (builtins)
attrValues concatStringsSep filter fromJSON match replaceStrings sort;
inherit (stdenv.lib)
assertMsg concatMapStringsSep groupBy' hasSuffix last mapAttrs
mapAttrsToList optionalString readFile removeSuffix unique versionAtLeast
versionOlder;
mkDep = depSpec: stdenv.mkDerivation {
inherit (depSpec) name;
src = fetchurl {
inherit (depSpec) urls sha256;
};
phases = "installPhase";
installPhase = ''
mkdir -p $out/${depSpec.path}
ln -s $src $out/${depSpec.path}/${depSpec.name}
'';
};
mkModuleMetadata = deps:
let
ids = filter
(id: id.type == "pom")
(map (dep: dep.id) deps);
modules = groupBy'
(meta: id:
let
isNewer = versionOlder meta.latest id.version;
isNewerRelease =
!(hasSuffix "-SNAPSHOT" id.version) &&
versionOlder meta.release id.version;
in {
groupId = id.group;
artifactId = id.name;
latest = if isNewer then id.version else meta.latest;
release = if isNewerRelease then id.version else meta.release;
versions = meta.versions ++ [id.version];
}
)
{
latest = "";
release = "";
versions = [];
}
(id: "${replaceStrings ["."] ["/"] id.group}/${id.name}/maven-metadata.xml")
ids;
in
attrValues (mapAttrs (path: meta:
let
versions' = sort versionOlder (unique meta.versions);
in
with meta; writeTextDir path ''
<?xml version="1.0" encoding="UTF-8"?>
<metadata modelVersion="1.1">
<groupId>${groupId}</groupId>
<artifactId>${artifactId}</artifactId>
<versioning>
${optionalString (latest != "") "<latest>${latest}</latest>"}
${optionalString (release != "") "<release>${release}</release>"}
<versions>
${concatMapStringsSep "\n " (v: "<version>${v}</version>") versions'}
</versions>
</versioning>
</metadata>
''
) modules);
mkSnapshotMetadata = deps:
let
snapshotDeps = filter (dep: dep ? build && dep ? timestamp) deps;
modules = groupBy'
(meta: dep:
let
id = dep.id;
isNewer = dep.build > meta.buildNumber;
# Timestamp values can be bogus, e.g. jitpack.io
updated = if (match "[0-9]{8}\.[0-9]{6}" dep.timestamp) != null
then replaceStrings ["."] [""] dep.timestamp
else "";
in {
groupId = id.group;
artifactId = id.name;
version = id.version;
timestamp = if isNewer then dep.timestamp else meta.timestamp;
buildNumber = if isNewer then dep.build else meta.buildNumber;
lastUpdated = if isNewer then updated else meta.lastUpdated;
versions = meta.versions or [] ++ [{
classifier = id.classifier or "";
extension = id.extension;
value = "${removeSuffix "-SNAPSHOT" id.version}-${dep.timestamp}-${toString dep.build}";
updated = updated;
}];
}
)
{
timestamp = "";
buildNumber = -1;
lastUpdated = "";
}
(dep: "${replaceStrings ["."] ["/"] dep.id.group}/${dep.id.name}/${dep.id.version}/maven-metadata.xml")
snapshotDeps;
mkSnapshotVersion = version: ''
<snapshotVersion>
${optionalString (version.classifier != "") "<classifier>${version.classifier}</classifier>"}
<extension>${version.extension}</extension>
<value>${version.value}</value>
${optionalString (version.updated != "") "<updated>${version.updated}</updated>"}
</snapshotVersion>
'';
in
attrValues (mapAttrs (path: meta:
with meta; writeTextDir path ''
<?xml version="1.0" encoding="UTF-8"?>
<metadata modelVersion="1.1">
<groupId>${groupId}</groupId>
<artifactId>${artifactId}</artifactId>
<version>${version}</version>
<versioning>
<snapshot>
${optionalString (timestamp != "") "<timestamp>${timestamp}</timestamp>"}
${optionalString (buildNumber != -1) "<buildNumber>${toString buildNumber}</buildNumber>"}
</snapshot>
${optionalString (lastUpdated != "") "<lastUpdated>${lastUpdated}</lastUpdated>"}
<snapshotVersions>
${concatMapStringsSep "\n " mkSnapshotVersion versions}
</snapshotVersions>
</versioning>
</metadata>
''
) modules);
mkRepo = project: type: deps: buildEnv {
name = "${project}-gradle-${type}-env";
paths = map mkDep deps ++ mkModuleMetadata deps ++ mkSnapshotMetadata deps;
};
mkInitScript = projectSpec: gradle:
let
repos = mapAttrs (mkRepo projectSpec.name) projectSpec.dependencies;
hasDependencies = mapAttrs (type: deps: deps != []) projectSpec.dependencies;
in
assert (assertMsg (hasDependencies.settings -> versionAtLeast gradle.version "6.0") ''
Project `${projectSpec.name}' has settings script dependencies, such as settings
plugins, which are not supported by gradle2nix for Gradle versions prior to 6.0.
Potential remedies:
- Pass `--gradle-version=<version>' to the gradle2nix command.
- Patch the `settings.gradle[.kts]' file to remove script dependencies.
'');
writeText "init.gradle" ''
static def offlineRepo(RepositoryHandler repositories, String env, String path) {
repositories.clear()
repositories.maven {
name "Nix''${env.capitalize()}MavenOffline"
url path
metadataSources {
it.gradleMetadata()
it.mavenPom()
it.artifact()
}
}
repositories.ivy {
name "Nix''${env.capitalize()}IvyOffline"
url path
layout "maven"
metadataSources {
it.gradleMetadata()
it.ivyDescriptor()
it.artifact()
}
}
}
${optionalString (hasDependencies.settings && (versionAtLeast gradle.version "6.0")) ''
gradle.beforeSettings {
offlineRepo(it.buildscript.repositories, "settings", "${repos.settings}")
}
''}
${optionalString (hasDependencies.plugin) ''
gradle.settingsEvaluated {
offlineRepo(it.pluginManagement.repositories, "plugin", "${repos.plugin}")
}
''}
${optionalString (hasDependencies.buildscript) ''
gradle.projectsLoaded {
allprojects {
buildscript {
offlineRepo(repositories, "buildscript", "${repos.buildscript}")
}
}
}
''}
${optionalString (hasDependencies.project) ''
gradle.projectsLoaded {
allprojects {
offlineRepo(repositories, "project", "${repos.project}")
}
}
''}
'';
mkGradle = gradleSpec:
gradleGen.gradleGen {
inherit (gradleSpec) nativeVersion;
name = "gradle-${gradleSpec.version}-${gradleSpec.type}";
src = fetchurl {
inherit (gradleSpec) url sha256;
};
} // {
inherit (gradleSpec) version;
};
mkProjectEnv = projectSpec: rec {
inherit (projectSpec) name path version;
gradle = args.gradlePackage or mkGradle projectSpec.gradle;
initScript = mkInitScript projectSpec gradle;
};
gradleEnv = mapAttrs
(_: p: mkProjectEnv p)
(fromJSON (readFile envSpec));
projectEnv = gradleEnv."";
pname = args.pname or projectEnv.name;
version = args.version or projectEnv.version;
buildProject = env: flags: ''
gradle --offline --no-daemon --no-build-cache \
--info --full-stacktrace --warning-mode=all \
${optionalString enableParallelBuilding "--parallel"} \
${optionalString enableDebug "-Dorg.gradle.debug=true"} \
--init-script ${env.initScript} \
${optionalString (env.path != "") ''-p "${env.path}"''} \
${concatStringsSep " " flags}
'';
buildIncludedProjects =
concatStringsSep "\n" (mapAttrsToList
(_: env: buildProject env [ "build" ])
(removeAttrs gradleEnv [ "" ]));
buildRootProject = buildProject projectEnv gradleFlags;
in stdenv.mkDerivation (args // {
inherit pname version;
nativeBuildInputs = (args.nativeBuildInputs or []) ++ [ projectEnv.gradle ];
buildPhase = args.buildPhase or ''
runHook preBuild
(
set -x
# use the init script here
TMPHOME=$(mktemp -d)
mkdir -p $TMPHOME/init.d
cp ${projectEnv.initScript} $TMPHOME/init.d
export "GRADLE_USER_HOME=$TMPHOME"
${buildIncludedProjects}
${buildRootProject}
)
runHook postBuild
'';
dontStrip = true;
})

View File

@@ -0,0 +1 @@
startingVersion = '1.0.0'

View File

@@ -0,0 +1,14 @@
buildscript {
repositories {
maven {
url 'https://plugins.gradle.org/m2/'
}
}
dependencies {
classpath 'gradle.plugin.net.vivin:gradle-semantic-build-versioning:4.0.0'
}
}
rootProject.name = "settings-buildscript"
//apply plugin: 'net.vivin.gradle-semantic-build-versioning'

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.apache</groupId>
<artifactId>test</artifactId>
<version>1.0.0</version>
<name>test</name>
<description>
test
</description>
</project>

View File

@@ -1 +0,0 @@
6eb7552156e0d517ae80cc2247be1427c8d90452

View File

@@ -1 +0,0 @@
9797702ee3e52e4be6bfbbc9fd20ac5447e7a541

View File

@@ -0,0 +1,10 @@
buildscript {
repositories {
maven {
url 'http://localhost:9999/'
}
}
dependencies {
classpath 'org.apache:test:1.0.0'
}
}

View File

@@ -8,12 +8,14 @@ import java.lang.IllegalArgumentException
@JsonClass(generateAdapter = true)
data class DefaultBuild(
override val gradle: DefaultGradle,
override val settingsDependencies: List<DefaultArtifact>,
override val pluginDependencies: List<DefaultArtifact>,
override val rootProject: DefaultProject,
override val includedBuilds: List<DefaultIncludedBuild>
) : Build, Serializable {
constructor(model: Build) : this(
DefaultGradle(model.gradle),
model.settingsDependencies.map(::DefaultArtifact),
model.pluginDependencies.map(::DefaultArtifact),
DefaultProject(model.rootProject),
model.includedBuilds.map(::DefaultIncludedBuild)

View File

@@ -2,6 +2,7 @@ package org.nixos.gradle2nix
interface Build {
val gradle: Gradle
val settingsDependencies: List<Artifact>
val pluginDependencies: List<Artifact>
val rootProject: Project
val includedBuilds: List<IncludedBuild>

View File

@@ -1,10 +1,13 @@
package org.nixos.gradle2nix
import dev.minutest.Tests
import dev.minutest.experimental.FOCUS
import dev.minutest.experimental.minus
import dev.minutest.junit.JUnit5Minutests
import dev.minutest.rootContext
import strikt.api.expectThat
import strikt.assertions.contains
import strikt.assertions.containsExactly
class PluginTest : JUnit5Minutests {
@Tests

View File

@@ -0,0 +1,26 @@
package org.nixos.gradle2nix
import dev.minutest.Tests
import dev.minutest.junit.JUnit5Minutests
import dev.minutest.rootContext
import strikt.api.expectThat
import strikt.assertions.containsExactly
class SettingsTest : JUnit5Minutests {
@Tests
fun tests() = rootContext("settings tests") {
withRepository("m2") {
withFixture("settings/buildscript") {
test("resolves settings plugin in buildscript classpath") {
expectThat(build()) {
get("settings dependencies") { settingsDependencies }.ids
.containsExactly(
"org.apache:test:1.0.0@jar",
"org.apache:test:1.0.0@pom"
)
}
}
}
}
}
}

View File

@@ -168,29 +168,27 @@ fun ContextBuilder<*>.withRepository(
fun ContextBuilder<*>.withFixture(
name: String,
block: TestContextBuilder<*, ProjectFixture>.() -> Unit
) {
derivedContext<TestFixture>(name) {
val url = checkNotNull(Thread.currentThread().contextClassLoader.getResource(name)?.toURI()) {
"$name: No test fixture found"
}
val fixtureRoot = Paths.get(url).toFile().absoluteFile
) = derivedContext<TestFixture>(name) {
val url = checkNotNull(Thread.currentThread().contextClassLoader.getResource(name)?.toURI()) {
"$name: No test fixture found"
}
val fixtureRoot = Paths.get(url).toFile().absoluteFile
deriveFixture {
TestFixture(name, fixtureRoot)
}
deriveFixture {
TestFixture(name, fixtureRoot)
}
val testRoots = fixtureRoot.listFiles()!!
.filter { it.isDirectory }
.map { it.absoluteFile }
.toList()
val testRoots = fixtureRoot.listFiles()!!
.filter { it.isDirectory }
.map { it.absoluteFile }
.toList()
testRoots.forEach { testRoot ->
derivedContext<ProjectFixture>(testRoot.name) {
deriveFixture { ProjectFixture(this, testRoot) }
before { copy() }
after { close() }
block()
}
testRoots.forEach { testRoot ->
derivedContext<ProjectFixture>(testRoot.name) {
deriveFixture { ProjectFixture(this, testRoot) }
before { copy() }
after { close() }
block()
}
}
}

View File

@@ -28,7 +28,8 @@ import org.gradle.util.GradleVersion
enum class ConfigurationScope {
BUILDSCRIPT,
PLUGIN,
PROJECT
PROJECT,
SETTINGS
}
internal class ConfigurationResolverFactory(

View File

@@ -6,6 +6,7 @@ import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.ProjectDependency
import org.gradle.api.internal.GradleInternal
import org.gradle.api.invocation.Gradle
import org.gradle.api.tasks.TaskContainer
import org.gradle.api.tasks.wrapper.Wrapper
@@ -85,6 +86,7 @@ private fun Project.buildModel(
modelProperties: ModelProperties,
pluginRequests: List<PluginRequest>
): DefaultBuild {
val settingsDependencies = settingsDependencies()
val plugins = buildPlugins(pluginRequests)
val subprojects = if (modelProperties.subprojects.isEmpty()) {
@@ -99,6 +101,7 @@ private fun Project.buildModel(
return DefaultBuild(
gradle = buildGradle(),
settingsDependencies = settingsDependencies,
pluginDependencies = plugins,
rootProject = buildProject(modelProperties.configurations, subprojects, plugins),
includedBuilds = includedBuilds()
@@ -126,6 +129,31 @@ private fun Project.buildGradle(): DefaultGradle =
)
}
private fun Project.settingsDependencies(): List<DefaultArtifact> {
val buildscript = (gradle as GradleInternal).settings.buildscript
val resolverFactory = ConfigurationResolverFactory(this, ConfigurationScope.SETTINGS, buildscript.repositories)
val resolver = resolverFactory.create(buildscript.dependencies)
logger.lifecycle(" Settings script")
val dependencies = buildscript.configurations
.flatMap(resolver::resolve)
.distinct()
.sorted()
if (resolver.unresolved.isNotEmpty()) {
logger.warn(buildString {
append(" Failed to resolve settings script dependencies:\n")
for (id in resolver.unresolved) {
append(" - $id\n")
}
})
}
return dependencies
}
private fun Project.buildPlugins(pluginRequests: List<PluginRequest>): List<DefaultArtifact> {
return objects.newInstance<PluginResolver>(this).resolve(pluginRequests).distinct().sorted()
}