local init = {} local cfg = require("luarocks.core.cfg") local fs = require("luarocks.fs") local path = require("luarocks.path") local deps = require("luarocks.deps") local dir = require("luarocks.dir") local util = require("luarocks.util") local persist = require("luarocks.persist") local write_rockspec = require("luarocks.cmd.write_rockspec") function init.add_to_parser(parser) local cmd = parser:command("init", "Initialize a directory for a Lua project using LuaRocks.", util.see_also()) cmd:argument("name", "The project name.") :args("?") cmd:argument("version", "An optional project version.") :args("?") cmd:option("--wrapper-dir", "Location where the 'lua' and 'luarocks' wrapper scripts " .. "should be generated; if not given, the current directory is used as a default.") cmd:flag("--reset", "Delete any .luarocks/config-5.x.lua and ./lua and generate new ones.") cmd:flag("--no-wrapper-scripts", "Do not generate wrapper ./lua and ./luarocks launcher scripts.") cmd:flag("--no-gitignore", "Do not generate a .gitignore file.") cmd:group("Options for specifying rockspec data", write_rockspec.cmd_options(cmd)) end local function gitignore_path(pwd, wrapper_dir, filename) local norm_cur = fs.absolute_name(pwd) local norm_file = fs.absolute_name(dir.path(wrapper_dir, filename)) if norm_file:sub(1, #norm_cur) == norm_cur then return norm_file:sub(#norm_cur + 2) else return filename end end local function write_gitignore(entries) local gitignore = "" local fd = io.open(".gitignore", "r") if fd then gitignore = fd:read("*a") fd:close() gitignore = "\n" .. gitignore .. "\n" end fd = io.open(".gitignore", gitignore and "a" or "w") if fd then for _, entry in ipairs(entries) do entry = "/" .. entry if not gitignore:find("\n"..entry.."\n", 1, true) then fd:write(entry.."\n") end end fd:close() end end local function inject_tree(tree) path.use_tree(tree) local tree_set = false for _, t in ipairs(cfg.rocks_trees) do if type(t) == "table" then if t.name == "project" then t.root = tree tree_set = true end end end if not tree_set then table.insert(cfg.rocks_trees, 1, { name = "project", root = tree }) end end local function write_wrapper_scripts(wrapper_dir, luarocks_wrapper, lua_wrapper) local tree = dir.path(fs.current_dir(), "lua_modules") fs.make_dir(wrapper_dir) luarocks_wrapper = dir.path(wrapper_dir, luarocks_wrapper) if not fs.exists(luarocks_wrapper) then util.printout("Preparing " .. luarocks_wrapper .. " ...") fs.wrap_script(arg[0], luarocks_wrapper, "none", nil, nil, "--project-tree", tree) else util.printout(luarocks_wrapper .. " already exists. Not overwriting it!") end lua_wrapper = dir.path(wrapper_dir, lua_wrapper) local write_lua_wrapper = true if fs.exists(lua_wrapper) then if not util.lua_is_wrapper(lua_wrapper) then util.printout(lua_wrapper .. " already exists and does not look like a wrapper script. Not overwriting.") write_lua_wrapper = false end end if write_lua_wrapper then if util.check_lua_version(cfg.variables.LUA, cfg.lua_version) then util.printout("Preparing " .. lua_wrapper .. " for version " .. cfg.lua_version .. "...") -- Inject tree so it shows up as a lookup path in the wrappers inject_tree(tree) fs.wrap_script(nil, lua_wrapper, "all") else util.warning("No Lua interpreter detected for version " .. cfg.lua_version .. ". Not creating " .. lua_wrapper) end end end --- Driver function for "init" command. -- @return boolean: True if succeeded, nil on errors. function init.command(args) local do_gitignore = not args.no_gitignore local do_wrapper_scripts = not args.no_wrapper_scripts local wrapper_dir = args.wrapper_dir or "." local pwd = fs.current_dir() if not args.name then args.name = dir.base_name(pwd) if args.name == "/" then return nil, "When running from the root directory, please specify the argument" end end util.title("Initializing project '" .. args.name .. "' for Lua " .. cfg.lua_version .. " ...") local ok, err = deps.check_lua_incdir(cfg.variables) if not ok then return nil, err end local has_rockspec = false for file in fs.dir() do if file:match("%.rockspec$") then has_rockspec = true break end end if not has_rockspec then args.version = args.version or "dev" args.location = pwd local ok, err = write_rockspec.command(args) if not ok then util.printerr(err) end end local ext = cfg.wrapper_suffix local luarocks_wrapper = "luarocks" .. ext local lua_wrapper = "lua" .. ext if do_gitignore then util.printout("Adding entries to .gitignore ...") local ignores = { "lua_modules", ".luarocks" } if do_wrapper_scripts then table.insert(ignores, 1, gitignore_path(pwd, wrapper_dir, luarocks_wrapper)) table.insert(ignores, 2, gitignore_path(pwd, wrapper_dir, lua_wrapper)) end write_gitignore(ignores) end util.printout("Preparing ./.luarocks/ ...") fs.make_dir(".luarocks") local config_file = ".luarocks/config-" .. cfg.lua_version .. ".lua" if args.reset then if do_wrapper_scripts then fs.delete(fs.absolute_name(dir.path(wrapper_dir, lua_wrapper))) end fs.delete(fs.absolute_name(config_file)) end local config_tbl, err = persist.load_config_file_if_basic(config_file, cfg) if config_tbl then local varnames = { "LUA_DIR", "LUA_INCDIR", "LUA_LIBDIR", "LUA_BINDIR", "LUA", } for _, varname in ipairs(varnames) do if cfg.variables[varname] then config_tbl.variables = config_tbl.variables or {} config_tbl.variables[varname] = cfg.variables[varname] end end local ok, err = persist.save_from_table(config_file, config_tbl) if ok then util.printout("Wrote " .. config_file) else util.printout("Failed writing " .. config_file .. ": " .. err) end else util.printout("Will not attempt to overwrite " .. config_file) end ok, err = persist.save_default_lua_version(".luarocks", cfg.lua_version) if not ok then util.printout("Failed setting default Lua version: " .. err) end util.printout("Preparing ./lua_modules/ ...") fs.make_dir("lua_modules/lib/luarocks/rocks-" .. cfg.lua_version) if do_wrapper_scripts then write_wrapper_scripts(wrapper_dir, luarocks_wrapper, lua_wrapper) end return true end init.needs_lock = function() return true end return init