From 0113de45464fb9dc8a16ad17588e01cdcd099499 Mon Sep 17 00:00:00 2001 From: Nathan DECHER Date: Sun, 10 May 2020 20:11:32 +0200 Subject: [PATCH] added glob targets, closes #3 --- Build.moon | 10 +++---- README.md | 4 +++ moonbuild.moon | 72 +++++++++++++++++++++++++++++++++++++------------- util.moon | 26 ++++++++++++++---- 4 files changed, 81 insertions(+), 31 deletions(-) diff --git a/Build.moon b/Build.moon index c278169..87a52df 100644 --- a/Build.moon +++ b/Build.moon @@ -8,8 +8,6 @@ OUT_C = patsubst MAIN, '%.moon', '%.lua.c' PREFIX = env 'PREFIX', '/usr/local' INSTALL_LOC = "#{PREFIX}/bin" -default public target 'all', deps: BINARY - public target 'install', from: BINARY, out: INSTALL_LOC, fn: => -install @infile, @outfile @@ -25,10 +23,8 @@ public target 'info', fn: => #echo "Compiled lua:", OUT_LUA #echo "Binary:", BINARY -target BINARY, out: {BINARY, OUT_C}, from: OUT_LUA, fn: => +default target BINARY, out: {BINARY, OUT_C}, from: OUT_LUA, fn: => -luastatic MAIN_LUA, OUT_LUA, '-I/usr/include/lua5.3', '-llua5.3' -foreach OUT_LUA, (file) -> - source=patsubst file, '%.lua', '%.moon' - target file, in: source, out: file, fn: => - -moonc @infile +target '%.lua', in: '%.moon', out: '%.lua', fn: => + -moonc @infile diff --git a/README.md b/README.md index f3a8e55..6cbd253 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,10 @@ Define a new target, and give it a list of depenancies, inputs, outputs and a fu - `outs`: the table of outputs - `outfile`: the first output +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. + ### `wildcard ` 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 `*`. diff --git a/moonbuild.moon b/moonbuild.moon index 0bb6719..6cd0452 100755 --- a/moonbuild.moon +++ b/moonbuild.moon @@ -8,7 +8,7 @@ import truncate_traceback, rewrite_traceback from require 'moonscript.errors' import trim from require 'moonscript.util' util=require 'util' -import exists, mtime, run, min, max, first, flatten from util +import exists, mtime, run, min, max, first, flatten, match, patsubst from util import insert, concat from table @@ -47,42 +47,76 @@ class Command -- represents a target class BuildObject all={} + skip={} + cycle={} + + @find: (name) => + target=all[name] + return target if target + for glob, tgt in pairs all + return tgt if match name, glob + nil + @build: (name) => - target=all[name] or error "No such target: #{name}" - target\build! + target=@find name or error "No such target: #{name}" + target\build name + + __tostring: => + "Target #{@name} (#{concat @deps, ', '})" new: (@name, @outs={}, @ins={}, @deps={}, @fn= =>) => @skip=false error "Duplicate build name #{@name}" if all[@name] all[@name]=@ - build: => - return if @skip - error "Can't build #{@name}: cyclic dependancy" if @cycle - @cycle=true - for depname in *@deps - dep=all[depname] or error "Can't build #{@name}: missing dependancy #{depname}" - dep\build! - return unless @shouldbuild! - - print "Building #{@name}" + build: (name) => + return if skip[name] + error "Can't build #{name}: cyclic depenancies found" if cycle[name] + cycle[name]=true + if @name!=name + @@build patsubst name, @name, dep for dep in *@deps + else + @@build dep 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 + @.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 + for f in *outs error "Can't build #{@name}: output file #{f} not created" unless exists f - @skip=true + skip[name]=true - shouldbuild: => + shouldbuild: (name) => return true if args.noskip return true if #@ins==0 or #@outs==0 - itimes=[mtime f for f in *@ins] + 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] - otimes=[mtime f for f in *@outs] + 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] diff --git a/util.moon b/util.moon index 171fee0..f2445b5 100644 --- a/util.moon +++ b/util.moon @@ -3,6 +3,8 @@ import attributes, dir from require 'lfs' import insert, concat from table unpack or=table.unpack +GLOB_PATT='^([^%%]*)%%([^%%]*)$' + -- min and max of table max= (t) -> m=t[1] @@ -109,15 +111,29 @@ wildcard= (pattern) -> -- string pattern patsubst= (str, pattern, replacement) -> return [patsubst s, pattern, replacement for s in *str] if (type str)=='table' - prefix, suffix=pattern\match '^(.*)%%(.*)$' - error "Invalid pattern #{pattern}" unless prefix - reprefix, resuffix=replacement\match '^(.*)%%(.*)$' - error "Invalid replacement pattern #{pattern}" unless reprefix + prefix, suffix=pattern\match GLOB_PATT + return str unless prefix + reprefix, resuffix=replacement\match GLOB_PATT + return replacement unless reprefix if (str\sub 1, #prefix)==prefix and (str\sub -#suffix)==suffix return reprefix..(str\sub #prefix+1, -#suffix-1)..resuffix str +-- 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 + env= (key, def) -> (os.getenv key) or def @@ -138,6 +154,6 @@ env= (key, def) -> :run, :popen -- string functions - :patsubst + :patsubst, :match, :isglob :env }