From 456d4b37b6e6715bfd7d46637b54635f8b466d78 Mon Sep 17 00:00:00 2001 From: Iskander Gaba Date: Wed, 29 Oct 2025 00:26:41 +0100 Subject: [PATCH 1/2] Add SDKMAN! support --- src/detection/packages/packages.h | 1 + src/detection/packages/packages_linux.c | 32 +++++++++++++++++++++++++ src/modules/packages/option.h | 1 + src/modules/packages/packages.c | 6 +++++ 4 files changed, 40 insertions(+) diff --git a/src/detection/packages/packages.h b/src/detection/packages/packages.h index 7464a30c17..795181910d 100644 --- a/src/detection/packages/packages.h +++ b/src/detection/packages/packages.h @@ -40,6 +40,7 @@ typedef struct FFPackagesResult uint32_t rpm; uint32_t scoopUser; uint32_t scoopGlobal; + uint32_t sdkman; uint32_t snap; uint32_t soar; uint32_t sorcery; diff --git a/src/detection/packages/packages_linux.c b/src/detection/packages/packages_linux.c index 3d83f3a524..2c92ac4eb1 100644 --- a/src/detection/packages/packages_linux.c +++ b/src/detection/packages/packages_linux.c @@ -272,6 +272,35 @@ static uint32_t getAMUser(void) return packagesPath.length > 0 ? getAMPackages(&packagesPath) : 0; } +static uint32_t getSDKMAN(void) +{ + const char* candidatesDir = getenv("SDKMAN_CANDIDATES_DIR"); + if (!ffStrSet(candidatesDir)) + return 0; + + FF_AUTO_CLOSE_DIR DIR* dir = opendir(candidatesDir); + if (!dir) + return 0; + + uint32_t count = 0; + char path[PATH_MAX]; + struct dirent *entry; + while ((entry = readdir(dir)) != NULL) + { + if (entry->d_name[0] == '.') + continue; + + if (entry->d_type == DT_DIR || entry->d_type == DT_UNKNOWN) + { + snprintf(path, sizeof(path), "%s/%s/current", candidatesDir, entry->d_name); + if (ffPathExists(path, FF_PATHTYPE_DIRECTORY)) + ++count; + } + } + + return count; +} + static int compareHash(const void* a, const void* b) { return memcmp(a, b, 32); @@ -556,6 +585,9 @@ void ffDetectPackagesImpl(FFPackagesResult* result, FFPackagesOptions* options) if (!(options->disabled & FF_PACKAGES_FLAG_AM_BIT)) result->amUser = getAMUser(); + if (!(options->disabled & FF_PACKAGES_FLAG_SDKMAN_BIT)) + result->sdkman = getSDKMAN(); + 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"); } diff --git a/src/modules/packages/option.h b/src/modules/packages/option.h index 240ca66664..39ddff0d42 100644 --- a/src/modules/packages/option.h +++ b/src/modules/packages/option.h @@ -36,6 +36,7 @@ typedef enum __attribute__((__packed__)) FFPackagesFlags FF_PACKAGES_FLAG_HPKG_BIT = 1ULL << 28, FF_PACKAGES_FLAG_PISI_BIT = 1ULL << 29, FF_PACKAGES_FLAG_SOAR_BIT = 1ULL << 30, + FF_PACKAGES_FLAG_SDKMAN_BIT = 1ULL << 31, FF_PACKAGES_FLAG_FORCE_UNSIGNED = UINT64_MAX, } FFPackagesFlags; static_assert(sizeof(FFPackagesFlags) == sizeof(uint64_t), ""); diff --git a/src/modules/packages/packages.c b/src/modules/packages/packages.c index 1d1094ae70..79e3477a7f 100644 --- a/src/modules/packages/packages.c +++ b/src/modules/packages/packages.c @@ -146,6 +146,7 @@ bool ffPrintPackages(FFPackagesOptions* options) FF_PRINT_PACKAGE(mport) FF_PRINT_PACKAGE(pisi) FF_PRINT_PACKAGE(soar) + FF_PRINT_PACKAGE(sdkman) putchar('\n'); } @@ -194,6 +195,7 @@ bool ffPrintPackages(FFPackagesOptions* options) FF_FORMAT_ARG(counts.hpkgUser, "hpkg-user"), FF_FORMAT_ARG(counts.pisi, "pisi"), FF_FORMAT_ARG(counts.soar, "soar"), + FF_FORMAT_ARG(counts.sdkman, "sdkman"), FF_FORMAT_ARG(nixAll, "nix-all"), FF_FORMAT_ARG(flatpakAll, "flatpak-all"), FF_FORMAT_ARG(brewAll, "brew-all"), @@ -297,6 +299,7 @@ void ffParsePackagesJsonObject(FFPackagesOptions* options, yyjson_val* module) break; case 'S': if (false); FF_TEST_PACKAGE_NAME(SCOOP) + FF_TEST_PACKAGE_NAME(SDKMAN) FF_TEST_PACKAGE_NAME(SNAP) FF_TEST_PACKAGE_NAME(SOAR) FF_TEST_PACKAGE_NAME(SORCERY) @@ -362,6 +365,7 @@ void ffGeneratePackagesJsonConfig(FFPackagesOptions* options, yyjson_mut_doc* do FF_TEST_PACKAGE_NAME(PKGSRC) FF_TEST_PACKAGE_NAME(RPM) FF_TEST_PACKAGE_NAME(SCOOP) + FF_TEST_PACKAGE_NAME(SDKMAN) FF_TEST_PACKAGE_NAME(SNAP) FF_TEST_PACKAGE_NAME(SOAR) FF_TEST_PACKAGE_NAME(SORCERY) @@ -423,6 +427,7 @@ bool ffGeneratePackagesJsonResult(FF_MAYBE_UNUSED FFPackagesOptions* options, yy FF_APPEND_PACKAGE_COUNT(rpm) FF_APPEND_PACKAGE_COUNT(scoopUser) FF_APPEND_PACKAGE_COUNT(scoopGlobal) + FF_APPEND_PACKAGE_COUNT(sdkman) FF_APPEND_PACKAGE_COUNT(snap) FF_APPEND_PACKAGE_COUNT(soar) FF_APPEND_PACKAGE_COUNT(sorcery) @@ -498,6 +503,7 @@ FFModuleBaseInfo ffPackagesModuleInfo = { {"Number of hpkg-user packages", "hpkg-user"}, {"Number of pisi packages", "pisi"}, {"Number of soar packages", "soar"}, + {"Number of sdkman packages", "sdkman"}, {"Total number of all nix packages", "nix-all"}, {"Total number of all flatpak app packages", "flatpak-all"}, {"Total number of all brew packages", "brew-all"}, From 92c89b8aaac920c14fdd8cc65d836a931ed74f99 Mon Sep 17 00:00:00 2001 From: Iskander Gaba Date: Wed, 29 Oct 2025 00:49:26 +0100 Subject: [PATCH 2/2] Print the package manager's name as "sdk" instead of "sdkman" to align with the cli name --- src/modules/packages/packages.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/modules/packages/packages.c b/src/modules/packages/packages.c index 79e3477a7f..adfea1a934 100644 --- a/src/modules/packages/packages.c +++ b/src/modules/packages/packages.c @@ -146,7 +146,7 @@ bool ffPrintPackages(FFPackagesOptions* options) FF_PRINT_PACKAGE(mport) FF_PRINT_PACKAGE(pisi) FF_PRINT_PACKAGE(soar) - FF_PRINT_PACKAGE(sdkman) + FF_PRINT_PACKAGE_NAME(sdkman, "sdk") putchar('\n'); } @@ -195,7 +195,7 @@ bool ffPrintPackages(FFPackagesOptions* options) FF_FORMAT_ARG(counts.hpkgUser, "hpkg-user"), FF_FORMAT_ARG(counts.pisi, "pisi"), FF_FORMAT_ARG(counts.soar, "soar"), - FF_FORMAT_ARG(counts.sdkman, "sdkman"), + FF_FORMAT_ARG(counts.sdkman, "sdk"), FF_FORMAT_ARG(nixAll, "nix-all"), FF_FORMAT_ARG(flatpakAll, "flatpak-all"), FF_FORMAT_ARG(brewAll, "brew-all"), @@ -503,7 +503,7 @@ FFModuleBaseInfo ffPackagesModuleInfo = { {"Number of hpkg-user packages", "hpkg-user"}, {"Number of pisi packages", "pisi"}, {"Number of soar packages", "soar"}, - {"Number of sdkman packages", "sdkman"}, + {"Number of SDKMAN! SDK packages", "sdk"}, {"Total number of all nix packages", "nix-all"}, {"Total number of all flatpak app packages", "flatpak-all"}, {"Total number of all brew packages", "brew-all"},