# HG changeset patch # User Matthew Wild # Date 1248664313 -3600 # Node ID 3407f006b9cb8cbfdc0fdcd7f875799865a0bf00 # Parent 7b1896ff4315de0e2f148ba0aa13851fcbd52e6d make_squishy: Automatically scan sources looking for modules and generate a squishy file diff -r 7b1896ff4315 -r 3407f006b9cb make_squishy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/make_squishy Mon Jul 27 04:11:53 2009 +0100 @@ -0,0 +1,113 @@ +#!/usr/bin/env lua + +local short_opts = { v = "verbose", vv = "very_verbose", o = "output", q = "quiet", qq = "very_quiet", f = "force" } +local files, opts = {}, {}; +local scanned_files, modules = {}, {}; + +for _, opt in ipairs(arg) do + if opt:match("^%-") then + local name = opt:match("^%-%-?([^%s=]+)()") + name = (short_opts[name] or name):gsub("%-+", "_"); + if name:match("^no_") then + name = name:sub(4, -1); + opts[name] = false; + else + opts[name] = opt:match("=(.*)$") or true; + end + else + table.insert(files, opt); + end +end + +if opts.very_verbose then opts.verbose = true; end +if opts.very_quiet then opts.quiet = true; end + +local noprint = function () end +local print_err, print_info, print_verbose, print_debug = noprint, noprint, noprint, noprint; + +if not opts.very_quiet then print_err = print; end +if not opts.quiet then print_info = print; end +if opts.verbose or opts.very_verbose then print_verbose = print; end +if opts.very_verbose then print_debug = print; end + +if not opts.force then + local squishy = io.open("squishy.new", "r"); + if squishy then + print_err("There is already a squishy file in this directory, use -f to force overwriting it"); + squishy:close(); + os.exit(1); + end +end + +local squishy, err = io.open("squishy.new", "w+"); +if not squishy then + print_err("Couldn't open squishy file for writing: "..tostring(err)); + os.exit(1); +end + +local LUA_DIRSEP = package.config:sub(1,1); +local LUA_PATH_MARK = package.config:sub(5,5); + +local base_path = files[1]:match("^(.-)"..LUA_DIRSEP.."[^"..LUA_DIRSEP.."]*$").."/"; + +local package_path = package.path:gsub("[^;]+", function (path) + if not path:match("^%"..LUA_DIRSEP) then + return base_path..path; + end + end):gsub("/%./", "/"); +local package_cpath = package.cpath:gsub("[^;]+", function (path) + if not path:match("^%"..LUA_DIRSEP) then + return base_path..path; + end + end):gsub("/%./", "/"); + + +function scan_file(outfile, scanfile) + for line in io.lines(scanfile) do + for _, module in line:gmatch("[^%w_]require%s*%(?([\"'])(.-)%1") do + if not modules[module] then + local binary; + modules[module] = true; + local filename = resolve_module(module, package_path); + if not filename then + binary = true; + filename = resolve_module(module, package_cpath); + end + if not filename then + print_info("Couldn't resolve "..module.." (required in "..scanfile..")"); + end + if not scanned_files[filename] then + table.insert(files, filename); + end + if filename then + outfile:write((binary and "Binary" or ""), string.format([[Module %q %q]], module, filename:gsub("^"..base_path:gsub("%p", "%%%1"), "")), "\n"); + end + end + end + end +end + + +function resolve_module(name, path) + name = name:gsub("%.", LUA_DIRSEP); + for c in path:gmatch("[^;]+") do + c = c:gsub("%"..LUA_PATH_MARK, name); + print_debug("Testing: "..c) + local f = io.open(c); + if f then + f:close(); + return c; + end + end + return nil; -- not found +end + +for _, filename in ipairs(files) do + squishy:write(string.format([[Main %q]], filename:gsub("^"..base_path:gsub("%p", "%%%1"), "")), "\n"); +end +squishy:write("\n"); +for _, filename in ipairs(files) do + scanned_files[filename] = true; + print_verbose("Found:", filename); + scan_file(squishy, filename) +end