mirror of
https://github.com/binaricat/Netcatty.git
synced 2026-11-07 08:31:00 +00:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d2a68c2df5 |
No files matched your search
@@ -142,26 +142,30 @@ export async function hasSpec(commandName: string): Promise<boolean> {
|
||||
return availableSpecsSet?.has(commandName) ?? false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Common shell commands preloaded when autocomplete is enabled.
|
||||
* Includes local overrides under electron/specs/ (e.g. yum, dnf, awk).
|
||||
*/
|
||||
export const COMMON_FIG_SPECS = [
|
||||
"git", "docker", "kubectl", "npm", "yarn", "pnpm",
|
||||
"ls", "cd", "cat", "grep", "find", "ssh", "scp",
|
||||
"curl", "wget", "tar", "zip", "unzip", "make",
|
||||
"python", "python3", "pip", "pip3", "node",
|
||||
"systemctl", "journalctl", "apt", "yum", "dnf", "brew",
|
||||
"vim", "nano", "less", "head", "tail", "sort",
|
||||
"awk", "sed", "chmod", "chown", "cp", "mv", "rm", "mkdir",
|
||||
] as const;
|
||||
|
||||
/**
|
||||
* Preload commonly used specs in batches to avoid overwhelming IPC.
|
||||
* Only call this when autocomplete is enabled.
|
||||
*/
|
||||
export function preloadCommonSpecs(): void {
|
||||
const common = [
|
||||
"git", "docker", "kubectl", "npm", "yarn", "pnpm",
|
||||
"ls", "cd", "cat", "grep", "find", "ssh", "scp",
|
||||
"curl", "wget", "tar", "zip", "unzip", "make",
|
||||
"python", "python3", "pip", "pip3", "node",
|
||||
"systemctl", "journalctl", "apt", "yum", "brew",
|
||||
"vim", "nano", "less", "head", "tail", "sort",
|
||||
"awk", "sed", "chmod", "chown", "cp", "mv", "rm", "mkdir",
|
||||
];
|
||||
|
||||
const BATCH_SIZE = 8;
|
||||
let offset = 0;
|
||||
|
||||
const loadBatch = () => {
|
||||
const batch = common.slice(offset, offset + BATCH_SIZE);
|
||||
const batch = COMMON_FIG_SPECS.slice(offset, offset + BATCH_SIZE);
|
||||
if (batch.length === 0) return;
|
||||
|
||||
for (const name of batch) {
|
||||
@@ -169,7 +173,7 @@ export function preloadCommonSpecs(): void {
|
||||
}
|
||||
|
||||
offset += BATCH_SIZE;
|
||||
if (offset < common.length) {
|
||||
if (offset < COMMON_FIG_SPECS.length) {
|
||||
if (typeof requestIdleCallback === "function") {
|
||||
requestIdleCallback(() => loadBatch());
|
||||
} else {
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
import assert from "node:assert/strict";
|
||||
import test from "node:test";
|
||||
import { COMMON_FIG_SPECS, normalizeCommandName } from "./autocomplete/figSpecLoader";
|
||||
|
||||
test("preload common specs includes dnf alongside yum and apt", () => {
|
||||
assert.ok(COMMON_FIG_SPECS.includes("apt"));
|
||||
assert.ok(COMMON_FIG_SPECS.includes("yum"));
|
||||
assert.ok(COMMON_FIG_SPECS.includes("dnf"));
|
||||
});
|
||||
|
||||
test("normalizeCommandName strips path and extension", () => {
|
||||
assert.equal(normalizeCommandName("/usr/bin/dnf"), "dnf");
|
||||
assert.equal(normalizeCommandName("DNF"), "dnf");
|
||||
});
|
||||
@@ -0,0 +1,60 @@
|
||||
const test = require("node:test");
|
||||
const assert = require("node:assert/strict");
|
||||
const path = require("node:path");
|
||||
const { pathToFileURL } = require("node:url");
|
||||
const fs = require("node:fs");
|
||||
|
||||
const dnfSpecPath = path.join(__dirname, "..", "specs", "dnf.js");
|
||||
|
||||
function resolveNames(name) {
|
||||
return Array.isArray(name) ? name : [name];
|
||||
}
|
||||
|
||||
function collectSubcommandNames(spec) {
|
||||
const names = new Set();
|
||||
for (const sub of spec.subcommands || []) {
|
||||
for (const n of resolveNames(sub.name)) names.add(n);
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
test("local dnf fig spec covers common Rocky/RHEL package-manager commands", async () => {
|
||||
assert.equal(fs.existsSync(dnfSpecPath), true, "electron/specs/dnf.js should exist");
|
||||
|
||||
const mod = await import(pathToFileURL(dnfSpecPath).href);
|
||||
const spec = mod.default?.default ?? mod.default;
|
||||
assert.ok(spec, "dnf spec should export a default completionSpec");
|
||||
assert.equal(spec.name, "dnf");
|
||||
|
||||
const names = collectSubcommandNames(spec);
|
||||
for (const required of [
|
||||
"install",
|
||||
"remove",
|
||||
"upgrade",
|
||||
"update",
|
||||
"autoremove",
|
||||
"reinstall",
|
||||
"downgrade",
|
||||
"search",
|
||||
"info",
|
||||
"list",
|
||||
"provides",
|
||||
"clean",
|
||||
"makecache",
|
||||
"repolist",
|
||||
"history",
|
||||
"group",
|
||||
"distro-sync",
|
||||
"swap",
|
||||
"module",
|
||||
]) {
|
||||
assert.equal(names.has(required), true, `missing dnf subcommand: ${required}`);
|
||||
}
|
||||
|
||||
const group = (spec.subcommands || []).find((s) => resolveNames(s.name).includes("group"));
|
||||
assert.ok(group, "group subcommand should exist");
|
||||
const groupNames = collectSubcommandNames(group);
|
||||
for (const required of ["install", "remove", "list", "info"]) {
|
||||
assert.equal(groupNames.has(required), true, `missing dnf group subcommand: ${required}`);
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,90 @@
|
||||
// dnf spec — DNF package manager (RHEL/Rocky/Alma/Fedora)
|
||||
const completionSpec = {
|
||||
name: "dnf",
|
||||
description: "DNF package manager (RHEL/Rocky/Alma/Fedora)",
|
||||
subcommands: [
|
||||
{ name: "install", description: "Install a package", args: { name: "package", isVariadic: true } },
|
||||
{ name: "remove", description: "Remove a package", args: { name: "package", isVariadic: true } },
|
||||
{ name: "upgrade", description: "Upgrade installed packages", args: { name: "package", isOptional: true, isVariadic: true } },
|
||||
{ name: "update", description: "Alias for upgrade", args: { name: "package", isOptional: true, isVariadic: true } },
|
||||
{ name: "autoremove", description: "Remove unneeded packages installed as dependencies" },
|
||||
{ name: "reinstall", description: "Reinstall a package", args: { name: "package", isVariadic: true } },
|
||||
{ name: "downgrade", description: "Downgrade a package", args: { name: "package", isVariadic: true } },
|
||||
{ name: "distro-sync", description: "Synchronize installed packages to the latest available versions", args: { name: "package", isOptional: true, isVariadic: true } },
|
||||
{ name: "swap", description: "Remove one package and install another in a single transaction", args: [
|
||||
{ name: "remove-spec" },
|
||||
{ name: "install-spec" },
|
||||
]},
|
||||
{ name: "search", description: "Search package details for the given string", args: { name: "keyword", isVariadic: true } },
|
||||
{ name: "info", description: "Display details about a package", args: { name: "package", isVariadic: true } },
|
||||
{ name: "list", description: "List packages", subcommands: [
|
||||
{ name: "installed", description: "List installed packages" },
|
||||
{ name: "available", description: "List available packages" },
|
||||
{ name: "updates", description: "List packages with updates available" },
|
||||
{ name: "obsoletes", description: "List obsoleting packages" },
|
||||
{ name: "all", description: "List all packages" },
|
||||
]},
|
||||
{ name: "provides", description: "Find which package provides a file/feature", args: { name: "feature" } },
|
||||
{ name: "clean", description: "Clean cached data", subcommands: [
|
||||
{ name: "all", description: "Clean all cached data" },
|
||||
{ name: "packages", description: "Clean cached packages" },
|
||||
{ name: "metadata", description: "Clean cached metadata" },
|
||||
{ name: "dbcache", description: "Clean cached db data" },
|
||||
{ name: "expire-cache", description: "Expire the cache" },
|
||||
]},
|
||||
{ name: "makecache", description: "Generate the metadata cache" },
|
||||
{ name: "repolist", description: "Display configured software repositories", subcommands: [
|
||||
{ name: "all", description: "List all repos" },
|
||||
{ name: "enabled", description: "List enabled repos" },
|
||||
{ name: "disabled", description: "List disabled repos" },
|
||||
]},
|
||||
{ name: "repoinfo", description: "Display repository information" },
|
||||
{ name: "history", description: "View and manage DNF transaction history", subcommands: [
|
||||
{ name: "list", description: "List transactions" },
|
||||
{ name: "info", description: "Show transaction details", args: { name: "id" } },
|
||||
{ name: "undo", description: "Undo a transaction", args: { name: "id" } },
|
||||
{ name: "redo", description: "Redo a transaction", args: { name: "id" } },
|
||||
{ name: "rollback", description: "Rollback to a previous transaction", args: { name: "id" } },
|
||||
]},
|
||||
{ name: "group", description: "Manage package groups", subcommands: [
|
||||
{ name: "install", description: "Install a package group", args: { name: "group" } },
|
||||
{ name: "remove", description: "Remove a package group", args: { name: "group" } },
|
||||
{ name: "list", description: "List available package groups" },
|
||||
{ name: "info", description: "Display details about a package group", args: { name: "group" } },
|
||||
{ name: "upgrade", description: "Upgrade a package group", args: { name: "group", isOptional: true } },
|
||||
]},
|
||||
{ name: "module", description: "Manage application stream modules", subcommands: [
|
||||
{ name: "list", description: "List modules", subcommands: [
|
||||
{ name: "all", description: "List all modules" },
|
||||
{ name: "enabled", description: "List enabled modules" },
|
||||
{ name: "disabled", description: "List disabled modules" },
|
||||
{ name: "installed", description: "List installed modules" },
|
||||
]},
|
||||
{ name: "info", description: "Show module details", args: { name: "module", isVariadic: true } },
|
||||
{ name: "install", description: "Install a module profile", args: { name: "module", isVariadic: true } },
|
||||
{ name: "remove", description: "Remove installed module profiles", args: { name: "module", isVariadic: true } },
|
||||
{ name: "enable", description: "Enable a module stream", args: { name: "module", isVariadic: true } },
|
||||
{ name: "disable", description: "Disable a module", args: { name: "module", isVariadic: true } },
|
||||
{ name: "reset", description: "Reset module state", args: { name: "module", isVariadic: true } },
|
||||
{ name: "update", description: "Update installed modules", args: { name: "module", isOptional: true, isVariadic: true } },
|
||||
]},
|
||||
{ name: "check-update", description: "Check for available package upgrades" },
|
||||
{ name: "check-upgrade", description: "Alias for check-update" },
|
||||
],
|
||||
options: [
|
||||
{ name: "-y", description: "Answer yes to all questions" },
|
||||
{ name: "-q", description: "Quiet operation" },
|
||||
{ name: "-v", description: "Verbose operation" },
|
||||
{ name: "--enablerepo", description: "Enable a repository", args: { name: "repo" } },
|
||||
{ name: "--disablerepo", description: "Disable a repository", args: { name: "repo" } },
|
||||
{ name: "--nogpgcheck", description: "Disable GPG signature checking" },
|
||||
{ name: "--skip-broken", description: "Skip packages with dependency problems" },
|
||||
{ name: "--showduplicates", description: "Show duplicate packages in repos" },
|
||||
{ name: "--installroot", description: "Set install root", args: { name: "path", template: "folders" } },
|
||||
{ name: "-C", description: "Run entirely from system cache" },
|
||||
{ name: "--security", description: "Include only security-related packages" },
|
||||
{ name: ["-h", "--help"], description: "Show help" },
|
||||
],
|
||||
};
|
||||
|
||||
export default completionSpec;
|
||||
Reference in new issue
Block a user