Split JavaScript targets out from the main Makefile.
authorJoe Wreschnig <joe.wreschnig@gmail.com>
Wed, 21 May 2014 07:54:12 +0000 (09:54 +0200)
committerJoe Wreschnig <joe.wreschnig@gmail.com>
Wed, 21 May 2014 07:54:33 +0000 (09:54 +0200)
Remove questionable git hackery and just force dist targets.

Makefile
javascript.mk [new file with mode: 0644]

index 22b272f..6bddcb2 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,82 +1,48 @@
 #!/usr/bin/make -f
 
 PKGNAME := string-lerp
-
-fallback = $(firstword $(shell command -v $(1)) $(2))
+all:
+       $(info Interesting targets:)
+       $(info    lint - validate source (with jshint))
+       $(info    test - run tests (with jstest))
+       $(info    ugly - generate minified source files)
+       $(info    dist - generate redistributables (if git tagged))
+       $(info )
+       $(info (Running these may download packages from npm.))
+       $(info )
+       @:
+
+include javascript.mk
 
 GIT ?= git
-git_ls-tree = $(shell $(GIT) ls-tree -r --name-only $(1))
-git_tag = $(shell $(GIT) name-rev --tags --name-only $(shell $(GIT) rev-parse $(1)))
-
-NPM ?= npm
-NPMBINDIR := ./node_modules/.bin
-JSTEST ?= $(NPMBINDIR)/jstest
-JSHINT ?= $(call fallback,jshint,$(NPMBINDIR)/jshint)
-UGLIFY ?= $(call fallback,uglifyjs,$(NPMBINDIR)/uglifyjs)
-SOURCES := string-lerp.js
-UGLIFIED = $(SOURCES:.js=.min.js)
-
-JSHINTFLAGS += --config tests/jshint.config
+git-describe = $(shell $(GIT) describe --tags --always $1)
 
-TESTS = $(wildcard tests/*.js)
-LINT_TARGETS = $(patsubst %.js,build/stamp/%.lint,$(SOURCES))
-TEST_TARGETS = $(patsubst %.js,build/stamp/%.test,$(SOURCES)) \
-               $(patsubst tests/%.js,build/stamp/%.test,$(TESTS))
-
-.PHONY: all check lint test ugly dist clean distclean install
+SOURCES := string-lerp.js
+UGLIFIED := $(call uglify-stampify,$(SOURCES))
 
-all:
-       @echo "Interesting targets:"
-       @echo "    lint - validate source (with jshint)"
-       @echo "    test - run tests (with jstest)"
-       @echo "    ugly - generate minified/mangled source files"
-       @echo "    dist - generate redistributables (if git tagged)"
-       @echo
-       @echo "(Running these may download packages from npm.)"
-       @echo
-
-%.min.js: %.js | $(UGLIFY)
-       $(UGLIFY) --comments -m < $< > $@
-
-build/stamp/%.lint: %.js | $(JSHINT)
-       @mkdir -p $(@D)
-       $(JSHINT) $(JSHINTFLAGS) $<
-       @touch $@
+JSHINTCONFIG := tests/jshint.config
+JSSTAMPDIR := build/stamp
 
-build/stamp/%.test: tests/%.js %.js | $(JSTEST)
-       @mkdir -p $(@D)
-       @echo $(JSTEST) $<
-       @$(JSTEST) $< > $@ || (cat $@ && rm -f $@ && exit 1)
-       @touch $@
+TESTS := $(wildcard tests/*.js)
+LINTS := $(call jshint-stampify,$(SOURCES) $(TESTS))
+TEST_TARGETS = $(patsubst %.js,build/stamp/tests/%.js.test,$(SOURCES))
 
-build/stamp/%.test: tests/%.js $(SOURCES) | $(JSTEST)
-       @mkdir -p $(@D)
-       @echo $(JSTEST) $<
-       @$(JSTEST) $< > $@ || (cat $@ && rm -f $@ && exit 1)
-       @touch $@
+.DELETE_ON_ERROR:
+.PHONY: all check lint test ugly dist clean distclean install .FORCE
 
 check: lint test
 
-lint: $(LINT_TARGETS)
+lint: $(LINTS)
 
 test: $(TEST_TARGETS)
 
-ugly: $(UGLIFIED)
-
-build/dist/$(PKGNAME)-undefined.zip build/dist/$(PKGNAME)-undefined.tar.gz:
-       $(error Distributables must be tagged or explicitly versioned)
-
-.SECONDEXPANSION:
-build/dist/$(PKGNAME)-%.zip: $$(call git_ls-tree,$$*)
-       @mkdir -p $(@D)
-       $(GIT) archive --prefix=$(PKGNAME)-$*/ --output=$@ $* || ($(RM) $@ && exit 1)
+ugly: check $(UGLIFIED)
 
-.SECONDEXPANSION:
-build/dist/$(PKGNAME)-%.tar.gz: $$(call git_ls-tree,$$*)
+$(PKGNAME)-%.zip $(PKGNAME)-%.tar.gz: .FORCE
        @mkdir -p $(@D)
-       $(GIT) archive --prefix=$(PKGNAME)-$*/ --output=$@ $* || ($(RM) $@ && exit 1)
+       $(GIT) archive --prefix=$(PKGNAME)-$(*F)/ --output=$@ $(*F)
 
-dist: check $(addprefix build/dist/$(PKGNAME)-$(call git_tag,HEAD),.zip .tar.gz)
+dist: check $(addprefix build/dist/$(PKGNAME)-$(call git-describe),.zip .tar.gz)
 
 clean:
        $(RM) -r build
@@ -87,12 +53,3 @@ distclean: clean
 
 install: check
        $(NPM) install -g .
-
-$(JSTEST):
-       $(NPM) install jstest
-
-$(JSHINT):
-       $(NPM) install jshint
-
-$(UGLIFY):
-       $(NPM) install uglify-js
diff --git a/javascript.mk b/javascript.mk
new file mode 100644 (file)
index 0000000..45b4a03
--- /dev/null
@@ -0,0 +1,59 @@
+# This is free and unencumbered software released into the public
+# domain. To the extent possible under law, the author of this file
+# waives all copyright and related or neighboring rights to it.
+
+.DELETE_ON_ERROR:
+
+javascript>fallback = $(firstword $(shell command -v $1) $2 $1)
+
+NPM ?= npm
+NPMROOT ?= .
+
+npmbindir = $(NPMROOT)/node_modules/.bin
+.PRECIOUS: $(npmbindir)/%
+
+from-npm = $(call javascript>fallback,$1,$(npmbindir)/$1)
+
+JSTEST ?= $(npmbindir)/jstest
+JSHINT ?= $(call from-npm,jshint)
+
+uglifyjs_npm_package := uglify-js
+
+UGLIFY ?= $(call from-npm,uglifyjs)
+UGLIFYFLAGS ?= --comments \
+               --compress $(UGLIFYCOMPRESSFLAGS) \
+               --mangle $(UGLIFYMANGLEFLAGS)
+
+JSSTAMPDIR ?= build/stamp
+JSHINTDIR ?= $(JSSTAMPDIR)
+JSTESTDIR ?= $(JSSTAMPDIR)
+JSUGLYDIR ?= .
+
+JSHINTFLAGS += $(if $(JSHINTCONFIG),--config $(JSHINTCONFIG))
+JSTESTFLAGS += $(if $(JSTESTFORMAT),--format $(JSTESTFORMAT))
+JSTESTFORMAT ?= spec
+
+jshint-stampify = $(patsubst %.js,$(JSHINTDIR)/%.js.lint,$1)
+uglify-stampify = $(patsubst %.js,$(JSUGLYDIR)/%.min.js,$1)
+
+javascript>capture-to-target = @echo "$1" && $1 > $@ || (cat $@ && exit 1)
+
+UGLIFY.js = $(UGLIFY) $(UGLIFYFLAGS)
+LINT.js = $(JSHINT) $(JSHINTFLAGS)
+TEST.js = $(JSTEST) $(JSTESTFLAGS)
+
+$(JSUGLYDIR)/%.min.js: %.js | $(UGLIFY)
+       @mkdir -p $(@D)
+       $(UGLIFY.js) < $< > $@
+
+$(JSHINTDIR)/%.js.lint: %.js | $(JSHINT)
+       @mkdir -p $(@D)
+       $(LINT.js) $<
+       @touch $@
+
+$(JSTESTDIR)/%.js.test: %.js | $(JSTEST)
+       @mkdir -p $(@D)
+       $(call javascript>capture-to-target,$(TEST.js) $<)
+
+$(npmbindir)/%:
+       $(NPM) install $(firstword $(value $(@F)_npm_package) $(@F))