1. 12

jann is a simple program I’ve been working on intermittently for quite a while now. It’s intended to serve as a copy-based alternative to GNU Stow for managing dotfiles (because I prefer not to have symlinks all over my disk). It’s nowhere near production-ready (it’s barely hobbyist-ready!) but I’m interested to hear the thoughts of lobste.rs users on its design and features. Contributions welcome :-)

  1.  

  2. 4

    I like GNU stow. A lot. One of the things I like about it is that if I edit the config file using whatever the usual mechanism is for the app, it shows up in my dotfiles repo as a change that needs to be resolved. I don’t think that would happen (organically) with a copy based system.

    The one thing I wish GNU stow could do is merge different sources of truth for a single target. By that I mean, I might want to keep most of my config data in a single repo for all my systems, and have a second repo that’s machine-specific that gets merged in somehow.

    Does jann have an answer for either of these? i.e. if I edit ~/.config/kitty/kitty.conf using my text editor, will jann detect that and show me that I need to sync it to my dotfiles repo? And does it offer some way to have system-specific mods to my main dotfiles?

    (I hope neither question sounds pointed… they are absolutely not meant that way… the right answer to the second one might make me want to switch if the answer to the first is livable.)

    1. 4

      I built my own tool to solve these problems as well – https://github.com/dcreemer/wsup ; it uses the concept of layers – I add my generic personal dotfiles on most hosts, then add in a couple layers for machine or project specific configs. All files are symlinked back to the layer git repo.

      1. 1

        This is a nice project. Forgive me if I’m not reading this right, but am I right in saying that as it the directory structure of the dotfile repo(s) needs to match the structure of your home directory? I must admit that was one of the reasons I disliked GNU Stow.

        1. 1

          Yes, you are correct. I wanted each “layer” to be a mirror of the home directory structure for ease of understanding. In this way, my “personal-private” layer can include files from ~/.ssh/ as can my “work1-private” layer. They both integrate into the “real” ~/.ssh/ directory.

        2. 1

          I like that scheme. Nice. Thanks for posting that. I’m tempted to adapt it to sit on top of stow.

          1. 2

            I would love that, and be happy to help out.

        3. 2

          The one thing I wish GNU stow could do is merge different sources of truth for a single target. By that I mean, I might want to keep most of my config data in a single repo for all my systems, and have a second repo that’s machine-specific that gets merged in somehow.

          yadm offers machine-specific files. It doesn’t provide a templating or inclusion system, but I don’t often need one.

          1. 2

            that was exactly the motivating factor for https://github.com/dcreemer/wsup .

            1. 1

              That looks really interesting. Thanks for the pointer.

            2. 1

              Thanks for your interest in the project :-)

              if I edit ~/.config/kitty/kitty.conf using my text editor, will jann detect that and show me that I need to sync it to my dotfiles repo

              jann does not have this feature. That said, some sort of jann --diff might be a really good addition. I must admit, since I edit virtually all the dotfiles that matter to me from a text-editor, I had not considered the case of application-modified files.

              And does it offer some way to have system-specific mods to my main dotfiles?

              No, but I want it to in the future. I have thought quite a lot about introducing some sort of patch-based system to jann to allow this sort of functionality, but it’s not present at the moment (I would really like any suggestions anyone has on how to do this elegantly!). A lot of applications offer the option to put multiple config files in a /config.d/ directory - so for Sway, I put my machine specific config in there, and just let jann manage the main config. Another more hacky, but workable solution, would be something like the following (note the slightly confusing paths are because jann enters a ./deploy directory when it executes - I may in future pre-populate the symbol table with BUNDLE and DEPLOY global variables to make this sort of scripting more readable).

              Edit: I have added the BUNDLE variable. DEPLOY is a little more complicated for technical reasons.

              deploy {
                  $ cat {{BUNDLE}}/general.config ~/setup/machine.config > specific.config
                  deploy/specific.config >> ~/.config/app/config
              }
              
              1. 2

                I don’t know much about rust and its ecosystem, so just dismiss me if I’m suggesting something that doesn’t fit the model you’re working with. But I’ve been tempted before to solve the problem using some templating engine. (ecosystem aside, after that, I start to feel like I’m rewriting puppet and slink back into my symlink-laden cave.)

                1. 2

                  Rust does, from what I understand, have some decent templating libraries. I know there is one that is a rough port of jinja which is rather nice. However, were I to implement templating - which sounds like it could be a worthwhile avenue - I would probably do it myself. Yes, I know that’s NIH syndrome, but it’s something I would enjoy doing and I’d be lying if I said that 40% of the reason for building jann wasn’t just a desire to write another parser :-)

                  Your comment about Puppet is very amusing to me, because another significant part of the reason why I built jann was being intimidated by Puppet, Ansible, et. al. The prospect of installing a huge program with the website tagline ‘DevOps automation for a multi-cloud world’ to manage a dozen text files on my laptop seemed a textbook case of cracking a nut with a hundred-tonne steam hammer! I am eager to ensure that jann strikes a good balance between covering people’s use-cases and remaining a small, reasonably elegant binary that ‘does one thing well’.

                  1. 1

                    The idea of avoiding “(XYZ overkill thing) to manage a dozen text files on my laptop” resonates. I think I occupy an odd middle zone in what I want from this kind of utility.

                    Mostly because my dozen config files are used in different ways across the three relatively disposable laptops I have to touch regularly. There’s my “daily driver” thinkpad, my “I need to mod my iOS app on the road” macbook and my “I need to cross a foreign border or go someplace it’ll probably get stolen” 10 year-old thinkpad with almost no personal data on it.

                    I want slightly different dots for all of these :)

                  2. 1

                    chezmoi has templating for configs that differ between machines; sounds like it might fulfill your requirements. I only started using it recently as a replacement for my manually-managed symlinks but like it so far.

                2. 1

                  I’m kinda starting to work on Yet Another™ “Dotfiles Manager” (though I want to use it to manage whole machines eventually, kinda poor man’s NixOS-inspired way). A crucial for me feature is that it should detect any changes between previous “deploy” and the current one, clearly show the diffs, and only be able to re-deploy after they’re resolved (it’s going to be copy-based).

                  I wanted to use CUE as the config language, but it showed up to be somewhat too early-stage for my liking (mainly through poor error messages), so now I intend to use Lua instead (which I know pretty well). You’re welcome to watch the repo if only for releases if you like, though usual disclaimer that I don’t promise any kind of a timeline/ETA.

                3. 2

                  Interesting project, I like that it doesn’t use symlinks, but as mentioned in other comments I feel like this necessitates a way to diff configs. With some templating functionality I would have definitely gave this a try about a month ago when I was re-engineering my setup.

                  After recently trying multiple different dotfile managers I came to the conclusion I should just use configuration management tools and ended up using ansible. With simple setups, dotfile managers can be nice, but once things start getting complicated I feel like using configuration management tools are better suited for the job, especially if you are already comfortable with using them.

                  Originally I was using vcsh with myrepos, and was fairly happy with them but because they rely on using separate git repos or branches for different systems it can mean a lot of duplication.

                  I then tried chezmoi, but I didn’t like being required to have everything in a single repository, at the same time I liked being able to template and encrypt files and variables.

                  With ansible I can:

                  • Keep everything I want to in separate git repos if I desire
                  • Encrypt files and variables
                  • Template
                  1. 3

                    I came to the same conclusion, it’s just so much more powerful, and chances that a problem comes up you haven’t thought of before you can’t solve with Ansible are slim. I ended up writing a wrapper around Ansible and a curly bootstrap script, so now I can install one or all of my dotfile profiles including the applications that belong to them with one command.