/****************************************************************************** __ ____ __ / / ___ ____ _/ __/_____________ _/ /__ / / / _ \/ __ `/ /_/ ___/ ___/ __ `/ / _ \ / /___/ __/ /_/ / __(__ ) /__/ /_/ / / __/ /_____/\___/\__,_/_/ /____/\___/\__,_/_/\___/ (C)opyright 2025, Leafscale, LLC - https://www.leafscale.com Project: Zygaena Filename: list.reef Authors: Chris Tusa License: Description: List installed or available packages ******************************************************************************/ module commands.list import sys.args import core.str import core.config import core.database import core.port import core.portindex import types import util.color import exitcodes as ec export fn execute(opts: types.GlobalOptions): int end export fn execute(opts: types.GlobalOptions): int let argc = args.count() // Load configuration and apply command-line overrides let base_cfg = config.load() let cfg = config.apply_overrides(base_cfg, opts.root, opts.prefix) let root_path = config.get_root(cfg) // Show root if set (verbose mode) if opts.verbose and str.length(root_path) > 0 color.print_info("Using root: " + root_path) end if // Check for --available flag if args.has_flag("available") or args.has_flag("a") list_available() return ec.EXIT_SUCCESS() end if // Default: list installed packages list_installed(root_path) return ec.EXIT_SUCCESS() end execute proc list_installed(root_path: string) mut packages: [string] = new [string](512) let pkg_count = list_installed_pkgs(packages, 512, root_path) if pkg_count == 0 color.print_info("No packages installed") return end if color.print_action("Installed packages:") println("") mut i = 0 while i < pkg_count let pkg_name = packages[i] let pkg = get_installed_pkg(pkg_name, root_path) // Format: name version print(" ") print(pkg.info.name) print(" ") print(pkg.info.version) print("-") println(int_to_str(pkg.info.release)) i = i + 1 end while println("") color.print_info("Total: " + int_to_str(pkg_count) + " packages") end list_installed // Helper functions for rooted operations fn list_installed_pkgs(names: [string], max_count: int, root_path: string): int if str.length(root_path) > 0 return database.list_installed_rooted(names, max_count, root_path) end if return database.list_installed(names, max_count) end list_installed_pkgs fn get_installed_pkg(name: string, root_path: string): types.InstalledPackage if str.length(root_path) > 0 return database.get_installed_rooted(name, root_path) end if return database.get_installed(name) end get_installed_pkg proc list_available() color.print_action("Available ports:") println("") mut total = 0 // Try ports index first (fast path) if portindex.port_index_exists() mut entries: [portindex.PortIndexEntry] = new [portindex.PortIndexEntry](4096) let entry_count = portindex.list_all_ports(entries, 4096) // Group by category for display mut current_cat = "" mut i = 0 while i < entry_count let entry = entries[i] if not str.equals(entry.category, current_cat) if str.length(current_cat) > 0 println("") end if current_cat = entry.category color.print_info(current_cat + "/") end if print(" ") print(entry.name) print(" ") print(entry.version) print(" - ") println(entry.description) total = total + 1 i = i + 1 end while else // Fall back to filesystem scan mut cats: [string] = new [string](32) let cat_count = port.get_categories(cats, 32) mut i = 0 while i < cat_count let category = cats[i] mut ports: [string] = new [string](256) let port_count = port.list_category(category, ports, 256) if port_count > 0 color.print_info(category + "/") mut j = 0 while j < port_count let port_name = ports[j] let result = port.find(port_name) if result.success let p = result.port print(" ") print(p.info.name) print(" ") print(p.info.version) print(" - ") println(p.info.description) end if j = j + 1 total = total + 1 end while println("") end if i = i + 1 end while end if println("") color.print_info("Total: " + int_to_str(total) + " ports") end list_available // Helper: convert int to string fn int_to_str(n: int): string if n == 0 return "0" end if mut negative = false mut value = n if n < 0 negative = true value = 0 - n end if mut result = "" while value > 0 let digit = value % 10 result = str.concat(str.substring("0123456789", digit, 1), result) value = value / 10 end while if negative result = str.concat("-", result) end if return result end int_to_str end module