2 -- $Id: PackageGraph.lua,v 1.13 2005/04/04 18:59:20 cpressey Exp $
3 -- Installer package functions written in Lua.
5 -- BEGIN lib/package.lua --
7 local POSIX = require("posix")
8 local FileName = require("filename")
9 local App = require("app")
17 -- This 'class' currently only contains static global methods
18 -- for dealing with packages. There is no 'package object.'
23 -- Determine whether a package is installed on a HDD.
25 Package.exists = function(base, pkg_name)
26 return FileName.is_dir(
27 App.expand("${root}${base}var/db/pkg/${pkg_name}", {
34 Package.list_all = function(base)
35 local i, filename, list
36 local dir = POSIX.dir(
37 App.expand("${root}${base}var/db/pkg", {
43 for i, filename in ipairs(dir) do
44 if filename ~= "." and filename ~= ".." then
45 table.insert(list, filename)
53 -- Methods which construct command-chains.
57 -- Delete all packages from a given base.
59 Package.cmds_clean = function(base, cmds)
61 cmdline = "${root}${CHROOT} ${root}${base} /${PKG_DELETE} '*'",
62 replacements = { base = base }
67 -- Create commands to copy a package from the installation media onto
70 -- This function returns the number of packages that will be copied
71 -- by the commands it has created, or nil if an error occurs.
73 Package.cmds_copy = function(base, cmds, pkg_name, pkg_seen, pkg_done)
74 local pty, rpkg_name, line, pkg_suffix
76 pkg_seen = pkg_seen or {}
77 pkg_done = pkg_done or {}
80 -- Get all the packages that this package depends on, and
81 -- recursively copy them first, if they're not already there,
82 -- and if we've not already seen them.
84 -- It woulld be nice if we could send this command through a command
85 -- chain so that we could get an accurate idea of what is being
86 -- run and so that it will be logged. But unfortunately that's
87 -- not feasible, since this function is building another command
88 -- chain for later use. So we use a pty.
90 pty = Pty.open(App.expand("${root}${PKG_INFO} -r ") .. pkg_name)
98 -- Only look at lines that begin with 'Dependency:'.
100 local found, len, rpkg_name =
101 string.find(line, "^Dependency:%s*([^%s]+)")
102 if found and not Package.exists(base, rpkg_name) then
103 local subcount = Package.cmds_copy(
104 base, cmds, rpkg_name, pkg_seen, pkg_done
106 if subcount == nil then
110 depcount = depcount + subcount
112 line = pty:readline()
117 if App.os.name == "FreeBSD" then
121 if not Package.exists(base, pkg_name) and not pkg_seen[pkg_name] then
122 pkg_seen[pkg_name] = true
123 depcount = depcount + 1
124 cmds:set_replacements{
127 pkg_suffix = pkg_suffix
130 "${root}${PKG_CREATE} -b ${pkg_name} ${root}${base}tmp/${pkg_name}.${pkg_suffix}",
132 cmdline = "${root}${CHROOT} ${root}${base} " ..
133 "/${PKG_ADD} /tmp/${pkg_name}.${pkg_suffix}",
135 on_executed = function(cmd, result, output)
137 pkg_done[cmd.tag] = true
141 "${root}${RM} ${root}${base}tmp/${pkg_name}.${pkg_suffix}"
149 -- Remove a package from a target system.
151 -- This function returns the number of packages that will be removed
152 -- by the commands it has created, or nil if an error occurs.
154 Package.cmds_remove = function(base, cmds, pkg_name, pkg_seen, pkg_done)
156 local command, rpkg_name
158 local seen_required_by = false
159 pkg_seen = pkg_seen or {}
160 pkg_done = pkg_done or {}
163 -- Get all the packages that this package depends on, and
164 -- recursively delete them.
166 pty = Pty.open(App.expand(
167 "${root}${CHROOT} ${root}${base} /${PKG_INFO} -R ${pkg_name}", {
176 line = pty:readline()
179 -- Only look at lines that follow the "Required by:" line.
181 if seen_required_by then
182 found, len, rpkg_name =
183 string.find(line, "^%s*([^%s]+)")
184 if found and Package.exists(base, rpkg_name) then
185 local subcount = Package.cmds_remove(
186 base, cmds, rpkg_name, pkg_seen, pkg_done
188 if subcount == nil then
192 depcount = depcount + subcount
195 if string.find(line, "^Required by:") then
196 seen_required_by = true
199 line = pty:readline()
203 if Package.exists(base, pkg_name) and not pkg_seen[pkg_name] then
204 pkg_seen[pkg_name] = true
205 depcount = depcount + 1
207 cmdline = "${root}${CHROOT} ${root}${base} /${PKG_DELETE} ${pkg_name}",
213 on_executed = function(cmd, result, output)
215 pkg_done[cmd.tag] = true
224 -- END of lib/package.lua --