Skip to content

Commit b53baba

Browse files
gnodetclaude
andcommitted
Fix resilientSrc to process each glob pattern independently
When glob-stream hits ENOENT, it stops emitting files from the entire source — even if the error only affects one glob pattern. This caused only 47 of 71 "others" symlinks to be created. Fix by processing each source pattern as a separate gulp.src stream and merging results into a single passthrough. An ENOENT in one pattern (e.g. the dsl glob hitting .camel-jbang/work) no longer aborts the other patterns (core, components). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 0722f1a commit b53baba

1 file changed

Lines changed: 44 additions & 2 deletions

File tree

docs/gulpfile.js

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,43 @@ const tasks = Array.from(sourcesMap).flatMap(([type, definition]) => {
315315
})
316316
}
317317

318+
// Wraps gulp.src to gracefully handle ENOENT from ephemeral directories
319+
// (e.g. .camel-jbang/work created/deleted by tests running in parallel).
320+
// Each source pattern is processed as a separate gulp.src stream so that
321+
// an ENOENT in one pattern (e.g. the dsl glob) doesn't abort the other
322+
// patterns (e.g. core, components). Results are merged into a single
323+
// passthrough stream.
324+
const ignorePatterns = ['**/target/**', '**/.camel-jbang/**']
325+
const resilientSrc = (source, options) => {
326+
const patterns = Array.isArray(source) ? source : [source]
327+
const passthrough = through2.obj()
328+
let remaining = patterns.length
329+
330+
const onStreamDone = () => {
331+
remaining--
332+
if (remaining === 0) {
333+
passthrough.end()
334+
}
335+
}
336+
337+
patterns.forEach(pattern => {
338+
const src = gulp.src(pattern, options)
339+
let done = false
340+
src.on('data', chunk => passthrough.write(chunk))
341+
src.on('error', err => {
342+
if (err.code === 'ENOENT') {
343+
console.error(`⚠️ ENOENT (skipped): ${err.path || err.message}`)
344+
} else {
345+
passthrough.destroy(err)
346+
}
347+
})
348+
src.on('end', () => { if (!done) { done = true; onStreamDone() } })
349+
src.on('close', () => { if (!done) { done = true; onStreamDone() } })
350+
})
351+
352+
return passthrough
353+
}
354+
318355
// creates symlinks from source to destination that satisfy the
319356
// given filter removing the basedir from a path, i.e. symlinking
320357
// from a flat hiearchy
@@ -327,10 +364,12 @@ const tasks = Array.from(sourcesMap).flatMap(([type, definition]) => {
327364
}
328365
})
329366

330-
return gulp.src(source, { ignore: ['**/target/**'] })
367+
let fileCount = 0
368+
return resilientSrc(source, { ignore: ignorePatterns, allowEmpty: true })
331369
.pipe(filterFn)
332370
.pipe(
333371
map((file, done) => {
372+
fileCount++
334373
// this flattens the output to just .../pages/.../file.ext
335374
// instead of .../pages/camel-.../src/main/docs/.../file.ext
336375
file.base = path.dirname(file.path)
@@ -340,6 +379,9 @@ const tasks = Array.from(sourcesMap).flatMap(([type, definition]) => {
340379
.pipe(gulp.symlink(destination, {
341380
relativeSymlinks: true,
342381
}))
382+
.on('end', () => {
383+
console.log(` → symlinked ${fileCount} files to ${destination}`)
384+
})
343385
}
344386

345387
// generates sorted & grouped nav.adoc file from a set of .adoc
@@ -410,7 +452,7 @@ const tasks = Array.from(sourcesMap).flatMap(([type, definition]) => {
410452
return done()
411453
}
412454

413-
return gulp.src(source, { ignore: ['**/target/**'] }) // asciidoc files
455+
return resilientSrc(source, { ignore: ignorePatterns, allowEmpty: true }) // asciidoc files
414456
.pipe(through2.obj(extractExamples)) // extracted example files
415457
// symlink links from a fixed directory, i.e. we could link to
416458
// the example files from `destination`, that would not work for

0 commit comments

Comments
 (0)