Regarding this /r/clojure thread
How would such a generator work? First, relevant quotes on the bootstrapping process, from the boot wiki
The bootstrapping process can be expressed in terms of input and output:
Fuser →
BOOTSTRAP
→ Jcp + Fcp + Fasset + Ewhere
- Fuser
- User's project files (the
build.boot
file, sources, assets, etc).- Jcp
- JARs on the classpath (the immutable classpath).
- Fcp
- Files in directories on the classpath (the mutable classpath).
- Fasset
- Files in directories not on the classpath that the program might need.
- E
- The Clojure environment in memory.
[...]
This process of extending the bootstrapping phase to create an artifact for deployment or distribution, or to launch an application can be described as a transformation:
Jcp + Fcp + Fasset + E →
TASK
→ Jcp + F’cp + F’asset + E’[...]
Boot provides a fileset record type to manage the parts of the process that involve interaction with the filesystem: an in-memory, immutable representation of the state of the files in Fcp and Fasset at a point in time.
The file-related parts of the process above can be described as:
Fcp + Fasset →
FILESET OPERATIONS
→ F’cp + F’assetor, equivalently, as:
fileset →
FILESET OPERATIONS
→ fileset’Operations on fileset values return new values.
This means that a generator could be represented as a task, iff a base and universal project template can be agreed upon. Obviously, the most general starting point is the creation of a new project (or root) directory.
So, we first create a function (i.e., task) that creates a new directory with a given name, and then accepts other functions. These other functions are constructed such that they modify the Fileset record, and return a new Fileset with their customizations. Some helper functions would be required, and thus a "boot-generator" library would be required. This library would be loaded in .profile.boot and any custom project templates could be defined there. Public generators could be defined and loaded just like boot tasks are now, e.g. boot -d user/generator-repo project-name
, or whatever. Commonly-used generators could be saved/required in .profile.boot so you could always have them without need for downloading.
The generator process could be represented as:
D + G → Fuser →BOOTSTRAP
→
Fcp + Fasset →
FILESET OPERATIONS
→
F’cp + F’asset
Where D is a function that creates the new project directory and G is one or more generator functions. An example of a basic generator function could be a function that creates a minimalistic build.boot
file itself. This generator function could in-turn be acted on by other generator functions to add dependencies, tasks, or whatever to the build.boot
file.
More to come: details of how the Fileset record would need to be interacted with/modified in order to support this.
A first look at the Fileset docs tells me that you might need helper functions for commit!
(instead of writing the files, pass the fileset to another generator) and accepting filesets from other generators. Could core.async channels be well suited to this?