文件
ParlzPackageManger/web/pmu/publish.php
T
JGZYES 9822891394 feat(pmu): package upload/publish CLI + PHP service
Client src/pmu.c (independent binary, links out.c + sha256.c):
- pmu register <email> <pwd>: local arithmetic human-verification, then POST register.php.
- pmu login / logout / whoami: session token stored in ~/.pmu/config.
- pmu ./x.pdm (or 'pmu publish x.pdm'): parses Package/Version/Architecture from
  the .pdm, computes sha256, uploads raw bytes with a Bearer token; the server
  auto-generates <pkg>.json and stores the .pdm; duplicate names are rejected.

Server web/pmu/*.php:
- lib.php: JSON responses, token auth, data store in web/pmu/data/*.json (gitignored).
- register/login/logout/publish.php: account + session + upload + registry write
  (writes web/mirror/packages/<name>.json, copies .pdm, appends packages.json).
- Duplicate package names -> 409; missing/invalid token -> 401.

Also: .gitignore web/pmu/data/*.json; release.yml builds pmu per-platform.
2026-09-05 22:30:47 +08:00

64 行
2.5 KiB
PHP

<?php
/* web/pmu/publish.php — upload a completed .pdm (raw body) and publish it to the
* mirror registry: writes/updates <pkg>.json, stores the .pdm under
* web/mirror/packages/<pkg>/, and appends the name to packages.json.
* Duplicate package names are rejected (409). Requires a valid bearer token. */
define('PMM_SITE', 1);
require __DIR__ . '/lib.php';
[$tok, $email] = pmu_require_auth_token();
$name = trim((string)($_GET['name'] ?? ''));
$ver = trim((string)($_GET['version'] ?? ''));
$arch = trim((string)($_GET['arch'] ?? 'amd64'));
$os = trim((string)($_GET['os'] ?? 'linux'));
$desc = trim((string)($_GET['description'] ?? $name));
if (!preg_match('/^[A-Za-z0-9][A-Za-z0-9._-]*$/', $name)) pmu_fail('invalid package name');
if ($ver === '') pmu_fail('missing version');
if ($arch === '') $arch = 'amd64';
if ($os !== 'windows' && $os !== 'linux' && $os !== 'macos') pmu_fail('invalid os');
$body = file_get_contents('php://input');
if (strlen($body) === 0) pmu_fail('empty upload body');
if (strlen($body) > 100 * 1024 * 1024) pmu_fail('package too large (>100 MB)');
$regDir = __DIR__ . '/../mirror/packages';
$pkgJson = $regDir . '/' . $name . '.json';
/* duplicate-name reject: the package name is already published */
if (is_file($pkgJson)) pmu_fail("package name '$name' already exists", 409);
$sha = hash('sha256', $body);
$file = $ver . '-' . $os . '-' . $arch . '.pdm';
$pkgDir = $regDir . '/' . $name;
if (!is_dir($pkgDir)) @mkdir($pkgDir, 0777, true);
file_put_contents($pkgDir . '/' . $file, $body);
$url = 'https://pmm.parlz.com/mirror/packages/' . $name . '/' . $file;
$meta = [
'name' => $name,
'version' => $ver,
'os' => $os,
'arch' => $arch,
'description' => $desc,
'variants' => [[
'name' => $name,
'version' => $ver,
'os' => $os,
'arch' => $arch,
'file' => $file,
'url' => $url,
'sha256' => $sha,
'description' => $desc,
]],
];
file_put_contents($pkgJson, json_encode($meta, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
/* append the name to the aggregate index if new */
$pk = $regDir . '/packages.json';
$list = is_file($pk) ? (json_decode(file_get_contents($pk), true) ?: []) : [];
if (!in_array($name, $list, true)) { $list[] = $name; file_put_contents($pk, json_encode($list, JSON_PRETTY_PRINT)); }
pmu_ok(['name' => $name, 'version' => $ver, 'file' => $file, 'url' => $url, 'sha256' => $sha]);