# Build the library

.PHONY: all clean

all: lib/libplayit.sh.2

lib/libplayit.sh.2: src/*/*.sh
	mkdir --parents lib
	find src -type f -name '*.sh' -print0 | LC_ALL=C sort -z | xargs -0 cat > lib/libplayit.sh.2

clean:
	rm --force lib/libplayit.sh.2


# Install the command. library, and man pages

.PHONY: install uninstall

## Set the default install paths
UID := $(shell id --user)
ifeq ($(UID),0)
    prefix = /usr/local
else
    prefix = $(HOME)/.local
endif
bindir = $(prefix)/bin
libdir = $(prefix)/lib
datadir = $(prefix)/share
mandir = $(datadir)/man
zshdir = $(datadir)/zsh
fishdir = $(datadir)/fish

install: all
	install -D --mode=755 play.it $(DESTDIR)$(bindir)/play.it
	install -D --mode=644 lib/libplayit.sh.2 $(DESTDIR)$(libdir)/play.it/libplayit.sh.2
	install -D --mode=644 man/man6/play.it.6 $(DESTDIR)$(mandir)/man6/play.it.6
	install -D --mode=644 man/fr/man6/play.it.6 $(DESTDIR)$(mandir)/fr/man6/play.it.6
	# Library compatibility link
	ln --symbolic --force \
		$(DESTDIR)$(libdir)/play.it/libplayit.sh.2 \
		$(DESTDIR)$(datadir)/play.it/libplayit2.sh

uninstall: uninstall-completion
	rm --force \
		$(DESTDIR)$(bindir)/play.it \
		$(DESTDIR)$(libdir)/play.it/libplayit.sh.2 \
		$(DESTDIR)$(mandir)/man6/play.it.6 \
		$(DESTDIR)$(mandir)/fr/man6/play.it.6
	rmdir --parents --ignore-fail-on-non-empty \
		$(DESTDIR)$(bindir) \
		$(DESTDIR)$(libdir)/play.it \
		$(DESTDIR)$(mandir)/man6 \
		$(DESTDIR)$(mandir)/fr/man6
	# Library compatibility link
	rm --force $(DESTDIR)$(datadir)/play.it/libplayit2.sh
	rmdir --parents --ignore-fail-on-non-empty $(DESTDIR)$(datadir)/play.it


# Install shell completion

.PHONY: install-completion-all install-completion-zsh install-completion-fish uninstall-completion

install-completion-all: install-completion-zsh install-completion-fish

install-completion-zsh:
	install -D --mode=644 shell-completions/zsh/_play.it $(DESTDIR)$(zshdir)/vendor-completions/_play.it

install-completion-fish:
	install -D --mode=644 shell-completions/fish/play.it.fish $(DESTDIR)$(fishdir)/vendor_completions.d/play.it.fish

uninstall-completion:
	rm --force $(DESTDIR)$(zshdir)/vendor-completions/_play.it
	rm --force $(DESTDIR)$(fishdir)/vendor_completions.d/play.it.fish
	test -d $(DESTDIR)$(zshdir)/vendor-completions && \
		rmdir --parents --ignore-fail-on-non-empty $(DESTDIR)$(zshdir)/vendor-completions || true
	test -d $(DESTDIR)$(fishdir)/vendor_completions.d && \
		rmdir --parents --ignore-fail-on-non-empty $(DESTDIR)$(fishdir)/vendor_completions.d || true


# Release preparation

.PHONY: dist

## The generated tarball is signed with gpg by default,
## NO_SIGN should be set to a non-0 value to skip the signature.
NO_SIGN := 0

dist: VERSION = $(shell head --lines=1 CHANGELOG)
dist: TARBALL = play.it-$(VERSION).tar.gz
dist: TAR_OPTIONS := --sort=name --mtime=2017-06-14 --owner=root:0 --group=root:0 --use-compress-program='gzip --no-name'
dist: CHANGELOG LICENSE README.md Makefile play.it man/man6/play.it.6 man/fr/man6/play.it.6 shell-completions/zsh/_play.it shell-completions/fish/play.it.fish src/*/*.sh tests/shunit2/*.sh
	mkdir --parents dist
	LC_ALL=C tar cf dist/$(TARBALL) $(TAR_OPTIONS) \
		   CHANGELOG \
		   LICENSE \
		   README.md \
		   Makefile \
		   play.it \
		   man/man6/play.it.6 \
		   man/fr/man6/play.it.6 \
		   shell-completions/zsh/_play.it \
		   shell-completions/fish/play.it.fish \
		   src/*/*.sh \
		   tests/shunit2/*.sh
ifeq ($(NO_SIGN),0)
	rm --force dist/$(TARBALL).asc
	gpg --armor --detach-sign dist/$(TARBALL)
endif


# Run tests, including:
# - syntax checks, relying on ShellCheck
# - regression tests, relying on shUnit2
# - man page syntax check

.PHONY: check shellcheck-library shellcheck-wrapper shunit2 man-syntax

check: shellcheck-library shellcheck-wrapper shunit2 man-syntax

## This is a unicode quote. Delete and retype it (or ignore/doublequote for literal).
shellcheck-library: SHELLCHECK_EXCLUDE += --exclude=SC1112
## Expressions don't expand in single quotes, use double quotes for that.
shellcheck-library: SHELLCHECK_EXCLUDE += --exclude=SC2016
## Double quote to prevent globbing and word splitting.
shellcheck-library: SHELLCHECK_EXCLUDE += --exclude=SC2086
## In POSIX sh, local is undefined.
shellcheck-library: SHELLCHECK_EXCLUDE += --exclude=SC3043
shellcheck-library:
	shellcheck --shell=sh $(SHELLCHECK_EXCLUDE) lib/libplayit.sh.2

shellcheck-wrapper:
	shellcheck --external-sources --shell=sh play.it

SHUNIT2_SCRIPTS := $(wildcard tests/shunit2/*.sh)
SHUNIT2_TESTS := $(addprefix shunit2_, $(SHUNIT2_SCRIPTS))
.PHONY: $(SHUNIT2_TESTS)
shunit2: $(SHUNIT2_TESTS)
$(SHUNIT2_TESTS): shunit2_%: %
	shunit2 $<

man-syntax:
	man --warnings --encoding=UTF-8 --local-file --troff-device=utf8 --ditroff man/man6/play.it.6 >/dev/null
	man --warnings --encoding=UTF-8 --local-file --troff-device=utf8 --ditroff man/fr/man6/play.it.6 >/dev/null
