From 472e2dc119ba3eca6a8672e7606df6a7dc847a19 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Mon, 28 Sep 2015 21:17:44 +0000 Subject: l3 (28sep15) git-svn-id: svn://tug.org/texlive/trunk@38490 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/tex/latex/l3build/l3build.lua | 267 +++++++++++++++--------- 1 file changed, 173 insertions(+), 94 deletions(-) (limited to 'Master/texmf-dist/tex/latex/l3build') diff --git a/Master/texmf-dist/tex/latex/l3build/l3build.lua b/Master/texmf-dist/tex/latex/l3build/l3build.lua index e8fffc16c43..489819a709c 100644 --- a/Master/texmf-dist/tex/latex/l3build/l3build.lua +++ b/Master/texmf-dist/tex/latex/l3build/l3build.lua @@ -17,8 +17,8 @@ --]] -- Version information: should be identical to that in l3build.dtx -release_date = "2015/09/14" -release_ver = "6007" +release_date = "2015/09/24" +release_ver = "6068" -- "module" is a deprecated function in Lua 5.2: as we want the name -- for other purposes, and it should eventually be 'free', simply @@ -35,14 +35,14 @@ bundle = bundle or "" if module == "" and bundle == "" then if string.match(arg[0], ".*l3build%.lua$") then print( - "\n" .. - "Error: Call l3build using a configuration file, not directly.\n" - ) + "\n" + .. "Error: Call l3build using a configuration file, not directly.\n" + ) else print( - "\n" .. - "Error: Specify either bundle or module in configuration script.\n" - ) + "\n" + .. "Error: Specify either bundle or module in configuration script.\n" + ) end os.exit(1) end @@ -170,19 +170,22 @@ function argparse() engine = "engine", ["halt-on-error"] = "halt" , ["halt-on-failure"] = "halt" , - help = "help" + help = "help" , + quiet = "quiet" } local short_options = { e = "engine", h = "help" , - H = "halt" + H = "halt" , + q = "quiet" } local option_args = { engine = true , halt = false, - help = false + help = false, + quiet = false } -- arg[1] is a special case: must be a command or "-h"/"--help" -- Deal with this by assuming help and storing only apparently-valid @@ -290,6 +293,7 @@ userargs = argparse() optengines = userargs["engine"] opthalt = userargs["halt"] opthelp = userargs["help"] +optquiet = userargs["quiet"] -- Convert a file glob into a pattern for use by e.g. string.gub -- Based on https://github.com/davidm/lua-glob-pattern @@ -405,23 +409,31 @@ lfs = require("lfs") -- For cleaning out a directory, which also ensures that it exists function cleandir(dir) - mkdir(dir) - rm(dir, "*") + local errorlevel = mkdir(dir) + if errorlevel ~= 0 then + return errorlevel + end + return rm(dir, "*") end -- Copy files 'quietly' function cp(glob, source, dest) + local errorlevel for _,i in ipairs(filelist(source, glob)) do local source = source .. "/" .. i if os_windows then - os.execute( - "copy /y " .. unix_to_win(source) .. " " - .. unix_to_win(dest) .. " > nul" - ) + errorlevel = os.execute( + "copy /y " .. unix_to_win(source) .. " " + .. unix_to_win(dest) .. " > nul" + ) else - os.execute("cp -f " .. source .. " " .. dest) + errorlevel = os.execute("cp -f " .. source .. " " .. dest) + end + if errorlevel ~=0 then + return errorlevel end end + return 0 end -- OS-dependent test for a directory @@ -479,9 +491,11 @@ function mkdir(dir) -- Windows (with the extensions) will automatically make directory trees -- but issues a warning if the dir already exists: avoid by including a test local dir = unix_to_win(dir) - os.execute("if not exist " .. dir .. "\\nul " .. "mkdir " .. dir) + return os.execute( + "if not exist " .. dir .. "\\nul " .. "mkdir " .. dir + ) else - os.execute("mkdir -p " .. dir) + return os.execute("mkdir -p " .. dir) end end @@ -512,9 +526,9 @@ end function ren(dir, source, dest) local dir = dir .. "/" if os_windows then - os.execute("ren " .. unix_to_win(dir) .. source .. " " .. dest) + return os.execute("ren " .. unix_to_win(dir) .. source .. " " .. dest) else - os.execute("mv " .. dir .. source .. " " .. dir .. dest) + return os.execute("mv " .. dir .. source .. " " .. dir .. dest) end end @@ -523,6 +537,8 @@ function rm(source, glob) for _,i in ipairs(filelist(source, glob)) do os.remove(source .. "/" .. i) end + -- os.remove doesn't give a sensible errorlevel + return 0 end -- Remove a directory tree @@ -530,9 +546,9 @@ function rmdir(dir) -- First, make sure it exists to avoid any errors mkdir(dir) if os_windows then - os.execute("rmdir /s /q " .. unix_to_win(dir) ) + return os.execute("rmdir /s /q " .. unix_to_win(dir) ) else - os.execute("rm -r " .. dir) + return os.execute("rm -r " .. dir) end end @@ -553,18 +569,19 @@ end -- Do some subtarget for all modules in a bundle function allmodules(target) - local errorlevel for _,i in ipairs(modules) do print( - "Running script " .. scriptname .. " with target \"" .. target .. "\" for module " - .. i - ) + "Running script " .. scriptname .. " with target \"" .. target + .. "\" for module " + .. i + ) local engines = "" if optengines then engines = " --engine=" .. table.concat(optengines, ",") end - errorlevel = run( - i, "texlua " .. scriptname .. " " .. target + local errorlevel = run( + i, + "texlua " .. scriptname .. " " .. target .. (opthalt and " -H" or "") .. engines ) @@ -672,10 +689,15 @@ end -- Unpack files needed to support testing/typesetting/unpacking function depinstall(deps) + local errorlevel for _,i in ipairs(deps) do print("Installing dependency: " .. i) - run(i, "texlua " .. scriptname .. " unpack") + errorlevel = run(i, "texlua " .. scriptname .. " unpack -q") + if errorlevel ~= 0 then + return errorlevel + end end + return 0 end -- Convert the raw log file into one for comparison/storage: keeps only @@ -690,8 +712,8 @@ function formatlog(logfile, newfile, engine) -- As Lua doesn't allow "(in|out)", a slightly complex approach: -- do a substitution to check the line is exactly what is required! string.match( - string.gsub(line, "^\\openin", "\\openout"), "^\\openout%d%d? = " - ) then + string.gsub(line, "^\\openin", "\\openout"), "^\\openout%d%d? = " + ) then return true end return false @@ -722,7 +744,7 @@ function formatlog(logfile, newfile, engine) line = string.gsub(line, "%(%.%/", "(") -- Zap paths if places other than 'here' are accessible if checksearch then - line = string.gsub(line, "%(.*/([%w-]+%.[%w-]+)%s*$", "(../%1") + line = string.gsub(line, "%(.*/([%w-]+%.[%w-]+)%)?%s*$", "(../%1") end -- Zap map loading of map line = string.gsub(line, "%{%w?:?[%w/%-]*/pdftex%.map%}", "") @@ -733,12 +755,15 @@ function formatlog(logfile, newfile, engine) end -- TeX90/XeTeX knows only the smaller set of dimension units line = string.gsub( - line, "cm, mm, dd, cc, bp, or sp", "cm, mm, dd, cc, nd, nc, bp, or sp" - ) + line, + "cm, mm, dd, cc, bp, or sp", "cm, mm, dd, cc, nd, nc, bp, or sp" + ) -- Normalise a case where fixing a TeX bug changes the message text line = string.gsub(line, "\\csname\\endcsname ", "\\csname\\endcsname") -- Zap "on line " and replace with "on line ..." + -- Two similar cases, Lua patterns mean we need to do them separately line = string.gsub(line, "on line %d*", "on line ...") + line = string.gsub(line, "on input line %d*", "on input line ...") -- Tidy up to ^^ notation for i = 0, 31 do line = string.gsub(line, string.char(i), "^^" .. string.char(64 + i)) @@ -747,8 +772,10 @@ function formatlog(logfile, newfile, engine) -- Two stages as line wrapping alters some of them and restore the break line = string.gsub(line, "^l%.%d+ ", "l. ...") line = string.gsub( - line, "%.%.%.l%.%d+ ( *)%}$", "..." .. os_newline .. "l. ...%1}" - ) + line, + "%.%.%.l%.%d+ ( *)%}$", + "..." .. os_newline .. "l. ...%1}" + ) -- Remove spaces at the start of lines: deals with the fact that LuaTeX -- uses a different number to the other engines line = string.gsub(line, "^%s+", "") @@ -825,9 +852,9 @@ function formatlualog(logfile, newfile) m .. " (%-?)%d+%.%d+", m .. " %1" .. string.format( - "%.3f", - string.match(line, m .. " %-?(%d+%.%d+)") or 0 - ) + "%.3f", + string.match(line, m .. " %-?(%d+%.%d+)") or 0 + ) ) end if string.match(line, "glue set %-?%d+%.%d+") then @@ -841,7 +868,7 @@ function formatlualog(logfile, newfile) line = round_digits(line, "plus") line = round_digits(line, "minus") end - -- LuaTeX writes ^^M as a new line, which we loose + -- LuaTeX writes ^^M as a new line, which we lose line = string.gsub(line, "%^%^M", "") -- Remove U+ notation in the "Missing character" message line = string.gsub( @@ -917,7 +944,7 @@ function formatlualog(logfile, newfile) elseif (string.len(lastline) == maxprintline) then if string.match(line, "\\ETC%.%}$") then -- If the line wrapped at \ETC we might have lost a space - return lastline + return lastline .. ((string.match(line, "^\\ETC%.%}$") and " ") or "") .. line, "" elseif string.match(line, "^%}%}%}$") then @@ -998,7 +1025,7 @@ function runcheck(name, hide) if not locate({unpackdir, testfiledir}, {name .. lveext}) then print( "Error: failed to find " .. tlgext .. " or " - .. lveext .. " file for " .. name .. "!" + .. lveext .. " file for " .. name .. "!" ) os.exit(1) end @@ -1072,6 +1099,11 @@ function runtest(name, engine, hide, ext) string.match(engine, "^u?ptex$") then realengine = "e" .. engine end + -- Special casing for XeTeX engine + local checkopts = checkopts + if string.match(engine, "xetex") then + checkopts = checkopts .. " -no-pdf" + end local logfile = testdir .. "/" .. name .. logext local newfile = testdir .. "/" .. name .. "." .. engine .. logext local asciiopt = "" @@ -1083,18 +1115,18 @@ function runtest(name, engine, hide, ext) end for i = 1, checkruns do run( - testdir, - -- No use of localdir here as the files get copied to testdir: - -- avoids any paths in the logs - os_setenv .. " TEXINPUTS=." .. (checksearch and os_pathsep or "") - .. os_concat .. - -- Avoid spurious output from (u)pTeX - os_setenv .. " GUESS_INPUT_KANJI_ENCODING=0" - .. os_concat .. - realengine .. format .. " " - .. checkopts .. " " .. asciiopt .. lvtfile - .. (hide and (" > " .. os_null) or "") - ) + testdir, + -- No use of localdir here as the files get copied to testdir: + -- avoids any paths in the logs + os_setenv .. " TEXINPUTS=." .. (checksearch and os_pathsep or "") + .. os_concat .. + -- Avoid spurious output from (u)pTeX + os_setenv .. " GUESS_INPUT_KANJI_ENCODING=0" + .. os_concat .. + realengine .. format .. " " + .. checkopts .. " " .. asciiopt .. lvtfile + .. (hide and (" > " .. os_null) or "") + ) end formatlog(logfile, newfile, engine) -- Store secondary files for this engine @@ -1337,24 +1369,29 @@ function clean() -- To make sure that distribdir never contains any stray subdirs, -- it is entirely removed then recreated rather than simply deleting -- all of the files - rmdir(distribdir) - mkdir(distribdir) - cleandir(localdir) - cleandir(testdir) - cleandir(typesetdir) - cleandir(unpackdir) + local errorlevel = + rmdir(distribdir) + + mkdir(distribdir) + + cleandir(localdir) + + cleandir(testdir) + + cleandir(typesetdir) + + cleandir(unpackdir) for _,i in ipairs(cleanfiles) do - rm(".", i) + errorlevel = rm(".", i) + errorlevel end + return errorlevel end function bundleclean() - allmodules("clean") + local errorlevel = allmodules("clean") for _,i in ipairs(cleanfiles) do - rm(".", i) + errorlevel = rm(".", i) + errorlevel end - rmdir(ctandir) - rmdir(tdsdir) + return ( + errorlevel + + rmdir(ctandir) + + rmdir(tdsdir) + ) end -- Check commands are defined @@ -1404,19 +1441,19 @@ function ctan(standalone) local exclude = tab_to_str(excludefiles) -- First, zip up all of the text files run( - dir, - zipexe .. " " .. zipopts .. " -ll ".. zipname .. " " .. "." - .. ( - (binfiles or exclude) and (" -x" .. binfiles .. " " .. exclude) - or "" - ) - ) + dir, + zipexe .. " " .. zipopts .. " -ll ".. zipname .. " " .. "." + .. ( + (binfiles or exclude) and (" -x" .. binfiles .. " " .. exclude) + or "" + ) + ) -- Then add the binary ones run( - dir, - zipexe .. " " .. zipopts .. " -g ".. zipname .. " " .. ". -i" .. - binfiles .. (exclude and (" -x" .. exclude) or "") - ) + dir, + zipexe .. " " .. zipopts .. " -g ".. zipname .. " " .. ". -i" .. + binfiles .. (exclude and (" -x" .. exclude) or "") + ) end local errorlevel if standalone then @@ -1543,14 +1580,24 @@ end -- Locally install files: only deals with those extracted, not docs etc. function install() - unpack() + local errorlevel = unpack() + if errorlevel ~= 0 then + return errorlevel + end kpse.set_program_name("latex") local texmfhome = kpse.var_value("TEXMFHOME") local installdir = texmfhome .. "/tex/" .. moduledir - cleandir(installdir) + errorlevel = cleandir(installdir) + if errorlevel ~= 0 then + return errorlevel + end for _,i in ipairs(installfiles) do - cp(i, unpackdir, installdir) + errorlevel = cp(i, unpackdir, installdir) + if errorlevel ~= 0 then + return errorlevel + end end + return 0 end function save(names) @@ -1583,7 +1630,7 @@ function save(names) print( "Test input \"" .. testfiledir .. "/" .. name .. lvtext .. "\" not found" - ) + ) end end end @@ -1592,25 +1639,47 @@ end -- Unpack the package files using an 'isolated' system: this requires -- a copy of the 'basic' DocStrip program, which is used then removed function unpack() - depinstall(unpackdeps) - bundleunpack() + local errorlevel = depinstall(unpackdeps) + if errorlevel ~= 0 then + return errorlevel + end + errorlevel = bundleunpack() + if errorlevel ~= 0 then + return errorlevel + end for _,i in ipairs(installfiles) do - cp(i, unpackdir, localdir) + errorlevel = cp(i, unpackdir, localdir) + if errorlevel ~= 0 then + return errorlevel + end end + return 0 end -- Split off from the main unpack so it can be used on a bundle and not -- leave only one modules files bundleunpack = bundleunpack or function(sourcedir) - mkdir(localdir) - cleandir(unpackdir) + local errorlevel = mkdir(localdir) + if errorlevel ~=0 then + return errorlevel + end + errorlevel = cleandir(unpackdir) + if errorlevel ~=0 then + return errorlevel + end for _,i in ipairs(sourcedir or {"."}) do for _,j in ipairs(sourcefiles) do - cp(j, i, unpackdir) + errorlevel = cp(j, i, unpackdir) + if errorlevel ~=0 then + return errorlevel + end end end for _,i in ipairs(unpacksuppfiles) do - cp(i, supportdir, localdir) + errorlevel = cp(i, supportdir, localdir) + if errorlevel ~=0 then + return errorlevel + end end for _,i in ipairs(unpackfiles) do for _,j in ipairs(filelist(unpackdir, i)) do @@ -1621,22 +1690,28 @@ bundleunpack = bundleunpack or function(sourcedir) -- stops, which confuses Lua) os.execute(os_yes .. ">>" .. localdir .. "/yes") local localdir = relpath(localdir, unpackdir) - run( + errorlevel = run( unpackdir, os_setenv .. " TEXINPUTS=." .. os_pathsep .. localdir .. (unpacksearch and os_pathsep or "") .. os_concat .. unpackexe .. " " .. unpackopts .. " " .. j .. " < " .. localdir .. "/yes" + .. (optquiet and (" > " .. os_null) or "") ) + if errorlevel ~=0 then + return errorlevel + end end end + return 0 end function version() print( - "\nl3build Release " .. string.gsub(release_date, "/", "-") .. - " (SVN r" .. release_ver .. ")\n" + "\n" + .. "l3build Release " .. string.gsub(release_date, "/", "-") + .. " (SVN r" .. release_ver .. ")\n" ) end @@ -1700,14 +1775,18 @@ function stdmain(target, files) help() end elseif target == "unpack" then - unpack() + errorlevel = unpack() elseif target == "version" then version() else help() end end - os.exit(errorlevel) + if errorlevel ~= 0 then + os.exit(1) + else + os.exit(0) + end end -- Allow main function to be disabled 'higher up' -- cgit v1.2.3