node-liblzma 1.1.8 → 2.0.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 (76) hide show
  1. package/.claude/settings.local.json +92 -0
  2. package/.gitattributes +3 -0
  3. package/.release-it.json +6 -0
  4. package/CHANGELOG.md +209 -0
  5. package/History.md +23 -1
  6. package/README.md +750 -30
  7. package/RELEASING.md +131 -0
  8. package/binding.gyp +159 -438
  9. package/biome.json +81 -0
  10. package/coverage/base.css +224 -0
  11. package/coverage/block-navigation.js +87 -0
  12. package/coverage/errors.ts.html +586 -0
  13. package/coverage/favicon.png +0 -0
  14. package/coverage/index.html +146 -0
  15. package/coverage/lcov-report/base.css +224 -0
  16. package/coverage/lcov-report/block-navigation.js +87 -0
  17. package/coverage/lcov-report/errors.ts.html +586 -0
  18. package/coverage/lcov-report/favicon.png +0 -0
  19. package/coverage/lcov-report/index.html +146 -0
  20. package/coverage/lcov-report/lzma.ts.html +2596 -0
  21. package/coverage/lcov-report/pool.ts.html +769 -0
  22. package/coverage/lcov-report/prettify.css +1 -0
  23. package/coverage/lcov-report/prettify.js +2 -0
  24. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  25. package/coverage/lcov-report/sorter.js +210 -0
  26. package/coverage/lcov.info +636 -0
  27. package/coverage/lzma.ts.html +2596 -0
  28. package/coverage/pool.ts.html +769 -0
  29. package/coverage/prettify.css +1 -0
  30. package/coverage/prettify.js +2 -0
  31. package/coverage/sort-arrow-sprite.png +0 -0
  32. package/coverage/sorter.js +210 -0
  33. package/coverage-reports/assets/monocart-coverage-app.js +2 -0
  34. package/coverage-reports/coverage-data.js +1 -0
  35. package/coverage-reports/index.html +48 -0
  36. package/err.log +26 -0
  37. package/index.d.ts +254 -0
  38. package/lib/errors.d.ts +72 -0
  39. package/lib/errors.d.ts.map +1 -0
  40. package/lib/errors.js +153 -0
  41. package/lib/errors.js.map +1 -0
  42. package/lib/lzma.d.ts +245 -0
  43. package/lib/lzma.d.ts.map +1 -0
  44. package/lib/lzma.js +626 -345
  45. package/lib/lzma.js.map +1 -0
  46. package/lib/pool.d.ts +123 -0
  47. package/lib/pool.d.ts.map +1 -0
  48. package/lib/pool.js +188 -0
  49. package/lib/pool.js.map +1 -0
  50. package/lib/types.d.ts +27 -0
  51. package/lib/types.d.ts.map +1 -0
  52. package/lib/types.js +5 -0
  53. package/lib/types.js.map +1 -0
  54. package/package.json +60 -21
  55. package/pnpm-workspace.yaml +3 -0
  56. package/scripts/analyze-coverage.js +132 -0
  57. package/scripts/build_xz_with_cmake.py +390 -0
  58. package/scripts/compare-coverage-tools.js +93 -0
  59. package/scripts/copy_dll.py +51 -0
  60. package/scripts/download_xz_from_github.py +375 -0
  61. package/src/bindings/module.cpp +107 -0
  62. package/src/bindings/node-liblzma.cpp +522 -0
  63. package/src/bindings/node-liblzma.hpp +144 -0
  64. package/src/errors.ts +167 -0
  65. package/src/lzma.ts +839 -0
  66. package/src/pool.ts +228 -0
  67. package/src/types.ts +30 -0
  68. package/tsconfig.json +50 -0
  69. package/vitest.config.istanbul.ts +29 -0
  70. package/vitest.config.monocart.ts +44 -0
  71. package/vitest.config.ts +44 -0
  72. package/xz-version.json +8 -0
  73. package/prebuilds/darwin-x64/node.napi.node +0 -0
  74. package/prebuilds/linux-x64/node.napi.node +0 -0
  75. package/prebuilds/win32-x64/node.napi.node +0 -0
  76. package/scripts/download_extract_deps.py +0 -29
@@ -0,0 +1,390 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Build XZ Utils using CMake from GitHub sources.
4
+
5
+ This script compiles liblzma from XZ sources using CMake, which works
6
+ with raw Git sources without needing autogen.sh or pre-built config files.
7
+
8
+ Usage:
9
+ python3 build_xz_with_cmake.py <xz_source_dir> <install_prefix> [runtime_link] [enable_threads]
10
+ """
11
+
12
+ import os
13
+ import sys
14
+ import subprocess
15
+ import platform
16
+ import argparse
17
+ import shutil
18
+ from pathlib import Path
19
+
20
+ def detect_cmake():
21
+ """Check if CMake is available"""
22
+ try:
23
+ result = subprocess.run(['cmake', '--version'],
24
+ capture_output=True, text=True, check=True)
25
+ version_line = result.stdout.split('\n')[0]
26
+ print(f"[PACKAGE] Found {version_line}")
27
+ return True
28
+ except (subprocess.CalledProcessError, FileNotFoundError):
29
+ return False
30
+
31
+ def get_cmake_generator():
32
+ """Get appropriate CMake generator for the current platform"""
33
+ system = platform.system()
34
+ if system == "Windows":
35
+ # Use Ninja or Unix Makefiles for better CI compatibility
36
+ # Visual Studio generator can be problematic in CI environments
37
+ return "Ninja" if shutil.which('ninja') else "Unix Makefiles"
38
+ else:
39
+ # Use Unix Makefiles on Linux/macOS (works with make, ninja, etc.)
40
+ return "Unix Makefiles"
41
+
42
+ def configure_cmake(source_dir, build_dir, install_dir, runtime_link="static", enable_threads="no"):
43
+ """Configure XZ build with CMake"""
44
+ generator = get_cmake_generator()
45
+ cmake_args = [
46
+ 'cmake',
47
+ f'-G{generator}',
48
+ f'-B{build_dir}',
49
+ f'-DCMAKE_INSTALL_PREFIX={install_dir}',
50
+ '-DCMAKE_BUILD_TYPE=Release',
51
+ '-DBUILD_SHARED_LIBS=OFF' if runtime_link == 'static' else '-DBUILD_SHARED_LIBS=ON',
52
+ # Build only liblzma, not the command-line tools
53
+ '-DCREATE_XZ_SYMLINKS=OFF',
54
+ '-DCREATE_LZMA_SYMLINKS=OFF',
55
+ # Disable CLI tools completely (they have libintl dependency issues on macOS)
56
+ '-DXZ_TOOL_XZ=OFF',
57
+ '-DXZ_TOOL_LZMAINFO=OFF',
58
+ '-DXZ_TOOL_XZDEC=OFF',
59
+ '-DXZ_TOOL_LZMADEC=OFF',
60
+ # Enable Position Independent Code for use in shared libraries
61
+ '-DCMAKE_POSITION_INDEPENDENT_CODE=ON',
62
+ # Disable compiler warnings that might cause issues in CI
63
+ '-DCMAKE_C_FLAGS=-w',
64
+ ]
65
+
66
+ # Platform-specific configuration
67
+ system = platform.system()
68
+
69
+ # Threading support - XZ 5.8+ has full XZ_THREADS support
70
+ if enable_threads.lower() in ['yes', 'true', '1']:
71
+ cmake_args.append('-DXZ_THREADS=yes')
72
+ print("[THREAD] Threading support: enabled (XZ_THREADS=yes)")
73
+ else:
74
+ cmake_args.append('-DXZ_THREADS=no')
75
+ print("[THREAD] Threading support: disabled (XZ_THREADS=no)")
76
+
77
+ if system == "Windows":
78
+ # Use Visual Studio generator for Windows builds (supports -A x64)
79
+ cmake_args.extend(['-G', 'Visual Studio 17 2022', '-A', 'x64'])
80
+ print("[BUILD] Windows x64 build configuration")
81
+ elif system == "Darwin":
82
+ # macOS specific optimizations
83
+ cmake_args.extend([
84
+ '-DCMAKE_OSX_DEPLOYMENT_TARGET=10.15'
85
+ ])
86
+
87
+ # For shared libraries on macOS, configure proper install_name
88
+ if runtime_link == "shared":
89
+ cmake_args.extend([
90
+ '-DCMAKE_INSTALL_NAME_DIR=@rpath',
91
+ '-DCMAKE_BUILD_WITH_INSTALL_RPATH=ON',
92
+ '-DCMAKE_INSTALL_RPATH=@loader_path;@loader_path/../lib',
93
+ '-DCMAKE_MACOSX_RPATH=ON'
94
+ ])
95
+ print("[BUILD] macOS shared library: configured @rpath install_name")
96
+
97
+ print("[BUILD] macOS build configuration")
98
+ else:
99
+ # Linux and other Unix systems
100
+ print("[BUILD] Linux/Unix build configuration")
101
+
102
+ cmake_args.append(source_dir)
103
+
104
+ print(f"[CONFIG] Configuring CMake build...")
105
+ print(f" Source: {source_dir}")
106
+ print(f" Build: {build_dir}")
107
+ print(f" Install: {install_dir}")
108
+ print(f" Runtime: {runtime_link}")
109
+
110
+ try:
111
+ result = subprocess.run(cmake_args, check=True, cwd=source_dir, capture_output=True, text=True)
112
+ print("[SUCCESS] CMake configuration successful")
113
+
114
+ # Log all CMake output for threading diagnostics
115
+ print(f"[DEBUG] Full CMake configuration output:")
116
+ for line in result.stdout.split('\n'):
117
+ if line.strip():
118
+ print(f"[DEBUG] {line.strip()}")
119
+
120
+ if result.stderr.strip():
121
+ print(f"[DEBUG] CMake stderr:")
122
+ for line in result.stderr.split('\n'):
123
+ if line.strip():
124
+ print(f"[DEBUG] {line.strip()}")
125
+
126
+ return True
127
+ except subprocess.CalledProcessError as e:
128
+ print(f"[ERROR] CMake configuration failed with exit code {e.returncode}")
129
+ if e.stdout:
130
+ print(f"[ERROR] stdout: {e.stdout}")
131
+ if e.stderr:
132
+ print(f"[ERROR] stderr: {e.stderr}")
133
+ return False
134
+
135
+ def build_cmake(build_dir):
136
+ """Build the configured CMake project"""
137
+ cmake_args = [
138
+ 'cmake',
139
+ '--build', build_dir,
140
+ '--config', 'Release',
141
+ '--parallel'
142
+ ]
143
+
144
+ print("[BUILD] Building XZ with CMake...")
145
+
146
+ try:
147
+ result = subprocess.run(cmake_args, check=True)
148
+ print("[SUCCESS] CMake build successful")
149
+ return True
150
+ except subprocess.CalledProcessError as e:
151
+ print(f"[ERROR] CMake build failed with exit code {e.returncode}")
152
+ return False
153
+
154
+ def install_cmake(build_dir, install_dir):
155
+ """Install the built libraries to the target directory"""
156
+ cmake_args = [
157
+ 'cmake',
158
+ '--install', build_dir,
159
+ '--prefix', install_dir,
160
+ '--config', 'Release'
161
+ ]
162
+
163
+ print(f"[INSTALL] Installing to {install_dir}...")
164
+
165
+ # Ensure install directory exists
166
+ os.makedirs(install_dir, exist_ok=True)
167
+
168
+ try:
169
+ result = subprocess.run(cmake_args, check=True)
170
+ print("[SUCCESS] CMake install successful")
171
+ return True
172
+ except subprocess.CalledProcessError as e:
173
+ print(f"[ERROR] CMake install failed with exit code {e.returncode}")
174
+ return False
175
+
176
+ def fix_windows_lib_names(install_dir):
177
+ """Fix Windows library naming: CMake creates lzma.lib but binding.gyp expects liblzma.lib"""
178
+ if platform.system() != "Windows":
179
+ return True
180
+
181
+ import shutil
182
+ lib_dir = os.path.join(install_dir, 'lib')
183
+ source_lib = os.path.join(lib_dir, 'lzma.lib')
184
+ target_lib = os.path.join(lib_dir, 'liblzma.lib')
185
+
186
+ if os.path.exists(source_lib) and not os.path.exists(target_lib):
187
+ try:
188
+ shutil.copy2(source_lib, target_lib)
189
+ print(f"[FIX] Created {target_lib} from {source_lib}")
190
+ return True
191
+ except Exception as e:
192
+ print(f"[WARNING] Could not create liblzma.lib: {e}")
193
+ return False
194
+ elif os.path.exists(target_lib):
195
+ print(f"[OK] {target_lib} already exists")
196
+ return True
197
+ else:
198
+ print(f"[WARNING] Source file {source_lib} not found")
199
+ return False
200
+
201
+ def verify_and_fix_dylib_install_name(install_dir, runtime_link="static"):
202
+ """Verify and fix macOS dylib install_name to use @rpath"""
203
+ # Only relevant for macOS shared library builds
204
+ if platform.system() != "Darwin" or runtime_link != "shared":
205
+ return True
206
+
207
+ dylib_path = os.path.join(install_dir, 'lib', 'liblzma.dylib')
208
+ if not os.path.exists(dylib_path):
209
+ print(f"[WARNING] Dylib not found at {dylib_path}")
210
+ return False
211
+
212
+ try:
213
+ # Check current install_name using otool
214
+ result = subprocess.run(['otool', '-D', dylib_path],
215
+ capture_output=True, text=True, check=True)
216
+ current_install_name = result.stdout.strip().split('\n')[-1]
217
+
218
+ print(f"[VERIFY] Current install_name: {current_install_name}")
219
+
220
+ # If install_name doesn't start with @rpath, fix it
221
+ if not current_install_name.startswith('@rpath'):
222
+ print(f"[FIX] Fixing install_name to use @rpath")
223
+ subprocess.run(['install_name_tool', '-id', '@rpath/liblzma.dylib', dylib_path],
224
+ check=True)
225
+
226
+ # Verify the fix
227
+ result = subprocess.run(['otool', '-D', dylib_path],
228
+ capture_output=True, text=True, check=True)
229
+ new_install_name = result.stdout.strip().split('\n')[-1]
230
+ print(f"[SUCCESS] Updated install_name: {new_install_name}")
231
+
232
+ if not new_install_name.startswith('@rpath'):
233
+ print(f"[ERROR] Failed to update install_name")
234
+ return False
235
+ else:
236
+ print(f"[OK] install_name already uses @rpath")
237
+
238
+ return True
239
+
240
+ except subprocess.CalledProcessError as e:
241
+ print(f"[ERROR] Failed to verify/fix install_name: {e}")
242
+ return False
243
+ except Exception as e:
244
+ print(f"[ERROR] Unexpected error in install_name verification: {e}")
245
+ return False
246
+
247
+ def verify_build(install_dir, runtime_link="static"):
248
+ """Verify that the build produced the expected files"""
249
+ expected_files = ['include/lzma.h'] # Common file for all builds
250
+
251
+ system = platform.system()
252
+ if system == "Windows":
253
+ if runtime_link == "static":
254
+ expected_files.append('lib/liblzma.lib')
255
+ else:
256
+ # For shared builds on Windows, expect both import lib and DLL
257
+ expected_files.extend(['lib/liblzma.lib', 'bin/liblzma.dll'])
258
+ else:
259
+ if runtime_link == "static":
260
+ expected_files.append('lib/liblzma.a')
261
+ else:
262
+ # For shared builds, look for .so files (or .dylib on macOS)
263
+ if system == "Darwin":
264
+ expected_files.append('lib/liblzma.dylib')
265
+ else:
266
+ expected_files.append('lib/liblzma.so')
267
+
268
+ missing_files = []
269
+ for file_path in expected_files:
270
+ full_path = os.path.join(install_dir, file_path)
271
+ if not os.path.exists(full_path):
272
+ missing_files.append(file_path)
273
+
274
+ if missing_files:
275
+ print(f"[WARNING] Missing expected files: {', '.join(missing_files)}")
276
+ return False
277
+ else:
278
+ print("[SUCCESS] Build verification successful - all expected files present")
279
+ return True
280
+
281
+ def main():
282
+ parser = argparse.ArgumentParser(
283
+ description='Build XZ Utils using CMake',
284
+ epilog='''
285
+ Required environment variables (strict validation):
286
+ RUNTIME_LINK: 'static' or 'shared' (REQUIRED)
287
+ ENABLE_THREAD_SUPPORT: 'yes' or 'no' (REQUIRED)
288
+ USE_GLOBAL: 'true' or 'false' (REQUIRED)
289
+
290
+ Examples:
291
+ RUNTIME_LINK=static ENABLE_THREAD_SUPPORT=yes USE_GLOBAL=false \\
292
+ python3 build_xz_with_cmake.py deps/xz build/liblzma
293
+
294
+ RUNTIME_LINK=shared ENABLE_THREAD_SUPPORT=no USE_GLOBAL=true \\
295
+ python3 build_xz_with_cmake.py deps/xz build/liblzma
296
+ ''',
297
+ formatter_class=argparse.RawDescriptionHelpFormatter
298
+ )
299
+
300
+ parser.add_argument('source_dir', help='XZ source directory')
301
+ parser.add_argument('install_dir', help='Installation directory')
302
+ parser.add_argument('--verbose', '-v', action='store_true',
303
+ help='Verbose output')
304
+
305
+ args = parser.parse_args()
306
+
307
+ # Get configuration from environment variables with strict validation
308
+ runtime_link = os.environ.get('RUNTIME_LINK')
309
+ enable_threads = os.environ.get('ENABLE_THREAD_SUPPORT')
310
+ use_global = os.environ.get('USE_GLOBAL')
311
+
312
+ # Strict validation - fail if critical variables are not explicitly set
313
+ if runtime_link is None:
314
+ print("[ERROR] RUNTIME_LINK environment variable must be explicitly set ('static' or 'shared')")
315
+ return 1
316
+
317
+ if enable_threads is None:
318
+ print("[ERROR] ENABLE_THREAD_SUPPORT environment variable must be explicitly set ('yes' or 'no')")
319
+ return 1
320
+
321
+ if use_global is None:
322
+ print("[ERROR] USE_GLOBAL environment variable must be explicitly set ('true' or 'false')")
323
+ return 1
324
+
325
+ # Validate values
326
+ if runtime_link not in ['static', 'shared']:
327
+ print(f"[ERROR] Invalid RUNTIME_LINK: {runtime_link}. Must be 'static' or 'shared'")
328
+ return 1
329
+
330
+ if enable_threads.lower() not in ['yes', 'no', 'true', 'false', '1', '0']:
331
+ print(f"[ERROR] Invalid ENABLE_THREAD_SUPPORT: {enable_threads}. Must be yes/no/true/false/1/0")
332
+ return 1
333
+
334
+ if use_global.lower() not in ['true', 'false']:
335
+ print(f"[ERROR] Invalid USE_GLOBAL: {use_global}. Must be 'true' or 'false'")
336
+ return 1
337
+
338
+ # Convert to absolute paths
339
+ source_dir = os.path.abspath(args.source_dir)
340
+ install_dir = os.path.abspath(args.install_dir)
341
+ build_dir = os.path.join(source_dir, 'build-cmake')
342
+
343
+ if args.verbose:
344
+ print("[VERBOSE] Verbose mode enabled")
345
+
346
+ # Validate source directory
347
+ cmake_file = os.path.join(source_dir, 'CMakeLists.txt')
348
+ if not os.path.exists(cmake_file):
349
+ print(f"[ERROR] CMakeLists.txt not found in {source_dir}")
350
+ return 1
351
+
352
+ # Check CMake availability
353
+ if not detect_cmake():
354
+ print("[ERROR] CMake not found. Please install CMake to continue.")
355
+ return 1
356
+
357
+ # Clean build directory if it exists
358
+ if os.path.exists(build_dir):
359
+ import shutil
360
+ print(f"[CLEAN] Cleaning existing build directory: {build_dir}")
361
+ shutil.rmtree(build_dir)
362
+
363
+ # Build process
364
+ success = (
365
+ configure_cmake(source_dir, build_dir, install_dir,
366
+ runtime_link, enable_threads) and
367
+ build_cmake(build_dir) and
368
+ install_cmake(build_dir, install_dir) and
369
+ fix_windows_lib_names(install_dir) and
370
+ verify_and_fix_dylib_install_name(install_dir, runtime_link) and
371
+ verify_build(install_dir, runtime_link)
372
+ )
373
+
374
+ if success:
375
+ print(f"[DONE] XZ build completed successfully!")
376
+ print(f" Libraries installed in: {install_dir}")
377
+ return 0
378
+ else:
379
+ print("[ERROR] Build failed")
380
+ return 1
381
+
382
+ if __name__ == '__main__':
383
+ try:
384
+ sys.exit(main())
385
+ except KeyboardInterrupt:
386
+ print("\n[ERROR] Interrupted by user")
387
+ sys.exit(1)
388
+ except Exception as e:
389
+ print(f"[ERROR] Unexpected error: {e}")
390
+ sys.exit(1)
@@ -0,0 +1,93 @@
1
+ #!/usr/bin/env node
2
+
3
+ import fs from 'fs';
4
+ import path from 'path';
5
+
6
+ const V8_COVERAGE = './coverage/coverage-final.json';
7
+ const MONOCART_DATA = './coverage-reports/coverage-data.js';
8
+ const SOURCE_FILE = './src/lzma.ts';
9
+
10
+ console.log('🔍 COMPARAISON V8 vs MONOCART\n');
11
+
12
+ // Lire V8
13
+ if (!fs.existsSync(V8_COVERAGE)) {
14
+ console.log('❌ V8 coverage manquant');
15
+ process.exit(1);
16
+ }
17
+ const v8Coverage = JSON.parse(fs.readFileSync(V8_COVERAGE, 'utf8'));
18
+ const sourceLines = fs.readFileSync(SOURCE_FILE, 'utf8').split('\n');
19
+ const filePath = path.resolve(SOURCE_FILE);
20
+ const v8Data = v8Coverage[filePath] || v8Coverage[Object.keys(v8Coverage)[0]];
21
+
22
+ // Lire Monocart
23
+ if (!fs.existsSync(MONOCART_DATA)) {
24
+ console.log('❌ Monocart data manquant');
25
+ process.exit(1);
26
+ }
27
+
28
+ // Extraire les données Monocart du fichier JS
29
+ const monocartContent = fs.readFileSync(MONOCART_DATA, 'utf8');
30
+ const monocartMatch = monocartContent.match(/window\.reportData\s*=\s*'([^']+)'/);
31
+ if (!monocartMatch) {
32
+ console.log('❌ Format Monocart non reconnu');
33
+ process.exit(1);
34
+ }
35
+
36
+ // Monocart utilise un format compressé, on doit le décoder
37
+ console.log('⚠️ Monocart utilise un format de données compressé, analyse simplifiée...');
38
+ const monocartData = { summary: null };
39
+ const summaryData = monocartData.summary;
40
+
41
+ console.log('📊 COMPARAISON GLOBALE:');
42
+ console.log(
43
+ `V8 : ${v8Data.s ? Object.values(v8Data.s).filter((x) => x > 0).length : 0} statements couverts / ${v8Data.s ? Object.keys(v8Data.s).length : 0} total`
44
+ );
45
+ console.log(
46
+ `Monocart : ${summaryData.statements.covered} statements couverts / ${summaryData.statements.total} total`
47
+ );
48
+ console.log('');
49
+
50
+ console.log(
51
+ `V8 : ${v8Data.b ? Object.values(v8Data.b).filter((arr) => arr.every((x) => x > 0)).length : 0} branches couvertes / ${v8Data.b ? Object.keys(v8Data.b).length : 0} total`
52
+ );
53
+ console.log(
54
+ `Monocart : ${summaryData.branches.covered} branches couvertes / ${summaryData.branches.total} total`
55
+ );
56
+ console.log('');
57
+
58
+ console.log(
59
+ `V8 : ${v8Data.f ? Object.values(v8Data.f).filter((x) => x > 0).length : 0} fonctions couvertes / ${v8Data.f ? Object.keys(v8Data.f).length : 0} total`
60
+ );
61
+ console.log(
62
+ `Monocart : ${summaryData.functions.covered} fonctions couvertes / ${summaryData.functions.total} total`
63
+ );
64
+ console.log('');
65
+
66
+ // Analyse des statements non couverts
67
+ const v8UncoveredStmts = Object.entries(v8Data.s || {}).filter(([, count]) => count === 0);
68
+ console.log(`🎯 V8 STATEMENTS NON COUVERTS: ${v8UncoveredStmts.length}`);
69
+ v8UncoveredStmts.slice(0, 5).forEach(([key]) => {
70
+ const stmt = v8Data.statementMap[key];
71
+ const line = stmt.start.line;
72
+ console.log(` Ligne ${line}: ${sourceLines[line - 1]?.trim() || 'N/A'}`);
73
+ });
74
+
75
+ console.log('\n💡 VERDICT:');
76
+ if (summaryData.statements.total !== Object.keys(v8Data.s || {}).length) {
77
+ console.log('⚠️ Monocart détecte un nombre différent de statements');
78
+ }
79
+
80
+ const v8Pct = (
81
+ (Object.values(v8Data.s || {}).filter((x) => x > 0).length / Object.keys(v8Data.s || {}).length) *
82
+ 100
83
+ ).toFixed(2);
84
+ const monocartPct = summaryData.statements.pct;
85
+
86
+ console.log(`V8 : ${v8Pct}% statements coverage`);
87
+ console.log(`Monocart : ${monocartPct}% statements coverage`);
88
+
89
+ if (Math.abs(parseFloat(monocartPct) - parseFloat(v8Pct)) > 1) {
90
+ console.log('✨ Monocart montre une différence significative !');
91
+ } else {
92
+ console.log('📊 Résultats similaires entre V8 et Monocart');
93
+ }
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Copy DLL file for Windows shared builds.
4
+
5
+ This script copies the liblzma.dll from the install directory to the build
6
+ directory so it can be found at runtime.
7
+
8
+ Usage:
9
+ python3 copy_dll.py <source_dll> <target_directory>
10
+ """
11
+
12
+ import os
13
+ import sys
14
+ import shutil
15
+ from pathlib import Path
16
+
17
+ def main():
18
+ if len(sys.argv) != 3:
19
+ print("[ERROR] Usage: python3 copy_dll.py <source_dll> <target_directory>")
20
+ return 1
21
+
22
+ source_dll = sys.argv[1]
23
+ target_dir = sys.argv[2]
24
+
25
+ # Convert to absolute paths
26
+ source_dll = os.path.abspath(source_dll)
27
+ target_dir = os.path.abspath(target_dir)
28
+
29
+ # Validate source file exists
30
+ if not os.path.exists(source_dll):
31
+ print(f"[ERROR] Source DLL not found: {source_dll}")
32
+ return 1
33
+
34
+ # Ensure target directory exists
35
+ os.makedirs(target_dir, exist_ok=True)
36
+
37
+ # Get filename and create target path
38
+ dll_name = os.path.basename(source_dll)
39
+ target_path = os.path.join(target_dir, dll_name)
40
+
41
+ try:
42
+ print(f"[COPY] Copying DLL from {source_dll} to {target_path}")
43
+ shutil.copy2(source_dll, target_path)
44
+ print(f"[SUCCESS] DLL copied successfully")
45
+ return 0
46
+ except Exception as e:
47
+ print(f"[ERROR] Failed to copy DLL: {e}")
48
+ return 1
49
+
50
+ if __name__ == '__main__':
51
+ sys.exit(main())