diff --git a/src/i18n.c b/src/i18n.c index a27f5bc..935a071 100644 --- a/src/i18n.c +++ b/src/i18n.c @@ -54,7 +54,7 @@ static const char *kBuiltinZh = "\"msg.hash-sha256\":\"sha256: %s\",\"msg.hash-sha1\":\"sha1: %s\"," "\"msg.installing\":\"正在安装 %s ...\",\"msg.installed\":\"已安装 %s\"," "\"msg.checksum-ok\":\"%s 校验 OK: %s\",\"msg.checksum-mismatch\":\"校验不匹配 (%s)!\"," -"\"msg.resolving-dep\":\"正在解析依赖 %s%s%s\",\"msg.dep-satisfied\":\"依赖 %s%s%s 已装/被提供,跳过\",\"msg.registry-ok\":\"注册表 sha256 OK: %s\",\"msg.cache-cleared\":\"已清理缓存: %d 个文件,释放 %.1f KB\",\"msg.offline-using-cache\":\"离线: 使用缓存 %s\",\"msg.err.not-cached\":\"%s 未在缓存中(先运行 pmm fetch)\",\"msg.doctor-issues\":\"doctor: 发现 %d 个问题\",\"msg.self-up-to-date\":\"当前 v%s 已是最新(v%s),跳过升级\"," +"\"msg.resolving-dep\":\"正在解析依赖 %s%s%s\",\"msg.dep-satisfied\":\"依赖 %s%s%s 已装/被提供,跳过\",\"msg.registry-ok\":\"注册表 sha256 OK: %s\",\"msg.cache-cleared\":\"已清理缓存: %d 个文件,释放 %.1f KB\",\"msg.offline-using-cache\":\"离线: 使用缓存 %s\",\"msg.err.not-cached\":\"%s 未在缓存中(先运行 pmm fetch)\",\"msg.postinst-ok\":\"安装后脚本执行成功: %s\",\"msg.warn.postinst\":\"安装后脚本返回非 0: %s\",\"msg.warn.postinst-missing\":\"安装后脚本缺失: %s\",\"msg.doctor-issues\":\"doctor: 发现 %d 个问题\",\"msg.self-up-to-date\":\"当前 v%s 已是最新(v%s),跳过升级\"," "\"msg.path-exists\":\"PATH 已包含 PMM 目录\",\"msg.err.registry-not-found\":\"找不到软件包 '%s'\"," "\"msg.pmm-self-replaced\":\"pmm 已更新到 %s\",\"msg.pmm-self-hint\":\"无法覆盖 %s(需 root/管理员);新版本在 %s。请将其加入 PATH 并在当前 shell 运行 hash -r\"," "\"msg.err.usage\":\"用法\",\"msg.err.unknown-cmd\":\"未知命令 '%s' (试试 'pmm help')\"," @@ -69,7 +69,7 @@ static const char *kBuiltinZh = static const char *kBuiltinEn = -"{\"help.banner\":\"PMM %s (%s)\",\"help.usage\":\"usage:\",\"help.commands\":\"commands:\",\"help.options\":\"options:\",\"help.common\":\"common commands:\",\"cmd.list\":\"list\",\"cmd.info\":\"info\",\"cmd.search\":\"search\",\"cmd.install\":\"install\",\"cmd.remove\":\"remove\",\"cmd.update\":\"update\",\"cmd.upgrade\":\"upgrade\",\"cmd.mirror\":\"mirror\",\"cmd.self-update\":\"self-update\",\"cmd.version\":\"version\",\"cmd.help\":\"help\",\"desc.list\":\"list packages by name\",\"desc.info\":\"show detailed info for a package\",\"desc.search\":\"search packages by keyword\",\"desc.install\":\"install a package by name\",\"desc.remove\":\"uninstall a package by name\",\"desc.update\":\"refresh the registry index (apt-style)\",\"desc.upgrade\":\"upgrade all installed packages\",\"desc.mirror\":\"list / manage mirrors\",\"desc.self-update\":\"update the pmm tool itself\",\"desc.version\":\"show version\",\"desc.help\":\"show help\",\"opt.p-drive\":\"install under :\\\\\\\\.pmm\",\"opt.no-color\":\"omit ANSI colours on a terminal (PMM_NO_COLOR=1 too)\",\"opt.quiet\":\"only print errors/warnings (suppress info/success)\",\"opt.verbose\":\"print extra detail\",\"msg.looking-up\":\"looking up %s in mirror %s\",\"msg.selected\":\"selected %s@%s (os=%s arch=%s)\",\"msg.downloading\":\"downloading %s%s\",\"msg.downloaded\":\"downloaded %s\",\"msg.hash-sha256\":\"sha256: %s\",\"msg.hash-sha1\":\"sha1: %s\",\"msg.sha256\":\"sha256: %s %s\",\"msg.sha1\":\"sha1: %s %s\",\"msg.installing\":\"installing %s ...\",\"msg.installing-file\":\"installing local file %s\",\"msg.installed\":\"installed %s\",\"msg.removed\":\"removed %s (%d files)\",\"msg.packed\":\"packed %s (%s %s) -> %s\",\"msg.checksum-ok\":\"%s checksum OK: %s\",\"msg.checksum-mismatch\":\"CHECKSUM MISMATCH (%s)!\\n expected: %s\\n actual: %s\",\"msg.registry-ok\":\"registry sha256 OK: %s\",\"msg.registry-not-found\":\"package '%s' not found in any registry mirror\",\"msg.no-version\":\"no version of '%s' for os=%s arch=%s satisfying '%s'\",\"msg.up-to-date\":\"%s %s is up to date (latest %s)\",\"msg.upgrading\":\"%s: %s -> %s\",\"msg.upgraded\":\"upgraded %d package(s).\",\"msg.no-installed\":\"no installed packages.\",\"msg.registry-empty\":\"registry index is empty.\",\"msg.registry-updated\":\"updated registry index: %d/%d packages cached.\",\"msg.skipping-no-registry\":\"skipping %s: no registry entry\",\"msg.no-match\":\"no package matches '%s'\",\"msg.description\":\"description: %s\",\"msg.cleaning-cache\":\"cleaning cache %s\",\"msg.drive-set\":\"install drive set to %c:\",\"msg.path-set\":\"install path set to %s\",\"msg.path-adding\":\"adding to PATH: %s\",\"msg.path-exists\":\"PATH already contains PMM dirs\",\"msg.path-updated\":\"PATH updated for new shells (reopen a terminal or run: setx) (user-level)\",\"msg.path-reload\":\"updated %s (reload your shell)\",\"msg.registered\":\"registered '%s' %s in Installed Apps (uninstall via pmm remove %s)\",\"msg.unregistered\":\"removed '%s' from Installed Apps\",\"msg.mirror-added\":\"mirror '%s' added\",\"msg.mirror-active\":\"active mirror set to '%s'\",\"msg.mirror-removed\":\"mirror '%s' removed\",\"msg.lang-set\":\"language set to '%s'\",\"msg.setting-set\":\"set %s = %s\",\"msg.empty-path\":\"empty file path\",\"msg.verifying-native\":\"verifying %s is a native %s binary...\",\"msg.resolving-dep\":\"resolving dependency %s%s%s\",\"msg.err.usage\":\"usage:\",\"msg.err.not-found\":\"package '%s' not found\",\"msg.err.not-installed\":\"package '%s' is not installed\",\"msg.err.empty-path\":\"empty file path\",\"msg.err.registry-not-found\":\"package '%s' not found in any registry mirror\",\"msg.err.no-suitable-asset\":\"no suitable %s asset found in latest release of %s\",\"msg.err.unknown-cmd\":\"unknown command '%s' (try 'pmm help')\",\"msg.err.failed-install\":\"failed to install %s\",\"msg.err.cannot-write\":\"cannot write %s\",\"msg.err.cannot-read\":\"cannot read %s\",\"msg.err.cannot-open\":\"cannot open file: %s\",\"msg.err.invalid-locale\":\"invalid language pack: %s\",\"msg.err.download-failed\":\"failed to download %s\",\"msg.err.no-registry-mirror\":\"no registry mirror configured. Add to ~/.pmm/mirror.ini\",\"msg.err.no-mirror\":\"no mirrors configured (use: pmm mirror add)\",\"msg.err.no-mirror-file\":\"no mirror file\",\"msg.err.no-registry-index\":\"no registry index (packages.json) available\",\"msg.err.bad-registry-index\":\"bad registry index\",\"msg.err.bad-entry\":\"bad registry entry '%s'\",\"msg.err.bad-registry-entry\":\"bad registry entry for '%s' (%s)\",\"msg.err.checksum-mismatch-file\":\"checksum mismatch for %s in %s\",\"msg.err.no-control\":\"%s has no pdm-control file\",\"msg.err.no-package\":\"pdm-control missing 'Package:' field\",\"msg.err.tar-control\":\"tar (control) failed\",\"msg.err.tar-data\":\"tar (data) failed\",\"msg.err.not-pdm\":\"'%s' is not a .pdm file\",\"msg.err.no-tar\":\"cannot run tar\",\"msg.err.bad-archive\":\"not a valid .pdm archive: %s\",\"msg.err.no-control-tar\":\"missing control.tar.gz in %s\",\"msg.err.extract\":\"data extraction failed\",\"msg.err.oom\":\"out of memory\",\"msg.err.json-parse\":\"JSON parse error: %s\",\"msg.err.unknown-host\":\"unknown host '%s'\",\"msg.err.checksum-refuse\":\"refusing to install: checksum verification failed\",\"msg.err.registry-entry-no-url\":\"registry entry for '%s' has no url\",\"msg.err.rpm-stage\":\"cannot create rpm stage dir: %s\",\"msg.err.rpm-decompress\":\"rpm payload decompress/cpio failed (need %s)\",\"msg.err.rpm-copy\":\"failed to copy rpm payload into /\",\"msg.warn.parse-checksum\":\"warning: could not parse %s checksum file\",\"msg.warn.download-retry\":\"download failed, trying next source...\",\"msg.warn.not-usable\":\"%s is not a usable %s binary; will fall back\",\"msg.warn.no-checksum\":\"warning: no sha256sums member, skipping integrity check\",\"msg.warn.no-filelist\":\"warning: could not record file list\",\"msg.warn.no-register\":\"warning: could not register '%s' in Installed Apps\",\"msg.api-unreachable\":\"could not reach a known release API for %s\",\"msg.retrying-asset\":\"retrying with %s (%s)\",\"mirror.sources\":\"mirrors:\",\"mirror.checking\":\"checking registry mirrors...\",\"mirror.result\":\"result: %d/%d sources reachable\",\"lang.packs-in\":\"language packs in %s:\",\"desc.clean\":\"clean cache\",\"desc.cache\":\"manage download cache\",\"desc.fetch\":\"predownload to cache\",\"msg.dep-satisfied\":\"dependency %s%s%s already installed/provided, skipped\",\"msg.err.conflict\":\"cannot install %s: conflicts with installed %s\",\"msg.cache-cleared\":\"cache cleaned: %d files, freed %.1f KB\",\"msg.offline-using-cache\":\"offline: using cached %s\",\"msg.err.not-cached\":\"%s not in cache (run pmm fetch)\",\"msg.self-up-to-date\":\"already up to date (v%s, latest v%s), skipping upgrade\",\"desc.doctor\":\"diagnose\",\"msg.doctor-issues\":\"doctor: found %d issue(s)\"}"; +"{\"help.banner\":\"PMM %s (%s)\",\"help.usage\":\"usage:\",\"help.commands\":\"commands:\",\"help.options\":\"options:\",\"help.common\":\"common commands:\",\"cmd.list\":\"list\",\"cmd.info\":\"info\",\"cmd.search\":\"search\",\"cmd.install\":\"install\",\"cmd.remove\":\"remove\",\"cmd.update\":\"update\",\"cmd.upgrade\":\"upgrade\",\"cmd.mirror\":\"mirror\",\"cmd.self-update\":\"self-update\",\"cmd.version\":\"version\",\"cmd.help\":\"help\",\"desc.list\":\"list packages by name\",\"desc.info\":\"show detailed info for a package\",\"desc.search\":\"search packages by keyword\",\"desc.install\":\"install a package by name\",\"desc.remove\":\"uninstall a package by name\",\"desc.update\":\"refresh the registry index (apt-style)\",\"desc.upgrade\":\"upgrade all installed packages\",\"desc.mirror\":\"list / manage mirrors\",\"desc.self-update\":\"update the pmm tool itself\",\"desc.version\":\"show version\",\"desc.help\":\"show help\",\"opt.p-drive\":\"install under :\\\\\\\\.pmm\",\"opt.no-color\":\"omit ANSI colours on a terminal (PMM_NO_COLOR=1 too)\",\"opt.quiet\":\"only print errors/warnings (suppress info/success)\",\"opt.verbose\":\"print extra detail\",\"msg.looking-up\":\"looking up %s in mirror %s\",\"msg.selected\":\"selected %s@%s (os=%s arch=%s)\",\"msg.downloading\":\"downloading %s%s\",\"msg.downloaded\":\"downloaded %s\",\"msg.hash-sha256\":\"sha256: %s\",\"msg.hash-sha1\":\"sha1: %s\",\"msg.sha256\":\"sha256: %s %s\",\"msg.sha1\":\"sha1: %s %s\",\"msg.installing\":\"installing %s ...\",\"msg.installing-file\":\"installing local file %s\",\"msg.installed\":\"installed %s\",\"msg.removed\":\"removed %s (%d files)\",\"msg.packed\":\"packed %s (%s %s) -> %s\",\"msg.checksum-ok\":\"%s checksum OK: %s\",\"msg.checksum-mismatch\":\"CHECKSUM MISMATCH (%s)!\\n expected: %s\\n actual: %s\",\"msg.registry-ok\":\"registry sha256 OK: %s\",\"msg.registry-not-found\":\"package '%s' not found in any registry mirror\",\"msg.no-version\":\"no version of '%s' for os=%s arch=%s satisfying '%s'\",\"msg.up-to-date\":\"%s %s is up to date (latest %s)\",\"msg.upgrading\":\"%s: %s -> %s\",\"msg.upgraded\":\"upgraded %d package(s).\",\"msg.no-installed\":\"no installed packages.\",\"msg.registry-empty\":\"registry index is empty.\",\"msg.registry-updated\":\"updated registry index: %d/%d packages cached.\",\"msg.skipping-no-registry\":\"skipping %s: no registry entry\",\"msg.no-match\":\"no package matches '%s'\",\"msg.description\":\"description: %s\",\"msg.cleaning-cache\":\"cleaning cache %s\",\"msg.drive-set\":\"install drive set to %c:\",\"msg.path-set\":\"install path set to %s\",\"msg.path-adding\":\"adding to PATH: %s\",\"msg.path-exists\":\"PATH already contains PMM dirs\",\"msg.path-updated\":\"PATH updated for new shells (reopen a terminal or run: setx) (user-level)\",\"msg.path-reload\":\"updated %s (reload your shell)\",\"msg.registered\":\"registered '%s' %s in Installed Apps (uninstall via pmm remove %s)\",\"msg.unregistered\":\"removed '%s' from Installed Apps\",\"msg.mirror-added\":\"mirror '%s' added\",\"msg.mirror-active\":\"active mirror set to '%s'\",\"msg.mirror-removed\":\"mirror '%s' removed\",\"msg.lang-set\":\"language set to '%s'\",\"msg.setting-set\":\"set %s = %s\",\"msg.empty-path\":\"empty file path\",\"msg.verifying-native\":\"verifying %s is a native %s binary...\",\"msg.resolving-dep\":\"resolving dependency %s%s%s\",\"msg.err.usage\":\"usage:\",\"msg.err.not-found\":\"package '%s' not found\",\"msg.err.not-installed\":\"package '%s' is not installed\",\"msg.err.empty-path\":\"empty file path\",\"msg.err.registry-not-found\":\"package '%s' not found in any registry mirror\",\"msg.err.no-suitable-asset\":\"no suitable %s asset found in latest release of %s\",\"msg.err.unknown-cmd\":\"unknown command '%s' (try 'pmm help')\",\"msg.err.failed-install\":\"failed to install %s\",\"msg.err.cannot-write\":\"cannot write %s\",\"msg.err.cannot-read\":\"cannot read %s\",\"msg.err.cannot-open\":\"cannot open file: %s\",\"msg.err.invalid-locale\":\"invalid language pack: %s\",\"msg.err.download-failed\":\"failed to download %s\",\"msg.err.no-registry-mirror\":\"no registry mirror configured. Add to ~/.pmm/mirror.ini\",\"msg.err.no-mirror\":\"no mirrors configured (use: pmm mirror add)\",\"msg.err.no-mirror-file\":\"no mirror file\",\"msg.err.no-registry-index\":\"no registry index (packages.json) available\",\"msg.err.bad-registry-index\":\"bad registry index\",\"msg.err.bad-entry\":\"bad registry entry '%s'\",\"msg.err.bad-registry-entry\":\"bad registry entry for '%s' (%s)\",\"msg.err.checksum-mismatch-file\":\"checksum mismatch for %s in %s\",\"msg.err.no-control\":\"%s has no pdm-control file\",\"msg.err.no-package\":\"pdm-control missing 'Package:' field\",\"msg.err.tar-control\":\"tar (control) failed\",\"msg.err.tar-data\":\"tar (data) failed\",\"msg.err.not-pdm\":\"'%s' is not a .pdm file\",\"msg.err.no-tar\":\"cannot run tar\",\"msg.err.bad-archive\":\"not a valid .pdm archive: %s\",\"msg.err.no-control-tar\":\"missing control.tar.gz in %s\",\"msg.err.extract\":\"data extraction failed\",\"msg.err.oom\":\"out of memory\",\"msg.err.json-parse\":\"JSON parse error: %s\",\"msg.err.unknown-host\":\"unknown host '%s'\",\"msg.err.checksum-refuse\":\"refusing to install: checksum verification failed\",\"msg.err.registry-entry-no-url\":\"registry entry for '%s' has no url\",\"msg.err.rpm-stage\":\"cannot create rpm stage dir: %s\",\"msg.err.rpm-decompress\":\"rpm payload decompress/cpio failed (need %s)\",\"msg.err.rpm-copy\":\"failed to copy rpm payload into /\",\"msg.warn.parse-checksum\":\"warning: could not parse %s checksum file\",\"msg.warn.download-retry\":\"download failed, trying next source...\",\"msg.warn.not-usable\":\"%s is not a usable %s binary; will fall back\",\"msg.warn.no-checksum\":\"warning: no sha256sums member, skipping integrity check\",\"msg.warn.no-filelist\":\"warning: could not record file list\",\"msg.warn.no-register\":\"warning: could not register '%s' in Installed Apps\",\"msg.api-unreachable\":\"could not reach a known release API for %s\",\"msg.retrying-asset\":\"retrying with %s (%s)\",\"mirror.sources\":\"mirrors:\",\"mirror.checking\":\"checking registry mirrors...\",\"mirror.result\":\"result: %d/%d sources reachable\",\"lang.packs-in\":\"language packs in %s:\",\"desc.clean\":\"clean cache\",\"desc.cache\":\"manage download cache\",\"desc.fetch\":\"predownload to cache\",\"msg.dep-satisfied\":\"dependency %s%s%s already installed/provided, skipped\",\"msg.err.conflict\":\"cannot install %s: conflicts with installed %s\",\"msg.cache-cleared\":\"cache cleaned: %d files, freed %.1f KB\",\"msg.offline-using-cache\":\"offline: using cached %s\",\"msg.err.not-cached\":\"%s not in cache (run pmm fetch)\",\"msg.postinst-ok\":\"post-install script ran OK: %s\",\"msg.warn.postinst\":\"post-install script returned non-zero: %s\",\"msg.warn.postinst-missing\":\"post-install script missing: %s\",\"msg.self-up-to-date\":\"already up to date (v%s, latest v%s), skipping upgrade\",\"desc.doctor\":\"diagnose\",\"msg.doctor-issues\":\"doctor: found %d issue(s)\"}"; /* Which built-in fallback matches the current locale? en -> en-US, else zh-CN. */ static const char *builtin_source(void) { diff --git a/src/pdm.c b/src/pdm.c index ff7fedb..678682d 100644 --- a/src/pdm.c +++ b/src/pdm.c @@ -668,6 +668,37 @@ int pdm_install_file(const char *pdmfile) { pmm_sync_self(nb); } + /* InstallScript: run a script shipped in the package after install (like a + * Debian postinst). The script path is relative to the package's install + * dir (root, or root/). */ + char *post = control_get(ctl, "InstallScript"); + if (post && *post) { + char sroot[1500]; + if (flat) snprintf(sroot, sizeof(sroot), "%s", home); + else if (pmm_install_subdir[0]) snprintf(sroot, sizeof(sroot), "%s/%s", root, pmm_install_subdir); + else snprintf(sroot, sizeof(sroot), "%s", root); + char spath[1700]; + snprintf(spath, sizeof(spath), "%s/%s", sroot, post); + char cx[1800]; + snprintf(cx, sizeof(cx), "chmod +x \"%s\" 2>/dev/null || true", spath); + system(cx); + FILE *xf = fopen(spath, "rb"); + if (xf) { + fclose(xf); +#ifdef _WIN32 + _putenv_s("PMM_ROOT", sroot); +#else + setenv("PMM_ROOT", sroot, 1); /* give the script its install dir */ +#endif + int src = system(spath); + if (src == 0) pmm_success("%s", pmm_tr_fmt("msg.postinst-ok", spath)); + else pmm_warn("%s", pmm_tr_fmt("msg.warn.postinst", spath)); + } else { + pmm_warn("%s", pmm_tr_fmt("msg.warn.postinst-missing", spath)); + } + free(post); + } + free(pkg); if (ver) free(ver); return 0; } diff --git a/web/docs/md/ppdm.md b/web/docs/md/ppdm.md index 5e4e31b..3d80220 100644 --- a/web/docs/md/ppdm.md +++ b/web/docs/md/ppdm.md @@ -81,10 +81,12 @@ Maintainer: you@mail.com # 可选: # LibraryPath: true # 装到 ~/.pmm/root 后,自动把本包 lib/ 加入 LD_LIBRARY_PATH(新 shell 生效) # InstallDir: tools/myapp # 把本包装到 ~/.pmm/root/tools/myapp (bin -> .../bin, lib -> .../lib) +# InstallScript: bin/postinst.sh # 安装后自动运行包内脚本(可访问 $PMM_ROOT 环境变量) ``` > `LibraryPath` 默认 `false`(不加);`true` 时 pmm 会在 `~/.bashrc` 写入本包 lib 目录的 > `LD_LIBRARY_PATH`。`InstallDir` 可把包装到 `~/.pmm/root/<子目录>`,该目录下的 `bin` 也会进 PATH。 +> `InstallScript` 指向包内脚本路径,安装后执行(环境变量 `$PMM_ROOT` = 本包安装目录)。 打包: diff --git a/web/mirror/lang/en-US.pjson b/web/mirror/lang/en-US.pjson index 812d90b..f1ccec1 100644 --- a/web/mirror/lang/en-US.pjson +++ b/web/mirror/lang/en-US.pjson @@ -134,5 +134,8 @@ "desc.cache": "manage download cache", "desc.fetch": "predownload to cache", "msg.offline-using-cache": "offline: using cached %s", - "msg.err.not-cached": "%s not in cache (run pmm fetch)" + "msg.err.not-cached": "%s not in cache (run pmm fetch)", + "msg.postinst-ok": "post-install script ran OK: %s", + "msg.warn.postinst": "post-install script returned non-zero: %s", + "msg.warn.postinst-missing": "post-install script missing: %s" } diff --git a/web/mirror/lang/zh-CN.pjson b/web/mirror/lang/zh-CN.pjson index d00a1e8..a9f9c04 100644 --- a/web/mirror/lang/zh-CN.pjson +++ b/web/mirror/lang/zh-CN.pjson @@ -134,5 +134,8 @@ "desc.cache": "管理缓存", "desc.fetch": "预下载到缓存", "msg.offline-using-cache": "离线: 使用缓存 %s", - "msg.err.not-cached": "%s 未在缓存中(先运行 pmm fetch)" + "msg.err.not-cached": "%s 未在缓存中(先运行 pmm fetch)", + "msg.postinst-ok": "安装后脚本执行成功: %s", + "msg.warn.postinst": "安装后脚本返回非 0: %s", + "msg.warn.postinst-missing": "安装后脚本缺失: %s" }