Hacker News new | past | comments | ask | show | jobs | submit login
A cross-platform multi-target dotfiles manager written in Rust (github.com/shemnei)
81 points by michidk 1 day ago | hide | past | favorite | 78 comments





Serious question: why Rust? Sounds like this is not exactly systems level programming or any user would suffer from or even notice garbage collection latency.

Is Rust building up a decent ecosystem now for application programming? When I tried developing in Rust I came to the conclusion that you pay a heavy price for not having a garbage collector. Was I doing it wrong?


I find Rust super ergonomic for any kind of app. The memory management aspect is trivial and second nature to anyone used to unmanaged languages, and the type system equally is not difficult to understand.

It's a general purpose language, but it does give you full control. Plus, of course, you can encode a large amount of program states in the type system and borrowing checks enforce rules that programmers usually have to check in their head.

I find that when I write Rust, I have to worry about an order of magnitude less about silly things like lifetime bugs, reference bugs, resource cleanup, all of which are 80% of my job when I write C#, or other similar managed languages.

Plus Rust can generate a static executable, which is reasonably small, and doesn't require a third party runtime.


As someone used to unamaged languages since 1986, and with a major focused on systems programing, it isn't that clear cut.

Rust executables are only 100% static on OSes that expose system libraries as static libraries, and there are not many of those around, outside embedded systems.


As a counterpoint to the parent commenter, I like using Rust for personal stuff (like the project being linked to) for almost everything besides the memory model; I prefer Cargo to any other build tool I've used, and I like how I can eliminate boilerplate with stuff like Serde (for serialization), clap (for argument parsing), and even for how I'm able to write one-off macros to generate code for myself. The documentation for the language and tooling is great, and most packages have fairly good documentatio as well because any package published on crates.io will have it generated from the doc comments into a static site and hosted on docs.rs. The compiler error messages are better than any other language I've used, and at least for my personal use on Linux, I can easily compile with musl and get a fully static binary when libc is my only native dependency; I'm sure that Linux desktops are part of the "not many of those around" you refer to, but the same trick would work just as easily for any Linux server, and I do feel like there are plenty of those around!

If I could get all of those quality of life things in a language with a garbage collector, I'd probably use that for most things instead. Right now though, the closest options would be maybe OCaml or Swift, one of which doesn't really give me nearly as much in terms of quality of life stuff around documentation and tooling, and the other isn't nearly as streamlined to use on my platform of choice as I'd like, so I'm using Rust unless (or until!) something better for my personal projects comes along.


What issues do you run into with Rusts memory management?

After years navigating this issue, I think the common understanding of "static" binary is just "something that won't give me a dll / dylib error on startup when I copy it to my friend's computer"

Which is a possibility, given that ldd/Dependency Walker result won't be an empty list.

Even shipping the whole computer on a container, might not do it, because most containers are leaky abstractions the way their Dockerfiles are written.


Yet in practice this works fine for all intents and purposes.

Sure, you might get a loading error if you try to run your Ubuntu 24.04-compiled executable on Ubuntu 18.04 if you use the default toolchain. tTat’s exactly the same as C or C++, only much easier to fix in rust by rustup-installing the right tool chain.

Compiling on Ubuntu 18.04 and running on 24.04 is absolutely not an issue. Same for windows.

In practice this is really not a problem, especially for cargo libraries that you anyway build from source.


I would say the same regarding dynamic linking, which is why most OSes have moved away from being static linking only executables, except embedded in the cases where it is a single blob uploaded into the device.

Not even modern 3D graphics APIs, none of them, work with static linking, yet another area static linking advocates have to accept the industry has moved on.


> Rust executables are only 100% static on OSes that expose system libraries as static libraries

This seems to be a weird hair to split. GP clearly means “a single executable you can run on any install of the target OS without dependencies.” Whether it’s a truly honest-to-goodness static binary that don’t link to libc or libSystem or whatever is important to approximately zero people, outside of internet pedants.


It is, because so many folks make such a big deal of how using computers as they used to be until early 1980's, with single static linking model.

Ironically the same folks don't see to appreciate how object files and binary libraries work in static linking, lets make it even better compiling always from source.


Nobody’s making a big deal about in it in this thread but you.

I beg to differ,

> Good dependency management, a rich package ecosystem, defaults to static binaries which are easy to distribute and a tendency to be fast (even if it’s just the lack of startup overhead) make it a popular choice.

> .....

> Plus Rust can generate a static executable, which is reasonably small, and doesn't require a third party runtime.

Somewhere this thread....

And guess what, you can also ignore my comments.


People are using a term in a different way than you want them to.

They use static binary to mean “the dependencies I specify in my package manager are all put in the one binary, and it doesn’t require a separately installed runtime to run”, which is totally reasonable, and it is opposed to so many languages that don’t work this way.

You’re using static binary to mean “does not link to anything at all”, which on some systems results in worse portability, since the syscall interface is unstable and linking to libc/libsystem/etc is the only supported way to make syscalls.

You come into the discussion assuming definition B, ignore the fact that they’re using definition A, say that they’re making a big deal about definition B, etc.

There’s no confusion from anyone here but you. We all are using definition A. You’re the only one using definition B. It’s probably better if you just recognize that and move on rather than insisting everyone here is an idiot but you.


Rust is a popular choice for CLI tools as well as Go and I do think the ecosystem is picking up.

In fact there are a bunch of them for the terminal.

https://terminaltrove.com/language/rust/

https://terminaltrove.com/language/go/


I've used both, and they are comparable in library support. I happen to write _much_ faster in Go, so it's usually my default choice for CLIs, unless I specifically need to bridge with another Rust program.

Two things:

1. Historically a CLI like this would often be written in C, so Rust isn't that strange of a choice.

2. Rust is know for the borrow checker and being a great low level language. However, it's also an excellent modern general purpose language with a great ecosystem. People end up using it for all kinds of things because it's a joy to use.

"When I tried developing in Rust I came to the conclusion that you pay a heavy price for not having a garbage collector. Was I doing it wrong?"

Rust is tricky to grasp initially, the learning curve goes pretty much vertical immediately, but once you "get it" it's very nice. When I started out I overused borrowing and ran into heaps of lifetime problems. I think limiting yourself to only using references for function arguments and, rarely, return values is a good place to start. As soon as you are start adding references to struct you should stop and think about who owns the data and what its lifetime is. Thinking properly about ownership is the big shift from GC languages. Once you've gotten into that habit, lifetimes are downstream from that.


>Historically a CLI like this would often be written in C

*Perl


Rust is my main programming language and Python the second. Rust is very much useful for application programming - especially these sort of applications. In fact, Rust is the language I sometimes reach for when my shell scripts cross a certain threshold of complexity. Rust even has some tools and an RFC to address the use case of using it like a scripting language (I believe that Go has something similar too).

I don't face much friction from the borrow checker to consider it a 'heavy price for not having a garbage collector'. There are even tools like bacon [1] that can give your real-time feedback on your code. It's even better with the default language server. I sometimes train other developers in Rust - mostly people who are not even into systems programming (JS, Python programmers). However, they don't seem to struggle too much with the borrow checker either. Could you elaborate a bit on what you consider as 'the heavy price'? What sort of issues were you facing frequently?

[1] https://github.com/Canop/bacon


It's BEEN built so the price has been paid. I'm not going to complain that someone over-engineered a useful tool and got away with it.

I will say that rust is pretty damn productive once you organize your brain around ownership. I haven't had to mark a lifetime in over a month.


Rust is a general purpose programming language not just systems programming language.

Syntactically it's a pretty nice language, with a nice and sane ecosystem (crates, etc), and it's fun to write (which is a pro especially for unpaid hobby projects). If you get used to it, it's nice to write various things in it. I'd probably use it for CLI tools at this point.

You do pay a bit in syntactic overhead (lifetimes, borrow checking perplexities), though you get used to it. I'd still not use it for a standard product-y web app. For CLI tools though, it's pretty good.


Honestly, Rust is a breeze to make CLI/TUI apps in. Some crates worth looking into: tokio (mostly for stuff built on top of it), clap, promptly, colored, ratatui. These are just a few ones to get you started, but there's lots more depending on what you need to accomplish!

Good dependency management, a rich package ecosystem, defaults to static binaries which are easy to distribute and a tendency to be fast (even if it’s just the lack of startup overhead) make it a popular choice.

It also helps that rust attracts the kind of devs that make nice tools.


As a user, if I have the choice between 2 apps, I’ll strongly favor a Go, Rust or ANSI C app over a Python, Ruby, Shell or C++ app.

This is because empirically, they usually work better, feel more polished, faster and I can easily contribute patches if I need. If a tool is written in Python, I’ll go out of my way to find a rewrite in another language.


I am a huge Rust fan and I work with Rust at my job.

I also recently started some open source projects (mostly CLI tools) where I picked Go for one reason: Rust’s learning curve is super steep.

In order to make my projects approachable for other developers Go seemed to be a better choice over Rust.


The primary purpose of Rust is to write Rust. It is only the secondary purpose to actually write useful things.

One thing your comment has in common with it then ;-)

Serious question: why not, if the author just knows Rust? Are you so allergic to anything written in Rust? Then get some new pills and ointments because there's going to be more and more of it.

As a Rust developer, let me point out that this is certainly the wrong way to respond when someone criticizes or makes an observation about Rust. Especially when they aren't hostile at all. It's clear from the commenters' question that they have a some preconceptions about Rust for which they are seeking clarifications from other Rust users. This sort of response will only make them give up on Rust due to the toxicity of the community, rather than address any real issues they may be facing.

I am not a Rust programmer and barely know it.

It's just wherever you go, here, Phoronix, Linux Kernel Mailing List for example, the forums are full of haters that just ask "not again, why?" anytime Rust is mentioned. Maybe I've become biased because of that.

Rust helps with performance and security, lots of examples are evidence of that. It's not 100% bulletproof, but nothing is. But it helps. And yet IT people just yell on it for some reason. Like we all should just get stuck forever with C, C++, praise Go, and hate everything else.


The antibodies are probably to the "written in rust" addendum, which seems unnecessary unless rust adds something to the product. Much of the answer above to "why Rust" concerns the developer, and we are potential customers, so who cares? Just drop the "in Rust" and don't worry going forward.

Honestly though I thought we were past the "written in Rust" phase.


It works. Including on me. I'm much more likely to pay attention to a tool that I know is written in Rust. This is both because I love the language and really enjoy using it, and because I've gotten conditioned to believing that tools written in it will be extremely robust, fast, useful, and stable. I can easily rattle off a dozen tools I use on a regular basis written in Rust that are significantly better than their non-Rust counterparts (starting with ripgrep, which is extremely fast). It's effective marketing still.

I just use a “dotfiles” folder that is a git repo and then hard-link the files in there into the home directory. One for unprivileged user and one for root on each platform. Simple enough and doesn't require an extra tool.

How do you handle differences between machines? I use cheznoi to manage my dotfiles and share them between 6 different devices, 2 of them are work machines. On my work machine I have maybe a 15% difference in config, primarily my hotkeys through keymapper, my SSH config files, and also the applications I have installed. Chezmoi let's me add logic to my source controlled config files that, based on the hostname/domain/network, etc let's me ouput different settings to the .config files, which I cannot do in the config files themselves.

For example: On my home machine I have the following keymapper hotkey: Windows + T: Activate Telegram On my work machine that's mapped to: Windows + T: Activate Teams


I went a different route and use different branches for different OS environments. macOS, macOS-arm, Linux, Windows (wsl)

The environments are basically the same in each but there’s some functionality I can do I one that I cannot do in another


Looks like we took similar approaches!

https://github.com/cquintana92/dotfilers

Congratulations, you too unlocked the "None of the hundreds that are out there work exactly like I want, so I'll write my own" badge.



Saw the name "comtrya" and was immediately reminded of that episode of Stargate, but figured it had to be a coincidence. Cannot tell you how happy I was to see the gif in the readme :)

Completely unrelated, but I recently switched to using nix with home manager and nix-darwin to handle my entire dev setup and dotfiles.

If you work a lot in remote dev environments (I use coder a lot at work) that really does the trick.


Likewise. I have two Mac laptops, three home servers, and a Windows desktop managed by Nix.

The home servers are nixOS, the rest basically have the CLI environment managed with nix-darwin and nixos-wsl, all with one flake (Git repo) containing all the configuration.

Case in point - this morning I’m rebuilding one of the servers onto new hardware, and the longest time spent was getting the flake config onto the server with git clone. Now just watching the rebuild switch command output, after which it’s good to go.


I had to switch off nix because my company's security controls made it impossible to use :(

There are many of these tools but i don't like to think of these things like dotfiles. What is a dotfile? A `.something` file in my home dir? is /etc/environment a dotfile? No, but i wan't to manage it still. What about Librewolf policies.json in /usr/lib64/librewolf/policies or similar. It's not a dotfile either. For some tools, i need some other tools to exist already in path. What about zsh where i want to sync 3 git repos for syntax highlighting and other scripts? Also what about secrets, maybe i want some encrypted stuff so i need a solution for that also.

Ansible is the best for these things, no symlinks needed, just configure what you want to exist and where and you can template configs or copy them or use some modules like `git_config` to then generate that ini file etc. Ansible vault also handles encryption easily so i can manage ssh keys, passwords...


Pretty cool, I personally just use Stow.

1. git clone my dotfiles repo

2. run `stow .`

3. profit

This pretty much guarantees that if my Mac dies today, I can just get up and running in no time on a new machine.


Same. Stow is pretry great! I only recently discovered about the .stowignore very handy!

This looks like it can work with windows as well and you can easily switch between profiles if you have multiple which is great too


I need something that works across OSes. Chezmoi works pretty well.

Dumb yet serious question : what problem is a dotfile manager even trying to solve?

Personally I have a git repo in my home directory and just commit dotfiles to it. The only drawback is that git always think there’s a git repo no matter where I am in my home, so I usually rename the .git folder to .git_hidden. And on the (rare) occasion that I want to update one of my dotfiles I just rename the .git_hidden directory back to .git.

It’s really just two “mv” commands, I can’t believe you need a tool for just that.

What am I missing out on?


I recently learned it. I have personal and work laptops (two work laptops as of now for different companies). 90% of dotfiles should be the same. But rest is pain to sync. I’m using chezmoi that has templating mechanism that helps me.

FWIW, you don't have to do that rename dance; git allows specifying the name of the .git metadata directory via `git --git-dir=$HOME/.git_hidden ...` or `GIT_DIR=$HOME/.git_hidden git ...`

I don't know how big your .gitignore must be when trying to use a tool that wants to own every file and directory to manage your /home but if that works for you, more power to ya


Oh, interesting, thanks!

And I don’t even bother with ignoring files! I just git add the ones I want to track :)


Start with ls -a -w1 > .gitignore, then edit it and delete everything you want to track.

> This project was driven by the personal need of having to manage several dotfiles for different machines/targets.

the functionality OP is searching for is already provided by chezmoi. and many more features.


Is there a concise comparison between other tools?

Specifically looking to see where this differs from chezmoi.


So, I'm usually the huge Rust promoter, but we already have a lot of dotfiles managers, and Chezmoi, although written in Go, is right there.

What can this one do that the other ones don't?

The README lists features that, well, I'd already expect modern dotfile managers to be able to do.


I've used a similar tool, called dotter, by SuperCuber on GitHub. It's actually very similar--uses a handlebars template language and built in Rust. Definitely a must have if you're on multiple *nix systems and you've invested time into developing your configs!

Shameless plug for my bare repo git shell wrapper approach inspired by others: https://github.com/k3vinw/simple-dotfiles-kit

I’ve been using it for a couple years now and it’s worked well for me across multiple machines.


Great job on the installation instructions.

Would also be great to see screenshots on what it looks like and how to quickly use it especially how the author uses it.


From skimming it seems it is feature wise very similar to yadm.

Good, because I am a fan of yadm, but I also don't feel the need to switch ;)


Why not stow? Am I missing out? I dont use Windows so not sure I need the cross platform.

Made the same comment. Why not stow?

Why no MacOS support if you claim cross-platform? That's not honest.

It's still cross platform, just across Linux and Windows, doesn't look dishonest. It's similar to other "linux/macos"-only tools that also call themselves cross platform.

The baffling part though is recommending using homebrew to install it on linux.


> The baffling part though is recommending using homebrew to install it on linux.

Do they really? Probably AI-generated.


How about using GNU stow?

Could have included a few screenshots.

For an utility like this?

why something so specialized needs a configuration file?

my dot file scripts just have very opinionated dir/file naming conventions and things just fall into place. it's not like you need to give tune much... even adding the template thing which i think is overkill (time would be best spent with a way to validate code cross platform of you ask me.. templating makes this more difficult while pretending to remove the need for it)


So you can manage your dotfile manager with a dotfile manager!

Nothing against the project, this part just seems pretty amusing


almost spilled my drink. thanks for nailing the joke i missed

Is this using ”dotfiles” as a general term for ”text based configuration files”? Is this a thing?

I only have two actual dotfiles on my system (git and one more)


Lots of config files begin with a dot themselves or because they are inside dot-names directories (ie xdg config default to ~/.config)

At least on Linux they do yes. But this is cross platform. A Normal total number of dotfiles on a windows system is about 0 or 1.

This is not true. Open your user folder and there will be tons of dotfiles. If you use git with ssh or Rust (.cargo) or C# (.nuget) and many other tools. In fact, even .config is started to show up now.

I guess devs are tired of %APPDATA% ?


Yes, I have 2 (nuget and git). But I obviously have many more text based configuration files than those. They just happen to have a name with a dot.

Are you using windows? I feel like dotfiles are much more common on unix-like systems. For me I've got dotfiles for zhs, ssh, git, two for my window manager, vim, and much more. I've even got one for nethack. I quite like it, I get new laptops up and running and feeling like home in a matter of minutes.

Yes windows. That’s my point: dotfiles are synonymous with ”configuration files” on Linux/Unix but not elsewhere so making a ”cross platform dotfiles manager” seems like a contradiction almost.

Even windows, MS made stuff has dotfiles.

By historical accident, Unix-like shells tend to hide by default files whose names begin with a dot. This led to programs naming their config files ".$program_name" and throwing them into $HOME. It's no longer cool to do this, but the tradition lives on.



Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: