script to list installed packages without any version online

Alexander Bergolth <[email protected]> Sat, 01 Apr 2006 23:58:02 +0200
Newsgroups gmane.linux.conectiva.apt-rpm
Message-ID <[email protected]>
This is a multi-part message in MIME format.
--------------060309000407050306080901
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

Hi!

I've attached a lua-script that lists all packages that are currently 
installed but don't have any version downloadable from a repository.

This can be useful before dist-upgrading to identify discontinued 
packages as the dependencies of those packages may cause apt to fail 
when upgrading the distribution.

Usage: Before dist-upgrading, change sources.list properly for the new 
distribution, do a apt-get update and run
   apt-cache script list-notonline.lua

Hope you'll find it useful,
Cheers,
--leo
-- 
-----------------------------------------------------------------------
[email protected]                Fax: +43-1-31336-906050
Zentrum fuer Informatikdienste - Wirtschaftsuniversitaet Wien - Austria


--------------060309000407050306080901
Content-Type: text/plain;
 name="list-notonline.lua"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="list-notonline.lua"

-- List installed packages without any online version
-- useful in preparation to dist-upgrade
--
-- usage: e.g. apt-cache script <scriptname>
-- (or see https://moin.conectiva.com.br/AptRpm/Scripting)
--
-- Author: Leo Bergolth

if script_slot == "Scripts::AptCache::Help::Command" then
  print(_("   list-notonline - Show installed packages without any online version"))
  return
end

if command_args and command_args[1] ~= "list-notonline" then
	return
end
command_consume = 1


function verstrtest(va, vb, operator, norel)
  if norel then
    -- chop off the release
    va= string.gsub(va, "-.+$", "")
    vb= string.gsub(vb, "-.+$", "")
  end
  res = verstrcmp(va, vb)
  -- operator "", "<=", ">=", "<", ">", "=", or "!="
  if res < 0 then
    if operator == '<' or operator == '!=' then
      return true
    end
  elseif res == 0 then
    if operator == '=' or operator == '<=' or operator == '>=' then
      return true
    end
  elseif res > 0 then
    if operator == '>' or operator == '!=' then
      return true
    end
  end
  return false
end


function collectobsoleted()
  -- collect a list of packages that obsolete installed packages
  obsoletedlist = {}
  for i, pkg in ipairs(pkglist()) do
    for i, ver in ipairs(pkgverlist(pkg)) do
      if verisonline(ver) then
        for i, dep in verdeplist(ver) do
          if dep.type == 'obsoletes' then
            name = pkgname(pkg)
            pkgobsoleted = dep.pkg
            -- only remember it if the obsoleted package is actually installed
            if pkgvercur(pkgobsoleted) then
              pkgidobsoleted = pkgid(pkgobsoleted)
              if not obsoletedlist[pkgidobsoleted] then
                obsoletedlist[pkgidobsoleted] = {}
              end
              table.insert(obsoletedlist[pkgidobsoleted], ver)
              -- print("obsoleted: "..name.." obsoletes "..dep.name.." ("..pkgname(pkgobsoleted)..") "..dep.operator.." "..dep.verstr)
            end
          end
        end
      end
    end
  end
  return obsoletedlist
end


function obsolete(ver)
  -- look for packages that obsolete the specified one
  pkg = verpkg(ver)
  name = pkgname(pkg)
  obsoleteslist = obsoletedlist[pkgid(pkg)]
  result = {}
  if obsoleteslist then
    for i, verobs in obsoleteslist do -- all versions that obsolete package vercur
      match = false
      for i, dep in verdeplist(verobs) do
        if dep.type == 'obsoletes' and dep.name == name then
          -- print("  obsoleted by "..pkgname(verpkg(verobs))
          --       .." (obsoletes "..dep.name.." "..dep.operator.." "..dep.verstr..")")
          if dep.verstr == "" then
            match = true
          else -- compare if (vercur dep.operator dep.verstr) is true
            if verstrtest(verstr(vercur), dep.verstr, dep.operator, 1) then
              match = true
            end
          end
        end
      end
      if match then
        table.insert(result, verobs)
      end
    end
  end
  if table.getn(result) > 0 then
    return result
  else
    return false
  end
end


function chopepoch(verstr)
  return(string.gsub(verstr, "^%d+:", ""))
end

function verlist2pkglist(verlist)
  -- returns a list of unique package names from a list of versions
  pkgs = {}
  for i, ver in verlist do
    pkgnam = pkgname(verpkg(ver))
    pkgs[pkgnam] = true
  end
  pkglist = {}
  table.foreach(pkgs, function (k, v) table.insert(pkglist, k) end)
  table.sort(pkglist)
  return pkglist
end


-- used by obsolete()
obsoletedlist = collectobsoleted()

-- print("Installed packages without any online version:")

for i, pkg in ipairs(pkglist()) do
  vercur = pkgvercur(pkg) -- version that is currently installed
  if vercur then -- currently installed
    verlist = pkgverlist(pkg) -- all versions that are available
    found = false
    for i, ver in ipairs(verlist) do
      if verisonline(ver) then
        found = true
        break
      end
    end
    if not found then
      name = pkgname(pkg)
      if string.find (name, 'gpg-pubkey#', 1, 1) ~= 1 then
        out = name -- .. "-" ..chopepoch(verstr(vercur))
        obsoletes = obsolete(vercur)
        if obsoletes then
          obsstr = table.concat(verlist2pkglist(obsoletes), " ")
          out = out .. " ("..obsstr..")"
          --for i, verobs in obsoletes do
          --  out = out .. "\n  obsoleted by "..pkgname(verpkg(verobs)).."-"..chopepoch(verstr(verobs)))
          --end
        end
        print(out)
      end
    end
  end
end

-- vim:ts=4:sw=4:et

--------------060309000407050306080901
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
apt-rpm mailing list
[email protected]
http://distro2.conectiva.com.br/mailman/listinfo/apt-rpm

--------------060309000407050306080901--