aboutsummaryrefslogtreecommitdiff
path: root/src/luarocks/cmd/init.lua
blob: b5359c9668f0cd7965d70b06f98040f9a0c83ef7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219

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 <name> 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