Split JavaScript targets out from the main Makefile.
[string-lerp.git] / javascript.mk
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))