@antora/content-aggregator 3.2.0-alpha.6 → 3.2.0-alpha.9
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 +100 -99
- package/lib/compute-origin.js +4 -3
- package/lib/filter-refs.js +3 -4
- package/lib/resolve-path-globs.js +24 -23
- package/package.json +9 -5
package/lib/aggregate-content.js
CHANGED
|
@@ -100,12 +100,12 @@ function aggregateContent (playbook) {
|
|
|
100
100
|
const sourcesByUrl = sources.reduce((accum, source) => {
|
|
101
101
|
return accum.set(source.url, [...(accum.get(source.url) || []), Object.assign({}, sourceDefaults, source)])
|
|
102
102
|
}, new Map())
|
|
103
|
-
const progress =
|
|
103
|
+
const progress = quiet ? undefined : createProgress(sourcesByUrl.keys(), process.stdout)
|
|
104
104
|
const refPatternCache = Object.assign(new Map(), { braces: new Map() })
|
|
105
105
|
const fetchConfig = { always: fetch, depth: Math.max(0, gitConfig.fetchDepth ?? 1) }
|
|
106
106
|
const loadOpts = { cacheDir, fetch: fetchConfig, gitPlugins, progress, startDir, refPatternCache }
|
|
107
107
|
return collectFiles(sourcesByUrl, loadOpts, concurrency).then(buildAggregate, (err) => {
|
|
108
|
-
progress
|
|
108
|
+
progress?.terminate()
|
|
109
109
|
throw err
|
|
110
110
|
})
|
|
111
111
|
})
|
|
@@ -125,14 +125,14 @@ async function collectFiles (sourcesByUrl, loadOpts, concurrency, fetchedUrls =
|
|
|
125
125
|
const msg0 = 'An unexpected error occurred while fetching content sources concurrently.'
|
|
126
126
|
const msg1 = 'Retrying with git.fetch_concurrency value of 1.'
|
|
127
127
|
logger.warn(rejections[0], msg0 + ' ' + msg1)
|
|
128
|
-
const fulfilledUrls = results.
|
|
128
|
+
const fulfilledUrls = results.filter((it) => it?.repo.url).map((it) => it.url)
|
|
129
129
|
return collectFiles(sourcesByUrl, loadOpts, Object.assign(concurrency, { fetch: 1 }), fulfilledUrls)
|
|
130
130
|
}
|
|
131
131
|
throw rejections[0]
|
|
132
132
|
}
|
|
133
133
|
return Promise.all(
|
|
134
134
|
results.map(({ repo, authStatus, sources }) =>
|
|
135
|
-
selectStartPathsForRepository(repo,
|
|
135
|
+
selectStartPathsForRepository(repo, sources).then((startPaths) =>
|
|
136
136
|
collectFilesFromStartPaths.bind(null, startPaths, repo, authStatus)
|
|
137
137
|
)
|
|
138
138
|
)
|
|
@@ -182,12 +182,12 @@ async function loadRepository (url, opts, result = {}) {
|
|
|
182
182
|
return git.setConfig(Object.assign({ path: 'remote.origin.private', value: authStatus }, repo))
|
|
183
183
|
})
|
|
184
184
|
.catch((fetchErr) => {
|
|
185
|
-
|
|
185
|
+
fetchOpts.onProgress?.finish(fetchErr)
|
|
186
186
|
if (HTTP_ERROR_CODE_RX.test(fetchErr.code) && fetchErr.data.statusCode === 401) fetchErr.rethrow = true
|
|
187
187
|
throw fetchErr
|
|
188
188
|
})
|
|
189
189
|
.then(() => fsp.writeFile(validStateFile, '').catch(invariably.void))
|
|
190
|
-
.then(() => fetchOpts.onProgress
|
|
190
|
+
.then(() => fetchOpts.onProgress?.finish())
|
|
191
191
|
} else {
|
|
192
192
|
authStatus = await git.getConfig(Object.assign({ path: 'remote.origin.private' }, repo))
|
|
193
193
|
}
|
|
@@ -203,12 +203,12 @@ async function loadRepository (url, opts, result = {}) {
|
|
|
203
203
|
return git.setConfig(Object.assign({ path: 'remote.origin.private', value: authStatus }, repo))
|
|
204
204
|
})
|
|
205
205
|
.catch((cloneErr) => {
|
|
206
|
-
|
|
206
|
+
fetchOpts.onProgress?.finish(cloneErr)
|
|
207
207
|
const authRequested = credentialManager.status({ url }) === 'requested'
|
|
208
208
|
throw transformGitCloneError(cloneErr, displayUrl, authRequested)
|
|
209
209
|
})
|
|
210
210
|
.then(() => fsp.writeFile(validStateFile, '').catch(invariably.void))
|
|
211
|
-
.then(() => fetchOpts.onProgress
|
|
211
|
+
.then(() => fetchOpts.onProgress?.finish())
|
|
212
212
|
}
|
|
213
213
|
} else if (await isDirectory((dir = expandPath(url, { dot: opts.startDir })))) {
|
|
214
214
|
const dotgit = ospath.join(dir, '.git')
|
|
@@ -244,26 +244,37 @@ function extractCredentials (url) {
|
|
|
244
244
|
// NOTE if only username is present, assume it's an oauth token and set password to empty string
|
|
245
245
|
const credentials = username ? { username, password: password || '' } : {}
|
|
246
246
|
return { displayUrl, url, credentials }
|
|
247
|
-
} else if (url.startsWith('git@')) {
|
|
248
|
-
return { displayUrl: url, url: 'https://' + url.substr(4).replace(':', '/') }
|
|
249
|
-
} else {
|
|
250
|
-
return { displayUrl: url, url }
|
|
251
247
|
}
|
|
248
|
+
if (url.startsWith('git@')) return { displayUrl: url, url: 'https://' + url.substr(4).replace(':', '/') }
|
|
249
|
+
return { displayUrl: url, url }
|
|
252
250
|
}
|
|
253
251
|
|
|
254
|
-
async function selectStartPathsForRepository (repo,
|
|
252
|
+
async function selectStartPathsForRepository (repo, sources) {
|
|
255
253
|
const startPaths = []
|
|
256
254
|
const originUrls = {}
|
|
257
255
|
for (const source of sources) {
|
|
258
256
|
const { version, editUrl } = source
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
257
|
+
let remoteName, originUrl
|
|
258
|
+
if (repo.url) {
|
|
259
|
+
remoteName = 'origin' // NOTE if repository is managed (has url property), we can assume remote name is origin
|
|
260
|
+
originUrl = repo.url
|
|
261
|
+
} else {
|
|
262
|
+
remoteName = source.remote || 'origin'
|
|
263
|
+
originUrl =
|
|
264
|
+
remoteName in originUrls
|
|
265
|
+
? originUrls[remoteName]
|
|
266
|
+
: (originUrls[remoteName] = await resolveRemoteUrl(repo, remoteName))
|
|
267
|
+
if (!originUrl) {
|
|
268
|
+
remoteName = undefined
|
|
269
|
+
if ((originUrl = posixify ? 'file:///' + posixify(repo.dir) : 'file://' + repo.dir).indexOf(' ')) {
|
|
270
|
+
originUrl = originUrl.replace(SPACE_RX, '%20')
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
263
274
|
const refs = await selectReferences(source, repo, remoteName)
|
|
264
275
|
if (refs.length) {
|
|
265
276
|
for (const ref of refs) {
|
|
266
|
-
for (const startPath of await selectStartPaths(source, repo,
|
|
277
|
+
for (const startPath of await selectStartPaths(source, repo, ref)) {
|
|
267
278
|
startPaths.push({ startPath, ref, originUrl, editUrl, version })
|
|
268
279
|
}
|
|
269
280
|
}
|
|
@@ -363,45 +374,40 @@ async function selectReferences (source, repo, remote) {
|
|
|
363
374
|
}
|
|
364
375
|
}
|
|
365
376
|
// NOTE isomorphic-git includes HEAD in list of remote branches (see https://isomorphic-git.org/docs/listBranches)
|
|
366
|
-
const remoteBranches =
|
|
377
|
+
const remoteBranches = remote
|
|
378
|
+
? (await git.listBranches(Object.assign({ remote }, repo))).filter((it) => it !== 'HEAD')
|
|
379
|
+
: []
|
|
367
380
|
if (remoteBranches.length) {
|
|
368
381
|
for (const shortname of filterRefs(remoteBranches, branchPatterns, patternCache)) {
|
|
369
382
|
const fullname = 'remotes/' + remote + '/' + shortname
|
|
370
383
|
refs.set(shortname, { shortname, fullname, type: 'branch', remote, head: noWorktree })
|
|
371
384
|
}
|
|
372
385
|
}
|
|
373
|
-
|
|
374
|
-
if (!isBare) {
|
|
386
|
+
if (!managed) {
|
|
375
387
|
const localBranches = await git.listBranches(repo).then((branches) => {
|
|
376
|
-
if (branches.length) return branches
|
|
377
|
-
if (currentBranch
|
|
378
|
-
return
|
|
388
|
+
if (branches.length || isBare) return branches
|
|
389
|
+
if (currentBranch != null) return [currentBranch]
|
|
390
|
+
return getCurrentBranchName(repo).then((branch) => (branch ? [branch] : []))
|
|
379
391
|
})
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
return shortname ? (pattern.startsWith('HEAD@') ? shortname : undefined) : candidate
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
for (const shortname of filterRefs(localBranches, branchPatterns, patternCache, onMatch)) {
|
|
395
|
-
const head = (worktrees.get(shortname) || { head: noWorktree }).head
|
|
396
|
-
refs.set(shortname, { shortname, fullname: 'heads/' + shortname, type: 'branch', head })
|
|
392
|
+
const worktrees = await findWorktrees(repo, worktreePatterns)
|
|
393
|
+
let onMatch
|
|
394
|
+
if ((worktreePatterns.join('') || '.') !== '.') {
|
|
395
|
+
const symbolicNames = new Map()
|
|
396
|
+
worktrees.forEach(({ name, symbolicName = 'HEAD@' + name }, shortname) => {
|
|
397
|
+
localBranches.push(symbolicName)
|
|
398
|
+
symbolicNames.set(symbolicName, shortname)
|
|
399
|
+
})
|
|
400
|
+
onMatch = (candidate, { pattern }) => {
|
|
401
|
+
const shortname = symbolicNames.get(candidate)
|
|
402
|
+
return shortname ? (pattern.startsWith('HEAD@') ? shortname : undefined) : candidate
|
|
397
403
|
}
|
|
398
404
|
}
|
|
399
|
-
} else if (!managed || !remoteBranches.length) {
|
|
400
|
-
const localBranches = await git.listBranches(repo)
|
|
401
405
|
if (localBranches.length) {
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
refs.
|
|
406
|
+
const preferRemote = isBare && remoteBranches.length > 0
|
|
407
|
+
for (const shortname of filterRefs(localBranches, branchPatterns, patternCache, onMatch)) {
|
|
408
|
+
if (preferRemote && refs.has(shortname)) continue
|
|
409
|
+
const head = (worktrees.get(shortname) || { head: false }).head
|
|
410
|
+
refs.set(shortname, { shortname, fullname: 'heads/' + shortname, type: 'branch', head })
|
|
405
411
|
}
|
|
406
412
|
}
|
|
407
413
|
}
|
|
@@ -415,13 +421,13 @@ function getCurrentBranchName (repo, remote) {
|
|
|
415
421
|
return (
|
|
416
422
|
remote && repo.noCheckout
|
|
417
423
|
? git
|
|
418
|
-
|
|
419
|
-
|
|
424
|
+
.resolveRef(Object.assign({ ref: 'refs/remotes/' + remote + '/HEAD', depth: 2 }, repo))
|
|
425
|
+
.catch(() => git.resolveRef(Object.assign({ ref: 'HEAD', depth: 2 }, repo)))
|
|
420
426
|
: git.resolveRef(Object.assign({ ref: 'HEAD', depth: 2 }, repo))
|
|
421
427
|
).then((ref) => (ref.startsWith('refs/') ? ref.replace(SHORTEN_REF_RX, '') : undefined))
|
|
422
428
|
}
|
|
423
429
|
|
|
424
|
-
async function selectStartPaths (source, repo,
|
|
430
|
+
async function selectStartPaths (source, repo, ref) {
|
|
425
431
|
const url = repo.url
|
|
426
432
|
const displayUrl = url || repo.dir
|
|
427
433
|
const worktreePath = ref.head
|
|
@@ -463,7 +469,7 @@ function collectFilesFromStartPath (startPath, repo, authStatus, ref, originUrl,
|
|
|
463
469
|
return (worktreePath ? readFilesFromWorktree(origin) : readFilesFromGitTree(repo, ref.oid, startPath))
|
|
464
470
|
.then((files) => {
|
|
465
471
|
const batch = deepClone((origin.descriptor = loadComponentDescriptor(files, ref, version)))
|
|
466
|
-
if ('nav' in batch) batch.nav.origin = origin
|
|
472
|
+
if ('nav' in batch && Array.isArray(batch.nav)) batch.nav.origin = origin
|
|
467
473
|
batch.files = files.map((file) => assignFileProperties(file, origin))
|
|
468
474
|
batch.origins = [origin]
|
|
469
475
|
return batch
|
|
@@ -548,9 +554,9 @@ function readFilesFromGitTree (repo, oid, startPath) {
|
|
|
548
554
|
Object.assign(root, { dirname: '' })
|
|
549
555
|
return startPath
|
|
550
556
|
? getGitTreeAtStartPath(repo, oid, startPath).then((start) => {
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
557
|
+
Object.assign(start, { dirname: startPath })
|
|
558
|
+
return srcGitTree(repo, root, start)
|
|
559
|
+
})
|
|
554
560
|
: srcGitTree(repo, root)
|
|
555
561
|
})
|
|
556
562
|
}
|
|
@@ -605,7 +611,8 @@ function visitGitTree (emitter, repo, root, filter, convert, parent, dirname = '
|
|
|
605
611
|
(target) => {
|
|
606
612
|
if (target.type === 'tree') {
|
|
607
613
|
return visitGitTree(emitter, repo, root, filter, convert, target, vfilePath, target.following)
|
|
608
|
-
}
|
|
614
|
+
}
|
|
615
|
+
if (target.type === 'blob' && filterVerdict === true && (mode = FILE_MODES[target.mode])) {
|
|
609
616
|
return convert(Object.assign({ mode, oid: target.oid, path: vfilePath }, repo)).then((result) =>
|
|
610
617
|
emitter.emit('entry', result)
|
|
611
618
|
)
|
|
@@ -677,11 +684,11 @@ function readGitObjectAtPath (repo, root, parent, pathSegments, following) {
|
|
|
677
684
|
if (entry.path === firstPathSegment) {
|
|
678
685
|
return entry.type === 'tree'
|
|
679
686
|
? git.readTree(Object.assign({ oid: entry.oid }, repo)).then((subtree) => {
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
687
|
+
Object.assign(subtree, { dirname: path.join(parent.dirname, entry.path) })
|
|
688
|
+
return (pathSegments = pathSegments.slice(1)).length
|
|
689
|
+
? readGitObjectAtPath(repo, root, subtree, pathSegments, following)
|
|
690
|
+
: Object.assign(subtree, { type: 'tree', following }) // Q: should this create copy?
|
|
691
|
+
})
|
|
685
692
|
: entry.mode === SYMLINK_FILE_MODE
|
|
686
693
|
? readGitSymlink(repo, root, parent, entry, following)
|
|
687
694
|
: Promise.resolve(entry)
|
|
@@ -735,18 +742,18 @@ function loadComponentDescriptor (files, ref, version) {
|
|
|
735
742
|
if (!version) {
|
|
736
743
|
if (version === undefined) throw new Error(`${COMPONENT_DESC_FILENAME} is missing a version`)
|
|
737
744
|
if (version === false) throw new Error(`${COMPONENT_DESC_FILENAME} has an invalid version`)
|
|
738
|
-
version =
|
|
745
|
+
version = typeof version === 'number' ? '' + version : ''
|
|
739
746
|
} else if (version === true) {
|
|
740
747
|
version = ref.shortname.replace(PATH_SEPARATOR_RX, '-')
|
|
741
748
|
} else if (version.constructor === Object) {
|
|
742
749
|
const refname = ref.shortname
|
|
743
750
|
let matched
|
|
744
751
|
if (refname in version) {
|
|
745
|
-
matched = version[refname]
|
|
752
|
+
matched = '' + (version[refname] ?? '')
|
|
746
753
|
} else if (
|
|
747
754
|
!Object.entries(version).some(([pattern, replacement]) => {
|
|
748
|
-
const result = refname.replace(makeMatcherRx(pattern, VERSION_MATCHER_OPTS), '\0' + replacement)
|
|
749
|
-
if (result === refname) return false
|
|
755
|
+
const result = refname.replace(makeMatcherRx(pattern, VERSION_MATCHER_OPTS), '\0' + (replacement ?? ''))
|
|
756
|
+
if (result === refname) return false // no match
|
|
750
757
|
matched = result.substr(1)
|
|
751
758
|
return true
|
|
752
759
|
})
|
|
@@ -761,7 +768,7 @@ function loadComponentDescriptor (files, ref, version) {
|
|
|
761
768
|
throw new Error(`version in ${COMPONENT_DESC_FILENAME} cannot have path segments: ${version}`)
|
|
762
769
|
}
|
|
763
770
|
data.version = version
|
|
764
|
-
return camelCaseKeys(data, ['asciidoc'])
|
|
771
|
+
return camelCaseKeys(data, ['asciidoc', 'ext'])
|
|
765
772
|
}
|
|
766
773
|
|
|
767
774
|
function assignFileProperties (file, origin) {
|
|
@@ -889,9 +896,8 @@ function identifyAuthStatus (credentialManager, credentials, url) {
|
|
|
889
896
|
const status = credentialManager.status({ url })
|
|
890
897
|
if (credentials) {
|
|
891
898
|
return typeof status === 'string' && status.startsWith('requested,') ? 'auth-required' : 'auth-embedded'
|
|
892
|
-
} else if (status != null) {
|
|
893
|
-
return 'auth-required'
|
|
894
899
|
}
|
|
900
|
+
if (status != null) return 'auth-required'
|
|
895
901
|
}
|
|
896
902
|
|
|
897
903
|
/**
|
|
@@ -916,21 +922,18 @@ function generateCloneFolderName (url) {
|
|
|
916
922
|
*
|
|
917
923
|
* @param {Repository} repo - The repository on which to operate.
|
|
918
924
|
* @param {String} remoteName - The name of the remote to resolve.
|
|
919
|
-
* @returns {String} The URL of the specified remote, if defined
|
|
925
|
+
* @returns {String} The URL of the specified remote, if defined
|
|
920
926
|
*/
|
|
921
927
|
function resolveRemoteUrl (repo, remoteName) {
|
|
922
928
|
return git.getConfig(Object.assign({ path: 'remote.' + remoteName + '.url' }, repo)).then((url) => {
|
|
923
|
-
if (url)
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
}
|
|
929
|
+
if (!url) return
|
|
930
|
+
if (url.startsWith('https://') || url.startsWith('http://')) {
|
|
931
|
+
return ~url.indexOf('@') ? url.replace(URL_AUTH_CLEANER_RX, '$1') : url
|
|
932
|
+
}
|
|
933
|
+
if (url.startsWith('git@')) return 'https://' + url.substr(4).replace(':', '/')
|
|
934
|
+
if (url.startsWith('ssh://')) {
|
|
935
|
+
return 'https://' + url.substr(url.indexOf('@') + 1 || 6).replace(URL_PORT_CLEANER_RX, '$1')
|
|
931
936
|
}
|
|
932
|
-
url = posixify ? 'file:///' + posixify(repo.dir) : 'file://' + repo.dir
|
|
933
|
-
return ~url.indexOf(' ') ? url.replace(SPACE_RX, '%20') : url
|
|
934
937
|
})
|
|
935
938
|
}
|
|
936
939
|
|
|
@@ -958,7 +961,7 @@ function loadGitPlugins (gitConfig, networkConfig, startDir) {
|
|
|
958
961
|
if (typeof credentialManager.configure === 'function') {
|
|
959
962
|
credentialManager.configure({ config: gitConfig.credentials, startDir })
|
|
960
963
|
}
|
|
961
|
-
if (typeof credentialManager.status !== 'function') Object.assign(credentialManager, { status
|
|
964
|
+
if (typeof credentialManager.status !== 'function') Object.assign(credentialManager, { status: invariably.void })
|
|
962
965
|
} else {
|
|
963
966
|
credentialManager = new GitCredentialManagerStore().configure({ config: gitConfig.credentials, startDir })
|
|
964
967
|
}
|
|
@@ -1067,31 +1070,29 @@ function resolveRepositoryFromWorktree (repo) {
|
|
|
1067
1070
|
function findWorktrees (repo, patterns) {
|
|
1068
1071
|
if (!patterns.length) return new Map()
|
|
1069
1072
|
const mainWorktree =
|
|
1070
|
-
patterns[0] === '.' && (patterns = patterns.slice(1))
|
|
1073
|
+
patterns[0] === '.' && (patterns = patterns.slice(1)) && !repo.noCheckout
|
|
1071
1074
|
? getCurrentBranchName(repo).then((branch) => branch && [branch, { head: repo.dir, name: '.' }])
|
|
1072
1075
|
: Promise.resolve()
|
|
1073
|
-
|
|
1076
|
+
if (!patterns.length) return mainWorktree.then((entry) => new Map(entry && [entry]))
|
|
1077
|
+
const worktreesDir = ospath.join(repo.dir, repo.dir === repo.gitdir ? '' : '.git', 'worktrees')
|
|
1074
1078
|
const patternCache = repo.cache[REF_PATTERN_CACHE_KEY]
|
|
1075
|
-
return
|
|
1076
|
-
worktreesDir
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
.
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
.readFile(ospath.join(gitdir, 'gitdir'), 'utf8')
|
|
1088
|
-
.then((contents) => [branch, { head: ospath.dirname(contents.trimEnd()), name: worktreeName }])
|
|
1089
|
-
)
|
|
1090
|
-
})
|
|
1079
|
+
return fsp
|
|
1080
|
+
.readdir(worktreesDir)
|
|
1081
|
+
.then((worktreeNames) => filterRefs(worktreeNames, patterns, patternCache), invariably.emptyArray)
|
|
1082
|
+
.then((worktreeNames) =>
|
|
1083
|
+
Promise.all(
|
|
1084
|
+
worktreeNames.map((worktreeName) => {
|
|
1085
|
+
const gitdir = ospath.resolve(worktreesDir, worktreeName)
|
|
1086
|
+
// NOTE branch name defaults to worktree name if HEAD is detached
|
|
1087
|
+
return getCurrentBranchName(Object.assign({}, repo, { gitdir })).then((branch = worktreeName) =>
|
|
1088
|
+
fsp
|
|
1089
|
+
.readFile(ospath.join(gitdir, 'gitdir'), 'utf8')
|
|
1090
|
+
.then((contents) => [branch, { head: ospath.dirname(contents.trimEnd()), name: worktreeName }])
|
|
1091
1091
|
)
|
|
1092
|
-
)
|
|
1093
|
-
|
|
1094
|
-
|
|
1092
|
+
})
|
|
1093
|
+
)
|
|
1094
|
+
)
|
|
1095
|
+
.then((entries) => mainWorktree.then((main) => (main ? new Map(entries).set(main[0], main[1]) : new Map(entries))))
|
|
1095
1096
|
}
|
|
1096
1097
|
|
|
1097
1098
|
async function gracefulPromiseAllWithLimit (tasks, limit = Infinity) {
|
package/lib/compute-origin.js
CHANGED
|
@@ -24,7 +24,7 @@ function computeOrigin (url, authStatus, gitdir, ref, startPath, worktreePath =
|
|
|
24
24
|
if (authStatus) origin.private = authStatus
|
|
25
25
|
if (url) origin.webUrl = removeGitSuffix(url)
|
|
26
26
|
if (editUrl === true) {
|
|
27
|
-
const match = url
|
|
27
|
+
const match = url?.match(HOSTED_GIT_REPO_RX)
|
|
28
28
|
if (match) {
|
|
29
29
|
const host = match[1]
|
|
30
30
|
let action = 'blob'
|
|
@@ -33,8 +33,9 @@ function computeOrigin (url, authStatus, gitdir, ref, startPath, worktreePath =
|
|
|
33
33
|
category = 'f'
|
|
34
34
|
} else if (host === 'bitbucket.org') {
|
|
35
35
|
action = 'src'
|
|
36
|
-
} else
|
|
37
|
-
action = 'edit'
|
|
36
|
+
} else {
|
|
37
|
+
if (reftype === 'branch') action = 'edit'
|
|
38
|
+
if (host.startsWith('gitlab.')) action = '-/' + action
|
|
38
39
|
}
|
|
39
40
|
origin.editUrlPattern = 'https://' + path.join(match[1], match[2], action, refname, category, startPath, '%s')
|
|
40
41
|
}
|
package/lib/filter-refs.js
CHANGED
|
@@ -11,10 +11,9 @@ function compileRx (pattern, opts) {
|
|
|
11
11
|
return Object.defineProperty(rx, 'pattern', { value: pattern })
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
function createMatcher (patterns, cache,
|
|
14
|
+
function createMatcher (patterns, cache = Object.assign(new Map(), { braces: new Map() })) {
|
|
15
15
|
const rxs = patterns.map(
|
|
16
|
-
(pattern) =>
|
|
17
|
-
cache.get(pattern) || cache.set(pattern, compileRx(pattern, opts || (opts = getMatcherOpts(cache)))).get(pattern)
|
|
16
|
+
(pattern) => cache.get(pattern) || cache.set(pattern, compileRx(pattern, getMatcherOpts(cache))).get(pattern)
|
|
18
17
|
)
|
|
19
18
|
if (rxs[0].negated) rxs.unshift(MATCH_ALL_RX)
|
|
20
19
|
return (candidate, onMatch) => {
|
|
@@ -39,7 +38,7 @@ function createMatcher (patterns, cache, opts) {
|
|
|
39
38
|
}
|
|
40
39
|
}
|
|
41
40
|
|
|
42
|
-
function filterRefs (candidates, patterns, cache
|
|
41
|
+
function filterRefs (candidates, patterns, cache, onMatch) {
|
|
43
42
|
const match = createMatcher(patterns, cache)
|
|
44
43
|
return candidates.reduce((accum, candidate) => {
|
|
45
44
|
if ((candidate = match(candidate, onMatch))) accum.push(candidate)
|
|
@@ -16,11 +16,11 @@ function resolvePathGlobs (base, patterns, listDirents, retrievePath, tree = { p
|
|
|
16
16
|
if (resolvedPaths.length) {
|
|
17
17
|
const rx = makeMatcherRx(pattern.substr(1), MATCHER_OPTS)
|
|
18
18
|
return resolvedPaths.filter((it) => !rx.test(it))
|
|
19
|
-
} else {
|
|
20
|
-
return resolvedPaths
|
|
21
19
|
}
|
|
20
|
+
return resolvedPaths
|
|
22
21
|
})
|
|
23
|
-
}
|
|
22
|
+
}
|
|
23
|
+
if (RX_MAGIC_DETECTOR.test(pattern)) {
|
|
24
24
|
return glob(base, pattern.split('/'), listDirents, retrievePath, tree).then((nestedPaths) =>
|
|
25
25
|
paths.then((resolvedPaths) => [...resolvedPaths, ...nestedPaths])
|
|
26
26
|
)
|
|
@@ -62,35 +62,36 @@ async function glob (base, patternSegments, listDirents, retrievePath, { oid, pa
|
|
|
62
62
|
dirent.isDirectory() && isMatch(dirent.name)
|
|
63
63
|
? patternSegments.length
|
|
64
64
|
? glob(base, patternSegments, listDirents, retrievePath, {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
65
|
+
oid: dirent.oid,
|
|
66
|
+
path: joinPath(path, dirent.name),
|
|
67
|
+
globbed: true,
|
|
68
|
+
})
|
|
69
69
|
: joinPath(path, dirent.name)
|
|
70
70
|
: []
|
|
71
71
|
)
|
|
72
72
|
)
|
|
73
73
|
)
|
|
74
74
|
return explicit ? [...[...explicit].map((it) => joinPath(path, it)), ...discovered] : discovered
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
return [joinPath(path, patternSegment)]
|
|
89
|
-
} else if (globbed) {
|
|
90
|
-
return (await retrievePath(base, { oid, path }, patternSegment)) ? [joinPath(path, patternSegment)] : []
|
|
75
|
+
}
|
|
76
|
+
const [magicBase, nextSegment] = extractMagicBase(patternSegments, patternSegment)
|
|
77
|
+
patternSegment = magicBase
|
|
78
|
+
if (nextSegment) {
|
|
79
|
+
const obj = await retrievePath(base, { oid, path }, patternSegment)
|
|
80
|
+
if (obj) {
|
|
81
|
+
return glob(base, patternSegments, listDirents, retrievePath, {
|
|
82
|
+
oid: obj.oid,
|
|
83
|
+
path: joinPath(path, patternSegment),
|
|
84
|
+
})
|
|
85
|
+
}
|
|
86
|
+
if ((patternSegment += '/' + patternSegments.join('/')).indexOf('{')) {
|
|
87
|
+
return expandBraces(patternSegment).map((it) => joinPath(path, it))
|
|
91
88
|
}
|
|
92
89
|
return [joinPath(path, patternSegment)]
|
|
93
90
|
}
|
|
91
|
+
if (globbed) {
|
|
92
|
+
return (await retrievePath(base, { oid, path }, patternSegment)) ? [joinPath(path, patternSegment)] : []
|
|
93
|
+
}
|
|
94
|
+
return [joinPath(path, patternSegment)]
|
|
94
95
|
}
|
|
95
96
|
|
|
96
97
|
function extractMagicBase (patternSegments, base) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@antora/content-aggregator",
|
|
3
|
-
"version": "3.2.0-alpha.
|
|
3
|
+
"version": "3.2.0-alpha.9",
|
|
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)",
|
|
@@ -11,7 +11,11 @@
|
|
|
11
11
|
"Balachandran Sivakumar <balachandran@balachandran.org>"
|
|
12
12
|
],
|
|
13
13
|
"homepage": "https://antora.org",
|
|
14
|
-
"repository":
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "git+https://gitlab.com/antora/antora.git",
|
|
17
|
+
"directory": "packages/content-aggregator"
|
|
18
|
+
},
|
|
15
19
|
"bugs": {
|
|
16
20
|
"url": "https://gitlab.com/antora/antora/issues"
|
|
17
21
|
},
|
|
@@ -28,9 +32,9 @@
|
|
|
28
32
|
"#constants": "./lib/constants.js"
|
|
29
33
|
},
|
|
30
34
|
"dependencies": {
|
|
31
|
-
"@antora/expand-path-helper": "~
|
|
32
|
-
"@antora/logger": "3.2.0-alpha.
|
|
33
|
-
"@antora/user-require-helper": "~
|
|
35
|
+
"@antora/expand-path-helper": "~3.0",
|
|
36
|
+
"@antora/logger": "3.2.0-alpha.9",
|
|
37
|
+
"@antora/user-require-helper": "~3.0",
|
|
34
38
|
"braces": "~3.0",
|
|
35
39
|
"cache-directory": "~2.0",
|
|
36
40
|
"fast-glob": "~3.3",
|