镜像自地址
https://github.com/JGZYES/ParlzPackageManger.git
已同步 2026-09-11 08:52:45 +08:00
install: add -dpkg (Linux deb) and -msi (Windows msi) local installs; split install_path dispatch + install_local_file
这个提交包含在:
+25
-6
@@ -151,8 +151,7 @@ static int native_binary_ok(const char *path, PmmOS os) {
|
||||
}
|
||||
|
||||
int install_file(const char *url, const char *name) {
|
||||
PmmOS os = pmm_detect_os();
|
||||
char cache[1024], path[1200], cmd[2600];
|
||||
char cache[1024], path[1200];
|
||||
pmm_cache_dir(cache, sizeof(cache));
|
||||
snprintf(path, sizeof(path), "%s/%s", cache, name);
|
||||
|
||||
@@ -189,6 +188,17 @@ int install_file(const char *url, const char *name) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return install_path(path, name);
|
||||
}
|
||||
|
||||
/* Install an already-local file path by its extension. Shared by downloads
|
||||
* (install_file) and local `pmm install -dpkg/-msi <file>` / `install file.deb`.
|
||||
* Returns 0 on success. */
|
||||
static int install_path(const char *path, const char *name) {
|
||||
PmmOS os = pmm_detect_os();
|
||||
char dest[1024];
|
||||
pmm_install_dir(dest, sizeof(dest));
|
||||
|
||||
const char *bname = base_name(name);
|
||||
/* A bare binary (no extension) must really be a native executable for this
|
||||
* OS; otherwise refuse so the caller can fall back to the os-named asset. */
|
||||
@@ -197,18 +207,16 @@ int install_file(const char *url, const char *name) {
|
||||
if (!native_binary_ok(path, os)) {
|
||||
fprintf(stderr, "pmm: %s is not a usable %s binary; will fall back\n",
|
||||
bname, pmm_os_name(os));
|
||||
remove(path);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
char dest[1024];
|
||||
pmm_install_dir(dest, sizeof(dest));
|
||||
|
||||
/* forward-slash clone of the cached path (native exes/tools accept it and the
|
||||
/* forward-slash clone of the path (native exes/tools accept it and the
|
||||
* git-bash shell won't mangle a command word like "C:/...") */
|
||||
char pwin[1200];
|
||||
snprintf(pwin, sizeof(pwin), "%s", path);
|
||||
for (char *q = pwin; *q; q++) if (*q == '\\') *q = '/';
|
||||
char cmd[2600];
|
||||
|
||||
/* .pdm packages are installed through the deb-like manager */
|
||||
if (has_suffix(bname, ".pdm") || has_suffix(bname, ".PDM")) {
|
||||
@@ -276,6 +284,17 @@ int install_file(const char *url, const char *name) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Install a local file by its extension — e.g. `pmm install -dpkg foo.deb`
|
||||
* (Linux) or `pmm install -msi foo.msi` (Windows). Returns 0 on success. */
|
||||
int install_local_file(const char *path) {
|
||||
if (!path || !*path) { fprintf(stderr, "pmm: empty file path\n"); return -1; }
|
||||
FILE *chk = fopen(path, "rb");
|
||||
if (!chk) { fprintf(stderr, "pmm: cannot open file: %s\n", path); return -1; }
|
||||
fclose(chk);
|
||||
printf("pmm: installing local file %s\n", path);
|
||||
return install_path(path, path);
|
||||
}
|
||||
|
||||
/* ---------- python-style version selection (==,>=,<=,>,<,!= , comma list) ---------- */
|
||||
|
||||
/* Compare dotted version strings numerically ("24.20.0" vs "24.2.0"). */
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
* name is the asset file name used to decide the install method. */
|
||||
int install_file(const char *url, const char *name);
|
||||
|
||||
/* Install a local file path according to its extension — e.g.
|
||||
* `pmm install -dpkg foo.deb` (Linux) or `pmm install -msi foo.msi` (Windows). */
|
||||
int install_local_file(const char *path);
|
||||
|
||||
/* Install from a remote registry (apt-style multi-mirror fallback):
|
||||
* looks up package `name` in the configured registry mirrors by priority.
|
||||
* If `version` is non-NULL, fetches {registry}/{name}/{version}.json, otherwise
|
||||
|
||||
+27
-1
@@ -138,6 +138,19 @@ static PmmHost host_from_name(const char *h) {
|
||||
return HOST_UNKNOWN;
|
||||
}
|
||||
|
||||
/* True if the filename has a known auto-installable extension (local packages). */
|
||||
static int has_installer_ext(const char *s) {
|
||||
static const char *exts[] = { ".deb", ".rpm", ".appimage", ".msi", ".exe", ".zip",
|
||||
".tgz", ".tar.gz", ".tar.xz", ".tar.bz2", ".7z",
|
||||
".dmg", ".pkg", ".pkg.tar.zst", NULL };
|
||||
size_t l = strlen(s);
|
||||
for (int i = 0; exts[i]; i++) {
|
||||
size_t el = strlen(exts[i]);
|
||||
if (l >= el && strcmp(s + l - el, exts[i]) == 0) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* <flag> <repo-ish> [--host <name>] */
|
||||
static int cmd_install_git(int argc, char **argv, const char *flag) {
|
||||
const char *repo = NULL;
|
||||
@@ -397,15 +410,21 @@ int main(int argc, char **argv) {
|
||||
strcmp(argv[2], "--forgejo") == 0))
|
||||
return cmd_install_git(argc - 3, argv + 3, argv[2] + 2);
|
||||
if (argc < 3) {
|
||||
fprintf(stderr, "pmm: usage: pmm install <pkg|file.pdm> [...] | pmm install --git <repo>\n");
|
||||
fprintf(stderr, "pmm: usage: pmm install <pkg|file.deb|file.msi|file.pdm> [pkg2 ...]\n"
|
||||
" | pmm install -dpkg <x.deb> install a .deb (Linux)\n"
|
||||
" | pmm install -msi <x.msi> install an .msi (Windows)\n"
|
||||
" | pmm install --git <repo>\n");
|
||||
return 1;
|
||||
}
|
||||
/* collect one or more package arguments (each may carry an inline version
|
||||
* spec like nodejs>=24,<25); optional -v/--version applies to a single one */
|
||||
const char *version = NULL;
|
||||
int forced = 0; /* 1 = -dpkg, 2 = -msi (install a local package by type) */
|
||||
const char *items[64]; int ni = 0;
|
||||
for (int i = 2; i < argc; i++) {
|
||||
const char *a = argv[i];
|
||||
if (strcmp(a, "-dpkg") == 0) { forced = 1; if (i + 1 < argc) items[ni++] = argv[++i]; continue; }
|
||||
if (strcmp(a, "-msi") == 0) { forced = 2; if (i + 1 < argc) items[ni++] = argv[++i]; continue; }
|
||||
if (strncmp(a, "-v", 2) == 0 && a[2]) { version = a + 2; continue; }
|
||||
if (strcmp(a, "-v") == 0 && i + 1 < argc) { version = argv[++i]; continue; }
|
||||
if (strcmp(a, "--version") == 0 && i + 1 < argc) { version = argv[++i]; continue; }
|
||||
@@ -443,6 +462,13 @@ int main(int argc, char **argv) {
|
||||
if (pdm_install_file(pkg) == 0) ok++; else fprintf(stderr, "pmm: failed to install %s\n", pkg);
|
||||
continue;
|
||||
}
|
||||
/* local file install: forced -dpkg/-msi, or an existing installer file
|
||||
* (e.g. `pmm install foo.deb` / `pmm install foo.msi`) */
|
||||
if (forced == 1 || forced == 2 || has_installer_ext(pkg)) {
|
||||
if (install_local_file(pkg) == 0) ok++;
|
||||
else fprintf(stderr, "pmm: failed to install %s\n", pkg);
|
||||
continue;
|
||||
}
|
||||
if (install_from_registry(pkg, spec[0] ? spec : NULL, mirror.name) == 0) ok++;
|
||||
}
|
||||
free(cfg.registry_url); free(cfg.mirror_name);
|
||||
|
||||
在新工单中引用
屏蔽一个用户