Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
;; this is src/myproject/boot_build.clj
(ns myproject.boot-build
(:require [boot.core :as core]
[cemerick.pomegranate.aether :as aether]
[boot.util :as util]
[boot.pod :as pod]
[clojure.java.io :as io]
[clojure.string :as str]
[cheshire.core :as json]
[boot.task.built-in :as task])
(:import [java.io BufferedInputStream]))
(defn sha256-stream [stream]
(let [buffer (byte-array 8192)
digest (java.security.MessageDigest/getInstance "SHA-256")
bstream (BufferedInputStream. stream)]
(loop []
(let [count (.read bstream buffer)]
(when (> count 0)
(.update digest buffer 0 count)
(recur))))
(apply str (map #(format "%02x" %)
(.digest digest)))))
(def sha256-file (comp sha256-stream io/input-stream))
(defn path-for-artifact [artifact]
(str
(str/replace (:groupId artifact) "." "/")
"/"
(:artifactId artifact)
"/"
(if (:snapshot artifact) (:baseVersion artifact) (:version artifact))
"/"
(:artifactId artifact)
"-"
(:version artifact)
(let [c (:classifier artifact)]
(if-not (empty? c) (str "-" c)))
"."
(:extension artifact)))
(defn map->coordinates [m]
(into
[(symbol (:groupId m) (:artifactId m))
(:version m)]
(mapcat identity (dissoc m :groupId :artifactId :properties
:file :class :version))))
(defn nix-attributes-for-artifact [m]
{:coordinates (map->coordinates m)
:relativePathname (path-for-artifact m)
:sha256 (sha256-file (:file m))})
(defn ensure-trailing-slash [s]
(if (str/ends-with? s "/") s (str s "/")))
(core/deftask nixdump
"dump nix info"
[f file PATH str "filename to dump to"]
(core/with-pass-thru [_]
(let [file-out (io/writer (if (= file "-") (System/out) file))]
(assert file "Expected --file option.")
(let [all-deps (-> (aether/resolve-dependencies
:repositories (:repositories pod/env)
:coordinates (:dependencies pod/env))
keys)
artifacts (map (comp nix-attributes-for-artifact
bean
(memfn getArtifact)
:dependency
meta) all-deps)]
(json/generate-stream
{:0NOTICE "Automatically generated by 'boot nixdump', do not edit"
:artifacts artifacts
:repositories (map (comp ensure-trailing-slash
:url
second)
(:repositories pod/env))}
file-out
{:pretty true}
)))))
;; for the avoidance of doubt, this is not a complete boot.build file. It's
;; some extra stuff you will probably want/need to merge into your already-
;; functional build.boot file
(set-env!
:dependencies '[
;; ...
[com.cemerick/pomegranate "0.3.1"]])
(require '[myproject.boot-build :refer :all])
with import <nixpkgs> {};
let sourceFilesOnly = path: type:
!((baseNameOf path == "var") ||
(baseNameOf path == "target"));
depSpecs = builtins.fromJSON (builtins.readFile ./app/dependencies.json);
mapJars = builtins.foldl'
(m: a: m // builtins.listToAttrs
[(lib.attrsets.nameValuePair
(builtins.head a.coordinates)
( a // { storePath = fetchurl {
urls = map (r: lib.concatStrings [r a.relativePathname])
depSpecs.repositories;
sha256 = a.sha256;
};
}) )])
{}
depSpecs.artifacts;
jarPaths = map (a: a.storePath) (builtins.attrValues mapJars);
in rec {
jar = stdenv.mkDerivation rec {
CLASSPATH = (lib.concatStrings (lib.intersperse ":" jarPaths));
name = "bookshlv";
srcs = builtins.filterSource sourceFilesOnly ./app;
buildInputs = [ openjdk makeWrapper ];
builder = writeScript "${name}-builder.sh" ''
source $stdenv/setup
cd $srcs
builddir=$TMP/tmp_install
res=$builddir/myproject/resources
mkdir -p $res
java -cp src:$builddir:$CLASSPATH clojure.main \
-e '(require (quote cljs.build.api))' \
-e "(cljs.build.api/build \"cljs-src\" {:main (quote myproject.core) :optimizations :whitespace :output-dir \"$builddir\" :output-to \"$res/public/frontend.js\"})"
java -cp src:${CLASSPATH}:$builddir -Dclojure.compile.path=$builddir clojure.lang.Compile myproject.core
cp -arv resources/myproject/resources/* $res
mkdir -p $out/share/java
(cd $builddir && jar -cvfe $out/share/java/$name.jar myproject.core .)
mkdir -p $out/bin
makeWrapper ${jre_headless}/bin/java $out/bin/$name \
--add-flags "-cp ${CLASSPATH}:$out/share/java/$name.jar" \
--add-flags "myproject.core"
'';
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment