blob: 853e669fd1febcf11732a239766ac44be30f2896 [file] [log] [blame]
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');
});