Skip to main content
This service is only available when DRAC_ENABLE_PACKAGECOUNT is enabled in your configuration.

Overview

The package counting service provides functionality to query and count installed packages from various system package managers. It supports multiple package managers across different platforms and uses caching to improve performance. Namespace: draconis::services::packages Header: <Drac++/Services/Packages.hpp>

Manager enum

Represents available package managers for package counting.
enum class Manager : types::u8
This enum is used as a bitmask. Individual values can be combined using the bitwise OR operator (|).

Values

ValueDescriptionPlatform
NoneNo package managerAll
CargoCargo, the Rust package managerAll
NixNix package managerLinux, macOS
Apkapk, the Alpine Linux package managerLinux
Dpkgdpkg, the Debian package system (used by APT)Linux
Mossmoss, the package manager for AerynOSLinux
PacmanPacman, the Arch Linux package managerLinux
RpmRPM package manager (Fedora, RHEL, etc.)Linux
XbpsXBPS, the X Binary Package System (Void Linux)Linux
HomebrewHomebrew package managermacOS
MacportsMacPorts package managermacOS
WingetWinget, the Windows Package ManagerWindows
ChocolateyChocolatey package managerWindows
ScoopScoop, command-line installerWindows
PkgNgpkg, package management systemFreeBSD, DragonFly BSD
PkgSrcpkgsrc package management systemNetBSD
HaikuPkghaikupkg package managerHaiku OS

Operators

operator|
constexpr auto
Combines two Manager flags using bitwise OR.
constexpr auto operator|(Manager pmA, Manager pmB) -> Manager
operator|=
constexpr auto
Combines two Manager flags using bitwise OR and assigns the result.
constexpr auto operator|=(Manager& lhs, Manager rhs) -> Manager&

Helper functions

HasPackageManager
constexpr bool
Checks if a specific Manager flag is set in a bitmask.
constexpr auto HasPackageManager(
  Manager current_flags,
  Manager flag_to_check
) -> bool
return
bool
true if the flag is set, false otherwise

PackageManagerInfo struct

Holds information needed to query a database-backed package manager.
struct PackageManagerInfo {
  types::String id;         // Unique identifier (e.g., "pacman", "dpkg")
  fs::path      dbPath;     // Filesystem path to the database
  types::String countQuery; // Query string (e.g., SQL)
}
id
types::String
Unique identifier for the package manager (used for cache key and logging)
dbPath
fs::path
Filesystem path to the database or primary directory
countQuery
types::String
Query string (e.g., SQL) or specific file/pattern if not a database

Core functions

GetTotalCount

Gets the total package count by querying all relevant package managers.
auto GetTotalCount(
  cache::CacheManager& cache,
  Manager enabledPackageManagers
) -> types::Result<types::u64>
cache
cache::CacheManager&
The CacheManager instance to use for caching
enabledPackageManagers
Manager
Bitmask of enabled package managers to query
return
types::Result<types::u64>
Result containing the total package count on success, or a DracError if aggregation fails (individual errors are logged)

GetIndividualCounts

Gets individual package counts from all enabled package managers.
auto GetIndividualCounts(
  cache::CacheManager& cache,
  Manager enabledPackageManagers
) -> types::Result<types::Map<types::String, types::u64>>
cache
cache::CacheManager&
The CacheManager instance to use for caching
enabledPackageManagers
Manager
Bitmask of enabled package managers to query
return
types::Result<types::Map<types::String, types::u64>>
Result containing a map of package manager names to their counts on success, or a DracError if all package managers fail

Query functions

GetCountFromDb

Gets package count from a database using SQLite.
auto GetCountFromDb(
  cache::CacheManager& cache,
  const types::String& pmId,
  const fs::path& dbPath,
  const types::String& countQuery
) -> types::Result<types::u64>
cache
cache::CacheManager&
The CacheManager instance to use for caching
pmId
const types::String&
Identifier for the package manager (for logging/cache)
dbPath
const fs::path&
Path to the SQLite database file
countQuery
const types::String&
SQL query to count packages (e.g., "SELECT COUNT(*) FROM packages")
return
types::Result<types::u64>
Result containing the count or a DracError

GetCountFromDirectory

Gets package count by iterating entries in a directory. Multiple overloads are available:

Full signature

auto GetCountFromDirectory(
  cache::CacheManager& cache,
  const types::String& pmId,
  const fs::path& dirPath,
  const types::String& fileExtensionFilter,
  bool subtractOne
) -> types::Result<types::u64>
cache
cache::CacheManager&
The CacheManager instance to use for caching
pmId
const types::String&
Identifier for the package manager (for logging/cache)
dirPath
const fs::path&
Path to the directory to iterate
fileExtensionFilter
const types::String&
Only count files with this extension (e.g., ".list")
subtractOne
bool
Whether to subtract one from the final count
return
types::Result<types::u64>
Result containing the count or a DracError

Simplified overloads

// With filter only (subtractOne defaults to false)
auto GetCountFromDirectory(
  cache::CacheManager& cache,
  const types::String& pmId,
  const fs::path& dirPath,
  const types::String& fileExtensionFilter
) -> types::Result<types::u64>

// With subtractOne only (no filter)
auto GetCountFromDirectory(
  cache::CacheManager& cache,
  const types::String& pmId,
  const fs::path& dirPath,
  bool subtractOne
) -> types::Result<types::u64>

// Simple directory iteration (no filter, no subtraction)
auto GetCountFromDirectory(
  cache::CacheManager& cache,
  const types::String& pmId,
  const fs::path& dirPath
) -> types::Result<types::u64>
The overload with bool subtractOne is prone to misuse due to C++‘s implicit conversion rules. A string literal can be implicitly converted to bool. Prefer explicit String construction when using the filter overload.

GetCountFromDirectoryNoCache

Gets package count by iterating entries in a directory without caching (for internal use).
auto GetCountFromDirectoryNoCache(
  const types::String& pmId,
  const fs::path& dirPath,
  const types::Option<types::String>& fileExtensionFilter,
  bool subtractOne
) -> types::Result<types::u64>
This function is for internal use to avoid nested cache calls.

GetCountFromPlist

Counts installed packages in a plist file (Linux only).
auto GetCountFromPlist(
  cache::CacheManager& cache,
  const types::String& pmId,
  const fs::path& plistPath
) -> types::Result<types::u64>
cache
cache::CacheManager&
The CacheManager instance to use for caching
pmId
const types::String&
Identifier for the package manager (for logging/cache)
plistPath
const fs::path&
Path to the plist file
return
types::Result<types::u64>
Result containing the count or a DracError

Platform-specific count functions

Each package manager has a dedicated count function:

Linux

auto CountApk(cache::CacheManager& cache) -> types::Result<types::u64>
auto CountDpkg(cache::CacheManager& cache) -> types::Result<types::u64>
auto CountMoss(cache::CacheManager& cache) -> types::Result<types::u64>
auto CountPacman(cache::CacheManager& cache) -> types::Result<types::u64>
auto CountRpm(cache::CacheManager& cache) -> types::Result<types::u64>
auto CountXbps(cache::CacheManager& cache) -> types::Result<types::u64>

macOS

auto GetHomebrewCount(cache::CacheManager& cache) -> types::Result<types::u64>
auto GetMacPortsCount(cache::CacheManager& cache) -> types::Result<types::u64>

Windows

auto CountWinGet(cache::CacheManager& cache) -> types::Result<types::u64>
auto CountChocolatey(cache::CacheManager& cache) -> types::Result<types::u64>
auto CountScoop(cache::CacheManager& cache) -> types::Result<types::u64>

BSD

// FreeBSD and DragonFly BSD
auto GetPkgNgCount(cache::CacheManager& cache) -> types::Result<types::u64>

// NetBSD
auto GetPkgSrcCount(cache::CacheManager& cache) -> types::Result<types::u64>

Haiku OS

auto GetSerenityCount(cache::CacheManager& cache) -> types::Result<types::u64>

Cross-platform

// Linux and macOS
auto CountNix(cache::CacheManager& cache) -> types::Result<types::u64>

// All platforms
auto CountCargo(cache::CacheManager& cache) -> types::Result<types::u64>

Example usage

#include <Drac++/Services/Packages.hpp>
#include <Drac++/Utils/CacheManager.hpp>

using namespace draconis::services::packages;
using namespace draconis::utils::cache;

auto main() -> int {
  CacheManager cache;
  
  // Enable multiple package managers
  Manager managers = Manager::Cargo | Manager::Pacman;
  
  // Get total count
  auto totalResult = GetTotalCount(cache, managers);
  if (totalResult) {
    std::cout << "Total packages: " << *totalResult << std::endl;
  }
  
  // Get individual counts
  auto countsResult = GetIndividualCounts(cache, managers);
  if (countsResult) {
    for (const auto& [name, count] : *countsResult) {
      std::cout << name << ": " << count << std::endl;
    }
  }
  
  return 0;
}

Build docs developers (and LLMs) love