Skip to content

Instantly share code, notes, and snippets.

@AshleighAdams
Forked from damphat/apt-rdepends-tree
Last active August 29, 2015 14:12
Show Gist options
  • Select an option

  • Save AshleighAdams/662da4fed7ed50c5eb93 to your computer and use it in GitHub Desktop.

Select an option

Save AshleighAdams/662da4fed7ed50c5eb93 to your computer and use it in GitHub Desktop.
#!/usr/bin/env lua
--[[
lua5.2
├─libc6 >= 2.14
│ └─libgcc1
│ ├─gcc-4.9-base = 4.9.2-9
│ └─libc6 >= 2.14*
└─libreadline6 >= 6.0
├─libc6 >= 2.15*
├─libtinfo5
│ └─libc6 >= 2.15*
└─readline-common
├─dpkg >= 1.15.4
└─install-info
└─libc6 >= 2.14*
]]
local argv = {}
local opts = {
["max-depth"] = "",
["tabs"] = false,
["line-length"] = "1",
}
do
local doneopts = false
for k,v in ipairs(table.pack(...)) do
if v == "--" then
doneopts = true
elseif v:sub(1, 2) == "--" then
local name, val = v:match("%-%-(.-)=(.+)")
if not name then
name, val = v:sub(3, -1), ""
end
if opts[name] == nil then
io.stderr:write(arg[0]..": unknown option --" .. name .. "\n")
os.exit(1)
else
opts[name] = val
end
else
table.insert(argv, v)
end
end
end
local linelength = assert(tonumber(opts["line-length"]))
local continued = "├" .. string.rep("─", linelength)
local middle = "│" .. string.rep(" ", linelength)
local last = "└" .. string.rep("─", linelength)
local afterlast = " " .. string.rep(" ", linelength)
if #argv == 0 then
io.stderr:write(arg[0]..": expected package name\n")
os.exit(1)
end
local done_depends = {}
local function do_pkg(pkg)
local p = io.popen("apt-rdepends " .. pkg .. " 2> /dev/null")
local depends = {}
local curpkg
while true do
local line = p:read("*l")
if not line then break end
if line:sub(1,2) == " " then
local k,v = line:match("%s*(.-):%s*(.+)")
if k == "Depends" then
local name, version = v:match("(.+) %((.+)%)")
if not name then
name, version = v, nil
end
table.insert(depends[curpkg], {name = name, version = version})
end
else
curpkg = line
depends[curpkg] = {}
end
end
-- now we graph it
local maxdepth = tonumber(opts["max-depth"])
local function itt_deps(name, version, done, depth, pre)
done = done or {}
depth = depth or 0
version = version or ""
pre = pre or ""
local tabs = string.rep("\t", depth)
local fmt = string.format("%s%s",
name,
version ~= ""
and " " .. version
or ""
)
if done[name] then
print(fmt .. "*")
return
elseif maxdepth and depth >= maxdepth then
print(fmt.."...")
return
else
print(fmt)
done[name] = true
end
local deps = depends[name]
local numdeps = #deps
for i = 1, numdeps do
local dep = deps[i]
local islast = i == numdeps
local prechild
if not opts.tabs then
local prethis = pre .. (islast and last or continued)
prechild = pre .. (islast and afterlast or middle)
io.stdout:write(prethis)
else
io.stdout:write(tabs)
prechild = tabs .. "\t"
end
itt_deps(dep.name, dep.version, done, depth + 1, prechild)
end
end
itt_deps(pkg, nil, done_depends)
end
for k,v in pairs(argv) do
do_pkg(v)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment