1
0
mirror of https://github.com/natnat-mc/moonbuild synced 2026-05-28 06:09:41 +02:00

44 Commits

Author SHA1 Message Date
Codinget 5518c61fc1 added lib, new alfons tasks, simplified executor behavior and added task count, fixed _.exclude not being in the _ lib, updated Build.moon and README.md 2020-11-13 19:53:51 +01:00
Codinget 81baa03624 Producing rockspec 2.1.3-2 2020-11-12 18:07:18 +01:00
Codinget 77f73f3a21 Producing rockspec 2.1.3-1 2020-11-12 18:07:00 +01:00
Codinget 31fcc58ccd fix freeze with -j and sync targets 2020-11-12 18:06:41 +01:00
Codinget fcf7c3fa07 Producing rockspec 2.1.2-2 2020-11-09 19:53:43 +01:00
Codinget 88a8117f06 Producing rockspec 2.1.2-1 2020-11-09 19:53:14 +01:00
Codinget 69e781bc8f fix crash when multiple targets depend on the same target 2020-11-09 19:53:05 +01:00
Codinget ee0d76db98 Producing rockspec 2.1.1-1 2020-11-08 00:53:45 +01:00
Codinget 6a6334fc78 actually honor sync requests 2020-11-08 00:53:32 +01:00
Codinget e5bd85933a Producing rockspec 2.1.0-3 2020-11-08 00:45:59 +01:00
Codinget 50d0c662c5 Producing rockspec 2.1.0-2 2020-11-08 00:45:26 +01:00
Codinget f742a3c003 Producing rockspec 2.1.0-1 2020-11-08 00:45:07 +01:00
Codinget fcd3b07572 added install target 2020-11-08 00:44:42 +01:00
Codinget b1f57c8929 fixed depfns 2020-11-08 00:44:35 +01:00
Codinget d31e5a9615 Producing rockspec 2.0.0-3 2020-11-07 21:15:58 +01:00
Codinget 89db21b79e Producing rockspec 2.0.0-2 2020-11-07 21:15:23 +01:00
Codinget 389627b430 removed test 2020-11-07 21:14:34 +01:00
Codinget b2f0de7b38 Producing rockspec 2.0.0-1 2020-11-07 21:13:00 +01:00
Codinget c8670ab903 v2 2020-11-07 21:01:26 +01:00
Codinget ceada11b0b Producing rockspec 1.1.4-2 2020-10-21 15:21:09 +02:00
Codinget e7251a5b55 fix rockspec with deps 2020-10-21 15:02:37 +02:00
Nathan DECHER 7203d38bdb Producing rockspec 1.1.4-1 2020-09-25 19:49:53 +02:00
Nathan DECHER 80a5c54032 added spec for stringutil, tableutil and the pure part of fsutil 2020-09-25 19:49:25 +02:00
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
Nathan DECHER 1de2cbe403 Producing rockspec 1.0.2-1 2020-09-13 18:43:10 +02:00
Nathan DECHER 750b6e152a depend on amalg.lua to produce a single binary, fix #10 2020-09-13 18:42:42 +02:00
Nathan DECHER 28116da35e updated README.md 2020-09-13 16:46:48 +02:00
Nathan DECHER 92952eefb4 removed Makefile 2020-09-13 16:46:40 +02:00
Nathan DECHER 2f07f8f6d6 Producing rockspec 1.0.1-1 2020-09-13 16:31:32 +02:00
65 changed files with 5006 additions and 1551 deletions
+1
View File
@@ -0,0 +1 @@
*.lua
+8 -2
View File
@@ -1,7 +1,13 @@
tasks:
build: =>
sh "moon bin/moonbuild.moon compile-lua"
bootstrap: => sh "moon bin/moonbuild.moon -jy"
bootstrapinstall: => sh "moon bin/moonbuild.moon install -jy"
release: =>
error "no version provided" unless @v
tasks.build!
sh "rockbuild -m -t #{@v} upload"
build: => (require 'moonbuild') j: true
install: => (require 'moonbuild') 'install', j: true
clean: => (require 'moonbuild') 'clean'
mrproper: => (require 'moonbuild') 'mrproper'
+65 -10
View File
@@ -1,14 +1,69 @@
SOURCES_MOON = flatten {'bin/moonbuild.moon', wildcard 'moonbuild/**.moon'}
OUT_LUA = patsubst SOURCES_MOON, '%.moon', '%.lua'
public var 'MOONC', 'moonc'
public var 'AMALG', 'amalg.lua'
public var 'RM', 'rm', '-f', '--'
public var 'LUA', 'lua5.3'
public target 'clean', fn: =>
-rm '-f', OUT_LUA
var 'LIB_SRC', _.wildcard 'moonbuild/**.moon'
var 'BIN_SRC', _.wildcard 'bin/*.moon'
public target 'info', fn: =>
#echo "Moonscript sources:", SOURCES_MOON
#echo "Compiled lua:", OUT_LUA
var 'LIB_LUA', _.patsubst LIB_SRC, '%.moon', '%.lua'
var 'BIN_LUA', _.patsubst BIN_SRC, '%.moon', '%.lua'
var 'BIN', _.patsubst BIN_LUA, 'bin/%.lua', 'out/%'
default target 'compile-lua', from: OUT_LUA
var 'MODULES', _.foreach (_.patsubst LIB_LUA, '%.lua', '%'), => @gsub '/', '.'
target '%.lua', in: '%.moon', out: '%.lua', fn: =>
-moonc @infile
with public default target 'all'
\after 'bin'
\after 'lib'
with public target 'install'
\after 'install-bin'
\after 'install-lib'
with public target 'install-bin'
\depends 'out/moonbuild'
\produces '/usr/local/bin/moonbuild'
\fn => _.cmd 'sudo', 'cp', @infile, @outfile
\sync!
with public target 'install-lib'
\depends 'out/moonbuild.lua'
\produces "/usr/local/share/lua/#{LUA\gsub 'lua', ''}/moonbuild.lua"
\fn => _.cmd 'sudo', 'cp', @infile, @outfile
\sync!
with public target 'clean'
\fn => _.cmd RM, LIB_LUA
\fn => _.cmd RM, BIN_LUA
with public target 'mrproper'
\after 'clean'
\fn => _.cmd RM, BIN
with public target 'bin'
\depends BIN
with public target 'lib'
\depends LIB_LUA
with target BIN, pattern: 'out/%'
\depends 'bin/%.lua'
\depends LIB_LUA
\produces 'out/%'
\mkdirs!
\fn =>
_.cmd AMALG, '-o', @outfile, '-s', @infile, MODULES
_.writefile @outfile, "#!/usr/bin/env #{LUA}\n#{_.readfile @outfile}"
_.cmd 'chmod', '+x', @outfile
with target 'out/moonbuild.lua'
\depends 'moonbuild/init.lua'
\depends LIB_LUA
\produces '%'
\fn =>
_.cmd AMALG, '-o', @outfile, '-s', @infile, _.exclude MODULES, 'moonbuild.init'
with target {LIB_LUA, BIN_LUA}, pattern: '%.lua'
\depends '%.moon'
\produces '%.lua'
\fn => _.moonc @infile, @outfile
+30 -21
View File
@@ -1,33 +1,42 @@
SOURCES_MOON := $(wildcard *.moon)
SOURCES_MOON := $(filter-out Build.moon, $(SOURCES_MOON))
OUT_LUA := $(foreach source, $(SOURCES_MOON), $(patsubst %.moon, %.lua, $(source)))
BINARY := moonbuild
MAIN := $(BINARY).moon
MAIN_LUA := $(patsubst %.moon, %.lua, $(MAIN))
OUT_C := $(patsubst %.moon, %.lua.c, $(MAIN))
PREFIX ?= /usr/local
.PHONY: all clean mrproper bin lib
.PHONY: all install clean mrproper info
MOONC = moonc
AMALG = amalg.lua
RM = rm -f --
LUA = lua5.3
all: $(BINARY)
LIB_SRC = $(wildcard moonbuild/*.moon) $(wildcard moonbuild/*/*.moon) $(wildcard moonbuild/*/*/*.moon)
BIN_SRC = $(wildcard bin/*.moon)
install: moonbuild
install $^ $(PREFIX)/bin
LIB_LUA = $(foreach moon, $(LIB_SRC), $(patsubst %.moon, %.lua, $(moon)))
BIN_LUA = $(foreach moon, $(BIN_SRC), $(patsubst %.moon, %.lua, $(moon)))
BIN = $(foreach lua, $(BIN_LUA), $(patsubst bin/%.lua, out/%, $(lua)))
MODULES = $(shell echo $(foreach lib, $(LIB_LUA), $(patsubst %.lua, %, $(lib))) | sed 's|/|.|g')
all: bin lib
install: all
sudo cp out/moonbuild /usr/local/bin/moonbuild
clean:
rm -f $(OUT_LUA)
rm -f $(OUT_C)
$(RM) $(LIB_LUA)
$(RM) $(BIN_LUA)
mrproper: clean
rm -f $(BINARY)
$(RM) $(BIN)
info:
@echo "Moonscript sources:" $(SOURCES_MOON)
@echo "Compiled lua:" $(OUT_LUA)
@echo "Binary:" $(BINARY)
bin: $(BIN)
$(BINARY): $(OUT_LUA)
luastatic $(MAIN_LUA) $(OUT_LUA) -I/usr/include/lua5.3 -llua5.3
lib: $(LIB_LUA)
out/%: bin/%.lua $(LIB_LUA)
@mkdir -p `dirname $@`
$(AMALG) -o $@.body -s $< $(MODULES)
@printf '#!/usr/bin/env %s\n' $(LUA) > $@.headline
@cat $@.headline $@.body > $@
@rm $@.headline $@.body
chmod +x $@
%.lua: %.moon
moonc $^
+22 -93
View File
@@ -1,102 +1,31 @@
# Moonbuild
Because `make` is painful to use, and build scripts are too slow. Moonbuild aims to be a good compromise.
# moonbuild
**Now in v2 - complete rework from v1**
You should probably use [`tup`](http://gittup.org/tup/) instead if you want a good build system.
Because `make` is painful to use, and build scripts are too slow. Moonbuild aims to be a good compromise.
You should probably use [http://gittup.org/tup/](tup) instead if you want a good build system.
## How does it work?
Basically like `make`, but in [Moonscript](https://moonscript.org) and with explicit ordering. See its `Build.moon` for examples (and you can compare it with the `Makefile`, both do the same thing).
`moonbuild` reads a build file, usually `Build.moon` that is written in a Moonscript DSL to define its targets and variables.
It then builds a DAG for the dependancies of the targets you tell it to build.
Then, it tries building every target in the graph while respecting dependancies, possibly on multiple processes.
## Why moonscript?
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.
Essentially, it works the same way as `make`, just with a different language, you can compare the `Build.moon` and `Makefile` in this repo to see for yourself.
## How do I install it?
- First, you'll need Lua 5.2 (untested) or 5.3 and [LuaRocks](https://luarocks.org)
- Then, you'll need `moonscript`, `argparse`, `luafilesystem` and `luastatic`, which you can get from `luarocks`
- Now, you can simply `make` Moonbuild, or build it with itself with `moon moonbuild.moon`
- You're now ready to install it, with `sudo make install` or `sudo ./moonbuild install`
## Why Moonscript?
Because it's fast, based on lua, and making DSLs with it is relatively easy.
It's also a language I like a lot, so I might have been biased when choosing it.
## Now, how do I use it?
First, you'll need a `Build.moon`, `Buildfile.moon`, `Build` or `Buildfile` in the root of your project.
Then, you'll need a few `target`s, and ideally a `default target` (or the default target will be `all`). `public target`s will be listed by `moonbuild -l`.
To execute a command, you can use either `-cmd` or `#cmd` (the former will print it before executing it, the later won't).
## Installing
It is available on luarocks with `luarocks install moonbuild`.
It is also recommended to install `luaposix` if you can, as it speeds it up a lot, or `luafilesystem` in case it isn't available.
### `[default] [public] target <name> [deps: <deps>] [in: <inputs>] [out: <outputs>] [from: <from>] [fn: <code>]`
Define a new target, and give it a list of depenancies, inputs, outputs and a function to run to build it.
## Building from source
You will need `argparse` and `moonscript` installed from luarocks, and `luaposix` or `luafilesystem` are recommended.
`deps`, `in` and `out` can be either strings or tables. `from` acts like both `in` and `deps`. `name` must be a string and `code` must be a function, that will be given a table with the following fields:
- `name`: the name of the target
- `ins`: the table of inputs
- `infile`: the first input
- `outs`: the table of outputs
- `outfile`: the first output
### Bootstrapping
You can build moonbuild with itself: `moon bin/moonbuild.moon -qjy`.
This will leave the binary ready to be used as `out/moonbuild`.
The binary and library can then be installed with `bin/moonbuild install`.
If `name` is a glob, the target becomes a glob target.
Glob targets can be used with name that matches them (with a limit of one glob target per name, and no ordering is specified).
Glob targets will have their name substituted for their inputs, outputs and dependancies.
### `-cmd [<args>...]`
Prints and executes the command `cmd` with the given args. See `run` for how `args` works.
### `#cmd [<args>...]`
Executes without printing the command `cmd` with the given args. See `run` for how `args` works.
### `wildcard <wc>`
Returns a table with all the matching files. Valid wildcards contain either `**`, which can be expanded by any characters, including '/', or `*`, which cannot be expanded by `/`. Wildcards can only contain one `**` or `*`.
`wc` must be a string
### `exclude <list> [<exclusions>...]`
Removes all exclusions from the given list, and returns it.
`list` must be a table, and `exclusions` can be any type
### `patsubst <str> <patt> <subst>`
If the string matches `patt`, makes it match `subst` instead. If `str` is a table, it is recursively applied to all array values.
Patterns are in the format `[prefix]%[suffix]`, with the `%` representing any sequence of characters, including `/`.
`str`, `pat` and `subst` must be strings
### `foreach <table> <code>`
Applies `code` to every element of `table`, and returns the resulting table.
`table` must be a table, and `code` a function.
### `min|max <table>`
Returns either the min or max value of the given table.
`table` must be a table
### `first <table> <code>`
Returns the first value of the table that verifies the given condition.
`table` must be a table, and `code` a function
### `flatten <table>`
Flattens a table so that it has exactly one dimension.
`table` can be anything
### `insert|unpack|concat`
The functions, imported from the `table` library.
### `mtime <file>`
Returns the modification time of `file`, or `nil` if it doesn't exist.
`file` must be a string
### `exists <file>`
Returns `true` if the file exists, `false` otherwise.
`file` must be a string
### `run <cmd> [<args> [print: <print>] [error: <error>]]`
Runs the given command with the given arguments. If `print` is truthy, prints the command before executing it, and if `error` is truthy, crashes if the command fails. Returns a boolean which is true if the command ended with success, and a number which is the return code.
`cmd` must be a string, `args` must be a table, which can contain either strings or other tables. `raw: <val>` is a special kind of argument that will not be escaped. `print` and `error` can be anything, but booleans or nil are recommended
### `popen <cmd> [<args> [print: <print>]]`
Same as `run`, but returns a `io.popen` handle.
## License
MIT
## Docs
TODO
-428
View File
@@ -1,428 +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
}
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
Executable → Regular
+71 -185
View File
@@ -1,196 +1,82 @@
#!/usr/bin/env moon
argparse=require 'argparse'
require 'moonscript'
-- load everything we need
import loadfile from require 'moonscript.base'
import truncate_traceback, rewrite_traceback from require 'moonscript.errors'
import trim from require 'moonscript.util'
Context = require 'moonbuild.context'
Variable = require 'moonbuild.core.Variable'
DepGraph = require 'moonbuild.core.DAG'
Executor = require 'moonbuild.core.executor'
import parseargs from require 'moonbuild._cmd.common'
import sort, concat from table
import exit from os
util=require 'moonbuild.util'
import exists, mtime, run, min, max, first, flatten, match, patsubst, sortedpairs from util
-- parse the arguments
argparse = require 'argparse'
parser = with argparse "moonbuild", "A build system in moonscript"
\option '-b --buildfile', "Build file to use", 'Build.moon'
\option '-j --parallel', "Sets the number of parallel tasks, 'y' to run as many as we have cores", '1'
\flag '-l --list', "List the targets", false
\flag '-V --list-variables', "List the variables", false
\flag '-q --quiet', "Don't print targets as they are being built", false
\flag '-f --force', "Always rebuild every target", false
\flag '-v --verbose', "Be verbose", false
(\option '-u --unset', "Unsets a variable")\count '*'
(\option '-s --set', "Sets a variable")\args(2)\count '*'
(\option '-S --set-list', "Sets a variable to a list")\args(2)\count '*'
(\argument 'targets', "Targets to build")\args '*'
\add_complete!
import insert, concat from table
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!
-- util functions
loadwithscope= (file, scope) ->
fn, err=loadfile file
error err or "failed to load code" unless 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
xpcall fn, rewrite, ...
overrides = {}
for unset in *args.unset
overrides[unset] = Variable.NIL
for set in *args.set
overrides[set[1]] = set[2]
for set in *args.set_list
overrides[set[1]] = parseargs set[2]
-- command object
-- represents a command that can be called
class Command
new: (@cmd, ...) =>
@args={...}
args.parallel = args.parallel == 'y' and 'y' or ((tonumber args.parallel) or error "Invalid argument for -j: #{args.parallel}")
error "Invalid argument for -j: #{args.parallel}" if args.parallel != 'y' and (args.parallel<1 or args.parallel%1 != 0)
print "Parsed CLI args" if args.verbose
__unm: => @run error: true, print: true
__len: => @run error: true
__tostring: => @cmd
run: (params) => run @cmd, @args, params
@run: (...) => -@ ...
-- build object
-- represents a target
class BuildObject
all={}
skip={}
@find: (name) =>
target=all[name]
return target if target
for glob, tgt in pairs all
return tgt if match name, glob
nil
@list: =>
{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\build name, upper
__tostring: =>
"Target #{@name} (#{concat @deps, ', '})"
new: (@name, @outs={}, @ins={}, @deps={}, @fn= =>) =>
@skip=false
error "Duplicate build name #{@name}" if all[@name]
all[@name]=@
build: (name, upper={}) =>
return if skip[name]
error "Cycle detected on #{@name}" if upper[@]
upper = setmetatable {[@]: true}, __index: upper
if @name!=name
@@build (patsubst name, @name, dep), upper for dep in *@deps
else
@@build dep, upper for dep in *@deps
return unless @shouldbuild name
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]
print "Building #{@name} as #{name}"
else
print "Building #{name}"
ok, err=pcall ->
@.fn
ins: ins
outs: outs
infile: ins[1]
outfile: outs[1]
name: name
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
shouldbuild: (name) =>
return true if args.noskip
return true if #@ins==0 or #@outs==0
ins=if @name!=name
[patsubst name, @name, elem for elem in *@ins]
else
@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
[patsubst name, @name, elem for elem in *@outs]
else
@outs
otimes=[mtime f for f in *outs]
for i=1, #@outs
return true if not otimes[i]
(max itimes)>(min otimes)
error "Need Lua >=5.2" if setfenv
targets={}
defaulttarget='all'
buildscope=
default: (target) ->
defaulttarget=target.name
target
public: (target) ->
insert targets, target.name
target
target: (name, params) ->
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
buildscope[k]=fn for k, fn in pairs util
setmetatable buildscope,
__index: (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
unless ok
if err
io.stderr\write err, '\n'
else
io.stderr\write "Unknown error\n"
os.exit 1
-- load the buildfile
ctx = Context!
ctx\load (loadfile args.buildfile), overrides
print "Loaded buildfile" if args.verbose
-- handle -l and -V
if args.list
io.write "Available targets:\n"
io.write "\t#{concat targets, ', '}\n"
os.exit 0
print "Public targets"
targets, n = {}, 1
for t in *ctx.targets
if t.public
targets[n], n = t.name, n+1
sort targets
print concat targets, ", "
print!
exit 0 unless args.list_variables
if args.list_variables
print "Public variables"
vars, n = {}, 1
for k, v in pairs ctx.variables
if v.public
vars[n], n = k, n+1
sort vars
print concat vars, ", "
print!
exit 0
if args.deps
io.write "Targets:\n"
for target, deps in sortedpairs BuildObject\list!, (a, b) -> a.name<b.name
io.write "\t#{target.name} "
if #target.ins==0
if #target.outs==0
io.write "[no in/out]"
else
io.write "[spontaneous generation]"
else
if #target.outs==0
io.write "[consumer]"
else
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"
os.exit 0
-- initialize the buildfile further
ctx\init!
print "Initialized buildfile" if args.verbose
if #args.targets==0
BuildObject\build defaulttarget
for target in *args.targets
BuildObject\build target
-- create the DAG
targets = #args.targets==0 and ctx.defaulttargets or args.targets
dag = DepGraph ctx, targets
print "Created dependancy graph" if args.verbose
-- execute the build
nparallel = args.parallel == 'y' and Executor\getmaxparallel! or args.parallel
print "Building with #{nparallel} max parallel process#{nparallel>1 and "es" or ""}" if args.verbose
executor = Executor dag, nparallel
executor\execute args
print "Finished" if args.verbose
+15
View File
@@ -0,0 +1,15 @@
import gmatch, match, gsub from string
import insert, remove, concat, sub, sort from table
_fs = require 'moonbuild._fs'
_cmd = require 'moonbuild._cmd'
_util = require 'moonbuild._util'
_common = require 'moonbuild._common'
_ = {}
for k, lib in pairs {:_fs, :_cmd, :_util, :_common}
_[k] = lib
for n in *lib!
_[n] = lib[n]
_
+21
View File
@@ -0,0 +1,21 @@
import parseargs, escape from require 'moonbuild._cmd.common'
ok, cmd, backend = false, nil, nil
unless ok
ok, cmd = pcall -> require 'moonbuild._cmd.posix'
backend = 'posix'
unless ok
ok, cmd = pcall -> require 'moonbuild._cmd.lua'
backend = 'lua'
error "unable to load any cmd library, tried luaposix and posix commands" unless ok
-- from the backend
cmd = {k, v for k, v in pairs cmd}
cmd.backend = backend
-- common cmd function
cmd.parseargs = parseargs
cmd.escape = escape
-- the library itself
setmetatable cmd, __call: => {'cmd', 'cmdrst', 'sh'}
+121
View File
@@ -0,0 +1,121 @@
import gsub, sub, match from string
import concat from table
specialchars =
'\"': '\\\"'
'\\': '\\\\'
'\'': '\\\''
'\n': '\\n'
'\r': '\\r'
'\t': '\\t'
replacespecialchar = (c) -> specialchars[c] or c
escape = (arg) ->
return arg if match arg, "^[a-zA-Z0-9_.-]+$"
'"'..(gsub arg, "([\"\\\n\r\t])", replacespecialchar)..'"'
parseargs = (argstr) ->
state = 'normal'
current, ci = {}, 1
args, ai = {}, 1
c = nil
i = 0
running = true
add = ->
current[ci], ci = c, ci+1
push = ->
args[ai], ai, current, ci = (concat current), ai+1, {}, 1 if ci!=1
addv = (v) ->
current[ci], ci = v, ci+1
fail = (msg) ->
error "failed to parse: #{msg} in state #{state} at pos #{i}", 2
finish = ->
running = false
EOF = ''
while running
i += 1
c = sub argstr, i, i
switch state
when 'normal'
switch c
when '\"'
state = 'doublequote'
when '\''
state = 'singlequote'
when ' '
push!
when '\n'
push!
when '\t'
push!
when '\\'
state = 'backslashnormal'
when EOF
push!
finish!
else
add!
when 'doublequote'
switch c
when '\"'
state = 'normal'
when '\\'
state = 'backslashdoublequote'
when EOF
fail "unexpected EOF"
else
add!
when 'singlequote'
switch c
when '\''
state = 'normal'
when EOF
fail "unexpected EOF"
else
add!
when 'backslashnormal'
switch c
when '\n'
state = 'normal'
when EOF
fail "unexpected EOF"
else
add!
state = 'normal'
when 'backslashdoublequote'
switch c
when '$'
add!
state = 'doublequote'
when '`'
add!
state = 'doublequote'
when '\"'
add!
state = 'doublequote'
when '\\'
add!
state = 'doublequote'
when '\n'
state = 'doublequote'
when EOF
fail "unexpected EOF"
else
addv '\\'
add!
state = 'doublequote'
args
{
:escape
:parseargs
}
+29
View File
@@ -0,0 +1,29 @@
import escape from require 'moonbuild._cmd.common'
import flatten from require 'moonbuild._common'
import execute from require 'moonbuild.compat.execute'
import popen from io
import concat from table
cmdline = (...) ->
concat [escape arg for arg in *flatten ...], ' '
cmd = (...) ->
ok, ret, code = execute cmdline ...
error "command #{first ...} exited with #{code} (#{ret})" unless ok
cmdrst = (...) ->
fd, err = popen cmdline ...
error err unless fd
data = fd\read '*a'
fd\close!
data
sh = (cli) ->
ok, ret, code = execute cli
error "command '#{cli}' exited with #{code} (#{ret})" unless ok
{
:cmd
:cmdrst
:sh
}
+46
View File
@@ -0,0 +1,46 @@
import spawn from require 'posix'
import fork, execp, pipe, dup2, _exit, close from require 'posix.unistd'
import fdopen from require 'posix.stdio'
import wait from require 'posix.sys.wait'
import flatten, first from require 'moonbuild._common'
import remove from table
cmd = (...) ->
code, ty = spawn flatten ...
error "command #{first ...} #{ty} with code #{code}" if ty!='exited' or code!=0
cmdrst = (...) ->
rd, wr = pipe!
pid, err = fork!
if pid == 0
dup2 wr, 1
close rd
args = flatten ...
c = remove args, 1
execp c, args
return _exit 1
if pid == nil
close rd
close wr
error "command #{first ...} failed to start: couldn't fork(): #{err}"
close wr
fd = fdopen rd, 'r'
data = fd\read '*a'
fd\close!
close rd
_, ty, code = wait pid
error "command #{first ...} #{ty} with code #{code}" if ty!='exited' or code!=0
data
sh = (cli) ->
cmd 'sh', '-c', cli
{
:cmd
:cmdrst
:sh
}
+163
View File
@@ -0,0 +1,163 @@
import sort, concat from table
import huge from math
import match, sub from string
common = {}
flatten = (list, ...) ->
return flatten {list, ...} if (select '#', ...)!=0
t = type list
switch t
when 'nil'
{}
when 'string'
{list}
when 'number'
{tostring list}
when 'boolean'
{list}
when 'table'
keys = [k for k in pairs list]
sort keys
elements, i = {}, 1
for k in *keys
if (type k)=='number'
for e in *(flatten list[k])
elements[i], i = e, i+1
else
return {list}
setmetatable elements, __tostring: => concat @, ' '
else
error "can't flatten elements of type #{t}"
first = (list, ...) ->
t = type list
switch t
when 'nil'
if (select '#', ...)==0
nil
else
first ...
when 'string'
list
when 'number'
tostring list
when 'boolean'
list
when 'table'
min = huge
for k in pairs list
if (type k) == 'number'
min = k if k < min
else
return list
first list[min]
else
error "can't find first of type #{t}"
foreach = (list, fn) ->
[fn v for v in *flatten list]
filter = (list, fn) ->
[v for v in *flatten list when fn v]
includes = (list, v) ->
return true if list==v
if (type list) == 'table'
for k, e in pairs list
if (type k) == 'number'
return true if includes e, v
if (type list) == 'number'
return (tostring list) == (tostring v)
false
patget = (s, pat) ->
prefix, suffix = match pat, '^(.*)%%(.*)$'
return s==pat and s or nil unless prefix
if (sub s, 1, #prefix)==prefix and (suffix == '' or (sub s, -#suffix)==suffix)
sub s, #prefix+1, -#suffix-1
else
nil
patset = (s, rep) ->
prefix, suffix = match rep, '^(.*)%%(.*)$'
if prefix
prefix..s..suffix
else
rep
patsubst = (s, pat, rep) ->
prefix, suffix = match pat, '^(.*)%%(.*)$'
rprefix, rsuffix = match rep, '^(.*)%%(.*)$'
t = type s
f = false
if t=='nil'
return nil
if t=='number'
t = 'string'
s = tostring s
if t=='string'
t = 'table'
s = {s}
f = true
if t!='table'
error "can't substitute patterns on type #{t}"
r, i = {}, 1
for s in *flatten s
if not prefix
if s==pat
if rprefix
r[i], i = rprefix..s..rsuffix, i+1
else
r[i], i = rep, i+1
elseif (sub s, 1, #prefix)==prefix and (suffix == '' or (sub s, -#suffix)==suffix)
if rprefix
r[i], i = rprefix..(sub s, #prefix+1, -#suffix-1)..rsuffix, i+1
else
r[i], i = rep, i+1
f and r[1] or r
exclude = (list, ...) ->
exclusions = flatten ...
[v for v in *flatten list when not includes exclusions, v]
min = (list) ->
m = list[1]
for i=2, #list
e = list[i]
m = e if e<m
m
max = (list) ->
m = list[1]
for i=2, #list
e = list[i]
m = e if e>m
m
minmax = (list) ->
m = list[1]
M = list[1]
for i=2, #list
e = list[i]
m = e if e<m
M = e if e>M
m, M
common.flatten = flatten
common.first = first
common.foreach = foreach
common.filter = filter
common.includes = includes
common.patget = patget
common.patset = patset
common.patsubst = patsubst
common.exclude = exclude
common.min = min
common.max = max
common.minmax = minmax
setmetatable common, __call: => [k for k in pairs common]
+198
View File
@@ -0,0 +1,198 @@
import remove, concat from table
import gmatch, match, gsub, sub from string
-- load backend
ok, fs, backend = false, nil, nil
unless ok
ok, fs = pcall -> require 'moonbuild._fs.posix'
backend = 'posix'
unless ok
ok, fs = pcall -> require 'moonbuild._fs.lfs'
backend = 'lfs'
unless ok
ok, fs = pcall -> require 'moonbuild._fs.cmd'
backend = 'cmd'
error "unable to load any fs library, tried luaposix, luafilesystem and posix commands" unless ok
-- caching mechanism
DISABLED = ( -> DISABLED )
NIL = ( -> NIL )
cacheenabled = true
caches = {}
clearcache = ->
v.clearcache! for k, v in pairs caches
clearentry = (entry) ->
v.clearentry entry for k, v in pairs caches
disableentry = (entry) ->
v.disableentry entry for k, v in pairs caches
disablecache = ->
cacheenabled = false
enablecache = ->
cacheenabled = true
withcache = (fn) ->
opts = {}
opts.cache = {}
opts.clearcache = ->
opts.cache = {}
opts.clearentry = (entry) ->
opts.cache[entry] = nil
opts.disableentry = (entry) ->
opts.cache[entry] = DISABLED
caches[fn] = opts
setmetatable opts,
__call: (arg) =>
return fn arg unless cacheenabled
cached = opts.cache[arg]
return fn arg if cached == DISABLED
return nil if cached == NIL
return cached if cached != nil
cached = fn arg
opts.cache[arg] = cached
opts.cache[arg] = NIL if cached == nil
return cached
fs = {
dir: withcache fs.dir
attributes: withcache fs.attributes
mkdir: fs.mkdir
}
import attributes, dir, mkdir from fs
-- actual functions
normalizepath = (file) ->
parts = [part for part in gmatch file, '[^/]+']
absolute = (sub file, 1, 1)=='/'
i = 1
while i<=#parts
if parts[i]=='.'
remove parts, i
continue
if parts[i]=='..' and i!=1 and parts[i-1]!='..'
remove parts, i
remove parts, i-1
i -= 1
continue
i += 1
if #parts==0
absolute and '/' or '.'
else
(absolute and '/' or '') .. concat parts, '/'
ls = (d) ->
[f for f in *dir normalizepath d when f!='.' and f!='..']
lswithpath = (d) ->
return ls '.' if d==''
[d..'/'..f for f in *dir normalizepath d when f!='.' and f!='..']
matchglob = (str, glob) ->
glob = gsub glob, '[%[%]%%+.?-]', => '%'..@
patt = '^'..(gsub glob, '%*%*?', => @=='**' and '.*' or '[^/]*')..'$'
rst = if (type str)=='table'
results, i = {}, 1
for s in *str
rst = (match s, patt) and s
results[i], i = rst, i+1 if rst
results
else
(match str, patt) and str
rst
exists = (f) ->
(attributes normalizepath f) != nil
isdir = (f) ->
((attributes normalizepath f) or {}).mode == 'directory'
wildcard = (glob) ->
parts = [part for part in gmatch glob, '[^/]+']
absolute = (sub glob, 1, 1)=='/'
for i, part in ipairs parts
prevpath = (absolute and '/' or '') .. concat parts, '/', 1, i-1
currpath = (i==1 and '' or (prevpath .. '/')) .. part
if match part, '%*%*.*%*%*'
error "Two '**' in the same path component in a wildcard"
if match part, '%*%*'
prefix = match currpath, '^(.*)%*%*'
suffix = (match part, '%*%*(.*)$') .. (i==#parts and '' or ('/'..concat parts, '/', i+1, #parts))
return {} unless exists prevpath
files = lswithpath prevpath
results, ri = {}, 1
for file in *files
if matchglob file, currpath
if i==#parts
results[ri], ri = file, ri+1
elseif isdir file
for result in *wildcard file .. '/' .. concat parts, '/', i+1, #parts
results[ri], ri = result, ri+1
if (matchglob file, prefix..'**') and isdir file
for result in *wildcard file .. '/**' .. suffix
results[ri], ri = result, ri+1
return results
if match part, '%*'
return {} unless exists prevpath
files = lswithpath prevpath
if i==#parts
return matchglob files, glob
results, ri = {}, 1
for file in *files
if (matchglob file, currpath) and isdir file
for result in *wildcard file .. '/' .. concat parts, '/', i+1, #parts
results[ri], ri = result, ri+1
return results
if exists glob
return {glob}
else
return {}
parent = (file) ->
normalizepath file..'/..'
actualmkdir = mkdir
mkdir = (dir) ->
actualmkdir dir
clearentry parent dir
mkdirs = (dir) ->
return if isdir dir
error "Can't mkdirs #{dir}: file exists" if exists dir
mkdirs parent dir
mkdir dir
-- from the backend
fs = {k, withcache fn for k, fn in pairs fs}
-- own functions
fs.normalizepath = normalizepath
fs.ls = ls
fs.lswithpath = lswithpath
fs.matchglob = matchglob
fs.exists = exists
fs.isdir = isdir
fs.wildcard = wildcard
fs.parent = parent
fs.mkdir = mkdir
fs.mkdirs = mkdirs
-- cache and backend
fs.clearcache = clearcache
fs.clearentry = clearentry
fs.disableentry = disableentry
fs.disablecache = disablecache
fs.enablecache = enablecache
fs.backend = backend
-- the library itself
setmetatable fs, __call: => {'dir', 'ls', 'normalizepath', 'exists', 'isdir', 'wildcard', 'mkdir', 'mkdirs'}
+54
View File
@@ -0,0 +1,54 @@
import escape from require 'moonbuild._cmd'
import execute from require 'moonbuild.compat.execute'
import popen from io
import gmatch, match, sub from string
error "commands ls and stat aren't available" unless (execute "which ls >/dev/null 2>&1") and (execute "which stat >/dev/null 2>&1")
{
dir: (path) ->
[file for file in (popen "ls -1 #{escape path}")\lines!]
attributes: (path) ->
fd = popen "stat -c '%d %i %A %h %u %g %s %b %t %T %X %Y %Z' #{escape path}"
stat = [part for part in gmatch (fd\read '*a'), "%S+"]
fd\close!
fd = popen "stat -f -c '%S' #{escape path}"
blksize = match (fd\read '*a'), '%S+'
fd\close!
{
dev: tonumber stat[1]
ino: tonumber stat[2]
nlink: tonumber stat[4]
uid: tonumber stat[5]
gid: tonumber stat[6]
size: tonumber stat[7]
blocks: tonumber stat[8]
blksize: tonumber blksize
access: tonumber stat[11]
modification: tonumber stat[12]
change: tonumber stat[13]
permissions: do
sub stat[3], 2
mode: do
switch sub stat[3], 1, 1
when '-' then 'file'
when 'd' then 'directory'
when 'l' then 'link'
when 's' then 'socket'
when 'p' then 'named pipe'
when 'c' then 'char device'
when 'b' then 'block device'
else 'other'
rdev: do
(tonumber stat[9]) * 256 + (tonumber stat[10])
}
mkdir: (path) ->
error "Mkdir #{path} failed" unless execute "mkdir #{escape path}"
}
+12
View File
@@ -0,0 +1,12 @@
import dir, attributes, mkdir from require 'lfs'
{
dir: (path) ->
[v for v in dir path]
attributes: attributes
mkdir: (path) ->
ok, err = mkdir path
error "Failed to mkdir #{path}: #{err}" unless ok
}
+68
View File
@@ -0,0 +1,68 @@
import dir from require 'posix.dirent'
import stat, mkdir, S_IFMT, S_IFBLK, S_IFCHR, S_IFDIR, S_IFIFO, S_IFLINK, S_IFREG, S_IFSOCK from require 'posix.sys.stat'
import band, btest from require 'moonbuild.compat.bit'
import concat from table
{
dir: dir
attributes: (path) ->
st = stat path
return nil unless st
mode = st.st_mode
{
mode: do
ty = band mode, S_IFMT
switch ty
when S_IFREG then 'file'
when S_IFDIR then 'directory'
when S_IFLINK then 'link'
when S_IFSOCK then 'socket'
when S_IFIFO then 'named pipe'
when S_IFCHR then 'char device'
when S_IFBLK then 'block device'
else 'other'
permissions: do
_suid = btest mode, 2048
_sgid = btest mode, 1024
_stic = btest mode, 512
_ur = btest mode, 256
_uw = btest mode, 128
_ux = btest mode, 64
_gr = btest mode, 32
_gw = btest mode, 16
_gx = btest mode, 8
_or = btest mode, 4
_ow = btest mode, 2
_ox = btest mode, 1
concat {
_ur and 'r' or '-'
_uw and 'w' or '-'
_suid and 's' or (_ux and 'x' or '-')
_gr and 'r' or '-'
_gw and 'w' or '-'
_sgid and 's' or (_gx and 'x' or '-')
_or and 'r' or '-'
_ow and 'w' or '-'
_stic and 't' or (_ox and 'x' or '-')
}
dev: st.st_dev
ino: st.st_ino
nlink: st.st_nlink
uid: st.st_uid
gid: st.st_gid
rdev: st.st_rdev
access: st.st_atime
modification: st.st_mtime
change: st.st_ctime
size: st.st_size
blocks: st.st_blocks
blksize: st.st_blksize
}
mkdir: (path) ->
ok, err = mkdir path
error "Failed to mkdir #{path}: #{err}" unless ok
}
+47
View File
@@ -0,0 +1,47 @@
import to_lua from require 'moonscript.base'
import parseargs, cmdrst from require 'moonbuild._cmd'
import gmatch, match, gsub from string
import open from io
util = {}
_pkgconfig = (mode, ...) ->
parseargs cmdrst 'pkg-config', "--#{mode}", ...
pkgconfig = setmetatable {}, __index: (mode) => (...) -> _pkgconfig mode, ...
_cdeps = (cc, cflags, path) ->
raw = cmdrst cc, cflags, '-M', path
rawlist = gsub (match raw, ':(.+)'), '\\\n', ' '
[v for v in gmatch rawlist, '%S+']
cdeps = setmetatable {},
__index: (cc) => (path, cflags) -> _cdeps cc, cflags, path
__call: (path, cflags) => _cdeps 'cc', cflags, path
readfile = (filename) ->
fd, err = open filename, 'rb'
error err unless fd
data, err = fd\read '*a'
error err unless data
fd\close!
data
writefile = (filename, data) ->
fd, err = open filename, 'wb'
error err unless fd
ok, err = fd\write data
error err unless ok
fd\close!
nil
moonc = (infile, outfile) ->
code, err = to_lua readfile infile
error "Failed to compile #{@infile}: #{err}" unless code
writefile outfile, code
util.pkgconfig = pkgconfig
util.cdeps = cdeps
util.readfile = readfile
util.writefile = writefile
util.moonc = moonc
setmetatable util, __call: => [k for k in pairs util]
+91
View File
@@ -0,0 +1,91 @@
loadstring = loadstring or load
import floor, ceil, pow from math
band = loadstring [[local a, b = ...; return a & b ]]
bor = loadstring [[local a, b = ...; return a | b ]]
bxor = loadstring [[local a, b = ...; return a ~ b ]]
bnot = loadstring [[local a = ...; return ~a ]]
shl = loadstring [[local a, b = ...; return a << b]]
shr = loadstring [[local a, b = ...; return a >> b]]
unless band
_checkint = (n) ->
if n%1 == 0
n
else
error "not an int"
_shl = (a, b) ->
a * pow(2, b)
_shr = (a, b) ->
v = a / pow(2, b)
if v<0
ceil v
else
floor v
_shr1 = (n) ->
n /= 2
if n<0
ceil v
else
floor v
_band = (a, b) ->
v = 0
n = 1
for i=0, 63
if a%2 == 1 and b%2 == 1
v += n
if i!=63
a = _shr1 a
b = _shr1 b
n *= 2
v
_bor = (a, b) ->
v = 0
n = 1
for i=0, 63
if a%2 == 1 or b%2 == 1
v += n
if i!=63
a = _shr1 a
b = _shr1 b
n *= 2
v
_bxor = (a, b) ->
v = 0
n = 1
for i=0, 63
if a%2 != b%2
v += n
if i!=63
a = _shr1 a
b = _shr1 b
n *= 2
v
_bnot = (a) ->
v = 0
n = 1
for i=0, 63
if a%2 == 0
v += n
if i!=63
a = _shr1 a
n *= 2
v
band = (a, b) -> _band (_checkint a), (_checkint b)
bor = (a, b) -> _bor (_checkint a), (_checkint b)
bxor = (a, b) -> _bxor (_checkint a), (_checkint b)
bnot = (a) -> _bnot (_checkint a)
shl = (a, b) -> _shl (_checkint a), (_checkint b)
shr = (a, b) -> _shr (_checkint a), (_checkint b)
btest = (a, b) -> (band a, b) == b
{ :band, :bor, :bxor, :bnot, :shl, :shr, :btest }
+29
View File
@@ -0,0 +1,29 @@
pcall = require 'moonbuild.compat.pcall'
runwithcontext = if setfenv
(fn, ctx, ...) ->
env = getfenv fn
setfenv fn, ctx
local data, ndata, ok
acc = (succ, ...) ->
ok = succ
if succ
data = {...}
ndata = select '#', ...
else
data = ...
acc pcall fn, ...
setfenv fn, env
if ok
unpack data, 1, ndata
else
error data
else
import dump from string
(fn, ctx, ...) ->
code = dump fn, false
fn = load code, 'runwithcontext', 'b', ctx
fn ...
{ :runwithcontext }
+10
View File
@@ -0,0 +1,10 @@
import execute from os
{
execute: (cmd) ->
a, b, c = execute cmd
if (type a) == 'boolean'
a, b, c
else
a==0 or nil, 'exit', a
}
+12
View File
@@ -0,0 +1,12 @@
pcall = _G.pcall
unpack = _G.unpack or table.unpack
testfn = (a, b) -> a == b and a == 1 and true or error!
testok, testrst = pcall testfn, 1, 1
unless testok and testrst
realpcall = pcall
pcall = (fn, ...) ->
args = { n: (select '#', ...), ... }
realpcall -> fn unpack args, 1, args.n
pcall
+38
View File
@@ -0,0 +1,38 @@
import runwithcontext from require 'moonbuild.compat.ctx'
topenv = require 'moonbuild.env.top'
initenv = require 'moonbuild.env.init'
import includes from require 'moonbuild._common'
import insert from table
class Context
new: =>
@targets = {}
@defaulttargets = {}
@variables = {}
@inits = {}
addvar: (var) =>
@variables[var.name] = var
addinit: (fn) =>
insert @inits, fn
addtarget: (target) =>
insert @targets, target
resetexecuted: =>
@executedtargets = {}
adddefault: (target) =>
error "not a target of the current context: #{target}" unless includes @targets, target
error "not a named target" unless (type target.name) == 'string'
insert @defaulttargets, target.name
load: (code, overrides) =>
runwithcontext code, (topenv @, overrides)
init: =>
if @inits[1]
env = (initenv @)
for init in *@inits
runwithcontext code, env
+215
View File
@@ -0,0 +1,215 @@
import first, filter, foreach, flatten, patsubst, includes from require 'moonbuild._common'
import runwithcontext from require 'moonbuild.compat.ctx'
globalenv = require 'moonbuild.env.global'
import exists, parent, mkdirs, clearentry, disableentry, attributes from require 'moonbuild._fs'
import sort, insert, remove from table
import huge from math
local DepNode, FileTarget
nodepriority = (a, b) ->
ta = type a.name
tb = type b.name
da = #a.deps
db = #b.deps
sa = a.sync
sb = b.sync
if ta=='string' and tb!='string'
return true
elseif ta!='string' and tb=='string'
return false
elseif a.priority > b.priority
return true
elseif a.priority < b.priority
return false
elseif sa and not sb
return false
elseif sb and not sa
return true
else
return da < db
transclosure = (obj, prop) ->
elems = {}
i = 1
set = {}
imp = (e) ->
return unless e[prop]
for v in *e[prop]
if not set[v]
elems[i], i = v, i+1
set[v] = i
imp v
imp obj
elems
mtime = (path) ->
attr = attributes path
attr and attr.modification
class DepGraph
new: (@ctx, names={}) =>
@nodes = {}
@env = globalenv @ctx
for name in *names
@addnode name
addnode: (name) =>
return if @nodes[name]
elected = @resolvedeps name
@nodes[name] = elected
for dep in *(transclosure elected, 'deps')
@nodes[dep.name] = dep
dep.deps = nil
elected.deps = nil
resolvedeps: (name) =>
do
node = @nodes[name]
return node, {} if node
candidates = filter {@ctx.targets, FileTarget!}, (target) -> target\matches name
nodes = foreach candidates, (candidate) -> a: {pcall -> DepNode @, candidate, name}
resolved = foreach (filter nodes, (node) -> node.a[1]), (node) -> node.a[2]
sort resolved, nodepriority
resolved[1] or error "Cannot resolve target #{name}: #{#candidates} candidates, #{#resolved} resolved"
buildablenodes: =>
[v for k, v in pairs @nodes when v\canbuild! and not v.built]
reset: =>
n.built = false for k, n in pairs @nodes
resetchildren: (names) =>
done = {}
stack = [v for v in *names]
while #stack != 0
name = remove stack
continue if done[name]
done[name] = true
node = @nodes[name]
node.built = false
insert stack, n for n in *(node\children!)
class DepNode
new: (@dag, target, @name) =>
@priority = target.priority
@buildfunctions = target.buildfunctions
@mkdirs = target._mkdirs
@sync = target._sync
@type = target._type
@outs = foreach target.outfiles, (name) -> patsubst @name, target.pattern, name
@type = 'virtual' if #@outs == 0
@built = false
resolve = (name) -> @dag\resolvedeps patsubst @name, target.pattern, name
after = flatten foreach target.needtargets, resolve
deps = flatten foreach target.infiles, resolve
if #target.depfunctions!=0
ctx = setmetatable {},
__index: (_, k) ->
switch k
when 'infile'
f = first deps
f and f.name
when 'infiles'
foreach deps, => @name
when 'outfile'
f = first @outs
f and f.name
when 'outfiles'
foreach @outs, => @name
when 'name'
@name
else
error "No such field in TargetDepsContext: #{k}"
__newindex: (k) =>
error "Attempt to set field #{k} of TargetDepsContext"
for depfn in *target.depfunctions
deps = flatten deps, foreach (runwithcontext depfn, @dag.env, ctx), resolve
@ins = foreach deps, (dep) -> dep.name
@after = foreach after, (dep) -> dep.name
@deps = flatten { deps, after }
@built = true if #@deps == 0 and #@buildfunctions == 0
children: =>
[k for k, n in pairs @dag.nodes when (includes n.ins, @name) or (includes n.after, @name)]
canbuild: =>
for node in *flatten { @ins, @after }
if not @dag.nodes[node].built
return false
for file in *@ins
if not exists file
error "Node #{@name} has ran all of its parents, but can't run since #{file} doesn't exist. Did you mean to use after instead of depends?"
return true
build: (opts={}) =>
force = opts.force or false
quiet = opts.quiet or false
return false if @built or #@buildfunctions == 0
return false unless force or @shouldbuild!
print "#{@type == 'virtual' and "Running" or "Building"} #{@name}" unless quiet
@actuallybuild!
true
shouldbuild: =>
-- targets with no outputs / inputs and virtual targets *NEED* to be built
return true if #@outs == 0 or #@ins == 0 or @type == 'virtual'
-- check min mtime for outputs
minout = huge
for file in *@outs
time = mtime file
-- if an output file is missing, we *NEED* to build it
return true if not time
minout = time if time < minout
-- check max mtime for inputs
maxin = 0
for file in *@ins
time = mtime file
maxin = time if time > maxin
-- if any input file is more recent than any output file, we need to build
maxin > minout
actuallybuild: =>
if @mkdirs
mkdirs parent file for file in *@outs
disableentry file for file in *@outs
ctx = setmetatable {},
__index: (_, k) ->
switch k
when 'infile' then @ins[1]
when 'infiles' then @ins
when 'outfile' then @outs[1]
when 'outfiles' then @outs
when 'name' then @name
else error "No such field in TargetContext: #{k}"
__newindex: (k) =>
error "Attempt to set field #{k} of TargetContext"
for fn in *@buildfunctions
runwithcontext fn, @dag.env, ctx
updatecache: =>
clearentry file for file in *@outs
class FileTarget
new: =>
@priority = -huge
@buildfunctions = {}
@_mkdirs = false
@_sync = false
@_type = 'file'
@needtargets = {}
@infiles = {}
@depfunctions = {}
@outfiles = {'%'}
@pattern = '%'
matches: (name) =>
exists name
DepGraph
+54
View File
@@ -0,0 +1,54 @@
import flatten, includes, patget from require 'moonbuild._common'
import insert from table
class Target
new: (@ctx, @name, opts={}) =>
@name = flatten @name if (type @name) != 'string'
@pattern = opts.pattern or ((type @name) == 'string' and @name or '%')
@priority = opts.priority or 0
error "pattern must be a string" unless (type @pattern) == 'string'
error "priority must be an int" unless (type @priority) == 'number' and @priority%1 == 0
@outfiles = {}
@infiles = {}
@needtargets = {}
@depfunctions = {}
@buildfunctions = {}
@_mkdirs = false
@_sync = false
@_type = 'normal'
@public = false
matches: (name) =>
if @name==name
return true
if (includes @name, name) and patget name, @pattern
return true
return false
produces: (...) =>
n = #@outfiles+1
for obj in *flatten ...
@outfiles[n], n = obj, n+1
depends: (...) =>
if (type ...) == 'function'
insert @depfunctions, (...)
else
n = #@infiles+1
for obj in *flatten ...
@infiles[n], n = obj, n+1
after: (...) =>
n = #@needtargets+1
for tgt in *flatten ...
@needtargets[n], n = tgt, n+1
fn: (fn) =>
insert @buildfunctions, fn
sync: =>
@_sync = true
mkdirs: =>
@_mkdirs = true
+11
View File
@@ -0,0 +1,11 @@
import flatten from require 'moonbuild._common'
class Variable
@NIL: ->
new: (@name, ...) =>
@public = false
if (select '#', ...) !=1 or (type ...) == 'table'
@value = flatten ...
else
@value = ...
+2
View File
@@ -0,0 +1,2 @@
ok, MultiProcessExecutor = pcall -> require 'moonbuild.core.multiprocessexecutor'
ok and MultiProcessExecutor or require 'moonbuild.core.singleprocessexecutor'
+82
View File
@@ -0,0 +1,82 @@
SingleProcessExecutor = require 'moonbuild.core.singleprocessexecutor'
import fork, _exit from require 'posix.unistd'
import wait from require 'posix.sys.wait'
import open, stderr from io
import match from string
class Executor
@getmaxparallel: =>
fd = open '/proc/cpuinfo', 'r'
return 1 unless fd
ncpu = 0
for line in fd\lines!
ncpu += 1 if match line, '^processor%s*:'
fd\close!
ncpu == 0 and 1 or ncpu
new: (@dag, @nparallel) =>
@processes = {}
@nprocesses = 0
@building = {}
@nbuilt = 0
execute: (opts) =>
if @nparallel == 1
return (SingleProcessExecutor @dag, 1)\execute opts
block = @dag\buildablenodes!
while #block != 0
for node in *block
@addprocess node, opts
if @nprocesses == @nparallel
@waitprocess!
block = [node for node in *@dag\buildablenodes! when not @building[node]]
while #block == 0 and @nprocesses != 0
@waitprocess!
block = [node for node in *@dag\buildablenodes! when not @building[node]]
while @nprocesses !=0
@waitprocess!
for name, node in pairs @dag.nodes
error "Node #{name} wasn't built" unless node.built
unless opts.quiet
if @nbuilt == 0
print "Nothing to be done"
else
print "Built #{@nbuilt} targets"
addprocess: (node, opts) =>
if node.sync
while @nprocesses != 0
@waitprocess!
node\build opts
node.built = true
node\updatecache!
return
pid = fork!
error "Failed to fork" unless pid
if pid!=0
@processes[pid] = node
@nprocesses += 1
@building[node] = true
else
ok, status = pcall -> node\build opts
if ok
_exit status and 0 or 2
_exit 0
else
stderr\write status
_exit 1
waitprocess: =>
pid, ty, status = wait!
error "Failed to wait" unless pid
error "Failed to build #{@processes[pid].name}" if ty != 'exited' or status != 0 and status != 2
@processes[pid].built = true
@processes[pid]\updatecache!
@processes[pid] = nil
@nprocesses -= 1
@nbuilt += 1 if status == 0
+24
View File
@@ -0,0 +1,24 @@
class Executor
@getmaxparallel: => 1
new: (@dag, @nparallel) =>
execute: (opts) =>
nbuilt = 0
block = @dag\buildablenodes!
while #block != 0
for node in *block
nbuilt +=1 if node\build opts
node\updatecache!
node.built = true
block = @dag\buildablenodes!
for name, node in pairs @dag.nodes
error "Node #{name} wasn't built" unless node.built
unless opts.quiet
if nbuilt == 0
print "Nothing to be done"
else
print "Built #{nbuilt} targets"
+18
View File
@@ -0,0 +1,18 @@
_ = require 'moonbuild._'
(ctx) ->
varlayer = setmetatable {},
__index: _G
for name, var in pairs ctx.variables
rawset varlayer, name, var.value
env = setmetatable {},
__index: varlayer
__newindex: (k) => error "attempt to assign to global variable '#{k}', which is disabled in the global env"
rawset env, '_', _
rawset env, '_G', env
rawset env, '_ENV', env
env, varlayer
+32
View File
@@ -0,0 +1,32 @@
Target = require 'moonbuild.core.Target'
Variable = require 'moonbuild.core.Variable'
_ = require 'moonbuild._'
import flatten from _
(ctx) ->
varlayer = setmetatable {},
__index: _G
for name, var in pairs ctx.variables
rawset varlayer, name, var.value
env = setmetatable {},
__index: varlayer
__newindex: (k) => error "attempt to assign to global variable '#{k}', use the function 'var' instead"
rawset env, '_', _
rawset env, '_G', env
rawset env, '_ENV', env
rawset env, 'var', (name, ...) ->
var = Variable name, ...
ctx\addvar var
rawset varlayer, name, var.value
var
rawset env, 'target', (name, opts) ->
target = Target ctx, name, opts
ctx\addtarget target
target
env, varlayer
+31
View File
@@ -0,0 +1,31 @@
initenv = require 'moonbuild.env.init'
Target = require 'moonbuild.core.Target'
Variable = require 'moonbuild.core.Variable'
(ctx, overrides) ->
env, varlayer = initenv ctx
rawset env, 'default', (target) ->
ctx\adddefault target
target
rawset env, 'public', (e) ->
clazz = ((getmetatable e) or {}).__class
if clazz == Target
e.public = true
elseif clazz == Variable
e.public = true
override = overrides[e.name]
if override
override = nil if override == Variable.NIL
e.value = override
rawset varlayer, e.name, override
else
error "cannot set an object of type #{clazz and clazz.__name or type e} public"
e
rawset env, 'init', (fn) ->
error "you can only add functions to init" unless (type fn) == 'function'
ctx\addinit fn
env, varlayer
-155
View File
@@ -1,155 +0,0 @@
local dir, attributes
do
local _obj_0 = require('lfs')
dir, attributes = _obj_0.dir, _obj_0.attributes
end
local gmatch, match, gsub, sub
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
do
local _obj_0 = table
insert, concat = _obj_0.insert, _obj_0.concat
end
local ls
ls = function(d)
local _accum_0 = { }
local _len_0 = 1
for f in dir(d) do
if f ~= '.' and f ~= '..' then
_accum_0[_len_0] = f
_len_0 = _len_0 + 1
end
end
return _accum_0
end
local lswithpath
lswithpath = function(d)
if d == '' then
return ls('.')
end
local _accum_0 = { }
local _len_0 = 1
for f in dir(d) do
if f ~= '.' and f ~= '..' then
_accum_0[_len_0] = d .. '/' .. f
_len_0 = _len_0 + 1
end
end
return _accum_0
end
local exists
exists = function(f)
return (attributes(f)) ~= nil
end
local isdir
isdir = function(f)
local a = attributes(f)
return a and a.mode == 'directory' or false
end
local mtime
mtime = function(f)
local a = attributes(f)
return a and a.modification
end
local matchglob
matchglob = function(str, glob)
local patt = '^' .. (gsub((gsub(glob, '%*%*', '.*')), '%*', '[^/]*')) .. '$'
local rst
if (type(str)) == 'table' then
local results, i = { }, 1
for _index_0 = 1, #str do
local s = str[_index_0]
rst = (match(s, patt)) and s
if rst then
results[i], i = rst, i + 1
end
end
rst = results
else
rst = (match(str, patt)) and str
end
return rst
end
local wildcard
wildcard = function(glob)
local parts
do
local _accum_0 = { }
local _len_0 = 1
for part in gmatch(glob, '[^/]+') do
_accum_0[_len_0] = part
_len_0 = _len_0 + 1
end
parts = _accum_0
end
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
if match(part, '%*%*.*%*%*') then
error("Two '**' in the same path component in a wildcard")
end
if match(part, '%*%*') then
local prefix = match(currpath, '^(.*)%*%*')
local suffix = (match(part, '%*%*(.*)$')) .. (i == #parts and '' or ('/' .. concat(parts, '/', i + 1, #parts)))
local files = lswithpath(prevpath)
local results = { }
for _index_0 = 1, #files do
local file = files[_index_0]
if matchglob(file, currpath) then
if i == #parts then
insert(results, file)
elseif isdir(file) then
local _list_0 = wildcard(file .. '/' .. concat(parts, '/', i + 1, #parts))
for _index_1 = 1, #_list_0 do
local result = _list_0[_index_1]
insert(results, result)
end
end
end
if (matchglob(file, prefix .. '**')) and isdir(file) then
local _list_0 = wildcard(file .. '/**' .. suffix)
for _index_1 = 1, #_list_0 do
local result = _list_0[_index_1]
insert(results, result)
end
end
end
return results
end
if match(part, '%*') then
local files = lswithpath(prevpath)
if i == #parts then
return matchglob(files, glob)
end
local results = { }
for _index_0 = 1, #files do
local file = files[_index_0]
if (matchglob(file, currpath)) and isdir(file) then
local _list_0 = wildcard(file .. '/' .. concat(parts, '/', i + 1, #parts))
for _index_1 = 1, #_list_0 do
local result = _list_0[_index_1]
insert(results, result)
end
end
end
return results
end
end
if exists(glob) then
return {
glob
}
else
return { }
end
end
return {
wildcard = wildcard,
exists = exists,
isdir = isdir,
mtime = mtime
}
-88
View File
@@ -1,88 +0,0 @@
import dir, attributes from require 'lfs'
import gmatch, match, gsub, sub from string
import insert, concat from table
ls = (d) ->
[f for f in dir d when f!='.' and f!='..']
lswithpath = (d) ->
if d==''
return ls '.'
[d..'/'..f for f in dir d when f!='.' and f!='..']
exists = (f) ->
(attributes f) != nil
isdir = (f) ->
a = attributes f
a and a.mode == 'directory' or false
mtime = (f) ->
a = attributes f
a and a.modification
matchglob = (str, glob) ->
patt = '^'..(gsub (gsub glob, '%*%*', '.*'), '%*', '[^/]*')..'$'
rst = if (type str)=='table'
results, i = {}, 1
for s in *str
rst = (match s, patt) and s
results[i], i = rst, i+1 if rst
results
else
(match str, patt) and str
rst
wildcard = (glob) ->
parts = [part for part in gmatch glob, '[^/]+']
absolute = (sub glob, 1, 1)=='/'
for i, part in ipairs parts
prevpath = (absolute and '/' or '') .. concat parts, '/', 1, i-1
currpath = prevpath .. '/' .. part
if match part, '%*%*.*%*%*'
error "Two '**' in the same path component in a wildcard"
if match part, '%*%*'
prefix = match currpath, '^(.*)%*%*'
suffix = (match part, '%*%*(.*)$') .. (i==#parts and '' or ('/'..concat parts, '/', i+1, #parts))
files = lswithpath prevpath
results = {}
for file in *files
if matchglob file, currpath
if i==#parts
insert results, file
elseif isdir file
for result in *wildcard file .. '/' .. concat parts, '/', i+1, #parts
insert results, result
if (matchglob file, prefix..'**') and isdir file
for result in *wildcard file .. '/**' .. suffix
insert results, result
return results
if match part, '%*'
files = lswithpath prevpath
if i==#parts
return matchglob files, glob
results = {}
for file in *files
if (matchglob file, currpath) and isdir file
for result in *wildcard file .. '/' .. concat parts, '/', i+1, #parts
insert results, result
return results
if exists glob
return {glob}
else
return {}
{
:wildcard
:exists, :isdir
:mtime
}
+60
View File
@@ -0,0 +1,60 @@
import loadfile from require 'moonscript.base'
Context = require 'moonbuild.context'
DepGraph = require 'moonbuild.core.DAG'
Executor = require 'moonbuild.core.executor'
_ = require 'moonbuild._'
import insert from table
moonbuild = (...) ->
-- build argument table
opts = {}
for i=1, select '#', ...
arg = select i, ...
if (type arg) == 'string'
insert opts, arg
elseif (type arg) == 'table'
for k, v in pairs arg
opts[k] = v if (type k) != 'number'
for i, v in ipairs arg
insert opts, v
else
error "Invalid argument type #{type arg} for moonbuild"
-- resolve arguments
buildfile = opts.buildfile or opts.b or 'Build.moon'
opts.buildfile = buildfile
parallel = opts.parallel or opts.j or 1
parallel = true if parallel == 'y'
opts.parallel = parallel
quiet = opts.quiet or opts.q or false
opts.quiet = quiet
force = opts.force or opts.f or false
opts.force = force
verbose = opts.verbose or opts.v or false
opts.verbose = verbose
-- create context and DAG
ctx = Context!
ctx\load (loadfile buildfile), opts
print "Loaded buildfile" if verbose
ctx\init!
print "Initialized buildfile" if verbose
targets = #opts==0 and ctx.defaulttargets or opts
dag = DepGraph ctx, targets
print "Created dependancy graph" if verbose
-- and build
nparallel = parallel == true and Executor\getmaxparallel! or parallel
print "Building with #{nparallel} max parallel process#{nparallel>1 and "es" or ""}" if verbose
executor = Executor dag, nparallel
executor\execute opts
print "Finished" if verbose
table = {
:moonbuild, :_
:Context, :DepGraph, :Executor
}
setmetatable table,
__call: (...) => moonbuild ...
__index: (name) => require "moonbuild.#{name}"
-52
View File
@@ -1,52 +0,0 @@
local match, gmatch, sub
do
local _obj_0 = string
match, gmatch, sub = _obj_0.match, _obj_0.gmatch, _obj_0.sub
end
local upper, lower
do
local _obj_0 = string
upper, lower = _obj_0.upper, _obj_0.lower
end
local GLOB_PATT = '^([^%%]*)%%([^%%]*)$'
local patsubst
patsubst = function(str, pattern, replacement)
if (type(str)) == 'table' then
local _accum_0 = { }
local _len_0 = 1
for _index_0 = 1, #str do
local s = str[_index_0]
_accum_0[_len_0] = patsubst(s, pattern, replacement)
_len_0 = _len_0 + 1
end
return _accum_0
end
local prefix, suffix = match(pattern, GLOB_PATT)
if not (prefix) then
return str
end
local reprefix, resuffix = match(replacement, GLOB_PATT)
if not (reprefix) then
return replacement
end
if (sub(str, 1, #prefix)) == prefix and (sub(str, -#suffix)) == suffix then
return reprefix .. (sub(str, #prefix + 1, -#suffix - 1)) .. resuffix
end
return str
end
local splitsp
splitsp = function(str)
local _accum_0 = { }
local _len_0 = 1
for elem in gmatch(str, '%S+') do
_accum_0[_len_0] = elem
_len_0 = _len_0 + 1
end
return _accum_0
end
return {
patsubst = patsubst,
splitsp = splitsp,
upper = upper,
lower = lower
}
-25
View File
@@ -1,25 +0,0 @@
import match, gmatch, sub from string
import upper, lower from string
GLOB_PATT='^([^%%]*)%%([^%%]*)$'
patsubst = (str, pattern, replacement) ->
return [patsubst s, pattern, replacement for s in *str] if (type str)=='table'
prefix, suffix = match pattern, GLOB_PATT
return str unless prefix
reprefix, resuffix = match replacement, GLOB_PATT
return replacement unless reprefix
if (sub str, 1, #prefix)==prefix and (sub str, -#suffix)==suffix
return reprefix..(sub str, #prefix+1, -#suffix-1)..resuffix
str
splitsp = (str) ->
[elem for elem in gmatch str, '%S+']
{
:patsubst
:splitsp
:upper, :lower
}
-132
View File
@@ -1,132 +0,0 @@
local insert, remove, concat, sort
do
local _obj_0 = table
insert, remove, concat, sort = _obj_0.insert, _obj_0.remove, _obj_0.concat, _obj_0.sort
end
local unpack = unpack or table.unpack
local sortedpairs
sortedpairs = function(table, cmp)
local keys
do
local _accum_0 = { }
local _len_0 = 1
for k in pairs(table) do
_accum_0[_len_0] = k
_len_0 = _len_0 + 1
end
keys = _accum_0
end
sort(keys, cmp)
return coroutine.wrap(function()
for _index_0 = 1, #keys do
local key = keys[_index_0]
coroutine.yield(key, table[key])
end
end)
end
local min
min = function(table, cmp)
if cmp == nil then
cmp = function(a, b)
return a < b
end
end
local val = table[1]
for i = 2, #table do
local elem = table[i]
if cmp(val, elem) then
val = elem
end
end
return val
end
local max
max = function(table, cmp)
if cmp == nil then
cmp = function(a, b)
return a < b
end
end
local val = table[1]
for i = 2, #table do
local elem = table[i]
if not cmp(val, elem) then
val = elem
end
end
return val
end
local foreach
foreach = function(tab, fn)
local _accum_0 = { }
local _len_0 = 1
for _index_0 = 1, #tab do
local e = tab[_index_0]
_accum_0[_len_0] = fn(e)
_len_0 = _len_0 + 1
end
return _accum_0
end
local first
first = function(tab, fn)
for _index_0 = 1, #tab do
local e = tab[_index_0]
if fn(e) then
return e
end
end
end
local exclude
exclude = function(tab, ...)
local i = 1
while i <= #tab do
local removed = false
for j = 1, select('#', ...) do
if tab[i] == select(j, ...) then
remove(tab, i)
removed = true
break
end
end
if not (removed) then
i = i + 1
end
end
return tab
end
local flatten
flatten = function(tab)
if (type(tab)) ~= 'table' then
return {
tab
}
end
local out = { }
for _index_0 = 1, #tab do
local e = tab[_index_0]
if (type(e)) == 'table' then
local _list_0 = flatten(e)
for _index_1 = 1, #_list_0 do
local v = _list_0[_index_1]
insert(out, v)
end
else
insert(out, e)
end
end
return out
end
return {
min = min,
max = max,
foreach = foreach,
first = first,
exclude = exclude,
flatten = flatten,
sortedpairs = sortedpairs,
insert = insert,
remove = remove,
concat = concat,
sort = sort,
unpack = unpack
}
-66
View File
@@ -1,66 +0,0 @@
import insert, remove, concat, sort from table
unpack or= table.unpack
sortedpairs = (table, cmp) ->
keys = [k for k in pairs table]
sort keys, cmp
coroutine.wrap ->
for key in *keys
coroutine.yield key, table[key]
min = (table, cmp=(a, b) -> a<b) ->
val = table[1]
for i=2, #table
elem = table[i]
if cmp val, elem
val = elem
val
max = (table, cmp=(a, b) -> a<b) ->
val = table[1]
for i=2, #table
elem = table[i]
if not cmp val, elem
val = elem
val
foreach = (tab, fn) ->
[fn e for e in *tab]
first = (tab, fn) ->
for e in *tab
return e if fn e
exclude = (tab, ...) ->
i=1
while i<=#tab
removed=false
for j=1, select '#', ...
if tab[i]==select j, ...
remove tab, i
removed = true
break
i += 1 unless removed
tab
flatten = (tab) ->
return {tab} if (type tab)!='table'
out = {}
for e in *tab
if (type e)=='table'
insert out, v for v in *flatten e
else
insert out, e
out
{
:min, :max
:foreach
:first
:exclude
:flatten
:sortedpairs
:insert, :remove, :concat, :sort
:unpack
}
-189
View File
@@ -1,189 +0,0 @@
local wildcard, exists, isdir, mtime
do
local _obj_0 = require('moonbuild.fsutil')
wildcard, exists, isdir, mtime = _obj_0.wildcard, _obj_0.exists, _obj_0.isdir, _obj_0.mtime
end
local foreach, first, flatten, exclude, sortedpairs, min, max
do
local _obj_0 = require('moonbuild.tableutil')
foreach, first, flatten, exclude, sortedpairs, min, max = _obj_0.foreach, _obj_0.first, _obj_0.flatten, _obj_0.exclude, _obj_0.sortedpairs, _obj_0.min, _obj_0.max
end
local patsubst, splitsp
do
local _obj_0 = require('moonbuild.stringutil')
patsubst, splitsp = _obj_0.patsubst, _obj_0.splitsp
end
local insert, concat, sort, pairs
do
local _obj_0 = require('moonbuild.tableutil')
insert, concat, sort, pairs = _obj_0.insert, _obj_0.concat, _obj_0.sort, _obj_0.pairs
end
local upper, lower
do
local _obj_0 = require('moonbuild.stringutil')
upper, lower = _obj_0.upper, _obj_0.lower
end
local GLOB_PATT = '^([^%%]*)%%([^%%]*)$'
local escapecmdpart
escapecmdpart = function(p)
if (type(p)) == 'table' then
if p.raw then
return p.raw
end
return concat((function()
local _accum_0 = { }
local _len_0 = 1
for _index_0 = 1, #p do
local part = p[_index_0]
_accum_0[_len_0] = escapecmdpart(part)
_len_0 = _len_0 + 1
end
return _accum_0
end)(), ' ')
end
if p:match('^[a-zA-Z0-9_./-]+$') then
return p
end
return '"' .. p:gsub('\\', '\\\\'):gsub('"', '\\"') .. '"'
end
local escapecmd
escapecmd = function(c, args)
if args == nil then
args = { }
end
c = escapecmdpart(c)
local _list_0 = flatten(args)
for _index_0 = 1, #_list_0 do
local a = _list_0[_index_0]
if a then
c = c .. (' ' .. escapecmdpart(a))
end
end
return c
end
local run
run = function(c, args, params)
if params == nil then
params = { }
end
local escaped = escapecmd(c, args)
if params.print then
print(escaped)
end
local ret, _, code = os.execute(escaped)
if (type(ret)) == 'number' then
ret, code = ret == 0, ret
end
if params.error and not ret then
error(tostring(c) .. " failed with code " .. tostring(code))
end
return ret, code
end
local popen
popen = function(c, args, mode, params)
if mode == nil then
mode = 'r'
end
if params == nil then
params = { }
end
local escaped = escapecmd(c, args)
if params.print then
print(escaped)
end
return io.popen(escaped, mode)
end
local calccdeps
calccdeps = function(infile, includesys)
if includesys == nil then
includesys = false
end
local data = (popen('cc', {
includesys and '-M' or '-MM',
infile
})):read('*a')
local rawdeps = data:gsub('\\\n', ''):match(':(.+)')
local _accum_0 = { }
local _len_0 = 1
for dep in rawdeps:gmatch('%S+') do
if dep ~= infile then
_accum_0[_len_0] = dep
_len_0 = _len_0 + 1
end
end
return _accum_0
end
local findclib
findclib = function(name, mode)
if mode == nil then
mode = 'all'
end
local args = {
name
}
if mode == 'all' or mode == 'cc' then
insert(args, '--cflags')
end
if mode == 'all' or mode == 'ld' then
insert(args, '--libs')
end
local _accum_0 = { }
local _len_0 = 1
for arg in (popen('pkg-config', args)):read('*a'):gmatch('%S+') do
_accum_0[_len_0] = arg
_len_0 = _len_0 + 1
end
return _accum_0
end
local match
match = function(str, glob)
local prefix, suffix = glob:match(GLOB_PATT)
if not (prefix) then
return str == glob
end
if (str:sub(1, #prefix)) == prefix and (str:sub(-#suffix)) == suffix then
return str:sub(#prefix + 1, -#suffix - 1)
end
return false
end
local isglob
isglob = function(glob)
if glob:match(GLOB_PATT) then
return true
else
return false
end
end
local env
env = function(key, def)
return (os.getenv(key)) or def
end
return {
min = min,
max = max,
foreach = foreach,
first = first,
exclude = exclude,
flatten = flatten,
sortedpairs = sortedpairs,
insert = insert,
remove = remove,
concat = concat,
sort = sort,
unpack = unpack,
wildcard = wildcard,
mtime = mtime,
exists = exists,
isdir = isdir,
run = run,
popen = popen,
calccdeps = calccdeps,
findclib = findclib,
patsubst = patsubst,
splitsp = splitsp,
upper = upper,
lower = lower,
match = match,
isglob = isglob,
env = env
}
-95
View File
@@ -1,95 +0,0 @@
import wildcard, exists, isdir, mtime from require 'moonbuild.fsutil'
import foreach, first, flatten, exclude, sortedpairs, min, max from require 'moonbuild.tableutil'
import patsubst, splitsp from require 'moonbuild.stringutil'
import insert, concat, sort, pairs from require 'moonbuild.tableutil'
import upper, lower from require 'moonbuild.stringutil'
GLOB_PATT='^([^%%]*)%%([^%%]*)$'
-- command functions
escapecmdpart= (p) ->
if (type p)=='table'
return p.raw if p.raw
return concat [escapecmdpart part for part in *p], ' '
return p if p\match '^[a-zA-Z0-9_./-]+$'
'"'..p\gsub('\\', '\\\\')\gsub('"', '\\"')..'"'
escapecmd= (c, args={}) ->
c=escapecmdpart c
for a in *flatten args
c..=' '..escapecmdpart a if a
c
run= (c, args, params={}) ->
escaped=escapecmd c, args
print escaped if params.print
ret, _, code=os.execute escaped
ret, code=ret==0, ret if (type ret)=='number'
error "#{c} failed with code #{code}" if params.error and not ret
ret, code
popen= (c, args, mode='r', params={}) ->
escaped=escapecmd c, args
print escaped if params.print
io.popen escaped, mode
calccdeps= (infile, includesys=false) ->
data=(popen 'cc', {includesys and '-M' or '-MM', infile})\read '*a'
rawdeps=data\gsub('\\\n', '')\match ':(.+)'
[dep for dep in rawdeps\gmatch '%S+' when dep!=infile]
findclib= (name, mode='all') ->
args={name}
insert args, '--cflags' if mode=='all' or mode=='cc'
insert args, '--libs' if mode=='all' or mode=='ld'
[arg for arg in (popen 'pkg-config', args)\read('*a')\gmatch '%S+']
-- glob match
match= (str, glob) ->
prefix, suffix=glob\match GLOB_PATT
return str==glob unless prefix
return str\sub #prefix+1, -#suffix-1 if (str\sub 1, #prefix)==prefix and (str\sub -#suffix)==suffix
false
-- is a valid glob
isglob= (glob) ->
return if glob\match GLOB_PATT
true
else
false
-- getenv
env= (key, def) ->
(os.getenv key) or def
{
-- table function
:min, :max
:foreach
:first
:exclude
:flatten
:sortedpairs
:insert, :remove, :concat, :sort
:unpack
-- file functions
:wildcard
:mtime
:exists, :isdir
-- command functions
:run, :popen
:calccdeps, :findclib
-- string functions
:patsubst
:splitsp
:upper, :lower
-- glob functions
:match, :isglob
-- env functions
:env
}
Executable
+2791
View File
File diff suppressed because it is too large Load Diff
+9 -9
View File
@@ -9,18 +9,18 @@ description:
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)
make).
If you can, installing luaposix and/or luafilesystem
will speed up builds and increase stability.
homepage: https://github.com/natnat-mc/moonbuild
dependencies:
- lua >= 5.3
- luafilesystem >= 1.7.0
- lua >= 5.1
- argparse >= 0.7.1-1
- moonscript >= 0.5.0-1
build:
type: builtin
modules:
moonbuild.util: moonbuild/util.lua
moonbuild.fsutil: moonbuild/fsutil.lua
moonbuild.stringutil: moonbuild/stringutil.lua
moonbuild.tableutil: moonbuild/tableutil.lua
install:
bin:
moonbuild: bin/moonbuild.lua
moonbuild: out/moonbuild
modules:
moonbuild: out/moonbuild.lua
+29
View File
@@ -0,0 +1,29 @@
build = {
install = {
bin = {
moonbuild = "bin/moonbuild.lua"
}
},
modules = {
["moonbuild.fsutil"] = "moonbuild/fsutil.lua",
["moonbuild.stringutil"] = "moonbuild/stringutil.lua",
["moonbuild.tableutil"] = "moonbuild/tableutil.lua",
["moonbuild.util"] = "moonbuild/util.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.1",
url = "git://github.com/natnat-mc/moonbuild"
}
version = "1.0.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.0.2",
url = "git://github.com/natnat-mc/moonbuild"
}
version = "1.0.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.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"
+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.4",
url = "git://github.com/natnat-mc/moonbuild"
}
version = "1.1.4-1"
+25
View File
@@ -0,0 +1,25 @@
build = {
install = {
bin = {
moonbuild = "moonbuild.lua"
}
},
type = "builtin"
}
dependencies = {
"lua >= 5.3",
"luafilesystem >= 1.7.0",
"argparse >= 0.7.1-1",
"moonscript >= 0.5.0-1"
}
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.4",
url = "git://github.com/natnat-mc/moonbuild"
}
version = "1.1.4-2"
+24
View File
@@ -0,0 +1,24 @@
build = {
install = {
bin = {
moonbuild = "out/moonbuild"
}
},
type = "builtin"
}
dependencies = {
"lua >= 5.1",
"argparse >= 0.7.1-1",
"moonscript >= 0.5.0-1"
}
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). If you can, installing luaposix and/or luafilesystem will speed up builds and increase stability.\n",
summary = "Small build system in between make and a build.sh"
}
package = "moonbuild"
rockspec_format = "3.0"
source = {
tag = "v2.0.0",
url = "git://github.com/natnat-mc/moonbuild"
}
version = "2.0.0-1"
+24
View File
@@ -0,0 +1,24 @@
build = {
install = {
bin = {
moonbuild = "out/moonbuild"
}
},
type = "builtin"
}
dependencies = {
"lua >= 5.1",
"argparse >= 0.7.1-1",
"moonscript >= 0.5.0-1"
}
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). If you can, installing luaposix and/or luafilesystem will speed up builds and increase stability.\n",
summary = "Small build system in between make and a build.sh"
}
package = "moonbuild"
rockspec_format = "3.0"
source = {
tag = "v2.0.0",
url = "git://github.com/natnat-mc/moonbuild"
}
version = "2.0.0-2"
+24
View File
@@ -0,0 +1,24 @@
build = {
install = {
bin = {
moonbuild = "out/moonbuild"
}
},
type = "builtin"
}
dependencies = {
"lua >= 5.1",
"argparse >= 0.7.1-1",
"moonscript >= 0.5.0-1"
}
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). If you can, installing luaposix and/or luafilesystem will speed up builds and increase stability.\n",
summary = "Small build system in between make and a build.sh"
}
package = "moonbuild"
rockspec_format = "3.0"
source = {
tag = "v2.0.0",
url = "git://github.com/natnat-mc/moonbuild"
}
version = "2.0.0-3"
+24
View File
@@ -0,0 +1,24 @@
build = {
install = {
bin = {
moonbuild = "out/moonbuild"
}
},
type = "builtin"
}
dependencies = {
"lua >= 5.1",
"argparse >= 0.7.1-1",
"moonscript >= 0.5.0-1"
}
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). If you can, installing luaposix and/or luafilesystem will speed up builds and increase stability.\n",
summary = "Small build system in between make and a build.sh"
}
package = "moonbuild"
rockspec_format = "3.0"
source = {
tag = "v2.1.0",
url = "git://github.com/natnat-mc/moonbuild"
}
version = "2.1.0-1"
+24
View File
@@ -0,0 +1,24 @@
build = {
install = {
bin = {
moonbuild = "out/moonbuild"
}
},
type = "builtin"
}
dependencies = {
"lua >= 5.1",
"argparse >= 0.7.1-1",
"moonscript >= 0.5.0-1"
}
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). If you can, installing luaposix and/or luafilesystem will speed up builds and increase stability.\n",
summary = "Small build system in between make and a build.sh"
}
package = "moonbuild"
rockspec_format = "3.0"
source = {
tag = "v2.1.0",
url = "git://github.com/natnat-mc/moonbuild"
}
version = "2.1.0-2"
+24
View File
@@ -0,0 +1,24 @@
build = {
install = {
bin = {
moonbuild = "out/moonbuild"
}
},
type = "builtin"
}
dependencies = {
"lua >= 5.1",
"argparse >= 0.7.1-1",
"moonscript >= 0.5.0-1"
}
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). If you can, installing luaposix and/or luafilesystem will speed up builds and increase stability.\n",
summary = "Small build system in between make and a build.sh"
}
package = "moonbuild"
rockspec_format = "3.0"
source = {
tag = "v2.1.0",
url = "git://github.com/natnat-mc/moonbuild"
}
version = "2.1.0-3"
+24
View File
@@ -0,0 +1,24 @@
build = {
install = {
bin = {
moonbuild = "out/moonbuild"
}
},
type = "builtin"
}
dependencies = {
"lua >= 5.1",
"argparse >= 0.7.1-1",
"moonscript >= 0.5.0-1"
}
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). If you can, installing luaposix and/or luafilesystem will speed up builds and increase stability.\n",
summary = "Small build system in between make and a build.sh"
}
package = "moonbuild"
rockspec_format = "3.0"
source = {
tag = "v2.1.1",
url = "git://github.com/natnat-mc/moonbuild"
}
version = "2.1.1-1"
+24
View File
@@ -0,0 +1,24 @@
build = {
install = {
bin = {
moonbuild = "out/moonbuild"
}
},
type = "builtin"
}
dependencies = {
"lua >= 5.1",
"argparse >= 0.7.1-1",
"moonscript >= 0.5.0-1"
}
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). If you can, installing luaposix and/or luafilesystem will speed up builds and increase stability.\n",
summary = "Small build system in between make and a build.sh"
}
package = "moonbuild"
rockspec_format = "3.0"
source = {
tag = "v2.1.2",
url = "git://github.com/natnat-mc/moonbuild"
}
version = "2.1.2-1"
+24
View File
@@ -0,0 +1,24 @@
build = {
install = {
bin = {
moonbuild = "out/moonbuild"
}
},
type = "builtin"
}
dependencies = {
"lua >= 5.1",
"argparse >= 0.7.1-1",
"moonscript >= 0.5.0-1"
}
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). If you can, installing luaposix and/or luafilesystem will speed up builds and increase stability.\n",
summary = "Small build system in between make and a build.sh"
}
package = "moonbuild"
rockspec_format = "3.0"
source = {
tag = "v2.1.2",
url = "git://github.com/natnat-mc/moonbuild"
}
version = "2.1.2-2"
+24
View File
@@ -0,0 +1,24 @@
build = {
install = {
bin = {
moonbuild = "out/moonbuild"
}
},
type = "builtin"
}
dependencies = {
"lua >= 5.1",
"argparse >= 0.7.1-1",
"moonscript >= 0.5.0-1"
}
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). If you can, installing luaposix and/or luafilesystem will speed up builds and increase stability.\n",
summary = "Small build system in between make and a build.sh"
}
package = "moonbuild"
rockspec_format = "3.0"
source = {
tag = "v2.1.3",
url = "git://github.com/natnat-mc/moonbuild"
}
version = "2.1.3-1"
+24
View File
@@ -0,0 +1,24 @@
build = {
install = {
bin = {
moonbuild = "out/moonbuild"
}
},
type = "builtin"
}
dependencies = {
"lua >= 5.1",
"argparse >= 0.7.1-1",
"moonscript >= 0.5.0-1"
}
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). If you can, installing luaposix and/or luafilesystem will speed up builds and increase stability.\n",
summary = "Small build system in between make and a build.sh"
}
package = "moonbuild"
rockspec_format = "3.0"
source = {
tag = "v2.1.3",
url = "git://github.com/natnat-mc/moonbuild"
}
version = "2.1.3-2"