Breaking Changes (MfGames Project Setup Flake)
In the beginning, I wanted to use NixOS options with the flake instead of using
a mkConfig function to generate the files and shell hooks. But, due to
complexities and struggling with Nix, I couldn't figure it out. But, after two
years of working on it, I finally got a working implementation that uses the
cleaner approach of options.
So that means instead of using mkLib, using
mfgames-project-setup-flake means
adding it as an input (as before), importing the model (that's new), and then
using configuration settings (those are new).
The flake still needs to be added as an input:
inputs.mfgames-project-setup.url = "git+https://src.mfgames.com/nixos-contrib/mfgames-project-setup-flake.git";
It also now has a module which needs to be imported and then configured using the same syntax that most other configurations are used.
imports = [
inputs.mfgames-project-setup.flakeModules.default
];
mfgames.project = {
enable = true;
rust.enable = true;
};
Then, in the mkShell call, the various hooks are called to integrate it.
devShells.default = pkgs.mkShell {
packages = []
++ config.mfgames.project.packages;
shellHook = config.mfgames.project.shellHook;
};
I also refactored how options where documented and displayed. It is now a script-generated file that is rebuild during the build process so I don't have to worry about getting it stale.
Versions
The old version is now v0.5.0 with the new version current at v1.1.0.
Breaking Changes
Since this is a really breaks existing setups, I'm also taking the opportunity to make other changes that have popped up in the last few years that I didn't want to be disruptive but I think will benefit the project in the long run.
REUSE
Probably the biggest one is stumbling onto REUSE Software and seeing a more nuanced (though complicated) specification for handling licenses that differ across files even in the same project. That is osmething I couldn't do but it resolved a number of issues I had after trying to integrate mfgames-writing-project-setup which is less code-oriented and more prose-oriented. After mulling over it, I decided to remove looking over the differencesand reasoning, I decided to integrate REUSE into the flake and remove the existing licensing handling.
This means removing the following keys from before:
creativeCommonsAttributionShareAlike.enablecreativeCommonsAttributionNonCommercialShareAlike.enablemit.enablemit.filename
And replacing it with:
mfgames.project.reuse.enablemfgames.project.reuse.ignore-dot-configmfgames.project.reuse.annotations
The most complicated part is that REUSE is “picky”. It requires every file to be
properly licensed, so I introduced the ability to create the REUSE.toml
annotations from the flake file which will be suppelemented by the automatic
annotations from the generated files this flake produces.
mfgames.project.reuse.annotations = [
{
path = [
"docs/**/*.md"
"news/**/*.md"
"README.md"
];
SPDX-FileCopyrightText = "2026 Dylan Moonfire <contact@mfgames.com>";
SPDX-License-Identifier = "CC-BY-4.0";
}
{
path = "src/**/*.nix";
SPDX-FileCopyrightText = "2026 Dylan Moonfire <contact@mfgames.com>";
SPDX-License-Identifier = "MIT";
}
];
I also consider most of the contents in .config to be generated files, so an
annotation is added to mark all of those files as public domain unless turned
off with mfgames.project.reuse.ignore-dot-config = false;.
Developer Certificate of Origin
I modified the setup so it adds the “Signed-off-by” to the bottom of Git commit messages if `mfgames.project.developerCertificateOfOrigin.enable = true".
Rust
I prefer a more vertical style of formatting in my code. That usually means I want braces on their own line for almost everything, including if statements. This was “on the same line” in the previous version, but now it defaults to braces on their own line.
Non-Breaking Changes
I found a consistent logging program that gives useful messages: gum. While the colors are not exactly my thing, I find it useful to have the same type of messages across the board. So you'll see a variety of functions now use that for logging, when easily done.
Project UUID
A few years ago, I stumbled onto a blog post about creating a “power ID” for
projects. In effect, a UUIDv7 that uniquely identifies a project and make it
easier to distinguish projects of the same same (such as Gemini the Protocol,
Gemini the Cryptocurrency, and Gemini the LLM). That is why you see
019530bd-5065-731f-925b-3961eb7aa613 in almost every blog post and article I
write about mfgames-project-setup-flake.
Since I've embraced that, I also modified this project to generate one if there
is no .config/project-uuid.txt present in the project. This is intended to be
checked in since it shouldn't change.
This functionality can be turned off with:
mfgames.project.project-uuid.enable = false;
Shell Formatting and Checking
I also recently started using shfmt and shellcheck for my shell scripts.
I've introduced some options for this.
mfgames.project.shell.enablemfgames.project.shell.checkmfgames.project.shell.formatmfgames.project.shell.includes
check and format use enable if not defined. And enable defaults to
mfgames.project.enable.
If check is true, then just check-shellcheck or just check will run that
utility against the files.
If format is true, then just format and just format-shfmt will format the
shell script, as will commiting a file.
Metadata
Project
- Project Home
- Documentation
- Project ID: 019530bd-5065-731f-925b-3961eb7aa613