Skip to content
My user configuration files written in Nix
Nix Shell Makefile Other
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.circleci
.githooks
apps
base
contrib
dotfiles
functions
overlays
profiles
scripts
tests
.dir-locals.el
.dockerignore
.gitignore
.gitmodules
.projectile
Dockerfile
Makefile
README.org
bootstrap.sh
choose-profile.bash
home.nix
identity.sample.nix

README.org

Home-Manager Configuration

https://circleci.com/gh/akirak/home.nix.svg?style=svg

This repository contains my user configuration files, which are actually nix configuration files handled by home-manager. If you are looking for a more modern way to manage dotfiles, this repository may or may not be an example. However, a better example will be John Wiegley’s nix-config repository.

Table of contents

Prerequisites

This configuration should run on Linux operating systems.

Installation and usage

Configuration of the Makefile

Administration tasks for this configuration are organized as a set of make tasks.

The following environment variables are set for the entire makefile.

export HOME_MANAGER_CONFIG = $(shell pwd)/home.nix
export NIX_PATH = nixpkgs=$(HOME)/.nix-defexpr/channels/nixpkgs:$(HOME)/.nix-defexpr/channels
export TMPDIR = $(shell scripts/nix-tmpdir)
export NIX_BUILD_SHELL = $(shell nix-build --no-out-link '<nixpkgs>' -A bash)/bin/bash

You will require make from (gnumake package) and git to run tasks in this Makefile.

Updating the configuration

You can update the configuration by running make:

make

The default tasks is defined as follows:

home-manager: tangle deps
	which home-manager >/dev/null 2>&1 || nix-shell '<home-manager>' -A install
	home-manager -I $(shell pwd) switch
	$(MAKE) post-install

Updating home-manager consists of the following tasks:

  1. Install dependencies.
  2. Run home-manager.
  3. Run post installation tasks.

Configuration files in this repository are generated from snippets in this README using org-babel-tangle of Emacs:

tangle:
	if command -v emacs >/dev/null 2>&1; then \
		emacs --batch --eval "(progn (require 'ob) (org-babel-tangle-file \"README.org\"))"; \
	fi

Alternatively, the makefile provides a task which builds the configuration but don’t switch it to check its correctness:

build: tangle
	which home-manager >/dev/null 2>&1 || nix-shell '<home-manager>' -A install
	home-manager -I $(shell pwd) build

Actually, I have set up myrepos to update all of my configuration repositories at once using the following command:

mr up

Initial installation

Bootstrapping

You can install this configuration on any Linux machine without any dependencies:

curl https://raw.githubusercontent.com/akirak/home.nix/master/bootstrap.sh | sh

It installs dependencies, clones the repository in ~/home.nix, and runs all jobs required for installation. It also installs my Emacs configuration if ~/.emacs.d does not exist.

Alternatively, you can clone this repository to anywhere and run

./bootstrap.sh

The following is the full source code of the script:

#!/bin/sh
NIX_OS_VERSION=unstable
HM_URL=https://github.com/rycee/home-manager/archive/master.tar.gz
REPO_URL=https://github.com/akirak/home.nix.git
REPO_DEST="$HOME/home.nix"

set -e

export NIX_BUILD_SHELL=$(command -v bash)

if ! command -v nix-env >/dev/null 2>&1; then
    if ! command -v xz >/dev/null 2>&1; then
        if grep -P ^'ID(_LIKE)?=debian' /etc/os-release >/dev/null; then
            sudo apt-get update --yes && sudo apt-get install --yes xz-utils
        else
            echo "xz program is missing, but don't know how to install it" >&2
            exit 1
        fi
    fi

    curl https://nixos.org/nix/install | sh \
        && . $HOME/.nix-profile/etc/profile.d/nix.sh
fi

nix-channel --add https://nixos.org/channels/nixos-${NIX_OS_VERSION} nixpkgs
nix-channel --add "${HM_URL}" home-manager
nix-channel --update

if ! command -v git >/dev/null 2>&1; then
    nix-env -i git
fi

if ! command -v systemctl >/dev/null 2>&1; then
    echo "Installing systemd from nixpkgs."
    echo "This may not work on non-NixOS distribution."
    nix-env -i systemd
fi

if [ ! -d /etc/nixos ]; then
    mkdir -m 0755 -p /nix/var/nix/{profiles,gcroots}/per-user/$USER
fi

if [ "$PWD" = "${REPO_DEST}" ]; then
    origin="$(git config --local remote.origin.url)"
    # Ensure that the origin is the same as REPO_URL
    [ "$origin" = "${REPO_URL}" ]
else
    if [ ! -d "${REPO_DEST}" ]; then
        git clone "${REPO_URL}" "${REPO_DEST}"
    fi
    cd "${REPO_DEST}"
fi
git submodule update --init --recursive

if nix-env -q 'git.*' >/dev/null 2>&1; then
    echo "Uninstalling git to avoid conflict..."
    nix-env -e git
fi

echo <<EOF
Choose a profile and run

  make all

EOF

if [ -z "${BOOTSTRAP_PREVENT_SUBSHELL}" ]; then
    nix-shell -p gnumake -p git
fi

Choosing a profile

Installation

After configuring your profile, run

make all

to install all the components.

all: install-hooks chemacs cachix home-manager lorri myrepos-checkout

Installing dependencies

Some dependencies cannot be installed by Nix, so they need to be installed in advance.

deps: fuse

FUSE support

fusermount must be installed.

fuse:
	if grep --silent -P "ID(_LIKE)?=debian" /etc/os-release \
		&& ! which fusermount >/dev/null 2>&1; then \
		sudo apt-get install --yes fuse; \
	fi

Post installation

Some tasks need to be run after home-manager.

post-install: system-icons chsh

System icons (only on Chrome OS)

system-icons:
	garcon-helper copy-icons

Change the shell

Somehow this doesn’t work.

chsh:
	scripts/chsh-zsh

Instead, you can install the shell to zsh using the following commands. Of course, you have to install zsh beforehand:

command -v zsh | sudo tee -a /etc/shells
chsh -s `command -v zsh`

Extra stuffs that are not installed by Nix

Other configuration repositories (myrepos)

I use myrepos to manage other configuration repositories.

With this make task, my repositories are automatically checked out. To skip the process, set NO_MR_CHECKOUT environment variable to a non-empty string:

myrepos-checkout:
	if [ ! -f "$(HOME)/.mrconfig" ]; then exit 1; fi
	cd $(HOME)
	if [ -z "$(NO_MR_CHECKOUT)" ]; then mr checkout; fi

Since this depends on mr program and its configuration file, both of which are installed by home-manager, you have to run this task after running home-manager.

Chemacs

chemacs:
	cd contrib/chemacs && bash install.sh

	if [ ! -f "$(HOME)/.emacs-profiles.el" ]; then \
		install -m 644 -t "$(HOME)" -v dotfiles/.emacs-profiles.el; \
	fi

	if [ ! -f "$(HOME)/.custom.el" ]; then \
		touch "$(HOME)/.custom.el"; \
	fi

Cachix

cachix:
	if ! command -v cachix 2>&1 >/dev/null; then \
		nix-env -iA cachix -f https://cachix.org/api/v1/install; \
	fi

Lorri

lorri:
	if ! command -v lorri >/dev/null 2>&1; then \
		scripts/install-lorri; \
	fi

Maintenance

Git hooks

install-hooks:
	if [ -e .git ]; then nix-shell -p git --run 'git config core.hooksPath .githooks'; fi

Synchronising the configuration repositories

Use myrepos to synchronize the configuration repositories with GitHub.

To pull changes from the remotes to the local repositories, run mr update (or mr up for short):

mr up

To push changes to the remotes, run mr push:

mr push

Cleaning up

clean:
	sudo rm -rf /homeless-shelter

Phony

.PHONY: install-hooks all chemacs home-manager system-icons clean \
	chsh update-nix-channels init-home-manager lorri tangle \
	myrepos-checkout cachix

Misc

Docker image

This repository also provides a Docker image, which is mostly intended for running the CI for my Emacs configuration.

Dockerfile

Dockerfile for the image is defined as follows:

FROM nixos/nix
RUN nix-env -i coreutils
ENV HOME /root
RUN mkdir -p /root/home.nix
ADD . /root/home.nix
WORKDIR /root/home.nix
RUN BOOTSTRAP_PREVENT_SUBSHELL=1 sh bootstrap.sh
RUN HOME_NIX_PROFILE_NOCONFIRM=1 \
        nix-shell -p bash --run 'bash choose-profile.bash'
RUN test -e profile.nix
RUN unlink profile.nix
RUN ln -s profiles/linux-full.nix profile.nix
RUN cp identity.sample.nix identity.nix
RUN NO_MR_CHECKOUT=1 nix-shell -p gnumake git --run 'make all'
RUN nix-shell -p bats --run 'bats tests/install-all.bats'
RUN nix-store --gc

CircleCI configuration

The Docker image is built on CircleCI. After running the installation tasks and tests, the produced image is uploaded to Docker Hub.

version: 2.1
executors:
  docker-publisher:
    environment:
      IMAGE_NAME: akirak/home.nix
    docker:
      - image: circleci/buildpack-deps:stretch
jobs:
  build:
    executor: docker-publisher
    steps:
      - checkout
      - setup_remote_docker
      - run: git submodule update --init
      - run:
          name: Build Docker image
          command: docker build -t $IMAGE_NAME:latest .
      - run:
          name: Archive Docker image
          command: docker save -o image.tar $IMAGE_NAME
      - persist_to_workspace:
          root: .
          paths:
            - ./image.tar
  publish-latest:
    executor: docker-publisher
    steps:
      - attach_workspace:
          at: /tmp/workspace
      - setup_remote_docker
      - run:
          name: Load archived Docker image
          command: docker load -i /tmp/workspace/image.tar
      - run:
          name: Publish Docker Image to Docker Hub
          command: |
            echo "$DOCKERHUB_PASS" | docker login -u "$DOCKERHUB_USERNAME" --password-stdin
            docker push $IMAGE_NAME:latest
workflows:
  version: 2
  build-master:
    jobs:
      - build
      - publish-latest:
          requires:
            - build
          filters:
            branches:
              only: master

Meta

You can’t perform that action at this time.