@antora/content-aggregator 3.0.0-beta.2 → 3.0.0-beta.3
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 +134 -141
- package/lib/constants.js +1 -12
- package/lib/filter-refs.js +13 -31
- package/lib/git-credential-manager-store.js +1 -1
- package/lib/invariably.js +3 -0
- package/lib/matcher.js +32 -0
- package/lib/resolve-path-globs.js +7 -19
- package/package.json +3 -4
package/lib/aggregate-content.js
CHANGED
|
@@ -15,17 +15,17 @@ 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
|
|
19
|
-
const
|
|
18
|
+
const globStream = require('glob-stream')
|
|
19
|
+
const invariably = require('./invariably')
|
|
20
|
+
const { makeMatcherRx, versionMatcherOpts: VERSION_MATCHER_OPTS } = require('./matcher')
|
|
20
21
|
const MultiProgress = require('multi-progress')
|
|
21
22
|
const ospath = require('path')
|
|
22
23
|
const { posix: path } = ospath
|
|
23
24
|
const posixify = ospath.sep === '\\' ? (p) => p.replace(/\\/g, '/') : undefined
|
|
24
25
|
const { fs: resolvePathGlobsFs, git: resolvePathGlobsGit } = require('./resolve-path-globs')
|
|
25
|
-
const { Transform } = require('stream')
|
|
26
|
-
const map = (transform
|
|
26
|
+
const { pipeline, Transform } = require('stream')
|
|
27
|
+
const map = (transform) => new Transform({ objectMode: true, transform })
|
|
27
28
|
const userRequire = require('@antora/user-require-helper')
|
|
28
|
-
const vfs = require('vinyl-fs')
|
|
29
29
|
const yaml = require('js-yaml')
|
|
30
30
|
|
|
31
31
|
const {
|
|
@@ -37,12 +37,10 @@ const {
|
|
|
37
37
|
GIT_CORE,
|
|
38
38
|
GIT_OPERATION_LABEL_LENGTH,
|
|
39
39
|
GIT_PROGRESS_PHASES,
|
|
40
|
-
PICOMATCH_VERSION_OPTS,
|
|
41
40
|
REF_PATTERN_CACHE_KEY,
|
|
42
41
|
SYMLINK_FILE_MODE,
|
|
43
42
|
VALID_STATE_FILENAME,
|
|
44
43
|
} = require('./constants')
|
|
45
|
-
|
|
46
44
|
const ANY_SEPARATOR_RX = /[:/]/
|
|
47
45
|
const CSV_RX = /\s*,\s*/
|
|
48
46
|
const VENTILATED_CSV_RX = /\s*,\s+/
|
|
@@ -272,99 +270,100 @@ async function selectReferences (source, repo, remote) {
|
|
|
272
270
|
const patternCache = repo.cache[REF_PATTERN_CACHE_KEY]
|
|
273
271
|
const noWorktree = repo.url ? undefined : null
|
|
274
272
|
const refs = new Map()
|
|
275
|
-
if (
|
|
276
|
-
tagPatterns
|
|
273
|
+
if (
|
|
274
|
+
tagPatterns &&
|
|
275
|
+
(tagPatterns = Array.isArray(tagPatterns)
|
|
277
276
|
? tagPatterns.map((pattern) => String(pattern))
|
|
278
|
-
: splitRefPatterns(String(tagPatterns))
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
277
|
+
: splitRefPatterns(String(tagPatterns))).length
|
|
278
|
+
) {
|
|
279
|
+
const tags = await git.listTags(repo)
|
|
280
|
+
if (tags.length) {
|
|
281
|
+
for (const shortname of filterRefs(tags, tagPatterns, patternCache)) {
|
|
282
282
|
// NOTE tags are stored using symbol keys to distinguish them from branches
|
|
283
283
|
refs.set(Symbol(shortname), { shortname, fullname: 'tags/' + shortname, type: 'tag', head: noWorktree })
|
|
284
284
|
}
|
|
285
285
|
}
|
|
286
286
|
}
|
|
287
|
-
if (branchPatterns)
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
287
|
+
if (!branchPatterns) return [...refs.values()]
|
|
288
|
+
if (worktreePatterns) {
|
|
289
|
+
if (worktreePatterns === '.') {
|
|
290
|
+
worktreePatterns = ['.']
|
|
291
|
+
} else if (worktreePatterns === true) {
|
|
292
|
+
worktreePatterns = ['.', '*']
|
|
293
|
+
} else {
|
|
294
|
+
worktreePatterns = Array.isArray(worktreePatterns)
|
|
295
|
+
? worktreePatterns.map((pattern) => String(pattern))
|
|
296
|
+
: splitRefPatterns(String(worktreePatterns))
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
const branchPatternsString = String(branchPatterns)
|
|
300
|
+
if (branchPatternsString === 'HEAD' || branchPatternsString === '.') {
|
|
301
|
+
const currentBranch = await getCurrentBranchName(repo, remote)
|
|
302
|
+
if (currentBranch) {
|
|
303
|
+
branchPatterns = [currentBranch]
|
|
304
|
+
} else if (isBare) {
|
|
305
|
+
return [...refs.values()]
|
|
306
|
+
} else {
|
|
307
|
+
// NOTE current branch is undefined when HEAD is detached
|
|
308
|
+
const head = worktreePatterns[0] === '.' ? repo.dir : noWorktree
|
|
309
|
+
refs.set('HEAD', { shortname: 'HEAD', fullname: 'HEAD', type: 'branch', detached: true, head })
|
|
310
|
+
return [...refs.values()]
|
|
298
311
|
}
|
|
299
|
-
|
|
300
|
-
|
|
312
|
+
} else if (
|
|
313
|
+
(branchPatterns = Array.isArray(branchPatterns)
|
|
314
|
+
? branchPatterns.map((pattern) => String(pattern))
|
|
315
|
+
: splitRefPatterns(branchPatternsString)).length
|
|
316
|
+
) {
|
|
317
|
+
let headBranchIdx
|
|
318
|
+
// NOTE we can assume at least two entries if HEAD or . are present
|
|
319
|
+
if (~(headBranchIdx = branchPatterns.indexOf('HEAD')) || ~(headBranchIdx = branchPatterns.indexOf('.'))) {
|
|
301
320
|
const currentBranch = await getCurrentBranchName(repo, remote)
|
|
302
321
|
if (currentBranch) {
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
if (!isBare) {
|
|
306
|
-
// NOTE current branch is undefined when HEAD is detached
|
|
307
|
-
const head = worktreePatterns[0] === '.' ? repo.dir : noWorktree
|
|
308
|
-
refs.set('HEAD', { shortname: 'HEAD', fullname: 'HEAD', type: 'branch', detached: true, head })
|
|
309
|
-
}
|
|
310
|
-
return [...refs.values()]
|
|
311
|
-
}
|
|
312
|
-
} else if (
|
|
313
|
-
(branchPatterns = Array.isArray(branchPatterns)
|
|
314
|
-
? branchPatterns.map((pattern) => String(pattern))
|
|
315
|
-
: splitRefPatterns(branchPatternsString)).length
|
|
316
|
-
) {
|
|
317
|
-
let headBranchIdx
|
|
318
|
-
// NOTE we can assume at least two entries if HEAD or . are present
|
|
319
|
-
if (~(headBranchIdx = branchPatterns.indexOf('HEAD')) || ~(headBranchIdx = branchPatterns.indexOf('.'))) {
|
|
320
|
-
const currentBranch = await getCurrentBranchName(repo, remote)
|
|
321
|
-
if (currentBranch) {
|
|
322
|
-
// NOTE ignore if current branch is already in list
|
|
323
|
-
if (~branchPatterns.indexOf(currentBranch)) {
|
|
324
|
-
branchPatterns.splice(headBranchIdx, 1)
|
|
325
|
-
} else {
|
|
326
|
-
branchPatterns[headBranchIdx] = currentBranch
|
|
327
|
-
}
|
|
328
|
-
} else {
|
|
329
|
-
if (!isBare) {
|
|
330
|
-
let head = noWorktree
|
|
331
|
-
if (worktreePatterns[0] === '.') {
|
|
332
|
-
worktreePatterns = worktreePatterns.slice(1)
|
|
333
|
-
head = repo.dir
|
|
334
|
-
}
|
|
335
|
-
// NOTE current branch is undefined when HEAD is detached
|
|
336
|
-
refs.set('HEAD', { shortname: 'HEAD', fullname: 'HEAD', type: 'branch', detached: true, head })
|
|
337
|
-
}
|
|
322
|
+
// NOTE ignore if current branch is already in list
|
|
323
|
+
if (~branchPatterns.indexOf(currentBranch)) {
|
|
338
324
|
branchPatterns.splice(headBranchIdx, 1)
|
|
325
|
+
} else {
|
|
326
|
+
branchPatterns[headBranchIdx] = currentBranch
|
|
327
|
+
}
|
|
328
|
+
} else if (isBare) {
|
|
329
|
+
branchPatterns.splice(headBranchIdx, 1)
|
|
330
|
+
} else {
|
|
331
|
+
let head = noWorktree
|
|
332
|
+
if (worktreePatterns[0] === '.') {
|
|
333
|
+
worktreePatterns = worktreePatterns.slice(1)
|
|
334
|
+
head = repo.dir
|
|
339
335
|
}
|
|
336
|
+
// NOTE current branch is undefined when HEAD is detached
|
|
337
|
+
refs.set('HEAD', { shortname: 'HEAD', fullname: 'HEAD', type: 'branch', detached: true, head })
|
|
338
|
+
branchPatterns.splice(headBranchIdx, 1)
|
|
340
339
|
}
|
|
341
|
-
} else {
|
|
342
|
-
return [...refs.values()]
|
|
343
340
|
}
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
341
|
+
} else {
|
|
342
|
+
return [...refs.values()]
|
|
343
|
+
}
|
|
344
|
+
// NOTE isomorphic-git includes HEAD in list of remote branches (see https://isomorphic-git.org/docs/listBranches)
|
|
345
|
+
const remoteBranches = (await git.listBranches(Object.assign({ remote }, repo))).filter((it) => it !== 'HEAD')
|
|
346
|
+
if (remoteBranches.length) {
|
|
347
|
+
for (const shortname of filterRefs(remoteBranches, branchPatterns, patternCache)) {
|
|
348
|
+
const fullname = 'remotes/' + remote + '/' + shortname
|
|
349
|
+
refs.set(shortname, { shortname, fullname, type: 'branch', remote, head: noWorktree })
|
|
351
350
|
}
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
}
|
|
351
|
+
}
|
|
352
|
+
// NOTE only consider local branches if repo has a worktree or there are no remote tracking branches
|
|
353
|
+
if (!isBare) {
|
|
354
|
+
const localBranches = await git.listBranches(repo)
|
|
355
|
+
if (localBranches.length) {
|
|
356
|
+
const worktrees = await findWorktrees(repo, worktreePatterns)
|
|
357
|
+
for (const shortname of filterRefs(localBranches, branchPatterns, patternCache)) {
|
|
358
|
+
const head = worktrees.get(shortname) || noWorktree
|
|
359
|
+
refs.set(shortname, { shortname, fullname: 'heads/' + shortname, type: 'branch', head })
|
|
361
360
|
}
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
}
|
|
361
|
+
}
|
|
362
|
+
} else if (!remoteBranches.length) {
|
|
363
|
+
const localBranches = await git.listBranches(repo)
|
|
364
|
+
if (localBranches.length) {
|
|
365
|
+
for (const shortname of filterRefs(localBranches, branchPatterns, patternCache)) {
|
|
366
|
+
refs.set(shortname, { shortname, fullname: 'heads/' + shortname, type: 'branch', head: noWorktree })
|
|
368
367
|
}
|
|
369
368
|
}
|
|
370
369
|
}
|
|
@@ -439,26 +438,9 @@ function collectFilesFromStartPath (startPath, repo, authStatus, ref, worktreePa
|
|
|
439
438
|
function readFilesFromWorktree (worktreePath, startPath) {
|
|
440
439
|
const cwd = ospath.join(worktreePath, startPath)
|
|
441
440
|
return fsp.stat(cwd).then(
|
|
442
|
-
(
|
|
443
|
-
if (!
|
|
444
|
-
return
|
|
445
|
-
vfs
|
|
446
|
-
.src(CONTENT_SRC_GLOB, Object.assign({ cwd }, CONTENT_SRC_OPTS))
|
|
447
|
-
.on('error', (err) => {
|
|
448
|
-
if (err.code === 'ENOENT' && err.syscall === 'stat') {
|
|
449
|
-
try {
|
|
450
|
-
if (fs.lstatSync(err.path).isSymbolicLink()) {
|
|
451
|
-
err.message = `Broken symbolic link detected at ${ospath.relative(cwd, err.path)}`
|
|
452
|
-
}
|
|
453
|
-
} catch {}
|
|
454
|
-
} else if (err.code === 'ELOOP') {
|
|
455
|
-
err.message = `Symbolic link cycle detected at ${ospath.relative(cwd, err.path)}`
|
|
456
|
-
}
|
|
457
|
-
reject(err)
|
|
458
|
-
})
|
|
459
|
-
.pipe(relativizeFiles())
|
|
460
|
-
.pipe(collectDataFromStream(resolve))
|
|
461
|
-
)
|
|
441
|
+
(startPathStat) => {
|
|
442
|
+
if (!startPathStat.isDirectory()) throw new Error(`the start path '${startPath}' is not a directory`)
|
|
443
|
+
return srcFs(cwd)
|
|
462
444
|
},
|
|
463
445
|
() => {
|
|
464
446
|
throw new Error(`the start path '${startPath}' does not exist`)
|
|
@@ -466,40 +448,42 @@ function readFilesFromWorktree (worktreePath, startPath) {
|
|
|
466
448
|
)
|
|
467
449
|
}
|
|
468
450
|
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
451
|
+
function srcFs (cwd) {
|
|
452
|
+
return new Promise((resolve, reject, cache = {}, files = []) =>
|
|
453
|
+
pipeline(
|
|
454
|
+
globStream(CONTENT_SRC_GLOB, Object.assign({ cache, cwd }, CONTENT_SRC_OPTS)),
|
|
455
|
+
map(({ path: abspathPosix }, _, next) => {
|
|
456
|
+
if (Array.isArray(cache[abspathPosix])) return next() // optimization, but not guaranteed
|
|
457
|
+
const abspath = posixify ? ospath.normalize(abspathPosix) : abspathPosix
|
|
458
|
+
const relpath = abspath.substr(cwd.length + 1)
|
|
459
|
+
symlinkAwareStat(abspath).then(
|
|
460
|
+
(stat) => {
|
|
461
|
+
if (stat.isDirectory()) return next()
|
|
462
|
+
fsp.readFile(abspath).then(
|
|
463
|
+
(contents) => {
|
|
464
|
+
files.push(new File({ path: posixify ? posixify(relpath) : relpath, contents, stat, src: { abspath } }))
|
|
465
|
+
next()
|
|
466
|
+
},
|
|
467
|
+
(readErr) => {
|
|
468
|
+
next(Object.assign(readErr, { message: readErr.message.replace(`'${abspath}'`, relpath) }))
|
|
469
|
+
}
|
|
470
|
+
)
|
|
471
|
+
},
|
|
472
|
+
(statErr) => {
|
|
473
|
+
if (statErr.symlink) {
|
|
474
|
+
statErr.message =
|
|
475
|
+
statErr.code === 'ELOOP'
|
|
476
|
+
? `Symbolic link cycle detected at ${relpath}`
|
|
477
|
+
: `Broken symbolic link detected at ${relpath}`
|
|
478
|
+
} else {
|
|
479
|
+
statErr.message = statErr.message.replace(`'${abspath}'`, relpath)
|
|
480
|
+
}
|
|
481
|
+
next(statErr)
|
|
482
|
+
}
|
|
483
|
+
)
|
|
484
|
+
}),
|
|
485
|
+
(err) => (err ? reject(err) : resolve(files))
|
|
486
|
+
)
|
|
503
487
|
)
|
|
504
488
|
}
|
|
505
489
|
|
|
@@ -690,7 +674,7 @@ function loadComponentDescriptor (files, ref, version) {
|
|
|
690
674
|
matched = version[refname]
|
|
691
675
|
} else if (
|
|
692
676
|
!Object.entries(version).some(([pattern, replacement]) => {
|
|
693
|
-
const result = refname.replace(
|
|
677
|
+
const result = refname.replace(makeMatcherRx(pattern, VERSION_MATCHER_OPTS), '\0' + replacement)
|
|
694
678
|
if (result === refname) return false
|
|
695
679
|
matched = result.substr(1)
|
|
696
680
|
return true
|
|
@@ -920,6 +904,15 @@ function isDirectory (url) {
|
|
|
920
904
|
return fsp.stat(url).then((stat) => stat.isDirectory(), invariably.false)
|
|
921
905
|
}
|
|
922
906
|
|
|
907
|
+
function symlinkAwareStat (path_) {
|
|
908
|
+
return fsp.lstat(path_).then((lstat) => {
|
|
909
|
+
if (!lstat.isSymbolicLink()) return lstat
|
|
910
|
+
return fsp.stat(path_).catch((statErr) => {
|
|
911
|
+
throw Object.assign(statErr, { symlink: true })
|
|
912
|
+
})
|
|
913
|
+
})
|
|
914
|
+
}
|
|
915
|
+
|
|
923
916
|
function tagsSpecified (sources) {
|
|
924
917
|
return sources.some(({ tags }) => tags && (Array.isArray(tags) ? tags.length : true))
|
|
925
918
|
}
|
|
@@ -1019,7 +1012,7 @@ function findWorktrees (repo, patterns) {
|
|
|
1019
1012
|
return (patterns.length
|
|
1020
1013
|
? fsp
|
|
1021
1014
|
.readdir((worktreesDir = ospath.join(repo.dir, '.git', 'worktrees')))
|
|
1022
|
-
.then((worktreeNames) => filterRefs(worktreeNames,
|
|
1015
|
+
.then((worktreeNames) => filterRefs(worktreeNames, patterns, patternCache), invariably.emptyArray)
|
|
1023
1016
|
.then((worktreeNames) =>
|
|
1024
1017
|
worktreeNames.length
|
|
1025
1018
|
? Promise.all(
|
package/lib/constants.js
CHANGED
|
@@ -4,22 +4,11 @@ module.exports = Object.freeze({
|
|
|
4
4
|
COMPONENT_DESC_FILENAME: 'antora.yml',
|
|
5
5
|
CONTENT_CACHE_FOLDER: 'content',
|
|
6
6
|
CONTENT_SRC_GLOB: '**/*[!~]',
|
|
7
|
-
CONTENT_SRC_OPTS: { follow: true, nomount: true, nosort: true, nounique: true,
|
|
7
|
+
CONTENT_SRC_OPTS: { follow: true, nomount: true, nosort: true, nounique: true, strict: false, uniqueBy: (m) => m },
|
|
8
8
|
FILE_MODES: { 100644: 0o100666 & ~process.umask(), 100755: 0o100777 & ~process.umask() },
|
|
9
9
|
GIT_CORE: 'antora',
|
|
10
10
|
GIT_OPERATION_LABEL_LENGTH: 8,
|
|
11
11
|
GIT_PROGRESS_PHASES: ['Counting objects', 'Compressing objects', 'Receiving objects', 'Resolving deltas'],
|
|
12
|
-
PICOMATCH_VERSION_OPTS: {
|
|
13
|
-
bash: true,
|
|
14
|
-
dot: true,
|
|
15
|
-
fastpaths: false,
|
|
16
|
-
nobracket: true,
|
|
17
|
-
noglobstar: true,
|
|
18
|
-
nonegate: true,
|
|
19
|
-
noquantifiers: true,
|
|
20
|
-
regex: false,
|
|
21
|
-
strictSlashes: true,
|
|
22
|
-
},
|
|
23
12
|
REF_PATTERN_CACHE_KEY: Symbol('RefPatternCache'),
|
|
24
13
|
SYMLINK_FILE_MODE: '120000',
|
|
25
14
|
VALID_STATE_FILENAME: 'valid',
|
package/lib/filter-refs.js
CHANGED
|
@@ -1,49 +1,31 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const {
|
|
4
|
-
const { makeRe: makePicomatchRx } = require('picomatch')
|
|
5
|
-
|
|
6
|
-
function getPicomatchOpts (cache) {
|
|
7
|
-
return {
|
|
8
|
-
bash: true,
|
|
9
|
-
dot: true,
|
|
10
|
-
expandRange: (begin, end, step, opts) => {
|
|
11
|
-
const pattern = opts ? `{${begin}..${end}..${step}}` : `{${begin}..${end}}`
|
|
12
|
-
return cache.braces.get(pattern) || cache.braces.set(pattern, bracesToGroup(pattern)).get(pattern)
|
|
13
|
-
},
|
|
14
|
-
fastpaths: false,
|
|
15
|
-
nobracket: true,
|
|
16
|
-
noglobstar: true,
|
|
17
|
-
noquantifiers: true,
|
|
18
|
-
regex: false,
|
|
19
|
-
strictSlashes: true,
|
|
20
|
-
}
|
|
21
|
-
}
|
|
3
|
+
const { makeMatcherRx, refMatcherOpts: getMatcherOpts, MATCH_ALL_RX } = require('./matcher')
|
|
22
4
|
|
|
23
5
|
function compileRx (pattern, opts) {
|
|
24
|
-
if (pattern === '*' || pattern === '**') return
|
|
6
|
+
if (pattern === '*' || pattern === '**') return MATCH_ALL_RX
|
|
25
7
|
return pattern.charAt() === '!' // do our own negate
|
|
26
|
-
? Object.defineProperty(
|
|
27
|
-
:
|
|
8
|
+
? Object.defineProperty(makeMatcherRx(pattern.substr(1), opts), 'negated', { value: true })
|
|
9
|
+
: makeMatcherRx(pattern, opts)
|
|
28
10
|
}
|
|
29
11
|
|
|
30
|
-
function createMatcher (patterns, cache) {
|
|
31
|
-
let opts
|
|
12
|
+
function createMatcher (patterns, cache, opts) {
|
|
32
13
|
const rxs = patterns.map(
|
|
33
14
|
(pattern) =>
|
|
34
|
-
cache.get(pattern) ||
|
|
35
|
-
cache.set(pattern, compileRx(pattern, opts || (opts = getPicomatchOpts(cache)))).get(pattern)
|
|
15
|
+
cache.get(pattern) || cache.set(pattern, compileRx(pattern, opts || (opts = getMatcherOpts(cache)))).get(pattern)
|
|
36
16
|
)
|
|
17
|
+
if (rxs[0].negated) rxs.unshift(MATCH_ALL_RX)
|
|
37
18
|
return (candidate) => {
|
|
38
|
-
let first = true
|
|
39
19
|
let matched
|
|
40
20
|
for (const rx of rxs) {
|
|
21
|
+
let voteIfMatched = true
|
|
41
22
|
if (matched) {
|
|
42
|
-
if (rx.negated
|
|
43
|
-
|
|
44
|
-
|
|
23
|
+
if (!rx.negated) continue
|
|
24
|
+
voteIfMatched = false
|
|
25
|
+
} else if (rx.negated) {
|
|
26
|
+
continue
|
|
45
27
|
}
|
|
46
|
-
|
|
28
|
+
if (rx.test(candidate)) matched = voteIfMatched
|
|
47
29
|
}
|
|
48
30
|
return matched
|
|
49
31
|
}
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
const { homedir } = require('os')
|
|
4
4
|
const expandPath = require('@antora/expand-path-helper')
|
|
5
|
-
const invariably = { void: () => undefined }
|
|
6
5
|
const { promises: fsp } = require('fs')
|
|
6
|
+
const invariably = require('./invariably')
|
|
7
7
|
const ospath = require('path')
|
|
8
8
|
|
|
9
9
|
class GitCredentialManagerStore {
|
package/lib/matcher.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { compile: bracesToGroup, expand: expandBraces } = require('braces')
|
|
4
|
+
const { makeRe: makeMatcherRx } = require('picomatch')
|
|
5
|
+
|
|
6
|
+
const BASE_OPTS = {
|
|
7
|
+
bash: true,
|
|
8
|
+
dot: true,
|
|
9
|
+
expandRange: (begin, end, step, opts) => bracesToGroup(opts ? `{${begin}..${end}..${step}}` : `{${begin}..${end}}`),
|
|
10
|
+
fastpaths: false,
|
|
11
|
+
nobracket: true,
|
|
12
|
+
noglobstar: true,
|
|
13
|
+
nonegate: true,
|
|
14
|
+
noquantifiers: true,
|
|
15
|
+
regex: false,
|
|
16
|
+
strictSlashes: true,
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
module.exports = {
|
|
20
|
+
MATCH_ALL_RX: { test: () => true },
|
|
21
|
+
expandBraces,
|
|
22
|
+
makeMatcherRx,
|
|
23
|
+
pathMatcherOpts: Object.assign({}, BASE_OPTS, { dot: false }),
|
|
24
|
+
refMatcherOpts: (cache) =>
|
|
25
|
+
Object.assign({}, BASE_OPTS, {
|
|
26
|
+
expandRange: (begin, end, step, opts) => {
|
|
27
|
+
const pattern = opts ? `{${begin}..${end}..${step}}` : `{${begin}..${end}}`
|
|
28
|
+
return cache.braces.get(pattern) || cache.braces.set(pattern, bracesToGroup(pattern)).get(pattern)
|
|
29
|
+
},
|
|
30
|
+
}),
|
|
31
|
+
versionMatcherOpts: Object.assign({}, BASE_OPTS, { nonegate: false }),
|
|
32
|
+
}
|
|
@@ -1,32 +1,20 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const { expand: expandBraces, compile: bracesToGroup } = require('braces')
|
|
4
3
|
const flattenDeep = require('./flatten-deep')
|
|
5
4
|
const { promises: fsp } = require('fs')
|
|
6
5
|
const git = require('./git')
|
|
7
|
-
const invariably =
|
|
8
|
-
const {
|
|
6
|
+
const invariably = require('./invariably')
|
|
7
|
+
const { expandBraces, makeMatcherRx, pathMatcherOpts: MATCHER_OPTS } = require('./matcher')
|
|
9
8
|
|
|
10
9
|
const NON_GLOB_SPECIAL_CHARS_RX = /[.+?^${}()|[\]\\]/g
|
|
11
10
|
const RX_MAGIC_DETECTOR = /[*{(]/
|
|
12
|
-
const PICOMATCH_OPTS = {
|
|
13
|
-
bash: true,
|
|
14
|
-
expandRange: (begin, end, step, opts) => bracesToGroup(opts ? `{${begin}..${end}..${step}}` : `{${begin}..${end}}`),
|
|
15
|
-
fastpaths: false,
|
|
16
|
-
nobracket: true,
|
|
17
|
-
noglobstar: true,
|
|
18
|
-
nonegate: true,
|
|
19
|
-
noquantifiers: true,
|
|
20
|
-
regex: false,
|
|
21
|
-
strictSlashes: true,
|
|
22
|
-
}
|
|
23
11
|
|
|
24
12
|
function resolvePathGlobs (base, patterns, listDirents, retrievePath, tree = { path: '' }) {
|
|
25
13
|
return patterns.reduce((paths, pattern) => {
|
|
26
14
|
if (pattern.charAt() === '!') {
|
|
27
15
|
return paths.then((resolvedPaths) => {
|
|
28
16
|
if (resolvedPaths.length) {
|
|
29
|
-
const rx =
|
|
17
|
+
const rx = makeMatcherRx(pattern.substr(1), MATCHER_OPTS)
|
|
30
18
|
return resolvedPaths.filter((it) => !rx.test(it))
|
|
31
19
|
} else {
|
|
32
20
|
return resolvedPaths
|
|
@@ -49,10 +37,10 @@ async function glob (base, patternSegments, listDirents, retrievePath, { oid, pa
|
|
|
49
37
|
if (patternSegment === '*') {
|
|
50
38
|
isMatch = (it) => it.charAt() !== '.'
|
|
51
39
|
} else if (~patternSegment.indexOf('(')) {
|
|
52
|
-
isMatch = (isMatch =
|
|
40
|
+
isMatch = (isMatch = makeMatcherRx(patternSegment, MATCHER_OPTS)).test.bind(isMatch)
|
|
53
41
|
} else if (~patternSegment.indexOf('{')) {
|
|
54
42
|
if (globbed) {
|
|
55
|
-
isMatch = (isMatch =
|
|
43
|
+
isMatch = (isMatch = makeMatcherRx(patternSegment, MATCHER_OPTS)).test.bind(isMatch)
|
|
56
44
|
} else if (~patternSegment.indexOf('*')) {
|
|
57
45
|
const [wildPatterns, literals] = expandBraces(patternSegment).reduce(
|
|
58
46
|
([wild, literal], it) => (~it.indexOf('*') ? [[...wild, it], literal] : [wild, [...literal, it]]),
|
|
@@ -64,7 +52,7 @@ async function glob (base, patternSegments, listDirents, retrievePath, { oid, pa
|
|
|
64
52
|
return expandBraces(patternSegment).map((it) => joinPath(path, it))
|
|
65
53
|
}
|
|
66
54
|
} else {
|
|
67
|
-
isMatch = (isMatch =
|
|
55
|
+
isMatch = (isMatch = makeSingleMatcherRx(patternSegment)).test.bind(isMatch)
|
|
68
56
|
}
|
|
69
57
|
let dirents = await listDirents(base, oid || path)
|
|
70
58
|
if (explicit) dirents = dirents.filter((dirent) => !explicit.has(dirent.name))
|
|
@@ -134,7 +122,7 @@ function makeAlternationMatcherRx (patterns) {
|
|
|
134
122
|
return new RegExp('^(?:' + patterns.map(patternToRx).join('|') + ')$')
|
|
135
123
|
}
|
|
136
124
|
|
|
137
|
-
function
|
|
125
|
+
function makeSingleMatcherRx (pattern) {
|
|
138
126
|
return new RegExp('^' + patternToRx(pattern) + '$')
|
|
139
127
|
}
|
|
140
128
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@antora/content-aggregator",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.3",
|
|
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)",
|
|
@@ -30,8 +30,7 @@
|
|
|
30
30
|
"progress": "~2.0",
|
|
31
31
|
"should-proxy": "~1.0",
|
|
32
32
|
"simple-get": "~4.0",
|
|
33
|
-
"vinyl": "~2.2"
|
|
34
|
-
"vinyl-fs": "~3.0"
|
|
33
|
+
"vinyl": "~2.2"
|
|
35
34
|
},
|
|
36
35
|
"engines": {
|
|
37
36
|
"node": ">=12.21.0"
|
|
@@ -49,5 +48,5 @@
|
|
|
49
48
|
"static site",
|
|
50
49
|
"web publishing"
|
|
51
50
|
],
|
|
52
|
-
"gitHead": "
|
|
51
|
+
"gitHead": "45da95a2e2dea538379d2d9f42013d2208fb86c3"
|
|
53
52
|
}
|