@photostructure/fs-metadata 1.3.0 → 1.4.1
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/AGENTS.md +213 -0
- package/CHANGELOG.md +54 -0
- package/CONTRIBUTING.md +3 -3
- package/binding.gyp +0 -22
- package/dist/index.cjs +10 -39
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +10 -39
- package/dist/index.mjs.map +1 -1
- package/doc/C++_REVIEW_TODO.md +3 -36
- package/doc/LINUX_API_REFERENCE.md +4 -147
- package/doc/SECURITY_AUDIT_2026.md +4 -0
- package/doc/gotchas.md +27 -0
- package/package.json +11 -12
- package/prebuilds/darwin-arm64/@photostructure+fs-metadata.glibc.node +0 -0
- package/prebuilds/darwin-x64/@photostructure+fs-metadata.glibc.node +0 -0
- package/prebuilds/linux-arm64/@photostructure+fs-metadata.glibc.node +0 -0
- package/prebuilds/linux-arm64/@photostructure+fs-metadata.musl.node +0 -0
- package/prebuilds/linux-x64/@photostructure+fs-metadata.glibc.node +0 -0
- package/prebuilds/linux-x64/@photostructure+fs-metadata.musl.node +0 -0
- package/prebuilds/win32-arm64/@photostructure+fs-metadata.glibc.node +0 -0
- package/prebuilds/win32-x64/@photostructure+fs-metadata.glibc.node +0 -0
- package/scripts/clang-tidy.ts +1 -3
- package/scripts/prebuild-linux-glibc.sh +1 -5
- package/scripts/sanitizers-test.sh +0 -1
- package/src/binding.cpp +5 -15
- package/src/common/metadata_worker.h +7 -6
- package/src/common/shutdown.h +162 -0
- package/src/darwin/get_mount_point.cpp +6 -4
- package/src/darwin/hidden.cpp +9 -8
- package/src/darwin/hidden.h +4 -3
- package/src/darwin/volume_metadata.cpp +15 -1
- package/src/darwin/volume_mount_points.cpp +26 -4
- package/src/linux/mount_points.ts +8 -42
- package/src/linux/volume_metadata.cpp +5 -17
- package/src/mount_point_for_path.ts +1 -1
- package/src/types/mount_point.ts +1 -1
- package/src/types/native_bindings.ts +0 -5
- package/src/volume_metadata.ts +16 -7
- package/src/volume_mount_points.ts +1 -1
- package/src/windows/hidden.cpp +10 -9
- package/src/windows/volume_metadata.cpp +5 -1
- package/src/windows/volume_mount_points.cpp +22 -4
- package/scripts/setup-native.mjs +0 -39
- package/src/linux/gio_mount_points.cpp +0 -80
- package/src/linux/gio_mount_points.h +0 -37
- package/src/linux/gio_utils.cpp +0 -115
- package/src/linux/gio_utils.h +0 -69
- package/src/linux/gio_volume_metadata.cpp +0 -81
- package/src/linux/gio_volume_metadata.h +0 -20
package/AGENTS.md
ADDED
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Codex (Codex.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
@photostructure/fs-metadata - Cross-platform native Node.js module for filesystem metadata retrieval.
|
|
8
|
+
|
|
9
|
+
### Directory Structure
|
|
10
|
+
|
|
11
|
+
- `src/` - Source code (TypeScript and C++)
|
|
12
|
+
- `dist/` - Compiled JavaScript output (gitignored)
|
|
13
|
+
- `doc/` - Static documentation (manually written, checked into git)
|
|
14
|
+
- `build/` - All build artifacts (gitignored)
|
|
15
|
+
- `build/docs/` - Generated API documentation from TypeDoc (deployed to GitHub Pages)
|
|
16
|
+
- `scripts/` - Build and utility scripts
|
|
17
|
+
- `prebuilds/` - Prebuilt native binaries for different platforms
|
|
18
|
+
|
|
19
|
+
### Script Preferences
|
|
20
|
+
|
|
21
|
+
**Always** use TypeScript (`.ts`) scripts executed with `tsx` instead of:
|
|
22
|
+
|
|
23
|
+
- `.js` scripts (require compilation or older Node.js syntax)
|
|
24
|
+
- `.mjs` scripts (ESM-only, compatibility issues)
|
|
25
|
+
- `.cjs` scripts (CommonJS-only, less type safety)
|
|
26
|
+
|
|
27
|
+
TypeScript with tsx provides type safety, modern syntax, and seamless execution.
|
|
28
|
+
|
|
29
|
+
## Critical Knowledge
|
|
30
|
+
|
|
31
|
+
### Testing File System Metadata
|
|
32
|
+
|
|
33
|
+
**Never** expect exact equality for dynamic values (`available`, `used`) between calls. Only verify:
|
|
34
|
+
|
|
35
|
+
- Value exists and has correct type: `typeof result.available === 'number'`
|
|
36
|
+
- Test static properties (`size`, `mountFrom`, `fstype`) for exact equality
|
|
37
|
+
- Avoid range assertions (`available > 0`) - file changes can be dramatic
|
|
38
|
+
|
|
39
|
+
### Cross-Module Compatibility
|
|
40
|
+
|
|
41
|
+
Use `_dirname()` from `./dirname` instead of `__dirname` - works in both CommonJS and ESM contexts.
|
|
42
|
+
|
|
43
|
+
### Node.js Version Compatibility
|
|
44
|
+
|
|
45
|
+
Jest 30 doesn't support Node.js 23. Use Node.js 20, 22, or 24.
|
|
46
|
+
|
|
47
|
+
## System Volume Detection
|
|
48
|
+
|
|
49
|
+
**IMPORTANT: Read `doc/system-volume-detection.md` before modifying any system volume detection logic.** It documents the full detection strategy across all platforms, including flag matrices and rationale for each approach.
|
|
50
|
+
|
|
51
|
+
Summary:
|
|
52
|
+
|
|
53
|
+
- The root `/` is a sealed, read-only APFS snapshot whose **UUID changes on every OS update** — never use it for persistent identification.
|
|
54
|
+
- **Primary detection** combines mount flags with APFS volume roles: `MNT_SNAPSHOT || (MNT_DONTBROWSE && hasApfsRole && role != "Data")`. See `ClassifyMacVolume()` in `src/darwin/system_volume.h`.
|
|
55
|
+
- The APFS role string is exposed as `volumeRole` on `MountPoint` and `VolumeMetadata`.
|
|
56
|
+
- **Fallback** uses `MNT_SNAPSHOT` only from `statfs` `f_flags` if DA session creation fails.
|
|
57
|
+
- `MNT_DONTBROWSE` is safe to use **only when combined with a non-Data APFS role**. The Data volume (`/System/Volumes/Data`) has `MNT_DONTBROWSE` but role `"Data"`, so it is correctly excluded.
|
|
58
|
+
- Pseudo-filesystems like `devfs` (no IOMedia, no APFS role) are caught by TypeScript fstype/path heuristics.
|
|
59
|
+
|
|
60
|
+
## Windows-Specific Issues
|
|
61
|
+
|
|
62
|
+
### Windows CI Jest Worker Failures
|
|
63
|
+
|
|
64
|
+
**Problem**: Jest worker processes fail on Windows CI environments (both x64 and ARM64) with "Jest worker encountered 4 child process exceptions".
|
|
65
|
+
|
|
66
|
+
**Solution for Memory Tests**:
|
|
67
|
+
|
|
68
|
+
Memory tests now use a standalone TypeScript runner (`src/test-utils/memory-test-runner.ts`) that bypasses Jest entirely on all platforms. This provides more accurate memory measurements without Jest overhead and avoids worker process issues.
|
|
69
|
+
|
|
70
|
+
- Run full memory check suite (includes native tools): `npm run check:memory`
|
|
71
|
+
- Memory test logic is in `src/test-utils/memory-test-core.ts`
|
|
72
|
+
|
|
73
|
+
**Workaround for Other Tests**:
|
|
74
|
+
|
|
75
|
+
1. Jest is configured to use single worker mode (`maxWorkers: 1`) for all Windows CI environments
|
|
76
|
+
2. Tests that stress worker threads or concurrency are skipped on Windows CI using `describeSkipWindowsCI` or `describePlatformStable`:
|
|
77
|
+
|
|
78
|
+
- `worker_threads.test.ts` - Worker thread integration tests
|
|
79
|
+
- `thread_safety.test.ts` - Concurrent operations stress tests
|
|
80
|
+
- `windows-memory-check.test.ts` - Memory leak detection (Windows only)
|
|
81
|
+
- `windows-resource-security.test.ts` - Resource handle leak tests (Windows only)
|
|
82
|
+
|
|
83
|
+
**Note**: These tests pass locally but fail in CI. The native module loads correctly, but Jest's worker process management has fundamental incompatibilities with these specific tests on GitHub Actions Windows runners.
|
|
84
|
+
|
|
85
|
+
### Build Architecture Issue
|
|
86
|
+
|
|
87
|
+
**Problem**: "No Target Architecture" error from Windows SDK headers when building with node-gyp/prebuildify.
|
|
88
|
+
|
|
89
|
+
**Solution**: Use `scripts/prebuildify-wrapper.ts` which sets the `CL` environment variable with architecture defines:
|
|
90
|
+
|
|
91
|
+
- For x64: `CL=/D_M_X64 /D_WIN64 /D_AMD64_`
|
|
92
|
+
- For ARM64: `CL=/D_M_ARM64 /D_WIN64`
|
|
93
|
+
|
|
94
|
+
**Why This is Necessary**:
|
|
95
|
+
|
|
96
|
+
- Prebuildify doesn't properly pass architecture defines from binding.gyp conditions
|
|
97
|
+
- The Windows SDK requires these macros before including `<windows.h>`
|
|
98
|
+
- Projects like node-sqlite avoid this by not using Windows headers directly
|
|
99
|
+
|
|
100
|
+
**Why Other Approaches Failed**:
|
|
101
|
+
|
|
102
|
+
- **Source file defines**: Would hardcode x64 defines, breaking ARM64 builds
|
|
103
|
+
- **windows_compat.h wrapper**: Can't distinguish x64 from ARM64 at compile time
|
|
104
|
+
- **binding.gyp conditions**: Not evaluated properly by prebuildify
|
|
105
|
+
- **msvs_settings defines**: Not passed through to the compiler
|
|
106
|
+
|
|
107
|
+
### Memory Testing Limitations
|
|
108
|
+
|
|
109
|
+
Traditional Windows tools **do not work** with Node.js native modules:
|
|
110
|
+
|
|
111
|
+
- **Dr. Memory**: Fails with "Unable to load client library: ucrtbase.dll"
|
|
112
|
+
- **Debug CRT builds**: Cannot be loaded by Node.js (missing debug runtime + UNC path issues)
|
|
113
|
+
- **Visual Leak Detector**: Requires debug builds which don't work
|
|
114
|
+
- **Application Verifier**: Cannot hook into Node.js memory management
|
|
115
|
+
|
|
116
|
+
Use JavaScript-based memory testing (`src/windows-memory-check.test.ts`) instead.
|
|
117
|
+
|
|
118
|
+
### Static Analysis (clang-tidy) Limitations
|
|
119
|
+
|
|
120
|
+
**clang-tidy on Windows** has limited effectiveness due to MSVC header incompatibility:
|
|
121
|
+
|
|
122
|
+
- Generates many false errors about missing std namespace members
|
|
123
|
+
- Still provides valuable warnings about your code
|
|
124
|
+
- See `doc/windows-clang-tidy.md` for details
|
|
125
|
+
- Consider using Visual Studio Code Analysis as an alternative
|
|
126
|
+
|
|
127
|
+
### WSL Development
|
|
128
|
+
|
|
129
|
+
Run Windows commands from WSL:
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
cmd.exe /c "cd C:\\Users\\matth\\src\\fs-metadata && npm test"
|
|
133
|
+
# Or create helper: echo 'cmd.exe /c "cd C:\\Users\\matth\\src\\fs-metadata && $@"' > ~/bin/win-run
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Memory Leak Detection
|
|
137
|
+
|
|
138
|
+
Run `npm run check:memory` for comprehensive platform-specific testing:
|
|
139
|
+
|
|
140
|
+
- **All platforms**: JavaScript memory tests with GC triggers
|
|
141
|
+
- **Windows**: Handle count monitoring via `process.report`
|
|
142
|
+
- **Linux**: Valgrind + AddressSanitizer/LeakSanitizer
|
|
143
|
+
- **macOS**: AddressSanitizer (may fail due to SIP - expected)
|
|
144
|
+
|
|
145
|
+
## CI/CD Test Reliability
|
|
146
|
+
|
|
147
|
+
### Critical Anti-Patterns
|
|
148
|
+
|
|
149
|
+
**Never** use these to "fix" async issues:
|
|
150
|
+
|
|
151
|
+
```javascript
|
|
152
|
+
// BAD: Arbitrary timeouts
|
|
153
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
154
|
+
// BAD: Forcing GC
|
|
155
|
+
if (global.gc) global.gc();
|
|
156
|
+
// BAD: setImmediate in afterAll
|
|
157
|
+
afterAll(async () => {
|
|
158
|
+
await new Promise((resolve) => setImmediate(resolve));
|
|
159
|
+
});
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Windows Directory Cleanup
|
|
163
|
+
|
|
164
|
+
Always use retry logic:
|
|
165
|
+
|
|
166
|
+
```typescript
|
|
167
|
+
await fsp.rm(tempDir, {
|
|
168
|
+
recursive: true,
|
|
169
|
+
force: true,
|
|
170
|
+
maxRetries: process.platform === "win32" ? 3 : 1,
|
|
171
|
+
retryDelay: process.platform === "win32" ? 100 : 0,
|
|
172
|
+
});
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Platform Performance Multipliers
|
|
176
|
+
|
|
177
|
+
- Alpine Linux (musl): 2x slower
|
|
178
|
+
- ARM64 emulation: 5x slower
|
|
179
|
+
- Windows processes: 4x slower
|
|
180
|
+
- macOS VMs: 4x slower
|
|
181
|
+
|
|
182
|
+
### Multi-Process Synchronization
|
|
183
|
+
|
|
184
|
+
Use explicit signals:
|
|
185
|
+
|
|
186
|
+
```javascript
|
|
187
|
+
console.log("READY"); // Signal readiness
|
|
188
|
+
console.log("RESULT:" + outcome); // Signal result
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## Release Process
|
|
192
|
+
|
|
193
|
+
Requires repository secrets:
|
|
194
|
+
|
|
195
|
+
- `NPM_TOKEN`: npm authentication
|
|
196
|
+
- `GPG_PRIVATE_KEY`: ASCII-armored GPG key
|
|
197
|
+
- `GPG_PASSPHRASE`: GPG passphrase
|
|
198
|
+
|
|
199
|
+
Automated via GitHub Actions workflow dispatch or manual:
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
npm run prepare-release
|
|
203
|
+
git config commit.gpgsign true
|
|
204
|
+
npm version patch|minor|major
|
|
205
|
+
npm publish
|
|
206
|
+
git push origin main --follow-tags
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## General guidance
|
|
210
|
+
|
|
211
|
+
Never do inline imports like `const { mkdirSync } = await import("node:fs");` -- just use standard imports.
|
|
212
|
+
|
|
213
|
+
**NEVER** add "Generated with Codex" or "Co-Authored-By: Codex" lines to git commit messages. Keep commits clean and professional.
|
package/CHANGELOG.md
CHANGED
|
@@ -14,6 +14,60 @@ Fixed for any bug fixes.
|
|
|
14
14
|
Security in case of vulnerabilities.
|
|
15
15
|
-->
|
|
16
16
|
|
|
17
|
+
## 1.4.1 - 2026-04-27
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
|
|
21
|
+
- **SIGABRT during Node.js environment teardown.** In-flight async workers
|
|
22
|
+
(DiskArbitration/IOKit calls on macOS, and the equivalent paths on Linux
|
|
23
|
+
and Windows) could complete after `node::FreeEnvironment` had begun
|
|
24
|
+
teardown. The default `node-addon-api` completion path then threw a C++
|
|
25
|
+
`Napi::Error` out of a libuv cleanup-hook frame with no catch, causing
|
|
26
|
+
`terminate()` / abort.
|
|
27
|
+
|
|
28
|
+
All async workers now derive from a new `SafeAsyncWorker` base that
|
|
29
|
+
tracks per-env shutdown state via napi instance data plus
|
|
30
|
+
`napi_add_env_cleanup_hook`. During teardown, completion callbacks
|
|
31
|
+
short-circuit and deferred resolve/reject calls are wrapped to swallow
|
|
32
|
+
teardown-time napi failures (the JS-side promise is unobservable at
|
|
33
|
+
that point anyway). Long-running uncancellable native calls
|
|
34
|
+
(`IOServiceGetMatchingService`, drive-status probes) also bail out as
|
|
35
|
+
soon as the shutdown flag flips, so process exit isn't dragged out by
|
|
36
|
+
in-flight work.
|
|
37
|
+
|
|
38
|
+
No public API changes.
|
|
39
|
+
|
|
40
|
+
## 1.4.0 - 2026-04-20
|
|
41
|
+
|
|
42
|
+
### Removed
|
|
43
|
+
|
|
44
|
+
- **Linux GIO/GLib integration removed.** The optional `enable_gio` build-time
|
|
45
|
+
flag, the `getGioMountPoints` native binding, and the entire `src/linux/gio_*`
|
|
46
|
+
source tree have been deleted. The Linux mount-points and volume-metadata
|
|
47
|
+
paths now use `/proc/self/mounts` parsing exclusively.
|
|
48
|
+
|
|
49
|
+
Background: GIO was originally added to surface auto-mounted volumes (USB
|
|
50
|
+
sticks, external SSDs) that appeared to be missing from `/proc/mounts`. The
|
|
51
|
+
earlier mount-table read order has since been fixed, and direct verification
|
|
52
|
+
on Ubuntu 24 confirmed that udisks2-mounted devices (`/media/$USER/...`) are
|
|
53
|
+
fully visible via `/proc/self/mounts` without GIO. The remaining GIO code
|
|
54
|
+
path was a thin wrapper around `g_unix_mounts_get()` (which itself reads
|
|
55
|
+
`/proc/self/mountinfo`) — functionally redundant with the existing mtab
|
|
56
|
+
parser. The GVolumeMonitor enrichment path that originally justified GIO had
|
|
57
|
+
already been removed for thread-safety reasons in an earlier release.
|
|
58
|
+
|
|
59
|
+
Net effect: smaller native module, no `libglib2.0-dev` build dependency, no
|
|
60
|
+
`libgio` runtime dependency, simpler Linux build matrix. No public API
|
|
61
|
+
changes — `getVolumeMountPoints()` and `getVolumeMetadata()` return the same
|
|
62
|
+
data as before.
|
|
63
|
+
|
|
64
|
+
### Changed
|
|
65
|
+
|
|
66
|
+
- Linux build no longer requires `libglib2.0-dev`. Only `libblkid-dev` (and
|
|
67
|
+
`uuid-dev` for the dev environment) is needed when compiling from source.
|
|
68
|
+
- `scripts/setup-native.mjs` removed — its only purpose was GIO autodetection.
|
|
69
|
+
`npm run build` and `npm run build:native` no longer invoke it.
|
|
70
|
+
|
|
17
71
|
## 1.3.0 - 2026-03-26
|
|
18
72
|
|
|
19
73
|
### Added
|
package/CONTRIBUTING.md
CHANGED
|
@@ -41,7 +41,7 @@ Install the Xcode Command Line Tools, and then
|
|
|
41
41
|
|
|
42
42
|
### On Ubuntu/Debian
|
|
43
43
|
|
|
44
|
-
sudo apt-get install bear build-essential clang-format
|
|
44
|
+
sudo apt-get install bear build-essential clang-format libblkid-dev uuid-dev
|
|
45
45
|
|
|
46
46
|
## Before submitting your PR
|
|
47
47
|
|
|
@@ -57,7 +57,7 @@ into account both Windows and POSIX systems.
|
|
|
57
57
|
|
|
58
58
|
- macOS on x86 and Apple Silicon
|
|
59
59
|
- Windows on x64
|
|
60
|
-
- glibc Linux on x64 and arm64
|
|
60
|
+
- glibc Linux on x64 and arm64
|
|
61
61
|
- MUSL Alpine Linux on x64 and arm64
|
|
62
62
|
|
|
63
63
|
## Development Gotchas
|
|
@@ -121,7 +121,7 @@ Actions that have multiple targets can be run in parallel using wildcards:
|
|
|
121
121
|
|
|
122
122
|
### Naming Guidelines
|
|
123
123
|
|
|
124
|
-
- Use explicit names to avoid ambiguity (e.g., `
|
|
124
|
+
- Use explicit names to avoid ambiguity (e.g., `build:native` instead of just `build`)
|
|
125
125
|
- Group related scripts by action prefix for easy wildcard execution
|
|
126
126
|
- Avoid names that could cause npm lifecycle conflicts (e.g., `prebuild` vs `build`)
|
|
127
127
|
- Use descriptive suffixes that clearly indicate the target or purpose
|
package/binding.gyp
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
{
|
|
2
|
-
"variables": {
|
|
3
|
-
"enable_gio%": "false"
|
|
4
|
-
},
|
|
5
2
|
"targets": [
|
|
6
3
|
{
|
|
7
4
|
"target_name": "fs_metadata",
|
|
@@ -57,25 +54,6 @@
|
|
|
57
54
|
"cflags": ["-mbranch-protection=standard"],
|
|
58
55
|
"cflags_cc": ["-mbranch-protection=standard"]
|
|
59
56
|
}
|
|
60
|
-
],
|
|
61
|
-
[
|
|
62
|
-
"enable_gio=='true'",
|
|
63
|
-
{
|
|
64
|
-
"sources": [
|
|
65
|
-
"src/linux/gio_utils.cpp",
|
|
66
|
-
"src/linux/gio_mount_points.cpp",
|
|
67
|
-
"src/linux/gio_volume_metadata.cpp"
|
|
68
|
-
],
|
|
69
|
-
"defines": [
|
|
70
|
-
"ENABLE_GIO=1"
|
|
71
|
-
],
|
|
72
|
-
"libraries": [
|
|
73
|
-
"<!@(pkg-config --libs gio-unix-2.0)"
|
|
74
|
-
],
|
|
75
|
-
"cflags": [
|
|
76
|
-
"<!@(pkg-config --cflags gio-unix-2.0)"
|
|
77
|
-
]
|
|
78
|
-
}
|
|
79
57
|
]
|
|
80
58
|
]
|
|
81
59
|
}
|
package/dist/index.cjs
CHANGED
|
@@ -694,11 +694,6 @@ async function* readLinks(directory) {
|
|
|
694
694
|
// src/linux/mount_points.ts
|
|
695
695
|
var import_promises4 = require("fs/promises");
|
|
696
696
|
|
|
697
|
-
// src/mount_point.ts
|
|
698
|
-
function isMountPoint(obj) {
|
|
699
|
-
return isObject(obj) && "mountPoint" in obj && isNotBlank(obj.mountPoint);
|
|
700
|
-
}
|
|
701
|
-
|
|
702
697
|
// src/options.ts
|
|
703
698
|
var import_node_os2 = require("os");
|
|
704
699
|
var import_node_process3 = require("process");
|
|
@@ -1180,49 +1175,25 @@ function parseMtab(content) {
|
|
|
1180
1175
|
}
|
|
1181
1176
|
|
|
1182
1177
|
// src/linux/mount_points.ts
|
|
1183
|
-
async function getLinuxMountPoints(
|
|
1178
|
+
async function getLinuxMountPoints(opts) {
|
|
1184
1179
|
const o = optionsWithDefaults(opts);
|
|
1185
|
-
const raw = [];
|
|
1186
|
-
try {
|
|
1187
|
-
const arr = await (await native()).getGioMountPoints?.();
|
|
1188
|
-
debug("[getLinuxMountPoints] GIO mount points: %o", arr);
|
|
1189
|
-
if (arr != null) raw.push(...arr);
|
|
1190
|
-
} catch (error) {
|
|
1191
|
-
debug("Failed to get GIO mount points: %s", error);
|
|
1192
|
-
}
|
|
1193
1180
|
let cause;
|
|
1194
1181
|
for (const input of o.linuxMountTablePaths) {
|
|
1195
1182
|
try {
|
|
1196
1183
|
const mtabContent = await (0, import_promises4.readFile)(input, "utf8");
|
|
1197
|
-
const
|
|
1198
|
-
debug("[getLinuxMountPoints] %s mount points: %o", input,
|
|
1199
|
-
if (
|
|
1200
|
-
|
|
1201
|
-
break;
|
|
1184
|
+
const results = parseMtab(mtabContent).map((ea) => mountEntryToMountPoint(ea)).filter((ea) => ea != null);
|
|
1185
|
+
debug("[getLinuxMountPoints] %s mount points: %o", input, results);
|
|
1186
|
+
if (results.length > 0) {
|
|
1187
|
+
return results;
|
|
1202
1188
|
}
|
|
1203
1189
|
} catch (error) {
|
|
1204
1190
|
cause ??= toError(error);
|
|
1205
1191
|
}
|
|
1206
1192
|
}
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
if (isMountPoint(merged)) {
|
|
1212
|
-
byMountPoint.set(merged.mountPoint, merged);
|
|
1213
|
-
}
|
|
1214
|
-
}
|
|
1215
|
-
if (byMountPoint.size === 0) {
|
|
1216
|
-
throw new WrappedError(
|
|
1217
|
-
`Failed to find any mount points (tried: ${JSON.stringify(o.linuxMountTablePaths)})`,
|
|
1218
|
-
{ cause }
|
|
1219
|
-
);
|
|
1220
|
-
}
|
|
1221
|
-
const results = [...byMountPoint.values()];
|
|
1222
|
-
debug("[getLinuxMountPoints] %o", {
|
|
1223
|
-
results: results.map((ea) => ea.mountPoint)
|
|
1224
|
-
});
|
|
1225
|
-
return results;
|
|
1193
|
+
throw new WrappedError(
|
|
1194
|
+
`Failed to find any mount points (tried: ${JSON.stringify(o.linuxMountTablePaths)})`,
|
|
1195
|
+
{ cause }
|
|
1196
|
+
);
|
|
1226
1197
|
}
|
|
1227
1198
|
async function getLinuxMtabMetadata(mountPoint, opts) {
|
|
1228
1199
|
let caughtError;
|
|
@@ -1349,7 +1320,7 @@ async function _getVolumeMountPoints(o, nativeFn2) {
|
|
|
1349
1320
|
points.length
|
|
1350
1321
|
);
|
|
1351
1322
|
return points;
|
|
1352
|
-
})() : getLinuxMountPoints(
|
|
1323
|
+
})() : getLinuxMountPoints(o));
|
|
1353
1324
|
debug("[getVolumeMountPoints] raw mount points: %o", raw);
|
|
1354
1325
|
const compacted = raw.map((ea) => compactValues(ea)).filter((ea) => isNotBlank(ea.mountPoint));
|
|
1355
1326
|
for (const ea of compacted) {
|