I was going to turn Biff into just a project template that used the libraries in this repo. However I decided that would make things unecessarily confusing for new users, so I've moved everything here to the Biff repo.
During a big rock show, you can flub a few things and nobody will hear it, because it gets buried under everything else.
— Jonny Lang
This is a collection of utility libraries containing code that I pull out of various projects I work on. (I used to call this "Trident," see History).
flub.edn defines the dependencies for all the libs, and task generates the libs' individual deps.edn files.
These are only published on git. If you want to use something, put this in your deps.edn:
{:deps
{:git/url "https://github.com/jacobobryant/flub",
:deps/root "core" ; change this value to specify which library you want
:tag "HEAD"}}
And then run clj -X:deps git-resolve-deps
to fetch the latest commit hash. If
you're using Leiningen, check out
lein-git-down.
In many cases it might be best to just copy anything you want into your own project/lib.
The libraries are generally separated based on their dependencies, so you should be able to depend on whatever you need without pulling in too much extra baggage. There are no docstrings, so you'll have to read the source.
Helper fns with almost no dependencies (the only exception is
org.clojure/tools.namespace
). Notable functions:
start-system
andrefresh
, my 15-line alternative to Component/Mount/Integrant (probably not for everyone, but it does everything I need it to). You store your system in a single map with flat, namespaced keys, then pass it through "component" functions which modify the system map. It's kind of like a Ring request going through middleware functions. Use it like so:
(ns yourapp.core
(:require [flub.core :as flub]))
(def your-components [...])
(defn start [first-start]
(flub/start-system
{:flub/first-start first-start
:flub/after-refresh `after-refresh}
your-components)
(println "System started."))
(defn -main []
(start true))
(defn after-refresh []
(start false))
(comment
(prn (keys @flub/system))
(flub/refresh) ; I map this to <leader>R in vim
)
select-ns
,select-ns-as
,prepend-ns
. These help you work with flat, namespaced keys. They go well withstart-system
.
A few components for use with flub.core/start-system
. There are currently components
for nREPL, Reitit and Jetty.
Helper fns for the world's niftiest database. I really should write docstrings for these ones.
I recommend aliasing this namespace as flux
.
Some Ring middleware, my personal fav being wrap-flat-keys
which lets you do
stuff like this:
(defn handler [{:keys [session/foo params/bar]}]
{:status 200
:headers/content-type "text/html; charset=utf-8"
:cookies/baz {...}})
Rum components etc. Mainly there's a base
component which fills in a lot
of stuff in <head>
for you.
Because I couldn't bring myself to call it misc
. These functions can't go in
flub.core
since they have dependencies, but they don't fit anywhere else
either.
A single function assert
which throws an exception (with human-readable
explanation) if the given value doesn't conform to the given Malli schema.
In case you want to use a similar setup for your own collection of libraries,
Flub requires two commits to release. In the first commit, you must include all
the new code and external dependencies. (Run ./task sync
to update the
external dependencies for each project, after you define them in flub.edn
*).
After you commit those changes, run ./task sync
again, then commit and push.
This will update the commit hashes for all the internal dependencies (i.e. Flub
libraries that depend on each other).
* But don't actually call it flub.edn, come up with your own name.
This repository used to be called Trident. It contained a bunch of code that I stopped using, and it had an overly complicated monorepo setup that caused me to stop updating any of the libraries since it took a while to remember how (which compounded the first problem). I've given Trident a new start in life as Flub (now 43% faster to type!). You can browse the last Trident commit if you want to see the old code.
There is one part that's possibly worth moving to Flub: trident.firestore. It's a CLJS wrapper for Firestore that uses core.async. I used it to write Mystery Cows. I also used it in my startup before I switched to Biff. Since I no longer use Firebase, the code will probably languish in obscurity unless someone else wants to take over.
Distributed under the MIT License, which you might also want to start using for your Clojure libraries.
Copyright © 2021 Jacob O'Bryant.