mirror of
https://github.com/tadfisher/gradle2nix.git
synced 2026-01-12 07:50:53 -05:00
WIP
This commit is contained in:
345
gradle-env.nix
345
gradle-env.nix
@@ -25,6 +25,8 @@
|
||||
, fetchs3
|
||||
, fetchurl
|
||||
, gradleGen
|
||||
, runCommandLocal
|
||||
, symlinkJoin
|
||||
, writeText
|
||||
, writeTextDir
|
||||
}:
|
||||
@@ -32,7 +34,7 @@
|
||||
{
|
||||
# Path to the environment spec generated by gradle2nix (e.g. gradle-env.json).
|
||||
envSpec
|
||||
, pname ? null
|
||||
, pname ? "project"
|
||||
, version ? null
|
||||
, enableParallelBuilding ? true
|
||||
# Arguments to Gradle used to build the project in buildPhase.
|
||||
@@ -52,9 +54,10 @@
|
||||
# `{ urls, sha256 }` and fetch into the Nix store. For example:
|
||||
#
|
||||
# {
|
||||
# s3 = { urls, sha256 }: fetchs3 {
|
||||
# s3 = { name, urls, hash }: fetchs3 {
|
||||
# s3url = builtins.head urls;
|
||||
# inherit sha256;
|
||||
# # TODO This doesn't work without patching fetchs3 to accept SRI hashes
|
||||
# inherit name hash;
|
||||
# region = "us-west-2";
|
||||
# credentials = {
|
||||
# access_key_id = "foo";
|
||||
@@ -67,7 +70,7 @@
|
||||
|
||||
let
|
||||
inherit (builtins)
|
||||
attrValues concatStringsSep filter fromJSON getAttr head match
|
||||
attrValues concatStringsSep elemAt filter fromJSON getAttr head match
|
||||
replaceStrings sort;
|
||||
|
||||
inherit (lib)
|
||||
@@ -75,162 +78,185 @@ let
|
||||
mapAttrsToList optionalString readFile removeSuffix unique versionAtLeast
|
||||
versionOlder;
|
||||
|
||||
inherit (lib.strings) sanitizeDerivationName;
|
||||
|
||||
toCoordinates = id:
|
||||
let
|
||||
coords = builtins.split ":" id;
|
||||
in {
|
||||
group = elemAt coords 0;
|
||||
module = elemAt coords 2;
|
||||
};
|
||||
|
||||
fetchers' = {
|
||||
http = fetchurl;
|
||||
https = fetchurl;
|
||||
s3 = { urls, sha256 }: fetchs3 {
|
||||
s3url = head urls;
|
||||
inherit sha256;
|
||||
};
|
||||
} // fetchers;
|
||||
|
||||
# Fetch urls using the scheme for the first entry only; there isn't a
|
||||
# straightforward way to tell Nix to try multiple fetchers in turn
|
||||
# and short-circuit on the first successful fetch.
|
||||
fetch = { urls, sha256 }:
|
||||
fetch = _: { urls, hash }:
|
||||
let
|
||||
first = head urls;
|
||||
scheme = head (builtins.match "([a-z0-9+.-]+)://.*" first);
|
||||
fetch' = getAttr scheme fetchers';
|
||||
urls' = filter (hasPrefix scheme) urls;
|
||||
in
|
||||
fetch' { urls = urls'; inherit sha256; };
|
||||
fetch' { urls = urls'; inherit hash; };
|
||||
|
||||
mkDep = { name, path, urls, sha256, ... }: stdenv.mkDerivation {
|
||||
inherit name;
|
||||
|
||||
src = fetch {
|
||||
inherit urls sha256;
|
||||
};
|
||||
|
||||
phases = "installPhase";
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out/${path}
|
||||
ln -s $src $out/${path}/${name}
|
||||
'';
|
||||
};
|
||||
|
||||
mkModuleMetadata = deps:
|
||||
mkDep = id: version: artifacts:
|
||||
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;
|
||||
|
||||
coords = toCoordinates id;
|
||||
modulePath = "${replaceStrings ["."] ["/"] coords.group}/${coords.module}/${version}";
|
||||
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);
|
||||
stdenv.mkDerivation {
|
||||
pname = "${coords.group}-${coords.module}";
|
||||
version = version;
|
||||
|
||||
mkSnapshotMetadata = deps:
|
||||
let
|
||||
snapshotDeps = filter (dep: dep ? build && dep ? timestamp) deps;
|
||||
srcs = mapAttrsToList fetch artifacts;
|
||||
|
||||
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;
|
||||
dontPatch = true;
|
||||
dontConfigure = true;
|
||||
dontBuild = true;
|
||||
dontFixup = true;
|
||||
dontInstall = true;
|
||||
|
||||
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>
|
||||
'';
|
||||
preUnpack = ''
|
||||
mkdir -p "$out/${modulePath}"
|
||||
'';
|
||||
|
||||
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);
|
||||
unpackCmd = ''
|
||||
cp "$curSrc" "$out/${modulePath}/$(stripHash "$curSrc")"
|
||||
'';
|
||||
|
||||
mkRepo = project: type: deps: buildEnv {
|
||||
name = "${project}-gradle-${type}-env";
|
||||
paths = map mkDep deps ++ mkModuleMetadata deps ++ mkSnapshotMetadata deps;
|
||||
sourceRoot = ".";
|
||||
|
||||
preferLocalBuild = true;
|
||||
allowSubstitutes = false;
|
||||
};
|
||||
|
||||
mkModule = id: versions:
|
||||
mapAttrsToList (version: artifacts: mkDep id version artifacts) versions;
|
||||
|
||||
mkModuleMetadata = id: versions:
|
||||
let
|
||||
|
||||
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 = name: deps: symlinkJoin {
|
||||
name = "${name}-gradle-env";
|
||||
# paths = map mkDep deps ++ mkModuleMetadata deps ++ mkSnapshotMetadata deps;
|
||||
paths = mapAttrsToList mkModule deps;
|
||||
};
|
||||
|
||||
mkInitScript = projectSpec: gradle:
|
||||
@@ -264,12 +290,12 @@ let
|
||||
static def offlineRepo(RepositoryHandler repositories, String env, String path) {
|
||||
repositories.clear()
|
||||
repositories.maven {
|
||||
name "Nix''${env.capitalize()}MavenOffline"
|
||||
name "Nix''${env.capitalize()}Offline"
|
||||
url path
|
||||
metadataSources {
|
||||
it.gradleMetadata()
|
||||
it.mavenPom()
|
||||
it.artifact()
|
||||
it.
|
||||
}
|
||||
}
|
||||
repositories.ivy {
|
||||
@@ -279,7 +305,6 @@ let
|
||||
metadataSources {
|
||||
it.gradleMetadata()
|
||||
it.ivyDescriptor()
|
||||
it.artifact()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -371,29 +396,31 @@ let
|
||||
|
||||
buildRootProject = buildProject projectEnv gradleFlags;
|
||||
|
||||
in stdenv.mkDerivation (args // {
|
||||
# in stdenv.mkDerivation (args // {
|
||||
|
||||
inherit pname version;
|
||||
# inherit pname version;
|
||||
|
||||
nativeBuildInputs = (args.nativeBuildInputs or []) ++ [ projectEnv.gradle ];
|
||||
# nativeBuildInputs = (args.nativeBuildInputs or []) ++ [ projectEnv.gradle ];
|
||||
|
||||
buildPhase = args.buildPhase or ''
|
||||
runHook preBuild
|
||||
# buildPhase = args.buildPhase or ''
|
||||
# runHook preBuild
|
||||
|
||||
(
|
||||
set -eux
|
||||
# (
|
||||
# set -eux
|
||||
|
||||
# Work around https://github.com/gradle/gradle/issues/1055
|
||||
TMPHOME="$(mktemp -d)"
|
||||
mkdir -p "$TMPHOME/init.d"
|
||||
export GRADLE_USER_HOME="$TMPHOME"
|
||||
# # Work around https://github.com/gradle/gradle/issues/1055
|
||||
# TMPHOME="$(mktemp -d)"
|
||||
# mkdir -p "$TMPHOME/init.d"
|
||||
# export GRADLE_USER_HOME="$TMPHOME"
|
||||
|
||||
${buildIncludedProjects}
|
||||
${buildRootProject}
|
||||
)
|
||||
# ${buildIncludedProjects}
|
||||
# ${buildRootProject}
|
||||
# )
|
||||
|
||||
runHook postBuild
|
||||
'';
|
||||
# runHook postBuild
|
||||
# '';
|
||||
|
||||
dontStrip = true;
|
||||
})
|
||||
# dontStrip = true;
|
||||
# })
|
||||
|
||||
in mkRepo pname (fromJSON (readFile envSpec))
|
||||
|
||||
Reference in New Issue
Block a user