The appimagelint's documentation, tells
appimagelint is a tool to check AppImage files for common issues. appimagelint runs a variety of checks on AppImages and reports the results in human-readable form in the console log.
So to get started
-
This step is optional: create the AppImage on the oldest distro for full compatability. In this tutorial, I am going to use the oldest LTS version of Ubuntu, i.e Ubuntu Xenial aka 16.04
docker pull ubuntu:16.04 docker run -it ubuntu:16.04
-
Download
pyappimage's appimage for a specific python version. For my test case, I am usingpython3.8pyappimage.sudo apt update sudo apt install file # or else appimagetool will fail in future sudo apt install wget # optional : to download pyappimage's appimage wget https://github.com/srevinsaju/pyappimage/releases/download/continuous/pyappimage-3.8-x86_64.AppImage chmod +x pyappimage*.AppImage
-
Cool. Now download the
appimagelintsource code.git clone https://github.com/TheAssassin/appimagelint cd appimagelint -
Now make a folder called
pyappimagemkdir pyappimage cd pyappimage touch pyappimage.json -
Now edit the
pyappimage/pyappimage.jsonfile, to add the following content.name: appimagelint entrypoint: appimagelint.cli:run categories: - Utility
if you are curious on where appimagelint.cli:run came from, here, on the setup.py, there is a section called console_scripts,
this has something like this
entry_points={
"console_scripts": [
"appimagelint = appimagelint.cli:run",
],
},So, I took the entrypoint from there.
If you are trying to package your own application, this is how entrypoint works
appimagelint.cli:run is translated to from appimagelint.cli import run; run()
-
Add
updateinformationto json. Update information is a static link to a file to getzsyncor update information i.e, the appimage you are bundling, can be delta updated. For more information on how to writeupdateinformation, see AppImage Docs updateinformationMy final json looks like this
name: appimagelint entrypoint: appimagelint.cli:run categories: - Utility updateinformation: gh-releases-zsync|TheAssassin|appimagelint|latest|appimagelint*.AppImage.zsync
-
Bootstrap
pyappimage. 🎉 You are ready to build. The command to build Python AppImage is simple; just./pyappimage=*.AppImage buildIn case you are failing with a
libfuseerror, add the--appimage-extract-and-runoption beforebuildAnd you are done. -
Test the generated AppImage, The generated appimage, is called
appimagelint-x86_64.AppImageRun it by./appimagelint-x86_64.AppImage --help
But this would fail now. Because of an odd error
Traceback (most recent call last): File "entrypoint.py", line 12, in <module> File "appimagelint/cli.py", line 91, in run args = parse_args() File "appimagelint/cli.py", line 47, in parse_args action="version", version=get_version(), File "appimagelint/cli.py", line 18, in get_version version = pkg_resources.require("appimagelint")[0].version File "pkg_resources/__init__.py", line 899, in require File "pkg_resources/__init__.py", line 785, in resolve pkg_resources.DistributionNotFound: The 'appimagelint' distribution was not found and is required by the application [886] Failed to execute script entrypoint
Looking at the traceback, it looks like on
appimagelint/cli.pyat line 18, appimagelint is trying to callpkg_resources.require, which calls thepipdata to see the version which was installed. Butpyappimagedoes not bundlepipmetadata. So we might need to replace that dataSo my patch looks like this:
diff --git a/appimagelint/cli.py b/appimagelint/cli.py
index e734440..5266e53 100644
--- a/appimagelint/cli.py
+++ b/appimagelint/cli.py
@@ -15,7 +15,7 @@ from .checks import IconsCheck, GlibcABICheck, GlibcxxABICheck, DesktopFilesChec
def get_version():
try:
import pkg_resources
- version = pkg_resources.require("appimagelint")[0].version
+ version = '0.0.1'
except ImportError:
version = "unknown"-
Try the build again to see if it works
./pyappimage=*.AppImage buildIn case you are failing with a
libfuseerror, add the--appimage-extract-and-runoption beforebuildAnd you are done. -
Attempt to run again. This time it fails with a different error
./appimagelint-x86_64.AppImage --appimage-extract-and-run
Traceback (most recent call last):
File "PyInstaller/hooks/rthooks/pyi_rth__tkinter.py", line 20, in <module>
FileNotFoundError: Tcl data directory "/tmp/appimage_extracted_9f4f32b23bc1296b3cecfc7ea8798a69/appimagelint/tcl" not found.
[4342] Failed to execute script pyi_rth__tkinterThis is because Tcl and Tkinter are bundled in a different directory. To add them separately, you could add this to pyappimage/pyappimage.json
name: appimagelint
entrypoint: appimagelint.cli:run
categories:
- Utility
updateinformation: gh-releases-zsync|TheAssassin|appimagelint|latest|appimagelint*.AppImage.zsync
add-data:
$APPDIR/usr/share/tcltk/tk8.4: tk
$APPDIR/usr/share/tcltk/tcl8.4: tcl
I added the folders for tk and tcl from their respective folders. You could append $APPDIR to add a folder from the pyappimage-*.AppImage to your compiled appimage. Or use absolute path, to copy from your host OS to the appimage.
- Now run it again, And 🎉 it works without errors now!