Skip to content

Commit edfa989

Browse files
committed
Enhance dependency management by adding download, verification, and extraction functions in build process
1 parent 3dcf30f commit edfa989

File tree

3 files changed

+121
-28
lines changed

3 files changed

+121
-28
lines changed

WORKFLOW_TEST.md

Lines changed: 0 additions & 22 deletions
This file was deleted.

gulpfile.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use strict';
22

3-
const { build, clean, copyManifest, installDeps } = require('./tasks/build');
3+
const { build, clean, copyManifest, installDeps, downloadDeps, verifyDeps, extractDeps, cleanDeps } = require('./tasks/build');
44
const { release } = require('./tasks/release');
55
const { tmpTestFiles } = require('./tasks/tmpTestFiles');
66
const { watch } = require('./tasks/watch');
@@ -9,6 +9,10 @@ exports.build = build;
99
exports.clean = clean;
1010
exports.copyManifest = copyManifest;
1111
exports.installDeps = installDeps;
12+
exports.downloadDeps = downloadDeps;
13+
exports.verifyDeps = verifyDeps;
14+
exports.extractDeps = extractDeps;
15+
exports.cleanDeps = cleanDeps;
1216
exports.release = release;
1317
exports.tmpTestFiles = tmpTestFiles;
1418
exports.watch = watch;

tasks/build.js

Lines changed: 116 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -197,14 +197,27 @@ function downloadDeps() {
197197
var destName = fileName.replace(/^.*[\\/]/, '');
198198
} else {
199199
// Need to concat endpoint (AWS) with the fileName
200-
var uri = manifest.endpoint + fileName;
200+
// Properly encode the filename to handle special characters like +
201+
var uri = manifest.endpoint + encodeURIComponent(fileName);
201202
var destName = fileName;
202203
}
203204

204-
return progress(request({uri: uri, timeout: 5000}))
205+
console.log(`Downloading ${depend} from ${uri}...`);
206+
207+
return progress(request({
208+
uri: uri,
209+
timeout: 30000, // Increased timeout for ARM64 dependencies which may be larger
210+
followRedirect: true,
211+
maxRedirects: 5
212+
}))
205213
.on('progress', state => {
206214
console.log(`Downloading ${depend}, ${(state.percent * 100).toFixed(0)}%`);
207215
})
216+
.on('error', (err) => {
217+
console.error(`Download error for ${depend}: ${err.message}`);
218+
console.error(`URI: ${uri}`);
219+
throw new Error(`Failed to download ${depend}: ${err.message}`);
220+
})
208221
.pipe(source(destName))
209222
.pipe(gulp.dest(destination));
210223
});
@@ -233,8 +246,31 @@ function extractDeps() {
233246
// directory level
234247
const properDestinationDir = path.join(destination, properName);
235248
jetpack.remove(properDestinationDir);
236-
return jetpack.createReadStream(path.join(destination, destName))
249+
250+
const filePath = path.join(destination, destName);
251+
console.log(`Extracting ${depend} from ${filePath}...`);
252+
253+
// Verify file exists before attempting extraction
254+
if (!jetpack.exists(filePath)) {
255+
throw new Error(`Dependency file not found: ${filePath}`);
256+
}
257+
258+
// Check file size to detect incomplete downloads
259+
const fileStats = jetpack.inspect(filePath);
260+
if (!fileStats || fileStats.size === 0) {
261+
throw new Error(`Dependency file is empty or corrupted: ${filePath} (size: ${fileStats ? fileStats.size : 'unknown'})`);
262+
}
263+
264+
console.log(`File ${destName} size: ${fileStats.size} bytes`);
265+
266+
return jetpack.createReadStream(filePath)
237267
.pipe(zlib.createGunzip())
268+
.on('error', (err) => {
269+
console.error(`Error extracting ${depend}: ${err.message}`);
270+
console.error(`File path: ${filePath}`);
271+
console.error(`File size: ${fileStats.size} bytes`);
272+
throw new Error(`Extraction failed for ${depend}: ${err.message}. File may be corrupted.`);
273+
})
238274
.pipe(tar.extract(properDestinationDir, {
239275
strip: 1,
240276
// There is a bug in tar-fs where, because stripped files & directories
@@ -246,13 +282,84 @@ function extractDeps() {
246282
ignore: (__, header) => {
247283
return header.name.length === 0;
248284
}
249-
}));
285+
}))
286+
.on('error', (err) => {
287+
console.error(`Error during tar extraction for ${depend}: ${err.message}`);
288+
throw err;
289+
});
250290
});
251291

252292
const tasksAsPromises = tasks.map(task => new Promise((resolve, reject) => task.on('finish', resolve).on('error', reject)));
253293
return Promise.all(tasksAsPromises);
254294
}
255295

296+
function verifyDeps() {
297+
console.log('Verifying downloaded dependencies...');
298+
var tasks = dependencies.map(depend => {
299+
const fileInfo = getActualFileInfo(manifest, depend, platform, arch);
300+
const fileName = fileInfo.name;
301+
302+
if( fileName.includes("http") ) {
303+
var destName = fileName.replace(/^.*[\\/]/, '');
304+
} else {
305+
var destName = fileName;
306+
}
307+
308+
const filePath = path.join(destination, destName);
309+
310+
return new Promise((resolve, reject) => {
311+
if (!jetpack.exists(filePath)) {
312+
reject(new Error(`Dependency file not found: ${filePath}`));
313+
return;
314+
}
315+
316+
const fileStats = jetpack.inspect(filePath);
317+
if (!fileStats || fileStats.size === 0) {
318+
reject(new Error(`Dependency file is empty: ${filePath}`));
319+
return;
320+
}
321+
322+
console.log(`✓ ${depend}: ${destName} (${fileStats.size} bytes)`);
323+
324+
// Test gzip header for compressed files
325+
if (destName.endsWith('.tar.gz') || destName.endsWith('.tgz')) {
326+
const stream = jetpack.createReadStream(filePath);
327+
const chunks = [];
328+
329+
stream.on('data', chunk => {
330+
chunks.push(chunk);
331+
if (chunks.length === 1) {
332+
// Check gzip magic number (1f 8b)
333+
const buffer = chunk;
334+
if (buffer.length >= 2 && buffer[0] === 0x1f && buffer[1] === 0x8b) {
335+
console.log(`✓ ${depend}: Valid gzip header detected`);
336+
stream.destroy();
337+
resolve();
338+
} else {
339+
stream.destroy();
340+
reject(new Error(`Invalid gzip header in ${destName}. Expected magic bytes 1f 8b, got ${buffer[0].toString(16)} ${buffer[1].toString(16)}`));
341+
}
342+
}
343+
});
344+
345+
stream.on('error', (err) => {
346+
reject(new Error(`Error reading ${destName}: ${err.message}`));
347+
});
348+
349+
stream.on('end', () => {
350+
if (chunks.length === 0) {
351+
reject(new Error(`No data read from ${destName}`));
352+
}
353+
});
354+
} else {
355+
resolve();
356+
}
357+
});
358+
});
359+
360+
return Promise.all(tasks);
361+
}
362+
256363
function cleanDeps() {
257364
var tasks = dependencies.map(depend => {
258365
const fileInfo = getActualFileInfo(manifest, depend, platform, arch);
@@ -274,4 +381,8 @@ function cleanDeps() {
274381
exports.build = gulp.series(gulp.parallel(html, fonts, nodeModules, other, environment), finalizeBuild);
275382
exports.clean = clean;
276383
exports.copyManifest = copyManifest;
277-
exports.installDeps = gulp.series(downloadDeps, extractDeps, cleanDeps);
384+
exports.installDeps = gulp.series(downloadDeps, verifyDeps, extractDeps, cleanDeps);
385+
exports.downloadDeps = downloadDeps;
386+
exports.verifyDeps = verifyDeps;
387+
exports.extractDeps = extractDeps;
388+
exports.cleanDeps = cleanDeps;

0 commit comments

Comments
 (0)