]> git.e2factory.org Git - e2factory.git/commitdiff
Add XZ support for sources
authorTobias Ulmer <tu@emlix.com>
Mon, 4 Mar 2013 19:04:02 +0000 (20:04 +0100)
committerTobias Ulmer <tu@emlix.com>
Mon, 4 Mar 2013 19:12:01 +0000 (20:12 +0100)
This depends on a tar version in the chroot that supports xz archives.

The code has been restructured such that we don't play guessing games
based on the magic number in the file header anmore, and just go by
extension. Also, since all this extraction business is only relevant to
file sources, move it into the files plugin instead of cluttering e2lib.

To be clear, this change removes the questionable feature of detecting
that a .tar.bz2 tarball was really a .tar.gz and will instead return an
error message by he way of tar failing.

Signed-off-by: Tobias Ulmer <tu@emlix.com>
generic/e2lib.lua
local/files.lua

index 3a528e1e018ddf7333ed05b320cffadb40c3646b..3c8fbc248f097740eba95c260d9c56230ab31ba2 100644 (file)
@@ -648,47 +648,7 @@ function e2lib.shquote(str)
     return "'"..str.."'"
 end
 
---- Determines the type of an archive.
--- Returns an empty string for tar archives, "--gzip" for
--- gzip files, "--bzip2" for bzip2 files,
--- and "zip" for zip archives.
--- @param path Path to an archive file (string).
--- @return False on error, otherwise a string as described above.
--- @return An error object on failure.
-function e2lib.tartype(path)
-    local e = err.new("Could not determine archive type")
-    local c
-
-    local f, re = io.open(path, "r")
-    if not f then
-        return false, e:append(": %s", re)
-    end
-
-    local d = f:read(512)
-    if not d then
-        return false, e:append(": read error")
-    end
-
-    f:close()
-
-    local l = string.len(d)
-
-    if l > 261 and string.sub(d, 258, 262) == "ustar" then
-        c = ""
-    elseif l > 1 and string.sub(d, 1, 2) == "\031\139" then
-        c = "--gzip"
-    elseif l > 2 and string.sub(d, 1, 3) == "BZh" then
-        c = "--bzip2"
-    elseif l > 3 and string.sub(d, 1, 4) == "PK\003\004" then
-        c = "zip"
-    else
-        return false, e:append(": could not determine type")
-    end
-
-    return c
-end
-
---- translate filename suffixes to valid tartypes for e2-su-2.2
+--- Translate filename suffixes to valid tartypes for e2-su-2.2 only.
 -- @param filename string: filename
 -- @return string: tartype, or nil on failure
 -- @return an error object on failure
@@ -707,40 +667,6 @@ function e2lib.tartype_by_suffix(filename)
     return tartype
 end
 
---- Generates the command to unpack an archive file.
--- @param physpath Current location and filename to be unpacked later.
--- @param virtpath Location and name of the file at the time of unpacking.
--- @param destdir Path where the unpacked files shall be put.
--- @return Tool name (string), or false on error.
--- @return Argument vector table for the tool, or an error object on failure.
-function e2lib.howtounpack(physpath, virtpath, destdir)
-    local tool
-    local toolargv = {}
-    local rc, re = e2lib.tartype(physpath)
-
-    if not rc then
-        return false, re
-    end
-
-    if rc == "zip" then
-        tool = "unzip"
-        table.insert(toolargv, virtpath)
-        table.insert(toolargv, "-d")
-        table.insert(toolargv, destdir)
-    else
-        tool = "tar"
-        table.insert(toolargv, "-C")
-        table.insert(toolargv, destdir)
-        if rc ~= "" then
-            table.insert(toolargv, rc)
-        end
-        table.insert(toolargv, "-xf")
-        table.insert(toolargv, virtpath)
-    end
-
-    return tool, toolargv
-end
-
 --- Read the first line from the given file and return it.
 -- Beware that end of file is considered an error.
 -- @param path Path to file (string).
index a2d36438d1ec62be1ad93cb2f3862c333e604152..36f56759101370ba4ffcd65d3e0861befabd097d 100644 (file)
@@ -232,6 +232,87 @@ local function gen_dest_dir_name(buildpath, sourcename, copypath, location,
     return destdir, destname
 end
 
+--- Determine archive type by looking at the file extension.
+-- @param filename File name (string).
+-- @return String constant describing archive,
+-- or false if archive suffix is unknown.
+-- @return Error object on failure.
+local function archive_by_suffix(filename)
+    local name = filename:lower() -- case insensitive matching
+    local atype
+
+    if name:match("%.tar$") then
+        atype = "TAR"
+    elseif name:match("%.tgz") or name:match("%.tar%.gz$") then
+        atype = "TAR_GZ"
+    elseif name:match("%.tar%.bz2$") then
+        atype = "TAR_BZIP2"
+    elseif name:match("%.tar%.xz$") then
+        atype = "TAR_XZ"
+    elseif name:match("%.zip$") then
+        atype = "ZIP"
+    else
+        return false, err.new("can not determine archive type of '%s'",
+            filename)
+    end
+
+    return atype
+end
+
+--- Generates the command to unpack an archive file.
+-- @param physpath Current location and filename to be unpacked later.
+-- @param virtpath Location and name of the file at the time of unpacking.
+-- @param destdir Path where the unpacked files shall be put.
+-- @return Tool name (string), or false on error.
+-- @return Argument vector table for the tool, or an error object on failure.
+local function gen_unpack_command(physpath, virtpath, destdir)
+    local tool
+    local toolargv = {}
+
+    local atype, re = archive_by_suffix(physpath)
+    if not atype then
+        return false, re
+    end
+
+    if atype == "ZIP" then
+        tool = "unzip"
+        table.insert(toolargv, virtpath)
+        table.insert(toolargv, "-d")
+        table.insert(toolargv, destdir)
+    elseif atype == "TAR" then
+        tool = "tar"
+        table.insert(toolargv, "-C")
+        table.insert(toolargv, destdir)
+        table.insert(toolargv, "-xf")
+        table.insert(toolargv, virtpath)
+    elseif atype == "TAR_GZ" then
+        tool = "tar"
+        table.insert(toolargv, "-z")
+        table.insert(toolargv, "-C")
+        table.insert(toolargv, destdir)
+        table.insert(toolargv, "-xf")
+        table.insert(toolargv, virtpath)
+    elseif atype == "TAR_BZIP2" then
+        tool = "tar"
+        table.insert(toolargv, "-j")
+        table.insert(toolargv, "-C")
+        table.insert(toolargv, destdir)
+        table.insert(toolargv, "-xf")
+        table.insert(toolargv, virtpath)
+    elseif atype == "TAR_XZ" then
+        tool = "tar"
+        table.insert(toolargv, "--xz")
+        table.insert(toolargv, "-C")
+        table.insert(toolargv, destdir)
+        table.insert(toolargv, "-xf")
+        table.insert(toolargv, virtpath)
+    else
+        return false, err.new("unhandled archive type")
+    end
+
+    return tool, toolargv
+end
+
 --- Prepare a files source.
 -- @param info The info table.
 -- @param sourcename The source name (string)
@@ -270,7 +351,7 @@ function files.prepare_source(info, sourcename, sourceset, buildpath)
                 return false, e:cat(re)
             end
 
-            local rc, re = e2lib.howtounpack(path, path, buildpath)
+            local rc, re = gen_unpack_command(path, path, buildpath)
             if not rc then
                 return false, e:cat(re)
             end
@@ -475,7 +556,7 @@ function files.toresult(info, sourcename, sourceset, directory)
         if file.unpack then
             local physpath = e2lib.join(destdir, e2lib.basename(file.location))
             local virtpath = e2lib.join(source, e2lib.basename(file.location))
-            local rc, re = e2lib.howtounpack(physpath, virtpath, "$(BUILD)")
+            local rc, re = gen_unpack_command(physpath, virtpath, "$(BUILD)")
             if not rc then
                 e:cat("unable to generate unpack command")
                 return false, e:cat(re)