From: Tobias Ulmer Date: Mon, 4 Mar 2013 19:04:02 +0000 (+0100) Subject: Add XZ support for sources X-Git-Tag: e2factory-2.3.13rc2~1 X-Git-Url: https://git.e2factory.org/?a=commitdiff_plain;h=47175c9e7224b48add43038d86021e0b7a4f0ad0;p=e2factory.git Add XZ support for sources 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 --- diff --git a/generic/e2lib.lua b/generic/e2lib.lua index 3a528e1..3c8fbc2 100644 --- a/generic/e2lib.lua +++ b/generic/e2lib.lua @@ -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). diff --git a/local/files.lua b/local/files.lua index a2d3643..36f5675 100644 --- a/local/files.lua +++ b/local/files.lua @@ -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)