Stay Out of My (Project) $Home

4 months ago 3

Warning, I’m about to get on my mild OCD soapbox again.

Too many development tools expect to get the privilege of a config file in the root directory of my projects. Many of them don’t even allow it to be a hidden file—they just require a fully unhidden “tool.yml” file sitting right there in the root of your project.

Stop it. Please.

Linux HOME Directory Link to heading

Once upon a time this was a serious problem for organizing files in the Linux HOME directory too. Tools thought way too much of themselves and added files, directories, etc. to your HOME folder. A lot of them still do!

Eventually some form of “Standard” was formed. XDG Directory Specifications laid out a set of folders and their uses that could be mostly agreed upon.

  • ~/.config: configuration files, often in ~/.config/toolname/
  • ~/.local/share: application data files
  • ~/.local/bin: user-specific executables
  • ~/.cache: non-essential cached data that can be deleted
  • ~/.local/state: persistent state data that should survive between restarts

I’m sure people complain about this system, but it’s good enough to impose some minimum amount of organization on the HOME folder. It does its job.

Not all projects use it, but it’s common enough that if a project becomes large enough and doesn’t support XDG directories, there’s usually some people who will show up and beg for XDG support. They might even help!

Projects Link to heading

Code project repos are faced with the same problem, though on a smaller scale.

Build systems have their own project layouts they either impose or prefer, but other tools often end up polluting the main project directory.

Take a look at my Eidetica project that I’m developing. I’m still in early development stages, I don’t have any release flows set up, it only uses a single primary coding language (Rust), and yet the home repo still has all the following:

├── Cargo.lock ├── Cargo.toml ├── LICENSE.txt ├── README.md ├── Taskfile.yml ├── cliff.toml ├── deny.toml ├── flake.lock ├── flake.nix ├── .prettierignore └── .github/

It’s not too bad yet, but the cruft has already started to form. More established projects are significantly worse.

And that’s without having set up Docker, CI beyond basic GitHub Actions, or many other common development tools yet. The Nix flake actually helps here by eliminating some tool configs that would otherwise live in the project root, but you can still see how quickly things accumulate.

Some of those files just aren’t important enough to deserve top billing in my project repo.

Solving Directories for Projects Link to heading

There are several different proposals for project organization, but they mostly take the same obvious route: apply the XDG recommendations (or a subset) to project repos and the tools designed to work with them.

dot-config is, as far as I’m aware, the most popular effort in this space even though it’s still only a ~50 star GitHub project. They focus on pushing for tools to support config files in a .config/ directory. That would solve many of these issues, but doesn’t solve the whole problem.

PRJ Spec Link to heading

The PRJ spec is far more complete.

The PRJ spec takes a different approach than dot-config. Instead of just focusing on configuration files, it defines a comprehensive set of conventions for project-centric tools:

  • Project Root Detection: Tools should use $PRJ_ROOT environment variable, or implement their own heuristics (like looking for .config folders)
  • Configuration Home: Tool configs go in $PRJ_ROOT/.config/ instead of scattered across the project root
  • Cache Management: Build caches and intermediate files go in either $PRJ_ROOT/.cache/ or shared in $XDG_CACHE_HOME/prj/$PRJ_ID if projects have unique IDs

The philosophy is that project-centric tools (linters, formatters, build systems) should follow the same organizational principles that XDG brought to user-centric tools. Instead of every tool inventing its own way to find the project root and scatter config files everywhere, they should follow consistent conventions.

Status Link to heading

Within a rounding error, no dev tools support these efforts. I’m still stuck installing config files into the root of my repos.

Personally, I try to follow PRJ spec principles when I have control over how to layout files in my project directories. Local scripting, testing, caching build artifacts for development or benchmarking, etc.

My cmprss tool for example has a test script that downloads example files into a PRJ-compliant cache directory instead of cluttering the project root.

I know it won’t actually be ‘fixed’ any time soon, but oh boy would it be nice.

Read Entire Article