added post on dotfile management with stow.
This commit is contained in:
		
							parent
							
								
									c64b05bb40
								
							
						
					
					
						commit
						3cf20c608d
					
				
					 1 changed files with 116 additions and 2 deletions
				
			
		| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
+++
 | 
					+++
 | 
				
			||||||
title = "DotfileManagement"
 | 
					title = "Dotfile Management with GNU Stow"
 | 
				
			||||||
date = 2023-07-29T16:37:34-05:00
 | 
					date = 2023-07-29T16:37:34-05:00
 | 
				
			||||||
draft = true
 | 
					draft = false
 | 
				
			||||||
+++
 | 
					+++
 | 
				
			||||||
:caution-caption: pass:[<span style="font-size: 2em">☠</span>]
 | 
					:caution-caption: pass:[<span style="font-size: 2em">☠</span>]
 | 
				
			||||||
:important-caption: pass:[<span style="font-size: 2em">❗</span>]
 | 
					:important-caption: pass:[<span style="font-size: 2em">❗</span>]
 | 
				
			||||||
| 
						 | 
					@ -10,3 +10,117 @@ draft = true
 | 
				
			||||||
:warning-caption: pass:[<span style="font-size: 2em">⚠</span>]
 | 
					:warning-caption: pass:[<span style="font-size: 2em">⚠</span>]
 | 
				
			||||||
:toc:
 | 
					:toc:
 | 
				
			||||||
:toclevels: 6
 | 
					:toclevels: 6
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					So ive been using git to managing my dotfiles since [checks `git log`]... 2018.
 | 
				
			||||||
 | 
					At first, I was going to write some inevitably brittle shell script to handle symlinking from the dotfile repo to where each file should be,
 | 
				
			||||||
 | 
					but before I got about to implementing it, I discovered `stow`.
 | 
				
			||||||
 | 
					Now, after using stow for dotfile management for over 5 years, I figure I should really document exactly how I go about managing my dotfiles, with an aim to help other people who want to have an easy to manage dotfiles repo that can be quickly deployed on new machines.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					== What Stow does
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					https://www.gnu.org/software/stow/[stow] is a 'symlink farm manager', but I almost prefer to think of it a simplistic package manager that makes it incredibly easy to create packages from scratch.
 | 
				
			||||||
 | 
					Like most of the gnu progect utility, the https://www.gnu.org/software/stow/manual/stow.html[documentation] covers a lot, but is a bit intimidating if you dont already know the software.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					At its core, if you are in directory `~/foo`, containing a directory `bar`, whitch itself contains some files and folders like so:
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					~
 | 
				
			||||||
 | 
					└── foo
 | 
				
			||||||
 | 
					    └── bar
 | 
				
			||||||
 | 
					        └── .config
 | 
				
			||||||
 | 
					            └── bar
 | 
				
			||||||
 | 
					                └── bar.cfg
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					`cd` ing into `foo` and running `stow bar` will symlink the contents of `bar` into `~`, resulting in a file structure looking like:
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					.
 | 
				
			||||||
 | 
					├── foo
 | 
				
			||||||
 | 
					│   └── bar
 | 
				
			||||||
 | 
					│       └── .config
 | 
				
			||||||
 | 
					│           └── bar
 | 
				
			||||||
 | 
					│               └── bar.cfg
 | 
				
			||||||
 | 
					└── .config -> ~/foo/bar/.config
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					now, stow does a neat thing called tree folding, so if you make another 'package' in `foo`, so the file tree looks like:
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					.
 | 
				
			||||||
 | 
					├── foo
 | 
				
			||||||
 | 
					│   ├── bar
 | 
				
			||||||
 | 
					│   │   └── .config
 | 
				
			||||||
 | 
					│   │       └── bar
 | 
				
			||||||
 | 
					│   │           └── bar.cfg
 | 
				
			||||||
 | 
					│   └── baz
 | 
				
			||||||
 | 
					│       └── .config
 | 
				
			||||||
 | 
					│           └── baz
 | 
				
			||||||
 | 
					│               └── baz.config
 | 
				
			||||||
 | 
					└── .config -> ~/foo/bar/.config
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					then running stow on baz, (`stow baz`) will result in:
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					.
 | 
				
			||||||
 | 
					├── foo
 | 
				
			||||||
 | 
					│   ├── bar
 | 
				
			||||||
 | 
					│   │   └── .config
 | 
				
			||||||
 | 
					│   │       └── bar
 | 
				
			||||||
 | 
					│   │           └── bar.cfg
 | 
				
			||||||
 | 
					│   └── baz
 | 
				
			||||||
 | 
					│       └── .config
 | 
				
			||||||
 | 
					│           └── baz
 | 
				
			||||||
 | 
					│               └── baz.config
 | 
				
			||||||
 | 
					└── .config
 | 
				
			||||||
 | 
					    ├── bar -> ~/foo/bar/.config/bar
 | 
				
			||||||
 | 
					    └── baz -> ~/foo/bar/.config/baz
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					stow realized that both `bar` and `baz` had `.config` in common, and turned it into a real directory, and remade the symlinks one level lower.
 | 
				
			||||||
 | 
					Stow calls this https://www.gnu.org/software/stow/manual/stow.html#Tree-folding[tree folding].
 | 
				
			||||||
 | 
					It can do the reverse, as well, running `stow -d bar` will result in:
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					.
 | 
				
			||||||
 | 
					├── foo
 | 
				
			||||||
 | 
					│   ├── bar
 | 
				
			||||||
 | 
					│   │   └── .config
 | 
				
			||||||
 | 
					│   │       └── bar
 | 
				
			||||||
 | 
					│   │           └── bar.cfg
 | 
				
			||||||
 | 
					│   └── baz
 | 
				
			||||||
 | 
					│       └── .config
 | 
				
			||||||
 | 
					│           └── baz
 | 
				
			||||||
 | 
					│               └── baz.config
 | 
				
			||||||
 | 
					└── .config -> ~/foo/baz/.config/baz
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					It detected that .config was no longer shared, and unfolded the tree, making `.config` a direct symlink again.
 | 
				
			||||||
 | 
					Note that if .config contained files that stow doesnt 'own', it would leave it alon,e only deleting the 'bar' symlink when `stow --delete bar` was run.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					In short, you can think of stow taking a folder, and symlinking the contents of that folder exactly 2 levels up the directory tree, symlinking `~/foo/bar/contents` directly to `~/contents`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					== Ok, how do I use this to manage my dotfiles?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					So now you know how to stow operates, you can make a 'package' for every program you have dotfiles for.
 | 
				
			||||||
 | 
					Id encorage you to take a look at the directory structure of my dotfiles https://git.venberg.xyz/Gabe/dotfiles[repo] if you want more examples of the directory structure you should aim for.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Once you have the file structure down, all you need to install on a new machine is `git` and `stow`, git clone your dotfile repo, `cd` into it, and `stow` the folders for the software you want to install configs for.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					== Non-stow considerations
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Stow helps you manage your configs, but nothing else.
 | 
				
			||||||
 | 
					A lot of your more complex configs probably reqire other software beyond the program that reads that config.
 | 
				
			||||||
 | 
					for example, my terminal emulator config needs a specific font installed,
 | 
				
			||||||
 | 
					my i3 config requires specific programs installed for which keybinds are defined,
 | 
				
			||||||
 | 
					my neovim config needs things like wget, gzip, python, cargo, xsel, fzf, and others for things from treesitter to clipboard support.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Id encorage your repos readme to have a section on each config package that has external dependencies,
 | 
				
			||||||
 | 
					explaining what dependencies are needed,
 | 
				
			||||||
 | 
					and if the dependency is only needed for a single functionality,
 | 
				
			||||||
 | 
					what functionality they add and what part of the config to comment out if the functionality is not needed.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Id also reccomend you create a directory called `scripts` or something similar that is not a stow package,
 | 
				
			||||||
 | 
					but is put on your `$PATH` by your `.zshrc` / `.bashrc` / `.fishrc` / the dotfile for whatever shell you use.
 | 
				
			||||||
 | 
					This is for you to put any scripts you develop that may be called by/aliased by your configurations.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					== Bootstrapping
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Stow can be found on pretty much every linux distributions package manager. If for some reason it is not, building from source is... suprisingly easy.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					You can find the source http://ftp.gnu.org/gnu/stow/[here], download `stow-latest.tar.gz`, and decompress it with `tar xvf stow-latest.tar.gz`. cd into the the uncompressed folder, and simply run `autoreconf -iv`, `./configure`, and `make`. The binary will be in `./bin/stow` free for you to move it into your `$PATH`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					== Conclusion, or something
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					So, that more or less explains how I manage every bit of text-based configuration on my machine. Again, Id highly reccomend you check out my https://git.venberg.xyz/Gabe/dotfiles[repo] or the repo of anyone else using stow for dotfile management. 
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue