From 1a8238cf916619b83f9f6f330a7d632bba96e38b Mon Sep 17 00:00:00 2001 From: niten Date: Sun, 29 May 2022 09:34:32 -0700 Subject: [PATCH] Switch to mkClojureLib --- build-uberjar.sh | 6 +++ flake.nix | 17 +++----- mkClojureLib.nix | 58 ++++++++++++++++++++++++++ resources/build-uberjar.rb | 85 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 154 insertions(+), 12 deletions(-) create mode 100644 build-uberjar.sh create mode 100644 mkClojureLib.nix create mode 100644 resources/build-uberjar.rb diff --git a/build-uberjar.sh b/build-uberjar.sh new file mode 100644 index 0000000..a2a79ff --- /dev/null +++ b/build-uberjar.sh @@ -0,0 +1,6 @@ +TARGET=$1 +CLASSPATH=$2 + +HOME=$TARGET/home +mkdir -p $HOME +clojure -Scp $CLASSPATH -Sdeps ${FIXME} -T:build lib-uberjar :project $PROJECT :target $TARGET :version $VERSION diff --git a/flake.nix b/flake.nix index eb8823d..d7c1fc0 100644 --- a/flake.nix +++ b/flake.nix @@ -19,7 +19,7 @@ utils.lib.eachDefaultSystem (system: let pkgs = nixpkgs.legacyPackages."${system}"; - clojure-build-tools = pkgs.callPackage ./build.tools.nix { + build-tools-jar = pkgs.callPackage ./build.tools.nix { inherit build-tools-src; inherit (gitignore.lib) gitignoreSource; }; @@ -27,17 +27,10 @@ inherit build-tools-src; inherit clj2nix; }; + mkClojureLib = + pkgs.callPackage ./mkClojureLib.nix { inherit build-tools-jar; }; in { - packages = utils.lib.flattenTree { inherit clojure-build-tools; }; - defaultPackage = self.packages."${system}".clojure-build-tools; - overlay = final: prev: { inherit clojure-build-tools; }; - devShell = pkgs.mkShell { - buildInputs = with pkgs; [ - clojure - jre - clj2nix.packages."${system}".clj2nix - update-deps - ]; - }; + packages = utils.lib.flattenTree { inherit mkClojureLib; }; + overlay = final: prev: { inherit mkClojureLib; }; }); } diff --git a/mkClojureLib.nix b/mkClojureLib.nix new file mode 100644 index 0000000..bd28956 --- /dev/null +++ b/mkClojureLib.nix @@ -0,0 +1,58 @@ +{ lib, mkDerivation, callPackage, jre, ruby, clojure, build-tools-jar +, writeScript, writeText, readFile, ... }: +{ src, name, group, version, clj-deps, src-paths, ... }: + +with lib; +let + build-tools-deps = writeText "deps.edn" '' + { :aliases + { :build + { :ns-default build + :replace-deps { + io.github.clojure/tools.build { + :local/root "${build-tools-jar}" + } + } + } + } + } + ''; + + deps = callPackage clj-deps { }; + classpath = clj-deps.makeClasspaths { }; + + uberjar-script = writeScript "uberjar-builder.rb" '' + ${ruby}/bin/ruby + ${readFile ./resources/uberjar-builder.rb} + ''; + + full-name = "${group}-${name}-${version}-standalone.jar"; + + target = "$TEMP/target"; + +in mkDerivation { + name = name; + + src = src; + + nativeBuildInputs = [ jre ]; + buildInputs = [ build-tools-jar ] ++ (map (x: x.paths) deps.packages); + + buildPhase = '' + HOME=$TEMP/home + mkdir -p $HOME + mkdir -p ${target} + ${uberjar-script} + --root=$PWD \ + --classpath=${classpath} \ + --target=${target} \ + --project=${group}/${name} \ + --version=${version} \ + --build-deps=${built-tools-deps} \ + --source-paths=${concatStringsSep "," src-paths} + ''; + + installPhase = '' + mv ${target}/${name}-${version}-standalone.jar $out + ''; +} diff --git a/resources/build-uberjar.rb b/resources/build-uberjar.rb new file mode 100644 index 0000000..0b4ad96 --- /dev/null +++ b/resources/build-uberjar.rb @@ -0,0 +1,85 @@ +require 'optparse' + +options = {} + +def ensure_key!(m, k) + if not m.has_key?(k) + ks = m.keys.map { |k| k.to_s }.join(",") + raise ArgumentError.new("Required key not set: #{k} (keys: #{ks})") + end +end + +OptionParser.new do |opts| + opts.on("-c", "--classpath=PATH", + "Classpath to pass to clojure.") { |cp| + options[:classpath] = cp + } + + opts.on("-t", "--target=TARGET", + "Directory at which to perform the build.") { |target| + options[:target] = target + } + + opts.on("-p", "--project=PROJECT", + "Name of the project being built (eg. org.clojure/build.tools).") { |project| + options[:project] = project + } + + opts.on("-v", "--version=VERS", + "Version of the project being built (eg. 1.0.2).") { |vers| + options[:version] = vers + } + + opts.on("-e", "--build-deps=PATH", + "Location of the build deps.edn, for build-specific dependencies.") { |deps| + options[:build_deps] = deps + } + + opts.on("-r", "--root=PATH", + "Root of the build project, containing deps.edn.") { |path| + options[:root] = path + } + + opts.on("-s", "--source-paths=PATHS", + "Location of the Clojure project to be built.") { |paths| + options[:sources] = paths.split(",") + } +end.parse! + +[:classpath, :target, :project, :build_deps, :sources, :root, :version].each { |k| + ensure_key!(options, k) +} + +target = options[:target] +if not (File::directory?(target) and File::writable?(target)) + raise ArgumentError.new("Not a valid build target directory: #{target}") +end + +options[:sources].each { |path| + raise ArgumentError.new("Not a valid source path: #{path}") if not (File::directory? path) +} + +if not File::exists? "#{options[:root]}/deps.edn" + raise ArgumentError.new("Does not appear to be project root directory: #{options[:root]}") +end + +if not File::exists? "#{options[:build_deps]}" + raise ArgumentError.new("Build deps.edn not found: #{options[:build_deps]}") +end + +command = [ + "clojure", + "-Scp #{options[:classpath]}", + "-Sdeps #{options[:build_deps]}", + "-T:build", + "lib-uberjar", + ":project #{options[:project]}", + ":target #{options[:target]}", + ":version #{options[:version]}", + ":srcs #{options[:sources]}" +].join(" ") + +Dir::chdir(options[:root]) do + output = `#{command}` + puts output +end