gulpfile.js (83 lines of code) (raw):

const cheerio = require('gulp-cheerio'); const env = process.env.CAMEL_ENV || 'development'; const gulp = require('gulp'); const htmlmin = require('gulp-htmlmin'); const inject = require('gulp-inject') /** * We minify all HTML files using htmlmin, this is to make them smaller in size * as we generate quite big HTML files in the documentation. We do not do this * unless the environment variable `CAMEL_ENV` is set to 'production' to help * with the development turnaround as this takes quite a while to do. */ gulp.task('minify', (done) => { if (env !== 'production') { done(); return; } return gulp.src('public/**/*.html') .pipe(htmlmin({ collapseBooleanAttributes: true, collapseWhitespace: true, collapseInlineTagWhitespace: true, conservativeCollapse: true, useShortDoctype: true, processScripts: ['application/ld+json'] })) .pipe(gulp.dest('public')); }); /* * Appends `sitemap-website.xml` to the `sitemap.xml`. * * We have sitemaps generated by Antora for each documentation component, these * are generated in `documentation/sitemap-*.xml` along with the * `documentation/sitemap.xml` that is a sitemap index pointing to each * component sitemap. * * Hugo also generates a sitemap in `public/sitemap-website.xml` containing all * pages generated from `content/` and other sources. We need to add the * `sitemap-website.xml` to the `sitemap.xml` so that we have a sitemap index * containing pointers to all individual sitemaps. * * Sitemaps are used by search engines (Google, Algolia, ...) to help them crawl * and index the website. */ gulp.task('sitemap', (done) => { return gulp.src('public/sitemap.xml') .pipe(cheerio(($, f) => $('sitemapindex').append(`<sitemap> <loc>https://camel.apache.org/sitemap-website.xml</loc> </sitemap>`) )) .pipe(gulp.dest('public')); }); gulp.task('htaccess', (done) => { return gulp.src(`static/.htaccess`) .pipe( inject( gulp.src('documentation/.htaccess'), { starttag:'<!-- inject:htaccess:docs -->', removeTags: true, transform: (filename, file) => { return versionlessRedirects(file.contents.toString('utf8')) }, } ) ) // redirect un-hashed resources (e.g. `/_/img/logo-d.svg`) to hashed resources (e.g. `/_/img/logo-d-f21b25ba38.svg`) // so we don't break backward compatibility .pipe( inject( gulp.src('documentation/_/data/rev-manifest.json'), { starttag:'<!-- inject:htaccess:resources -->', removeTags: true, transform: (filename, file) => { const data = JSON.parse(file.contents) let rules = '' for (const [key, value] of Object.entries(data)) { if (key.endsWith('.svg') || key.endsWith('.png')) { rules += `Redirect 301 /_/${key} /_/${value}\n` } } return rules }, } ) ) .pipe(gulp.dest('public')) }); const REDIRECT_RX = /^Redirect 302 \/(?<component>c.*)\/latest \/\k<component>\/(?<version>.*)$/ function versionlessRedirects (text) { const lines = text.split('\n') const processed = lines.reduce((accum, line) => { accum.push(line) const m = line.match(REDIRECT_RX) if (m) { accum.push(`RedirectMatch 302 "^/${m.groups.component}(/?)$" "/${m.groups.component}/${m.groups.version}/"`) // The first line redirects **/next to **/next/ so the second line does not match. // Apparently it needs to be a match or it will transform **/next/ to **/next// accum.push(`RedirectMatch 301 "^/${m.groups.component}/next$" "/${m.groups.component}/next/"`) accum.push(`RedirectMatch 302 "^/${m.groups.component}/(?![0-9].*|next/)(.+)$" "/${m.groups.component}/${m.groups.version}/$1"`) // As an alternative, the following line works as long as no file names start with 'next' // accum.push(`RedirectMatch 302 "^/${m.groups.component}/(?![0-9].*|next)(.+)$" "/${m.groups.component}/${m.groups.version}/$1"`) } return accum }, []) return processed.join('\n') } /* * Removes the content from the `public` directory. */ gulp.task('clean', () => { return require('del')('public'); });