DSL for compiling files
-- Makefile
hello: hello.c
$ make hello
cc -o hello hello.c
$ make hello
make: 'hello' er tidssvarende
Use file dependencies and modification time
# Makefile
hello: hello.c
# Catch system calls from process
$ strace -e stat "make hello"
...
stat("hello", {st_mode=S_IFREG|0775, st_size=8559, ...}) = 0
stat("hello.c", {st_mode=S_IFREG|0664, st_size=61, ...}) = 0
...
make: 'hello' er tidssvarende.
Rules
# Makefile
fisk.js: fisk.coffee
%.js: %.coffee
coffee < $< > $@
JS_FINAL = js/project-name-all.js
JS_TARGETS = $(shell find js -name "*.js")
JS_MINIFIED = $(JS_TARGETS:.js=.min.js)
all: $(JS_FINAL)
# Concat
$(JS_FINAL): $(JS_MINIFIED)
cat $^ >$@
rm -f $^
%.min.js: %.js
uglifyjs -o $@ $<
echo >> $@
clean:
rm -f $(JS_FINAL)
Actually build system, but great project "menu" and tool abstraction layer
[Why use make]# Makefile
.PHONY: migrate js
migrate:
php artisan migrate --env=development
js:
# grunt build
gulp
$ make migrate
$ make js
Could also use npm/composer "scripts"
$ composer run-script migrate
At least one pr language
redo, fabricate.py, Tup, ninja, shake
Aim for make, with virtual fs, etc.
Lots of plugins, though
coffee, less, stylus, jade...
// JavaScript
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
concat: {
options: {
separator: ';'
},
dist: {
src: ['src/**/*.js'],
dest: 'dist/<%= pkg.name %>.js'
}
},
uglify: {
options: {
banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n'
},
dist: {
files: {
'dist/<%= pkg.name %>.min.js': ['<%= concat.dist.dest %>']
}
}
},
-> Educas.dkThe streaming build system
var gulp = require("gulp"),
jade = require("gulp-jade");
gulp.task("default", function () {
gulp.src("app/**/*.jade")
.pipe(jade())
.pipe(gulp.dest("public/"));
});
Concurrent tasks
// takes in a callback so the engine knows when it'll be done
orchestrator.add('one', function (cb) {
// do stuff -- async or otherwise
cb(err);
});
// identifies a dependent task must be complete before this one begins
orchestrator.add('two', ['one'], function () {
// task 'one' is done now
});
orchestrator.start('one', 'two');
# .on('something', ...) "EventEmitter"
readable.on('data', function(chunk) {
console.log('got %d bytes of data', chunk.length);
})
readable.on('end', function() {
console.log('there will be no more data.');
});
# Readable stream -> writeable stream
File watching (wraps fs.watch)
gulp.watch("app/**/*.coffee", function () {...});
Virtual files on streams
new File({
cwd: "/home/tbh/educas-dk/",
base: "/app/",
path: "/app/file.coffee"
contents: new Buffer("test = 123")
});
Assets
# Gemfile
source 'https://rails-assets.org'
gem 'rails'
gem 'rails-assets'
gem 'rails-assets-angular'
gem 'rails-assets-bootstrap'
// application.js
//= require angular
angular.module(...)
$ bundle install
$ rails server