From 9095c747854cf2a3bc50d51ca94c0d22bd319125 Mon Sep 17 00:00:00 2001 From: JGZYES Date: Sun, 30 Aug 2026 20:16:23 +0800 Subject: [PATCH] drop standalone pdm; all functionality in pmm (install local .pdm, pack, info, list, remove, self-update); remove pdm from builds/workflow --- .github/workflows/release.yml | 8 +-- Makefile | 23 +++---- README.md | 17 +++-- build.bat | 6 +- src/main.c | 108 +++++++++++++----------------- src/pdm_main.c | 122 ---------------------------------- 6 files changed, 67 insertions(+), 217 deletions(-) delete mode 100644 src/pdm_main.c diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fe364c3..66bdf57 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -6,6 +6,9 @@ on: - 'v*' workflow_dispatch: +permissions: + contents: write + jobs: build: strategy: @@ -41,10 +44,6 @@ jobs: src/main.c src/json.c src/ini.c src/pmm.c src/http.c src/repo.c src/install.c \ src/sha256.c src/sha1.c src/mirrors.c src/pdm.c - - name: Build pdm - run: | - ${{ matrix.cc }} -O2 -Wall -static -std=c11 -o out/pdm${{ matrix.ext }} \ - src/pdm_main.c src/pdm.c src/pmm.c src/sha256.c src/install.c src/http.c \ src/json.c src/ini.c src/mirrors.c src/sha1.c - name: Upload artifact @@ -60,6 +59,5 @@ jobs: with: files: | out/pmm${{ matrix.ext }} - out/pdm${{ matrix.ext }} generate_release_notes: true name: PMM ${{ github.ref_name }} diff --git a/Makefile b/Makefile index c75bb48..f911d09 100644 --- a/Makefile +++ b/Makefile @@ -2,28 +2,21 @@ CC ?= gcc CFLAGS ?= -O2 -Wall -static -Wextra -std=c11 PREFIX ?= /usr/local -CORE = src/main.c src/json.c src/ini.c src/pmm.c src/http.c src/repo.c \ - src/install.c src/sha256.c src/sha1.c src/mirrors.c src/pdm.c +SRC = src/main.c src/json.c src/ini.c src/pmm.c src/http.c src/repo.c \ + src/install.c src/sha256.c src/sha1.c src/mirrors.c src/pdm.c -all: pmm pdm +all: pmm -pmm: $(CORE) $(wildcard src/*.h) - $(CC) $(CFLAGS) -o $@ $(CORE) +pmm: $(SRC) $(wildcard src/*.h) + $(CC) $(CFLAGS) -o $@ $(SRC) -PDM_DEPS = src/pdm_main.c src/pdm.c src/pmm.c src/sha256.c src/install.c \ - src/http.c src/json.c src/ini.c src/mirrors.c src/sha1.c - -pdm: $(PDM_DEPS) $(wildcard src/*.h) - $(CC) $(CFLAGS) -o $@ $(PDM_DEPS) - -install: all +install: pmm install -m 755 pmm $(PREFIX)/bin/pmm - install -m 755 pdm $(PREFIX)/bin/pdm uninstall: - rm -f $(PREFIX)/bin/pmm $(PREFIX)/bin/pdm + rm -f $(PREFIX)/bin/pmm clean: - rm -f pmm pdm pmm.exe pdm.exe + rm -f pmm pmm.exe .PHONY: all install uninstall clean diff --git a/README.md b/README.md index 0058ce9..08921da 100644 --- a/README.md +++ b/README.md @@ -8,12 +8,12 @@ ## 构建 ```sh -make # Linux / macOS(或任何有 make 的环境),生成 pmm + pdm 两个二进制 -build.bat # Windows(只需 MinGW gcc),同样生成 pmm.exe + pdm.exe +make # Linux / macOS(或任何有 make 的环境),生成 pmm 二进制 +build.bat # Windows(只需 MinGW gcc),生成 pmm.exe make install # 安装到 /usr/local/bin(可选) ``` -产物是单文件 `pmm` / `pdm`(或 `.exe`),无 DLL/第三方库依赖。 +产物是单文件 `pmm`(或 `pmm.exe`),无 DLL/第三方库依赖。 > 重要:Windows 构建须用**静态链接**(`-static`)。否则产物会依赖 MinGW 的 > `libmcfgthread-2.dll`,在没装 MinGW 的普通 PowerShell 里会因为找不到该 DLL 而 @@ -36,7 +36,7 @@ pmm install --gitea https://git.example.com/owner/repo # Gitea/Forgejo(含 pmm install --git owner/repo --host forgejo # 强制指定主机类型 pmm mirror list / add <名> <源> / use <名> / remove <名> -pmm self-update # 从镜像安装最新版 pmm+pdm(自动识别本机 os/arch) +pmm self-update # 从镜像安装最新版 pmm(自动识别本机 os/arch) pmm list pmm help / version pmm install -pd # 安装到 D:\.pmm(可换成 -pc 回到 C 盘,-px 任意盘) @@ -69,14 +69,14 @@ SHA 实现为纯 C 内置(FIPS 180-4),无外部依赖。 ## .pdm 包格式(模拟 dpkg 的 deb) -`pdm pack ./目录` 会把目录打包成一个 `.pdm`(一个 tar 归档,含 +`pmm pack ./目录` 会把目录打包成一个 `.pdm`(一个 tar 归档,含 `control.tar.gz` / `data.tar.gz` / `sha256sums` 三个成员,与 deb 的 `control.tar`+`data.tar` 思路一致): - 目录里需有一个 `pdm-control` 文件,格式为 `KEY: value` 行: `Package` / `Version` / `Architecture` / `Description` / `Maintainer` - 其余文件全部作为文件有效载荷,安装时解包到安装根目录(`~/.pmm/root`) -- `pdm install ` / `pmm install ` 安装,`pdm remove` 卸载 +- `pmm install ` 安装,`pmm remove` 卸载 - 安装记录写入 `~/.pmm/installed/<包名>.info`,含文件清单,用于卸载 ## apt 式镜像(mirror.ini / mirror.conf) @@ -181,7 +181,7 @@ pmm install "nodejs>=24,<25" # 带空格/组合时加引号 ## 自动加入 PATH -每次成功安装后,pmm/pdm 会把 PMM 目录 **自动加入用户 PATH**(幂等,不重复): +每次成功安装后,pmm 会把 PMM 目录 **自动加入用户 PATH**(幂等,不重复): - 始终加入 `~/.pmm/bin` 与 `~/.pmm/root`; - 还会扫描 `~/.pmm/root/` 下含有可执行文件的子目录并加入,例如安装 Node.js 后 @@ -204,7 +204,7 @@ pmm install "nodejs>=24,<25" # 带空格/组合时加引号 **自动按当前系统选平台**: ```sh -pdmm install nodejs # Windows 上装 node.exe 版,Linux 上自动装 ELF 版 +pmm install nodejs # Windows 上装 node.exe 版,Linux 上自动装 ELF 版 pmm install nodejs ``` @@ -240,7 +240,6 @@ src/sha256.c/.h SHA-256(FIPS 180-4) src/sha1.c/.h SHA-1(FIPS 180-4) src/mirrors.c/.h apt 式镜像列表(priority 排序 + 下载回退) src/pdm.c/.h .pdm 打包/安装/卸载(模拟 deb) -src/pdm_main.c 独立 pdm 工具 src/install.c/.h 下载、校验与各平台安装 mirror/ 镜像站(Node.js 网页版) examples/ 配置文件示例 diff --git a/build.bat b/build.bat index b3c643b..af64449 100644 --- a/build.bat +++ b/build.bat @@ -1,8 +1,6 @@ @echo off -rem One-shot Windows build: produces pmm.exe and pdm.exe (needs MinGW gcc + curl in PATH) +rem One-shot Windows build: produces pmm.exe (needs MinGW gcc + curl in PATH) set SRC=src\main.c src\json.c src\ini.c src\pmm.c src\http.c src\repo.c src\install.c src\sha256.c src\sha1.c src\mirrors.c src\pdm.c gcc -O2 -Wall -static -Wextra -std=c11 -o pmm.exe %SRC% if errorlevel 1 (echo pmm build failed & exit /b 1) -gcc -O2 -Wall -static -Wextra -std=c11 -o pdm.exe src\pdm_main.c src\pdm.c src\pmm.c src\sha256.c src\install.c src\http.c src\json.c src\ini.c src\mirrors.c src\sha1.c -if errorlevel 1 (echo pdm build failed & exit /b 1) -echo built pmm.exe and pdm.exe +echo built pmm.exe diff --git a/src/main.c b/src/main.c index 1d11433..4b482c8 100644 --- a/src/main.c +++ b/src/main.c @@ -273,27 +273,17 @@ static int cmd_mirror(int argc, char **argv) { return 1; } -static int cmd_list(void) { - char dir[1024]; - pmm_install_dir(dir, sizeof(dir)); - printf("install dir: %s\n", dir); -#ifdef _WIN32 - char cmd[1200]; - snprintf(cmd, sizeof(cmd), "dir /b \"%s\" 2>nul", dir); -#else - char cmd[1200]; - snprintf(cmd, sizeof(cmd), "ls -1 \"%s\" 2>/dev/null", dir); -#endif - return system(cmd) == 0 ? 0 : 0; -} - static void print_help(void) { printf("ParlzPackageManger (PMM) v%s\n\n", PMM_VERSION); printf("usage:\n"); printf(" pmm install install from registry mirrors (apt-style)\n"); printf(" pmm install install a local .pdm package\n"); + printf(" pmm install [pkg2 ...] install several packages\n"); printf(" pmm pack [out.pdm] pack a folder into a .pdm\n"); - printf(" pmm pdm install|list|remove|info ... manage .pdm packages\n"); + printf(" pmm info show package control info\n"); + printf(" pmm list list installed packages\n"); + printf(" pmm remove uninstall a package\n"); + printf(" pmm self-update update pmm (auto os/arch)\n"); printf(" pmm install --git any git host, API auto-detected\n"); printf(" pmm install --github GitHub latest release\n"); printf(" pmm install --gitlab GitLab latest release\n"); @@ -349,7 +339,7 @@ int main(int argc, char **argv) { printf("pmm %s (%s) [%s]\n", PMM_VERSION, pmm_os_name(pmm_detect_os()), pmm_detect_arch()); return 0; } - if (strcmp(argv[1], "list") == 0) return cmd_list(); + if (strcmp(argv[1], "list") == 0) { pdm_list_installed(); return 0; } if (strcmp(argv[1], "mirror") == 0) return cmd_mirror(argc - 2, argv + 2); /* pmm remove (also used by the Windows "Uninstall" registration) */ if (strcmp(argv[1], "remove") == 0) { @@ -378,55 +368,57 @@ 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 | pmm install --git \n"); + fprintf(stderr, "pmm: usage: pmm install [...] | pmm install --git \n"); return 1; } - /* parse package name + optional version spec: - * pmm install nodejs==24.20.0 - * pmm install "nodejs>=24,<25" - * pmm install nodejs -v 24.20.0 / --version ">=24,<25" */ - const char *raw_pkg = NULL, *version = NULL; + /* 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; + const char *items[64]; int ni = 0; for (int i = 2; i < argc; i++) { const char *a = argv[i]; 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; } if (strncmp(a, "--version=", 10) == 0) { version = a + 10; continue; } - if (!raw_pkg && a[0] != '-') { raw_pkg = a; continue; } + if (a[0] != '-' && ni < 64) items[ni++] = a; } - if (!raw_pkg) raw_pkg = argv[2]; - /* split "nodejs>=24,<25" -> pkg="nodejs", spec=">=24,<25"; else pkg only */ - char pkg[256], spec[256]; - if (version && *version) { - strncpy(pkg, raw_pkg, sizeof(pkg) - 1); - strncpy(spec, version, sizeof(spec) - 1); - } else { - const char *ops[] = { ">=", "<=", "==", "!=", ">", "<", NULL }; - const char *pos = NULL; - for (int i = 0; ops[i]; i++) { pos = strstr(raw_pkg, ops[i]); if (pos) break; } - if (pos) { - size_t n = (size_t)(pos - raw_pkg); - if (n >= sizeof(pkg)) n = sizeof(pkg) - 1; - memcpy(pkg, raw_pkg, n); pkg[n] = '\0'; - strncpy(spec, pos, sizeof(spec) - 1); - } else { - strncpy(pkg, raw_pkg, sizeof(pkg) - 1); - spec[0] = '\0'; - } - } - pkg[sizeof(pkg) - 1] = '\0'; spec[sizeof(spec) - 1] = '\0'; - /* local .pdm file? */ - size_t la = strlen(pkg); - if (la > 4 && (strcmp(pkg + la - 4, ".pdm") == 0 || strcmp(pkg + la - 4, ".PDM") == 0)) - return pdm_install_file(pkg) == 0 ? 0 : 1; + if (ni == 0) items[ni++] = argv[2]; + PmmConfig cfg; MirrorSel mirror; load_config(&cfg); load_mirror(&cfg, &mirror); - /* apt-style: mirrors.first-wins by priority, active mirror if named */ - int rc = install_from_registry(pkg, spec[0] ? spec : NULL, mirror.name); + int ok = 0; + for (int k = 0; k < ni; k++) { + const char *raw = items[k]; + char pkg[256], spec[256]; + if (ni == 1 && version && *version) { + strncpy(pkg, raw, sizeof(pkg) - 1); pkg[sizeof(pkg)-1] = '\0'; + strncpy(spec, version, sizeof(spec) - 1); spec[sizeof(spec)-1] = '\0'; + } else { + const char *ops[] = { ">=", "<=", "==", "!=", ">", "<", NULL }; + const char *pos = NULL; + for (int i = 0; ops[i]; i++) { pos = strstr(raw, ops[i]); if (pos) break; } + if (pos) { + size_t n = (size_t)(pos - raw); + if (n >= sizeof(pkg)) n = sizeof(pkg) - 1; + memcpy(pkg, raw, n); pkg[n] = '\0'; + strncpy(spec, pos, sizeof(spec) - 1); spec[sizeof(spec)-1] = '\0'; + } else { + strncpy(pkg, raw, sizeof(pkg) - 1); pkg[sizeof(pkg)-1] = '\0'; + spec[0] = '\0'; + } + } + size_t la = strlen(pkg); + if (la > 4 && (strcmp(pkg + la - 4, ".pdm") == 0 || strcmp(pkg + la - 4, ".PDM") == 0)) { + if (pdm_install_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); free(mirror.name); free(mirror.api_base); - return rc == 0 ? 0 : 1; + return ok == ni ? 0 : 1; } if (strcmp(argv[1], "pack") == 0) { @@ -437,17 +429,9 @@ int main(int argc, char **argv) { return pdm_pack(argv[2], argc >= 4 ? argv[3] : NULL) == 0 ? 0 : 1; } - if (strcmp(argv[1], "pdm") == 0) { - /* pmm pdm install/list/remove/info (sugar for the standalone pdm tool) */ - if (argc >= 3 && strcmp(argv[2], "install") == 0) - return pdm_install_file(argc >= 4 ? argv[3] : NULL) == 0 ? 0 : 1; - if (argc >= 3 && strcmp(argv[2], "list") == 0) { pdm_list_installed(); return 0; } - if (argc >= 3 && strcmp(argv[2], "remove") == 0) - return pdm_remove(argc >= 4 ? argv[3] : NULL) == 0 ? 0 : 1; - if (argc >= 3 && strcmp(argv[2], "info") == 0) - return pdm_info(argc >= 4 ? argv[3] : NULL) == 0 ? 0 : 1; - fprintf(stderr, "pmm: usage: pmm pdm install|list|remove|info ...\n"); - return 1; + if (strcmp(argv[1], "info") == 0) { + if (argc < 3) { fprintf(stderr, "pmm: usage: pmm info \n"); return 1; } + return pdm_info(argv[2]) == 0 ? 0 : 1; } fprintf(stderr, "pmm: unknown command '%s' (try 'pmm help')\n", argv[1]); diff --git a/src/pdm_main.c b/src/pdm_main.c deleted file mode 100644 index ef8e6a8..0000000 --- a/src/pdm_main.c +++ /dev/null @@ -1,122 +0,0 @@ -/* pdm_main.c - standalone `pdm` tool (pack/install/remove/info/list) - * - * usage: - * pdm pack [output.pdm] pack a folder (with pdm-control) into .pdm - * pdm install install local .pdm - * pdm info show package control info - * pdm list list installed packages - * pdm remove remove installed package - */ -#include -#include -#include -#include "pdm.h" -#include "pmm.h" -#include "install.h" - -static void usage(void) { - printf("pdm - Parlz .pdm package tool\n\n" - "usage:\n" - " pdm pack [output.pdm] pack folder (needs pdm-control) into .pdm\n" - " pdm install install local .pdm\n" - " pdm install [-v ] install from registry (pmm mirror)\n" - " pdm info show control info\n" - " pdm list list installed packages\n" - " pdm remove remove installed package\n" - "options: -p install under :\\.pdm (e.g. -pd -> D:\\.pdm)\n"); -} - -/* Parse "-p" / "-p " and compact argv; records the drive so - * pdm installs under :\.pmm. */ -static int consume_drive_flag(int argc, char **argv) { - int w = 1; - for (int r = 1; r < argc; r++) { - const char *a = argv[r]; - if (a[0] == '-' && a[1] == 'p' && (a[2] >= 'A' && a[2] <= 'Z' || a[2] >= 'a' && a[2] <= 'z')) { - char dr[2] = { a[2], '\0' }; - pmm_set_install_drive(dr); - continue; - } - if (strcmp(a, "-p") == 0 && r + 1 < argc) { - const char *nxt = argv[r + 1]; - if (nxt[0] && (nxt[0] >= 'A' && nxt[0] <= 'Z' || nxt[0] >= 'a' && nxt[0] <= 'z') && nxt[1] == '\0') { - char dr[2] = { nxt[0], '\0' }; - pmm_set_install_drive(dr); - r++; - continue; - } - } - argv[w++] = argv[r]; - } - return w; -} - -int main(int argc, char **argv) { - if (argc < 2) { usage(); return 0; } - pmm_set_self_path(argv[0]); - argc = consume_drive_flag(argc, argv); - if (argc < 2) { usage(); return 0; } - /* version: pdm -v / --version */ - if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-v") == 0) { - printf("pdm %s (%s) [%s]\n", PMM_VERSION, pmm_os_name(pmm_detect_os()), pmm_detect_arch()); - return 0; - } - /* self-update: install the latest pmm tool package (contains pmm + pdm) */ - if (strcmp(argv[1], "update") == 0 || strcmp(argv[1], "self-update") == 0) { - printf("pdm: updating pmm+pdm for %s/%s\n", pmm_os_name(pmm_detect_os()), pmm_detect_arch()); - int rc = install_from_registry("pmm", NULL, NULL); - if (rc == 0) - printf("pdm: updated. New tools are under %s/root/bin\n", - pmm_config_dir((char[1024]){0}, 1024)); - return rc == 0 ? 0 : 1; - } - if (strcmp(argv[1], "pack") == 0) { - if (argc < 3) { fprintf(stderr, "pdm: usage: pdm pack [output.pdm]\n"); return 1; } - return pdm_pack(argv[2], argc >= 4 ? argv[3] : NULL) == 0 ? 0 : 1; - } - if (strcmp(argv[1], "install") == 0 || strcmp(argv[1], "-i") == 0) { - if (argc < 3) { fprintf(stderr, "pdm: usage: pdm install [-v ver]\n"); return 1; } - /* parse [pkg] [ -v ] ; pkg may be "nodejs==24.20.0" / "nodejs>=24,<25" */ - const char *raw = NULL, *version = NULL; - for (int i = 2; i < argc; i++) { - const char *a = argv[i]; - 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; } - if (strncmp(a, "--version=", 10) == 0) { version = a + 10; continue; } - if (!raw && a[0] != '-') { raw = a; continue; } - } - if (!raw) raw = argv[2]; - char pkg[256], spec[256]; - if (version && *version) { - strncpy(pkg, raw, sizeof(pkg) - 1); - strncpy(spec, version, sizeof(spec) - 1); - } else { - const char *ops[] = { ">=", "<=", "==", "!=", ">", "<", NULL }; - const char *pos = NULL; - for (int i = 0; ops[i]; i++) { pos = strstr(raw, ops[i]); if (pos) break; } - if (pos) { size_t n = (size_t)(pos - raw); if (n >= sizeof(pkg)) n = sizeof(pkg) - 1; memcpy(pkg, raw, n); pkg[n] = '\0'; strncpy(spec, pos, sizeof(spec) - 1); } - else { strncpy(pkg, raw, sizeof(pkg) - 1); spec[0] = '\0'; } - } - pkg[sizeof(pkg) - 1] = '\0'; spec[sizeof(spec) - 1] = '\0'; - size_t l = strlen(pkg); - if (l > 4 && (strcmp(pkg + l - 4, ".pdm") == 0 || strcmp(pkg + l - 4, ".PDM") == 0)) - return pdm_install_file(pkg) == 0 ? 0 : 1; - /* otherwise treat as a registry package name */ - return install_from_registry(pkg, spec[0] ? spec : NULL, NULL) == 0 ? 0 : 1; - } - if (strcmp(argv[1], "info") == 0) { - if (argc < 3) { fprintf(stderr, "pdm: usage: pdm info \n"); return 1; } - return pdm_info(argv[2]) == 0 ? 0 : 1; - } - if (strcmp(argv[1], "list") == 0 || strcmp(argv[1], "-l") == 0) { - pdm_list_installed(); - return 0; - } - if (strcmp(argv[1], "remove") == 0 || strcmp(argv[1], "-r") == 0) { - if (argc < 3) { fprintf(stderr, "pdm: usage: pdm remove \n"); return 1; } - return pdm_remove(argv[2]) == 0 ? 0 : 1; - } - usage(); - return 1; -}