Packages (Linux): adds AppImage packages support

Fixes #2179
This commit is contained in:
李通洲
2026-04-21 11:02:19 +08:00
parent 8970774e5f
commit 4b4c37ed88
6 changed files with 35 additions and 2 deletions
+1
View File
@@ -14,6 +14,7 @@ Features:
* Improves PhysicalMemory reliability on OpenBSD and FreeBSD, including support for x86 UEFI systems on OpenBSD and non-UEFI systems on FreeBSD (PhysicalMemory, OpenBSD / FreeBSD)
* Adds `display.common.(ndigits|spaceBeforeUnit)` options to configure common formatting for duration, percent, size, frequency and temperature values (#2234)
* Slightly improves performance by skipping probes for ignored device types (Sound)
* Adds support for AppImage package detection (#2179, Packages, Linux)
Bugfixes:
* Fixes a potential crash on certain Intel GPU models when using `--gpu-driver-specific` (#2259, GPU, Linux)
+1 -1
View File
@@ -119,7 +119,7 @@ if(NOT BINARY_LINK_TYPE IN_LIST BINARY_LINK_TYPE_OPTIONS)
message(FATAL_ERROR "BINARY_LINK_TYPE must be one of ${BINARY_LINK_TYPE_OPTIONS}")
endif()
set(PACKAGE_MANAGERS AM APK BREW CHOCO DPKG EMERGE EOPKG FLATPAK GUIX LINGLONG LPKG LPKGBUILD MACPORTS NIX OPKG PACMAN PACSTALL PALUDIS PISI PKG PKGTOOL RPM SCOOP SNAP SOAR SORCERY WINGET XBPS)
set(PACKAGE_MANAGERS AM APPIMAGE APK BREW CHOCO DPKG EMERGE EOPKG FLATPAK GUIX LINGLONG LPKG LPKGBUILD MACPORTS NIX OPKG PACMAN PACSTALL PALUDIS PISI PKG PKGTOOL RPM SCOOP SNAP SOAR SORCERY WINGET XBPS)
foreach(package_manager ${PACKAGE_MANAGERS})
if(package_manager STREQUAL "WINGET")
option(PACKAGES_DISABLE_${package_manager} "Disable ${package_manager} package manager detection by default" ON)
+1
View File
@@ -6,6 +6,7 @@
typedef struct FFPackagesResult {
uint32_t amSystem;
uint32_t amUser;
uint32_t appimage;
uint32_t apk;
uint32_t brew;
uint32_t brewCask;
+24
View File
@@ -118,6 +118,25 @@ static uint32_t countFilesRecursive(FFstrbuf* baseDir, const char* dirname, cons
return sum;
}
static uint32_t getNumElementsBySuffix(FFstrbuf* baseDir, const char* dirname, const char* suffix) {
uint32_t baseDirLength = baseDir->length;
ffStrbufAppendS(baseDir, dirname);
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(baseDir->chars);
ffStrbufSubstrBefore(baseDir, baseDirLength);
if (dirp == NULL) {
return 0;
}
uint32_t count = 0;
struct dirent* entry;
while ((entry = readdir(dirp)) != NULL) {
if (entry->d_name[0] != '.' && ffStrEndsWithIgnCase(entry->d_name, suffix)) {
++count;
}
}
return count;
}
static uint32_t getXBPSImpl(FFstrbuf* baseDir) {
DIR* dir = opendir(baseDir->chars);
if (dir == NULL) {
@@ -621,4 +640,9 @@ void ffDetectPackagesImpl(FFPackagesResult* result, FFPackagesOptions* options)
if (!(options->disabled & FF_PACKAGES_FLAG_SOAR_BIT)) {
result->soar += getSQLite3Int(&baseDir, ".local/share/soar/db/soar.db", "SELECT COUNT(DISTINCT pkg_id || pkg_name) FROM packages WHERE is_installed = true", "soar");
}
if (!(options->disabled & FF_PACKAGES_FLAG_APPIMAGE_BIT)) {
result->appimage += getNumElementsBySuffix(&baseDir, "/AppImages", ".appimage");
result->appimage += getNumElementsBySuffix(&baseDir, "/Applications", ".appimage");
}
}
+1
View File
@@ -37,6 +37,7 @@ typedef enum FF_A_PACKED FFPackagesFlags {
FF_PACKAGES_FLAG_SOAR_BIT = 1ULL << 30,
FF_PACKAGES_FLAG_KISS_BIT = 1ULL << 31,
FF_PACKAGES_FLAG_MOSS_BIT = 1ULL << 32,
FF_PACKAGES_FLAG_APPIMAGE_BIT = 1ULL << 33,
FF_PACKAGES_FLAG_FORCE_UNSIGNED = UINT64_MAX,
} FFPackagesFlags;
static_assert(sizeof(FFPackagesFlags) == sizeof(uint64_t), "");
+7 -1
View File
@@ -109,6 +109,7 @@ bool ffPrintPackages(FFPackagesOptions* options) {
FF_PRINT_PACKAGE_NAME(amSystem, "am")
FF_PRINT_PACKAGE_NAME(amUser, "appman")
}
FF_PRINT_PACKAGE(appimage)
FF_PRINT_PACKAGE(sorcery)
FF_PRINT_PACKAGE(lpkg)
FF_PRINT_PACKAGE(lpkgbuild)
@@ -166,6 +167,7 @@ bool ffPrintPackages(FFPackagesOptions* options) {
FF_ARG(counts.pacstall, "pacstall"),
FF_ARG(counts.mport, "mport"),
FF_ARG(counts.amUser, "am-user"),
FF_ARG(counts.appimage, "appimage"),
FF_ARG(counts.pkgsrc, "pkgsrc"),
FF_ARG(counts.hpkgSystem, "hpkg-system"),
FF_ARG(counts.hpkgUser, "hpkg-user"),
@@ -220,8 +222,9 @@ void ffParsePackagesJsonObject(FFPackagesOptions* options, yyjson_val* module) {
case 'A':
if (false)
;
FF_TEST_PACKAGE_NAME(APK)
FF_TEST_PACKAGE_NAME(AM)
FF_TEST_PACKAGE_NAME(APPIMAGE)
FF_TEST_PACKAGE_NAME(APK)
break;
case 'B':
if (false)
@@ -352,6 +355,7 @@ void ffGeneratePackagesJsonConfig(FFPackagesOptions* options, yyjson_mut_doc* do
if (false)
;
FF_TEST_PACKAGE_NAME(AM)
FF_TEST_PACKAGE_NAME(APPIMAGE)
FF_TEST_PACKAGE_NAME(APK)
FF_TEST_PACKAGE_NAME(BREW)
FF_TEST_PACKAGE_NAME(CHOCO)
@@ -407,6 +411,7 @@ bool ffGeneratePackagesJsonResult(FF_A_UNUSED FFPackagesOptions* options, yyjson
FF_APPEND_PACKAGE_COUNT(all)
FF_APPEND_PACKAGE_COUNT(amSystem)
FF_APPEND_PACKAGE_COUNT(amUser)
FF_APPEND_PACKAGE_COUNT(appimage)
FF_APPEND_PACKAGE_COUNT(apk)
FF_APPEND_PACKAGE_COUNT(brew)
FF_APPEND_PACKAGE_COUNT(brewCask)
@@ -507,6 +512,7 @@ FFModuleBaseInfo ffPackagesModuleInfo = {
{ "Number of linglong packages", "linglong" },
{ "Number of pacstall packages", "pacstall" },
{ "Number of mport packages", "mport" },
{ "Number of appimage packages", "appimage" },
{ "Number of am-user (aka appman) packages", "am-user" },
{ "Number of pkgsrc packages", "pkgsrc" },
{ "Number of hpkg-system packages", "hpkg-system" },