Git Product home page Git Product logo

toml-bombadil's Introduction

Toml Bombadil - A dotfile manager written in rust

GitHub Actions workflow status Code coverage status AUR package
crates Conventional commits Repository license

Documentation · Installation · Configuration

A dotfile manager written in Rust

  • Dotfile template: define your dotfiles templates and link them as needed.
  • Dotfile profiles: create profiles for different machines and situations and combine them on the flow.
  • Installation hooks: run custom commands before and after installing your dotfiles.
  • Gpg encryption: add encrypted secrets to your dotfile configuration with gpg.

Explore Toml Bombadil's docs  ▶

example gif

Why another dotfile manager ?

I wrote Toml Bombadil because I kept changing my desktop environment: switching from i3 to sway, from sway to xfce, from xfce to gnome and back to sway. When you keep changing your working environment like this you end up with several problems:

  • Some symlinks will end up orphans.
  • Not every program you use support Xresources and you will most probably have to manually edit some themes/config.
  • When starting a fresh installation you will very likely need to adapt your existing dotfiles to your new machine.
  • It is a mess.

Toml Bombadil try to solve this with a simple addition to the symlink method used by other tools: instead of creating a symlink from a dotfile to the actual config path of a program, it will create a copy of it and symlink the copy. This additional step allow to use your original dotfile as a template and inject variables in the copy. You can have multiple value files in the same dotfile repository and change color scheme, or any value on the fly.

In addition, this is completely optional, you could start using Toml Bombadil only to generate symlinks and templatize your dot file progressively.

Installation

Arch Linux:

pacman -S toml-bombadil

Cargo:

cargo install toml-bombadil

Quickstart

See Docs -> Quickstart.

Shell completions

Command line completion scripts for several popular shells can be generated by running bombadil generate-completions. An example for generating a completion script and outputting it to a file for zsh would be bombadil generate-completions zsh > <somewhere on your $fpath>/_bombadil. Available shells are: bash, elvish, fish, and zsh.

Troubleshooting

If you get lost you can use bombadil get {resource_name} to see what is currently configured. Available resources are dots, hooks, path, profiles, vars, secrets.

Optionally you can display resources for a profile with the --profiles flag.

Example repositories

If you use Bombadil please submit an issue, or a PR to update this section, we will be happy to reference your dotfiles here!

Contributing

Found a bug, have a suggestion for a new feature? Please read the contribution guideline and submit an issue.

License

All the code in this repository is released under the MIT License, for more information take a look at the LICENSE file.

toml-bombadil's People

Contributors

dependabot[bot] avatar dnaka91 avatar dspeckhals avatar dtolnay avatar haozeke avatar kakawait avatar mrkajetanp avatar nukesor avatar oknozor avatar salim-b avatar shoyuvanilla avatar svenstaro avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

toml-bombadil's Issues

[FEATURE] Less verbose output

Is your feature request related to a problem? Please describe.
Current output feels like a verbose one. With a bigger list of dotfiles errors might get missed too easily.

Describe the solution you'd like
I'd love to have the default output just throw out changes and errors while the current behavior becomes available using a --verbose switch.

[FEATURE] Add Cargo lockfile

Is your feature request related to a problem? Please describe.
In general, it's advised to check the Cargo.toml into git, if the project provides an executable: Cargo book.
One important reason for this is that distro package maintainers need be able to guarantee that a single commit results in the same executable with the same behavior. This is the concept of reproducable/deterministic builds. Without a lockfile however, this is an impossible task, as dependencies get updated all the time and library versions might change from on second to another.

I experienced this exact issue in one of my projects where I depended on clap v3.0.0-beta.3, which introduced breaking changes in a follow-up beta version.

Some people didn't build the project with the --locked flag, which resulted in failing builds.
All other users however, including the AUR package, were still able to build properly, as they knew which version the project was supposed to use via the lockfile.

I'm currently in the process of creating an AUR bombadil-git package, which is why I stumbled upon this issue.

Describe the solution you'd like
It would be awesome to have the Cargo.lock checked into the project.
This would allow us to reproduce builds based on specific commits.

Disable Templating

Hey there 😺,
I've noticed that the README says, that Templating is optional. I am therefore guessing that it can be disabled. If that is the case, how?

Thank you for your help!

Create 2.0.1 release

Hello,
Can you create a new release, so this commit is taken into account please? 42a7ff9 (toml-bombadil can't be installed at the moment)
Thanks a lot

[BUG] User unfriendly behavior running bombadil install

Describe the bug
Running bombadil install without argument results in

bombadil install
No such file or directory (os error 2)

and critically it also deletes the pre-existing symlink at .config/bombadil.toml.

To Reproduce
Just run bombadil install in your home dir.

Expected behavior
I don't really know. What is it even supposed to do without argument? Anyway, it should NOT delete the pre-existing symlink at .config/bombadil.toml. It should also provide a more helpful error message.

Additional context
--help doesn't document how install can work without being called with an explicit dotfiles directory.

[FEATURE] - Add regex support in import paths

Importing is currently done this way :

[[import]]
path = 'path/to/imported-config.toml` 

The path property only supports path to a file. Users shall be able to import multiple files using a regex or a directory path :

[[import]]
path = 'path/to/config_dir/*.toml` 
[[import]]
path = 'path/to/config_dir/**

Switch to Tempfile

The temp_testdir library hasn't received any updates since over two years.

There's a proper maintained library which supplies similar functionality called tempfile.

I also requested a deprecation notice of the original temp_testdir author.

It would probably be a good idea to migrate to tempfile in the long run.

Update git2-rs version once it's out

Libgit2 released a new version 1.4 and the bindings currently break on systems that already migrated to that version.

git2-rs is planning to release a new version with the update to v1.4: rust-lang/git2-rs#811

Once this is done, I'll create a PR that'll simply bumps the version :)

[FEATURE] List of gpg keys to encryt secrets for

Might not be the usual case, for me it is.

Is your feature request related to a problem? Please describe.
I've strictly separated users for private and work. I've different gpg keyrings. Different private keys. Currently I can encrypt secrets for one key, which means I cannot use secrets in the same repository on other hosts with different keyrings.

Describe the solution you'd like
I hope it would be easily managable to add gpg_user_ids in addition to gpg_user_id as a list of gpg keys to encrypt data for.

Describe alternatives you've considered
Third-party like git crypt and bypass bombadil secrets management, I guess.

[BUG] Non-existant variables result in variable expression being rendered verbatim

Describe the bug
In case a variable a isn't set, the expression {{a}} will not result in an error but it will just be rendered verbatim. It should instead produce an error. Silent failures aren't good! Perhaps an option should instead be provided to ignore errors but the errors should be visible by default.

To Reproduce
Have a config with {{a}} but don't define that variable.

Expected behavior
It should result in an error during bombadil link since the variable is unset and will likely result in the unexpected behavior of the expression {{a}} being rendered verbatim.

[FEATURE] Add bombadil watch to automatically sync configs on changes

Is your feature request related to a problem? Please describe.
Currently the default bombadil process is a bit annoying as on every config change, you have to remember to type bombadil link -p stuff.

Describe the solution you'd like
It would be nice for rapid config changes to be able to do just bombadil watch -p stuff and it would detect changes automatically on the dotfiles dir and then run bombadil link -p stuff. I think this would be easy to do when using watchexec as a lib.

[FEATURE] template variable rendireng in files with braces

Is your feature request related to a problem? Please describe.
Not sure if I missed something, but rendering {{variable_name}} when linking a file which contains any kind of { or } does not render the variable value?

# foo.vars
foo = 'variable foo value bar'
[profiles.custom.dots]
foobar = { source = 'foo', target = '.bar' }
  • foo
#!/usr/bin/env dash

#{{{
#
# This file has vim fold markers
#}}}

echo "{{foo}}"

{{foo}} is not redered correctly here.

Describe the solution you'd like
The rendered file should have {{foo}} rendered as variable foo value bar.

Am I missing something? Any hint appreciated.

Feature Request: Add possibility to encrypt secret vars using GPG

Bombadil should support secrets for variables (example: user password in a maven setttings template) to avoid committing secret values in a dotfile repository.

Proposal :

Creating secrets :

Bombadil should have a command enabling an user to add a secret variable to a variable file.

Ex: bombadil add-secret --var-file path/to/var/file --var-name maven_password --value mypassword

optionally --value could be replaced by the --ask parameter and bombadil should prompt the user for the secret value

Encrypting/Decrypting

Bombadil should inspire from pass (the standard unix password manager) and use gpg to encrypt/decrypt secret

Bombadil would delegate encrypting/decrypting to gpg, this simplify greatly the management of keys etc..

When bombadil needs to encrypt/unencrypt a variable it should use the default gpg key and eventually prompt the user for the gpg key passphrase if needed.

[BUG] Can not install, unresolved import `watchexec::ignore`

Describe the bug
A clear and concise description of what the bug is.

cargo install toml-bombadil

error[E0432]: unresolved import `watchexec::ignore`
   --> /Users/green/.cargo/registry/src/github.com-1ecc6299db9ec823/toml-bombadil-3.1.0/src/lib.rs:224:13
    |
224 |             ignore,
    |             ^^^^^^ no `ignore` in the root

To Reproduce
Steps to reproduce the behavior:
cargo install toml-bombadil

Additional context

I tried the stable rust and nightly rust, they all throw this error.

Improve contrast of doc's light version

In light mode the doc snippet code contrast has low ration that lead to be hard to read even more for colorblind people or other disease.

Screen Shot 2022-01-04 at 14 19 52

And lighthouse confirmed

Screen Shot 2022-01-04 at 14 21 43

Personally I don't have any eyes disease but even reading the doc in late night was a bit tiring. (A bit too late in night to find out the switch button on topbar to switch to dark, then was perfect in dark mode).

[BUG] Add secret to file should keep existing formatting

Describe the bug

If I have a file containing secrets plus some comments like the following :

# Work stuff
super_secret = "pouet"

# Personal stuff
reddit_password = "incrackable"

If use the command bombadil add secret -f myfile.toml I will loose the comments and manual sorting of the secrets.

Proposal : just append the secret at end of file.

Feature Request: Add possibility to split configuration into several files

bombadil.toml can get quite big over time. It would help to be able to better organize the configuration by allowing the user to split the file into smaller ones.

The user would add one or several import configurations in the main conf file :

# Simple import
[[import]]
source = "another.conf.toml"

# Folder import (any regex should work)
[[import]]
source = "config.d/*.toml"

The external configuration file(s) should simply be inject in the main configuration file.

[FEATURE] Extra Profiles

Why

I have been using profiles a lot to organize my dots on multiple machines, so it has become very tideous to try and remember which profiles I need on which machines

What is it

So I was think it would be nice to have some sort of system very similar to cargos feature flags where you have a single flag enable other flags

The config file

[settings]
vars = ["default_colors.toml"]
extra-profiles = ["shell"]

[profiles.nord]
extra-profiles = ["shell", "sway"]
vars = ["colors.toml"]

[profiles.shell.dots]
fish = {...}
ranger = {...}

[profiles.sway]
prehooks = ["pkill waybar"]
posthooks = ["sway reload"]

[profiles.sway.dots]
waybar-top  = {....}
waybar-bottom = {...}
sway = {...}

So with this config you should be able to
bombadil link should also enable shell + defaults
bombadil link -p shell should do the same thing
bombadil link -p nord should enable enable shell and sway and nord + defaults

[FEATURE] - Allow linking with sudoers permissions

Currently linking to a root owned path produce the following :

"/home/okno/dotfiles/.dots/systemd/sway.service" => "/etc/systemd/user/sway.service" : Permission denied (os error 13)

This shall instead prompt the user for sudo password.

[FEATURE] - Add dot `ignore` and `var` fields

.bombadilignore content would be just like .gitignore. It should prevent bombadil from liking mentioned files.

Let's take a simple example :

# .bombadilignore
sway/vars.toml
# bombadil
sway = { source = "sway", target = ".config/sway" }

With the following dir linked :

sway
├── bar
├── colors
├── config
├── vars.toml
...

This would allow a more flexible organization.
We could also auto-ignore var files when creating symlinks. Do we need both ignore file and var files auto ignore or just one of these features ?

[BUG] When using --profile and bombadil toml configuration is not valid, the error is not explicit enough

If my bombadil toml configuration file is not valid (eg: missing a comma in an array) and I use the link command with the profile parameter (eg: bombadil link --profiles test) the error is the following :

error: 'test' isn't a valid value for '--profiles <profiles>...'
        [possible values: ]


USAGE:
    bombadil link --profiles <profiles>...

For more information try --help

The error should be about the toml file not being properly formatted and not about some unexisting profile.

Feature Request : simplify use of variables and profiles

In the current state of bombadil the use of variables and profiles is overly complicated :

  • we should not need a specific type of global variables (meta)
  • profiles are linked to a dot and create a specific command every time, it can rapidly get cluttered

Proposal :

  • Variables can reference any other variable name using a special format
  • Meta variables are not necessary anymore so remove them
  • Use a "default profile for all dots, hooks, var files etc
  • Add the possibility to link dots, hooks and var files to a custom profile (ex: corporate)
  • When "activating" the profile it should override the variables of the default profile if existing
  • Add a parameter to the link command to enable the user to activate a specific profil (if not specified the default profile is used)
  • The profile parameter could take an array to enable the user to combine profiles. (values would be overriden following the profiles order in the array)

Example :

bombadil.toml

# Default dot for maven
[[dot]]
name = "maven"
source = "maven/settings.xml
target = ".m2/settings.xml

# Dot for corporate profile
[[dot.corporate]]
name = "maven"
source = "maven/settings.corporate.xml" # activating the corporate profile will change the source for settings.xml but not the target

# Variables activated by default
[[var]] 
path = "vars.toml"

[[var]] 
path = "vars2.toml"

# Variables activated for corporate profile, would override existing variables from default profile
[[var.corporate]]
path = "vars.corporate.toml"

# Hook activated by default, will always run
[[hook]]
command  = "sway reload"

# Hook activated for corporate profile, will run only if corporate profile is activated
[[hook.corporate]]
command = "echo i love $$"

[FEATURE] More powerful templating engine

Is your feature request related to a problem? Please describe.
Currently it's a bit cumbersome to use templating with files where a single variable will be substituted with multiple lines.
It just makes reading and managing dotfiles a bit annoying.

For example, this is one of my configuration files that's currently managed by toml-bombadil right now.

...

[[block]]
block = "hueshift"
step = 50
hue_shifter = "redshift"

__[i3status_config]__

[[block]]
block = "music"
player = "spotify"
max_width = 15
marquee = true
marquee_interval = 10
marquee_speed = 0.25
buttons = ["prev", "play", "next"]

...

The i3status_config variable is then specified for two different profiles:

Desktop:

i3status_config = ""

Laptop:

i3_layout = """
[[block]]
block = "backlight"

[[block]]
block = "battery"
device = "BAT0"
driver = "sysfs"
allow_missing = true
hide_missing = true
format = "Bat0: {percentage}% {time}"

[[block]]
block = "battery"
device = "BAT1"
driver = "sysfs"
allow_missing = true
hide_missing = true
format = "Bat1: {percentage}% {time}"
"""

Describe the solution you'd like
There are multiple full-featured templating engines out there.
I've personally worked with a few and I was quite pleased about the way they work and the amount of features they provide.

For example, this would allow us to declare the example above like this:

[[block]]
block = "hueshift"
step = 50
hue_shifter = "redshift"

__[#if profile == "laptop"]__
[[block]]
block = "backlight"

[[block]]
block = "battery"
device = "BAT0"
driver = "sysfs"
allow_missing = true
hide_missing = true
format = "Bat0: {percentage}% {time}"

[[block]]
block = "battery"
device = "BAT1"
driver = "sysfs"
allow_missing = true
hide_missing = true
format = "Bat1: {percentage}% {time}"
"""
__[#if]__

[[block]]
block = "music"
player = "spotify"
max_width = 15
marquee = true
marquee_interval = 10
marquee_speed = 0.25
buttons = ["prev", "play", "next"]

This makes the dotfiles much more readable, as one no longer has to switch between files to adjust the same configuration/code block.

I assume we have to guarantee backwards compatibility, which means that the delimiter syntax __[]__ would have to stay the same.

This is obviously a problem.

Solutions could be:

  • Find a library that allows to set custom delimiters
  • We could try to hide the new functionality behind a feature flag.
    But I assume that this will result in very segmented code :/.
  • A fork that'll be developed in parallel.

Additional context
Adding a full-featured templating engine would obviously add a bit of compile time, but at the same time it provides us with a lot features and it would probably remove a big chunk of custom parsing code from the project.

Bug: linking does not keep file permissions

I use bombadil to link a script with execution permissions, because the symbolic link is based on the copy of the file with variables replaced it does not have execution permisssions.

[FEATURE] - Improve `get var` command

Currently listing variables output the following :

❯ bombadil get vars      
alacritty_background: #292C3E
wob_border_color: #FF6D7070
pulse_audio_fg: #0d0d0d
client_unfocused_indicator: #6D7070
client_focused_indicator: #1BA6FA
light_black: #6D7070
foreground: #EBEBEB
client_urgent_indicator: #6D7070
alacritty_cyan: #21DEEF
magenta: #8763B8
light_cyan: #73FBF1
...

This can quickly be huge if you have a lot of variables in your config. A better solution would be to list variables per files like so :

"bombadil.d/vars.toml" :
  alacritty_background: #292C3E
  wob_border_color: #FF6D7070

"bombadil/another_varfile.toml" : 
  foreground: #EBEBEB
  magenta: #8763B8
# and so on 

Even better we could add info regarding indirection (variable reference) :

"bombadil.d/vars.toml" :
  alacritty_background: %background # here the value should be colored
  wob_border_color: #FF6D7070

"bombadil/another_varfile.toml" : 
  background: #EBEBEB # here the key should have the same color
  magenta: #8763B8
# and so on 

Bombadil should not stop processing dots because of one linking issue

When there are multiple dots that bombadil cannot link, only the first error is shown to the user.

Steps

  1. Create a file with two dots pointing to unexisting sources :
[[dot]]
source = "pouet"
target = ".config/pouet

[[dot]]
source = "pouet2"
target = ".config/pouet2
  1. Run bombadil link command

  2. The output only shows the first error :

Path does not exists : "/home/lucas/.dotfiles/.pouet"

Current behavior :

Bombadil show an error for the first problematic dot and stops processing dots

Proposed behavior :

bombadil should continue processing dots if there is an error.
so it can alert the user on other problematic dots (and also not break the user's system because of one problematic dot)

[FEATURE] - Save the last known state to `.dots` for a clean symlink removal

Let's say we have the following entry installed :

sway = { source = "sway", target = ".config/sway" }

This is linked like this :

# $HOME/.config
sway -> /home/user/dotfiles/.dots/sway

Now we change our sway entry to :

i3 = { source = "i3", target = ".config/i3" }

And run bombadil link.

Doing this we are left with a dangling $HOME/.config/sway symlink.

Since it's not possible to find symlinks from the target file, one way to solve this would be to add a .dots/.state.toml file on
linking. This files would contain a Map(source -> target). Allowing to check for link to removes, even if the config as changed.

[FEATURE] - Allow link specific source file to target file

Is your feature request related to a problem? Please describe.

I'm studying dotfiles manager now, I have'n used toml-bombadil, I just read the docs yet, so maybe it's not a problem.

Some dotfiles could be changed by the application, like vscode settings.json, how to sync the change to the source file?

Describe the solution you'd like

can we allow some file directly to link to the source file instead of .dots, like: `{source="xxx",target="yyy",type="direct"}
Describe alternatives you've considered
Manual copy & paste dotfiles.

Additional context

Like this: Add any other context or screenshots about the feature request here.

[FEATURE] Consider symlinking every file individually when specifying a directory.

Is your feature request related to a problem? Please describe.
Currently when you have multiple files which belong in a directory you just specify the directory, eg.

nvim = { source = "nvim", target = ".config/nvim" }

But there is a problem. Every time you call bombadil link it overwrites the files that neovim creates in the config directory (for example the plugin directory). That means that I have to specify every file and folder which should be linked into .config/vim individually so that it does not overwrite files and directories.

Describe the solution you'd like
I would like that bombadil takes every file in the directory nvim and symlinks it individually when I specify nvim = { source = "nvim", target = ".config/nvim" }.

Describe alternatives you've considered
I considered specifying every file individually, which makes writing the configuration file very tedious.

Of course if you know a way to do what I want without changing anything it would be awesome as well and thank you for this awesome Dotfile Manager!

[BUG] doc bats-test HOWTO.md redirect to 404 pages

To Reproduce

  1. Go to https://oknozor.github.io/toml-bombadil/docs/contributing/how-to-contribute/
  2. Click on HOWTO

Write bats tests

If you have spotted a bug, a great way to help us improve toml bombadil is to write a bats test to reproduce it, see HOWTO for more info.

Expected behavior
Should render html version of https://github.com/oknozor/toml-bombadil/blob/main/bats-tests/HOWTO.md

Additional context
But since bats-test is outside website folder I don't know how to tell Zola taking the file in consideration.
Or update link to point to source (Github) directly

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.