diff --git a/Build.moon b/Build.moon index 1018365..1622055 100644 --- a/Build.moon +++ b/Build.moon @@ -1,4 +1,3 @@ -public var MOONC: 'moonc' public var AMALG: 'amalg.lua' public var RM: 'rm', '-f', '--' public var LUA: 'lua5.3' @@ -41,27 +40,23 @@ with public target 'mrproper' \after 'clean' \fn => _.cmd RM, BIN, LIB -with public target 'bin' - \depends BIN - -with public target 'lib' - \depends LIB_LUA, LIB - -with target BIN, pattern: 'out/%' - \depends 'bin/%.lua' - \produces 'out/%' - \mkdirs! - \fn => - _.writefile @out, "#!/usr/bin/env #{LUA}\n#{_.readfile @infile}" - _.cmd 'chmod', '+x', @out - -with target LIB - \depends 'moonbuild/init.lua' - \depends LIB_LUA - \produces '%' - \fn => _.cmd AMALG, '-o', @out, '-s', @infile, _.exclude MODULES, 'moonbuild.init' - -with target {LIB_LUA, BIN_LUA}, pattern: '%.lua' - \depends '%.moon' - \produces '%.lua' - \fn => _.moonc @infile, @out +with pipeline! -- lib + \sources LIB_SRC + \step 'compile-lib' + pattern: {'%.moon', '%.lua'} + fn: => _.moonc @infile, @out + \step 'lib' + output: LIB + fn: => _.cmd AMALG, '-o', @out, '-s', 'moonbuild/init.lua', _.exclude MODULES, 'moonbuild.init' + +with pipeline! -- bin + \sources BIN_SRC + \step 'compile-bin' + pattern: {'%.moon', '%.lua'} + fn: => _.moonc @infile, @out + \step 'bin' + pattern: {'bin/%.lua', 'out/%'} + mkdirs: true + fn: => + _.writefile @out, "#!/usr/bin/env #{LUA}\n#{_.readfile @infile}" + _.cmd 'chmod', '+x', @out diff --git a/moonbuild/core/Pipeline.moon b/moonbuild/core/Pipeline.moon new file mode 100644 index 0000000..9328f68 --- /dev/null +++ b/moonbuild/core/Pipeline.moon @@ -0,0 +1,56 @@ +Target = require 'moonbuild.core.Target' +_ = require 'moonbuild._' +import flatten, patsubst from _ + +class Pipeline + new: (@ctx) => + @lastsources = {} + + sources: (...) => + @lastsources = flatten @lastsources, ... + source: (src) => + @lastsources = flatten @lastsources, src + + step: (name, params) => + public = true + public, params = false, name if (type name) == 'table' + + tgttype = if params.pattern + error "pattern must be a table with the same format as patsubst" unless (type params.pattern) == 'table' and (type params.pattern[1]) == 'string' and (type params.pattern[2]) == 'string' + 'pattern' + elseif params.output or params.out + error "output must be a string" unless (type params.output or params.out) == 'string' + 'single' + else + error "invalid step type for pipeline: must be pattern or single (out/output)" + + tgtouts = switch tgttype + when 'pattern' then patsubst @lastsources, params.pattern[1], params.pattern[2] + when 'single' then params.output or params.out + + tgtpatt = switch tgttype + when 'pattern' then params.pattern[2] + when 'single' then nil + + tgtins = switch tgttype + when 'pattern' then params.pattern[1] + when 'single' then @lastsources + + tgtprod = switch tgttype + when 'pattern' then params.pattern[2] + when 'single' then '%' + + tgt = with Target @ctx, tgtouts, pattern: tgtpatt + \depends tgtins + \produces tgtprod + \fn params.fn or error "pipeline steps need a fn" + tgt\mkdirs! if params.mkdirs + tgt\sync! if params.sync + @ctx\addtarget tgt + + if public + @ctx\addtarget with Target @ctx, name + \depends tgtouts + .public = true + + @lastsources = tgtouts diff --git a/moonbuild/env/init.moon b/moonbuild/env/init.moon index 04e6dad..3a1d2b2 100644 --- a/moonbuild/env/init.moon +++ b/moonbuild/env/init.moon @@ -1,5 +1,6 @@ Target = require 'moonbuild.core.Target' Variable = require 'moonbuild.core.Variable' +Pipeline = require 'moonbuild.core.Pipeline' _ = require 'moonbuild._' import flatten from _ @@ -18,8 +19,8 @@ import flatten from _ rawset env, '_G', env rawset env, '_ENV', env - rawset env, 'var', (name, ...) -> - var = Variable name, ... + rawset env, 'var', (...) -> + var = Variable ... ctx\addvar var rawset varlayer, var.name, var.value var @@ -29,4 +30,7 @@ import flatten from _ ctx\addtarget target target + rawset env, 'pipeline', -> + Pipeline ctx + env, varlayer diff --git a/out/moonbuild.lua b/out/moonbuild.lua index d22a888..483bc99 100644 --- a/out/moonbuild.lua +++ b/out/moonbuild.lua @@ -2107,6 +2107,123 @@ return DepGraph end end +do +local _ENV = _ENV +package.preload[ "moonbuild.core.Pipeline" ] = function( ... ) local arg = _G.arg; +local Target = require('moonbuild.core.Target') +local _ = require('moonbuild._') +local flatten, patsubst +flatten, patsubst = _.flatten, _.patsubst +local Pipeline +do + local _class_0 + local _base_0 = { + sources = function(self, ...) + self.lastsources = flatten(self.lastsources, ...) + end, + source = function(self, src) + self.lastsources = flatten(self.lastsources, src) + end, + step = function(self, name, params) + local public = true + if (type(name)) == 'table' then + public, params = false, name + end + local tgttype + if params.pattern then + if not ((type(params.pattern)) == 'table' and (type(params.pattern[1])) == 'string' and (type(params.pattern[2])) == 'string') then + error("pattern must be a table with the same format as patsubst") + end + tgttype = 'pattern' + elseif params.output or params.out then + if not ((type(params.output or params.out)) == 'string') then + error("output must be a string") + end + tgttype = 'single' + else + tgttype = error("invalid step type for pipeline: must be pattern or single (out/output)") + end + local tgtouts + local _exp_0 = tgttype + if 'pattern' == _exp_0 then + tgtouts = patsubst(self.lastsources, params.pattern[1], params.pattern[2]) + elseif 'single' == _exp_0 then + tgtouts = params.output or params.out + end + local tgtpatt + local _exp_1 = tgttype + if 'pattern' == _exp_1 then + tgtpatt = params.pattern[2] + elseif 'single' == _exp_1 then + tgtpatt = nil + end + local tgtins + local _exp_2 = tgttype + if 'pattern' == _exp_2 then + tgtins = params.pattern[1] + elseif 'single' == _exp_2 then + tgtins = self.lastsources + end + local tgtprod + local _exp_3 = tgttype + if 'pattern' == _exp_3 then + tgtprod = params.pattern[2] + elseif 'single' == _exp_3 then + tgtprod = '%' + end + local tgt + do + local _with_0 = Target(self.ctx, tgtouts, { + pattern = tgtpatt + }) + _with_0:depends(tgtins) + _with_0:produces(tgtprod) + _with_0:fn(params.fn or error("pipeline steps need a fn")) + tgt = _with_0 + end + if params.mkdirs then + tgt:mkdirs() + end + if params.sync then + tgt:sync() + end + self.ctx:addtarget(tgt) + if public then + self.ctx:addtarget((function() + do + local _with_0 = Target(self.ctx, name) + _with_0:depends(tgtouts) + _with_0.public = true + return _with_0 + end + end)()) + end + self.lastsources = tgtouts + end + } + _base_0.__index = _base_0 + _class_0 = setmetatable({ + __init = function(self, ctx) + self.ctx = ctx + self.lastsources = { } + end, + __base = _base_0, + __name = "Pipeline" + }, { + __index = _base_0, + __call = function(cls, ...) + local _self_0 = setmetatable({}, _base_0) + cls.__init(_self_0, ...) + return _self_0 + end + }) + _base_0.__class = _class_0 + Pipeline = _class_0 + return _class_0 +end +end +end + do local _ENV = _ENV package.preload[ "moonbuild.core.Target" ] = function( ... ) local arg = _G.arg; @@ -2539,6 +2656,7 @@ local _ENV = _ENV package.preload[ "moonbuild.env.init" ] = function( ... ) local arg = _G.arg; local Target = require('moonbuild.core.Target') local Variable = require('moonbuild.core.Variable') +local Pipeline = require('moonbuild.core.Pipeline') local _ = require('moonbuild._') local flatten flatten = _.flatten @@ -2558,8 +2676,8 @@ return function(ctx) rawset(env, '_', _) rawset(env, '_G', env) rawset(env, '_ENV', env) - rawset(env, 'var', function(name, ...) - local var = Variable(name, ...) + rawset(env, 'var', function(...) + local var = Variable(...) ctx:addvar(var) rawset(varlayer, var.name, var.value) return var @@ -2569,6 +2687,9 @@ return function(ctx) ctx:addtarget(target) return target end) + rawset(env, 'pipeline', function() + return Pipeline(ctx) + end) return env, varlayer end end