Perl programmer for hire: download my resume (PDF).
John Bokma's Hacking & Hiking

Using a Makefile

Because tumblelog has many arguments it's a good idea to store the command and its arguments somewhere. While it's possible to create an alias or a bash script, for example, I decided to use a Makefile.

A Short Makefile Tutorial

A simple Makefile consists of one or more "rules" with the following shape:

target: prerequisites …
	recipe
	…
	…

Note: a tab character has to be inserted before each recipe line.

Usually, the target is a file generated by a program. But it also can be the name of an action to carry out. In the latter case the target's name is added as a prerequisite to the .PHONY target to avoid confusing make when there is a file with the same name.

Let's start with a simple example: the stylesheet (CSS) has as its prerequisite the SCSS file and the recipe to create the former from the latter involves the sass command.

TUMBLELOG = ../../projects/tumblelog
SCSS = soothe.scss
SASS = sass --sourcemap=none -t compressed
CSS  = soothe.css

htdocs/$(CSS): $(TUMBLELOG)/styles/$(SCSS)
	$(SASS) $(TUMBLELOG)/styles/$(SCSS) htdocs/$(CSS)

To make the actual recipe easier to read I have defined four variables first. The rule can be read as follows:

The CSS file depends on the latest version of the SCSS file. If the latter is more recent, follow the recipe.

If you run make on this short Makefile each recipe is displayed, in this case just one line. If you don't want to see a recipe you have to put an @ character in front of it.

Note that if you switch to a different style and it's older than the current one no update will happen. In such a case run make with the -B option to unconditionally make all targets.

Next, let's have a look at a rule for generating the local version of the website.

TUMBLELOG = ../../projects/tumblelog
PYTHON = python3
CSS  = soothe.css
DOMAIN = plurrrr.com
TEMPLATE = plurrrr.html
AUTHOR = 'John Bokma'
NAME = 'Plurrrr'
DESCRIPTION = "John Bokma's tumblelog"
BLOG_URL = http://$(DOMAIN)/
BLOG = plurrrr.md

.PHONY: local

local: htdocs/$(CSS)
	@echo "Building latest version of $(NAME) using Python"
	@$(PYTHON) $(TUMBLELOG)/tumblelog.py --output-dir htdocs \
	  --template $(TEMPLATE) --css $(CSS) \
	  --author $(AUTHOR) \
	  --description $(DESCRIPTION) \
	  --blog-url $(BLOG_URL) \
          --name $(NAME) --quiet $(BLOG)

Because the local target is not a file we add it as a prerequisite of the .PHONY target. The local target has one prerequisite, the CSS file. Note that the output of each recipe itself is suppressed using the @ character, but that the message after echo is displayed to show what is happening.

Now that we have a local version of the site we need to upload it.

DOMAIN = plurrrr.com

.PHONY: all local

all: local
	@rsync -avh --delete -c htdocs/ ti:sites/$(DOMAIN)/public/

In this case there is only one recipe: the rsync program is used to synchronise the local htdocs directory with the remote one. Note that I have added an alias ti to my ~/.ssh/config file to save typing.

Important: I use rsync with the --delete option which means that files that are inside the remote directory but not in the local directory will be deleted.

If you have already files in your remote directory, for example .htaccess, and you want to use the --delete option you must copy those files first to the local directory.

Intermezzo: counting days

If you want to see how many days you have been blogging you can use the following:

find htdocs/archive -name '*.html' -print | grep -cv week

This finds all HTML files in the archive directory but only counts (grep option -c) those that don't contain the word week (grep option -v; invert match). I've the following to the local target of my Makefile so after creating all pages it reports the number of days:

@echo -n 'Number of days: ' \
  && find htdocs/archive -name '*.html' -print | grep -cv week

The Complete Makefile

Save the following to a textfile named Makefile inside the same directory that contains the htdocs subdirectory:

TUMBLELOG = ../../projects/tumblelog
PYTHON = python3
SCSS = soothe.scss
SASS = sass --sourcemap=none -t compressed
CSS  = soothe.css
DOMAIN = plurrrr.com
TEMPLATE = plurrrr.html
AUTHOR = 'John Bokma'
NAME = 'Plurrrr'
DESCRIPTION = "John Bokma's tumblelog"
BLOG_URL = http://$(DOMAIN)/
BLOG = plurrrr.md

.PHONY: all local

all: local
	@rsync -avh --delete -c htdocs/ ti:sites/$(DOMAIN)/public/

htdocs/$(CSS): $(TUMBLELOG)/styles/$(SCSS)
	@echo "Compiling stylesheet '$(SCSS)' to '$(CSS)'"
	@$(SASS) $(TUMBLELOG)/styles/$(SCSS) htdocs/$(CSS)

local: htdocs/$(CSS)
	@echo "Building latest version of $(NAME) using Python"
	@$(PYTHON) $(TUMBLELOG)/tumblelog.py --output-dir htdocs \
	  --template $(TEMPLATE) --css $(CSS) \
	  --author $(AUTHOR) \
	  --description $(DESCRIPTION) \
	  --blog-url $(BLOG_URL) \
	  --name $(NAME) --quiet $(BLOG)
	@echo -n 'Number of days: ' \
	  && find htdocs/archive -name '*.html' -print | grep -cv week

Now, if you type make local a local version of your site should be created. If you type make all or just make the local version should be created and uploaded.

Example output:

Compiling stylesheet 'soothe.scss' to 'soothe.css'
Building latest version of 'Plurrrr' using Python
Number of days: 203
sending incremental file list
feed.json
feed.rss
index.html
archive/2019/10/14.html
archive/2019/week/42.html

sent 17.81K bytes  received 1.79K bytes  5.60K bytes/sec
total size is 9.77M  speedup is 498.68

Make from everywhere

Things can be made even easier by creating an alias. The -C option of the make program tells it to change the working directory to the one given and run make from inside this directory.

alias mp='make -C ~/Amber/in-house/sites/plurrrr.com/'

For example, I have the above alias added to ~/.bash_aliases. Now I can just type mp, short for make plurrrr, from any directory and my tumblelog is created and uploaded; no need to cd to the site's working directory first.

Related