Estimated reading time: 3 minutes

Making a nice home

Back in Kick_me_birthday_reminders I said:

You could trigger a rebuild in your ~/.bashrc before you call rem to see the reminders, so they are always up to date at login. Or, you could be like me and have a post commit hook for git to manage this… because you are keeping your home directory version controlled as a sanity measure I hope!

Today, Stuart Grady asked me in a private mail:

Okay, at which point is the “Tip of the Day” thingy going to be about using hooks and make in $HOME?

I’ll take the hint and look at make. For the purposes of this post we’re going to pretend we haven’t read recursive make considered harmful as I don’t heed its advice for the Makefile I have in my home directory. That said, let’s have a look at what can be found in my current top-level Makefile.

Permissions

I keep my home directory version controlled with git, but git out of the box doesn’t maintain permissions on files(beyond the executable bit anyway). There are plenty of ways around this including using external tools such as etckeeper, but I prefer the simple approach of setting the permissions when they’re needed:

PRIVATE_FILES := .abook/addressbook .gnupg/secring.gpg .mailfilter .msmtprc \
        .ssh/id_rsa
PRIVATE_DIRS := .gnupg

fix-perms: $(PRIVATE_FILES) $(PRIVATE_DIRS)
        $(info - Removing extra read permissions from private files and directories)
        chmod 600 $(PRIVATE_FILES)
        chmod 700 $(PRIVATE_DIRS)

If this rule is called after a git pull is issued then the files always have the correct permissions.

vim hacks

I also call make in some subdirectories, the most interesting one is probably for .vim:

CTAGS := exuberant-ctags

TARGETS := $(patsubst /usr/lib/%, tags/%.ctags, $(wildcard /usr/lib/python*)) \
    doc/tags

.PHONY: clean

all: $(TARGETS)

$(TARGETS): tags/%.ctags: /usr/lib/%
    $(CTAGS) --exclude=test_* --exclude=tests.py --exclude=test.py \
        --exclude=*/test/* --exclude=*/tests/* --languages=python \
        -R -f $@ $<

doc/tags: $(filter-out doc/tags, $(wildcard doc/*))
    vim -X -u NONE -c 'helptags $(dir $@)' -c ':q' </dev/null &>/dev/null

clean:
    rm -f $(TARGETS)

The values in the patsubst block of the TARGETS definition are a list of filenames to use for tag storage with ctags. The rule creates a different ctags file for each installed python version. In the rule to make the ctags files we specifically exclude test files as they aren’t often useful in omni-completion, and they significantly pollute the tags database for normal use.

The final entry in TARGETS simply updates the tag lists for help files installed in ~/.vim/doc.

Documentation

The final subdirectory Makefile we’re going to look at is actually called in a number of different directories to create HTML versions of reStructuredText files.

GENERATED = $(patsubst %.rst, %.html, $(wildcard *.rst))

all: $(GENERATED)

$(GENERATED): %.html: %.rst
        rst2html.py $< $@

If we call the above Makefile from our git hooks after any pull or merge we always have up to date processed versions of documents. It is like having a personal web viewable wiki, but without having to use an awful markup language.


Authenticate this page by pasting this signature into Keybase.

Have a suggestion or see a typo? Edit this page