97 lines
2.6 KiB
Nix
97 lines
2.6 KiB
Nix
{ lib, stdenv, callPackage, clojure, jre, writeText, writeShellScript, toEDN }:
|
|
{ src, name, group, version, clj-deps, src-paths, ... }:
|
|
|
|
with lib;
|
|
let
|
|
classpath = clj-deps.makeClasspaths { };
|
|
deps-jars = splitString ":" classpath;
|
|
|
|
full-name = "${name}-${version}-standalone";
|
|
|
|
manifest = writeText "MANIFEST.MF" ''
|
|
Manifest-Version: 1.0
|
|
|
|
'';
|
|
|
|
extract-jar = jar: ''
|
|
echo jar -xf ${jar}
|
|
jar -xf ${jar}
|
|
'';
|
|
|
|
clj-compile = classpath: ns: ''
|
|
echo java -cp .:${classpath} clojure.main -e "(compile ${ns})"
|
|
java -cp .:${classpath} clojure.main -e "(compile ${ns})"
|
|
'';
|
|
|
|
matches-ext = ext: filename: (builtins.match ".+[.]${ext}$" filename) != null;
|
|
strip-ext = ext: filename:
|
|
builtins.head (builtins.match "(.+)[.]${ext}$" filename);
|
|
|
|
concatMapAttrs = f: attrs: concatLists (mapAttrsToList f attrs);
|
|
|
|
find-files = pred: path:
|
|
let
|
|
find-files-impl = base:
|
|
concatMapAttrs (handle-file base) (builtins.readDir base);
|
|
handle-file = base: name: type:
|
|
if (type == "directory") then
|
|
find-files-impl "${base}/${name}"
|
|
else
|
|
(if (pred name) then [ "${base}/${name}" ] else [ ]);
|
|
in find-files-impl path;
|
|
|
|
file-to-namespace = base: filename:
|
|
let
|
|
swap-chars = replaceStrings [ "_" "/" ] [ "-" "." ];
|
|
strip-clj = strip-ext "clj";
|
|
strip-base = replaceStrings [ "${base}/" ] [ "" ];
|
|
ns = swap-chars (strip-base (strip-clj (toString filename)));
|
|
in "'${ns}";
|
|
|
|
target-namespaces = concatMap (subdir:
|
|
let dir = src + "/${subdir}";
|
|
in map (file-to-namespace dir) (find-files (matches-ext "clj") dir))
|
|
src-paths;
|
|
|
|
copy-source-path = target: subdir: "cp -R ${src}/${subdir}/* ${target}";
|
|
|
|
build-script = let
|
|
join-lines = concatStringsSep "\n";
|
|
srcs = concatStringsSep ":" (map (path: "./${path}") src-paths);
|
|
in writeShellScript "create-${full-name}-uberjar.sh" ''
|
|
HOME=./home
|
|
mkdir $HOME
|
|
mkdir classes
|
|
|
|
mkdir ./deps
|
|
cd ./deps
|
|
${join-lines (map extract-jar deps-jars)}
|
|
cd ..
|
|
${join-lines
|
|
(map (clj-compile "${classpath}:${srcs}:./deps") target-namespaces)}
|
|
mkdir target
|
|
cp -R classes/* target/
|
|
${join-lines (map (copy-source-path "./target/") src-paths)}
|
|
cp -R deps/* target/
|
|
cp ./deps.edn ./target/deps.edn
|
|
cd target
|
|
jar cmf ${manifest} ../out.jar -C . ./*
|
|
'';
|
|
|
|
pthru = o: builtins.trace o o;
|
|
|
|
in stdenv.mkDerivation {
|
|
name = "${full-name}.jar";
|
|
|
|
src = src;
|
|
|
|
nativeBuildInputs = [ jre ];
|
|
buildInputs = map (x: x.paths) clj-deps.packages;
|
|
|
|
buildPhase = "${build-script}";
|
|
|
|
installPhase = ''
|
|
mv out.jar $out
|
|
'';
|
|
}
|