From 4091c6791aa24f807a3bfc64ecd5735c10f6f475 Mon Sep 17 00:00:00 2001 From: JGZYES Date: Sun, 6 Sep 2026 18:01:41 +0800 Subject: [PATCH] =?UTF-8?q?release:=20PMM=20v0.6.0=20+=20ppdm=20v0.0.2=20?= =?UTF-8?q?=E2=80=94=20=E7=AB=99=E7=82=B9=E7=89=88=E6=9C=AC/=E6=96=87?= =?UTF-8?q?=E6=A1=A3/CI=20=E7=89=88=E6=9C=AC=E6=8F=90=E5=8D=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - pmm 0.6.0: 结构化错误码(见前), 站点 PMM_VERSION + install.sh 版本 + 文档版本 - ppdm 0.0.2: 新增 list/del 命令(客户端) + web/ppdm/list.php/del.php 后端 - CI: ppdm 构建版本 0.0.1 -> 0.0.2 - docs: ppdm.md 加 list/del, download/install 文档 0.5.6 -> 0.6.0 - CHANGELOG 0.6.0 增 ppdm 0.0.2 全量发布说明 --- .github/workflows/release.yml | 4 +-- CHANGELOG/0.6.0.md | 9 ++++- src/ppdm.c | 37 ++++++++++++++++++- web/_common.php | 2 +- web/docs/md/download.md | 14 ++++---- web/docs/md/install.md | 8 ++--- web/docs/md/ppdm.md | 20 +++++++++-- web/install.sh | 2 +- web/ppdm/del.php | 68 +++++++++++++++++++++++++++++++++++ web/ppdm/list.php | 29 +++++++++++++++ 10 files changed, 173 insertions(+), 20 deletions(-) create mode 100644 web/ppdm/del.php create mode 100644 web/ppdm/list.php diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index baf9c67..71fe779 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -59,8 +59,8 @@ jobs: ${{ matrix.cc }} -O2 -Wall -static -std=c11 -D_GNU_SOURCE -D_FORTIFY_SOURCE=0 -U_FORTIFY_SOURCE -DPMM_VERSION=\"$VER\" -o out/${{ matrix.bin }} \ 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/out.c src/i18n.c - # -- ppdm package dev tool (register/login/update/pack/publish) — own version 0.0.1 - ${{ matrix.cc }} -O2 -Wall -static -std=c11 -D_GNU_SOURCE -D_FORTIFY_SOURCE=0 -U_FORTIFY_SOURCE -DPPDM_VERSION=\"0.0.1\" -o out/${{ matrix.ppdm }} \ + # -- ppdm package dev tool (register/login/list/del/update/pack/publish) — own version 0.0.2 + ${{ matrix.cc }} -O2 -Wall -static -std=c11 -D_GNU_SOURCE -D_FORTIFY_SOURCE=0 -U_FORTIFY_SOURCE -DPPDM_VERSION=\"0.0.2\" -o out/${{ matrix.ppdm }} \ src/ppdm.c src/pmm.c src/json.c src/ini.c src/http.c src/repo.c src/install.c \ src/sha256.c src/sha1.c src/mirrors.c src/pdm.c src/out.c src/i18n.c diff --git a/CHANGELOG/0.6.0.md b/CHANGELOG/0.6.0.md index 0946b40..f0da08f 100644 --- a/CHANGELOG/0.6.0.md +++ b/CHANGELOG/0.6.0.md @@ -24,4 +24,11 @@ ## 说明 - 兼容性:错误码在 0.6.0 起稳定;旧脚本若匹配 `[PMM]:[ERROR]:` 前缀,建议改用 `[PMM]:[E]:`(`` 为两位数字错误码)。 -- `ppdm` 仍为独立版本 `0.0.1`,本次同步接入错误码格式。 + +## 同步:ppdm v0.0.2 +- **新增 `ppdm list`**:列出当前账号已发布的包(`name@version os/arch + url`)。 +- **新增 `ppdm del [version]`**:删除自己已发布的包,可只删某个版本。 +- **后端新增 `web/ppdm/list.php`、`web/ppdm/del.php`**(按 `owner` 鉴权,他人包拒绝)。 +- **ppdm 0.0.2 全量发布**:像 pmm 一样打 `.pdm` 进镜像(`dists/`+`files/`), + 可用 `pmm install ppdm` 安装;`install-ppdm.sh` 与 GitHub Release 资产同时更新。 +- ppdm 版本从 `0.0.1` 升到 `0.0.2`(独立于 PMM 0.6.0)。 diff --git a/src/ppdm.c b/src/ppdm.c index e68c2a9..02b3af7 100644 --- a/src/ppdm.c +++ b/src/ppdm.c @@ -22,7 +22,7 @@ #include #ifndef PPDM_VERSION -#define PPDM_VERSION "0.0.1" /* ppdm has its own version, independent of PMM */ +#define PPDM_VERSION "0.0.2" /* ppdm has its own version, independent of PMM */ #endif #ifdef _WIN32 @@ -206,6 +206,8 @@ static void usage(void) { " ppdm logout 撤销并清除本地 token\n" " ppdm whoami 当前登录邮箱 + 服务器\n" " ppdm pack [out] 把 打包成 .pdm(需含 pdm-control)\n" + " ppdm list 列出当前账号已发布的包\n" + " ppdm del [version] 删除自己已发布的包(可只删某版本)\n" " ppdm update 更新 ppdm 自身\n" " ppdm ./xxxx.pdm 发布包(自动生成 json)\n" " ppdm help | -h 帮助\n\n" @@ -310,6 +312,39 @@ int main(int argc, char **argv) { return pdm_pack(argv[2], argc >= 4 ? argv[3] : NULL) == 0 ? 0 : 1; } + /* ---- list : packages owned by the current account ---- */ + if (strcmp(argv[1], "list") == 0) { + if (!g_token[0]) { pmm_error_c(PMM_E_USAGE, "请先执行 ppdm login", "请先 ppdm login\n"); return 1; } + snprintf(url, sizeof(url), "%s/list.php", g_server); + snprintf(auth, sizeof(auth), "-H 'Authorization: Bearer %s'", g_token); + http_post(url, auth, "{}", NULL, resp, sizeof(resp)); + if (js_ok(resp)) { + char list[8192]; + js_val(resp, "list", list, sizeof(list)); + if (list[0]) printf("当前账号已发布的包:\n%s\n", list); + else pmm_info("当前账号还没有发布任何包\n"); + } else js_err_print(resp); + return js_ok(resp) ? 0 : 1; + } + + /* ---- del [version] : remove a package you own ---- */ + if (strcmp(argv[1], "del") == 0 || strcmp(argv[1], "rm") == 0) { + if (argc < 3) { pmm_error_c(PMM_E_USAGE, "用法: ppdm del <包名> [版本]", "用法: ppdm del [version]\n"); return 1; } + if (!g_token[0]) { pmm_error_c(PMM_E_USAGE, "请先执行 ppdm login", "请先 ppdm login\n"); return 1; } + char q[2300]; + if (argc >= 4) snprintf(q, sizeof(q), "%s/del.php?name=%s&version=%s", g_server, argv[2], argv[3]); + else snprintf(q, sizeof(q), "%s/del.php?name=%s", g_server, argv[2]); + snprintf(auth, sizeof(auth), "-H 'Authorization: Bearer %s'", g_token); + http_post(q, auth, "{}", NULL, resp, sizeof(resp)); + if (js_ok(resp)) { + char removed[256] = ""; + js_val(resp, "removed", removed, sizeof(removed)); + if (argc >= 4) pmm_success("已删除 %s 的版本 %s\n", argv[2], argv[3]); + else pmm_success("已删除包 %s\n", argv[2]); + } else js_err_print(resp); + return js_ok(resp) ? 0 : 1; + } + /* ---- update : download the latest ppdm and install it under ~/.ppdm/bin/ppdm ---- */ if (strcmp(argv[1], "update") == 0) { char dir[1024], bin[1400], tmp[1500]; diff --git a/web/_common.php b/web/_common.php index 5ffad96..a908f33 100644 --- a/web/_common.php +++ b/web/_common.php @@ -4,7 +4,7 @@ * then pmm_header($active,$title); ... pmm_footer(); */ if (!defined('PMM_SITE')) { http_response_code(403); exit('forbidden'); } -define('PMM_VERSION', '0.5.6'); +define('PMM_VERSION', '0.6.0'); function pmm_nav_links(string $active): string { $items = [ diff --git a/web/docs/md/download.md b/web/docs/md/download.md index 4c06235..7ceb179 100644 --- a/web/docs/md/download.md +++ b/web/docs/md/download.md @@ -10,22 +10,22 @@ curl -sSL https://pmm.parlz.com/download/install.sh | bash ## 各平台产物(`/download/`) -- [pmm-0.5.6-windows-amd64.zip](/download/pmm-0.5.6-windows-amd64.zip) — Windows 免安装 -- [pmm_0.5.6_amd64.deb](/download/pmm_0.5.6_amd64.deb) — Debian/Ubuntu -- [pmm-0.5.6.x86_64.rpm](/download/pmm-0.5.6.x86_64.rpm) — CentOS/RHEL -- [pmm-0.5.6.apk](/download/pmm-0.5.6.apk) — Alpine -- [pmm-0.5.6.pkg.tar.zst](/download/pmm-0.5.6.pkg.tar.zst) — Arch +- [pmm-0.6.0-windows-amd64.zip](/download/pmm-0.6.0-windows-amd64.zip) — Windows 免安装 +- [pmm_0.6.0_amd64.deb](/download/pmm_0.6.0_amd64.deb) — Debian/Ubuntu +- [pmm-0.6.0.x86_64.rpm](/download/pmm-0.6.0.x86_64.rpm) — CentOS/RHEL +- [pmm-0.6.0.apk](/download/pmm-0.6.0.apk) — Alpine +- [pmm-0.6.0.pkg.tar.zst](/download/pmm-0.6.0.pkg.tar.zst) — Arch - [pmm](/download/pmm) — Linux 二进制 - [pmm.exe](/download/pmm.exe) — Windows 二进制 - [install.sh](/download/install.sh) — 一键安装脚本 - [install-ppdm.sh](/download/install-ppdm.sh) — ppdm 开发者工具一键安装脚本 -> `.pdm` 包走镜像注册表:`pmm install pmm==0.5.6`(见 [镜像源](index.php?page=mirror))。 +> `.pdm` 包走镜像注册表:`pmm install pmm==0.6.0`(见 [镜像源](index.php?page=mirror))。 ## 用 pmm 安装(从镜像注册表) ```bash -pmm install pmm==0.5.6 +pmm install pmm==0.6.0 pmm install nodejs ``` diff --git a/web/docs/md/install.md b/web/docs/md/install.md index e7acd27..b2ad20c 100644 --- a/web/docs/md/install.md +++ b/web/docs/md/install.md @@ -14,7 +14,7 @@ curl -sSL https://pmm.parlz.com/download/install.sh | bash ```bash # PowerShell -Invoke-WebRequest https://pmm.parlz.com/download/pmm-0.5.6-windows-amd64.zip -OutFile pmm.zip +Invoke-WebRequest https://pmm.parlz.com/download/pmm-0.6.0-windows-amd64.zip -OutFile pmm.zip Expand-Archive pmm.zip -DestinationPath pmm ``` @@ -23,21 +23,21 @@ Expand-Archive pmm.zip -DestinationPath pmm ## Debian / Ubuntu(.deb) ```bash -curl -L -o pmm.deb https://pmm.parlz.com/download/pmm_0.5.6_amd64.deb +curl -L -o pmm.deb https://pmm.parlz.com/download/pmm_0.6.0_amd64.deb sudo apt install ./pmm.deb ``` ## CentOS / RHEL(.rpm) ```bash -curl -L -o pmm.rpm https://pmm.parlz.com/download/pmm-0.5.6.x86_64.rpm +curl -L -o pmm.rpm https://pmm.parlz.com/download/pmm-0.6.0.x86_64.rpm sudo rpm -Uvh pmm.rpm ``` ## 用 pmm 安装 pmm 自身 ```bash -pmm install pmm==0.5.6 +pmm install pmm==0.6.0 ``` ## 装好后 diff --git a/web/docs/md/ppdm.md b/web/docs/md/ppdm.md index 3d80220..f6c7079 100644 --- a/web/docs/md/ppdm.md +++ b/web/docs/md/ppdm.md @@ -3,7 +3,7 @@ `ppdm`(ParlzPackageDevManager)是 PMM 生态里的**开发者工具**:把软件打包成 `.pdm` 并发布到镜像注册表。 它与 `pmm`(安装/使用包)分开,负责“做包、发包”。 -- 版本:独立版本号(当前 `0.0.1`),不受 PMM 主版本影响。 +- 版本:独立版本号(当前 `0.0.2`),不受 PMM 主版本影响。 - 服务端:`https://pmm.parlz.com/ppdm`(PHP,对应仓库 `web/ppdm/`)。 - 配置:`~/.ppdm/config`(Linux)或 `D:\.ppdm\config`(Windows)。 @@ -14,7 +14,7 @@ ```bash curl -sSL https://pmm.parlz.com/download/install-ppdm.sh | bash hash -r -ppdm -v # ppdm 0.0.1 +ppdm -v # ppdm 0.0.2 ``` 脚本会自动下载最新 `ppdm` 装到 `~/.ppdm/bin/ppdm`(与 `ppdm update` 同一路径),并把 `~/.ppdm/bin` 加进 PATH。 @@ -34,7 +34,7 @@ ppdm update 验证: ```bash -ppdm -v # ppdm 0.0.1 +ppdm -v # ppdm 0.0.2 ppdm help ``` @@ -47,6 +47,8 @@ ppdm help | `ppdm logout` | 撤销并清除 token | | `ppdm whoami` | 显示当前邮箱 + 服务器 | | `ppdm pack [out]` | 把 `dir` 打包成 `.pdm`(`dir` 内需有 `pdm-control`) | +| `ppdm list` | 列出当前账号已发布的包 | +| `ppdm del [version]` | 删除自己已发布的包(可只删某版本) | | `ppdm update` | 更新 ppdm 自身 | | `ppdm ./xxx.pdm` | 发布包(自动生成 json) | | `ppdm help` | 帮助 | @@ -113,6 +115,18 @@ ppdm ./myapp_1.0.0.pdm - 同版本重复上传 → 409; - 别人改你的包 → 409(阻止越权)。 +#### 管理自己发布的包(`ppdm list` / `ppdm del`) + +```bash +ppdm list # 列出当前账号已发布的所有包(name@version os/arch + url) +ppdm del myapp # 删除整个包(所有版本) +ppdm del myapp 1.0.0 # 只删除某一个版本(其它版本保留) +``` + +- `list` 需要先 `ppdm login`;只返回**当前账号作为 owner** 的包。 +- `del` 只能删自己创建的包;他人包会返回 `you are not the owner`。 +- 删整包时,`dists/.json`、`dists//.json` 与 `files/<首字母>//*.pdm` 一并移除。 + ## 4. 用 pmm 安装刚发布的包 ```bash diff --git a/web/install.sh b/web/install.sh index 4c9ebed..82cc785 100644 --- a/web/install.sh +++ b/web/install.sh @@ -8,7 +8,7 @@ # 下载官方 release 二进制并安装到 ~/.pmm/root/bin/pmm(与 `pmm install pmm` 自升级同一路径, # 避免 install.sh 与 pmm self-update 两处安装“串”)。 set -e -VER="0.5.6" +VER="0.6.0" REPO="JGZYES/ParlzPackageManger" # ---- 检测平台 ---- diff --git a/web/ppdm/del.php b/web/ppdm/del.php new file mode 100644 index 0000000..9778f11 --- /dev/null +++ b/web/ppdm/del.php @@ -0,0 +1,68 @@ +[&version=] ver optional: omit to remove the whole package. + * Returns {"ok":true,...} on success. A non-owner or unknown package is rejected. */ +define('PMM_SITE', 1); +require __DIR__ . '/lib.php'; + +[$tok, $email] = pmu_require_auth_token(); + +$name = trim((string)($_GET['name'] ?? ($_POST['name'] ?? ''))); +$ver = trim((string)($_GET['version'] ?? ($_POST['version'] ?? ''))); +if (!preg_match('/^[A-Za-z0-9][A-Za-z0-9._-]*$/', $name)) pmu_fail('invalid package name'); +if ($ver !== '' && !preg_match('/^[A-Za-z0-9][A-Za-z0-9._-]*$/', $ver)) pmu_fail('invalid version'); + +$regDir = __DIR__ . '/../mirror/dists'; +$filesRoot = __DIR__ . '/../mirror/files'; +$pkgJson = $regDir . '/' . $name . '.json'; + +if (!is_file($pkgJson)) pmu_fail("package '$name' not found", 404); +$m = json_decode(file_get_contents($pkgJson), true) ?: null; +if (($m['owner'] ?? '') !== $email) pmu_fail("you are not the owner of '$name'", 403); + +$letter = strtolower(substr($name, 0, 1)); +$pkgDir = $filesRoot . '/' . $letter . '/' . $name; + +/* delete just one version */ +if ($ver !== '') { + $new = []; $removed = 0; + foreach (($m['variants'] ?? []) as $v) { + if (($v['version'] ?? '') === $ver) { + if (is_file($pkgDir . '/' . ($v['file'] ?? ''))) @unlink($pkgDir . '/' . $v['file']); + $removed++; + } else { + $new[] = $v; + } + } + if (!$removed) pmu_fail("version '$ver' not found in '$name'", 404); + $m['variants'] = $new; + if (!empty($new)) { + file_put_contents($pkgJson, json_encode($m, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); + } else { + /* last version gone -> drop the whole package below */ + if (is_file($pkgJson)) @unlink($pkgJson); + } + @unlink($regDir . '/' . $name . '/' . $ver . '.json'); + if (empty($new)) { + $vd = $regDir . '/' . $name; + if (is_dir($vd)) { foreach (glob($vd . '/*') as $f) @unlink($f); @rmdir($vd); } + $pk = $regDir . '/packages.json'; + $list = is_file($pk) ? (json_decode(file_get_contents($pk), true) ?: []) : []; + $list = array_values(array_filter($list, fn($n) => $n !== $name)); + if (is_file($pk)) file_put_contents($pk, json_encode($list, JSON_PRETTY_PRINT)); + } + pmu_ok(['name' => $name, 'version' => $ver, 'removed' => $removed]); +} + +/* delete the whole package */ +if (is_dir($pkgDir)) { foreach (glob($pkgDir . '/*') as $f) @unlink($f); @rmdir($pkgDir); } +if (is_file($pkgJson)) @unlink($pkgJson); +$vd = $regDir . '/' . $name; +if (is_dir($vd)) { foreach (glob($vd . '/*') as $f) @unlink($f); @rmdir($vd); } +$pk = $regDir . '/packages.json'; +$list = is_file($pk) ? (json_decode(file_get_contents($pk), true) ?: []) : []; +$list = array_values(array_filter($list, fn($n) => $n !== $name)); +if (is_file($pk)) file_put_contents($pk, json_encode($list, JSON_PRETTY_PRINT)); + +pmu_ok(['name' => $name, 'removed' => true]); diff --git a/web/ppdm/list.php b/web/ppdm/list.php new file mode 100644 index 0000000..a9b1183 --- /dev/null +++ b/web/ppdm/list.php @@ -0,0 +1,29 @@ +