How to get list of existing debs installed that are also offered as snaps?

Hi,
I have Firefox, LibreOffice, VLC media player, Pinta drawing program etc all installed by deb packages. Is there some tool that would display all deb packages that can be replaced by snaps? Specially if snaps are newer version of software then debs from official deb repository. For example in Ubuntu 20.04 LibreOffice 6.4 is installed by default as deb package, but LibreOffice 7.0 is available as snap. Is there some tool or something that can automatically search and report which debs could be replaced on my PC by snaps alternatives?
Thanks

1 Like

There is no tool that does this as far as I’m aware. Note that debs and snaps aren’t always going to be 1-1. Snaps by definition bundle their dependencies, so it’s not at all uncommon to have a snap that is made up of MANY debs.

That said, you can get close to what you’re looking for without being perfect by utilizing the command-not-found database to pull out commands in a given package and check them against commands available in snaps. Here’s a hacky, probably broken tool that you can run to do exactly this (you’ll need to make sure you have python3, python3-apt, and python3-commandnotfound installed):

#!/usr/bin/env python3

import apt
from CommandNotFound import CommandNotFound


def main():
    # Create a collection of all debs that are installed
    installed_debs = {p.name for p in apt.Cache() if p.is_installed}

    # Now fetch all debs contained in the command-not-found database (note that
    # the presence of packages in this database is up to whether or not the
    # source deb declares certain things, so this will NOT be all-encompassing)
    cnf = CommandNotFound.CommandNotFound()
    indexed_debs = {row[0]: row[1] for row in cnf.db.con.execute("SELECT name, pkgID FROM packages").fetchall()}

    # Loop over each installed deb, fetch the commands contained within it
    # (as determined by command-not-found), and look for snaps that also
    # contain that command
    for package_name in sorted(installed_debs):
        try:
            indexed_deb_id = indexed_debs[package_name]
        except KeyError:
            continue

        # Loop over every command contained in this package, and use
        # command-not-found to look up snaps that contain those commands
        possible_snaps = set()
        for row in cnf.db.con.execute(
                "SELECT command FROM commands WHERE pkgID=?",
                (indexed_deb_id,)):
            command = row[0]
            for snap in cnf.get_snaps(command)[0]:
                possible_snaps.add(snap[0])

        # If we found some possible alternatives, print them out
        if possible_snaps:
            print(f"Possible snap replacements for {package_name}:")
            for snap in sorted(possible_snaps):
                print(f"    {snap}")
            print()


if __name__ == "__main__":
    main()

command-not-found just uses snap advise-snap behind the scenes for the snap lookup, if you’re curious. For example:

$ snap advise-snap --command 0ad

Command "0ad" not found, but can be installed with:

sudo snap install 0ad

See 'snap info <snap name>' for additional versions.

I have copied your Python code to text editor, saved the file, set execution on file and run it. I get error:

File "./a.py", line 46
           ^
SyntaxError: unexpected EOF while parsing

It looks to me that there must be some code missing at the end. Is there some limitation on this forum for the size of the text in code block.

Whoops, I missed a final paren when copying into the forum, sorry about that. I’ve edited the post, try again.

1 Like

Now I get the following error:

Traceback (most recent call last):
File “./program.py”, line 45, in
main()
File “./program.py”, line 9, in main
installed_debs = {p.name for p in apt.Cache() if p.candidate.is_installed}
File “./program.py”, line 9, in
installed_debs = {p.name for p in apt.Cache() if p.candidate.is_installed}
AttributeError: ‘NoneType’ object has no attribute ‘is_installed’

Wild idea. Is it possible to package this program and all dependency in a snap package?

1 Like

Ah that’s not a dep issue, just a bug :slight_smile: . I edited it again, give it a shot. If I make it a snap it gives the impression I intend to support and update it, when really I just wanted to give you a starting point.

1 Like

Thanks, now it works fine. Great thanks.

Understand you perfectly. It would still be interesting application to have as snap.

1 Like