1
0
mirror of https://github.com/natnat-mc/moonbuild synced 2026-05-28 08:29:40 +02:00

16 Commits

Author SHA1 Message Date
Nathan DECHER 0779ea3ad4 Producing rockspec 1.1.3-1 2020-09-15 11:37:21 +02:00
Nathan DECHER e3e185110a Merge branch 'master' of github.com:natnat-mc/moonbuild 2020-09-15 11:37:04 +02:00
Nathan DECHER 7b4973f0b4 fixed wildcard and normalizepath 2020-09-15 11:36:44 +02:00
Nathan DECHER c96b2ece70 fixed wildcard and normalizepath 2020-09-15 11:36:17 +02:00
Nathan DECHER 0e23ccecfb Producing rockspec 1.1.2-1 2020-09-14 11:28:51 +02:00
Nathan DECHER ccce358155 min and max were broken, fixed them 2020-09-14 11:28:35 +02:00
Nathan DECHER a125eab22f Producing rockspec 1.1.1-1 2020-09-14 11:08:19 +02:00
Nathan DECHER 0c43e3a5b1 fixed broken cache 2020-09-14 11:08:04 +02:00
Nathan DECHER cf252749f4 Producing rockspec 1.1.0-1 2020-09-14 09:45:21 +02:00
Nathan DECHER 16673afc61 install actually installs with correct perms 2020-09-14 09:44:46 +02:00
Nathan DECHER a26a1500df added fs cache, closes #9 2020-09-14 09:44:30 +02:00
Nathan DECHER d2db470347 rockspec? 2020-09-13 21:40:35 +02:00
Nathan DECHER b80e9d38bb Producing rockspec 1.0.3-3 2020-09-13 21:08:44 +02:00
Nathan DECHER 61f32c0675 Producing rockspec 1.0.3-1 2020-09-13 21:08:16 +02:00
Nathan DECHER 04ca1f5a10 -d is cleaner 2020-09-13 21:07:53 +02:00
Nathan DECHER ffce216a34 re-added install target that doesn't use luarocks 2020-09-13 21:05:25 +02:00
17 changed files with 527 additions and 530 deletions
+2 -1
View File
@@ -1 +1,2 @@
/*/**.lua
/moonbuild/*.lua
/bin/*.lua
+2
View File
@@ -1,6 +1,8 @@
tasks:
build: =>
sh "moon bin/moonbuild.moon compile"
install: =>
sh "moon bin/moonbuild.moon install"
release: =>
error "no version provided" unless @v
tasks.build!
+16 -3
View File
@@ -5,15 +5,28 @@ BINARY_LUA = patsubst BINARY, '%.moon', '%.lua'
OUT_AMALG = 'moonbuild.lua'
public target 'clean', fn: =>
-rm '-f', OUT_LUA
-rm '-f', OUT_LUA, BINARY_LUA
public target 'info', fn: =>
#echo "Moonscript sources:", SOURCES_MOON
#echo "Compiled lua:", OUT_LUA
default target 'compile', from: OUT_AMALG
public target 'compile', deps: OUT_AMALG
target OUT_AMALG, from: {BINARY_LUA, OUT_LUA}, out: OUT_AMALG, fn: =>
public target 'install', from: OUT_AMALG, out: '/usr/local/bin/moonbuild', fn: =>
dfd, err = io.open @outfile, 'w'
error err unless dfd
ifd, err = io.open @infile, 'r'
error err unless ifd
dfd\write '#!/usr/bin/env lua5.3\n'
for line in ifd\lines!
dfd\write line, '\n'
ifd\close!
dfd\close!
-chmod '+x', @outfile
#echo "Installed at:", @outfile
default target OUT_AMALG, from: {BINARY_LUA, OUT_LUA}, out: OUT_AMALG, fn: =>
modules = foreach (patsubst OUT_LUA, '%.lua', '%'), => @gsub '/', '.'
-Command 'amalg.lua', '-o', @outfile, '-s', 'bin/moonbuild.lua', modules
+3
View File
@@ -10,7 +10,10 @@ Basically like `make`, but in [Moonscript](https://moonscript.org) and with expl
It's fast, based on lua, and it's easy to write DSLs with it, so the build instructions can be readable. Also, it's a full programming language, so there are no arbitrary restrictions.
## How do I install it?
Any of these will work
- `luarocks install moonbuild` (probably as root)
- `moon bin/moonbuild.moon install` (probably as root, in the cloned repo)
- `alfons install` (probably as root, in the cloned repo, requires alfons)
## Now, how do I use it?
First, you'll need a `Build.moon`, `Buildfile.moon`, `Build` or `Buildfile` in the root of your project.
-429
View File
@@ -1,429 +0,0 @@
local argparse = require('argparse')
require('moonscript')
local loadfile
loadfile = require('moonscript.base').loadfile
local truncate_traceback, rewrite_traceback
do
local _obj_0 = require('moonscript.errors')
truncate_traceback, rewrite_traceback = _obj_0.truncate_traceback, _obj_0.rewrite_traceback
end
local trim
trim = require('moonscript.util').trim
local util = require('moonbuild.util')
local exists, mtime, run, min, max, first, flatten, match, patsubst, sortedpairs
exists, mtime, run, min, max, first, flatten, match, patsubst, sortedpairs = util.exists, util.mtime, util.run, util.min, util.max, util.first, util.flatten, util.match, util.patsubst, util.sortedpairs
local insert, concat
do
local _obj_0 = table
insert, concat = _obj_0.insert, _obj_0.concat
end
local parser = argparse('moonbuild')
parser:argument('targets', "Targets to run"):args('*')
parser:flag('-a --noskip', "Always run targets")
parser:flag('-l --list', "List available targets")
parser:flag('-d --deps', "List targets and their dependancies")
local args = parser:parse()
local loadwithscope
loadwithscope = function(file, scope)
local fn, err = loadfile(file)
if not (fn) then
error(err or "failed to load code")
end
local dumped
dumped, err = string.dump(fn)
if not (dumped) then
error(err or "failed to dump function")
end
return load(dumped, file, 'b', scope)
end
local pcall
pcall = function(fn, ...)
local rewrite
rewrite = function(err)
local trace = debug.traceback('', 2)
local trunc = truncate_traceback(trim(trace))
return rewrite_traceback(trunc, err)
end
return xpcall(fn, rewrite, ...)
end
local Command
do
local _class_0
local _base_0 = {
__unm = function(self)
return self:run({
error = true,
print = true
})
end,
__len = function(self)
return self:run({
error = true
})
end,
__tostring = function(self)
return self.cmd
end,
run = function(self, params)
return run(self.cmd, self.args, params)
end
}
_base_0.__index = _base_0
_class_0 = setmetatable({
__init = function(self, cmd, ...)
self.cmd = cmd
self.args = {
...
}
end,
__base = _base_0,
__name = "Command"
}, {
__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
local self = _class_0
self.run = function(self, ...)
return -self(...)
end
Command = _class_0
end
local BuildObject
do
local _class_0
local all, skip
local _base_0 = {
__tostring = function(self)
return "Target " .. tostring(self.name) .. " (" .. tostring(concat(self.deps, ', ')) .. ")"
end,
build = function(self, name, upper)
if upper == nil then
upper = { }
end
if skip[name] then
return
end
if upper[self] then
error("Cycle detected on " .. tostring(self.name))
end
upper = setmetatable({
[self] = true
}, {
__index = upper
})
if self.name ~= name then
local _list_0 = self.deps
for _index_0 = 1, #_list_0 do
local dep = _list_0[_index_0]
self.__class:build((patsubst(name, self.name, dep)), upper)
end
else
local _list_0 = self.deps
for _index_0 = 1, #_list_0 do
local dep = _list_0[_index_0]
self.__class:build(dep, upper)
end
end
if not (self:shouldbuild(name)) then
return
end
local ins = self.ins
local outs = self.outs
if self.name ~= name then
do
local _accum_0 = { }
local _len_0 = 1
local _list_0 = self.ins
for _index_0 = 1, #_list_0 do
local elem = _list_0[_index_0]
_accum_0[_len_0] = patsubst(name, self.name, elem)
_len_0 = _len_0 + 1
end
ins = _accum_0
end
do
local _accum_0 = { }
local _len_0 = 1
local _list_0 = self.outs
for _index_0 = 1, #_list_0 do
local elem = _list_0[_index_0]
_accum_0[_len_0] = patsubst(name, self.name, elem)
_len_0 = _len_0 + 1
end
outs = _accum_0
end
print("Building " .. tostring(self.name) .. " as " .. tostring(name))
else
print("Building " .. tostring(name))
end
local ok, err = pcall(function()
return self.fn({
ins = ins,
outs = outs,
infile = ins[1],
outfile = outs[1],
name = name
})
end)
if not (ok) then
error("Can't build " .. tostring(self.name) .. ": lua error\n" .. tostring(err))
end
for _index_0 = 1, #outs do
local f = outs[_index_0]
if not (exists(f)) then
error("Can't build " .. tostring(self.name) .. ": output file " .. tostring(f) .. " not created")
end
end
skip[name] = true
end,
shouldbuild = function(self, name)
if args.noskip then
return true
end
if #self.ins == 0 or #self.outs == 0 then
return true
end
local ins
if self.name ~= name then
do
local _accum_0 = { }
local _len_0 = 1
local _list_0 = self.ins
for _index_0 = 1, #_list_0 do
local elem = _list_0[_index_0]
_accum_0[_len_0] = patsubst(name, self.name, elem)
_len_0 = _len_0 + 1
end
ins = _accum_0
end
else
ins = self.ins
end
local itimes
do
local _accum_0 = { }
local _len_0 = 1
for _index_0 = 1, #ins do
local f = ins[_index_0]
_accum_0[_len_0] = mtime(f)
_len_0 = _len_0 + 1
end
itimes = _accum_0
end
for i = 1, #self.ins do
if not (itimes[i]) then
error("Can't build " .. tostring(self.name) .. ": missing inputs")
end
end
local outs
if self.name ~= name then
do
local _accum_0 = { }
local _len_0 = 1
local _list_0 = self.outs
for _index_0 = 1, #_list_0 do
local elem = _list_0[_index_0]
_accum_0[_len_0] = patsubst(name, self.name, elem)
_len_0 = _len_0 + 1
end
outs = _accum_0
end
else
outs = self.outs
end
local otimes
do
local _accum_0 = { }
local _len_0 = 1
for _index_0 = 1, #outs do
local f = outs[_index_0]
_accum_0[_len_0] = mtime(f)
_len_0 = _len_0 + 1
end
otimes = _accum_0
end
for i = 1, #self.outs do
if not otimes[i] then
return true
end
end
return (max(itimes)) > (min(otimes))
end
}
_base_0.__index = _base_0
_class_0 = setmetatable({
__init = function(self, name, outs, ins, deps, fn)
if outs == nil then
outs = { }
end
if ins == nil then
ins = { }
end
if deps == nil then
deps = { }
end
if fn == nil then
fn = function(self) end
end
self.name, self.outs, self.ins, self.deps, self.fn = name, outs, ins, deps, fn
self.skip = false
if all[self.name] then
error("Duplicate build name " .. tostring(self.name))
end
all[self.name] = self
end,
__base = _base_0,
__name = "BuildObject"
}, {
__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
local self = _class_0
all = { }
skip = { }
self.find = function(self, name)
local target = all[name]
if target then
return target
end
for glob, tgt in pairs(all) do
if match(name, glob) then
return tgt
end
end
return nil
end
self.list = function(self)
local _tbl_0 = { }
for name, target in pairs(all) do
do
local _tbl_1 = { }
local _list_0 = target.deps
for _index_0 = 1, #_list_0 do
local dep = _list_0[_index_0]
_tbl_1[dep] = self:find(dep)
end
_tbl_0[target] = _tbl_1
end
end
return _tbl_0
end
self.build = function(self, name, upper)
local target = (self:find(name)) or error("No such target: " .. tostring(name))
return target:build(name, upper)
end
BuildObject = _class_0
end
if setfenv then
error("Need Lua >=5.2")
end
local targets = { }
local defaulttarget = 'all'
local buildscope = {
default = function(target)
defaulttarget = target.name
return target
end,
public = function(target)
insert(targets, target.name)
return target
end,
target = function(name, params)
local tout = flatten(params.out)
local tin = flatten(params["in"])
local tdeps = flatten(params.deps)
local _list_0 = flatten(params.from)
for _index_0 = 1, #_list_0 do
local f = _list_0[_index_0]
insert(tin, f)
insert(tdeps, f)
end
return BuildObject(name, tout, tin, tdeps, params.fn)
end,
Command = Command
}
for k, fn in pairs(util) do
buildscope[k] = fn
end
setmetatable(buildscope, {
__index = function(self, k)
local global = rawget(_G, k)
if global then
return global
end
return function(...)
return Command(k, ...)
end
end
})
local file = first({
'Build.moon',
'Buildfile.moon',
'Build',
'Buildfile'
}, exists)
if not (file) then
error("No Build.moon or Buildfile found")
end
local buildfn = loadwithscope(file, buildscope)
if not (buildfn) then
error("Failed to load build function")
end
local ok, err = pcall(buildfn)
if not (ok) then
if err then
io.stderr:write(err, '\n')
else
io.stderr:write("Unknown error\n")
end
os.exit(1)
end
if args.list then
io.write("Available targets:\n")
io.write("\t" .. tostring(concat(targets, ', ')) .. "\n")
os.exit(0)
end
if args.deps then
io.write("Targets:\n")
for target, deps in sortedpairs(BuildObject:list(), function(a, b)
return a.name < b.name
end) do
io.write("\t" .. tostring(target.name) .. " ")
if #target.ins == 0 then
if #target.outs == 0 then
io.write("[no in/out]")
else
io.write("[spontaneous generation]")
end
else
if #target.outs == 0 then
io.write("[consumer]")
else
io.write("(" .. tostring(concat(target.ins, ', ')) .. " -> " .. tostring(concat(target.outs, ', ')) .. ")")
end
end
io.write("\n")
for name, dep in sortedpairs(deps) do
io.write("\t\t" .. tostring(name) .. " (" .. tostring(dep.name) .. ")\n")
end
end
os.exit(0)
end
if #args.targets == 0 then
BuildObject:build(defaulttarget)
end
local _list_0 = args.targets
for _index_0 = 1, #_list_0 do
local target = _list_0[_index_0]
BuildObject:build(target)
end
+61 -48
View File
@@ -1,43 +1,44 @@
#!/usr/bin/env moon
argparse=require 'argparse'
argparse = require 'argparse'
require 'moonscript'
import loadfile from require 'moonscript.base'
import truncate_traceback, rewrite_traceback from require 'moonscript.errors'
import trim from require 'moonscript.util'
util=require 'moonbuild.util'
util = require 'moonbuild.util'
import freezecache, invalidatecache from require 'moonbuild.fsutil'
import exists, mtime, run, min, max, first, flatten, match, patsubst, sortedpairs from util
import insert, concat from table
parser=argparse 'moonbuild'
parser = argparse 'moonbuild'
parser\argument('targets', "Targets to run")\args '*'
parser\flag '-a --noskip', "Always run targets"
parser\flag '-l --list', "List available targets"
parser\flag '-d --deps', "List targets and their dependancies"
args=parser\parse!
args = parser\parse!
-- util functions
loadwithscope= (file, scope) ->
fn, err=loadfile file
loadwithscope = (file, scope) ->
fn, err = loadfile file
error err or "failed to load code" unless fn
dumped, err=string.dump fn
dumped, err = string.dump fn
error err or "failed to dump function" unless dumped
load dumped, file, 'b', scope
pcall= (fn, ...) ->
rewrite=(err) ->
trace=debug.traceback '', 2
trunc=truncate_traceback trim trace
rewrite_traceback trunc, err
pcall = (fn, ...) ->
rewrite = (err) ->
trace = debug.traceback '', 2
trunc = truncate_traceback trim trace
(rewrite_traceback trunc, err) or trace
xpcall fn, rewrite, ...
-- command object
-- represents a command that can be called
class Command
new: (@cmd, ...) =>
@args={...}
@args = {...}
__unm: => @run error: true, print: true
__len: => @run error: true
@@ -49,11 +50,11 @@ class Command
-- build object
-- represents a target
class BuildObject
all={}
skip={}
all = {}
skip = {}
@find: (name) =>
target=all[name]
target = all[name]
return target if target
for glob, tgt in pairs all
return tgt if match name, glob
@@ -63,16 +64,16 @@ class BuildObject
{target, {dep, @find dep for dep in *target.deps} for name, target in pairs all}
@build: (name, upper) =>
target=(@find name) or error "No such target: #{name}"
target = (@find name) or error "No such target: #{name}"
target\build name, upper
__tostring: =>
"Target #{@name} (#{concat @deps, ', '})"
new: (@name, @outs={}, @ins={}, @deps={}, @fn= =>) =>
@skip=false
@skip = false
error "Duplicate build name #{@name}" if all[@name]
all[@name]=@
all[@name] = @
build: (name, upper={}) =>
return if skip[name]
@@ -84,43 +85,45 @@ class BuildObject
@@build dep, upper for dep in *@deps
return unless @shouldbuild name
ins=@ins
outs=@outs
ins = @ins
outs = @outs
if @name!=name
ins=[patsubst name, @name, elem for elem in *@ins]
outs=[patsubst name, @name, elem for elem in *@outs]
ins = [patsubst name, @name, elem for elem in *@ins]
outs = [patsubst name, @name, elem for elem in *@outs]
print "Building #{@name} as #{name}"
else
print "Building #{name}"
ok, err=pcall ->
freezecache file for file in *outs
ok, err = pcall ->
@.fn
ins: ins
outs: outs
infile: ins[1]
outfile: outs[1]
name: name
invalidatecache file for file in *outs
error "Can't build #{@name}: lua error\n#{err}" unless ok
for f in *outs
error "Can't build #{@name}: output file #{f} not created" unless exists f
skip[name]=true
skip[name] = true
shouldbuild: (name) =>
return true if args.noskip
return true if #@ins==0 or #@outs==0
ins=if @name!=name
ins = if @name!=name
[patsubst name, @name, elem for elem in *@ins]
else
@ins
itimes=[mtime f for f in *ins]
itimes = [mtime f for f in *ins]
for i=1, #@ins
error "Can't build #{@name}: missing inputs" unless itimes[i]
outs=if @name!=name
outs = if @name!=name
[patsubst name, @name, elem for elem in *@outs]
else
@outs
otimes=[mtime f for f in *outs]
otimes = [mtime f for f in *outs]
for i=1, #@outs
return true if not otimes[i]
@@ -128,10 +131,9 @@ class BuildObject
error "Need Lua >=5.2" if setfenv
targets={}
defaulttarget='all'
local targets, defaulttarget
buildscope=
buildscope =
default: (target) ->
defaulttarget=target.name
target
@@ -139,30 +141,41 @@ buildscope=
insert targets, target.name
target
target: (name, params) ->
tout=flatten params.out
tin=flatten params.in
tdeps=flatten params.deps
tout = flatten params.out
tin = flatten params.in
tdeps = flatten params.deps
for f in *flatten params.from
insert tin, f
insert tdeps, f
BuildObject name, tout, tin, tdeps, params.fn
:Command
buildscope[k]=fn for k, fn in pairs util
buildscope[k] = fn for k, fn in pairs util
setmetatable buildscope,
__index: (k) =>
global=rawget _G, k
global = rawget _G, k
return global if global
(...) -> Command k, ...
file=first {'Build.moon', 'Buildfile.moon', 'Build', 'Buildfile'}, exists
error "No Build.moon or Buildfile found" unless file
buildfn=loadwithscope file, buildscope
error "Failed to load build function" unless buildfn
ok, err=pcall buildfn
loadtargets = ->
targets = {}
defaulttarget = 'all'
file = first {'Build.moon', 'Buildfile.moon', 'Build', 'Buildfile'}, exists
error "No Build.moon or Buildfile found" unless file
buildfn = loadwithscope file, buildscope
error "Failed to load build function" unless buildfn
buildfn!
buildtargets = ->
if #args.targets==0
BuildObject\build defaulttarget
for target in *args.targets
BuildObject\build target
ok, err = pcall loadtargets
unless ok
if err
io.stderr\write err, '\n'
io.stderr\write "Error while loading build file: ", err, '\n'
else
io.stderr\write "Unknown error\n"
os.exit 1
@@ -188,10 +201,10 @@ if args.deps
io.write "(#{concat target.ins, ', '} -> #{concat target.outs, ', '})"
io.write "\n"
for name, dep in sortedpairs deps
io.write "\t\t#{name} (#{dep.name})\n"
io.write "\t\t#{name}"
if name!=dep.name
io.write " (#{dep.name})"
io.write "\n"
os.exit 0
if #args.targets==0
BuildObject\build defaulttarget
for target in *args.targets
BuildObject\build target
buildtargets!
+201 -37
View File
@@ -1,11 +1,78 @@
do
do
local _ENV = _ENV
package.preload[ "moonbuild.fscache" ] = function( ... ) local arg = _G.arg;
local attributes, dir
do
local _obj_0 = require('lfs')
attributes, dir = _obj_0.attributes, _obj_0.dir
end
local unpack = unpack or table.unpack
local FROZEN
FROZEN = function() end
local makecached
makecached = function(fn)
local cache = { }
local invalidate
invalidate = function(val)
cache[val] = nil
end
local freeze
freeze = function(val)
cache[val] = FROZEN
end
local clear
clear = function()
cache = { }
end
local get
get = function(val)
local cached = cache[val]
if cached ~= FROZEN and cached ~= nil then
return unpack(cached)
end
local ret = {
fn(val)
}
if cached ~= FROZEN then
cache[val] = ret
end
return unpack(ret)
end
return setmetatable({
get = get,
invalidate = invalidate,
freeze = freeze,
clear = clear
}, {
__call = function(self, val)
return get(val)
end
})
end
return {
attributes = makecached(attributes),
dir = makecached(function(file)
local _accum_0 = { }
local _len_0 = 1
for k in dir(file) do
_accum_0[_len_0] = k
_len_0 = _len_0 + 1
end
return _accum_0
end)
}
end
end
do
local _ENV = _ENV
package.preload[ "moonbuild.fsutil" ] = function( ... ) local arg = _G.arg;
local dir, attributes
do
local _obj_0 = require('lfs')
local _obj_0 = require('moonbuild.fscache')
dir, attributes = _obj_0.dir, _obj_0.attributes
end
local gmatch, match, gsub, sub
@@ -13,16 +80,59 @@ do
local _obj_0 = string
gmatch, match, gsub, sub = _obj_0.gmatch, _obj_0.match, _obj_0.gsub, _obj_0.sub
end
local insert, concat
local insert, remove, concat
do
local _obj_0 = table
insert, concat = _obj_0.insert, _obj_0.concat
insert, remove, concat = _obj_0.insert, _obj_0.remove, _obj_0.concat
end
local normalizepath
normalizepath = function(file)
local parts
do
local _accum_0 = { }
local _len_0 = 1
for part in gmatch(file, '[^/]+') do
_accum_0[_len_0] = part
_len_0 = _len_0 + 1
end
parts = _accum_0
end
local absolute = (sub(file, 1, 1)) == '/'
for i = 1, #parts do
local _continue_0 = false
repeat
if parts[i] == '.' then
remove(parts, i)
i = i - 1
_continue_0 = true
break
end
if parts[i] == '..' and i ~= 1 then
remove(parts, i)
remove(parts, i - 1)
i = i - 2
_continue_0 = true
break
end
_continue_0 = true
until true
if not _continue_0 then
break
end
end
if #parts == 0 then
return '.'
else
return (absolute and '/' or '') .. concat(parts, '/')
end
end
local ls
ls = function(d)
local _accum_0 = { }
local _len_0 = 1
for f in dir(d) do
local _list_0 = dir(normalizepath(d))
for _index_0 = 1, #_list_0 do
local f = _list_0[_index_0]
if f ~= '.' and f ~= '..' then
_accum_0[_len_0] = f
_len_0 = _len_0 + 1
@@ -37,7 +147,9 @@ lswithpath = function(d)
end
local _accum_0 = { }
local _len_0 = 1
for f in dir(d) do
local _list_0 = dir(normalizepath(d))
for _index_0 = 1, #_list_0 do
local f = _list_0[_index_0]
if f ~= '.' and f ~= '..' then
_accum_0[_len_0] = d .. '/' .. f
_len_0 = _len_0 + 1
@@ -47,16 +159,16 @@ lswithpath = function(d)
end
local exists
exists = function(f)
return (attributes(f)) ~= nil
return (attributes(normalizepath(f))) ~= nil
end
local isdir
isdir = function(f)
local a = attributes(f)
local a = attributes(normalizepath(f))
return a and a.mode == 'directory' or false
end
local mtime
mtime = function(f)
local a = attributes(f)
local a = attributes(normalizepath(f))
return a and a.modification
end
local matchglob
@@ -93,7 +205,7 @@ wildcard = function(glob)
local absolute = (sub(glob, 1, 1)) == '/'
for i, part in ipairs(parts) do
local prevpath = (absolute and '/' or '') .. concat(parts, '/', 1, i - 1)
local currpath = prevpath .. '/' .. part
local currpath = (i == 1 and '' or (prevpath .. '/')) .. part
if match(part, '%*%*.*%*%*') then
error("Two '**' in the same path component in a wildcard")
end
@@ -152,11 +264,37 @@ wildcard = function(glob)
return { }
end
end
local parentdir
parentdir = function(file)
return normalizepath(file .. '/..')
end
local freezecache
freezecache = function(file)
dir.freeze(file)
dir.freeze(parentdir(file))
return attributes.invalidate(file)
end
local invalidatecache
invalidatecache = function(file)
dir.invalidate(file)
dir.invalidate(parentdir(file))
return attributes.invalidate(file)
end
local clearcache
clearcache = function()
dir.clear()
return attributes.clear()
end
return {
wildcard = wildcard,
exists = exists,
isdir = isdir,
mtime = mtime
mtime = mtime,
normalizepath = normalizepath,
parentdir = parentdir,
freezecache = freezecache,
invalidatecache = invalidatecache,
clearcache = clearcache
}
end
@@ -260,7 +398,7 @@ min = function(table, cmp)
local val = table[1]
for i = 2, #table do
local elem = table[i]
if cmp(val, elem) then
if cmp(elem, val) then
val = elem
end
end
@@ -276,7 +414,7 @@ max = function(table, cmp)
local val = table[1]
for i = 2, #table do
local elem = table[i]
if not cmp(val, elem) then
if not cmp(elem, val) then
val = elem
end
end
@@ -570,6 +708,11 @@ end
local trim
trim = require('moonscript.util').trim
local util = require('moonbuild.util')
local freezecache, invalidatecache
do
local _obj_0 = require('moonbuild.fsutil')
freezecache, invalidatecache = _obj_0.freezecache, _obj_0.invalidatecache
end
local exists, mtime, run, min, max, first, flatten, match, patsubst, sortedpairs
exists, mtime, run, min, max, first, flatten, match, patsubst, sortedpairs = util.exists, util.mtime, util.run, util.min, util.max, util.first, util.flatten, util.match, util.patsubst, util.sortedpairs
local insert, concat
@@ -602,7 +745,7 @@ pcall = function(fn, ...)
rewrite = function(err)
local trace = debug.traceback('', 2)
local trunc = truncate_traceback(trim(trace))
return rewrite_traceback(trunc, err)
return (rewrite_traceback(trunc, err)) or trace
end
return xpcall(fn, rewrite, ...)
end
@@ -721,6 +864,10 @@ do
else
print("Building " .. tostring(name))
end
for _index_0 = 1, #outs do
local file = outs[_index_0]
freezecache(file)
end
local ok, err = pcall(function()
return self.fn({
ins = ins,
@@ -730,6 +877,10 @@ do
name = name
})
end)
for _index_0 = 1, #outs do
local file = outs[_index_0]
invalidatecache(file)
end
if not (ok) then
error("Can't build " .. tostring(self.name) .. ": lua error\n" .. tostring(err))
end
@@ -887,8 +1038,7 @@ end
if setfenv then
error("Need Lua >=5.2")
end
local targets = { }
local defaulttarget = 'all'
local targets, defaulttarget
local buildscope = {
default = function(target)
defaulttarget = target.name
@@ -926,23 +1076,40 @@ setmetatable(buildscope, {
end
end
})
local file = first({
'Build.moon',
'Buildfile.moon',
'Build',
'Buildfile'
}, exists)
if not (file) then
error("No Build.moon or Buildfile found")
local loadtargets
loadtargets = function()
targets = { }
defaulttarget = 'all'
local file = first({
'Build.moon',
'Buildfile.moon',
'Build',
'Buildfile'
}, exists)
if not (file) then
error("No Build.moon or Buildfile found")
end
local buildfn = loadwithscope(file, buildscope)
if not (buildfn) then
error("Failed to load build function")
end
return buildfn()
end
local buildfn = loadwithscope(file, buildscope)
if not (buildfn) then
error("Failed to load build function")
local buildtargets
buildtargets = function()
if #args.targets == 0 then
BuildObject:build(defaulttarget)
end
local _list_0 = args.targets
for _index_0 = 1, #_list_0 do
local target = _list_0[_index_0]
BuildObject:build(target)
end
end
local ok, err = pcall(buildfn)
local ok, err = pcall(loadtargets)
if not (ok) then
if err then
io.stderr:write(err, '\n')
io.stderr:write("Error while loading build file: ", err, '\n')
else
io.stderr:write("Unknown error\n")
end
@@ -974,16 +1141,13 @@ if args.deps then
end
io.write("\n")
for name, dep in sortedpairs(deps) do
io.write("\t\t" .. tostring(name) .. " (" .. tostring(dep.name) .. ")\n")
io.write("\t\t" .. tostring(name))
if name ~= dep.name then
io.write(" (" .. tostring(dep.name) .. ")")
end
io.write("\n")
end
end
os.exit(0)
end
if #args.targets == 0 then
BuildObject:build(defaulttarget)
end
local _list_0 = args.targets
for _index_0 = 1, #_list_0 do
local target = _list_0[_index_0]
BuildObject:build(target)
end
return buildtargets()
+33
View File
@@ -0,0 +1,33 @@
import attributes, dir from require 'lfs'
unpack or= table.unpack
FROZEN = ->
makecached = (fn) ->
cache = {}
invalidate = (val) ->
cache[val] = nil
freeze = (val) ->
cache[val] = FROZEN
clear = ->
cache = {}
get = (val) ->
cached = cache[val]
if cached!=FROZEN and cached!=nil
return unpack cached
ret = {fn val}
if cached!=FROZEN
cache[val] = ret
unpack ret
setmetatable { :get, :invalidate, :freeze, :clear },
__call: (val) => get val
{
attributes: makecached attributes
dir: makecached (file) -> [k for k in dir file]
}
+46 -10
View File
@@ -1,25 +1,42 @@
import dir, attributes from require 'lfs'
import dir, attributes from require 'moonbuild.fscache'
import gmatch, match, gsub, sub from string
import insert, concat from table
import insert, remove, concat from table
normalizepath = (file) ->
parts = [part for part in gmatch file, '[^/]+']
absolute = (sub file, 1, 1)=='/'
for i=1, #parts
if parts[i]=='.'
remove parts, i
i -= 1
continue
if parts[i]=='..' and i!=1
remove parts, i
remove parts, i-1
i -= 2
continue
if #parts==0
'.'
else
(absolute and '/' or '') .. concat parts, '/'
ls = (d) ->
[f for f in dir d when f!='.' and f!='..']
[f for f in *dir normalizepath d when f!='.' and f!='..']
lswithpath = (d) ->
if d==''
return ls '.'
[d..'/'..f for f in dir d when f!='.' and f!='..']
return ls '.' if d==''
[d..'/'..f for f in *dir normalizepath d when f!='.' and f!='..']
exists = (f) ->
(attributes f) != nil
(attributes normalizepath f) != nil
isdir = (f) ->
a = attributes f
a = attributes normalizepath f
a and a.mode == 'directory' or false
mtime = (f) ->
a = attributes f
a = attributes normalizepath f
a and a.modification
matchglob = (str, glob) ->
@@ -40,7 +57,7 @@ wildcard = (glob) ->
for i, part in ipairs parts
prevpath = (absolute and '/' or '') .. concat parts, '/', 1, i-1
currpath = prevpath .. '/' .. part
currpath = (i==1 and '' or (prevpath .. '/')) .. part
if match part, '%*%*.*%*%*'
error "Two '**' in the same path component in a wildcard"
@@ -81,8 +98,27 @@ wildcard = (glob) ->
else
return {}
parentdir = (file) ->
normalizepath file..'/..'
freezecache = (file) ->
dir.freeze file
dir.freeze parentdir file
attributes.invalidate file
invalidatecache = (file) ->
dir.invalidate file
dir.invalidate parentdir file
attributes.invalidate file
clearcache = ->
dir.clear!
attributes.clear!
{
:wildcard
:exists, :isdir
:mtime
:normalizepath, :parentdir
:freezecache, :invalidatecache, :clearcache
}
+2 -2
View File
@@ -12,7 +12,7 @@ min = (table, cmp=(a, b) -> a<b) ->
val = table[1]
for i=2, #table
elem = table[i]
if cmp val, elem
if cmp elem, val
val = elem
val
@@ -20,7 +20,7 @@ max = (table, cmp=(a, b) -> a<b) ->
val = table[1]
for i=2, #table
elem = table[i]
if not cmp val, elem
if not cmp elem, val
val = elem
val
+23
View File
@@ -0,0 +1,23 @@
build = {
install = {
bin = {
moonbuild = "moonbuild.lua"
}
},
type = "builtin"
}
dependencies = {
"lua >= 5.3",
"luafilesystem >= 1.7.0"
}
description = {
detailed = "moonbuild is a small build system that simplifies your build definitions by allowing you to use declarative as well as imperative rules. It represents the build as a DAG with explicit ordering, and doesn't give you any default confusing rules (unlike make)\n",
summary = "Small build system in between make and a build.sh"
}
package = "moonbuild"
rockspec_format = "3.0"
source = {
tag = "v1.0.3",
url = "git://github.com/natnat-mc/moonbuild"
}
version = "1.0.3-1"
+23
View File
@@ -0,0 +1,23 @@
build = {
install = {
bin = {
moonbuild = "moonbuild.lua"
}
},
type = "builtin"
}
dependencies = {
"lua >= 5.3",
"luafilesystem >= 1.7.0"
}
description = {
detailed = "moonbuild is a small build system that simplifies your build definitions by allowing you to use declarative as well as imperative rules. It represents the build as a DAG with explicit ordering, and doesn't give you any default confusing rules (unlike make)\n",
summary = "Small build system in between make and a build.sh"
}
package = "moonbuild"
rockspec_format = "3.0"
source = {
tag = "v1.0.3",
url = "git://github.com/natnat-mc/moonbuild"
}
version = "1.0.3-2"
+23
View File
@@ -0,0 +1,23 @@
build = {
install = {
bin = {
moonbuild = "moonbuild.lua"
}
},
type = "builtin"
}
dependencies = {
"lua >= 5.3",
"luafilesystem >= 1.7.0"
}
description = {
detailed = "moonbuild is a small build system that simplifies your build definitions by allowing you to use declarative as well as imperative rules. It represents the build as a DAG with explicit ordering, and doesn't give you any default confusing rules (unlike make)\n",
summary = "Small build system in between make and a build.sh"
}
package = "moonbuild"
rockspec_format = "3.0"
source = {
tag = "v1.0.3",
url = "git://github.com/natnat-mc/moonbuild"
}
version = "1.0.3-3"
+23
View File
@@ -0,0 +1,23 @@
build = {
install = {
bin = {
moonbuild = "moonbuild.lua"
}
},
type = "builtin"
}
dependencies = {
"lua >= 5.3",
"luafilesystem >= 1.7.0"
}
description = {
detailed = "moonbuild is a small build system that simplifies your build definitions by allowing you to use declarative as well as imperative rules. It represents the build as a DAG with explicit ordering, and doesn't give you any default confusing rules (unlike make)\n",
summary = "Small build system in between make and a build.sh"
}
package = "moonbuild"
rockspec_format = "3.0"
source = {
tag = "v1.1.0",
url = "git://github.com/natnat-mc/moonbuild"
}
version = "1.1.0-1"
+23
View File
@@ -0,0 +1,23 @@
build = {
install = {
bin = {
moonbuild = "moonbuild.lua"
}
},
type = "builtin"
}
dependencies = {
"lua >= 5.3",
"luafilesystem >= 1.7.0"
}
description = {
detailed = "moonbuild is a small build system that simplifies your build definitions by allowing you to use declarative as well as imperative rules. It represents the build as a DAG with explicit ordering, and doesn't give you any default confusing rules (unlike make)\n",
summary = "Small build system in between make and a build.sh"
}
package = "moonbuild"
rockspec_format = "3.0"
source = {
tag = "v1.1.1",
url = "git://github.com/natnat-mc/moonbuild"
}
version = "1.1.1-1"
+23
View File
@@ -0,0 +1,23 @@
build = {
install = {
bin = {
moonbuild = "moonbuild.lua"
}
},
type = "builtin"
}
dependencies = {
"lua >= 5.3",
"luafilesystem >= 1.7.0"
}
description = {
detailed = "moonbuild is a small build system that simplifies your build definitions by allowing you to use declarative as well as imperative rules. It represents the build as a DAG with explicit ordering, and doesn't give you any default confusing rules (unlike make)\n",
summary = "Small build system in between make and a build.sh"
}
package = "moonbuild"
rockspec_format = "3.0"
source = {
tag = "v1.1.2",
url = "git://github.com/natnat-mc/moonbuild"
}
version = "1.1.2-1"
+23
View File
@@ -0,0 +1,23 @@
build = {
install = {
bin = {
moonbuild = "moonbuild.lua"
}
},
type = "builtin"
}
dependencies = {
"lua >= 5.3",
"luafilesystem >= 1.7.0"
}
description = {
detailed = "moonbuild is a small build system that simplifies your build definitions by allowing you to use declarative as well as imperative rules. It represents the build as a DAG with explicit ordering, and doesn't give you any default confusing rules (unlike make)\n",
summary = "Small build system in between make and a build.sh"
}
package = "moonbuild"
rockspec_format = "3.0"
source = {
tag = "v1.1.3",
url = "git://github.com/natnat-mc/moonbuild"
}
version = "1.1.3-1"