diff options
author | Hans Hagen <pragma@wxs.nl> | 2009-05-28 11:23:00 +0200 |
---|---|---|
committer | Hans Hagen <pragma@wxs.nl> | 2009-05-28 11:23:00 +0200 |
commit | 1d3090326210c6e6f7ec5432799ded25b75bba46 (patch) | |
tree | c5921203789ec669e6bccaba4bd56f9c072dc56b /scripts/context/lua/mtx-update.lua | |
parent | 94d83f84758766511c5e324721e39fea6ab71dae (diff) | |
download | context-1d3090326210c6e6f7ec5432799ded25b75bba46.tar.gz |
beta 2009.05.28 11:23
Diffstat (limited to 'scripts/context/lua/mtx-update.lua')
-rw-r--r-- | scripts/context/lua/mtx-update.lua | 419 |
1 files changed, 278 insertions, 141 deletions
diff --git a/scripts/context/lua/mtx-update.lua b/scripts/context/lua/mtx-update.lua index b56780c68..66f6898d3 100644 --- a/scripts/context/lua/mtx-update.lua +++ b/scripts/context/lua/mtx-update.lua @@ -1,5 +1,5 @@ if not modules then modules = { } end modules ['mtx-update'] = { - version = 1.001, + version = 1.002, comment = "companion to mtxrun.lua", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", copyright = "PRAGMA ADE / ConTeXt Development Team", @@ -11,15 +11,20 @@ if not modules then modules = { } end modules ['mtx-update'] = { -- Together with Arthur Reutenauer she made sure that it worked well on all -- platforms that matter. +local format, concat, gmatch = string.format, table.concat, string.gmatch + scripts = scripts or { } scripts.update = scripts.update or { } minimals = minimals or { } minimals.config = minimals.config or { } +-- this is needed under windows +-- else rsync fails to set the right chmod flags to files + os.setenv("CYGWIN","nontsec") -scripts.update.allformats = { +scripts.update.texformats = { "cont-en", "cont-nl", "cont-cz", @@ -28,125 +33,105 @@ scripts.update.allformats = { "cont-it", "cont-ro", "cont-uk", - "metafun", + "cont-pe", + "cont-xp", "mptopdf", "plain" } -scripts.update.fewformats = { - "cont-en", - "cont-nl", +scripts.update.mpformats = { "metafun", - "mptopdf", - "plain" + "mpost", } +-- experimental is not functional at the moment + scripts.update.repositories = { "current", "experimental" } +-- more options than just these two are available (no idea why this is here) + scripts.update.versions = { "current", "latest" } +-- list of basic folders that are needed to make a functional distribution + +scripts.update.base = { + { "base/tex/", "texmf" }, + { "base/metapost/", "texmf" }, + { "fonts/common/", "texmf" }, + { "fonts/other/", "texmf" }, -- not *really* needed, but helpful + { "context/<version>/", "texmf-context" }, + { "context/img/", "texmf-context" }, + { "misc/setuptex/", "." }, + { "misc/web2c", "texmf" }, + { "bin/common/<platform>/", "texmf-<platform>" }, + { "bin/context/<platform>/", "texmf-<platform>" }, + { "bin/metapost/<platform>/", "texmf-<platform>" }, + { "bin/man/", "texmf-<platform>" }, +} + +-- binaries and font-related files +-- for pdftex we don't need OpenType fonts, for LuaTeX/XeTeX we don't need TFM files + scripts.update.engines = { ["luatex"] = { - { "base/tex/", "texmf" }, - { "base/metapost/", "texmf" }, { "fonts/new/", "texmf" }, - { "fonts/common/", "texmf" }, - { "fonts/other/", "texmf" }, - { "context/<version>/", "texmf-context" }, - { "context/img/", "texmf-context" }, - { "context/config/", "texmf-context" }, - { "misc/setuptex/", "." }, - { "misc/web2c", "texmf" }, - { "bin/common/<platform>/", "texmf-<platform>" }, - { "bin/context/<platform>/", "texmf-<platform>" }, - { "bin/metapost/<platform>/", "texmf-<platform>" }, { "bin/luatex/<platform>/", "texmf-<platform>" }, - { "bin/man/", "texmf-<platform>" } }, ["xetex"] = { - { "base/tex/", "texmf" }, - { "base/metapost/", "texmf" }, { "base/xetex/", "texmf" }, { "fonts/new/", "texmf" }, - { "fonts/common/", "texmf" }, - { "fonts/other/", "texmf" }, - { "context/<version>/", "texmf-context" }, - { "context/img/", "texmf-context" }, - { "context/config/", "texmf-context" }, - { "misc/setuptex/", "." }, - { "misc/web2c", "texmf" }, - { "bin/common/<platform>/", "texmf-<platform>" }, - { "bin/context/<platform>/", "texmf-<platform>" }, - { "bin/metapost/<platform>/", "texmf-<platform>" }, { "bin/xetex/<platform>/", "texmf-<platform>" }, - { "bin/man/", "texmf-<platform>" } }, ["pdftex"] = { - { "base/tex/", "texmf" }, - { "base/metapost/", "texmf" }, { "fonts/old/", "texmf" }, - { "fonts/common/", "texmf" }, - { "fonts/other/", "texmf" }, - { "context/<version>/", "texmf-context" }, - { "context/img/", "texmf-context" }, - { "context/config/", "texmf-context" }, - { "misc/setuptex/", "." }, - { "misc/web2c", "texmf" }, - { "bin/common/<platform>/", "texmf-<platform>" }, - { "bin/context/<platform>/", "texmf-<platform>" }, - { "bin/metapost/<platform>/", "texmf-<platform>" }, { "bin/pdftex/<platform>/", "texmf-<platform>" }, - { "bin/man/", "texmf-<platform>" } }, ["all"] = { - { "base/tex/", "texmf" }, - { "base/metapost/", "texmf" }, - { "base/xetex/", "texmf" }, - { "fonts/old/", "texmf" }, { "fonts/new/", "texmf" }, - { "fonts/common/", "texmf" }, - { "fonts/other/", "texmf" }, - { "context/<version>/", "texmf-context" }, - { "context/img/", "texmf-context" }, - { "context/config/", "texmf-context" }, - { "misc/setuptex/", "." }, - { "misc/web2c", "texmf" }, - { "bin/common/<platform>/", "texmf-<platform>" }, - { "bin/context/<platform>/", "texmf-<platform>" }, - { "bin/metapost/<platform>/", "texmf-<platform>" }, + { "fonts/old/", "texmf" }, + { "base/xetex/", "texmf" }, { "bin/luatex/<platform>/", "texmf-<platform>" }, { "bin/xetex/<platform>/", "texmf-<platform>" }, { "bin/pdftex/<platform>/", "texmf-<platform>" }, - { "bin/man/", "texmf-<platform>" } }, } scripts.update.platforms = { - ["mswin"] = "mswin", - ["windows"] = "mswin", - ["win32"] = "mswin", - ["win"] = "mswin", - ["linux"] = "linux", - ["freebsd"] = "freebsd", - ["linux-32"] = "linux", - ["linux-64"] = "linux-64", - ["linux32"] = "linux", - ["linux64"] = "linux-64", - ["linux-ppc"] = "linux-ppc", - ["ppc"] = "linux-ppc", - ["osx"] = "osx-intel", - ["osx-intel"] = "osx-intel", - ["osx-ppc"] = "osx-ppc", - ["osx-powerpc"] = "osx-ppc", - ["osxintel"] = "osx-intel", - ["osxppc"] = "osx-ppc", - ["osxpowerpc"] = "osx-ppc", + ["mswin"] = "mswin", + ["windows"] = "mswin", + ["win32"] = "mswin", + ["win"] = "mswin", + ["linux"] = "linux", + ["freebsd"] = "freebsd", + ["freebsd-amd64"] = "freebsd-amd64", + ["linux-32"] = "linux", + ["linux-64"] = "linux-64", + ["linux32"] = "linux", + ["linux64"] = "linux-64", + ["linux-ppc"] = "linux-ppc", + ["ppc"] = "linux-ppc", + ["osx"] = "osx-intel", + ["macosx"] = "osx-intel", + ["osx-intel"] = "osx-intel", + ["osx-ppc"] = "osx-ppc", + ["osx-powerpc"] = "osx-ppc", + ["osxintel"] = "osx-intel", + ["osxppc"] = "osx-ppc", + ["osxpowerpc"] = "osx-ppc", + ["solaris-intel"] = "solaris-intel", + ["solaris-sparc"] = "solaris-sparc", + ["solaris"] = "solaris-sparc", +} + +-- the list is filled up later (when we know what modules to download) + +scripts.update.modules = { } function scripts.update.run(str) @@ -160,7 +145,7 @@ function scripts.update.run(str) end function scripts.update.fullpath(path) - if input.aux.rootbased_path(path) then + if file.is_rootbased_path(path) then return path else return lfs.currentdir() .. "/" .. path @@ -168,47 +153,138 @@ function scripts.update.fullpath(path) end function scripts.update.synchronize() + logs.report("update","start") + local texroot = scripts.update.fullpath(states.get("paths.root")) - local engines = states.get('engines') - local platforms = states.get('platforms') - local repositories = states.get('repositories') - local bin = states.get("rsync.program") - local url = states.get("rsync.server") - local version = states.get("context.version") + local engines = states.get('engines') or { } + local platforms = states.get('platforms') or { } + local repositories = states.get('repositories') -- minimals + local bin = states.get("rsync.program") -- rsync + local url = states.get("rsync.server") -- contextgarden.net + local version = states.get("context.version") -- current (or beta) + local extras = states.get("extras") -- extra goodies (like modules) local force = environment.argument("force") + + bin = string.gsub(bin,"\\","/") + if not url:find("::$") then url = url .. "::" end local ok = lfs.attributes(texroot,"mode") == "directory" if not ok and force then dir.mkdirs(texroot) ok = lfs.attributes(texroot,"mode") == "directory" end + + if force then + dir.mkdirs(format("%s/%s", texroot, "texmf-cache")) + dir.mkdirs(format("%s/%s", texroot, "texmf-local")) + end + if ok or not force then - if force then - dir.mkdirs(string.format("%s/%s", texroot, "texmf-cache")) + + local fetched, individual, osplatform = { }, { }, os.currentplatform() + + -- takes a collection as argument and returns a list of folders + + local function collection_to_list_of_folders(collection, platform) + local archives = {} + for _, c in ipairs(collection) do + local archive = c[1] + archive = archive:gsub("<platform>", platform) + archive = archive:gsub("<version>", version) + archives[#archives+1] = archive + end + return archives end - local fetched, individual = { }, { } - for engine, _ in pairs(engines) do - local collections = scripts.update.engines[engine] - if collections then - for _, collection in ipairs(collections) do - for platform, _ in pairs(platforms) do - platform = scripts.update.platforms[platform] - if platform then - local archive = collection[1]:gsub("<platform>", platform) - local destination = string.format("%s/%s", texroot, collection[2]:gsub("<platform>", platform)) - destination = destination:gsub("\\","/") - archive = archive:gsub("<version>",version) ---~ if platform == "windows" or platform == "mswin" then - if os.currentplatform() == "windows" or os.currentplatform() == "mswin" then - destination = destination:gsub("([a-zA-Z]):/", "/cygdrive/%1/") - end - individual[#individual+1] = { archive, destination } + + -- takes a list of folders as argument and returns a string for rsync + -- sample input: + -- {'bin/common', 'bin/context'} + -- output: + -- 'minimals/current/bin/common minimals/current/bin/context' + + local function list_of_folders_to_rsync_string(list_of_folders) + local repository = 'current' + local prefix = format("%s/%s/", states.get('rsync.module'), repository) -- minimals/current/ + + return prefix .. concat(list_of_folders, format(" %s", prefix)) + end + + -- example of usage: print(list_of_folders_to_rsync_string(collection_to_list_of_folders(scripts.update.base, os.currentplatform))) + + -- rename function and add some more functionality: + -- * recursive/non-recursive (default: non-recursive) + -- * filter folders or regular files only (default: no filter) + -- * grep for size of included files (with --stats switch) + + local function get_list_of_files_from_rsync(list_of_folders) + -- temporary file to store the output of rsync (could be a more random name; watch for overwrites) + local temp_file = "rsync.tmp.txt" + -- a set of folders + local folders = {} + local command = format("%s %s'%s' > %s", bin, url, list_of_folders_to_rsync_string(list_of_folders), temp_file) + os.execute(command) + -- read output of rsync + local data = io.loaddata(temp_file) or "" + -- for every line extract the filename + for chmod, s in data:gmatch("([d%-][rwx%-]+).-(%S+)[\n\r]") do + -- skip "current" folder + if s ~= '.' and chmod:len() == 10 then + folders[#folders+1] = s + end + end + -- delete the file to which we have put output of rsync + os.remove(temp_file) + return folders + end + + -- rsync://contextgarden.net/minimals/current/modules/ + + if extras and type(extras) == "table" then + -- fetch the list of available modules from rsync server + local available_modules = get_list_of_files_from_rsync({"modules/"}) + -- hash of requested modules + -- local h = table.tohash(extras:split(",")) + for _, s in ipairs(available_modules) do + -- if extras == "all" or h[s] then + if extras.all or extras[s] then + scripts.update.modules[#scripts.update.modules+1] = { format("modules/%s/",s), "texmf-context" } + end + end + -- TODO: check if every module from the list has been added and issue warning otherwise + -- one idea to do it: remove every value from h once added and then check if anything is left in h + end + + local function add_collection(collection,platform) + if collection and platform then + platform = scripts.update.platforms[platform] + if platform then + for _, c in ipairs(collection) do + local archive = c[1]:gsub("<platform>", platform) + local destination = format("%s/%s", texroot, c[2]:gsub("<platform>", platform)) + destination = destination:gsub("\\","/") + archive = archive:gsub("<version>",version) + if osplatform == "windows" or osplatform == "mswin" then + destination = destination:gsub("([a-zA-Z]):/", "/cygdrive/%1/") end + individual[#individual+1] = { archive, destination } end end end end + + for platform, _ in pairs(platforms) do + add_collection(scripts.update.base,platform) + end + for platform, _ in pairs(platforms) do + add_collection(scripts.update.modules,platform) + end + for engine, _ in pairs(engines) do + for platform, _ in pairs(platforms) do + add_collection(scripts.update.engines[engine],platform) + end + end + local combined = { } for _, repository in ipairs(scripts.update.repositories) do if repositories[repository] then @@ -219,11 +295,11 @@ function scripts.update.synchronize() cd = { } combined[destination] = cd end - cd[#cd+1] = string.format("%s/%s/%s",states.get('rsync.module'),repository,archive) + cd[#cd+1] = format("%s/%s/%s",states.get('rsync.module'),repository,archive) end end end - if input.verbose then + if logs.verbose then for k, v in pairs(combined) do logs.report("update", k) for k,v in ipairs(v) do @@ -232,24 +308,53 @@ function scripts.update.synchronize() end end for destination, archive in pairs(combined) do - local archives, command = table.concat(archive," "), "" - local normalflags, deleteflags = states.get("rsync.flags.normal"), states.get("rsync.flags.delete") - if true then -- environment.argument("keep") or destination:find("%.$") then - command = string.format("%s %s %s'%s' '%s'", bin, normalflags, url, archives, destination) - else - command = string.format("%s %s %s %s'%s' '%s'", bin, normalflags, deleteflags, url, archives, destination) + local archives, command = concat(archive," "), "" + -- local normalflags, deleteflags = states.get("rsync.flags.normal"), states.get("rsync.flags.delete") + -- if environment.argument("keep") or destination:find("%.$") then + -- command = format("%s %s %s'%s' '%s'", bin, normalflags, url, archives, destination) + -- else + -- command = format("%s %s %s %s'%s' '%s'", bin, normalflags, deleteflags, url, archives, destination) + -- end + local normalflags, deleteflags = states.get("rsync.flags.normal"), "" + if (destination:find("texmf$") or destination:find("texmf%-context$")) and (not environment.argument("keep")) then + deleteflags = states.get("rsync.flags.delete") end - logs.report("mtx update", string.format("running command: %s",command)) + command = format("%s %s %s %s'%s' '%s'", bin, normalflags, deleteflags, url, archives, destination) + logs.report("mtx update", format("running command: %s",command)) if not fetched[command] then scripts.update.run(command) fetched[command] = command end end + + local function update_script(script, platform) + local bin = bin:gsub("\\","/") + local texroot = texroot:gsub("\\","/") + platform = scripts.update.platforms[platform] + if platform then + local command + if platform == 'mswin' then + bin = bin:gsub("([a-zA-Z]):/", "/cygdrive/%1/") + texroot = texroot:gsub("([a-zA-Z]):/", "/cygdrive/%1/") + command = string.format("%s -t %s/texmf-context/scripts/context/lua/%s.lua %s/texmf-mswin/bin/", bin, texroot, script, texroot) + else + command = string.format("%s -tgo --chmod=a+x %s/texmf-context/scripts/context/lua/%s.lua %s/texmf-%s/bin/%s", bin, texroot, script, texroot, platform, script) + end + logs.report("mtx update", format("updating %s for %s: %s", script, platform, command)) + scripts.update.run(command) + end + end + + for platform, _ in pairs(platforms) do + update_script('luatools',platform) + update_script('mtxrun',platform) + end + else - logs.report("mtx update", string.format("no valid texroot: %s",texroot)) + logs.report("mtx update", format("no valid texroot: %s",texroot)) end if not force then - logs.report("update", "use --force to really update") + logs.report("update", "use --force to really update files") end logs.report("update","done") end @@ -262,32 +367,59 @@ function table.fromhash(t) return h end - +-- make the ConTeXt formats function scripts.update.make() + logs.report("make","start") + local force = environment.argument("force") local texroot = scripts.update.fullpath(states.get("paths.root")) - local engines = states.get('engines') + local engines= states.get('engines') local platforms = states.get('platforms') local formats = states.get('formats') - input.load_tree(texroot) + + resolvers.load_tree(texroot) + -- update filename database for pdftex/xetex scripts.update.run("mktexlsr") + -- update filename database for luatex scripts.update.run("luatools --generate") - local formatlist = table.concat(table.fromhash(formats), " ") + local askedformats = formats + local texformats = table.tohash(scripts.update.texformats) + local mpformats = table.tohash(scripts.update.mpformats) + for k,v in pairs(texformats) do + if not askedformats[k] then + texformats[k] = nil + end + end + for k,v in pairs(mpformats) do + if not askedformats[k] then + mpformats[k] = nil + end + end + local formatlist = concat(table.fromhash(texformats), " ") if formatlist ~= "" then for engine in pairs(engines) do - -- todo: just handle make here or in mtxrun --script context --make ---~ os.execute("set") - scripts.update.run(string.format("texexec --make --all --fast --%s %s",engine,formatlist)) + if engine == "luatex" then + scripts.update.run(format("context --make")) -- maybe also formatlist + else + -- todo: just handle make here or in mtxrun --script context --make + scripts.update.run(format("texexec --make --all --fast --%s %s",engine,formatlist)) + end end end + local formatlist = concat(table.fromhash(mpformats), " ") + if formatlist ~= "" then + scripts.update.run(format("texexec --make --all --fast %s",formatlist)) + end if not force then - logs.report("make", "use --force to really make") + logs.report("make", "use --force to really make formats") end + scripts.update.run("mktexlsr") + scripts.update.run("luatools --generate") logs.report("make","done") end -banner = banner .. " | download tools " +logs.extendbanner("Download Tools 0.20",true) messages.help = [[ --platform=string platform (windows, linux, linux-64, osx-intel, osx-ppc, linux-ppc) @@ -296,8 +428,9 @@ messages.help = [[ --repository=string specify version (current, experimental) --context=string specify version (current, latest, yyyy.mm.dd) --rsync=string rsync binary (rsync) ---texroot installation directory (not guessed for the moment) ---engine tex engine (luatex, pdftex, xetex) +--texroot=string installation directory (not guessed for the moment) +--engine=string tex engine (luatex, pdftex, xetex) +--extras=string extra modules (can be list or 'all') --force instead of a dryrun, do the real thing --update update minimal tree --make also make formats and generate file databases @@ -305,8 +438,6 @@ messages.help = [[ --state update tree using saved state ]] -input.verbose = true - scripts.savestate = true if scripts.savestate then @@ -315,7 +446,7 @@ if scripts.savestate then -- tag, value, default, persistent - input.starttiming(states) + statistics.starttiming(states) states.set("info.version",0.1) -- ok states.set("info.count",(states.get("info.count") or 0) + 1,1,false) -- ok @@ -333,11 +464,11 @@ if scripts.savestate then states.set("context.version", environment.argument("context"), "current", true) -- ok local valid = table.tohash(scripts.update.repositories) - for r in string.gmatch(environment.argument("repository") or "current","([^, ]+)") do + for r in gmatch(environment.argument("repository") or "current","([^, ]+)") do if valid[r] then states.set("repositories." .. r, true) end end local valid = scripts.update.engines - for r in string.gmatch(environment.argument("engine") or "all","([^, ]+)") do + for r in gmatch(environment.argument("engine") or "all","([^, ]+)") do if r == "all" then for k, v in pairs(valid) do if k ~= "all" then @@ -349,12 +480,16 @@ if scripts.savestate then end end local valid = scripts.update.platforms - for r in string.gmatch(environment.argument("platform") or os.currentplatform(),"([^, ]+)") do + for r in gmatch(environment.argument("platform") or os.currentplatform(),"([^, ]+)") do if valid[r] then states.set("platforms." .. r, true) end end - local valid = table.tohash(scripts.update.allformats) - for r in string.gmatch(environment.argument("formats") or "","([^, ]+)") do + local valid = table.tohash(scripts.update.texformats) + for r in gmatch(environment.argument("formats") or "","([^, ]+)") do + if valid[r] then states.set("formats." .. r, true) end + end + local valid = table.tohash(scripts.update.mpformats) + for r in gmatch(environment.argument("formats") or "","([^, ]+)") do if valid[r] then states.set("formats." .. r, true) end end @@ -362,7 +497,9 @@ if scripts.savestate then states.set("formats.cont-nl", true) states.set("formats.metafun", true) - -- modules + for r in gmatch(environment.argument("extras") or "","([^, ]+)") do + states.set("extras." .. r, true) + end logs.report("state","loaded") @@ -382,12 +519,12 @@ if environment.argument("update") then elseif environment.argument("make") then scripts.update.make() else - input.help(banner,messages.help) + logs.help(messages.help) end if scripts.savestate then - input.stoptiming(states) - states.set("info.runtime",tonumber(input.elapsedtime(states))) + statistics.stoptiming(states) + states.set("info.runtime",tonumber(statistics.elapsedtime(states))) if environment.argument("force") then states.save() logs.report("state","saved") |