@antora/content-aggregator 3.1.6 → 3.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/aggregate-content.js +53 -56
- package/lib/constants.js +2 -2
- package/lib/git-plugin-http.js +5 -4
- package/lib/matcher.js +1 -6
- package/package.json +6 -6
package/lib/aggregate-content.js
CHANGED
|
@@ -15,7 +15,8 @@ const getCacheDir = require('cache-directory')
|
|
|
15
15
|
const GitCredentialManagerStore = require('./git-credential-manager-store')
|
|
16
16
|
const git = require('./git')
|
|
17
17
|
const { NotFoundError, ObjectTypeError, UnknownTransportError, UrlParseError } = git.Errors
|
|
18
|
-
const globStream = require('glob
|
|
18
|
+
const { globStream } = require('fast-glob')
|
|
19
|
+
const { inspect } = require('util')
|
|
19
20
|
const invariably = require('./invariably')
|
|
20
21
|
const logger = require('./logger')
|
|
21
22
|
const { makeMatcherRx, versionMatcherOpts: VERSION_MATCHER_OPTS } = require('./matcher')
|
|
@@ -118,11 +119,11 @@ async function collectFiles (sourcesByUrl, loadOpts, concurrency, fetchedUrls) {
|
|
|
118
119
|
})
|
|
119
120
|
return gracefulPromiseAllWithLimit(loadTasks, concurrency.fetch).then(([results, rejections]) => {
|
|
120
121
|
if (rejections.length) {
|
|
121
|
-
if (concurrency.fetch > 1 && rejections.every(({ recoverable }) => recoverable)) {
|
|
122
|
+
if (concurrency.fetch > 1 && results.length > 1 && rejections.every(({ recoverable }) => recoverable)) {
|
|
122
123
|
if (loadOpts.progress) loadOpts.progress.terminate() // reset cursor position and allow it be reused
|
|
123
|
-
const msg0 = 'An unexpected error occurred while
|
|
124
|
+
const msg0 = 'An unexpected error occurred while fetching content sources concurrently.'
|
|
124
125
|
const msg1 = 'Retrying with git.fetch_concurrency value of 1.'
|
|
125
|
-
logger.warn(msg0 + ' ' + msg1)
|
|
126
|
+
logger.warn(rejections[0], msg0 + ' ' + msg1)
|
|
126
127
|
const fulfilledUrls = results.map((it) => it && it.repo.url && it.url).filter((it) => it)
|
|
127
128
|
return collectFiles(sourcesByUrl, loadOpts, Object.assign(concurrency, { fetch: 1 }), fulfilledUrls)
|
|
128
129
|
}
|
|
@@ -383,7 +384,7 @@ async function selectReferences (source, repo, remote) {
|
|
|
383
384
|
}
|
|
384
385
|
|
|
385
386
|
/**
|
|
386
|
-
* Returns the current branch name
|
|
387
|
+
* Returns the current branch name or undefined if the HEAD is detached.
|
|
387
388
|
*/
|
|
388
389
|
function getCurrentBranchName (repo, remote) {
|
|
389
390
|
let refPromise
|
|
@@ -437,12 +438,13 @@ function collectFilesFromStartPath (startPath, repo, authStatus, ref, originUrl,
|
|
|
437
438
|
const worktreePath = ref.head
|
|
438
439
|
const origin = computeOrigin(originUrl, authStatus, repo.gitdir, ref, startPath, worktreePath, editUrl)
|
|
439
440
|
return (worktreePath ? readFilesFromWorktree(origin) : readFilesFromGitTree(repo, ref.oid, startPath))
|
|
440
|
-
.then((files) =>
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
441
|
+
.then((files) => {
|
|
442
|
+
const batch = deepClone((origin.descriptor = loadComponentDescriptor(files, ref, version)))
|
|
443
|
+
if ('nav' in batch) batch.nav.origin = origin
|
|
444
|
+
batch.files = files.map((file) => assignFileProperties(file, origin))
|
|
445
|
+
batch.origins = [origin]
|
|
446
|
+
return batch
|
|
447
|
+
})
|
|
446
448
|
.catch((err) => {
|
|
447
449
|
const where = worktreePath || (worktreePath === false ? repo.gitdir : repo.url || repo.dir)
|
|
448
450
|
const flag = worktreePath ? ' <worktree>' : ref.remote && worktreePath === false ? ` <remotes/${ref.remote}>` : ''
|
|
@@ -467,19 +469,18 @@ function readFilesFromWorktree (origin) {
|
|
|
467
469
|
}
|
|
468
470
|
|
|
469
471
|
function srcFs (cwd, origin) {
|
|
470
|
-
return new Promise((resolve, reject,
|
|
472
|
+
return new Promise((resolve, reject, files = []) =>
|
|
471
473
|
pipeline(
|
|
472
|
-
globStream(CONTENT_SRC_GLOB, Object.assign({
|
|
473
|
-
forEach(({ path:
|
|
474
|
-
if ((
|
|
475
|
-
const
|
|
476
|
-
const relpath =
|
|
477
|
-
|
|
478
|
-
(stat) =>
|
|
479
|
-
if (stat.isDirectory()) return done() // detects directories that slipped through cache check
|
|
474
|
+
globStream(CONTENT_SRC_GLOB, Object.assign({ cwd }, CONTENT_SRC_OPTS)),
|
|
475
|
+
forEach(({ path: relpath, dirent }, _, done) => {
|
|
476
|
+
if (dirent.isDirectory()) return done()
|
|
477
|
+
const relpathPosix = relpath
|
|
478
|
+
const abspath = posixify ? ospath.join(cwd, (relpath = ospath.normalize(relpath))) : cwd + '/' + relpath
|
|
479
|
+
fsp.stat(abspath).then(
|
|
480
|
+
(stat) =>
|
|
480
481
|
fsp.readFile(abspath).then(
|
|
481
482
|
(contents) => {
|
|
482
|
-
files.push(new File({ path:
|
|
483
|
+
files.push(new File({ path: relpathPosix, contents, stat, src: { abspath } }))
|
|
483
484
|
done()
|
|
484
485
|
},
|
|
485
486
|
(readErr) => {
|
|
@@ -489,22 +490,28 @@ function srcFs (cwd, origin) {
|
|
|
489
490
|
: logger.error(logObject, readErr.message.replace(`'${abspath}'`, relpath))
|
|
490
491
|
done()
|
|
491
492
|
}
|
|
492
|
-
)
|
|
493
|
-
},
|
|
493
|
+
),
|
|
494
494
|
(statErr) => {
|
|
495
495
|
const logObject = { file: { abspath, origin } }
|
|
496
|
-
if (
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
(
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
496
|
+
if (dirent.isSymbolicLink()) {
|
|
497
|
+
fsp
|
|
498
|
+
.readlink(abspath)
|
|
499
|
+
.then(
|
|
500
|
+
(symlink) =>
|
|
501
|
+
(statErr.code === 'ELOOP' ? 'ELOOP: symbolic link cycle, ' : 'ENOENT: broken symbolic link, ') +
|
|
502
|
+
`${relpath} -> ${symlink}`,
|
|
503
|
+
() => statErr.message.replace(`'${abspath}'`, relpath)
|
|
504
|
+
)
|
|
505
|
+
.then((message) => {
|
|
506
|
+
logger.error(logObject, message)
|
|
507
|
+
done()
|
|
508
|
+
})
|
|
504
509
|
} else {
|
|
505
|
-
|
|
510
|
+
statErr.code === 'ENOENT'
|
|
511
|
+
? logger.warn(logObject, `ENOENT: file or directory disappeared, ${statErr.syscall} ${relpath}`)
|
|
512
|
+
: logger.error(logObject, statErr.message.replace(`'${abspath}'`, relpath))
|
|
513
|
+
done()
|
|
506
514
|
}
|
|
507
|
-
done()
|
|
508
515
|
}
|
|
509
516
|
)
|
|
510
517
|
}),
|
|
@@ -674,8 +681,13 @@ function filterGitEntry (entry) {
|
|
|
674
681
|
|
|
675
682
|
function gitEntryToFile (entry) {
|
|
676
683
|
return git.readBlob(entry).then(({ blob: contents }) => {
|
|
677
|
-
|
|
678
|
-
|
|
684
|
+
const stat = {
|
|
685
|
+
mode: entry.mode,
|
|
686
|
+
size: (contents = Buffer.from(contents.buffer)).byteLength,
|
|
687
|
+
isDirectory: invariably.false,
|
|
688
|
+
isFile: invariably.true,
|
|
689
|
+
isSymbolicLink: invariably.false,
|
|
690
|
+
}
|
|
679
691
|
return new File({ path: entry.path, contents, stat })
|
|
680
692
|
})
|
|
681
693
|
}
|
|
@@ -687,7 +699,7 @@ function loadComponentDescriptor (files, ref, version) {
|
|
|
687
699
|
files.splice(descriptorFileIdx, 1)
|
|
688
700
|
let data
|
|
689
701
|
try {
|
|
690
|
-
data = yaml.load(descriptorFile.contents.toString(), { schema: yaml.CORE_SCHEMA })
|
|
702
|
+
data = Object(yaml.load(descriptorFile.contents.toString(), { schema: yaml.CORE_SCHEMA }))
|
|
691
703
|
} catch (err) {
|
|
692
704
|
throw Object.assign(err, { message: `${COMPONENT_DESC_FILENAME} has invalid syntax; ${err.message}` })
|
|
693
705
|
}
|
|
@@ -902,20 +914,6 @@ function isDirectory (url) {
|
|
|
902
914
|
return fsp.stat(url).then((stat) => stat.isDirectory(), invariably.false)
|
|
903
915
|
}
|
|
904
916
|
|
|
905
|
-
function symlinkAwareStat (path_) {
|
|
906
|
-
return fsp.lstat(path_).then((lstat) => {
|
|
907
|
-
if (!lstat.isSymbolicLink()) return lstat
|
|
908
|
-
return fsp.stat(path_).catch((statErr) =>
|
|
909
|
-
fsp
|
|
910
|
-
.readlink(path_)
|
|
911
|
-
.catch(invariably.void)
|
|
912
|
-
.then((symlink) => {
|
|
913
|
-
throw Object.assign(statErr, { symlink })
|
|
914
|
-
})
|
|
915
|
-
)
|
|
916
|
-
})
|
|
917
|
-
}
|
|
918
|
-
|
|
919
917
|
function tagsSpecified (sources) {
|
|
920
918
|
return sources.some(({ tags }) => tags && (Array.isArray(tags) ? tags.length : true))
|
|
921
919
|
}
|
|
@@ -986,15 +984,14 @@ function transformGitCloneError (err, displayUrl, authRequested) {
|
|
|
986
984
|
} else if (err.code === 'ENOTFOUND') {
|
|
987
985
|
wrappedMsg = `Content repository host could not be resolved: ${err.hostname}`
|
|
988
986
|
} else {
|
|
989
|
-
wrappedMsg =
|
|
987
|
+
wrappedMsg = err.message || String(err)
|
|
990
988
|
recoverable = trimMessage = true
|
|
991
989
|
}
|
|
992
|
-
if (trimMessage)
|
|
993
|
-
wrappedMsg = ~(wrappedMsg = wrappedMsg.trimEnd()).indexOf('. ') ? wrappedMsg : wrappedMsg.replace(/\.$/, '')
|
|
994
|
-
}
|
|
990
|
+
if (trimMessage && !~(wrappedMsg = wrappedMsg.trimEnd()).indexOf('. ')) wrappedMsg = wrappedMsg.replace(/\.$/, '')
|
|
995
991
|
const errWrapper = new Error(`${wrappedMsg} (url: ${displayUrl})`)
|
|
996
|
-
errWrapper.stack += `\nCaused by: ${err.stack
|
|
997
|
-
|
|
992
|
+
errWrapper.stack += `\nCaused by: ${err.stack ? inspect(err).replace(/^Error \[(.+?)\](?=: )/, '$1') : err}`
|
|
993
|
+
if (recoverable) Object.defineProperty(errWrapper, 'recoverable', { value: true })
|
|
994
|
+
return errWrapper
|
|
998
995
|
}
|
|
999
996
|
|
|
1000
997
|
function splitRefPatterns (str) {
|
package/lib/constants.js
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
module.exports = Object.freeze({
|
|
4
4
|
COMPONENT_DESC_FILENAME: 'antora.yml',
|
|
5
5
|
CONTENT_CACHE_FOLDER: 'content',
|
|
6
|
-
CONTENT_SRC_GLOB: '
|
|
7
|
-
CONTENT_SRC_OPTS: {
|
|
6
|
+
CONTENT_SRC_GLOB: '**/!(*~)',
|
|
7
|
+
CONTENT_SRC_OPTS: { dot: true, ignore: ['**/.*{,/**}'], objectMode: true, onlyFiles: false, unique: false },
|
|
8
8
|
FILE_MODES: { 100644: 0o100666 & ~process.umask(), 100755: 0o100777 & ~process.umask() },
|
|
9
9
|
GIT_CORE: 'antora',
|
|
10
10
|
GIT_OPERATION_LABEL_LENGTH: 8,
|
package/lib/git-plugin-http.js
CHANGED
|
@@ -49,11 +49,12 @@ module.exports = ({ headers: extraHeaders, httpProxy, httpsProxy, noProxy } = {}
|
|
|
49
49
|
}
|
|
50
50
|
return {
|
|
51
51
|
async request ({ url, method, headers, body }) {
|
|
52
|
-
headers = mergeHeaders(headers, extraHeaders)
|
|
52
|
+
headers = Object.assign(mergeHeaders(headers, extraHeaders), { connection: 'close' })
|
|
53
53
|
body = await mergeBuffers(body)
|
|
54
|
-
return new Promise((resolve, reject) =>
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
return new Promise((resolve, reject) => {
|
|
55
|
+
const opts = { url, method, headers, body, timeout: 0, keepAlive: false }
|
|
56
|
+
return get(opts, (err, res) => (err ? reject(err) : resolve(distillResponse(res))))
|
|
57
|
+
})
|
|
57
58
|
},
|
|
58
59
|
}
|
|
59
60
|
}
|
package/lib/matcher.js
CHANGED
|
@@ -16,15 +16,10 @@ const BASE_OPTS = {
|
|
|
16
16
|
strictSlashes: true,
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
function makeMatcherRx (input, opts) {
|
|
20
|
-
if (input && ~input.indexOf('{')) input = input.replace(/^([^({]+)\./, '$1(?:.)')
|
|
21
|
-
return makeRe(input, opts)
|
|
22
|
-
}
|
|
23
|
-
|
|
24
19
|
module.exports = {
|
|
25
20
|
MATCH_ALL_RX: { test: () => true },
|
|
26
21
|
expandBraces,
|
|
27
|
-
makeMatcherRx,
|
|
22
|
+
makeMatcherRx: makeRe,
|
|
28
23
|
pathMatcherOpts: Object.assign({}, BASE_OPTS, { dot: false }),
|
|
29
24
|
refMatcherOpts: (cache) =>
|
|
30
25
|
Object.assign({}, BASE_OPTS, {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@antora/content-aggregator",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.8",
|
|
4
4
|
"description": "Fetches and aggregates content from distributed sources for use in an Antora documentation pipeline.",
|
|
5
5
|
"license": "MPL-2.0",
|
|
6
6
|
"author": "OpenDevise Inc. (https://opendevise.com)",
|
|
@@ -29,20 +29,20 @@
|
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@antora/expand-path-helper": "~2.0",
|
|
32
|
-
"@antora/logger": "3.1.
|
|
32
|
+
"@antora/logger": "3.1.8",
|
|
33
33
|
"@antora/user-require-helper": "~2.0",
|
|
34
34
|
"braces": "~3.0",
|
|
35
35
|
"cache-directory": "~2.0",
|
|
36
|
-
"glob
|
|
36
|
+
"fast-glob": "~3.3",
|
|
37
37
|
"hpagent": "~1.2",
|
|
38
|
-
"isomorphic-git": "~1.
|
|
38
|
+
"isomorphic-git": "~1.25",
|
|
39
39
|
"js-yaml": "~4.1",
|
|
40
40
|
"multi-progress": "~4.0",
|
|
41
|
-
"picomatch": "~
|
|
41
|
+
"picomatch": "~4.0",
|
|
42
42
|
"progress": "~2.0",
|
|
43
43
|
"should-proxy": "~1.0",
|
|
44
44
|
"simple-get": "~4.0",
|
|
45
|
-
"vinyl": "~
|
|
45
|
+
"vinyl": "~3.0"
|
|
46
46
|
},
|
|
47
47
|
"engines": {
|
|
48
48
|
"node": ">=16.0.0"
|