webnf / dwn

A clojure build tool, based on nix
17 stars 2 forks source link

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:

Could?