SuperCuber / dotter

A dotfile manager and templater written in rust 🦀
The Unlicense
853 stars 45 forks source link

[FEATURE(S)] Many relatively small features #74

Closed NomisIV closed 1 year ago

NomisIV commented 3 years ago

I'm considering making my own dotfile manager, but dotter has got a lot of things right about it, and my implementation would be too similar to necessitate it's existence. Instead I'll propose some changes I would like to see. I'm very much open for discussion when it comes to them, and I can probably make PRs for them too.

Here are the features:

Package-scoped variables in the local config

It's a bit confusing that variables from different packages can be declared under the same [variables] "namespace" in the local.toml. One solution would be to look for variables in variables.<package name>.<variable> instead of variables.<variable> in the local config. This would also allow for multiple packages to have variables with the same name, which is an added benefit.

Support using the computer hostname as the local config file name (Added: https://github.com/SuperCuber/dotter/pull/75)

Example: <computer name>.toml instead of local.toml. This would allow the local configurations to be synced between all machines, since the machines would look for different files. It might be worth mentioning that NixOS is using this method with their flakes, so I guess you could say the method is "battle tested"

Allow for a default destination for config files

I find myself frequently writing "<package>/<file>" = "~/.config/<package>/<file>", which is a bit annoying. My preferred solution to this is that by default the package folder is symlinked to ~/.config/<package>, of course, this assumes that none of the files in the package are templated.

Allow specifying a location for the source dotfile directory

Even better if the value could be set as an environment variable. This would allow dotter to run anywhere. This is super easy in structopt. Just add an option to specify the location of the dotfile source folder, and make it default to an environment variable named DOTTER_SRCDIR or something similar. If the environment variable is unspecified, dotter can default to using the current directory for backwards compatibility.

Add an option to symlink an entire directory

Currently dotter recursively links each file in the specified directory. I'm managing my gtk icon theme with dotter, and everytime I run the dotter command, it checks every. single. icon. I would like to be able to just link the entire icon directory to the right location in my system.

A solution that I quite like, but which might be a bit confusing at first, is this: <package>/<folder> = <dest>/<folder> creates a symlink from the package folder to the destination folder, and <package>/<folder> = <dest>/<folder>/ (notice the trailing slash) symlinks the content of the folder to the destination folder.

Add support for checking if the program for the dotfile is installed

This would be very useful when deploying the dotfiles on a new system. Add an option called "requires" (or similar) which takes a string containing the program's name when declaring a package. After deploying the dotfiles, dotter could return a summary of what packages need to be installed, or the fuctionality to (try to) install them automatically through the package manager could be added (this might pose a problem though, since packages can be named differently in different package repositories).

Example:

# global.toml
[sway]
requires = "sway"
...
$ dotter
...
Packages needing installation:
sway

Add support for reloading programs if the dotfile has been updated

Add an option called "reload", which takes a shell command as a string, and runs it in a sub shell if any of the files for that package has been updated.

Example:

# global.toml
[sway]
reload = "swaymsg reload"
...
$ dotter
...
Reloading sway

Conclusion

I'd love to discuss this further, and also implement these features as PRs

SuperCuber commented 3 years ago

That's quite an issue hehe, I'll go through these one by one:

Package-scoped variables

The variables are shared between packages on purpose - with my use case for example, I have variables in the graphics package that doesn't actually have any files - its only use is to be depended on by other packages and have the variables be used everywhere.

I think the solution of having [package_name.variables.package_name in the case where you want to scope them is good enough - since scoping them by default would make sharing impossible.

Hostname as local config name

This seems like a good idea - in case local.toml doesn't exist, just check hostname.toml. This would be beneficial for users who want to check their local.toml into source control.

Default destination for config files

I don't think I understand this section. You could use "<package>" = "~/.config/<package>" for this - but I'm probably missing something.

Location for source file directory

This seems like a pretty good idea. I can see this being useful for running from inside your source repo, although I think running from outside the repo is a bit strange.

Symlink a directory non-recursively

This suggestion actually came up in another issue ( #67 ) and I thought it was pretty useful back then. The way I see it is something like this, using complex targets:

"a" = {target="b", type="symbolic", recursive=false}

Checking if the program is installed

This is possible to do with post-deploy hooks, since they have access to a bunch of variables. You could use a combination of handlebars' {{#each}} and dotter.packages to write your own version for this that takes the correct variable. I think OS package management is out of scope for a dotfile manager.

Reloading

My opinion on this is the same as the previous section - post-deploy hooks are flexible enough for the user to implement it himself.


The sections I agree with should be pretty easy to implement - a PR would be appreciated but I'll get it done eventually without one :D

NomisIV commented 3 years ago

Package-scoped variables

I see your point, but I would still say it's a bit confusing as they are "scoped" in global.toml, but not in local.toml. If it was possible to access other package's variables by prefixing them with the package name, it would be still be possible to implement scoped variables, while allowing shared variables. So here is the font line from your i3 config as an example:

font pango:{{graphics.font.monospace}} {{graphics.font.size}}

So the scope for each file would be the package's own variables, plus the other packages as "namespaces" (I really don't know if that's the correct terminology, but I don't know what else to call it)

If you still don't like the scoping idea, I would still suggest making it clearer that there only is a global scope, for example by merging all the [<package>.variables] in global.toml to a single [variables] like in local.toml.

Default destination for config files

Yeah, that's probably a better solution than linking each file separately. However I still think it's a good idea to implement an option to specify a default location for each package, so that I wouldn't have to repeat that line for every package. But I'm not quite sure how it would be done.

Symlink a directory non-recursively

Oh, I see. I'll try that. Thanks! EDIT: Ah, it isn't implemented yet...

Checking if the program is installed

While it is possible with post-deploy hooks, I feel like it could be done easier by implementing it directly into dotter, but I also see why it would be a bit out of scope. I just think it would be a nice feature, and it's not really a deal breaker.

Can I use templating and the builtin variables in post-deploy hooks? If not, would it be possible to add them as environment variables or something when running the script?

Reloading

Is there a way to know what files have been updated in a post hook? I wouldn't want to reload everything every time. Maybe a variable for the changed files could be added to the builtin variables.


I probably won't have much time next week, but the week after that I think I could start working on some PRs. I'm planning on starting with hostnames as local config, since it's probably the easiest one.

SuperCuber commented 3 years ago

Scoped variables

Both of your changes are breaking, and there isn't enough reason to change it. I do think that this should be cleared up in the wiki if it isn't already though.

Checking if a program is installed

Yes, all hooks have full templating

Reloading

This could be a good addition to the dotter.variables builtin... Although it's not the simplest addition, since that will have to be patched in after all the discovery of the current state of the filesystem is done. Depending on how that code was structured this could be either really easy or really hard.

stfnx commented 3 years ago

Support using the computer hostname as the local config file name

That would be great! This way you could put the local config in the repo too and don't loose it when reinstalling the machine.

NomisIV commented 3 years ago

It's already merged (see https://github.com/SuperCuber/dotter/pull/75) but there hasn't been a cargo update since. You could get it working right now by cloning from master and building it yourself

SuperCuber commented 3 years ago

@NomisIV @stfnx new github release coming in the next few minutes, although the AUR package will take a while longer as I don't maintain it.

SuperCuber commented 1 year ago

Closing this because the features I agree with have been implemented.