pacman-debian 7.3.34 → 7.4.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 (78) hide show
  1. package/README.md +12 -0
  2. package/README_zh-CN.md +11 -0
  3. package/dist/cli/paclink.js +95 -0
  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 +54 -7
  7. package/dist/cli/pacman.js.map +1 -1
  8. package/dist/cli/pactree.d.ts +3 -0
  9. package/dist/cli/pactree.d.ts.map +1 -0
  10. package/dist/cli/pactree.js +216 -0
  11. package/dist/cli/pactree.js.map +1 -0
  12. package/dist/core/deps.d.ts +5 -0
  13. package/dist/core/deps.d.ts.map +1 -1
  14. package/dist/core/deps.js +85 -19
  15. package/dist/core/deps.js.map +1 -1
  16. package/dist/core/logger.d.ts +7 -0
  17. package/dist/core/logger.d.ts.map +1 -0
  18. package/dist/core/logger.js +93 -0
  19. package/dist/core/logger.js.map +1 -0
  20. package/dist/core/options.d.ts +1 -0
  21. package/dist/core/options.d.ts.map +1 -1
  22. package/dist/core/paclinks.d.ts +9 -0
  23. package/dist/core/paclinks.d.ts.map +1 -0
  24. package/dist/core/paclinks.js +69 -0
  25. package/dist/core/paclinks.js.map +1 -0
  26. package/dist/core/tar.d.ts +2 -1
  27. package/dist/core/tar.d.ts.map +1 -1
  28. package/dist/core/tar.js +33 -4
  29. package/dist/core/tar.js.map +1 -1
  30. package/dist/core/types.d.ts +12 -0
  31. package/dist/core/types.d.ts.map +1 -1
  32. package/dist/db/dpkg-compat.js +6 -6
  33. package/dist/db/dpkg-compat.js.map +1 -1
  34. package/dist/debug-upgrade.d.ts +2 -0
  35. package/dist/debug-upgrade.d.ts.map +1 -0
  36. package/dist/debug-upgrade.js +140 -0
  37. package/dist/debug-upgrade.js.map +1 -0
  38. package/dist/i18n/en.json +2 -0
  39. package/dist/i18n/paclink/en.d.ts.map +1 -1
  40. package/dist/i18n/paclink/en.js +7 -0
  41. package/dist/i18n/paclink/en.js.map +1 -1
  42. package/dist/i18n/paclink/zh-CN.d.ts.map +1 -1
  43. package/dist/i18n/paclink/zh-CN.js +7 -0
  44. package/dist/i18n/paclink/zh-CN.js.map +1 -1
  45. package/dist/i18n/zh-CN.json +2 -0
  46. package/dist/makepkg/build.d.ts.map +1 -1
  47. package/dist/makepkg/build.js +3 -5
  48. package/dist/makepkg/build.js.map +1 -1
  49. package/dist/makepkg/pkgbuild.d.ts +1 -1
  50. package/dist/makepkg/pkgbuild.d.ts.map +1 -1
  51. package/dist/makepkg/pkgbuild.js +111 -59
  52. package/dist/makepkg/pkgbuild.js.map +1 -1
  53. package/dist/ops/install.d.ts +2 -1
  54. package/dist/ops/install.d.ts.map +1 -1
  55. package/dist/ops/install.js +88 -35
  56. package/dist/ops/install.js.map +1 -1
  57. package/dist/ops/query.d.ts.map +1 -1
  58. package/dist/ops/query.js +59 -33
  59. package/dist/ops/query.js.map +1 -1
  60. package/dist/ops/upgrade.d.ts.map +1 -1
  61. package/dist/ops/upgrade.js +69 -12
  62. package/dist/ops/upgrade.js.map +1 -1
  63. package/dist/repo/config.d.ts.map +1 -1
  64. package/dist/repo/config.js +35 -4
  65. package/dist/repo/config.js.map +1 -1
  66. package/dist/repo/repository.d.ts.map +1 -1
  67. package/dist/repo/repository.js +167 -43
  68. package/dist/repo/repository.js.map +1 -1
  69. package/dist/scripts/setup.js +2 -1
  70. package/dist/scripts/setup.js.map +1 -1
  71. package/docs/en/architecture.md +109 -45
  72. package/docs/en/pactree.md +42 -0
  73. package/docs/en/yay-aur.md +10 -6
  74. package/docs/zh-CN/pactree.md +41 -0
  75. package/lib/pac4deb/src/libalpm.c +40 -33
  76. package/lib/pac4deb/src/stubs_manual.c +11 -1
  77. package/package.json +3 -2
  78. package/resources/pacman.conf.template +16 -2
@@ -7,26 +7,29 @@ src/
7
7
  ├── cli/
8
8
  │ ├── pacman.ts # CLI argument parsing and dispatch
9
9
  │ ├── paclink.ts # Virtual package link management
10
+ │ ├── pactree.ts # Dependency tree viewer
10
11
  │ ├── update-ca-trust.ts # Arch-compat CA certificate updater
11
12
  │ ├── archlinux-java.ts # Arch-compat Java alternatives manager
12
13
  │ └── fix_default.ts # Arch-compat default JDK helper
13
14
  ├── core/ # Package format parsers, dependency engine
14
15
  │ ├── ar.ts # ar archive parser
15
- │ ├── tar.ts # tar extractor
16
+ │ ├── tar.ts # tar extractor (with progress callback)
16
17
  │ ├── deb.ts # .deb package parser
17
18
  │ ├── pkgfile.ts # .pkg.tar.zst parser
18
19
  │ ├── compress.ts # gz/xz decompression
19
20
  │ ├── control.ts # debian control file parser
20
- └── deps.ts # Dependency resolution engine
21
+ ├── deps.ts # Dependency resolution engine (verCmp built-in)
22
+ │ ├── logger.ts # File logger
23
+ │ └── paclinks.ts # Paclink mapping file (TS backend)
21
24
  ├── db/
22
25
  │ ├── localdb.ts # Directory-based local package DB
23
26
  │ ├── database.ts # DB wrapper with transactions
24
- │ └── dpkg-compat.ts # dpkg status file read/write
27
+ │ └── dpkg-compat.ts # dpkg status file read/write (no dpkg command)
25
28
  ├── ops/
26
29
  │ ├── install.ts # Package installation
27
30
  │ ├── remove.ts # Package removal
28
31
  │ ├── query.ts # All -Q queries
29
- │ └── upgrade.ts # Sync + upgrade flow
32
+ │ └── upgrade.ts # Sync + upgrade flow (dpkg-aware)
30
33
  ├── repo/
31
34
  │ ├── repository.ts # Repo sync, download, JSONL cache
32
35
  │ └── config.ts # pacman.conf parser with Include support
@@ -34,10 +37,8 @@ src/
34
37
  │ └── setup.ts # Interactive setup script
35
38
  ├── makepkg/
36
39
  │ ├── index.ts # Main makepkg entry
37
- │ ├── pkgbuild.ts # PKGBUILD parser
38
- │ ├── source.ts # Source download/extraction
39
- │ ├── build.ts # build()/package() execution
40
- │ └── printsrcinfo.ts # .SRCINFO generation
40
+ │ ├── pkgbuild.ts # PKGBUILD parser (single-bash optimization)
41
+ │ ├── build.ts # build()/package() execution (VCS support)
41
42
  ├── ui/ # User interface (prompt, formatting)
42
43
  └── index.ts # Entry point
43
44
  ```
@@ -50,7 +51,7 @@ lib/pac4deb/ # libalpm C library
50
51
  │ └── alpm_list.h # Linked list header
51
52
  └── src/
52
53
  ├── libalpm.c # Core implementation (handle, db, pkg, JSON parser)
53
- ├── stubs_manual.c # ~200 stubs for rarely-used libalpm functions
54
+ ├── stubs_manual.c # ~200 stubs for libalpm functions, idx search
54
55
  └── alpm_list.c # Linked list implementation
55
56
  ```
56
57
 
@@ -58,7 +59,7 @@ lib/pac4deb/ # libalpm C library
58
59
 
59
60
  ### Local database: `/var/lib/pacman-debian/local/`
60
61
 
61
- Directory-per-package format matching Arch Linux's local DB:
62
+ Directory-per-package format:
62
63
 
63
64
  ```
64
65
  /var/lib/pacman-debian/local/
@@ -77,48 +78,109 @@ Directory-per-package format matching Arch Linux's local DB:
77
78
  Packages installed via `dpkg` or `apt` are read directly from
78
79
  `/var/lib/dpkg/status` at query time (mtime-cached). When `pacman-debian`
79
80
  installs a package, it writes a dpkg-compatible entry ensuring `apt` and `dpkg`
80
- still see the package.
81
+ still see the package. **No `dpkg` command is ever invoked** — the status file
82
+ is parsed directly, and file lists are read from `/var/lib/dpkg/info/*.list`.
81
83
 
82
84
  ### Repository cache: `/var/cache/pacman-debian/packages/`
83
85
 
84
86
  Each repository is cached in JSON Lines chunks (5000 packages per `.jsonl`
85
87
  file). During sync, a `packages.idx` index is also built — one line per
86
- package, sorted globally, with format `pkgname description\tprovides\tchunk\toffset`.
88
+ package, sorted globally by name.
89
+
90
+ **Idx format (v2, since 7.4.0):**
91
+ ```
92
+ pkgname version\tdescription\tprovides\tchunk\toffset
93
+ ```
94
+
95
+ The version is embedded directly in the idx line, allowing `findInRepo()` and
96
+ search to return name + version without reading from the JSONL chunk.
87
97
 
88
98
  ```
89
99
  /var/cache/pacman-debian/packages/
90
- ├── bookworm/
100
+ ├── trixie/
91
101
  │ ├── 00000.jsonl # JSON Lines, ~5000 pkg per chunk
92
102
  │ ├── ...
93
- │ └── packages.idx # Global sorted index (tabs, ~200KB)
103
+ │ └── packages.idx # Sorted index with version embedded
94
104
  └── ...
95
105
  ```
96
106
 
97
107
  #### Memory Index Cache
98
108
 
99
- `packages.idx` is cached in memory after first read, keyed by repo name + mtime:
109
+ `packages.idx` is loaded **once** and cached permanently until
110
+ `invalidateIdxCache()` is called. No stat/mtime checks on subsequent lookups:
100
111
 
101
112
  ```
102
113
  _idxCache = new Map<string, IdxEntry>();
103
- IdxEntry { lines: string[], mtime: number, providesIndex: Map<string, Array<{chunkFile, offset}>> }
114
+ IdxEntry { lines: string[], providesIndex: Map<string, Array<{chunkFile, offset}>> }
115
+ _pkgCache = new Map<string, RepoPkg>() // LRU by chunkFile:offset
104
116
  ```
105
117
 
106
- - Subsequent `-S`/`-Ss`/`-Sl` operations read from memory, no disk I/O
107
- - `providesIndex` is an inverted index: `provides name → [{ chunkFile, offset }]`
108
- - `findProvider()` does O(1) `Map.get()` for provides lookups
109
- - `pacman -Syy` clears the cache (`invalidateIdxCache()`)
110
- - After incremental sync, idx file mtime changes → auto reload
111
-
112
118
  ### Lookup Paths
113
119
 
114
120
  | Operation | Method | Why |
115
121
  |-----------|--------|-----|
116
- | `-S <pkg>` / `-Qo` | Binary search `packages.idx` → seek JSONL | O(log N), single line read |
117
- | `-Ss` | Line-scan `packages.idx` (name + desc) seek JSONL | ~1.4MB scan, no JSON parse |
122
+ | `-S <pkg>` / `-Qo` | Binary search `packages.idx` → seek JSONL | O(log N), single pread |
123
+ | `-Ss` | Line-scan `packages.idx` (name + desc + version) | ~500KB scan, cached reads |
118
124
  | `-Sl` | Read `packages.idx` → seek each pkg | Lazy-load via index |
119
125
  | Dependency provides | Scan `packages.idx` provides field | Index-only, no JSON parse |
120
126
  | `-Qi` / `-Ql` | dpkg status or localdb | No cache involved |
121
127
 
128
+ ## Version Comparison (built-in, no dpkg dependency)
129
+
130
+ Since **7.4.0**, the version comparison algorithm (`verCmp` in `src/core/deps.ts`)
131
+ is a pure TypeScript port of dpkg's C implementation (`libdpkg/version.c`):
132
+
133
+ ```
134
+ verrevcmp(a, b):
135
+ 1. Skip non-digit prefixes, compare by character weight (order())
136
+ order(c):
137
+ digits → 0 (compared as integers below)
138
+ letters → ASCII value
139
+ '~' → -1 (sorts before everything)
140
+ other → charCode + 256
141
+ 2. Skip leading zeros on digit groups
142
+ 3. Compare digit groups as integers
143
+ 4. Longer digit group wins
144
+ ```
145
+
146
+ Epoch comparison: `epoch:a > epoch:b` → a wins (integer comparison).
147
+ Revision comparison: same algorithm applied to the `-revision` suffix.
148
+
149
+ This eliminates the only hard dependency on the `dpkg` command. The `dpkg`
150
+ binary is now entirely optional — only the dpkg status file is read.
151
+
152
+ ## Paclink Mapping Backend
153
+
154
+ Since **7.4.0**, Debian→Arch package name mappings are stored in
155
+ `/var/lib/pacman-debian/paclinks` (plain text, sorted by virt name):
156
+
157
+ ```
158
+ glibc libc6
159
+ go golang-go
160
+ libxtst libxtst6
161
+ python python3
162
+ ```
163
+
164
+ The C libalpm shim reads this file directly at startup via `load_paclinks()`,
165
+ adding virtual names as `provides` on the corresponding dpkg packages.
166
+ No recompilation is needed to add new mappings. Use `paclink -I` to
167
+ initialize all common mappings from your installed Debian packages.
168
+
169
+ ## Sync Flow (Release-based for Debian repos)
170
+
171
+ Since **7.4.0**, Debian repository sync follows apt's approach:
172
+
173
+ 1. Download `InRelease` / `Release` file with `If-Modified-Since`
174
+ 2. If 304 → repo is up to date
175
+ 3. Parse SHA256 hashes from Release file
176
+ 4. For each component (`main`, `universe`, etc.), compare SHA256 with cached
177
+ values from the previous sync
178
+ 5. Only download new `Packages.xz`/`Packages.gz` when SHA256 differs
179
+ 6. Save new SHA256 in `.info` for next sync
180
+
181
+ This eliminates false `notModified` returns from `If-Modified-Since` on
182
+ Packages files that haven't changed but where the Release metadata is newer.
183
+
122
184
  ## Dependency Engine
123
185
 
124
186
  The dependency resolver (`src/core/deps.ts`) handles:
@@ -130,41 +192,29 @@ The dependency resolver (`src/core/deps.ts`) handles:
130
192
  - BFS resolution with pre-loaded DB state
131
193
  - Conflict detection across installed and to-be-installed packages
132
194
  - System package protection (glibc, libc6, etc.)
133
-
134
- - File validation: installed packages with no real files on disk are
135
- considered NOT installed, forcing re-download.
136
- - Explicit targets always have their dependencies processed even if the
137
- target itself is already installed.
138
- - Queue uses `shift()` to pop processed items, preventing memory accumulation.
195
+ - dpkg-aware upgrade scanning: also checks apt-installed packages against
196
+ Debian repo updates
139
197
 
140
198
  ### Performance Optimizations
141
199
 
142
200
  | Technique | Description |
143
201
  |-----------|-------------|
144
- | **idx memory cache** | `findInRepo()` binary search on `_idxCache.lines[]` in memory |
202
+ | **idx memory cache** | `findInRepo()` binary search on `_idxCache.lines[]` in memory (loaded once) |
145
203
  | **provides inverted index** | `findProvider()` does `Map.get()` O(1) |
146
204
  | **BFS + cursor** | Dependency queue uses index pointer instead of `shift()` |
147
205
  | **batch head-tail scan** | Binary searches sorted idx from both ends simultaneously |
148
206
  | **keep-alive HTTP** | Shared `https.Agent({ keepAlive: true, maxSockets: 8 })` |
149
207
  | **async .gz decompress** | Non-blocking zlib with callback |
150
208
  | **304 conditional requests** | Sync sends `If-Modified-Since`, skip unchanged repos |
151
-
152
- ### Delete Dependency Handling
153
-
154
- | Operation | Logic |
155
- |-----------|-------|
156
- | `-R` | Remove specified package only |
157
- | `-Rs` | Remove package + recursive orphan find, reverse-topological order |
158
- | `-Rc` | Cascade: find all packages requiring the target |
159
- | `-Rsc` | Recursive + cascade combination |
160
- | `-Rn` | Backup conffiles as `.dpkg-old`, then remove |
161
-
162
- Removal auto-sorts dependents first (leaves before roots).
209
+ | **Release-based SHA256 check** | Only download Packages when content actually changed |
210
+ | **Package read cache** | `_pkgCache` caches `readPkgAt()` results by chunk+offset |
211
+ | **Single-bash PKGBUILD parse** | Source once, export all variables (was 35 separate forks) |
163
212
 
164
213
  ## Repository Support
165
214
 
166
215
  - **Debian/Ubuntu**: Reads `Packages.gz` / `Packages.xz` from standard
167
216
  repository indices. Supports `$repo`/`$arch` variable substitution.
217
+ Release-based SHA256 validation before downloading.
168
218
  - **Arch Linux**: Reads `db.tar.gz` from Arch-compatible repositories.
169
219
  Downloaded `.pkg.tar.zst` files are extracted and installed.
170
220
  - **Arch ARM**: Binary packages require glibc 2.38+ — Debian 12 ships 2.36.
@@ -174,12 +224,26 @@ Removal auto-sorts dependents first (leaves before roots).
174
224
 
175
225
  Key features:
176
226
 
177
- - **Performance**: `packages.idx` index enables sub-second single-package lookup.
227
+ - **Performance**: `packages.idx` with embedded version enables sub-100ms
228
+ search across 3000+ packages; idx is loaded once and cached in memory.
229
+ - **Zero dpkg dependency**: Version comparison algorithm ported from libdpkg,
230
+ dpkg status read directly, no `dpkg` command required.
178
231
  - **Parallel sync**: Repos sync concurrently with per-repo progress display.
232
+ - **64-bit indexed binary search**: Sorted idx enables O(log N) single-package lookup.
179
233
  - **i18n**: Full Chinese and English localization via `$LANG` detection.
180
234
  - **Color**: Matching official pacman color scheme.
181
235
  - **Root check**: Query commands work without root; write operations require `sudo`.
182
- - **Link system** (`paclink`): Debian→Arch virtual package name mappings.
236
+ - **Link system** (`paclink`): Debian→Arch virtual package name mappings stored
237
+ in file backend, read by C shim at startup.
238
+ - **makepkg**: VCS source support (git, hg), parallel downloads, progress bars.
239
+ - **Release-based sync**: SHA256-validated Debian repo updates (like apt).
240
+ - **XferCommand**: Custom download commands (aria2c, curl, wget).
241
+ - **CheckSpace**: Configurable disk space verification before install.
242
+ - **IgnorePkg / NoUpgrade / NoExtract**: Standard pacman config options supported.
243
+ - **VerbosePkgLists**: Tabular package listing with version, repo, size columns.
244
+ - **CleanMethod**: `KeepInstalled` / `KeepCurrent` cache cleaning policy.
245
+ - **Downgrade protection**: Version comparison handles epochs, revisions, `~`
246
+ (pre-release), and all dpkg version semantics.
183
247
 
184
248
  Key limitations:
185
249
 
@@ -0,0 +1,42 @@
1
+ # pactree — Package Dependency Tree Viewer
2
+
3
+ `pactree` displays the dependency tree of a package, showing what it depends
4
+ on (forward) or what depends on it (reverse). It queries all available sources:
5
+ local database, dpkg status, and repository indexes.
6
+
7
+ ## Usage
8
+
9
+ ```
10
+ pactree [options] <package>
11
+ ```
12
+
13
+ ## Options
14
+
15
+ | Flag | Description |
16
+ |------|-------------|
17
+ | `-r`, `--reverse` | Show reverse dependencies (what depends on this package) |
18
+ | `-d`, `--depth` | Maximum tree depth (default: unlimited) |
19
+ | `-s`, `--sync` | Show version numbers |
20
+ | `-h`, `--help` | Show help |
21
+
22
+ ## Examples
23
+
24
+ ```bash
25
+ # Show what glibc depends on
26
+ pactree glibc
27
+
28
+ # Show what depends on glibc (reverse)
29
+ pactree -r glibc
30
+
31
+ # Limit depth to 2
32
+ pactree -d 2 python3
33
+
34
+ # Show with versions
35
+ pactree -s mesa
36
+ ```
37
+
38
+ ## Notes
39
+
40
+ - Circular dependencies are detected and marked with `(circular)`
41
+ - Missing packages are marked with `(not found)`
42
+ - The tree queries dpkg status, pacman-debian local DB, and sync repos
@@ -10,6 +10,7 @@ modification. It reads:
10
10
  pacman-debian
11
11
  - dpkg status (`/var/lib/dpkg/status`) — system packages from apt/dpkg
12
12
  - Sync databases (`/var/cache/pacman-debian/packages/*/` — JSONL chunks)
13
+ - Paclink mappings (`/var/lib/pacman-debian/paclinks`) — Debian→Arch name map
13
14
 
14
15
  Over 200 stubs are provided for rarely-used functions.
15
16
 
@@ -18,14 +19,17 @@ Over 200 stubs are provided for rarely-used functions.
18
19
  - **packages.idx binary search (C)**: `alpm_db_get_pkg` and
19
20
  `alpm_find_dbs_satisfier` use binary search on the sorted index, then read
20
21
  a single JSONL line by byte offset — no full JSONL loading.
22
+ - **Paclink file backend**: Since 7.4.0, mappings are read from
23
+ `/var/lib/pacman-debian/paclinks` (sorted text file) by `load_paclinks()`.
24
+ No hardcoded table or recompilation needed. `libc6 → glibc`,
25
+ `libxtst6 → libxtst`, `golang-go → go`, etc. are resolved at startup.
21
26
  - **Auto-register sync DBs**: `ensure_syncdbs` scans
22
27
  `/var/cache/pacman-debian/packages/` on first `alpm_get_syncdbs`,
23
28
  registering all available repos lazily.
24
29
  - **Package DB pointer**: `pkg_internal.db` field tracks owning database;
25
30
  `alpm_pkg_get_db` returns it, preventing `DB().Name()` nil dereference.
26
31
  - **idx-based search**: `alpm_db_search` scans index lines for pattern
27
- matching instead of loading all packages. ~1.5s for -Ss with 6 repos / 15k
28
- packages.
32
+ matching instead of loading all packages. Sub-second for -Ss with 7 repos.
29
33
  - **dpkg Provides parsing**: `load_dpkg_status` reads the `Provides:` field
30
34
  from dpkg status, so Debian packages that declare virtual names
31
35
  (e.g. `7zip` → `p7zip`) are discoverable by yay via
@@ -34,10 +38,10 @@ Over 200 stubs are provided for rarely-used functions.
34
38
  database after sync DBs, matching both package names and provides.
35
39
  - **find_in_idx provides scan**: After binary search by package name fails,
36
40
  scans the `provides` column of `packages.idx` for sync DB provides.
37
- - **dpkg -S fallback**: For `lib*.so` SONAMEs not found anywhere, forks
38
- `dpkg -S` to locate the owning Debian package at runtime.
39
41
  - **Debian alternatives**: Checks `/etc/alternatives/` for `sh`, `awk`, `vi`,
40
42
  `editor` etc. and adds virtual provides to the owning package.
43
+ - **alpm_pkg_find**: Implemented (no longer a stub), searches linked list by
44
+ name for yay's dependency resolution.
41
45
 
42
46
  ### Build
43
47
 
@@ -56,9 +60,9 @@ sudo apt install golang-go
56
60
  git clone https://aur.archlinux.org/yay.git /tmp/yay
57
61
  cd /tmp/yay && go build -o /usr/local/bin/yay
58
62
 
59
- # Use with pacman-debian (PACMAN env var detected automatically)
63
+ # Use with pacman-debian
60
64
  yay -Ss ponysay
61
- sudo -E yay -S ponysay
65
+ sudo pacman -S jdk21-openjdk # yay also works for sync packages
62
66
  ```
63
67
 
64
68
  Note: AUR packages that depend on `python` (not `python3`) are resolved
@@ -0,0 +1,41 @@
1
+ # pactree — 包依赖树查看器
2
+
3
+ 显示包的依赖树(正向:依赖了什么,反向:被什么依赖)。查询所有可用来源:
4
+ 本地数据库、dpkg 状态和仓库索引。
5
+
6
+ ## 用法
7
+
8
+ ```
9
+ pactree [选项] <包名>
10
+ ```
11
+
12
+ ## 选项
13
+
14
+ | 选项 | 说明 |
15
+ |------|------|
16
+ | `-r`, `--reverse` | 显示反向依赖(谁依赖这个包) |
17
+ | `-d`, `--depth` | 最大树深度(默认不限) |
18
+ | `-s`, `--sync` | 显示版本号 |
19
+ | `-h`, `--help` | 显示帮助 |
20
+
21
+ ## 示例
22
+
23
+ ```bash
24
+ # 查看 glibc 依赖了什么
25
+ pactree glibc
26
+
27
+ # 查看谁依赖 glibc(反向)
28
+ pactree -r glibc
29
+
30
+ # 限制深度为 2
31
+ pactree -d 2 python3
32
+
33
+ # 显示版本
34
+ pactree -s mesa
35
+ ```
36
+
37
+ ## 说明
38
+
39
+ - 循环依赖会被检测并标记 `(circular)`
40
+ - 找不到的包标记 `(not found)`
41
+ - 查询范围包括 dpkg 状态、pacman-debian 本地数据库和同步仓库
@@ -380,6 +380,45 @@ static alpm_list_t *load_dpkg_status(const char *path) {
380
380
  return pkgs;
381
381
  }
382
382
 
383
+ /* Read paclink mappings from /var/lib/pacman-debian/paclinks.
384
+ Format: <virt_name> <deb_package_name>, one per line, sorted by virt. */
385
+ static void load_paclinks(alpm_list_t *pkgs) {
386
+ char path[4096];
387
+ snprintf(path, sizeof(path), "%s/paclinks", DB_DIR);
388
+ FILE *fp = fopen(path, "r");
389
+ if (!fp) return;
390
+ char line[512];
391
+ while (fgets(line, sizeof(line), fp)) {
392
+ if (line[0] == '#' || line[0] == '\n' || line[0] == '\r') continue;
393
+ char virt[256] = {0}, deb[256] = {0};
394
+ if (sscanf(line, "%255s %255s", virt, deb) != 2) continue;
395
+ for (alpm_list_t *it = pkgs; it; it = it->next) {
396
+ pkg_internal *p = it->data;
397
+ if (strcmp(p->name, deb) != 0) continue;
398
+ if (p->provides && *p->provides) {
399
+ char tmp[512]; snprintf(tmp, sizeof(tmp), ",%s,", p->provides);
400
+ char needle[64]; snprintf(needle, sizeof(needle), ",%s,", virt);
401
+ if (strstr(tmp, needle)) break;
402
+ }
403
+ size_t old = p->provides ? strlen(p->provides) : 0;
404
+ size_t add = strlen(virt);
405
+ char *nv = malloc(old + add + 3);
406
+ if (!nv) break;
407
+ if (p->provides) {
408
+ memcpy(nv, p->provides, old);
409
+ nv[old] = ',';
410
+ memcpy(nv + old + 1, virt, add + 1);
411
+ free(p->provides);
412
+ } else {
413
+ memcpy(nv, virt, add + 1);
414
+ }
415
+ p->provides = nv;
416
+ break;
417
+ }
418
+ }
419
+ fclose(fp);
420
+ }
421
+
383
422
  /* Resolve Debian alternatives: readlink /bin/<cmd> to find real binary,
384
423
  then map its package name back to the virtual provide name.
385
424
  e.g. /bin/sh -> dash -> add provides "sh" on the dash pkg_internal */
@@ -474,39 +513,7 @@ static void add_alternative_provides(alpm_list_t *pkgs) {
474
513
  }
475
514
  }
476
515
 
477
- /* Map common Arch package names to Debian equivalents.
478
- These are packages that don't map 1:1 by name but provide equivalent functionality. */
479
- static const char *pkg_map[][2] = {
480
- {"ca-certificates", "ca-certificates-utils"},
481
- {"python3", "python"},
482
- {NULL, NULL}
483
- };
484
- for (int i = 0; pkg_map[i][0]; i++) {
485
- for (alpm_list_t *it = pkgs; it; it = it->next) {
486
- pkg_internal *p = it->data;
487
- if (strcmp(p->name, pkg_map[i][0]) != 0) continue;
488
- const char *virt = pkg_map[i][1];
489
- if (p->provides && *p->provides) {
490
- char tmp[512]; snprintf(tmp, sizeof(tmp), ",%s,", p->provides);
491
- char needle[64]; snprintf(needle, sizeof(needle), ",%s,", virt);
492
- if (strstr(tmp, needle)) break;
493
- }
494
- size_t old = p->provides ? strlen(p->provides) : 0;
495
- size_t add = strlen(virt);
496
- char *nv = malloc(old + add + 3);
497
- if (!nv) break;
498
- if (p->provides) {
499
- memcpy(nv, p->provides, old);
500
- nv[old] = ',';
501
- memcpy(nv + old + 1, virt, add + 1);
502
- free(p->provides);
503
- } else {
504
- memcpy(nv, virt, add + 1);
505
- }
506
- p->provides = nv;
507
- break;
508
- }
509
- }
516
+ load_paclinks(pkgs);
510
517
  }
511
518
 
512
519
  /* Load local database: our packages + dpkg status */
@@ -425,7 +425,17 @@ void *alpm_pkg_get_checkdepends(alpm_pkg_t *p) { (void)p; return NULL; }
425
425
  void *alpm_pkg_get_makedepends(alpm_pkg_t *p) { (void)p; return NULL; }
426
426
  void *alpm_pkg_get_xdata(alpm_pkg_t *p) { (void)p; return NULL; }
427
427
  void *alpm_pkg_get_handle(alpm_pkg_t *p) { (void)p; return NULL; }
428
- alpm_pkg_t *alpm_pkg_find(void *list, const char *name) { (void)list; (void)name; return NULL; }
428
+ alpm_pkg_t *alpm_pkg_find(void *list, const char *name) {
429
+ if (!list || !name) return NULL;
430
+ alpm_list_t *it;
431
+ for (it = (alpm_list_t *)list; it; it = it->next) {
432
+ alpm_pkg_t *p = (alpm_pkg_t *)it->data;
433
+ if (!p) continue;
434
+ const char *n = alpm_pkg_get_name(p);
435
+ if (n && strcmp(n, name) == 0) return p;
436
+ }
437
+ return NULL;
438
+ }
429
439
  int alpm_pkg_should_ignore(alpm_handle_t *h, alpm_pkg_t *p) { (void)h; (void)p; return 0; }
430
440
  int alpm_pkg_download_size(alpm_pkg_t *p) { (void)p; return 0; }
431
441
  int alpm_filelist_contains(void *fl, const char *path) { (void)fl; (void)path; return 0; }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pacman-debian",
3
- "version": "7.3.34",
3
+ "version": "7.4.0",
4
4
  "description": "A Debian/Ubuntu package manager using Arch Linux pacman syntax. Manages .deb packages at dpkg level, supports Arch .pkg.tar.zst, AUR helpers (yay), and makepkg. Configurable multi-repo setup.",
5
5
  "pacmanVersion": "7.1.0",
6
6
  "main": "dist/index.js",
@@ -31,7 +31,8 @@
31
31
  "paclink": "dist/cli/paclink.js",
32
32
  "update-ca-trust": "dist/cli/update-ca-trust.js",
33
33
  "archlinux-java": "dist/cli/archlinux-java.js",
34
- "fix_default": "dist/cli/fix_default.js"
34
+ "fix_default": "dist/cli/fix_default.js",
35
+ "pactree": "dist/cli/pactree.js"
35
36
  },
36
37
  "scripts": {
37
38
  "build": "tsc && make -s -C lib/pac4deb",
@@ -8,11 +8,25 @@ Architecture = auto
8
8
  #HookDir = /etc/pacman.d/hooks/
9
9
  HoldPkg = pacman glibc
10
10
  ParallelDownloads = 5
11
- #CheckSpace
11
+ CheckSpace
12
12
  Color
13
13
  #VerbosePkgLists
14
14
  #DownloadUser = alpm
15
15
 
16
+ # Custom download command (replace built-in HTTP with external tool)
17
+ #XferCommand = /usr/bin/curl -L -C - -f -o %o %u
18
+ #XferCommand = /usr/bin/wget --passive-ftp -c -O %o %u
19
+
20
+ # CleanMethod: KeepInstalled (default) or KeepCurrent
21
+ #CleanMethod = KeepInstalled
22
+
23
+ # Ignore these packages during upgrade
24
+ #IgnorePkg =
25
+ #IgnoreGroup =
26
+
27
+ # Protect files from overwrite during install
28
+ #NoUpgrade =
29
+ #NoExtract =
30
+
16
31
  SigLevel = Never
17
32
  LocalFileSigLevel = Optional
18
- #RemoteFileSigLevel = Required