Scroll to navigation

dh-clojure-lein(7) Debhelper Clojure tools dh-clojure-lein(7)

NAME

dh-clojure-lein - Debhelper support for Leiningen projects

DESCRIPTION

Support for Leiningen projects consists of a Debhelper build system, available via the dh --buildsystem argument, and support for automatic and customizable adjustments to projects.

Currently under development, and should not be considered stable until (at least) the dh-clojure major version is no longer 0 and this notice changes.

USAGE

Buildsystem

The build system is designed to facilitate packaging Leiningen-based Clojure projects for Debian, and can be activated by passing the --buildsystem=leiningen option to dh:

 %:
    dh $@ --buildsystem=leiningen

It takes action during these debhelper stages:

Sets up a debian/dh-clojure/tmp/maven-repo symlink pointing to /usr/share/maven-repo for use by lein as a :local-repo.
Creates a debian/dh-clojure/tmp/pom.xml for use in the debian/PACKAGENAME.poms file (which it also creates), and it creates an unversioned symlink in target/ for the jar.
Calls helpers from the maven-repo-helper package to install the built jars into /usr/share/java and poms and jar symlinks in /usr/share/maven-repo and generate the ${maven:Depends} substitution variable.
Runs "lein test".
Runs "lein clean" and cleans up after the previous steps.

Project Adjustment (middleware)

The Leiningen project.clj will be adjusted by a middleware injected by the buildsystem (see above). By default, it will set all of the dependency versions in the project to "debian", excepting "org.clojure/clojure", which will be set to "1.x".

The project adjustments may be customized by code in an optional debian/dh-clojure-lein.clj file. That file may define an "dhclj-adjust-project" function which will receive a function that returns the leiningen project map, and must return that project map, after any adjusments.

For example, this

 (defn dhclj-adjust-project [project]
   (assoc (project) :version "1.x"))

changes the project version to "1.x", and of course "dissoc" can remove a map entry.

Note that all definition names starting with "dhclj-" are reserved by dh-clojure-lein.

In the project map passed to "dhclj-adjust-project" the values of the dependency-related entries ":dependencies", ":managed-dependencies", and ":plugins" are not dependency vectors (as in project.clj), but are in leiningen's dependency *map* format, which is more suitable for manipulation. For example

  [[org.clojure/clojure "42.x"]]

is represented as

  {{:group-id "org.clojure", :artifact-id "clojure"}
   {:artifact-id "clojure", :group-id "org.clojure", :version "42.x"}}

Though in most cases, this won't be important because the following client functions (defined in "debian.dh-clojure-lein.client") handle the common project manipulations (see the EXAMPLES section below):

(add-dep DEP-MAP DEP-SPEC)
Adds the dependency specified by DEP-SPEC (the dependency must not be present in the original project).
(del-dep DEP-MAP DEP-KEY)
Removes the dependency specified by DEP-KEY (the dependency must be present in the original project).
(set-dep DEP-MAP DEP-KEY FIELD VALUE)
Sets the specified FIELD (":version" or ":exclusions") of the dependency specified by DEP-VEC to the given value (the dependency must be present in the original project). Setting ":exclusions" to "nil" will remove all exclusions from the dependency.

A DEP-KEY is the subset of a lein project dependency vector that uniquely identifies a dependency, either a symbol like "org.clojure/tools.cli" or a a lein project dependency vector starting with that symbol, optionally followed by a ":classifier", and/or ":extension", for example "[org.clojure/tools.cli :classifier "test"]".

A DEP_SPECs is a lein project dependency vector with the exception that it may omit the version, for example "[org.clojure/tools.cli "1.x"]" or "[org.clojure/tools.cli :classifier "test"]".

Note that unless otherwise specified, the default value for all dependencies will be set to either "debian", or for "org.clojure/clojure", to "1.x".

Some adjustments should only apply when specific profiles are active, for example, removing a dependency in a test profile. The active profile(s) can be investigated via

(active-profiles PROJECT)
Returns a sequence of the active profiles like "(:base :system :user :provided :dev)". So to check whether the ":test" profile is active: "(some #{:test} (active-profiles PROJECT))".

Emacs clojure-mode and paredit (via elpa-clojure-mode and elpa-paredit in Debian) can be quite helpful if you're editing a lot of these files. They provide automatic indentation, highlighting, structural editing, etc.

EXAMPLES

Project adjustments

See the Clojure API <https://clojure.github.io/clojure/clojure.core-api.html#clojure.core> for documentation of specific calls like "assoc", "update", and "->".

Change the project version:

 (defn dhclj-adjust-project [project]
   (assoc (project) :version "11.x"))

Change the version and adjust dependencies:

 (require '[debian.dh-clojure-lein.client :as deb])
 (defn adjust-deps [deps]
   (-> deps
       (deb/add-dep '[w "1.x"])
       (deb/add-dep 'org.clojure/core.match)
       (deb/del-dep 'murphy)
       (deb/set-dep 'y :version "5.x")
       (deb/set-dep 'y :exclusions nil) ;; delete exclusions
       (deb/set-dep '[x/y :classifier "test"] :version "5.x")))
 (defn dhclj-adjust-project [project]
   (-> (project)
       (assoc :version "11.x")
       (update :dependencies adjust-deps)))

Equivalently:

 (require '[debian.dh-clojure-lein.client :as deb])
 (defn dhclj-adjust-project [project]
   (-> (project)
       (assoc :version "11.x")
       (update :dependencies deb/add-dep '[w "1.x"])
       (update :dependencies deb/add-dep 'org.clojure/core.match)
       (update :dependencies deb/del-dep 'murphy)
       (update :dependencies deb/set-dep 'y :version "5.x")
       (update :dependencies deb/set-dep '[x/y :classifier "test"] :version "5.x")))

Make profile-specific adjustments:

 (require '[debian.dh-clojure-lein.client :as deb])
 (defn adjust-deps [deps proj]
   (let [test? (some #{:test} (active-profiles proj)
         dev? (some #{:dev} (active-profiles proj)]
     (cond-> deps
       true (deb/add-dep '[w "1.x"])
       dev? (deb/add-dep 'a/b)
       test? (deb/del-dep 'murphy)
       true (deb/set-dep 'x :version "5.x")
       true (deb/set-dep '[x/y :classifier "test"] :version "5.x"))))
 (defn dhclj-adjust-project [project]
   (-> (project)
       (assoc :version "11.x")
       (update :dependencies adjust-deps)))

Equivalently:

 (require '[debian.dh-clojure-lein.client
            :refer [active-profiles add-dep set-dep]])
 (defn fix-shared [deps]
   (-> %
       (add-dep '[w "1.x"])
       (set-dep 'x :version "5.x")
       (set-dep '[x/y :classifier "test"] :version "5.x")))
 (defn adjust-deps [deps proj]
   (let [test? (some #{:test} (active-profiles proj)
         dev? (some #{:dev} (active-profiles proj)]
     (cond
       test? (-> deps fix-shared (add-dep 'a/b))
       dev? (-> deps fix-shared (del-dep 'murphy))
       :else (fix-shared deps))))
 (defn dhclj-adjust-project [project]
   (-> (project)
       (assoc :version "11.x")
       (update :dependencies adjust-deps)))

FILES

debian/dh-clojure-lein.clj

SEE ALSO

dh-clojure(7), dh(1), lein(1), and <https://clojure.github.io/clojure/clojure.core-api.html>

2024-10-06 0.1.0