pacman-debian 7.4.0 → 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.
Files changed (59) hide show
  1. package/dist/cli/archlinux-java.js +36 -12
  2. package/dist/cli/archlinux-java.js.map +1 -1
  3. package/dist/cli/paclink.js +17 -28
  4. package/dist/cli/paclink.js.map +1 -1
  5. package/dist/cli/pacman.d.ts.map +1 -1
  6. package/dist/cli/pacman.js +18 -10
  7. package/dist/cli/pacman.js.map +1 -1
  8. package/dist/core/deps.d.ts +2 -0
  9. package/dist/core/deps.d.ts.map +1 -1
  10. package/dist/core/deps.js +19 -5
  11. package/dist/core/deps.js.map +1 -1
  12. package/dist/core/options.d.ts +1 -0
  13. package/dist/core/options.d.ts.map +1 -1
  14. package/dist/core/pkgfile.d.ts +2 -0
  15. package/dist/core/pkgfile.d.ts.map +1 -1
  16. package/dist/core/pkgfile.js +6 -0
  17. package/dist/core/pkgfile.js.map +1 -1
  18. package/dist/core/tar.d.ts +1 -0
  19. package/dist/core/tar.d.ts.map +1 -1
  20. package/dist/core/tar.js +54 -7
  21. package/dist/core/tar.js.map +1 -1
  22. package/dist/core/types.d.ts +5 -0
  23. package/dist/core/types.d.ts.map +1 -1
  24. package/dist/db/dpkg-compat.d.ts +5 -2
  25. package/dist/db/dpkg-compat.d.ts.map +1 -1
  26. package/dist/db/dpkg-compat.js +124 -51
  27. package/dist/db/dpkg-compat.js.map +1 -1
  28. package/dist/db/localdb.d.ts.map +1 -1
  29. package/dist/db/localdb.js +21 -2
  30. package/dist/db/localdb.js.map +1 -1
  31. package/dist/lock/dpkg-helper +0 -0
  32. package/dist/lock/dpkg-lock.d.ts +5 -0
  33. package/dist/lock/dpkg-lock.d.ts.map +1 -0
  34. package/dist/lock/dpkg-lock.js +113 -0
  35. package/dist/lock/dpkg-lock.js.map +1 -0
  36. package/dist/ops/install.d.ts.map +1 -1
  37. package/dist/ops/install.js +227 -144
  38. package/dist/ops/install.js.map +1 -1
  39. package/dist/ops/query.js +3 -2
  40. package/dist/ops/query.js.map +1 -1
  41. package/dist/ops/remove.d.ts.map +1 -1
  42. package/dist/ops/remove.js +106 -60
  43. package/dist/ops/remove.js.map +1 -1
  44. package/dist/ops/upgrade.d.ts.map +1 -1
  45. package/dist/ops/upgrade.js +6 -5
  46. package/dist/ops/upgrade.js.map +1 -1
  47. package/dist/repo/config.d.ts.map +1 -1
  48. package/dist/repo/config.js +26 -3
  49. package/dist/repo/config.js.map +1 -1
  50. package/dist/repo/repository.d.ts +6 -0
  51. package/dist/repo/repository.d.ts.map +1 -1
  52. package/dist/repo/repository.js +199 -24
  53. package/dist/repo/repository.js.map +1 -1
  54. package/dist/scripts/setup.js +25 -76
  55. package/dist/scripts/setup.js.map +1 -1
  56. package/lib/pac4deb/include/alpm.h +2 -1
  57. package/lib/pac4deb/src/libalpm.c +76 -21
  58. package/package.json +2 -2
  59. package/resources/paclinks.conf +64 -0
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.acquireDpkgLock = acquireDpkgLock;
37
+ exports.releaseDpkgLock = releaseDpkgLock;
38
+ exports.isDpkgLocked = isDpkgLocked;
39
+ exports.withDpkgLock = withDpkgLock;
40
+ const fs = __importStar(require("node:fs"));
41
+ const path = __importStar(require("node:path"));
42
+ const node_child_process_1 = require("node:child_process");
43
+ let _lockProc = null;
44
+ let _lockCount = 0;
45
+ function helperPath() {
46
+ const local = path.join(__dirname, 'dpkg-helper');
47
+ if (fs.existsSync(local))
48
+ return local;
49
+ const dev = path.join(__dirname, '../../dist/lock/dpkg-helper');
50
+ if (fs.existsSync(dev))
51
+ return dev;
52
+ return '/usr/local/lib/pacman-debian/dpkg-helper';
53
+ }
54
+ async function acquireDpkgLock(timeout = 0) {
55
+ if (_lockCount > 0) {
56
+ _lockCount++;
57
+ return;
58
+ }
59
+ const hp = helperPath();
60
+ return new Promise((resolve, reject) => {
61
+ const cp = (0, node_child_process_1.spawn)(hp, [String(timeout)], {
62
+ stdio: ['pipe', 'pipe', 'pipe'],
63
+ });
64
+ let resolved = false;
65
+ const errChunks = [];
66
+ cp.stderr.on('data', (c) => errChunks.push(c));
67
+ cp.on('exit', (code) => {
68
+ if (!resolved) {
69
+ resolved = true;
70
+ const err = Buffer.concat(errChunks).toString('utf8');
71
+ reject(new Error(err || `dpkg-lock exited with code ${code}`));
72
+ }
73
+ });
74
+ cp.on('error', (err) => {
75
+ if (!resolved) {
76
+ resolved = true;
77
+ reject(err);
78
+ }
79
+ });
80
+ cp.stdout.on('data', (data) => {
81
+ if (!resolved && data.toString('utf8').includes('ok')) {
82
+ resolved = true;
83
+ _lockProc = cp;
84
+ _lockCount = 1;
85
+ resolve();
86
+ }
87
+ });
88
+ });
89
+ }
90
+ function releaseDpkgLock() {
91
+ if (_lockCount > 1) {
92
+ _lockCount--;
93
+ return;
94
+ }
95
+ if (_lockProc) {
96
+ _lockProc.kill();
97
+ _lockProc = null;
98
+ }
99
+ _lockCount = 0;
100
+ }
101
+ function isDpkgLocked() {
102
+ return _lockCount > 0;
103
+ }
104
+ async function withDpkgLock(fn, timeout = 30) {
105
+ await acquireDpkgLock(timeout);
106
+ try {
107
+ return await fn();
108
+ }
109
+ finally {
110
+ releaseDpkgLock();
111
+ }
112
+ }
113
+ //# sourceMappingURL=dpkg-lock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dpkg-lock.js","sourceRoot":"","sources":["../../src/lock/dpkg-lock.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/ops/install.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAiBpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAwJtD,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,YAAY,EAAE,IAAI,GAAE,cAAmB,EAAE,UAAU,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC,CAMpK;AA8GD,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,cAAmB,GAAG,OAAO,CAAC,OAAO,CAAC,CAmD5F;AAED,wBAAsB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,GAAE,cAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,CAqQnG"}
1
+ {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/ops/install.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAkBpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAiKtD,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,YAAY,EAAE,IAAI,GAAE,cAAmB,EAAE,UAAU,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC,CAMpK;AA8GD,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,cAAmB,GAAG,OAAO,CAAC,OAAO,CAAC,CA+D5F;AAED,wBAAsB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,GAAE,cAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,CAiTnG"}
@@ -49,6 +49,7 @@ 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");
@@ -76,50 +77,56 @@ async function installDeb(filePath, reason, opts = {}, onProgress) {
76
77
  if (realFiles.length > 0)
77
78
  return true;
78
79
  }
79
- const tx = (0, database_1.createTransaction)('install', control.package, control.version);
80
- if (!opts.noscriptlet) {
81
- const preinst = (0, deb_1.readScript)(pkg, 'preinst');
82
- if (preinst)
83
- (0, database_1.saveScript)(control.package, 'preinst', preinst);
84
- (0, database_1.runScript)(control.package, 'preinst', ['install']);
85
- }
86
- const files = (0, tar_1.extractTar)(pkg.dataTar, '/', onProgress, _cfg.noExtract, _cfg.noUpgrade);
87
- if (!opts.noscriptlet) {
88
- const postinst = (0, deb_1.readScript)(pkg, 'postinst');
89
- if (postinst)
90
- (0, database_1.saveScript)(control.package, 'postinst', postinst);
91
- (0, database_1.runScript)(control.package, 'postinst', ['configure']);
92
- }
93
- // Run ldconfig if package installs shared libraries
94
- const hasSoFiles = files.some(f => /\.so(\.|$)/.test(f));
95
- if (hasSoFiles) {
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);
96
117
  try {
97
- (0, node_child_process_1.execSync)('/usr/sbin/ldconfig', { stdio: 'inherit' });
118
+ await (0, dpkg_compat_1.writeDpkgEntry)(ip);
98
119
  }
99
- catch { }
100
- }
101
- const ip = {
102
- name: control.package, version: control.version,
103
- architecture: control.architecture || 'amd64',
104
- description: control.description || '',
105
- depends: control.depends, 'pre-depends': control['pre-depends'],
106
- conflicts: control.conflicts, provides: control.provides,
107
- maintainer: control.maintainer, homepage: control.homepage,
108
- controlSection: control.section || 'misc',
109
- controlPriority: control.priority || 'optional',
110
- installedSize: control['installed-size'] ? parseInt(control['installed-size'], 10) : undefined,
111
- installTime: Date.now(), reason, files,
112
- };
113
- (0, database_1.addPackage)(db, ip);
114
- try {
115
- (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;
116
126
  }
117
- catch (e) {
118
- console.error((0, i18n_1.t)('warn_failed_dpkg_status', String(e)));
127
+ finally {
128
+ (0, dpkg_lock_1.releaseDpkgLock)();
119
129
  }
120
- (0, database_1.saveDatabase)(db);
121
- (0, database_1.completeTransaction)(tx.id);
122
- return true;
123
130
  }
124
131
  /* When installing a real package, remove any existing link with the same name.
125
132
  Links are virtual mappings (Debian→Arch), real packages take precedence. */
@@ -140,91 +147,100 @@ async function installArch(filePath, reason, opts = {}, onProgress) {
140
147
  const existing = (0, database_1.getPackage)(db, info.name);
141
148
  if (opts.needed && existing && existing.version === info.version)
142
149
  return false;
143
- const tx = (0, database_1.createTransaction)('install', info.name, info.version);
144
- if (!opts.noscriptlet && (install?.pre_install || install?.post_install)) {
145
- const parts = [];
146
- if (install.pre_install)
147
- parts.push(`pre_install() {\n${install.pre_install}\n}`);
148
- if (install.post_install)
149
- parts.push(`post_install() {\n${install.post_install}\n}`);
150
- if (install.pre_remove)
151
- parts.push(`pre_remove() {\n${install.pre_remove}\n}`);
152
- if (install.post_remove)
153
- parts.push(`post_remove() {\n${install.post_remove}\n}`);
154
- const script = parts.join('\n') + '\n';
155
- (0, database_1.saveScript)(info.name, '.INSTALL', script);
156
- const tmpScript = `/var/lib/pacman-debian/info/${info.name}/.INSTALL`;
157
- if (install?.pre_install) {
158
- try {
159
- (0, node_child_process_1.execSync)(`/bin/bash -c 'source "${tmpScript}" && pre_install' 2>&-`, { stdio: 'pipe' });
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 { }
160
171
  }
161
- catch { }
162
172
  }
163
- }
164
- const files = [];
165
- const total = dataBlocks.length;
166
- const _archCfg = (0, config_1.loadConfig)();
167
- const matchArch = (p, name) => p === name || p === '/' + name || (p.endsWith('/*') && name.startsWith(p.slice(0, -1)));
168
- for (let i = 0; i < total; i++) {
169
- const entry = dataBlocks[i];
170
- const targetPath = path.resolve('/', entry.name);
171
- if (!targetPath.startsWith('/'))
172
- continue;
173
- files.push('/' + entry.name);
174
- if (_archCfg.noExtract.some(p => matchArch(p, entry.name)))
175
- continue;
176
- if (entry.data) {
177
- fs.mkdirSync(path.dirname(targetPath), { recursive: true });
178
- if (_archCfg.noUpgrade.some(p => matchArch(p, entry.name)) && fs.existsSync(targetPath)) {
179
- const bak = targetPath + '.pacnew';
180
- fs.writeFileSync(bak, entry.data, { mode: 0o755 });
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
+ }
181
194
  }
182
- else {
183
- fs.writeFileSync(targetPath, entry.data, { mode: 0o755 });
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
+ }
202
+ try {
203
+ (0, node_child_process_1.execSync)(`/bin/bash -c 'source "${tmpScript}" && post_install' 2>&-`, { stdio: 'pipe' });
184
204
  }
205
+ catch { }
185
206
  }
186
- onProgress?.(i + 1, total, entry.name);
187
- }
188
- if (!opts.noscriptlet && install?.post_install) {
189
- const tmpScript = `/var/lib/pacman-debian/info/${info.name}/.INSTALL`;
190
- if (!fs.existsSync(tmpScript)) {
191
- (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 { }
192
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);
193
231
  try {
194
- (0, node_child_process_1.execSync)(`/bin/bash -c 'source "${tmpScript}" && post_install' 2>&-`, { stdio: 'pipe' });
232
+ await (0, dpkg_compat_1.writeDpkgEntry)(ip);
195
233
  }
196
- catch { }
197
- }
198
- // Run ldconfig if package installs shared libraries
199
- const hasSoFiles = files.some(f => /\.so(\.|$)/.test(f));
200
- if (hasSoFiles) {
201
- try {
202
- (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)));
203
236
  }
204
- catch { }
205
- }
206
- const ip = {
207
- name: info.name, version: info.version,
208
- architecture: info.arch || 'any',
209
- description: info.description || '',
210
- depends: (info.depends || []).join(', '),
211
- conflicts: (info.conflicts || []).join(', '),
212
- provides: (info.provides || []).join(', '),
213
- homepage: info.url,
214
- controlSection: 'unknown', controlPriority: 'optional',
215
- installedSize: info.installedSize,
216
- installTime: Date.now(), reason, files, repoType: 'arch',
217
- };
218
- (0, database_1.addPackage)(db, ip);
219
- try {
220
- (0, dpkg_compat_1.writeDpkgEntry)(ip);
237
+ (0, database_1.saveDatabase)(db);
238
+ (0, database_1.completeTransaction)(tx.id);
239
+ return true;
221
240
  }
222
- catch (e) {
223
- console.error((0, i18n_1.t)('warn_failed_dpkg_status', String(e)));
241
+ finally {
242
+ (0, dpkg_lock_1.releaseDpkgLock)();
224
243
  }
225
- (0, database_1.saveDatabase)(db);
226
- (0, database_1.completeTransaction)(tx.id);
227
- return true;
228
244
  }
229
245
  async function installPkgFile(filePath, reason, opts = {}, onProgress) {
230
246
  if (opts.print) {
@@ -404,38 +420,63 @@ async function installPkg(target, opts = {}) {
404
420
  };
405
421
  console.log((0, i18n_1.t)('packages_single', fname) + '\n');
406
422
  if (!await (0, prompt_1.confirm)((0, i18n_1.t)('confirm_proceed')))
407
- return false;
423
+ return true;
408
424
  if (opts.print) {
409
425
  console.log((0, i18n_1.t)('would_install', fname));
410
426
  return true;
411
427
  }
412
- console.log(`(1/1) ${(0, i18n_1.t)('progress_loading_files_msg')} ${drawBar(0)}`);
413
- const result = await installPkgFile(localPath, 'explicit', opts);
414
- console.log(`(1/1) installing ${fname} ${drawBar(100)}`);
415
- if (isUrl)
416
- try {
417
- fs.unlinkSync(localPath);
418
- }
419
- catch { }
420
- return result;
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
+ }
421
454
  }
422
455
  async function installPackages(targets, opts = {}) {
423
456
  (0, database_1.initDb)();
424
- // Validate targets exist
457
+ // Validate targets exist (support repo/pkgname syntax)
425
458
  const targetPkgs = [];
426
459
  for (const target of targets) {
427
- const rp = (0, repository_1.findInRepo)(target);
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;
428
469
  if (!rp) {
429
470
  const cacheDir = '/var/cache/pacman-debian/packages';
430
471
  if (!fs.existsSync(cacheDir) || fs.readdirSync(cacheDir).length === 0) {
431
472
  console.error((0, i18n_1.t)('error_db_not_synced'));
432
- return 0;
473
+ throw new Error('package database is not synchronized');
433
474
  }
434
- console.error((0, i18n_1.t)('error_not_found', target));
435
- continue;
475
+ console.error((0, i18n_1.t)('error_not_found', displayName));
476
+ throw new Error(`target not found: ${displayName}`);
436
477
  }
437
- if (opts.needed && (0, dpkg_compat_1.dpkgHasPackage)(target)) {
438
- console.log((0, i18n_1.t)('pkg_up_to_date', target));
478
+ if (opts.needed && (0, dpkg_compat_1.dpkgHasPackage)(name)) {
479
+ console.log((0, i18n_1.t)('pkg_up_to_date', name));
439
480
  continue;
440
481
  }
441
482
  targetPkgs.push(rp);
@@ -444,15 +485,39 @@ async function installPackages(targets, opts = {}) {
444
485
  return 0;
445
486
  // Resolve dependencies
446
487
  console.log((0, i18n_1.t)('resolving_deps'));
447
- const { install: depResults, errors: depErrors } = (0, deps_1.resolveDeps)(targets);
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 });
448
507
  for (const err of depErrors)
449
508
  console.error((0, i18n_1.t)('warn_prefix', err));
450
- if (depErrors.length > 0 && depResults.length === 0)
451
- return 0;
509
+ if (depErrors.length > 0)
510
+ throw new Error('dependency resolution failed');
452
511
  // Dedupe: deps first, then targets (Arch pacman convention)
453
512
  const allPkgs = [];
454
513
  const seen = new Set();
514
+ const targetNames = new Set(targetPkgs.map(p => p.package));
455
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;
456
521
  if (seen.has(dr.pkg.package))
457
522
  continue;
458
523
  seen.add(dr.pkg.package);
@@ -473,7 +538,7 @@ async function installPackages(targets, opts = {}) {
473
538
  if (conflicts.length > 0) {
474
539
  console.error('');
475
540
  console.error((0, i18n_1.t)('error_unresolvable_conflicts'));
476
- return 0;
541
+ throw new Error('unresolvable package conflicts detected');
477
542
  }
478
543
  const totalSize = allPkgs.reduce((s, p) => s + (p.size || 0), 0);
479
544
  const totalInst = allPkgs.reduce((s, p) => s + ((p.installedSize || 0) * 1024), 0);
@@ -563,7 +628,12 @@ async function installPackages(targets, opts = {}) {
563
628
  }
564
629
  };
565
630
  const workers = Array.from({ length: Math.min(parallelN, total) }, () => doBatch());
566
- await Promise.all(workers);
631
+ try {
632
+ await Promise.all(workers);
633
+ }
634
+ catch (error) {
635
+ throw new Error(`package download failed: ${error.message}`);
636
+ }
567
637
  // 汇总行
568
638
  const totalSz = allPkgs.reduce((s, p) => s + (p.size || 0), 0);
569
639
  const elapsed = (Date.now() - startTime) / 1000;
@@ -621,6 +691,8 @@ async function installPackages(targets, opts = {}) {
621
691
  }
622
692
  }
623
693
  fmtCheck((0, i18n_1.t)('progress_loading_files_msg'));
694
+ if (!integrityOk)
695
+ throw new Error('package integrity check failed');
624
696
  // 4. File conflict check
625
697
  fmtCheck((0, i18n_1.t)('progress_checking_conflicts_msg'));
626
698
  // 5. Available space check
@@ -635,20 +707,31 @@ async function installPackages(targets, opts = {}) {
635
707
  const needKb = allPkgs.reduce((s, p) => s + ((p.installedSize || 0)), 0);
636
708
  if (availKb < needKb) {
637
709
  console.error(`\n error: not enough disk space (need ${(needKb / 1024).toFixed(1)} MiB, have ${(availKb / 1024).toFixed(1)} MiB)`);
638
- return 0;
710
+ throw new Error('not enough disk space');
639
711
  }
640
712
  }
641
713
  }
642
- catch { }
714
+ catch (error) {
715
+ if (error.message === 'not enough disk space')
716
+ throw error;
717
+ }
643
718
  }
644
719
  fmtCheck((0, i18n_1.t)('progress_checking_space_msg'));
645
- // Install phase (serial for safety)
646
- for (const { pkg: p, path: localPath } of downloaded) {
647
- const isExplicit = targetPkgs.some(r => r.package === p.package);
648
- await installPkgFile(localPath, isExplicit ? (opts.asdeps ? 'dependency' : 'explicit') : 'dependency', opts);
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)();
649
734
  }
650
- // Post-transaction hooks
651
- process.stdout.write((0, i18n_1.t)('running_hooks') + '\n');
652
735
  return total;
653
736
  }
654
737
  //# sourceMappingURL=install.js.map