Skip to content
Permalink
Browse files
Merge pull request #122 from hansva/master
Update Antora version
  • Loading branch information
hansva committed Feb 6, 2022
2 parents e2fa6e4 + ac1930a commit a001210166890f1c7bd364b6846e3ecbb5a9ebdf
Showing 37 changed files with 2,134 additions and 1,493 deletions.
@@ -1,4 +1,4 @@
FROM node:lts-stretch
FROM node:lts-bullseye

RUN set -ex \
&& apt-get update \
@@ -6,7 +6,7 @@ Tools used to generate the website:

- [Git](https://git-scm.com/) a source code management tool used to fetch document sources from different
github repositories.
- [Node.js](https://nodejs.org/) a JavaScript runtime used to build the website. You will need to use Node.js version 12.
- [Node.js](https://nodejs.org/) a JavaScript runtime used to build the website. You will need to use Node.js version 16.
- [yarn](https://yarnpkg.com/) a blazing fast dependency and package manager tool used to download
and manage required libraries.
- (installed via yarn) [Gulp](http://gulpjs.com/) a task automation tool. Used to build the Hop
@@ -33,7 +33,7 @@ Make sure that you have Node.js (herein "`Node`") installed.

If this command fails with an error, you do not have Node.js installed.

This project requires the Node Maintenance LTS version 12 (e.g., V12.19.0).
This project requires the Node LTS version 16 (e.g., V16.13.2).

Please make sure to have a suitable version of Node.js installed. You have several options to install
Node.js on your machine:
@@ -42,12 +42,12 @@ Node.js on your machine:
- Install using [Homebrew](https://brew.sh/) and [Node formulae](https://formulae.brew.sh/formula/node)
- Install from official [Node packages](https://nodejs.org/en/download/)

Note - If you have different Node version other than Node.js Maintenance LTS version 12 you can use following command to make
Node.js Maintenance LTS version 12 as your default Node.js version.
Note - If you have different Node version other than Node.js LTS version 16 you can use following command to make
Node.js LTS version 16 as your default Node.js version.

$ nvm alias default 12
$ nvm alias default 16

Now that you have Node 12 installed, you can proceed with checking the Yarn installation.
Now that you have Node 16 installed, you can proceed with checking the Yarn installation.

#### Yarn

@@ -1,8 +1,10 @@
'use strict'

const { obj: map } = require('through2')
const log = require('fancy-log')
const PluginError = require('plugin-error')
const prettierEslint = require('prettier-eslint')
const { Transform } = require('stream')
const map = (transform) => new Transform({ objectMode: true, transform })

module.exports = () => {
const report = { changed: 0, unchanged: 0 }
@@ -17,9 +19,9 @@ module.exports = () => {
.concat(' file')
.concat(report.unchanged === 1 ? '' : 's')
.concat(' unchanged')
console.log(`prettier-eslint: ${changed}; ${unchanged}`)
log(`prettier-eslint: ${changed}; ${unchanged}`)
} else {
console.log(`prettier-eslint: left ${report.unchanged} file${report.unchanged === 1 ? '' : 's'} unchanged`)
log(`prettier-eslint: left ${report.unchanged} file${report.unchanged === 1 ? '' : 's'} unchanged`)
}
})

@@ -1,40 +1,34 @@
'use strict'

const asciidoctor = require('asciidoctor.js')()
const Asciidoctor = require('@asciidoctor/core')()
const data = require('gulp-data')
const template = require('gulp-template')
const fs = require('fs-extra')
const handlebars = require('handlebars')
const { obj: map } = require('through2')
const merge = require('merge-stream')
const ospath = require('path')
const path = ospath.posix
const requireFromString = require('require-from-string')
const template = require('gulp-template')
const { Transform } = require('stream')
const map = (transform = () => {}, flush = undefined) => new Transform({ objectMode: true, transform, flush })
const vfs = require('vinyl-fs')
const yaml = require('js-yaml')

const ASCIIDOC_ATTRIBUTES = {
experimental: '',
icons: 'font',
sectanchors: '',
'source-highlighter': 'highlight.js',
}
const ASCIIDOC_ATTRIBUTES = { experimental: '', icons: 'font', sectanchors: '', 'source-highlighter': 'highlight.js' }

module.exports = (src, previewSrc, previewDest, sink = () => map(), layouts = {}) => () =>
module.exports = (src, previewSrc, previewDest, sink = () => map()) => (done) =>
Promise.all([
loadSampleUiModel(previewSrc),
toPromise(
merge(
compileLayouts(src, layouts),
merge(compileLayouts(src),
registerPartials(src),
registerHelpers(src),
registerTemplatedHelpers(src),
copyImages(previewSrc, previewDest),
),
copyImages(previewSrc, previewDest)),
),
])
.then(([baseUiModel]) => ({ ...baseUiModel, env: process.env }))
.then((baseUiModel) =>
.then(([baseUiModel, { layouts }]) => [{ ...baseUiModel, env: process.env }, layouts])
.then(([baseUiModel, layouts]) =>
vfs
.src('**/*.adoc', { base: previewSrc, cwd: previewSrc })
.pipe(
@@ -48,7 +42,7 @@ module.exports = (src, previewSrc, previewDest, sink = () => map(), layouts = {}
if (file.stem === '404') {
uiModel.page = { layout: '404', title: 'Page Not Found' }
} else {
const doc = asciidoctor.load(file.contents, { safe: 'safe', attributes: ASCIIDOC_ATTRIBUTES })
const doc = Asciidoctor.load(file.contents, { safe: 'safe', attributes: ASCIIDOC_ATTRIBUTES })
uiModel.page.attributes = Object.entries(doc.getAttributes())
.filter(([name, val]) => name.startsWith('page-'))
.reduce((accum, [name, val]) => {
@@ -60,11 +54,16 @@ module.exports = (src, previewSrc, previewDest, sink = () => map(), layouts = {}
uiModel.page.contents = Buffer.from(doc.convert())
}
file.extname = '.html'
file.contents = Buffer.from(layouts[uiModel.page.layout](uiModel))
next(null, file)
try {
file.contents = Buffer.from(layouts.get(uiModel.page.layout)(uiModel))
next(null, file)
} catch (e) {
next(transformHandlebarsError(e, uiModel.page.layout))
}
}),
)
.pipe(vfs.dest(previewDest))
.on('error', done)
.pipe(sink()),
)

@@ -82,6 +81,8 @@ function registerPartials (src) {
}

function registerHelpers (src) {
handlebars.registerHelper('resolvePage', resolvePage)
handlebars.registerHelper('resolvePageURL', resolvePageURL)
return vfs.src('helpers/*.js', { base: src, cwd: src }).pipe(
map((file, enc, next) => {
handlebars.registerHelper(file.stem, requireFromString(file.contents.toString()))
@@ -100,19 +101,51 @@ function registerTemplatedHelpers (src) {
}))
}

function compileLayouts (src, layouts) {
function compileLayouts (src) {
const layouts = new Map()
return vfs.src('layouts/*.hbs', { base: src, cwd: src }).pipe(
map((file, enc, next) => {
layouts[file.stem] = handlebars.compile(file.contents.toString(), { preventIndent: true })
next()
}),
map(
(file, enc, next) => {
const srcName = path.join(src, file.relative)
layouts.set(file.stem, handlebars.compile(file.contents.toString(), { preventIndent: true, srcName }))
next()
},
function (done) {
this.push({ layouts })
done()
},
),
)
}

function copyImages (src, dest) {
return vfs.src('**/*.{png,svg}', { base: src, cwd: src }).pipe(vfs.dest(dest))
return vfs
.src('**/*.{png,svg}', { base: src, cwd: src })
.pipe(vfs.dest(dest))
.pipe(map((file, enc, next) => next()))
}

function resolvePage (spec, context = {}) {
if (spec) return { pub: { url: resolvePageURL(spec) } }
}

function resolvePageURL (spec, context = {}) {
if (spec) return '/' + (spec = spec.split(':').pop()).slice(0, spec.lastIndexOf('.')) + '.html'
}

function transformHandlebarsError ({ message, stack }, layout) {
const m = stack.match(/^ *at Object\.ret \[as (.+?)\]/m)
const templatePath = `src/${m ? 'partials/' + m[1] : 'layouts/' + layout}.hbs`
const err = new Error(`${message}${~message.indexOf('\n') ? '\n^ ' : ' '}in UI template ${templatePath}`)
err.stack = [err.toString()].concat(stack.substr(message.length + 8)).join('\n')
return err
}

function toPromise (stream) {
return new Promise((resolve, reject) => stream.on('error', reject).on('finish', resolve))
return new Promise((resolve, reject, data = {}) =>
stream
.on('error', reject)
.on('data', (chunk) => chunk.constructor === Object && Object.assign(data, chunk))
.on('finish', () => resolve(data)),
)
}
@@ -8,7 +8,6 @@ const cssnano = require('cssnano')
const data = require('gulp-data')
const fs = require('fs-extra')
const imagemin = require('gulp-imagemin')
const { obj: map } = require('through2')
const merge = require('merge-stream')
const ospath = require('path')
const path = ospath.posix
@@ -19,18 +18,29 @@ const postcssUrl = require('postcss-url')
const postcssVar = require('postcss-custom-properties')
const rename = require('gulp-rename')
const rev = require('gulp-rev')
const rewrite = require('gulp-rev-rewrite')
const template = require('gulp-template')
const terser = require('gulp-terser')
const vfs = require('vinyl-fs')
const { obj: map } = require('through2')

module.exports = (src, dest, preview) => () => {
const opts = { base: src, cwd: src }
const sourcemaps = preview || process.env.SOURCEMAPS === 'true'
const postcssPlugins = [
postcssImport,
(css, { messages, opts: { file } }) =>
Promise.all(
messages
.reduce((accum, { file: depPath, type }) => (type === 'dependency' ? accum.concat(depPath) : accum), [])
.map((importedPath) => fs.stat(importedPath).then(({ mtime }) => mtime)),
).then((mtimes) => {
const newestMtime = mtimes.reduce((max, curr) => (!max || curr > max ? curr : max), file.stat.mtime)
if (newestMtime > file.stat.mtime) file.stat.mtimeMs = +(file.stat.mtime = newestMtime)
}),
postcssUrl([
{
filter: '**/~typeface-*/files/*',
filter: '**/*.@(woff|woff2)',
url: (asset) => {
const relpath = asset.pathname.substr(1)
const abspath = require.resolve(relpath)
@@ -41,10 +51,12 @@ module.exports = (src, dest, preview) => () => {
},
},
]),
postcssVar({ preserve: preview ? 'preserve-computed' : false }),
postcssVar({ preserve: preview }),
preview ? postcssCalc : () => {},
autoprefixer,
preview ? () => {} : cssnano({ preset: 'default' }),
preview
? () => {}
: (css, result) => cssnano({ preset: 'default' })(css, result).then(() => postcssPseudoElementFixer(css, result)),
]

let manifest
@@ -53,6 +65,7 @@ module.exports = (src, dest, preview) => () => {
vfs
.src('js/+([0-9])-*.js', { ...opts, sourcemaps })
.pipe(terser())
// NOTE concat already uses stat from newest combined file
.pipe(concat('js/site.js'))
.pipe(rev()),
vfs
@@ -61,11 +74,22 @@ module.exports = (src, dest, preview) => () => {
// see https://gulpjs.org/recipes/browserify-multiple-destination.html
map((file, enc, next) => {
if (file.relative.endsWith('.bundle.js')) {
file.contents = browserify(file.relative, { basedir: src, detectGlobals: false })
const mtimePromises = []
const bundlePath = file.path
browserify(file.relative, { basedir: src, detectGlobals: false })
.plugin('browser-pack-flat/plugin')
.bundle()
file.path = file.path.slice(0, file.path.length - 10) + '.js'
next(null, file)
.on('file', (bundledPath) => {
if (bundledPath !== bundlePath) mtimePromises.push(fs.stat(bundledPath).then(({ mtime }) => mtime))
})
.bundle((bundleError, bundleBuffer) =>
Promise.all(mtimePromises).then((mtimes) => {
const newestMtime = mtimes.reduce((max, curr) => (curr > max ? curr : max), file.stat.mtime)
if (newestMtime > file.stat.mtime) file.stat.mtimeMs = +(file.stat.mtime = newestMtime)
if (bundleBuffer !== undefined) file.contents = bundleBuffer
file.path = file.path.slice(0, file.path.length - 10) + '.js'
next(bundleError, file)
}),
)
} else {
fs.readFile(file.path, 'UTF-8').then((contents) => {
file.contents = Buffer.from(contents)
@@ -76,43 +100,56 @@ module.exports = (src, dest, preview) => () => {
)
.pipe(buffer())
.pipe(terser())
// NOTE use this statement to bundle a JavaScript library that cannot be browserified, like jQuery
//vfs.src(require.resolve('<package-name-or-require-path>'), opts).pipe(concat('js/vendor/<library-name>.js')),
.pipe(rev()),
vfs.src('css/site.css', { ...opts, sourcemaps })
.pipe(postcss(postcssPlugins))
vfs
.src('css/site.css', { ...opts, sourcemaps })
.pipe(postcss((file) => ({ plugins: postcssPlugins, options: { file } })))
.pipe(rev()),
vfs.src('font/*.{ttf,woff*(2)}', opts),
vfs
.src('img/**/*.{jpg,ico,png,svg}', opts)
.pipe(
imagemin([
imagemin.gifsicle(),
imagemin.jpegtran(),
imagemin.optipng(),
imagemin.svgo({
plugins: [
{ removeViewBox: false },
{ cleanupIDs: { remove: false } },
{ removeTitle: false },
{ removeDesc: false },
],
}),
]),
),
vfs.src('img/**/*.{jpg,ico,png,svg}', opts)
.pipe(imagemin([
imagemin.gifsicle(),
imagemin.jpegtran(),
imagemin.optipng(),
imagemin.svgo({
plugins: [
{ removeViewBox: false },
{ cleanupIDs: { remove: false } },
{ removeTitle: false },
{ removeDesc: false },
],
}),
]))
.pipe(rev()),
vfs.src('helpers/*.js', opts),
vfs.src('layouts/*.hbs', opts),
vfs.src('partials/*.hbs', opts),
).pipe(vfs.dest(dest, { sourcemaps: sourcemaps && '.' }))
)
.pipe(rewrite())
.pipe(vfs.dest(dest, { sourcemaps: sourcemaps && '.' }))
.pipe(rev.manifest())
.pipe(vfs.dest(path.join(dest, 'data')))
.pipe(map((file, enc, next) => {
manifest = file.contents.toString()
next(null, null)
}))
.pipe(
map((file, enc, next) => {
manifest = file.contents.toString()
next(null, file)
}),
)
.pipe(vfs.src('helpers/*.js.template', opts))
.pipe(data(() => ({ manifest: manifest })))
.pipe(template())
.pipe(rename((path) => {
path.extname = '' // strip .template
}))
.pipe(
rename((path) => {
path.extname = '' // strip .template
}),
)
.pipe(vfs.dest(dest))
}

function postcssPseudoElementFixer (css, result) {
css.walkRules(/(?:^|[^:]):(?:before|after)/, (rule) => {
rule.selector = rule.selectors.map((it) => it.replace(/(^|[^:]):(before|after)$/, '$1::$2')).join(',')
})
}

0 comments on commit a001210

Please sign in to comment.