Warning: this is an htmlized version!
The original is here, and the conversion rules are here. |
-- -*- coding: raw-text-unix -*- -- Edrx, 2004sep08 -- Current version: 2004dec22 -- (find-angg "LUA/debs2.lua") -- -- debs.lua: find the .debs corresponding to installed packages. -- -- To create a new Debian system from an existing one (say, in another -- partition) we usually need a repository of .debs; and we usually -- want the new system to have a subset of the packages that are -- installed in the current one, with exactly the same versions, and, -- for dozens of reasons, we want to need to access the net as little -- as possible. The best solution is then to create a local repository -- with the right selection of .debs, but how do we do that? -- -- This library provides some functions to help in that task. It is -- easy to obtain the names of the packages currently installed, each -- with its version string: -- -- # (find-man "1 grep-status") -- # (find-sh "grep-status -s Package,Version -F Status ' installed'") -- grep-status --show-field=Package,Version --field=Status ' installed' -- -- Usually _all_ the original .debs corresponding to those packages -- are available somewhere in the system: -- -- * the ones that were downloaded by apt are at -- (find-fline "/var/cache/apt/archives/") -- -- * the ones coming from CD installs are inside the CD images; -- we can either mount the real CD or its .iso image -- -- * the ones coming from local repositories, are, huh, well, just -- files inside these local repositories -- -- * the ones that have been installed with "dpkg -i" from -- nonstandard .debs, like things that we have compiled locally or -- that we have downloaded from very nonstandard places, are in -- directories that we know; we are always very organized when we -- put our root hats on :) -- -- So we just need to list these .debs, typically with -- -- find dir1 dir2 ... dirn -name '*.deb' -- -- and then cross the output with the output of "grep-status" to -- obtain the first listed .deb corresponding to each installed -- package, plus a listing of the installed packages for which no -- corresponding .deb was found. -- -- After that we need a few other tricks to convert the output to a -- series of "cp"s or "ln"s. Check the examples at the end of the -- file. (But they're not well-documented, sorry). strfind = string.find splitdebversion = function (str) local _, __, epoch, colon, version _, __, epoch, colon, version = strfind(str, "^(.*)(%%3a)(.*)$") if _ then return epoch, colon, version end _, __, epoch, colon, version = strfind(str, "^(.*)(:)(.*)$") if _ then return epoch, colon, version end return nil, nil, str end splitdeb = function (str) local _, __, dir, name, epoch, colon, version, arch _, __, dir, rest = strfind(str, "^(.*/)([^/]*)$") if _ then str = rest end _, __, name, v, arch = strfind(str, "^([^_]*)_([^_]*)_([^_.]*).deb$") if not _ then return end epoch, colon, version = splitdebversion(v) return {dir=dir, name=name, epoch=epoch, colon=colon, version=version, arch=arch} end readinstalleddebs = function (fname) for str in io.lines(fname) do local _, __, field, contents = strfind(str, "^(.*): (.*)$") if field == "Package" then name = contents end if field == "Version" then epoch, colon, version = splitdebversion(contents) installed[name] = {name=name, epoch=epoch, colon=colon, version=version} end end end readdeblist = function (fname) for pathname in io.lines(fname) do local struct = splitdeb(pathname) if struct and installed[struct.name] and not installed[struct.name].pathname and installed[struct.name].version == struct.version then installed[struct.name].pathname = pathname end end end readall = function (fname_installeddebs, ...) installed = {} readinstalleddebs(fname_installeddebs) for i=1,table.getn(arg) do readdeblist(arg[i]) end end printall = function () for name,struct in installed do print(struct.pathname or "# no deb found for " .. name) end end if arg and string.gsub(arg[0], ".*/", "") == "debs.lua" then readall(unpack(arg)) printall() end --[[ # Examples and tests: #* lua50 -e ' dofile(os.getenv("HOME").."/LUA/debs.lua") PP(splitdeb("libstartup-notification0_0.7-1_i386.deb")) PP(splitdeb("libstdc++5-3.3-dev_1%3a3.3.4-6sarge1.2_i386.deb")) PP(splitdeb("/foo/libstdc++5_1:3.3.4-6sarge1.2_i386.deb")) ' #* mkdir /tmp/cdd/ sudo umount /tmp/cdd/ sudo mount -o loop /big/hdb2/CDs/debian-br-cdd/sarge-i386-1.raw /tmp/cdd find /tmp/cdd/ -name '*.deb' | sort | tee /tmp/cdddebs ls /var/cache/apt/archives/*.deb | tee /tmp/vcdebs ls /big/hdb2/CDs/cdd-extra/*.deb | tee /tmp/cddextradebs grep-status --show-field=Package,Version --field=Status ' installed' \ | tee /tmp/installed-debs #* lua50 -e ' dofile("'$HOME/LUA/debs.lua'") installed = {} readinstalleddebs("/tmp/installed-debs") readdeblist("/tmp/vcdebs") readdeblist("/tmp/cddextradebs") readdeblist("/tmp/cdddebs") for name,struct in installed do print("# " .. name, "->", struct.pathname or "") end ' | sort | tee /tmp/o | l -S #* lua50 -e ' dofile("'$HOME/LUA/debs.lua'") readall("/tmp/installed-debs", "/tmp/vcdebs", "/tmp/cddextradebs", "/tmp/cdddebs") for name,struct in installed do print(struct.pathname or "# no deb found for " .. name) end ' | sort | tee /tmp/o | l -S #* lua50 ~/LUA/debs.lua \ /tmp/installed-debs \ /tmp/vcdebs /tmp/cddextradebs /tmp/cdddebs #* --]]