Makefile
author Oleksandr Gavenko <gavenkoa@gmail.com>
Sun, 10 Jan 2016 16:54:12 +0200
changeset 178 ef24ad27c83d
parent 175 9a83576eec4c
child 183 e3293e79262b
permissions -rw-r--r--
Add deploy dependency on CSS file.

#
# You can override such variables in Makefile.config:
#
#   SF_USER     SourceForge user name.

################################################################
# Standard GNU Makefile settings.

SHELL = /bin/bash
export PATH := /bin:/usr/bin:${PATH}

# Disable built in pattern rules.
MAKEFLAGS += -r
# Disable built in variables.
MAKEFLAGS += -R
# Disable built in suffix rules.
.SUFFIXES:
# Delete target file if command fails.
.DELETE_ON_ERROR:
# Default target.
.DEFAULT_GOAL = help

################################################################
# Build script definitions.

BUILD_SCRIPTS := $(firstword $(MAKEFILE_LIST))

ifneq '' '$(wildcard Makefile.config)'
  include Makefile.config
  BUILD_SCRIPTS += Makefile.config
endif

################################################################
# Version extracting/generation.

# Prevent making distribution with wrong version.
ifneq '' '$(filter deploy% dist%,$(MAKECMDGOALS))'
  ifeq '' '$(MAKE_RESTARTS)'
    $(info $(shell rm -f VERSION))
  endif
endif

# Here are vmajor and vminor. Look README section "Versioning rules."
-include VERSION

VERSION:
	\
vtagdist=$$(hg log -r . --template '{latesttagdistance}'); \
vatrelease=$$([ $$vtagdist -le 1 ] && echo yes || echo no); \
vtag=$$(hg log -r . --template '{latesttag}'); \
vmajor=$${vtag#v}; \
vmajor=$${vmajor%%.*}; \
vminor=$${vtag#*.}; \
vrev=$$(hg id -i); \
visclean=$$(case $$vrev in *+) echo no;; *) echo yes;; esac); \
vrev=$${vrev%+}; \
{ \
echo "vrev=$$vrev"; \
echo "vtag=$$vtag"; \
echo "vtagdist=$$vtagdist"; \
echo "visclean=$$visclean"; \
echo "vatrelease=$$vatrelease"; \
echo "vmajor=$$vmajor"; \
echo "vminor=$$vminor"; \
} >VERSION

################################################################
# Determine platform/environment.

host_os = unix
ifneq '' '$(COMSPEC)'
  ifneq '' '$(WINDIR)'
    # Probably under Windows.
    host_os = windows
    ifneq '' '$(wildcard /etc/setup/*cygwin*)'
      # Probably under Cygwin.
      host_os = cygwin
    endif
  endif
endif

################################################################
# Build tools definition/switches.

RST_WARNING_FLAGS := --halt warning
RST_FLAGS := --strip-comments
RST_FLAGS += $(RST_WARNING_FLAGS)

RST2HTML := rst2html
ifeq '$(host_os)' 'cygwin'
  RST2HTML := rst2html.py
endif
RST2HTML_FLAGS := $(RST_FLAGS)

################################################################
# Project dirs/files.

pkgname = 2048-js-ai
sfpkgname = js-2048-ai
fullpkgname = $(pkgname)-$(vmajor).$(vminor)

DIST_DIR = $(fullpkgname)

RST_GEN_FILES := VERSION.rst
RST_COMMON_FILES := VERSION.rst header.rst
RST_FILES := $(filter-out $(RST_COMMON_FILES),$(sort $(wildcard *.rst) $(RST_GEN_FILES)))
RST_HTML_FILES := $(RST_FILES:.rst=.html)

JS_FILES := $(wildcard *.js)
HTML_FILES := 2048.html
CSS_FILES := rst.css
WWW_FILES := $(JS_FILES) $(HTML_FILES) $(CSS_FILES) $(RST_HTML_FILES)

DIST_FILES = $(WWW_FILES) $(RST_FILES) VERSION

DIST_TARBALLS = $(DIST_DIR).tar.gz $(DIST_DIR).zip

JSDOC_DIR := jsdoc

################################################################
# Deploy targets.

ifeq '' '$(SF_USER)'
  SF_USER := gavenkoa
endif
ifeq '' '$(DEFUN_USER)'
  DEFUN_USER := user
endif

.PHONY: deploy
deploy: deploy2defun deploy2sf

.PHONY: deploy2defun
deploy2defun: deploy2defun-src deploy2defun-www

.PHONY: deploy2defun-src
deploy2defun-src:
	hg push ssh://$(DEFUN_USER)@hg.defun.work//srv/hg/2048-js-ai/ || [ $$? = 1 ]

.PHONY: deploy2defun-www
deploy2defun-www: deploy-check $(WWW_FILES)
	( echo 'cd /srv/www/2048'; \
for f in $(WWW_FILES); do \
  echo "put $$f"; \
  echo "chmod 644 $$f"; \
done; \
echo "put 2048.html index.html"; \
echo 'quit'; \
) | sftp -b - $(DEFUN_USER)@defun.work

# First time you deploy to SourceForge (sf) you need manually login to:
#   $ sftp $(SF_USER),$(pkgname)@web.sourceforge.net
# as it may require interactive input for accepting server public key.
# Next time any action fully automated.

.PHONY: deploy2sf
deploy2sf: deploy2sf-src deploy2sf-www deploy2sf-release

.PHONY: deploy2sf-src
deploy2sf-src:
	hg push ssh://$(SF_USER)@hg.code.sf.net/p/$(sfpkgname)/hg || [ $$? = 1 ]

# Will be accessed via http://$(pkgname).sourceforge.net
.PHONY: deploy2sf-www
deploy2sf-www: deploy-check $(WWW_FILES)
	( echo 'cd htdocs'; \
for f in $(WWW_FILES); do \
  echo "put $$f"; \
  echo "chmod 644 $$f"; \
done; \
echo "put 2048.html index.html"; \
echo 'quit'; \
) | sftp -b - $(SF_USER),$(sfpkgname)@web.sourceforge.net

.PHONY: deploy2sf-release
deploy2sf-release: deploy-check $(DIST_TARBALLS)
	( echo 'cd /home/frs/project/$(shell v=$(sfpkgname); echo $${v:0:1}/$${v:0:2})/$(sfpkgname)'; \
echo "put  README.rst"; \
echo "chmod 644 README.rst"; \
echo "mkdir v$(vmajor).$(vminor)"; \
echo "cd v$(vmajor).$(vminor)"; \
for f in $(DIST_TARBALLS); do \
	echo "put $$f"; \
	echo "chmod 644 $$f"; \
done; \
echo 'quit'; \
) | sftp -b - $(SF_USER),$(sfpkgname)@frs.sourceforge.net

.PHONY: deploy-check
deploy-check:
	\
case ${visclean} in \
  no) echo "Local changes found. Build stop."; \
    exit 1;; \
esac
	\
case $(vatrelease) in \
  no) echo "We are not at release. Build stop."; \
    exit 1;; \
esac

################################################################
# Dist targets.

.PHONY: dist
dist: dist-bin

.PHONY: dist-bin
dist-bin: $(DIST_TARBALLS)

%.tar.gz: %
	tar zcf $*.tar.gz $*

%.tar.bz2: %
	tar jcf $*.tar.bz2 $*

%.zip: %
	zip -r $*.zip $*

$(DIST_DIR): $(DIST_FILES)
	rm -rf $@
	mkdir $@
	cp $(DIST_FILES) $@

################################################################
# Documentation targets.

.PHONY: docs
docs: html

.PHONY: html
html: rst2html

.PHONY: rst2html
rst2html: $(RST_HTML_FILES)

$(RST_HTML_FILES): $(RST_COMMON_FILES)

$(RST_HTML_FILES): %.html: %.rst rst.css header.rst VERSION.rst $(BUILD_SCRIPTS)
	$(RST2HTML) $(RST2HTML_FLAGS) --stylesheet=rst.css $*.rst $@

VERSION.rst: VERSION $(BUILD_SCRIPTS)
	{ \
	echo 'For ``$(pkgname)`` version: ``$(vmajor).$(vminor)``.'; \
	echo; \
	case ${visclean} in \
		yes) echo 'Source files are at revision: ``$(vrev)``.';; \
		no) echo 'Some source files was modified from revision: ``$(vrev)``.';; \
	esac; \
	echo; \
	case ${vatrelease} in \
		yes) echo 'Package is at release state.';; \
		no) echo 'Package is far from release state by $(vtagdist) changes.';; \
	esac; \
	echo; \
	echo 'Build date: ``'$$(date +%F)'``.'; \
	} >$@

################################################################
# Helpers targets.

.PHONY: help
help:
	@\
echo; \
echo Current configuration:; \
echo; \
sed 's=^=  =' <VERSION
	@if [ -f Makefile.config ]; then \
		echo; \
		echo User configuration:; \
		echo; \
		sed 's=^=  =' <Makefile.config; \
	fi
	@\
echo; \
echo Supported targets:; \
echo; \
sed -n -e '/^[[:alnum:]_-]*:/{s=^\(.*\):.*=  \1=;p;}' $(BUILD_SCRIPTS)

.PHONY: jsdoc
jsdoc:
	jsdoc -a -p -d=$(JSDOC_DIR) $(JS_FILES)

################################################################
# Clean targets.

.PHONY: distclean
distclean: clean
	rm -f VERSION

.PHONY: clean
clean:
	rm -rf $(JSDOC_DIR) $(RST_GEN_FILES) $(RST_HTML_FILES) $(DIST_DIR) $(DIST_TARBALLS)