Skip to content

Commit

Permalink
Reworked makefile
Browse files Browse the repository at this point in the history
  • Loading branch information
maxim-belkin committed Dec 21, 2019
1 parent b5c2878 commit ba4f717
Show file tree
Hide file tree
Showing 4 changed files with 186 additions and 75 deletions.
122 changes: 47 additions & 75 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,73 +1,51 @@
# Use /bin/bash instead of /bin/sh
export SHELL = /bin/bash

## ========================================
## Commands for both workshop and lesson websites.

# Settings
MAKEFILES=Makefile $(wildcard *.mk)
JEKYLL_VERSION=3.8.5
JEKYLL=bundle install --path .vendor/bundle && bundle update && bundle exec jekyll
PARSER=bin/markdown_ast.rb
DST=_site

# Check Python 3 is installed and determine if it's called via python3 or python
# (https://stackoverflow.com/a/4933395)
PYTHON3_EXE := $(shell which python3 2>/dev/null)
ifneq (, $(PYTHON3_EXE))
ifeq (,$(findstring Microsoft/WindowsApps/python3,$(subst \,/,$(PYTHON3_EXE))))
PYTHON := python3
endif
endif
# #################################################
# ** Customizations **

ifeq (,$(PYTHON))
PYTHON_EXE := $(shell which python 2>/dev/null)
ifneq (, $(PYTHON_EXE))
PYTHON_VERSION_FULL := $(wordlist 2,4,$(subst ., ,$(shell python --version 2>&1)))
PYTHON_VERSION_MAJOR := $(word 1,${PYTHON_VERSION_FULL})
ifneq (3, ${PYTHON_VERSION_MAJOR})
$(error "Your system does not appear to have Python 3 installed.")
endif
PYTHON := python
else
$(error "Your system does not appear to have any Python installed.")
endif
endif
# Markdown parser (requires 'kramdown' & 'json')
PARSER ?= bin/markdown_ast.rb

# Local directory where
DST ?= _site

# Address and port of a locally rendered website
# Used by `jekyll` or Docker
HOST ?= 127.0.0.1
PORT ?= 4000
# ##################################################

# Controls
.PHONY : commands clean files
# Variables & commands
-include tools.mk
-include commands.mk

# Default target
.DEFAULT_GOAL := commands

## I. Commands for both workshop and lesson websites
## =================================================
.PHONY: serve site docker-serve repo-check clean clean-rmd

## * serve : render website and run a local server
serve : lesson-md
${JEKYLL} serve
@$(JEKYLL_SERVE_CMD)

## * site : build website but do not run a server
site : lesson-md
${JEKYLL} build
@$(JEKYLL_BUILD_CMD)

## * docker-serve : use Docker to serve the site
docker-serve :
docker run --rm -it --volume ${PWD}:/srv/jekyll \
--volume=${PWD}/.docker-vendor/bundle:/usr/local/bundle \
-p 127.0.0.1:4000:4000 \
jekyll/jekyll:${JEKYLL_VERSION} \
bin/run-make-docker-serve.sh
@$(DOCKER_SERVE_CMD)

## * repo-check : check repository settings
repo-check :
@${PYTHON} bin/repo_check.py -s .
@$(REPO_CHECK_CMD)

## * clean : clean up junk files
clean :
@rm -rf ${DST}
@rm -rf .sass-cache
@$(JEKYLL_CLEAN_CMD)
@rm -rf bin/__pycache__
@find . -name .DS_Store -exec rm {} \;
@find . -name '*~' -exec rm {} \;
Expand All @@ -82,43 +60,18 @@ clean-rmd :
##
## II. Commands specific to workshop websites
## =================================================

.PHONY : workshop-check
.PHONY: workshop-check

## * workshop-check : check workshop homepage
workshop-check :
@${PYTHON} bin/workshop_check.py .
@$(WORKSHOP_CHECK_CMD)


##
## III. Commands specific to lesson websites
## =================================================

.PHONY : lesson-check lesson-md lesson-files lesson-fixme

# RMarkdown files
RMD_SRC = $(wildcard _episodes_rmd/??-*.Rmd)
RMD_DST = $(patsubst _episodes_rmd/%.Rmd,_episodes/%.md,$(RMD_SRC))

# Lesson source files in the order they appear in the navigation menu.
MARKDOWN_SRC = \
index.md \
CODE_OF_CONDUCT.md \
setup.md \
$(sort $(wildcard _episodes/*.md)) \
reference.md \
$(sort $(wildcard _extras/*.md)) \
LICENSE.md

# Generated lesson files in the order they appear in the navigation menu.
HTML_DST = \
${DST}/index.html \
${DST}/conduct/index.html \
${DST}/setup/index.html \
$(patsubst _episodes/%.md,${DST}/%/index.html,$(sort $(wildcard _episodes/*.md))) \
${DST}/reference/index.html \
$(patsubst _extras/%.md,${DST}/%/index.html,$(sort $(wildcard _extras/*.md))) \
${DST}/license/index.html
.PHONY: lesson-md lesson-check lesson-check-all \
unittest lesson-files lesson-fixme

## * lesson-md : convert Rmarkdown files to markdown
lesson-md : ${RMD_DST}
Expand All @@ -128,15 +81,15 @@ _episodes/%.md: _episodes_rmd/%.Rmd

# * lesson-check : validate lesson Markdown
lesson-check : lesson-fixme
@${PYTHON} bin/lesson_check.py -s . -p ${PARSER} -r _includes/links.md
@$(LESSON_CHECK_CMD)

## * lesson-check-all : validate lesson Markdown, checking line lengths and trailing whitespace
lesson-check-all :
@${PYTHON} bin/lesson_check.py -s . -p ${PARSER} -r _includes/links.md -l -w --permissive
@$(LESSON_CHECK_ALL_CMD)

## * unittest : run unit tests on checking tools
unittest :
@${PYTHON} bin/test_lesson_check.py
@$(UNITTEST_CMD)

## * lesson-files : show expected names of generated files for debugging
lesson-files :
Expand All @@ -152,7 +105,26 @@ lesson-fixme :
##
## IV. Auxililary (plumbing) commands
## =================================================
.PHONY: commands bundle lock

## * commands : show all commands.
commands :
@sed -n -e '/^##/s|^##[[:space:]]*||p' $(MAKEFILE_LIST)

## * bundle : create or update .vendor/bundle.
bundle : .vendor/bundle

.vendor/bundle : Gemfile
@$(BUNDLE_INSTALL_CMD)

## * lock : create or update Gemfile.lock from the current Gemfile
lock : Gemfile.lock

Gemfile.lock : Gemfile
@$(BUNDLE_LOCK_CMD)

Gemfile :
ifeq (, $(wildcard ./Gemfile))
$(error Gemfile not found)
endif

1 change: 1 addition & 0 deletions bin/boilerplate/_config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ defaults:
# Files and directories that are not to be copied.
exclude:
- Makefile
- *.mk
- bin/
- .Rproj.user/
- .vendor/
Expand Down
69 changes: 69 additions & 0 deletions commands.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# JEKYLL_BUILD_CMD
# JEKYLL_CLEAN_CMD
# JEKYLL_SERVE_CMD
ifneq (, $(JEKYLL))
JEKYLL_CMD := jekyll
# We can use 'bundle exec' only if we have a Gemfile
ifneq (, $(wildcard ./Gemfile))
ifneq (, $(BUNDLE))
JEKYLL_CMD := bundle exec $(JEKYLL_CMD)
endif
endif
JEKYLL_BUILD_CMD := $(JEKYLL_CMD) build
JEKYLL_CLEAN_CMD := $(JEKYLL_CMD) clean
JEKYLL_SERVE_CMD := $(JEKYLL_CMD) serve -H $(HOST) -P $(PORT)
else
JEKYLL_BUILD_CMD = $(error Can't build a website: Jekyll not found)
JEKYLL_CLEAN_CMD = rm -rf $(DST) .jekyll-metadata .sass-cache
JEKYLL_SERVE_CMD = $(error Can't serve a website: Jekyll not found)
endif


# DOCKER_SERVE_CMD
ifneq (, $(DOCKER))
DOCKER_SERVE_CMD = \
$(DOCKER) run --rm -it \
--volume ${PWD}:/srv/jekyll \
--volume ${PWD}/.docker-vendor/bundle:/usr/local/bundle \
--publish $(HOST):$(PORT):4000 \
jekyll/jekyll:${JEKYLL_VERSION} \
bin/run-make-docker-serve.sh
else
DOCKER_SERVE_CMD = $(error Can't serve the site using Docker: Docker not found)
endif


# REPO_CHECK_CMD
# WORKSHOP_CHECK_CMD
# LESSON_CHECK_CMD
# LESSON_CHECK_ALL_CMD
# UNITTEST_CMD
ifneq (, $(PYTHON))
REPO_CHECK_CMD = ${PYTHON} bin/repo_check.py -s .
WORKSHOP_CHECK_CMD = ${PYTHON} bin/workshop_check.py .
LESSON_CHECK_CMD = ${PYTHON} bin/lesson_check.py -s . -p ${PARSER} -r _includes/links.md
LESSON_CHECL_ALL_CMD = ${PYTHON} bin/lesson_check.py -s . -p ${PARSER} -r _includes/links.md -l -w --permissive
UNITTEST_CMD = ${PYTHON} bin/test_lesson_check.py
else
REPO_CHECK_CMD = $(error Can't check repository settings: Python 3 not found!)
WORKSHOP_CHECK_CMD = $(error Can't check workshop homepage: Python 3 not found)
LESSON_CHECK_CMD = $(error Can't validate lesson files: Python 3 not found)
LESSON_CHECK_ALL_CMD = $(error Can't validate lesson files: Python 3 not found)
UNITTEST_CMD = $(error Can't perform unit testing: Python 3 not found)
endif


# BUNDLE_INSTALL_CMD
# BUNDLE_LOCK_CMD
ifneq (, $(BUNDLE))
define BUNDLE_INSTALL_CMD
$(BUNDLE) install --path .vendor/bundle
$(BUNDLE) update
endef
BUNDLE_LOCK_CMD = $(BUNDLE) lock --update
else
BUNDLE_INSTALL_CMD = $(error Can't create .vendor/bundle: Bundle not found)
BUNDLE_LOCK_CMD = $(error Can't create/update Gemfile.lock: Bundle not found)
endif


69 changes: 69 additions & 0 deletions tools.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Detect required programs: Gem, Docker, Rscript, Jekyll
GEM ?= $(shell which gem 2>/dev/null)
DOCKER ?= $(shell which docker 2>/dev/null)
RSCRIPT ?= $(shell which Rscript 2>/dev/null)
JEKYLL ?= $(shell which jekyll 2>/dev/null)
BUNDLE ?= $(shell which bundle 2>/dev/null)


# Determine Jekyll version that we need
ifneq (, $(JEKYLL_VERSION))
# Get Jekyll version from the Gemfile.lock
ifneq (, $(wildcard ./Gemfile.lock))
JEKYLL_VERSION := $(shell sed -n "/jekyll\ (=.*)/s|.*(= \(.*\))|\1|p" Gemfile.lock)
endif

ifeq (, $(JEKYLL_VERSION))
# Sync with https://pages.github.com/versions
JEKYLL_VERSION := 3.8.5
endif
endif


# Python
# Check Python 3 is installed and determine if it's called via python3 or python
PYTHON3_EXE := $(shell which python3 2>/dev/null)
ifneq (, $(PYTHON3_EXE))
ifeq (,$(findstring Microsoft/WindowsApps/python3,$(subst \,/,$(PYTHON3_EXE))))
PYTHON := python3
endif
endif

ifeq (,$(PYTHON))
PYTHON_EXE := $(shell which python 2>/dev/null)
ifneq (, $(PYTHON_EXE))
PYTHON_VERSION_FULL := $(wordlist 2,4,$(subst ., ,$(shell python --version 2>&1)))
PYTHON_VERSION_MAJOR := $(word 1,${PYTHON_VERSION_FULL})
ifneq (3, ${PYTHON_VERSION_MAJOR})
$(warning Your system does not appear to have Python 3 installed)
else
PYTHON := python
endif
else
$(warning Your system does not appear to have any Python installed)
endif
endif

# RMarkdown files
RMD_SRC = $(wildcard _episodes_rmd/??-*.Rmd)
RMD_DST = $(patsubst _episodes_rmd/%.Rmd,_episodes/%.md,$(RMD_SRC))

# Lesson source files in the order they appear in the navigation menu.
MARKDOWN_SRC = \
index.md \
CODE_OF_CONDUCT.md \
setup.md \
$(sort $(wildcard _episodes/*.md)) \
reference.md \
$(sort $(wildcard _extras/*.md)) \
LICENSE.md

# Generated lesson files in the order they appear in the navigation menu.
HTML_DST = \
${DST}/index.html \
${DST}/conduct/index.html \
${DST}/setup/index.html \
$(patsubst _episodes/%.md,${DST}/%/index.html,$(sort $(wildcard _episodes/*.md))) \
${DST}/reference/index.html \
$(patsubst _extras/%.md,${DST}/%/index.html,$(sort $(wildcard _extras/*.md))) \
${DST}/license/index.html

0 comments on commit ba4f717

Please sign in to comment.