This is an automated email from the ASF dual-hosted git repository.

gnodet pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git

commit f3eba6b11dacfd04cf4321bc316ce548fecd31bb
Author: Guillaume Nodet <[email protected]>
AuthorDate: Thu Apr 9 01:58:34 2026 +0200

    Fix docs gulp ENOENT race condition with concurrent builds
    
    When builds run concurrently (tests + docs via mvnd), the glob scanner
    may traverse into target/ directories that are being modified by test
    execution. This causes ENOENT when target/surefire is deleted mid-scan.
    
    The fast-glob ignore option filters results but does not prevent
    directory traversal. Add ENOENT error handlers on gulp.src streams
    to gracefully handle this race condition.
    
    Also split the dsl glob pattern to properly match sub-modules.
    
    Co-Authored-By: Claude Opus 4.6 <[email protected]>
---
 docs/gulpfile.js | 29 ++++++++++++++++++++++++++---
 1 file changed, 26 insertions(+), 3 deletions(-)

diff --git a/docs/gulpfile.js b/docs/gulpfile.js
index 9880997246ff..7481f5969106 100644
--- a/docs/gulpfile.js
+++ b/docs/gulpfile.js
@@ -207,7 +207,8 @@ const sources = {
         
'../core/camel-main/src/main/docs/!(*-component|*-language|*-dataformat|*-summary).adoc',
         
'../components/{*,*/*}/src/main/docs/!(*-component|*-language|*-dataformat|*-summary).adoc',
         
'../dsl/src/main/docs/!(*-component|*-language|*-dataformat|*-summary).adoc',
-        
'../dsl/{*,*/!(target)}/src/main/docs/!(*-component|*-language|*-dataformat|*-summary).adoc',
+        
'../dsl/*/src/main/docs/!(*-component|*-language|*-dataformat|*-summary).adoc',
+        
'../dsl/*/*/src/main/docs/!(*-component|*-language|*-dataformat|*-summary).adoc',
       ],
       destination: 'components/modules/others/pages',
       keep: [
@@ -315,6 +316,28 @@ const tasks = Array.from(sourcesMap).flatMap(([type, 
definition]) => {
     })
   }
 
+  // Wraps gulp.src() to handle ENOENT errors from race conditions when
+  // builds run concurrently (e.g., test execution deleting target/surefire
+  // while the glob scans directories). Uses a passthrough stream to
+  // decouple error handling from gulp's task tracking.
+  const resilientSrc = (source, options) => {
+    const passthrough = through2.obj()
+    const src = gulp.src(source, options)
+
+    src.on('data', (file) => passthrough.push(file))
+    src.on('end', () => passthrough.push(null))
+    src.on('error', (err) => {
+      if (err.code === 'ENOENT' && err.path && 
err.path.includes(`${path.sep}target${path.sep}`)) {
+        console.warn(`⚠️ Ignoring ENOENT in build directory: ${err.path}`)
+        passthrough.push(null)
+      } else {
+        passthrough.destroy(err)
+      }
+    })
+
+    return passthrough
+  }
+
   // creates symlinks from source to destination that satisfy the
   // given filter removing the basedir from a path, i.e. symlinking
   // from a flat hiearchy
@@ -327,7 +350,7 @@ const tasks = Array.from(sourcesMap).flatMap(([type, 
definition]) => {
       }
     })
 
-    return gulp.src(source, { ignore: ['**/target/**'] })
+    return resilientSrc(source, { ignore: ['**/target/**', '**/target'] })
       .pipe(filterFn)
       .pipe(
         map((file, done) => {
@@ -410,7 +433,7 @@ const tasks = Array.from(sourcesMap).flatMap(([type, 
definition]) => {
       return done()
     }
 
-    return gulp.src(source, { ignore: ['**/target/**'] }) // asciidoc files
+    return resilientSrc(source, { ignore: ['**/target/**', '**/target'] }) // 
asciidoc files
       .pipe(through2.obj(extractExamples)) // extracted example files
       // symlink links from a fixed directory, i.e. we could link to
       // the example files from `destination`, that would not work for

Reply via email to