jakejs / jake

JavaScript build tool, similar to Make or Rake. Built to work with Node.js.
http://jakejs.com
Apache License 2.0
1.97k stars 190 forks source link

no way to define multi-file tasks #346

Open jedwards1211 opened 6 years ago

jedwards1211 commented 6 years ago

It's pretty common for a build step to generate multiple output files. In this case, one wants a build tool that will run that build step if any of the output files are missing or older than the input files. Here is a simple example of how to do that in GNU make:

SHELL := /bin/bash

src_files     := $(shell find src -type f -name '*.js')
lib_files      := $(patsubst src/%.js, lib/%.js, $(src_files))

.PHONY: lib

lib: $(lib_files)

$(lib_files): $(src_files)
  babel src/ --out-dir lib

As far as I can tell, it's impossible to do this in Jake because file only accepts a single output file name. I could easily generate individual file tasks for each input and output file, but that would be inefficient because running babel individually on each file is many times slower than running it once on a whole directory tree.

To be clear, what I would like to be able to do is:

var glob = require('glob')

var src_files = glob.sync('src/**/*.js')
var lib_files = src_files.map(file => file.replace(/^src/, 'lib')

file(lib_files, src_files, function () {
  jake.exec('babel src/ --out-dir lib')
})

task('lib', lib_files)
welearnednothing commented 6 years ago

@jedwards1211 Try rule instead of file, it’ll do exactly what you’re looking for. The docs have examples that match what you’re trying to do. Let me know if you have any trouble!

jedwards1211 commented 6 years ago

@welearnednothing nope -- from what I see in the docs, rule clearly runs a command on a single input file to produce a single output file, which I explicitly said above is inefficient compared to just running a single babel command on an entire directory tree. I want jake to see if anything in lib is older than anything in src, and if so, run babel src/ --out-dir lib. If there is a way to do that please point me to an example. The hacky way would be to make lib/.babelify the target file and touch it after running the command, to mark the last build time.

welearnednothing commented 6 years ago

@jedwards1211 Gotcha. I swear I’ve done exactly this, but I’m not at my computer to find an example. I’ll dig into it some more. Reopening the ticket.

jedwards1211 commented 6 years ago

@welearnednothing Meanwhile, I made my own build tool 😸 Feel free to check it out: https://github.com/jcoreio/promake