Welcome to mirror list, hosted at ThFree Co, Russian Federation.

unpack.lua « luarocks « src - github.com/torch/luajit-rocks.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: a889bac597702101460c8f0310a0802f52d65a9b (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

--- Module implementing the LuaRocks "unpack" command.
-- Unpack the contents of a rock.
--module("luarocks.unpack", package.seeall)
local unpack = {}
package.loaded["luarocks.unpack"] = unpack

local fetch = require("luarocks.fetch")
local fs = require("luarocks.fs")
local util = require("luarocks.util")
local build = require("luarocks.build")
local dir = require("luarocks.dir")

unpack.help_summary = "Unpack the contents of a rock."
unpack.help_arguments = "[--force] {<rock>|<name> [<version>]}"
unpack.help = [[
Unpacks the contents of a rock in a newly created directory.
Argument may be a rock file, or the name of a rock in a rocks server.
In the latter case, the app version may be given as a second argument.

--force   Unpack files even if the output directory already exists.
]]

--- Load a rockspec file to the given directory, fetches the source
-- files specified in the rockspec, and unpack them inside the directory.
-- @param rockspec_file string: The URL for a rockspec file.
-- @param dir_name string: The directory where to store and unpack files.
-- @return table or (nil, string): the loaded rockspec table or 
-- nil and an error message.
local function unpack_rockspec(rockspec_file, dir_name)
   assert(type(rockspec_file) == "string")
   assert(type(dir_name) == "string")

   local rockspec, err = fetch.load_rockspec(rockspec_file)
   if not rockspec then
      return nil, "Failed loading rockspec "..rockspec_file..": "..err
   end
   local ok, err = fs.change_dir(dir_name)
   if not ok then return nil, err end
   local ok, sources_dir = fetch.fetch_sources(rockspec, true, ".")
   if not ok then
      return nil, sources_dir
   end
   ok, err = fs.change_dir(sources_dir)
   if not ok then return nil, err end
   ok, err = build.apply_patches(rockspec)
   fs.pop_dir()
   fs.pop_dir()
   if not ok then return nil, err end
   return rockspec
end

--- Load a .rock file to the given directory and unpack it inside it.
-- @param rock_file string: The URL for a .rock file.
-- @param dir_name string: The directory where to unpack.
-- @param kind string: the kind of rock file, as in the second-level
-- extension in the rock filename (eg. "src", "all", "linux-x86")
-- @return table or (nil, string): the loaded rockspec table or 
-- nil and an error message.
local function unpack_rock(rock_file, dir_name, kind)
   assert(type(rock_file) == "string")
   assert(type(dir_name) == "string")

   local ok, err, errcode = fetch.fetch_and_unpack_rock(rock_file, dir_name)
   if not ok then
      return nil, "Failed unzipping rock "..rock_file, errcode
   end
   ok, err = fs.change_dir(dir_name)
   if not ok then return nil, err end
   local rockspec_file = dir_name..".rockspec"
   local rockspec, err = fetch.load_rockspec(rockspec_file)
   if not rockspec then
      return nil, "Failed loading rockspec "..rockspec_file..": "..err
   end
   if kind == "src" then
      if rockspec.source.file then
         local ok, err = fs.unpack_archive(rockspec.source.file)
         if not ok then
            return nil, err
         end
         ok, err = fs.change_dir(rockspec.source.dir)
         if not ok then return nil, err end
         ok, err = build.apply_patches(rockspec)
         fs.pop_dir()
         if not ok then return nil, err end
      end
   end
   return rockspec
end

--- Create a directory and perform the necessary actions so that
-- the sources for the rock and its rockspec are unpacked inside it,
-- laid out properly so that the 'make' command is able to build the module.
-- @param file string: A rockspec or .rock URL.
-- @return boolean or (nil, string): true if successful or nil followed
-- by an error message.
local function run_unpacker(file, force)
   assert(type(file) == "string")
   
   local base_name = dir.base_name(file)
   local dir_name, kind, extension = base_name:match("(.*)%.([^.]+)%.(rock)$")
   if not extension then
      dir_name, extension = base_name:match("(.*)%.(rockspec)$")
      kind = "rockspec"
   end
   if not extension then
      return nil, file.." does not seem to be a valid filename."
   end

   local exists = fs.exists(dir_name)
   if exists and not force then
      return nil, "Directory "..dir_name.." already exists."
   end
   if not exists then
      local ok, err = fs.make_dir(dir_name)
      if not ok then return nil, err end
   end
   local rollback = util.schedule_function(fs.delete, fs.absolute_name(dir_name))

   local rockspec, err
   if extension == "rock" then
      rockspec, err = unpack_rock(file, dir_name, kind)
   elseif extension == "rockspec" then
      rockspec, err = unpack_rockspec(file, dir_name)
   end
   if not rockspec then
      return nil, err
   end
   if kind == "src" or kind == "rockspec" then
      if rockspec.source.dir ~= "." then
         local ok = fs.copy(rockspec.local_filename, rockspec.source.dir)
         if not ok then
            return nil, "Failed copying unpacked rockspec into unpacked source directory."
         end
      end
      util.printout()   
      util.printout("Done. You may now enter directory ")
      util.printout(dir.path(dir_name, rockspec.source.dir))
      util.printout("and type 'luarocks make' to build.")
   end
   util.remove_scheduled_function(rollback)
   return true
end

--- Driver function for the "unpack" command.
-- @param name string: may be a rock filename, for unpacking a 
-- rock file or the name of a rock to be fetched and unpacked.
-- @param version string or nil: if the name of a package is given, a
-- version may also be passed.
-- @return boolean or (nil, string): true if successful or nil followed
-- by an error message.
function unpack.run(...)
   local flags, name, version = util.parse_flags(...)

   assert(type(version) == "string" or not version)
   if type(name) ~= "string" then
      return nil, "Argument missing. "..util.see_help("unpack")
   end

   if name:match(".*%.rock") or name:match(".*%.rockspec") then
      return run_unpacker(name, flags["force"])
   else
      local search = require("luarocks.search")
      return search.act_on_src_or_rockspec(run_unpacker, name, version)
   end
end

return unpack