about summary refs log tree commit diff
path: root/users/wpcarro/website/blog/content/english/lets-learn-nix-dotfiles.md
diff options
context:
space:
mode:
Diffstat (limited to 'users/wpcarro/website/blog/content/english/lets-learn-nix-dotfiles.md')
-rw-r--r--users/wpcarro/website/blog/content/english/lets-learn-nix-dotfiles.md401
1 files changed, 0 insertions, 401 deletions
diff --git a/users/wpcarro/website/blog/content/english/lets-learn-nix-dotfiles.md b/users/wpcarro/website/blog/content/english/lets-learn-nix-dotfiles.md
deleted file mode 100644
index 084fb19e4406..000000000000
--- a/users/wpcarro/website/blog/content/english/lets-learn-nix-dotfiles.md
+++ /dev/null
@@ -1,401 +0,0 @@
----
-title: "Let's Learn Nix: Dotfiles"
-date: 2020-03-13T22:23:02Z
-draft: true
----
-
-## Let's Learn Nix: Dotfiles
-
-### Dependencies
-
-Speaking of dependencies, here's what you should know before reading this tutorial.
-
-- Basic Nix syntax: Nix 1p
-
-What version of Nix are we using? What version of `<nixpkgs>` are we using? What
-operating system are we using? So many variables...
-
-Cartesian product of all possibilities...
-
-TODO(wpcarro): Create a graphic of the options.
-
-### The problems of dotfiles
-
-How do you manage your dependencies?
-
-You can use `stow` to install the dotfiles.
-
-### home-manager
-
-What we are going to write is most likely less preferable to the following
-alternatives:
-- using Nix home-manager
-- committing your `.gitconfig` into your
-
-In the next tutorial, we will use [home-manager][wtf-home-mgr] to replace the
-functionality that we wrote.
-
-So why bother completing this?
-
-### Let's begin
-
-Welcome to the first tutorial in the [Let's Learn Nix][wtf-lln] series. Today we
-are going to create a Nix derivation for one of your dotfiles.
-
-"Dotfiles" refers to a user's collection of configuration files. Typically these
-files look like:
-- `.vimrc`
-- `.xsessionrc`
-- `.bashrc`
-
-The leading "dot" at the beginning gives dotfiles their name.
-
-You probably have amassed a collection of dotfiles whether or not you are
-aware. For example, if you use [git][wtf-git], the file `~/.gitconfig` should
-exist on your machine. You can verify this with:
-
-```shell
-$ stat ~/.gitconfig
-```
-
-When I was first learning `git`, I learned to configure it using commands I
-found in books and tutorials that often looked like:
-
-```shell
-$ git config user.email
-```
-
-The `~/.gitconfig` file on your machine may look something like this:
-
-```.gitconfig
-[user]
-	name = John Cleese
-	email = john@flying-circus.com
-	username = jcleese
-[core]
-	editor = emacs
-[web]
-	browser = google-chrome
-[rerere]
-	enabled = 1
-	autoupdate = 1
-[push]
-	default = matching
-[color]
-	ui = auto
-[alias]
-	a = add --all
-	ai = add -i
-	b = branch
-	cl = clone
-	cp = cherry-pick
-	d = diff
-	fo = fetch origin
-	lg = log --oneline --graph --decorate
-	ps = push
-	pb = pull --rebase
-	s = status
-```
-
-As I ran increasingly more `git config` commands to configure my `git`
-preferences, the size of my `.gitconfig` increased, and the less likely I was to
-remember which options I set to which values.
-
-Thankfully a coworker at the time, Ryan ([@rschmukler][who-ryan]), told me that
-he version-controlled his `.gitconfig` file along with his other configuration
-files (e.g. `.vimrc`) in a repository he called "dotfiles".
-
-Version-controlling your dotfiles improves upon a workflow where you have a
-variety of configuration files scattered around your machine.
-
-If you look at the above `.gitconfig`, can you spot the dependencies?
-
-We explicitly depend `emacs` and `google-chrome`. We also *implicitly* depend on
-`git`: there is not much value of having a `.gitconfig` file if you also do not
-have `git` installed on your machine.
-
-Dependencies:
-- `emacs`
-- `google-chrome`
-
-Let's use Nix to generate this `.gitconfig` file. Here is what I would like our
-API to be:
-
-Let's create a file `gitconfig.nix` and build our function section-by-section:
-
-TODO(wpcarro): Link to sections here
-- options.user
-- options.core
-- options.web
-- options.rerere
-- options.push
-- options.color
-- options.alias
-
-```shell
-$ touch gitconfig.nix
-```
-
-### options.user
-
-```haskell
-AttrSet -> String
-```
-
-```nix
-user = {
-  name = "John Cleese";
-  email = "john@flying-circus.com";
-  username = "jcleese";
-};
-```
-
-```.gitconfig
-[user]
-	name = John Cleese
-	email = john@flying-circus.com
-	username = jcleese
-```
-
-### options.core
-
-```nix
-core = {
-  editor = "${pkgs.emacs}/bin/emacs";
-};
-```
-
-```.gitconfig
-[core]
-	editor = /nix/store/<hash>-emacs-<version>/bin/emacs
-```
-
-### options.web
-
-```nix
-web.browser = "${pkgs.google-chrome}/bin/google-chrome";
-```
-
-```.gitconfig
-[web]
-	browser = /nix/store/<hash>-google-chrome-<version>/bin/google-chrome
-```
-
-### options.rerere
-
-```nix
-rerere = {
-  enabled = true;
-  autoupdate = true;
-};
-```
-
-```.gitconfig
-[rerere]
-	enabled = 1
-	autoupdate = 1
-```
-
-### options.push
-
-```nix
-push.default = "matching";
-```
-
-```.gitconfig
-[push]
-	default = matching
-```
-
-### options.color
-
-```nix
-color.ui = "auto";
-```
-
-```.gitconfig
-[color]
-	ui = auto
-```
-
-We need to define a function named `gitconfig` that creates a Nix [derivation][wtf-derivation]:
-
-```nix
-# file: gitconfig.nix
-let
-  # Import the <nixpkgs> package repository.
-  pkgs = import <nixpkgs> {};
-
-  # Stringify the attribute set, `xs`, as a multilined string formatted as "<key> = <value>".
-  # See attrsets.nix for more functions that work with attribute sets.
-  encodeAttrSet = xs: lib.concatStringsSep "\n" (lib.mapAttrsToList (k: v: "${k} = ${v}") xs);
-
-  # Define out function name `gitconfig` that accepts an `options` argument.
-  gitconfig = options: pkgs.stdenv.mkDerivation {
-    # The gitconfig file that Nix builds will be located /nix/store/some-hash-gitconfig.
-    name = "gitconfig";
-    src = pkgs.writeTextFile ".gitconfig" ''
-      [user]
-          name = ${options.user.name}
-          email = ${options.user.email}
-          username = ${options.user.username}
-      [core]
-          editor = ${options.core.editor}
-      [web]
-          editor = ${options.web.browser}
-      [rerere]
-          enabled = ${if options.rerere.enabled "1" else "0"}
-          autoupdate = ${if options.rerere.autoupdate "1" else "0"}
-      [push]
-          default = ${options.push.default}
-      [color]
-          ui = ${options.color.ui}
-      [alias]
-          ${encodeAttrSet options.aliases}
-    '';
-    buildPhase = ''
-      ${pkgs.coreutils}/bin/cp $src $out
-    '';
-    installPhase = ''
-      ${pkgs.coreutils}/bin/ln -s $out ~/.gitconfig
-    '';
-  };
-} in gitconfig {
-  user = {
-    name = "John Cleese";
-    email = "john@flying-circus.com";
-    username = "jcleese";
-  };
-  core = {
-    editor = "${pkgs.emacs}/bin/emacs";
-  };
-  web.browser = "${pkgs.google-chrome}/bin/google-chrome";
-  rerere = {
-    enabled = true;
-    autoupdate = true;
-  };
-  push.default = "matching";
-  color.ui = "auto";
-  aliases = {
-	a  = "add --all";
-	ai = "add -i";
-	b  = "branch";
-	cl = "clone";
-	cp = "cherry-pick";
-	d  = "diff";
-	fo = "fetch origin";
-	lg = "log --oneline --graph --decorate";
-	ps = "push";
-	pb = "pull --rebase";
-	s  = "status";
-  };
-}
-```
-
-### options.alias
-
-We want to write a function that accepts an attribute set and returns a
-string. While Nix is a dynamically typed programming language, thinking in types
-helps me clarify what I'm trying to write.
-
-```haskell
-encodeAttrSet :: AttrSet -> String
-```
-
-I prefer using a Haskell-inspired syntax for describing type signatures. Even if
-you haven't written Haskell before, you may find the syntax intuitive.
-
-Here is a non comprehensive, but demonstrative list of example type signatures:
-- `[String]`: A list of strings (i.e. `[ "cogito" "ergo" "sum" ]`)
-- `AttrSet`: A nix attribute set (i.e. `{ name = "John Cleese"; age = 80; }`).
-- `add :: Integer -> Integer -> Integer`: A function named `add` that accepts
-  two integers and returns an integer.
-
-Specifically, we want to make sure that when we call:
-
-```nix
-encodeAttrSet {
-  a = "add --all";
-  b = "branch";
-}
-```
-
-...it returns a string that looks like this:
-
-```.gitconfig
-a = "add --all"
-b = "branch"
-```
-
-
-TODO(wpcarro): @tazjin's nix-1p mentions this. Link to it.
-Nix has useful functions scattered all over the place:
-- `lib.nix`
-- `list.nix`
-- `lib.attrSet`
-
-But I cannot recall exactly which functions we will need to write
-`encodeAttrSet`. In these cases, I do the following:
-1. Run `nix repl`.
-2. Browse the Nix source code.
-
-Google "nix attribute sets" and find the Github link to `attrsets.nix`.
-
-You should consider repeating this search but instead of searching for
-"attribute sets" search for "lists" and "strings". That is how I found the
-functions needed to write `encodeAttrSet`. Let's return to our `nix repl`.
-
-Load the nixpkgs set:
-
-```nix
-nix-repl> :l <nixpkgs>
-Added 11484 variables.
-```
-
-Define a test input called `attrs`:
-
-```nix
-nix-repl> attrs = { fname = "John"; lname = "Cleese"; }
-```
-
-Map the attribute set into `[String]` using `lib.mapAttrsToList`:
-
-```nix
-nix-repl> lib.mapAttrsToList (k: v: "${k} = ${toString v}") attrs
-[ "fname = John" "lname = Cleese" ]
-```
-
-Now join the `[String]` together using `lib.concatStringsSep`:
-
-```nix
-nix-repl> lib.concatStringsSep "\n" (lib.mapAttrsToList (k: v: "${k} = ${v}") attrs)
-"fname = John\nlname = Cleese"
-```
-
-Now let's use this to define our function `encodeAttrSet`:
-
-```nix
-# file: gitconfig.nix
-encodeAttrSet = xs: lib.concatStringsSep "\n" (lib.mapAttrsToList (k: v: "${k} = ${v}") xs);
-```
-
-### Using nixpkgs search
-
-[Nixpkgs search][wtf-nixpkgs-search].
-
-### Conclusion
-
-We learned how to help ourselves.
-
-- Where does `emacs` exist? What about `google-chrome`? [nixpkgs search][wtf-nixpkgs-search]
-- Verify that I have it? [nix REPL][using-nix-repl]
-
-We used Nix to create our first derivation.
-
-[wtf-lln]: /lets-learn-nix
-[wtf-git]: https://git-scm.com/
-[wtf-derivation]: https://nixos.org/nixos/nix-pills/our-first-derivation.html
-[wtf-nixpkgs-search]: https://nixos.org/nixos/packages.html?channel=nixos-19.09
-[using-nix-repl]: /using-the-nix-repl
-[wtf-home-mgr]: https://github.com/rycee/home-manager
-[who-ryan]: https://twitter.com/rschmukler