roxify 1.5.9 → 1.5.10
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/dist/cli.js +32 -0
- package/dist/utils/native.js +6 -4
- package/dist/utils/rust-cli-wrapper.js +92 -29
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -195,6 +195,28 @@ async function encodeCommand(args) {
|
|
|
195
195
|
catch (e) {
|
|
196
196
|
resolvedOutput = join('/', parsed.output || outputPath || outputName);
|
|
197
197
|
}
|
|
198
|
+
// Check for empty directories *before* attempting native Rust encoder.
|
|
199
|
+
try {
|
|
200
|
+
const anyDir = inputPaths.some((p) => {
|
|
201
|
+
try {
|
|
202
|
+
return statSync(resolve(safeCwd, p)).isDirectory();
|
|
203
|
+
}
|
|
204
|
+
catch (e) {
|
|
205
|
+
return false;
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
if (anyDir) {
|
|
209
|
+
const { index } = await packPathsGenerator(inputPaths, undefined, () => { });
|
|
210
|
+
if (!index || index.length === 0) {
|
|
211
|
+
console.log(' ');
|
|
212
|
+
console.error('Error: No files found in specified input paths.');
|
|
213
|
+
process.exit(1);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
catch (e) {
|
|
218
|
+
// ignore errors from the quick pre-check and proceed to try Rust encoding
|
|
219
|
+
}
|
|
198
220
|
if (isRustBinaryAvailable() && !parsed.forceTs) {
|
|
199
221
|
try {
|
|
200
222
|
console.log(`Encoding to ${resolvedOutput} (Using native Rust encoder)\n`);
|
|
@@ -313,6 +335,11 @@ async function encodeCommand(args) {
|
|
|
313
335
|
if (inputPaths.length > 1) {
|
|
314
336
|
currentEncodeStep = 'Reading files';
|
|
315
337
|
const { index, stream, totalSize } = await packPathsGenerator(inputPaths, undefined, onProgress);
|
|
338
|
+
if (!index || index.length === 0) {
|
|
339
|
+
console.log(' ');
|
|
340
|
+
console.error('Error: No files found in specified input paths.');
|
|
341
|
+
process.exit(1);
|
|
342
|
+
}
|
|
316
343
|
inputData = stream;
|
|
317
344
|
inputSizeVal = totalSize;
|
|
318
345
|
displayName = parsed.outputName || 'archive';
|
|
@@ -328,6 +355,11 @@ async function encodeCommand(args) {
|
|
|
328
355
|
if (st.isDirectory()) {
|
|
329
356
|
currentEncodeStep = 'Reading files';
|
|
330
357
|
const { index, stream, totalSize } = await packPathsGenerator([resolvedInput], dirname(resolvedInput), onProgress);
|
|
358
|
+
if (!index || index.length === 0) {
|
|
359
|
+
console.log(' ');
|
|
360
|
+
console.error(`Error: No files found in ${resolvedInput}`);
|
|
361
|
+
process.exit(1);
|
|
362
|
+
}
|
|
331
363
|
inputData = stream;
|
|
332
364
|
inputSizeVal = totalSize;
|
|
333
365
|
displayName = parsed.outputName || basename(resolvedInput);
|
package/dist/utils/native.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { join, dirname, resolve } from 'path';
|
|
1
|
+
import { existsSync } from 'fs';
|
|
3
2
|
import { createRequire } from 'module';
|
|
3
|
+
import { arch, platform } from 'os';
|
|
4
|
+
import { dirname, join, resolve } from 'path';
|
|
4
5
|
import { fileURLToPath } from 'url';
|
|
5
|
-
import { existsSync } from 'fs';
|
|
6
6
|
function getNativeModule() {
|
|
7
7
|
let moduleDir;
|
|
8
8
|
let nativeRequire;
|
|
@@ -59,7 +59,9 @@ function getNativeModule() {
|
|
|
59
59
|
// @ts-ignore
|
|
60
60
|
console.debug('[native] moduleDir', moduleDir);
|
|
61
61
|
let root = moduleDir && moduleDir !== '.' ? moduleDir : process.cwd();
|
|
62
|
-
while (root.length > 1 &&
|
|
62
|
+
while (root.length > 1 &&
|
|
63
|
+
!existsSync(resolve(root, 'package.json')) &&
|
|
64
|
+
!existsSync(resolve(root, 'Cargo.toml'))) {
|
|
63
65
|
const parent = resolve(root, '..');
|
|
64
66
|
if (parent === root)
|
|
65
67
|
break;
|
|
@@ -23,27 +23,51 @@ function findRustBinary() {
|
|
|
23
23
|
const binNames = process.platform === 'win32'
|
|
24
24
|
? ['roxify-cli.exe', 'roxify_cli.exe', 'roxify_native.exe']
|
|
25
25
|
: ['roxify-cli', 'roxify_cli', 'roxify_native'];
|
|
26
|
+
const baseDir = typeof moduleDir !== 'undefined' ? moduleDir : process.cwd();
|
|
26
27
|
// Possible locations relative to this file (works in repo and in packaged dist)
|
|
27
28
|
const relativeDirs = [
|
|
28
|
-
join(
|
|
29
|
-
join(
|
|
30
|
-
join(
|
|
31
|
-
join(
|
|
29
|
+
join(baseDir, '..', '..', 'target', 'release'),
|
|
30
|
+
join(baseDir, '..', '..', 'dist'),
|
|
31
|
+
join(baseDir, '..'),
|
|
32
|
+
join(baseDir, '..', '..'),
|
|
33
|
+
join(baseDir, '..', 'target', 'release'),
|
|
32
34
|
];
|
|
33
35
|
for (const dir of relativeDirs) {
|
|
34
36
|
for (const name of binNames) {
|
|
35
37
|
candidates.push(join(dir, name));
|
|
36
38
|
}
|
|
37
39
|
}
|
|
38
|
-
//
|
|
40
|
+
// Walk up parents to find a workspace-level target/release (repo root may contain target)
|
|
41
|
+
try {
|
|
42
|
+
let cur = baseDir;
|
|
43
|
+
for (let i = 0; i < 8; i++) {
|
|
44
|
+
for (const name of binNames) {
|
|
45
|
+
candidates.push(join(cur, '..', '..', '..', '..', '..', '..', '..', 'target', 'release', name));
|
|
46
|
+
candidates.push(join(cur, '..', '..', '..', '..', '..', 'target', 'release', name));
|
|
47
|
+
candidates.push(join(cur, '..', '..', '..', 'target', 'release', name));
|
|
48
|
+
candidates.push(join(cur, '..', '..', 'target', 'release', name));
|
|
49
|
+
candidates.push(join(cur, '..', 'target', 'release', name));
|
|
50
|
+
candidates.push(join(cur, 'target', 'release', name));
|
|
51
|
+
}
|
|
52
|
+
const parent = join(cur, '..');
|
|
53
|
+
if (parent === cur)
|
|
54
|
+
break;
|
|
55
|
+
cur = parent;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
catch (e) { }
|
|
59
|
+
// Common global paths (last resort)
|
|
39
60
|
if (process.platform !== 'win32') {
|
|
40
61
|
candidates.push('/usr/local/bin/roxify_native');
|
|
41
62
|
candidates.push('/usr/bin/roxify_native');
|
|
42
63
|
}
|
|
43
64
|
for (const p of candidates) {
|
|
44
65
|
try {
|
|
45
|
-
if (existsSync(p))
|
|
66
|
+
if (existsSync(p)) {
|
|
67
|
+
// eslint-disable-next-line no-console
|
|
68
|
+
console.log(`Found Rust binary candidate: ${p}`);
|
|
46
69
|
return p;
|
|
70
|
+
}
|
|
47
71
|
}
|
|
48
72
|
catch (e) { }
|
|
49
73
|
}
|
|
@@ -56,8 +80,11 @@ function findRustBinary() {
|
|
|
56
80
|
const out = execSync(`${which} ${name}`, { encoding: 'utf-8' })
|
|
57
81
|
.split('\n')[0]
|
|
58
82
|
.trim();
|
|
59
|
-
if (out && existsSync(out))
|
|
83
|
+
if (out && existsSync(out)) {
|
|
84
|
+
// eslint-disable-next-line no-console
|
|
85
|
+
console.debug(`Found Rust binary in PATH: ${out}`);
|
|
60
86
|
return out;
|
|
87
|
+
}
|
|
61
88
|
}
|
|
62
89
|
catch (e) {
|
|
63
90
|
// ignore
|
|
@@ -76,30 +103,66 @@ export async function encodeWithRustCLI(inputPath, outputPath, compressionLevel
|
|
|
76
103
|
throw new Error('Rust CLI binary not found. Run: cargo build --release');
|
|
77
104
|
}
|
|
78
105
|
return new Promise((resolve, reject) => {
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
106
|
+
const baseArgs = ['encode', '--level', String(compressionLevel)];
|
|
107
|
+
const addNameArgs = (arr) => {
|
|
108
|
+
if (name) {
|
|
109
|
+
arr.push('--name', name);
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
const addPassArgs = (arr) => {
|
|
113
|
+
if (passphrase) {
|
|
114
|
+
arr.push('--passphrase', passphrase);
|
|
115
|
+
arr.push('--encrypt', encryptType);
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
const args = [...baseArgs];
|
|
119
|
+
addNameArgs(args);
|
|
120
|
+
addPassArgs(args);
|
|
87
121
|
args.push(inputPath, outputPath);
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
122
|
+
const spawnAndWait = (argsToUse) => {
|
|
123
|
+
return new Promise((res, rej) => {
|
|
124
|
+
const proc = spawn(cliPath, argsToUse);
|
|
125
|
+
let stderr = '';
|
|
126
|
+
proc.stderr.on('data', (data) => {
|
|
127
|
+
stderr += data.toString();
|
|
128
|
+
});
|
|
129
|
+
proc.on('error', (err) => rej(err));
|
|
130
|
+
proc.on('close', (code) => res({ code, stderr }));
|
|
131
|
+
});
|
|
132
|
+
};
|
|
133
|
+
(async () => {
|
|
134
|
+
try {
|
|
135
|
+
const debugMsg = `Rust CLI: ${cliPath} ${args.join(' ')}`;
|
|
136
|
+
// eslint-disable-next-line no-console
|
|
137
|
+
console.log(debugMsg);
|
|
138
|
+
let result = await spawnAndWait(args);
|
|
139
|
+
if (result.code === 0)
|
|
140
|
+
return resolve();
|
|
141
|
+
// If the error mentions an unexpected '--name' arg (older binary), retry without name
|
|
142
|
+
if (name &&
|
|
143
|
+
result.stderr &&
|
|
144
|
+
(/unexpected argument.*--name/.test(result.stderr) ||
|
|
145
|
+
/unexpected argument .*'--name'/.test(result.stderr) ||
|
|
146
|
+
result.stderr.includes("'--name'"))) {
|
|
147
|
+
const argsNoName = [...baseArgs];
|
|
148
|
+
addPassArgs(argsNoName);
|
|
149
|
+
argsNoName.push(inputPath, outputPath);
|
|
150
|
+
// eslint-disable-next-line no-console
|
|
151
|
+
console.log('Rust CLI rejected --name; retrying without --name');
|
|
152
|
+
const retryDebug = `Retrying Rust CLI: ${cliPath} ${argsNoName.join(' ')}`;
|
|
153
|
+
// eslint-disable-next-line no-console
|
|
154
|
+
console.log(retryDebug);
|
|
155
|
+
result = await spawnAndWait(argsNoName);
|
|
156
|
+
// eslint-disable-next-line no-console
|
|
157
|
+
console.log(`Rust retry exited with code ${result.code}`);
|
|
158
|
+
if (result.code === 0)
|
|
159
|
+
return resolve();
|
|
160
|
+
}
|
|
161
|
+
reject(new Error(`Rust CLI exited with code ${result.code}: ${result.stderr}`));
|
|
99
162
|
}
|
|
100
|
-
|
|
101
|
-
reject(new Error(`
|
|
163
|
+
catch (err) {
|
|
164
|
+
reject(new Error(`Failed to spawn Rust CLI: ${err.message || err}`));
|
|
102
165
|
}
|
|
103
|
-
});
|
|
166
|
+
})();
|
|
104
167
|
});
|
|
105
168
|
}
|
package/package.json
CHANGED