-
Notifications
You must be signed in to change notification settings - Fork 205
Expand file tree
/
Copy pathgulpfile.js
More file actions
135 lines (127 loc) · 5.01 KB
/
Copy pathgulpfile.js
File metadata and controls
135 lines (127 loc) · 5.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
const cheerio = require('gulp-cheerio');
const env = process.env.CAMEL_ENV || 'development';
const fs = require('fs/promises');
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') {
// Without this pass the output keeps Hugo's uppercase doctype, self-closing
// void elements and trailing whitespace, so `yarn check:html` reports a
// doctype-style, void-style or no-trailing-whitespace error on essentially
// every page. Say so, rather than let that look like broken markup.
console.log(`minify: skipped because CAMEL_ENV is '${env}', not 'production'.`);
console.log('minify: check:html only gives meaningful results on a production build.');
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', () => {
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', () => {
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')
}
// Register the generate-markdown task with lazy loading to avoid requiring
// node-html-parser when running other tasks (like clean or sitemap)
gulp.task('generate-markdown', () => {
const generateMarkdown = require('./gulp/tasks/generate-markdown');
return generateMarkdown();
});
/*
* Removes the content from the `public` directory.
*/
gulp.task('clean', () => {
return fs.rm('public', { recursive: true, force: true });
});