pacman-debian 7.3.36 → 7.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -0
- package/README_zh-CN.md +11 -0
- package/dist/cli/archlinux-java.js +36 -12
- package/dist/cli/archlinux-java.js.map +1 -1
- package/dist/cli/paclink.js +84 -0
- package/dist/cli/paclink.js.map +1 -1
- package/dist/cli/pacman.d.ts.map +1 -1
- package/dist/cli/pacman.js +66 -11
- package/dist/cli/pacman.js.map +1 -1
- package/dist/cli/pactree.d.ts +3 -0
- package/dist/cli/pactree.d.ts.map +1 -0
- package/dist/cli/pactree.js +216 -0
- package/dist/cli/pactree.js.map +1 -0
- package/dist/core/deps.d.ts +7 -0
- package/dist/core/deps.d.ts.map +1 -1
- package/dist/core/deps.js +104 -24
- package/dist/core/deps.js.map +1 -1
- package/dist/core/logger.d.ts +7 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +93 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/options.d.ts +2 -0
- package/dist/core/options.d.ts.map +1 -1
- package/dist/core/paclinks.d.ts +9 -0
- package/dist/core/paclinks.d.ts.map +1 -0
- package/dist/core/paclinks.js +69 -0
- package/dist/core/paclinks.js.map +1 -0
- package/dist/core/pkgfile.d.ts +2 -0
- package/dist/core/pkgfile.d.ts.map +1 -1
- package/dist/core/pkgfile.js +6 -0
- package/dist/core/pkgfile.js.map +1 -1
- package/dist/core/tar.d.ts +3 -1
- package/dist/core/tar.d.ts.map +1 -1
- package/dist/core/tar.js +87 -11
- package/dist/core/tar.js.map +1 -1
- package/dist/core/types.d.ts +17 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/db/dpkg-compat.d.ts +5 -2
- package/dist/db/dpkg-compat.d.ts.map +1 -1
- package/dist/db/dpkg-compat.js +130 -57
- package/dist/db/dpkg-compat.js.map +1 -1
- package/dist/db/localdb.d.ts.map +1 -1
- package/dist/db/localdb.js +21 -2
- package/dist/db/localdb.js.map +1 -1
- package/dist/debug-upgrade.d.ts +2 -0
- package/dist/debug-upgrade.d.ts.map +1 -0
- package/dist/debug-upgrade.js +140 -0
- package/dist/debug-upgrade.js.map +1 -0
- package/dist/i18n/en.json +2 -0
- package/dist/i18n/paclink/en.d.ts.map +1 -1
- package/dist/i18n/paclink/en.js +7 -0
- package/dist/i18n/paclink/en.js.map +1 -1
- package/dist/i18n/paclink/zh-CN.d.ts.map +1 -1
- package/dist/i18n/paclink/zh-CN.js +7 -0
- package/dist/i18n/paclink/zh-CN.js.map +1 -1
- package/dist/i18n/zh-CN.json +2 -0
- package/dist/lock/dpkg-helper +0 -0
- package/dist/lock/dpkg-lock.d.ts +5 -0
- package/dist/lock/dpkg-lock.d.ts.map +1 -0
- package/dist/lock/dpkg-lock.js +113 -0
- package/dist/lock/dpkg-lock.js.map +1 -0
- package/dist/makepkg/build.d.ts.map +1 -1
- package/dist/makepkg/build.js +3 -5
- package/dist/makepkg/build.js.map +1 -1
- package/dist/makepkg/pkgbuild.d.ts.map +1 -1
- package/dist/makepkg/pkgbuild.js +109 -53
- package/dist/makepkg/pkgbuild.js.map +1 -1
- package/dist/ops/install.d.ts +2 -1
- package/dist/ops/install.d.ts.map +1 -1
- package/dist/ops/install.js +290 -157
- package/dist/ops/install.js.map +1 -1
- package/dist/ops/query.d.ts.map +1 -1
- package/dist/ops/query.js +62 -35
- package/dist/ops/query.js.map +1 -1
- package/dist/ops/remove.d.ts.map +1 -1
- package/dist/ops/remove.js +106 -60
- package/dist/ops/remove.js.map +1 -1
- package/dist/ops/upgrade.d.ts.map +1 -1
- package/dist/ops/upgrade.js +71 -13
- package/dist/ops/upgrade.js.map +1 -1
- package/dist/repo/config.d.ts.map +1 -1
- package/dist/repo/config.js +60 -6
- package/dist/repo/config.js.map +1 -1
- package/dist/repo/repository.d.ts +6 -0
- package/dist/repo/repository.d.ts.map +1 -1
- package/dist/repo/repository.js +348 -49
- package/dist/repo/repository.js.map +1 -1
- package/dist/scripts/setup.js +27 -77
- package/dist/scripts/setup.js.map +1 -1
- package/docs/en/architecture.md +109 -45
- package/docs/en/pactree.md +42 -0
- package/docs/en/yay-aur.md +10 -6
- package/docs/zh-CN/pactree.md +41 -0
- package/lib/pac4deb/include/alpm.h +2 -1
- package/lib/pac4deb/src/libalpm.c +116 -54
- package/lib/pac4deb/src/stubs_manual.c +11 -1
- package/package.json +4 -3
- package/resources/paclinks.conf +64 -0
- package/resources/pacman.conf.template +16 -2
package/dist/ops/install.js
CHANGED
|
@@ -49,19 +49,21 @@ const repository_1 = require("../repo/repository");
|
|
|
49
49
|
const config_1 = require("../repo/config");
|
|
50
50
|
const database_1 = require("../db/database");
|
|
51
51
|
const dpkg_compat_1 = require("../db/dpkg-compat");
|
|
52
|
+
const dpkg_lock_1 = require("../lock/dpkg-lock");
|
|
52
53
|
const localdb_1 = require("../db/localdb");
|
|
53
54
|
const deps_1 = require("../core/deps");
|
|
54
55
|
const format_1 = require("../ui/format");
|
|
55
56
|
const progress_1 = require("../ui/progress");
|
|
56
57
|
const prompt_1 = require("../ui/prompt");
|
|
57
58
|
const i18n_1 = require("../i18n");
|
|
58
|
-
async function installDeb(filePath, reason, opts = {}) {
|
|
59
|
+
async function installDeb(filePath, reason, opts = {}, onProgress) {
|
|
59
60
|
(0, database_1.initDb)();
|
|
60
61
|
const pkg = (0, deb_1.parseDeb)(filePath);
|
|
61
62
|
const db = (0, database_1.loadDatabase)();
|
|
62
63
|
removeLinkIfPresent(pkg.control.package);
|
|
63
64
|
const { control } = pkg;
|
|
64
65
|
const existing = (0, database_1.getPackage)(db, control.package);
|
|
66
|
+
const _cfg = (0, config_1.loadConfig)();
|
|
65
67
|
if (opts.needed && existing && existing.version === control.version) {
|
|
66
68
|
return false;
|
|
67
69
|
}
|
|
@@ -75,50 +77,56 @@ async function installDeb(filePath, reason, opts = {}) {
|
|
|
75
77
|
if (realFiles.length > 0)
|
|
76
78
|
return true;
|
|
77
79
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
const
|
|
81
|
-
if (
|
|
82
|
-
(0,
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
const
|
|
88
|
-
if (
|
|
89
|
-
(0,
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
80
|
+
await (0, dpkg_lock_1.acquireDpkgLock)();
|
|
81
|
+
try {
|
|
82
|
+
const tx = (0, database_1.createTransaction)('install', control.package, control.version);
|
|
83
|
+
if (!opts.noscriptlet) {
|
|
84
|
+
const preinst = (0, deb_1.readScript)(pkg, 'preinst');
|
|
85
|
+
if (preinst)
|
|
86
|
+
(0, database_1.saveScript)(control.package, 'preinst', preinst);
|
|
87
|
+
(0, database_1.runScript)(control.package, 'preinst', ['install']);
|
|
88
|
+
}
|
|
89
|
+
const files = (0, tar_1.extractTar)(pkg.dataTar, '/', onProgress, _cfg.noExtract, _cfg.noUpgrade);
|
|
90
|
+
if (!opts.noscriptlet) {
|
|
91
|
+
const postinst = (0, deb_1.readScript)(pkg, 'postinst');
|
|
92
|
+
if (postinst)
|
|
93
|
+
(0, database_1.saveScript)(control.package, 'postinst', postinst);
|
|
94
|
+
(0, database_1.runScript)(control.package, 'postinst', ['configure']);
|
|
95
|
+
}
|
|
96
|
+
// Run ldconfig if package installs shared libraries
|
|
97
|
+
const hasSoFiles = files.some(f => /\.so(\.|$)/.test(f));
|
|
98
|
+
if (hasSoFiles) {
|
|
99
|
+
try {
|
|
100
|
+
(0, node_child_process_1.execSync)('/usr/sbin/ldconfig', { stdio: 'inherit' });
|
|
101
|
+
}
|
|
102
|
+
catch { }
|
|
103
|
+
}
|
|
104
|
+
const ip = {
|
|
105
|
+
name: control.package, version: control.version,
|
|
106
|
+
architecture: control.architecture || 'amd64',
|
|
107
|
+
description: control.description || '',
|
|
108
|
+
depends: control.depends, 'pre-depends': control['pre-depends'],
|
|
109
|
+
conflicts: control.conflicts, provides: control.provides,
|
|
110
|
+
maintainer: control.maintainer, homepage: control.homepage,
|
|
111
|
+
controlSection: control.section || 'misc',
|
|
112
|
+
controlPriority: control.priority || 'optional',
|
|
113
|
+
installedSize: control['installed-size'] ? parseInt(control['installed-size'], 10) : undefined,
|
|
114
|
+
installTime: Date.now(), reason, files, repo: opts.repo,
|
|
115
|
+
};
|
|
116
|
+
(0, database_1.addPackage)(db, ip);
|
|
95
117
|
try {
|
|
96
|
-
(0,
|
|
118
|
+
await (0, dpkg_compat_1.writeDpkgEntry)(ip);
|
|
97
119
|
}
|
|
98
|
-
catch {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
depends: control.depends, 'pre-depends': control['pre-depends'],
|
|
105
|
-
conflicts: control.conflicts, provides: control.provides,
|
|
106
|
-
maintainer: control.maintainer, homepage: control.homepage,
|
|
107
|
-
controlSection: control.section || 'misc',
|
|
108
|
-
controlPriority: control.priority || 'optional',
|
|
109
|
-
installedSize: control['installed-size'] ? parseInt(control['installed-size'], 10) : undefined,
|
|
110
|
-
installTime: Date.now(), reason, files,
|
|
111
|
-
};
|
|
112
|
-
(0, database_1.addPackage)(db, ip);
|
|
113
|
-
try {
|
|
114
|
-
(0, dpkg_compat_1.writeDpkgEntry)(ip);
|
|
120
|
+
catch (e) {
|
|
121
|
+
console.error((0, i18n_1.t)('warn_failed_dpkg_status', String(e)));
|
|
122
|
+
}
|
|
123
|
+
(0, database_1.saveDatabase)(db);
|
|
124
|
+
(0, database_1.completeTransaction)(tx.id);
|
|
125
|
+
return true;
|
|
115
126
|
}
|
|
116
|
-
|
|
117
|
-
|
|
127
|
+
finally {
|
|
128
|
+
(0, dpkg_lock_1.releaseDpkgLock)();
|
|
118
129
|
}
|
|
119
|
-
(0, database_1.saveDatabase)(db);
|
|
120
|
-
(0, database_1.completeTransaction)(tx.id);
|
|
121
|
-
return true;
|
|
122
130
|
}
|
|
123
131
|
/* When installing a real package, remove any existing link with the same name.
|
|
124
132
|
Links are virtual mappings (Debian→Arch), real packages take precedence. */
|
|
@@ -128,7 +136,7 @@ function removeLinkIfPresent(pkgName) {
|
|
|
128
136
|
(0, localdb_1.removePackage)(pkgName, existing.version);
|
|
129
137
|
}
|
|
130
138
|
}
|
|
131
|
-
async function installArch(filePath, reason, opts = {}) {
|
|
139
|
+
async function installArch(filePath, reason, opts = {}, onProgress) {
|
|
132
140
|
(0, database_1.initDb)();
|
|
133
141
|
const data = fs.readFileSync(filePath);
|
|
134
142
|
const { info, install, files: pkgFiles, dataBlocks } = (0, pkgfile_1.parsePkgTarZst)(data);
|
|
@@ -139,88 +147,110 @@ async function installArch(filePath, reason, opts = {}) {
|
|
|
139
147
|
const existing = (0, database_1.getPackage)(db, info.name);
|
|
140
148
|
if (opts.needed && existing && existing.version === info.version)
|
|
141
149
|
return false;
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
const
|
|
145
|
-
if (install
|
|
146
|
-
parts
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
150
|
+
await (0, dpkg_lock_1.acquireDpkgLock)();
|
|
151
|
+
try {
|
|
152
|
+
const tx = (0, database_1.createTransaction)('install', info.name, info.version);
|
|
153
|
+
if (!opts.noscriptlet && (install?.pre_install || install?.post_install)) {
|
|
154
|
+
const parts = [];
|
|
155
|
+
if (install.pre_install)
|
|
156
|
+
parts.push(`pre_install() {\n${install.pre_install}\n}`);
|
|
157
|
+
if (install.post_install)
|
|
158
|
+
parts.push(`post_install() {\n${install.post_install}\n}`);
|
|
159
|
+
if (install.pre_remove)
|
|
160
|
+
parts.push(`pre_remove() {\n${install.pre_remove}\n}`);
|
|
161
|
+
if (install.post_remove)
|
|
162
|
+
parts.push(`post_remove() {\n${install.post_remove}\n}`);
|
|
163
|
+
const script = parts.join('\n') + '\n';
|
|
164
|
+
(0, database_1.saveScript)(info.name, '.INSTALL', script);
|
|
165
|
+
const tmpScript = `/var/lib/pacman-debian/info/${info.name}/.INSTALL`;
|
|
166
|
+
if (install?.pre_install) {
|
|
167
|
+
try {
|
|
168
|
+
(0, node_child_process_1.execSync)(`/bin/bash -c 'source "${tmpScript}" && pre_install' 2>&-`, { stdio: 'pipe' });
|
|
169
|
+
}
|
|
170
|
+
catch { }
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
const files = [];
|
|
174
|
+
const total = dataBlocks.length;
|
|
175
|
+
const _archCfg = (0, config_1.loadConfig)();
|
|
176
|
+
const matchArch = (p, name) => p === name || p === '/' + name || (p.endsWith('/*') && name.startsWith(p.slice(0, -1)));
|
|
177
|
+
for (let i = 0; i < total; i++) {
|
|
178
|
+
const entry = dataBlocks[i];
|
|
179
|
+
const targetPath = (0, tar_1.safeTargetPath)('/', entry.name);
|
|
180
|
+
files.push('/' + entry.name);
|
|
181
|
+
if (_archCfg.noExtract.some(p => matchArch(p, entry.name)))
|
|
182
|
+
continue;
|
|
183
|
+
if (entry.data) {
|
|
184
|
+
fs.mkdirSync(path.dirname(targetPath), { recursive: true });
|
|
185
|
+
if (_archCfg.noUpgrade.some(p => matchArch(p, entry.name)) && fs.existsSync(targetPath)) {
|
|
186
|
+
const bak = targetPath + '.pacnew';
|
|
187
|
+
fs.writeFileSync(bak, entry.data, { mode: 0o755 });
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
if (fs.existsSync(targetPath) && fs.lstatSync(targetPath).isSymbolicLink())
|
|
191
|
+
fs.unlinkSync(targetPath);
|
|
192
|
+
fs.writeFileSync(targetPath, entry.data, { mode: 0o755 });
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
onProgress?.(i + 1, total, entry.name);
|
|
196
|
+
}
|
|
197
|
+
if (!opts.noscriptlet && install?.post_install) {
|
|
198
|
+
const tmpScript = `/var/lib/pacman-debian/info/${info.name}/.INSTALL`;
|
|
199
|
+
if (!fs.existsSync(tmpScript)) {
|
|
200
|
+
(0, database_1.saveScript)(info.name, '.INSTALL', `post_install() {\n${install.post_install}\n}\n`);
|
|
201
|
+
}
|
|
157
202
|
try {
|
|
158
|
-
(0, node_child_process_1.execSync)(`/bin/bash -c 'source "${tmpScript}" &&
|
|
203
|
+
(0, node_child_process_1.execSync)(`/bin/bash -c 'source "${tmpScript}" && post_install' 2>&-`, { stdio: 'pipe' });
|
|
159
204
|
}
|
|
160
205
|
catch { }
|
|
161
206
|
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
if (entry.data) {
|
|
170
|
-
fs.mkdirSync(path.dirname(targetPath), { recursive: true });
|
|
171
|
-
fs.writeFileSync(targetPath, entry.data, { mode: 0o755 });
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
if (!opts.noscriptlet && install?.post_install) {
|
|
175
|
-
const tmpScript = `/var/lib/pacman-debian/info/${info.name}/.INSTALL`;
|
|
176
|
-
if (!fs.existsSync(tmpScript)) {
|
|
177
|
-
(0, database_1.saveScript)(info.name, '.INSTALL', `post_install() {\n${install.post_install}\n}\n`);
|
|
207
|
+
// Run ldconfig if package installs shared libraries
|
|
208
|
+
const hasSoFiles = files.some(f => /\.so(\.|$)/.test(f));
|
|
209
|
+
if (hasSoFiles) {
|
|
210
|
+
try {
|
|
211
|
+
(0, node_child_process_1.execSync)('/usr/sbin/ldconfig', { stdio: 'inherit' });
|
|
212
|
+
}
|
|
213
|
+
catch { }
|
|
178
214
|
}
|
|
215
|
+
const ip = {
|
|
216
|
+
name: info.name, version: info.version,
|
|
217
|
+
architecture: info.arch || 'any',
|
|
218
|
+
description: info.description || '',
|
|
219
|
+
depends: (info.depends || []).join(', '),
|
|
220
|
+
conflicts: (info.conflicts || []).join(', '),
|
|
221
|
+
provides: (info.provides || []).join(', '),
|
|
222
|
+
maintainer: info.packager,
|
|
223
|
+
homepage: info.url,
|
|
224
|
+
license: (info.license || []).join(', '), pkgbase: info.base, buildDate: info.buildDate,
|
|
225
|
+
controlSection: 'misc', controlPriority: 'optional',
|
|
226
|
+
installedSize: info.installedSize ?? (info.size ? Math.ceil(info.size / 1024) : undefined),
|
|
227
|
+
installTime: Date.now(), reason, files, repoType: 'arch',
|
|
228
|
+
repo: opts.repo,
|
|
229
|
+
};
|
|
230
|
+
(0, database_1.addPackage)(db, ip);
|
|
179
231
|
try {
|
|
180
|
-
(0,
|
|
232
|
+
await (0, dpkg_compat_1.writeDpkgEntry)(ip);
|
|
181
233
|
}
|
|
182
|
-
catch {
|
|
183
|
-
|
|
184
|
-
// Run ldconfig if package installs shared libraries
|
|
185
|
-
const hasSoFiles = files.some(f => /\.so(\.|$)/.test(f));
|
|
186
|
-
if (hasSoFiles) {
|
|
187
|
-
try {
|
|
188
|
-
(0, node_child_process_1.execSync)('/usr/sbin/ldconfig', { stdio: 'inherit' });
|
|
234
|
+
catch (e) {
|
|
235
|
+
console.error((0, i18n_1.t)('warn_failed_dpkg_status', String(e)));
|
|
189
236
|
}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
name: info.name, version: info.version,
|
|
194
|
-
architecture: info.arch || 'any',
|
|
195
|
-
description: info.description || '',
|
|
196
|
-
depends: (info.depends || []).join(', '),
|
|
197
|
-
conflicts: (info.conflicts || []).join(', '),
|
|
198
|
-
provides: (info.provides || []).join(', '),
|
|
199
|
-
homepage: info.url,
|
|
200
|
-
controlSection: 'unknown', controlPriority: 'optional',
|
|
201
|
-
installedSize: info.installedSize,
|
|
202
|
-
installTime: Date.now(), reason, files, repoType: 'arch',
|
|
203
|
-
};
|
|
204
|
-
(0, database_1.addPackage)(db, ip);
|
|
205
|
-
try {
|
|
206
|
-
(0, dpkg_compat_1.writeDpkgEntry)(ip);
|
|
237
|
+
(0, database_1.saveDatabase)(db);
|
|
238
|
+
(0, database_1.completeTransaction)(tx.id);
|
|
239
|
+
return true;
|
|
207
240
|
}
|
|
208
|
-
|
|
209
|
-
|
|
241
|
+
finally {
|
|
242
|
+
(0, dpkg_lock_1.releaseDpkgLock)();
|
|
210
243
|
}
|
|
211
|
-
(0, database_1.saveDatabase)(db);
|
|
212
|
-
(0, database_1.completeTransaction)(tx.id);
|
|
213
|
-
return true;
|
|
214
244
|
}
|
|
215
|
-
async function installPkgFile(filePath, reason, opts = {}) {
|
|
245
|
+
async function installPkgFile(filePath, reason, opts = {}, onProgress) {
|
|
216
246
|
if (opts.print) {
|
|
217
247
|
console.log((0, i18n_1.t)('would_install', path.basename(filePath)));
|
|
218
248
|
return true;
|
|
219
249
|
}
|
|
220
250
|
if (filePath.endsWith('.pkg.tar.zst') || filePath.endsWith('.pkg.tar.xz') || filePath.endsWith('.pkg.tar.gz')) {
|
|
221
|
-
return installArch(filePath, reason, opts);
|
|
251
|
+
return installArch(filePath, reason, opts, onProgress);
|
|
222
252
|
}
|
|
223
|
-
return installDeb(filePath, reason, opts);
|
|
253
|
+
return installDeb(filePath, reason, opts, onProgress);
|
|
224
254
|
}
|
|
225
255
|
function parseFtpUrl(url) {
|
|
226
256
|
const rest = url.slice(6);
|
|
@@ -383,42 +413,70 @@ async function installPkg(target, opts = {}) {
|
|
|
383
413
|
return false;
|
|
384
414
|
}
|
|
385
415
|
const cols = process.stdout.columns || 80;
|
|
386
|
-
const barLen = Math.max(
|
|
387
|
-
const
|
|
416
|
+
const barLen = Math.max(cols - 50, 8);
|
|
417
|
+
const drawBar = (pct) => {
|
|
418
|
+
const filled = Math.round((pct / 100) * barLen);
|
|
419
|
+
return `[${'#'.repeat(filled)}${'-'.repeat(barLen - filled)}] ${String(pct).padStart(3)}%`;
|
|
420
|
+
};
|
|
388
421
|
console.log((0, i18n_1.t)('packages_single', fname) + '\n');
|
|
389
422
|
if (!await (0, prompt_1.confirm)((0, i18n_1.t)('confirm_proceed')))
|
|
390
|
-
return
|
|
423
|
+
return true;
|
|
391
424
|
if (opts.print) {
|
|
392
425
|
console.log((0, i18n_1.t)('would_install', fname));
|
|
393
426
|
return true;
|
|
394
427
|
}
|
|
395
|
-
process.stdout.write((0, i18n_1.t)('
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
428
|
+
process.stdout.write(`(1/1) ${(0, i18n_1.t)('progress_loading_files_msg')} ${drawBar(0)}`);
|
|
429
|
+
let lastName = '';
|
|
430
|
+
try {
|
|
431
|
+
const result = await installPkgFile(localPath, 'explicit', opts, (current, total, name) => {
|
|
432
|
+
const pct = total > 0 ? Math.round(current / total * 100) : 100;
|
|
433
|
+
lastName = name;
|
|
434
|
+
process.stdout.write(`\r\x1b[K(1/1) ${(0, i18n_1.t)('progress_loading_files_msg')} ${name} ${drawBar(pct)}`);
|
|
435
|
+
});
|
|
436
|
+
process.stdout.write(`\r\x1b[K(1/1) installing ${fname} ${drawBar(100)}\n`);
|
|
437
|
+
if (isUrl)
|
|
438
|
+
try {
|
|
439
|
+
fs.unlinkSync(localPath);
|
|
440
|
+
}
|
|
441
|
+
catch { }
|
|
442
|
+
return result;
|
|
443
|
+
}
|
|
444
|
+
catch (error) {
|
|
445
|
+
process.stdout.write(`\r\x1b[K`);
|
|
446
|
+
console.error(`error: failed to install ${fname}${lastName ? ` near ${lastName}` : ''}: ${error.message}`);
|
|
447
|
+
if (isUrl)
|
|
448
|
+
try {
|
|
449
|
+
fs.unlinkSync(localPath);
|
|
450
|
+
}
|
|
451
|
+
catch { }
|
|
452
|
+
return false;
|
|
453
|
+
}
|
|
404
454
|
}
|
|
405
455
|
async function installPackages(targets, opts = {}) {
|
|
406
456
|
(0, database_1.initDb)();
|
|
407
|
-
// Validate targets exist
|
|
457
|
+
// Validate targets exist (support repo/pkgname syntax)
|
|
408
458
|
const targetPkgs = [];
|
|
409
459
|
for (const target of targets) {
|
|
410
|
-
const
|
|
460
|
+
const sl = target.indexOf('/');
|
|
461
|
+
const repo = sl > 0 ? target.slice(0, sl) : undefined;
|
|
462
|
+
const requested = sl > 0 ? target.slice(sl + 1) : target;
|
|
463
|
+
const eq = requested.indexOf('=');
|
|
464
|
+
const name = eq >= 0 ? requested.slice(0, eq) : requested;
|
|
465
|
+
const version = eq >= 0 ? requested.slice(eq + 1) : undefined;
|
|
466
|
+
const rp = version ? (0, repository_1.findInRepoVersioned)(name, version, repo)
|
|
467
|
+
: (repo ? (0, repository_1.findInRepoScoped)(repo, name) : (0, repository_1.findInRepo)(name));
|
|
468
|
+
const displayName = target;
|
|
411
469
|
if (!rp) {
|
|
412
470
|
const cacheDir = '/var/cache/pacman-debian/packages';
|
|
413
471
|
if (!fs.existsSync(cacheDir) || fs.readdirSync(cacheDir).length === 0) {
|
|
414
472
|
console.error((0, i18n_1.t)('error_db_not_synced'));
|
|
415
|
-
|
|
473
|
+
throw new Error('package database is not synchronized');
|
|
416
474
|
}
|
|
417
|
-
console.error((0, i18n_1.t)('error_not_found',
|
|
418
|
-
|
|
475
|
+
console.error((0, i18n_1.t)('error_not_found', displayName));
|
|
476
|
+
throw new Error(`target not found: ${displayName}`);
|
|
419
477
|
}
|
|
420
|
-
if (opts.needed && (0, dpkg_compat_1.dpkgHasPackage)(
|
|
421
|
-
console.log((0, i18n_1.t)('pkg_up_to_date',
|
|
478
|
+
if (opts.needed && (0, dpkg_compat_1.dpkgHasPackage)(name)) {
|
|
479
|
+
console.log((0, i18n_1.t)('pkg_up_to_date', name));
|
|
422
480
|
continue;
|
|
423
481
|
}
|
|
424
482
|
targetPkgs.push(rp);
|
|
@@ -427,15 +485,39 @@ async function installPackages(targets, opts = {}) {
|
|
|
427
485
|
return 0;
|
|
428
486
|
// Resolve dependencies
|
|
429
487
|
console.log((0, i18n_1.t)('resolving_deps'));
|
|
430
|
-
const
|
|
488
|
+
const preferredRepos = new Map();
|
|
489
|
+
if (!(0, config_1.loadConfig)().notFindDepsFromCurrentRepo) {
|
|
490
|
+
for (const target of targets) {
|
|
491
|
+
const slash = target.indexOf('/');
|
|
492
|
+
const requested = slash > 0 ? target.slice(slash + 1) : target;
|
|
493
|
+
const eq = requested.indexOf('=');
|
|
494
|
+
const name = eq >= 0 ? requested.slice(0, eq) : requested;
|
|
495
|
+
if (slash > 0)
|
|
496
|
+
preferredRepos.set(name, [target.slice(0, slash)]);
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
const depTargets = targets.map(target => {
|
|
500
|
+
const slash = target.indexOf('/');
|
|
501
|
+
const prefix = slash > 0 ? target.slice(0, slash + 1) : '';
|
|
502
|
+
const requested = slash > 0 ? target.slice(slash + 1) : target;
|
|
503
|
+
const eq = requested.indexOf('=');
|
|
504
|
+
return prefix + (eq >= 0 ? requested.slice(0, eq) : requested);
|
|
505
|
+
});
|
|
506
|
+
const { install: depResults, errors: depErrors } = (0, deps_1.resolveDeps)(depTargets, { preferredRepos });
|
|
431
507
|
for (const err of depErrors)
|
|
432
508
|
console.error((0, i18n_1.t)('warn_prefix', err));
|
|
433
|
-
if (depErrors.length > 0
|
|
434
|
-
|
|
509
|
+
if (depErrors.length > 0)
|
|
510
|
+
throw new Error('dependency resolution failed');
|
|
435
511
|
// Dedupe: deps first, then targets (Arch pacman convention)
|
|
436
512
|
const allPkgs = [];
|
|
437
513
|
const seen = new Set();
|
|
514
|
+
const targetNames = new Set(targetPkgs.map(p => p.package));
|
|
438
515
|
for (const dr of depResults) {
|
|
516
|
+
// The explicit target below is authoritative, including an exact
|
|
517
|
+
// `name=version` request; do not let an unversioned dependency lookup
|
|
518
|
+
// replace it with the first repository match.
|
|
519
|
+
if (targetNames.has(dr.pkg.package))
|
|
520
|
+
continue;
|
|
439
521
|
if (seen.has(dr.pkg.package))
|
|
440
522
|
continue;
|
|
441
523
|
seen.add(dr.pkg.package);
|
|
@@ -456,11 +538,29 @@ async function installPackages(targets, opts = {}) {
|
|
|
456
538
|
if (conflicts.length > 0) {
|
|
457
539
|
console.error('');
|
|
458
540
|
console.error((0, i18n_1.t)('error_unresolvable_conflicts'));
|
|
459
|
-
|
|
541
|
+
throw new Error('unresolvable package conflicts detected');
|
|
460
542
|
}
|
|
461
543
|
const totalSize = allPkgs.reduce((s, p) => s + (p.size || 0), 0);
|
|
462
544
|
const totalInst = allPkgs.reduce((s, p) => s + ((p.installedSize || 0) * 1024), 0);
|
|
463
|
-
|
|
545
|
+
const _cfg = (0, config_1.loadConfig)();
|
|
546
|
+
if (_cfg.verbosePkgLists) {
|
|
547
|
+
const cols = process.stdout.columns || 80;
|
|
548
|
+
const nameW = Math.max(20, Math.floor(cols * 0.3));
|
|
549
|
+
const verW = Math.max(16, Math.floor(cols * 0.2));
|
|
550
|
+
const repoW = Math.max(10, Math.floor(cols * 0.15));
|
|
551
|
+
console.log((0, i18n_1.t)('packages_multi', String(allPkgs.length), ''));
|
|
552
|
+
console.log(` ${'Name'.padEnd(nameW)} ${'Version'.padEnd(verW)} ${'Repo'.padEnd(repoW)} Size`);
|
|
553
|
+
console.log(` ${'─'.repeat(nameW)} ${'─'.repeat(verW)} ${'─'.repeat(repoW)} ${'─'.repeat(8)}`);
|
|
554
|
+
for (const p of allPkgs) {
|
|
555
|
+
const name = p.package.length > nameW ? p.package.slice(0, nameW - 3) + '...' : p.package;
|
|
556
|
+
const ver = (p.version || '').length > verW ? (p.version || '').slice(0, verW - 3) + '...' : (p.version || '');
|
|
557
|
+
console.log(` ${name.padEnd(nameW)} ${ver.padEnd(verW)} ${p.repo.padEnd(repoW)} ${(0, format_1.formatBytes)(p.size || 0).padStart(8)}`);
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
else {
|
|
561
|
+
console.log((0, i18n_1.t)('packages_multi', String(allPkgs.length), allPkgs.map(p => p.package).join(' ')));
|
|
562
|
+
}
|
|
563
|
+
console.log('');
|
|
464
564
|
console.log((0, i18n_1.t)('total_download_size', (0, format_1.formatBytes)(totalSize).padStart(9)));
|
|
465
565
|
console.log((0, i18n_1.t)('total_installed_size', (0, format_1.formatBytes)(totalInst).padStart(9)));
|
|
466
566
|
console.log('');
|
|
@@ -471,11 +571,13 @@ async function installPackages(targets, opts = {}) {
|
|
|
471
571
|
console.log((0, i18n_1.t)('would_install', `${p.package}-${p.version}`));
|
|
472
572
|
return allPkgs.length;
|
|
473
573
|
}
|
|
574
|
+
// ---- Transaction start ----
|
|
575
|
+
console.log((0, i18n_1.t)('processing_changes'));
|
|
474
576
|
// ---- Download phase ----
|
|
475
577
|
const total = allPkgs.length;
|
|
476
578
|
const cols = process.stdout.columns || 80;
|
|
477
579
|
const parallelN = (0, config_1.loadConfig)().parallelDownloads || 1;
|
|
478
|
-
console.log((0, i18n_1.t)('
|
|
580
|
+
console.log((0, i18n_1.t)('retrieving_packages'));
|
|
479
581
|
const downloaded = [];
|
|
480
582
|
const startTime = Date.now();
|
|
481
583
|
/** Render a right-aligned progress bar line. leftText precedes `[`, rightText follows `]`. */
|
|
@@ -487,7 +589,11 @@ async function installPackages(targets, opts = {}) {
|
|
|
487
589
|
return line;
|
|
488
590
|
};
|
|
489
591
|
const nameWidth = Math.max(25, Math.floor(cols * 0.35));
|
|
592
|
+
let dlIdx = 0;
|
|
490
593
|
const downloadOne = async (p) => {
|
|
594
|
+
const idx = ++dlIdx;
|
|
595
|
+
const digits = String(total).length;
|
|
596
|
+
const prefix = `(${String(idx).padStart(digits)}/${String(total).padEnd(digits)})`;
|
|
491
597
|
const pkgLabel = `${p.package}-${p.version}-${p.architecture || 'any'}`;
|
|
492
598
|
const displayName = pkgLabel.length > nameWidth ? pkgLabel.slice(0, nameWidth - 3) + '...' : pkgLabel;
|
|
493
599
|
let finalRate = 0, prevTime = Date.now(), prevBytes = 0, smoothRate = 0;
|
|
@@ -504,11 +610,11 @@ async function installPackages(targets, opts = {}) {
|
|
|
504
610
|
const eta = smoothRate > 0 && tot > 0 ? (tot - rec) / smoothRate : 0;
|
|
505
611
|
const etaS = (0, progress_1.formatETA)(eta);
|
|
506
612
|
const pct = tot > 0 ? Math.round(rec / tot * 100) : 0;
|
|
507
|
-
const line = barLine(` ${displayName.padEnd(nameWidth)} ${dl.val.padStart(6)} ${dl.unit.padEnd(3)} ${rateStr} ${etaS} [`, `] ${String(pct).padStart(3)}%`, pct);
|
|
613
|
+
const line = barLine(` ${prefix} ${displayName.padEnd(nameWidth)} ${dl.val.padStart(6)} ${dl.unit.padEnd(3)} ${rateStr} ${etaS} [`, `] ${String(pct).padStart(3)}%`, pct);
|
|
508
614
|
process.stdout.write(`\r${line}`);
|
|
509
615
|
});
|
|
510
616
|
const finalSize = (0, progress_1.humanSize)(p.size || 0, 1);
|
|
511
|
-
const compLine = barLine(` ${displayName.padEnd(nameWidth)} ${finalSize.val.padStart(6)} ${finalSize.unit.padEnd(3)} ${(0, progress_1.formatRate)(finalRate)} ${'00:00'} [`, `] 100%`, 100);
|
|
617
|
+
const compLine = barLine(` ${prefix} ${displayName.padEnd(nameWidth)} ${finalSize.val.padStart(6)} ${finalSize.unit.padEnd(3)} ${(0, progress_1.formatRate)(finalRate)} ${'00:00'} [`, `] 100%`, 100);
|
|
512
618
|
process.stdout.write(`\r${compLine}\n`);
|
|
513
619
|
return { pkg: p, path: localPath, rate: finalRate };
|
|
514
620
|
};
|
|
@@ -522,7 +628,12 @@ async function installPackages(targets, opts = {}) {
|
|
|
522
628
|
}
|
|
523
629
|
};
|
|
524
630
|
const workers = Array.from({ length: Math.min(parallelN, total) }, () => doBatch());
|
|
525
|
-
|
|
631
|
+
try {
|
|
632
|
+
await Promise.all(workers);
|
|
633
|
+
}
|
|
634
|
+
catch (error) {
|
|
635
|
+
throw new Error(`package download failed: ${error.message}`);
|
|
636
|
+
}
|
|
526
637
|
// 汇总行
|
|
527
638
|
const totalSz = allPkgs.reduce((s, p) => s + (p.size || 0), 0);
|
|
528
639
|
const elapsed = (Date.now() - startTime) / 1000;
|
|
@@ -533,7 +644,10 @@ async function installPackages(targets, opts = {}) {
|
|
|
533
644
|
const totalLine = barLine(` ${totalLabel.padEnd(nameWidth)} ${totalSizeStr.val.padStart(6)} ${totalSizeStr.unit.padEnd(3)} ${totalRateStr} ${'00:00'} [`, `] 100%`, 100);
|
|
534
645
|
process.stdout.write(totalLine + '\n');
|
|
535
646
|
// ---- Pre-install checks (after download, matching real pacman order) ----
|
|
536
|
-
const
|
|
647
|
+
const totalChk = downloaded.length;
|
|
648
|
+
const digitsChk = String(totalChk).length;
|
|
649
|
+
let chkIdx = 0;
|
|
650
|
+
const prefixChk = () => `(${String(++chkIdx).padStart(digitsChk)}/${String(totalChk).padEnd(digitsChk)})`;
|
|
537
651
|
const checkMessages = [
|
|
538
652
|
(0, i18n_1.t)('progress_checking_keys_msg'),
|
|
539
653
|
(0, i18n_1.t)('progress_checking_integrity_msg'),
|
|
@@ -541,10 +655,11 @@ async function installPackages(targets, opts = {}) {
|
|
|
541
655
|
(0, i18n_1.t)('progress_checking_conflicts_msg'),
|
|
542
656
|
(0, i18n_1.t)('progress_checking_space_msg'),
|
|
543
657
|
];
|
|
544
|
-
const
|
|
658
|
+
const maxChkMsgTw = Math.max(...checkMessages.map(m => (0, progress_1.terminalWidth)(m)));
|
|
545
659
|
const fmtCheck = (msg) => {
|
|
546
|
-
const
|
|
547
|
-
const
|
|
660
|
+
const p = prefixChk();
|
|
661
|
+
const pad = maxChkMsgTw - (0, progress_1.terminalWidth)(msg);
|
|
662
|
+
const line = barLine(` ${p} ${msg}${' '.repeat(pad)} [`, `] 100%`, 100);
|
|
548
663
|
process.stdout.write(line + '\n');
|
|
549
664
|
};
|
|
550
665
|
// 1. Keys check
|
|
@@ -564,8 +679,9 @@ async function installPackages(targets, opts = {}) {
|
|
|
564
679
|
// 3. Load files — validate package archive format
|
|
565
680
|
for (const { pkg: p, path: fp } of downloaded) {
|
|
566
681
|
try {
|
|
567
|
-
if (fp.endsWith('.deb'))
|
|
568
|
-
(0,
|
|
682
|
+
if (fp.endsWith('.deb')) {
|
|
683
|
+
(0, deb_1.parseDeb)(fp);
|
|
684
|
+
}
|
|
569
685
|
else
|
|
570
686
|
(0, node_child_process_1.execSync)(`tar -t --zstd -f "${fp}" 2>/dev/null | head -1`, { encoding: 'utf8', timeout: 5000 });
|
|
571
687
|
}
|
|
@@ -575,30 +691,47 @@ async function installPackages(targets, opts = {}) {
|
|
|
575
691
|
}
|
|
576
692
|
}
|
|
577
693
|
fmtCheck((0, i18n_1.t)('progress_loading_files_msg'));
|
|
694
|
+
if (!integrityOk)
|
|
695
|
+
throw new Error('package integrity check failed');
|
|
578
696
|
// 4. File conflict check
|
|
579
697
|
fmtCheck((0, i18n_1.t)('progress_checking_conflicts_msg'));
|
|
580
698
|
// 5. Available space check
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
const
|
|
586
|
-
const
|
|
587
|
-
if (
|
|
588
|
-
|
|
589
|
-
|
|
699
|
+
const cfg = (0, config_1.loadConfig)();
|
|
700
|
+
if (cfg.checkSpace) {
|
|
701
|
+
try {
|
|
702
|
+
const dfPath = cfg.rootDir === '/' ? '/' : cfg.rootDir;
|
|
703
|
+
const df = (0, node_child_process_1.execSync)(`df -k "${dfPath}"`, { encoding: 'utf8', timeout: 5000 });
|
|
704
|
+
const match = df.trim().split('\n').pop()?.match(/\s(\d+)\s+(\d+)\s+(\d+)/);
|
|
705
|
+
if (match) {
|
|
706
|
+
const availKb = parseInt(match[3], 10);
|
|
707
|
+
const needKb = allPkgs.reduce((s, p) => s + ((p.installedSize || 0)), 0);
|
|
708
|
+
if (availKb < needKb) {
|
|
709
|
+
console.error(`\n error: not enough disk space (need ${(needKb / 1024).toFixed(1)} MiB, have ${(availKb / 1024).toFixed(1)} MiB)`);
|
|
710
|
+
throw new Error('not enough disk space');
|
|
711
|
+
}
|
|
590
712
|
}
|
|
591
713
|
}
|
|
714
|
+
catch (error) {
|
|
715
|
+
if (error.message === 'not enough disk space')
|
|
716
|
+
throw error;
|
|
717
|
+
}
|
|
592
718
|
}
|
|
593
|
-
catch { }
|
|
594
719
|
fmtCheck((0, i18n_1.t)('progress_checking_space_msg'));
|
|
595
|
-
//
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
720
|
+
// Hold dpkg locks for the complete system-modifying transaction.
|
|
721
|
+
await (0, dpkg_lock_1.acquireDpkgLock)();
|
|
722
|
+
try {
|
|
723
|
+
for (const { pkg: p, path: localPath } of downloaded) {
|
|
724
|
+
const isExplicit = targetPkgs.some(r => r.package === p.package);
|
|
725
|
+
const ok = await installPkgFile(localPath, isExplicit ? (opts.asdeps ? 'dependency' : 'explicit') : 'dependency', { ...opts, repo: p.repo });
|
|
726
|
+
if (!ok)
|
|
727
|
+
throw new Error(`failed to install ${p.package}`);
|
|
728
|
+
}
|
|
729
|
+
// Post-transaction hooks
|
|
730
|
+
process.stdout.write((0, i18n_1.t)('running_hooks') + '\n');
|
|
731
|
+
}
|
|
732
|
+
finally {
|
|
733
|
+
(0, dpkg_lock_1.releaseDpkgLock)();
|
|
599
734
|
}
|
|
600
|
-
// Post-transaction hooks
|
|
601
|
-
process.stdout.write((0, i18n_1.t)('running_hooks') + '\n');
|
|
602
735
|
return total;
|
|
603
736
|
}
|
|
604
737
|
//# sourceMappingURL=install.js.map
|