A clojure build tool, based on nix
Switch branches/tags
Nothing to show
Clone or download
Latest commit 145b8ef Dec 3, 2018
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
deps.aether Likewise for commented/manual-invocation dep generation Dec 3, 2018
deps.expander version updates Feb 2, 2018
example/leiningen Document custom maven repositories Dec 3, 2018
lein.reader make lein.reader emit main ns Feb 2, 2018
nix.aether/src [WIP] update and cleanup Oct 13, 2017
nix.data/src/webnf/nix nix-data: implement boolean emit Jan 9, 2018
nrepl-cmp/webnf/dwn artifact descriptor May 3, 2017
scripts nix 2.0 Dec 3, 2018
src have fromLein tage arguments Feb 2, 2018
.gitignore wip Oct 3, 2016
0001-prepare-for-hardcoded-sopath.patch fix juds builder Jan 10, 2017
README.md Document custom maven repositories Dec 3, 2018
build-clojure.nix update clojure and juds Dec 3, 2018
call-package.nix add `dwn` tool Feb 2, 2018
clojure.repo.edn update clojure and juds Dec 3, 2018
compile-gte-mtime.patch proper incremental compile for plugins May 23, 2017
config.edn.nix [WIP] config language rework Nov 17, 2016
config.nix [WIP] component config Mar 9, 2017
default-config.nix major rework, declarative config Oct 14, 2016
default-old.nix restore default.nix, add systemd runner Mar 11, 2017
default.nix move clojure.nix -> default.nix Jan 30, 2018
dwn-next.nix [WIP] Oct 16, 2017
dwn-tool.nix update clojure and juds Dec 3, 2018
dwn.repo.edn Merge branch 'patch' into webnf/dwn/master Dec 3, 2018
gen-repo.sh leiningen reader update Jan 7, 2018
install-systemd restore default.nix, add systemd runner Mar 11, 2017
juds.nix update clojure and juds Dec 3, 2018
module.nix [WIP] config language rework Nov 17, 2016
nrepl-project.nix [WIP] update and cleanup Oct 13, 2017
nrepl.repo.edn [WIP] update and cleanup Oct 13, 2017
packages.nix update clojure and juds Dec 3, 2018
project.clj Move to a modern release of Aether (renamed Maven Resolver) Dec 3, 2018
project.nix update clojure and juds Dec 3, 2018
shell.nix clean up usage of devMode Jan 9, 2018
start.sh.in launcher for clojure components via a socket Feb 14, 2016
update-repos add `dwn` tool Feb 2, 2018
util-instantiated.nix updates and new utils Feb 15, 2016
util.nix Fixes and rename listClasspath -> listClassPath Mar 12, 2016

README.md

DWN -- A Clojure launcher via Nix(OS)

Installation

Nix

For now, you need the Nix package manager installed. This is most easily done by

curl https://nixos.org/nix/install | sh

Installing from checkout

There is rudimentary command line tooling, in the form of a dwn command. You can build it with:

nix-build shell.nix -A dwnTool

Install it to your user profile with:

nix-env -i ./result

Now, the dwn command should be in your $PATH.

Usage

You need a project.nix file. Most easily, this can be written by delegating to a Leiningen project:

{ fromLein }:
fromLein ./project.clj {
  devMode = false;
  closureRepo = ./project.repo.edn;
}

You can try the following commands with the example/leiningen project.

With the project.nix file in place, you need to generate a repository file for the project. That file holds all the sha1s for you dependency artifacts, similar to a php-composer lockfile. This command generates the repo file in project.repo.edn, which is meant to be checked in:

dwn gen-repo ./project.nix

After having generated the repo file, you can build the project:

dwn build ./project.nix

This generates ./result with a classpath for your project, along with shell launchers for your main namespaces.

It is idiomatic, to run your project like this:

$(dwn build ./project.nix --no-out-link)/bin/main

That command will rebuild your project before running it, if changed.

Advanced usage

For lack of a leiningen descriptor, or if you need to do something that's not supported by the leiningen descriptor reader, you can override any option to dwn's native project descriptor. See src/nix/lib/make-project.nix. E.g. to use custom repositories:

{ fromLein, defaultMavenRepos }:
fromLein ./project.clj {
  devMode = false;
  closureRepo = ./project.repo.edn;
  mavenRepos = defaultMavenRepos ++ [ https://maven.repository.redhat.com/ga/ ];
}

Dev Notes

The entry path is shell.nix -> default.nix -> packages.nix

There is some interesting bootstrapping going on between deps.aether/default.nix and deps.expander/default.nix, but project.nix is already a fully formed project descriptor for the webnf.dwn runtime library.

Philosophy

Why?

Nix is a lazy, dynamically typed functional language, that is designed to produce immutable filesets via build recipes. It is also a package manager for software on Linux, OSX, Windows and Hurd. It lets you use all of that software to complete your build recipes and it has awesome ways for distributing the result of your own build recipes.

Clojure, on the other hand is a strict, dynamically typed functional language, that is designed to utilize immutability in application-level code. This means, that by using Nix, we can build a rock solid foundation to run clojure on, including options for spinning it up in the cloud, in containers or vms, via NixOS.

Clojure goes onto Nix, like jam onto bread. Or, as Alex Miller put it at EuroClojure '17: "They are cut from the same cloth".

Jam and bread do call for butter, though, i.e. tooling to bring out the flavor.

How?

Like Nix(OS), DWN isn't peanut butter. It isn't very opinionated. Instead, it's just plain butter, that underscores the the flavors, already there.

What?

DWN is tooling to:

  • generate a project.repo.edn file with checksums of maven artifacts, that can be committed to SCM
    • this contains the whole graph of muliple version per coordinate, discovered by the dependency crawler in deps.aether
  • use a custom, most-recent wins strategy, to always select newer versions from repo.edn, in order to build a classpath
    • in addition to most-recent-wins, this retains a partial ordering on the classpath, where a referrer would usually be able to override its dependents' resource paths (except when they are on the wrong side of a dependency cycle)
  • generate runners for your clojure code
    • shell launchers
    • systemd .service files (to be exposed via dwn)
    • edn descriptors, that can be started in webnf.dwn container within an existing java process (to be exposed via dwn)
  • compile namespaces to jvm byte code, before building the classpath
  • switch between dev mode, where generated artifacts would point into a working direcory vs. {dev false}, where everything is content-hashed into /nix/store.

Could?

  • DWN could be folded into a bin/dwn script + a .local/share/dwn state directory The script could mimic a more traditional dependency+build+distribution - tool, by tying together the existing functionality and thus be more readily accessible to UNIX users, while still providing the benefit of stable builds and a vast "standard library" for clojure.java.shell