diff --git a/moonbuild/core/DAG.moon b/moonbuild/core/DAG.moon index 1629c86..e3e4bb8 100644 --- a/moonbuild/core/DAG.moon +++ b/moonbuild/core/DAG.moon @@ -56,22 +56,44 @@ class DepGraph addnode: (name) => return if @nodes[name] - elected = @resolvedeps name + elected = @topresolvedeps name @nodes[name] = elected for dep in *(transclosure elected, 'deps') @nodes[dep.name] = dep dep.deps = nil elected.deps = nil - resolvedeps: (name) => + topresolvedeps: (name) => + errors = {} + ok, rst = pcall -> @resolvedeps name, nil, errors + if ok + rst + else + msg = {"Failed to resolve target \'#{name}\'\n"} + for e in *errors + if e.err\match '^moonbuild' + e.err = e.err\match ': (.+)$' + for i=#errors, 1, -1 + e = errors[i] + insert msg, "#{string.rep '| ', e.level - 1}+-[#{e.name}] level #{e.level}: #{e.err}" + insert msg, '' + error table.concat msg, '\n' + + resolvedeps: (name, level=1, errors={}) => do node = @nodes[name] - return node, {} if node + if node + print "deps(#{name}) = #{node.name or '[noname]'}" + return node, {} candidates = filter {@ctx.targets, FileTarget!}, (target) -> target\matches name - nodes = foreach candidates, (candidate) -> a: {pcall -> DepNode @, candidate, name} + nodes = foreach candidates, (candidate) -> a: {pcall -> DepNode @, candidate, name, level, errors} 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" + unless resolved[1] + err = "Cannot resolve target #{name}: #{#candidates} candidates, #{#resolved} resolved" + table.insert errors, {:name, :level, :err} + error err + resolved[1] buildablenodes: => [v for k, v in pairs @nodes when v\canbuild! and not v.built] @@ -91,7 +113,7 @@ class DepGraph insert stack, n for n in *(node\children!) class DepNode - new: (@dag, target, @name) => + new: (@dag, target, @name, @level, errors) => @priority = target.priority @buildfunctions = target.buildfunctions @mkdirs = target._mkdirs @@ -101,7 +123,7 @@ class DepNode @type = 'virtual' if #@outs == 0 @built = false - resolve = (name) -> @dag\resolvedeps patsubst @name, target.pattern, name + resolve = (name) -> @dag\resolvedeps (patsubst @name, target.pattern, name), level + 1, errors after = flatten foreach target.needtargets, resolve deps = flatten foreach target.infiles, resolve if #target.depfunctions!=0 @@ -149,7 +171,7 @@ class DepNode return false if @built or #@buildfunctions == 0 return false unless force or @shouldbuild! - print "#{@type == 'virtual' and "Running" or "Building"} #{@name}" unless quiet + print "#{@type == 'virtual' and "Running" or "Building"} #{@name} [level #{@level}]" unless quiet @actuallybuild! true diff --git a/out/moonbuild.lua b/out/moonbuild.lua index e9bd49f..920dbd9 100644 --- a/out/moonbuild.lua +++ b/out/moonbuild.lua @@ -1,5 +1,3 @@ -do - do local _ENV = _ENV package.preload[ "moonbuild._" ] = function( ... ) local arg = _G.arg; @@ -1750,7 +1748,7 @@ do if self.nodes[name] then return end - local elected = self:resolvedeps(name) + local elected = self:topresolvedeps(name) self.nodes[name] = elected local _list_0 = (transclosure(elected, 'deps')) for _index_0 = 1, #_list_0 do @@ -1760,10 +1758,42 @@ do end elected.deps = nil end, - resolvedeps = function(self, name) + topresolvedeps = function(self, name) + local errors = { } + local ok, rst = pcall(function() + return self:resolvedeps(name, nil, errors) + end) + if ok then + return rst + else + local msg = { + "Failed to resolve target \'" .. tostring(name) .. "\'\n" + } + for _index_0 = 1, #errors do + local e = errors[_index_0] + if e.err:match('^moonbuild') then + e.err = e.err:match(': (.+)$') + end + end + for i = #errors, 1, -1 do + local e = errors[i] + insert(msg, tostring(string.rep('| ', e.level - 1)) .. "+-[" .. tostring(e.name) .. "] level " .. tostring(e.level) .. ": " .. tostring(e.err)) + end + insert(msg, '') + return error(table.concat(msg, '\n')) + end + end, + resolvedeps = function(self, name, level, errors) + if level == nil then + level = 1 + end + if errors == nil then + errors = { } + end do local node = self.nodes[name] if node then + print("deps(" .. tostring(name) .. ") = " .. tostring(node.name or '[noname]')) return node, { } end end @@ -1777,7 +1807,7 @@ do return { a = { pcall(function() - return DepNode(self, candidate, name) + return DepNode(self, candidate, name, level, errors) end) } } @@ -1788,7 +1818,16 @@ do return node.a[2] end) sort(resolved, nodepriority) - return resolved[1] or error("Cannot resolve target " .. tostring(name) .. ": " .. tostring(#candidates) .. " candidates, " .. tostring(#resolved) .. " resolved") + if not (resolved[1]) then + local err = "Cannot resolve target " .. tostring(name) .. ": " .. tostring(#candidates) .. " candidates, " .. tostring(#resolved) .. " resolved" + table.insert(errors, { + name = name, + level = level, + err = err + }) + error(err) + end + return resolved[1] end, buildablenodes = function(self) local _accum_0 = { } @@ -1917,7 +1956,7 @@ do return false end if not (quiet) then - print(tostring(self.type == 'virtual' and "Running" or "Building") .. " " .. tostring(self.name)) + print(tostring(self.type == 'virtual' and "Running" or "Building") .. " " .. tostring(self.name) .. " [level " .. tostring(self.level) .. "]") end self:actuallybuild() return true @@ -1999,8 +2038,8 @@ do } _base_0.__index = _base_0 _class_0 = setmetatable({ - __init = function(self, dag, target, name) - self.dag, self.name = dag, name + __init = function(self, dag, target, name, level, errors) + self.dag, self.name, self.level = dag, name, level self.priority = target.priority self.buildfunctions = target.buildfunctions self.mkdirs = target._mkdirs @@ -2015,7 +2054,7 @@ do self.built = false local resolve resolve = function(name) - return self.dag:resolvedeps(patsubst(self.name, target.pattern, name)) + return self.dag:resolvedeps((patsubst(self.name, target.pattern, name)), level + 1, errors) end local after = flatten(foreach(target.needtargets, resolve)) local deps = flatten(foreach(target.infiles, resolve)) @@ -2750,8 +2789,6 @@ end end end -end - local loadfile loadfile = require('moonscript.base').loadfile local Context = require('moonbuild.context')