@antora/content-aggregator 3.1.14 → 3.2.0-alpha.10
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 +184 -116
- package/lib/compute-origin.js +6 -4
- package/lib/decode-uint8-array.js +1 -1
- package/lib/filter-refs.js +17 -9
- package/lib/git-credential-manager-store.js +5 -5
- package/lib/git.js +8 -1
- package/lib/matcher.js +1 -1
- package/lib/posixify.js +1 -1
- package/lib/resolve-path-globs.js +1 -1
- package/package.json +7 -6
package/lib/aggregate-content.js
CHANGED
|
@@ -1,32 +1,32 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const computeOrigin = require('./compute-origin')
|
|
4
|
-
const { createHash } = require('crypto')
|
|
4
|
+
const { createHash } = require('node:crypto')
|
|
5
5
|
const createGitHttpPlugin = require('./git-plugin-http')
|
|
6
6
|
const decodeUint8Array = require('./decode-uint8-array')
|
|
7
7
|
const deepClone = require('./deep-clone')
|
|
8
|
-
const EventEmitter = require('events')
|
|
8
|
+
const EventEmitter = require('node:events')
|
|
9
9
|
const expandPath = require('@antora/expand-path-helper')
|
|
10
10
|
const File = require('./file')
|
|
11
11
|
const filterRefs = require('./filter-refs')
|
|
12
|
-
const fs = require('fs')
|
|
12
|
+
const fs = require('node:fs')
|
|
13
13
|
const { promises: fsp } = fs
|
|
14
14
|
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
18
|
const { globStream } = require('fast-glob')
|
|
19
|
-
const { inspect } = require('util')
|
|
19
|
+
const { inspect } = require('node:util')
|
|
20
20
|
const invariably = require('./invariably')
|
|
21
21
|
const logger = require('./logger')
|
|
22
22
|
const { makeMatcherRx, versionMatcherOpts: VERSION_MATCHER_OPTS } = require('./matcher')
|
|
23
23
|
const MultiProgress = require('multi-progress') // calls require('progress') as a peer dependencies
|
|
24
|
-
const ospath = require('path')
|
|
24
|
+
const ospath = require('node:path')
|
|
25
25
|
const { posix: path } = ospath
|
|
26
26
|
const posixify = require('./posixify')
|
|
27
27
|
const removeGitSuffix = require('./remove-git-suffix')
|
|
28
28
|
const { fs: resolvePathGlobsFs, git: resolvePathGlobsGit } = require('./resolve-path-globs')
|
|
29
|
-
const { pipeline, Writable } = require('stream')
|
|
29
|
+
const { pipeline, Writable } = require('node:stream')
|
|
30
30
|
const forEach = (write) => new Writable({ objectMode: true, write })
|
|
31
31
|
const userRequire = require('@antora/user-require-helper')
|
|
32
32
|
const yaml = require('js-yaml')
|
|
@@ -102,7 +102,8 @@ function aggregateContent (playbook) {
|
|
|
102
102
|
}, new Map())
|
|
103
103
|
const progress = quiet ? undefined : createProgress(sourcesByUrl.keys(), process.stdout)
|
|
104
104
|
const refPatternCache = Object.assign(new Map(), { braces: new Map() })
|
|
105
|
-
const
|
|
105
|
+
const fetchConfig = { always: fetch, depth: Math.max(0, gitConfig.fetchDepth ?? 1) }
|
|
106
|
+
const loadOpts = { cacheDir, fetch: fetchConfig, gitPlugins, progress, startDir, refPatternCache }
|
|
106
107
|
return collectFiles(sourcesByUrl, loadOpts, concurrency).then(buildAggregate, (err) => {
|
|
107
108
|
progress?.terminate()
|
|
108
109
|
throw err
|
|
@@ -110,11 +111,11 @@ function aggregateContent (playbook) {
|
|
|
110
111
|
})
|
|
111
112
|
}
|
|
112
113
|
|
|
113
|
-
async function collectFiles (sourcesByUrl, loadOpts, concurrency, fetchedUrls) {
|
|
114
|
+
async function collectFiles (sourcesByUrl, loadOpts, concurrency, fetchedUrls = []) {
|
|
114
115
|
const loadTasks = [...sourcesByUrl.entries()].map(([url, sources]) => {
|
|
115
116
|
const loadOptsForUrl = Object.assign({}, loadOpts)
|
|
116
|
-
if (loadOpts.fetch && fetchedUrls
|
|
117
|
-
if (tagsSpecified(sources)) loadOptsForUrl.
|
|
117
|
+
if (loadOpts.fetch.always && fetchedUrls.length && ~fetchedUrls.indexOf(url)) loadOptsForUrl.fetch.always = false
|
|
118
|
+
if (tagsSpecified(sources)) loadOptsForUrl.fetch.tags = true
|
|
118
119
|
return loadRepository.bind(null, url, loadOptsForUrl, { url, sources })
|
|
119
120
|
})
|
|
120
121
|
return gracefulPromiseAllWithLimit(loadTasks, concurrency.fetch).then(([results, rejections]) => {
|
|
@@ -131,7 +132,7 @@ async function collectFiles (sourcesByUrl, loadOpts, concurrency, fetchedUrls) {
|
|
|
131
132
|
}
|
|
132
133
|
return Promise.all(
|
|
133
134
|
results.map(({ repo, authStatus, sources }) =>
|
|
134
|
-
selectStartPathsForRepository(repo,
|
|
135
|
+
selectStartPathsForRepository(repo, sources).then((startPaths) =>
|
|
135
136
|
collectFilesFromStartPaths.bind(null, startPaths, repo, authStatus)
|
|
136
137
|
)
|
|
137
138
|
)
|
|
@@ -163,7 +164,7 @@ async function loadRepository (url, opts, result = {}) {
|
|
|
163
164
|
if (~url.indexOf(':') && GIT_URI_DETECTOR_RX.test(url)) {
|
|
164
165
|
let credentials, displayUrl
|
|
165
166
|
;({ displayUrl, url, credentials } = extractCredentials(url))
|
|
166
|
-
const { cacheDir, fetch,
|
|
167
|
+
const { cacheDir, fetch, gitPlugins, progress } = opts
|
|
167
168
|
dir = ospath.join(cacheDir, generateCloneFolderName(displayUrl))
|
|
168
169
|
// NOTE the presence of the url property on the repo object implies the repository is remote
|
|
169
170
|
repo = { cache, dir, fs, gitdir: dir, noCheckout: true, url }
|
|
@@ -171,9 +172,9 @@ async function loadRepository (url, opts, result = {}) {
|
|
|
171
172
|
const validStateFile = ospath.join(dir, VALID_STATE_FILENAME)
|
|
172
173
|
try {
|
|
173
174
|
await fsp.access(validStateFile)
|
|
174
|
-
if (fetch) {
|
|
175
|
+
if (fetch.always) {
|
|
175
176
|
await fsp.unlink(validStateFile)
|
|
176
|
-
const fetchOpts = buildFetchOptions(repo, progress, displayUrl, credentials, gitPlugins,
|
|
177
|
+
const fetchOpts = buildFetchOptions(repo, progress, displayUrl, credentials, gitPlugins, fetch, 'fetch')
|
|
177
178
|
await git
|
|
178
179
|
.fetch(fetchOpts)
|
|
179
180
|
.then(() => {
|
|
@@ -193,7 +194,7 @@ async function loadRepository (url, opts, result = {}) {
|
|
|
193
194
|
} catch (gitErr) {
|
|
194
195
|
await fsp['rm' in fsp ? 'rm' : 'rmdir'](dir, { recursive: true, force: true })
|
|
195
196
|
if (gitErr.rethrow) throw transformGitCloneError(gitErr, displayUrl)
|
|
196
|
-
const fetchOpts = buildFetchOptions(repo, progress, displayUrl, credentials, gitPlugins,
|
|
197
|
+
const fetchOpts = buildFetchOptions(repo, progress, displayUrl, credentials, gitPlugins, fetch, 'clone')
|
|
197
198
|
await git
|
|
198
199
|
.clone(fetchOpts)
|
|
199
200
|
.then(() => git.resolveRef(Object.assign({ ref: 'HEAD', depth: 1 }, repo)))
|
|
@@ -210,8 +211,15 @@ async function loadRepository (url, opts, result = {}) {
|
|
|
210
211
|
.then(() => fetchOpts.onProgress?.finish())
|
|
211
212
|
}
|
|
212
213
|
} else if (await isDirectory((dir = expandPath(url, { dot: opts.startDir })))) {
|
|
213
|
-
const
|
|
214
|
-
|
|
214
|
+
const dotgit = ospath.join(dir, '.git')
|
|
215
|
+
const dotgitStat = await fsp.stat(dotgit).catch(() => ({ isFile: invariably.false, isDirectory: invariably.false }))
|
|
216
|
+
if (dotgitStat.isDirectory()) {
|
|
217
|
+
repo = { cache, dir, fs, gitdir: dotgit }
|
|
218
|
+
} else if (dotgitStat.isFile()) {
|
|
219
|
+
repo = await resolveRepositoryFromWorktree({ cache, dir, fs, gitdir: dotgit })
|
|
220
|
+
} else {
|
|
221
|
+
repo = { cache, dir, fs, gitdir: dir, noCheckout: true }
|
|
222
|
+
}
|
|
215
223
|
try {
|
|
216
224
|
await git.resolveRef(Object.assign({ ref: 'HEAD', depth: 1 }, repo))
|
|
217
225
|
} catch {
|
|
@@ -241,7 +249,7 @@ function extractCredentials (url) {
|
|
|
241
249
|
return { displayUrl: url, url }
|
|
242
250
|
}
|
|
243
251
|
|
|
244
|
-
async function selectStartPathsForRepository (repo,
|
|
252
|
+
async function selectStartPathsForRepository (repo, sources) {
|
|
245
253
|
const startPaths = []
|
|
246
254
|
const originUrls = {}
|
|
247
255
|
for (const source of sources) {
|
|
@@ -290,6 +298,7 @@ async function selectReferences (source, repo, remote) {
|
|
|
290
298
|
const isBare = managed || repo.noCheckout
|
|
291
299
|
const patternCache = repo.cache[REF_PATTERN_CACHE_KEY]
|
|
292
300
|
const noWorktree = managed ? undefined : false
|
|
301
|
+
const isLinkedWorktree = repo.worktree?.name
|
|
293
302
|
const refs = new Map()
|
|
294
303
|
if (
|
|
295
304
|
tagPatterns &&
|
|
@@ -305,48 +314,63 @@ async function selectReferences (source, repo, remote) {
|
|
|
305
314
|
}
|
|
306
315
|
}
|
|
307
316
|
}
|
|
308
|
-
if (
|
|
309
|
-
|
|
310
|
-
|
|
317
|
+
if (
|
|
318
|
+
!branchPatterns ||
|
|
319
|
+
!(branchPatterns = Array.isArray(branchPatterns)
|
|
320
|
+
? branchPatterns.map((pattern) => String(pattern))
|
|
321
|
+
: splitRefPatterns(String(branchPatterns))).length
|
|
322
|
+
) {
|
|
323
|
+
return [...refs.values()]
|
|
324
|
+
}
|
|
325
|
+
let useWorktree = false
|
|
326
|
+
if (!managed && (useWorktree = {})) {
|
|
311
327
|
if (worktreePatterns === '.') {
|
|
312
|
-
|
|
328
|
+
isLinkedWorktree ? (useWorktree.linked = isLinkedWorktree) : isBare || (useWorktree.main = true)
|
|
329
|
+
worktreePatterns = []
|
|
330
|
+
} else if (!worktreePatterns) {
|
|
331
|
+
worktreePatterns = []
|
|
313
332
|
} else if (worktreePatterns === true) {
|
|
314
|
-
|
|
333
|
+
if (!isBare) useWorktree.main = true
|
|
334
|
+
// NOTE if we don't start at a linked worktree, linked worktree cannot be current worktree
|
|
335
|
+
if (isLinkedWorktree) useWorktree.linked = isLinkedWorktree
|
|
336
|
+
worktreePatterns = ['*']
|
|
337
|
+
} else if (worktreePatterns === '/.') {
|
|
338
|
+
if (!isBare) useWorktree.main = true
|
|
339
|
+
worktreePatterns = []
|
|
315
340
|
} else {
|
|
316
|
-
worktreePatterns =
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
341
|
+
worktreePatterns = (
|
|
342
|
+
Array.isArray(worktreePatterns)
|
|
343
|
+
? worktreePatterns.map((pattern) => String(pattern))
|
|
344
|
+
: splitRefPatterns(String(worktreePatterns))
|
|
345
|
+
).reduce((accum, it) => {
|
|
346
|
+
if (it === '/.') return (isBare || (useWorktree.main = true)) && accum
|
|
347
|
+
if (it === '.') {
|
|
348
|
+
isLinkedWorktree ? (useWorktree.linked = isLinkedWorktree) : isBare || (useWorktree.main = true)
|
|
349
|
+
} else {
|
|
350
|
+
accum.push(it)
|
|
351
|
+
}
|
|
352
|
+
return accum
|
|
353
|
+
}, [])
|
|
322
354
|
}
|
|
323
|
-
|
|
324
|
-
worktreePatterns = []
|
|
355
|
+
if (!(useWorktree.main || useWorktree.linked)) useWorktree = false
|
|
325
356
|
}
|
|
326
|
-
|
|
327
|
-
if (
|
|
328
|
-
const currentBranch = await getCurrentBranchName(repo, remote)
|
|
329
|
-
if (currentBranch) {
|
|
330
|
-
branchPatterns = [currentBranch]
|
|
331
|
-
} else if (isBare) {
|
|
332
|
-
return [...refs.values()]
|
|
333
|
-
} else {
|
|
334
|
-
// NOTE current branch is undefined when HEAD is detached
|
|
335
|
-
const head = usePrimaryWorktree ? repo.dir : noWorktree
|
|
336
|
-
refs.set('HEAD', { shortname: 'HEAD', fullname: 'HEAD', type: 'branch', detached: true, head })
|
|
337
|
-
return [...refs.values()]
|
|
338
|
-
}
|
|
339
|
-
} else if (
|
|
340
|
-
(branchPatterns = Array.isArray(branchPatterns)
|
|
341
|
-
? branchPatterns.map((pattern) => String(pattern))
|
|
342
|
-
: splitRefPatterns(branchPatternsString)).length
|
|
343
|
-
) {
|
|
357
|
+
let currentBranch
|
|
358
|
+
if (!isLinkedWorktree) {
|
|
344
359
|
let headBranchIdx
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
if (
|
|
349
|
-
|
|
360
|
+
if (branchPatterns.length === 1 && (branchPatterns[0] === 'HEAD' || branchPatterns[0] === '.')) {
|
|
361
|
+
if ((currentBranch = await getCurrentBranchName(repo, remote).then((branch) => branch ?? false))) {
|
|
362
|
+
branchPatterns = [currentBranch]
|
|
363
|
+
} else if (isBare) {
|
|
364
|
+
return [...refs.values()]
|
|
365
|
+
} else {
|
|
366
|
+
// NOTE current branch is undefined when HEAD is detached
|
|
367
|
+
const head = useWorktree.main ? repo.dir : noWorktree
|
|
368
|
+
refs.set('HEAD', { shortname: 'HEAD', fullname: 'HEAD', type: 'branch', detached: true, head })
|
|
369
|
+
return [...refs.values()]
|
|
370
|
+
}
|
|
371
|
+
} else if (~(headBranchIdx = branchPatterns.indexOf('HEAD')) || ~(headBranchIdx = branchPatterns.indexOf('.'))) {
|
|
372
|
+
// NOTE we can assume at least two entries if HEAD or . are present
|
|
373
|
+
if ((currentBranch = await getCurrentBranchName(repo, remote).then((branch) => branch ?? false))) {
|
|
350
374
|
if (~branchPatterns.indexOf(currentBranch)) {
|
|
351
375
|
branchPatterns.splice(headBranchIdx, 1)
|
|
352
376
|
} else {
|
|
@@ -355,14 +379,12 @@ async function selectReferences (source, repo, remote) {
|
|
|
355
379
|
} else if (isBare) {
|
|
356
380
|
branchPatterns.splice(headBranchIdx, 1)
|
|
357
381
|
} else {
|
|
358
|
-
const head =
|
|
382
|
+
const head = useWorktree.main ? repo.dir : noWorktree
|
|
359
383
|
// NOTE current branch is undefined when HEAD is detached
|
|
360
384
|
refs.set('HEAD', { shortname: 'HEAD', fullname: 'HEAD', type: 'branch', detached: true, head })
|
|
361
385
|
branchPatterns.splice(headBranchIdx, 1)
|
|
362
386
|
}
|
|
363
387
|
}
|
|
364
|
-
} else {
|
|
365
|
-
return [...refs.values()]
|
|
366
388
|
}
|
|
367
389
|
// NOTE isomorphic-git includes HEAD in list of remote branches (see https://isomorphic-git.org/docs/listBranches)
|
|
368
390
|
const remoteBranches = remote
|
|
@@ -374,22 +396,42 @@ async function selectReferences (source, repo, remote) {
|
|
|
374
396
|
refs.set(shortname, { shortname, fullname, type: 'branch', remote, head: noWorktree })
|
|
375
397
|
}
|
|
376
398
|
}
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
399
|
+
if (!managed) {
|
|
400
|
+
const localBranches = await git.listBranches(repo).then((branches) => {
|
|
401
|
+
if (branches.length || isBare) return branches
|
|
402
|
+
if (currentBranch != null) return [currentBranch]
|
|
403
|
+
return getCurrentBranchName(repo).then((branch) => (branch ? [branch] : []))
|
|
404
|
+
})
|
|
405
|
+
const worktrees = await findWorktrees(repo, worktreePatterns, useWorktree)
|
|
406
|
+
let onMatch
|
|
407
|
+
if ((useWorktree || worktreePatterns.length) && worktrees.size) {
|
|
408
|
+
const headNames = new Map()
|
|
409
|
+
worktrees.forEach(({ name, symbolicNames }, shortname) => {
|
|
410
|
+
if (name) {
|
|
411
|
+
const headName = 'HEAD@' + name
|
|
412
|
+
localBranches.push(headName)
|
|
413
|
+
headNames.set(headName, shortname)
|
|
414
|
+
}
|
|
415
|
+
if (symbolicNames) {
|
|
416
|
+
for (const symbolicName of symbolicNames) {
|
|
417
|
+
const symbolicHeadName = symbolicName === 'HEAD' ? symbolicName : 'HEAD@' + symbolicName
|
|
418
|
+
localBranches.push(symbolicHeadName)
|
|
419
|
+
headNames.set(symbolicHeadName, shortname)
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
})
|
|
423
|
+
onMatch = (candidate, { pattern }) => {
|
|
424
|
+
const shortname = headNames.get(candidate)
|
|
425
|
+
if (!shortname) return candidate
|
|
426
|
+
if (pattern === 'HEAD' || pattern.startsWith('HEAD@')) return shortname
|
|
385
427
|
}
|
|
386
428
|
}
|
|
387
|
-
} else if (!managed || !remoteBranches.length) {
|
|
388
|
-
const localBranches = await git.listBranches(repo)
|
|
389
429
|
if (localBranches.length) {
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
refs.
|
|
430
|
+
const preferRemote = isBare && remoteBranches.length > 0
|
|
431
|
+
for (const shortname of filterRefs(localBranches, branchPatterns, patternCache, onMatch)) {
|
|
432
|
+
if (preferRemote && refs.has(shortname)) continue
|
|
433
|
+
const head = (worktrees.get(shortname) || { head: false }).head
|
|
434
|
+
refs.set(shortname, { shortname, fullname: 'heads/' + shortname, type: 'branch', head })
|
|
393
435
|
}
|
|
394
436
|
}
|
|
395
437
|
}
|
|
@@ -400,15 +442,13 @@ async function selectReferences (source, repo, remote) {
|
|
|
400
442
|
* Returns the current branch name or undefined if the HEAD is detached.
|
|
401
443
|
*/
|
|
402
444
|
function getCurrentBranchName (repo, remote) {
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
}
|
|
411
|
-
return refPromise.then((ref) => (ref.startsWith('refs/') ? ref.replace(SHORTEN_REF_RX, '') : undefined))
|
|
445
|
+
return (
|
|
446
|
+
remote && repo.noCheckout
|
|
447
|
+
? git
|
|
448
|
+
.resolveRef(Object.assign({ ref: 'refs/remotes/' + remote + '/HEAD', depth: 2 }, repo))
|
|
449
|
+
.catch(() => git.resolveRef(Object.assign({ ref: 'HEAD', depth: 2 }, repo)))
|
|
450
|
+
: git.resolveRef(Object.assign({ ref: 'HEAD', depth: 2 }, repo))
|
|
451
|
+
).then((ref) => (ref.startsWith('refs/') ? ref.replace(SHORTEN_REF_RX, '') : undefined))
|
|
412
452
|
}
|
|
413
453
|
|
|
414
454
|
async function selectStartPaths (source, repo, ref) {
|
|
@@ -752,7 +792,7 @@ function loadComponentDescriptor (files, ref, version) {
|
|
|
752
792
|
throw new Error(`version in ${COMPONENT_DESC_FILENAME} cannot have path segments: ${version}`)
|
|
753
793
|
}
|
|
754
794
|
data.version = version
|
|
755
|
-
return camelCaseKeys(data, ['asciidoc'])
|
|
795
|
+
return camelCaseKeys(data, ['asciidoc', 'ext'])
|
|
756
796
|
}
|
|
757
797
|
|
|
758
798
|
function assignFileProperties (file, origin) {
|
|
@@ -769,18 +809,20 @@ function assignFileProperties (file, origin) {
|
|
|
769
809
|
return file
|
|
770
810
|
}
|
|
771
811
|
|
|
772
|
-
function buildFetchOptions (repo, progress, displayUrl, credentialsFromUrl, gitPlugins,
|
|
812
|
+
function buildFetchOptions (repo, progress, displayUrl, credentialsFromUrl, gitPlugins, fetch, operation) {
|
|
773
813
|
const { credentialManager, http, urlRouter } = gitPlugins
|
|
814
|
+
const corsProxy = false
|
|
815
|
+
const depth = fetch.depth || undefined
|
|
774
816
|
const onAuth = resolveCredentials.bind(credentialManager, new Map().set(undefined, credentialsFromUrl))
|
|
775
817
|
const onAuthFailure = onAuth
|
|
776
818
|
const onAuthSuccess = (url) => credentialManager.approved({ url })
|
|
777
|
-
const opts = Object.assign({ corsProxy
|
|
819
|
+
const opts = Object.assign({ corsProxy, depth, http, onAuth, onAuthFailure, onAuthSuccess }, repo)
|
|
778
820
|
if (urlRouter) opts.url = urlRouter.ensureGitSuffix(opts.url)
|
|
779
821
|
if (progress) opts.onProgress = createProgressListener(progress, displayUrl, operation)
|
|
780
822
|
if (operation === 'fetch') {
|
|
781
823
|
opts.prune = true
|
|
782
|
-
if (
|
|
783
|
-
} else if (!
|
|
824
|
+
if (fetch.tags) opts.tags = opts.pruneTags = true
|
|
825
|
+
} else if (!fetch.tags) {
|
|
784
826
|
opts.noTags = true
|
|
785
827
|
}
|
|
786
828
|
return opts
|
|
@@ -875,7 +917,11 @@ function resolveCredentials (credentialsFromUrlHolder, url, auth) {
|
|
|
875
917
|
}
|
|
876
918
|
|
|
877
919
|
function identifyAuthStatus (credentialManager, credentials, url) {
|
|
878
|
-
|
|
920
|
+
const status = credentialManager.status({ url })
|
|
921
|
+
if (credentials) {
|
|
922
|
+
return typeof status === 'string' && status.startsWith('requested,') ? 'auth-required' : 'auth-embedded'
|
|
923
|
+
}
|
|
924
|
+
if (status != null) return 'auth-required'
|
|
879
925
|
}
|
|
880
926
|
|
|
881
927
|
/**
|
|
@@ -1006,7 +1052,7 @@ function transformGitCloneError (err, displayUrl, authRequested) {
|
|
|
1006
1052
|
}
|
|
1007
1053
|
|
|
1008
1054
|
function splitRefPatterns (str) {
|
|
1009
|
-
return ~str.indexOf('{') ?
|
|
1055
|
+
return str.split(~str.indexOf('{') ? VENTILATED_CSV_RX : CSV_RX)
|
|
1010
1056
|
}
|
|
1011
1057
|
|
|
1012
1058
|
function camelCaseKeys (o, stopPaths = [], p = '') {
|
|
@@ -1029,38 +1075,60 @@ function coerceToString (value) {
|
|
|
1029
1075
|
return value == null ? '' : String(value)
|
|
1030
1076
|
}
|
|
1031
1077
|
|
|
1032
|
-
function
|
|
1033
|
-
|
|
1034
|
-
|
|
1078
|
+
function resolveRepositoryFromWorktree (repo) {
|
|
1079
|
+
return fsp
|
|
1080
|
+
.readFile(repo.gitdir, 'utf8')
|
|
1081
|
+
.then((contents) => contents.substr(8).trimEnd())
|
|
1082
|
+
.then((worktreeGitdir) =>
|
|
1083
|
+
fsp.readFile(ospath.join(worktreeGitdir, 'commondir'), 'utf8').then(
|
|
1084
|
+
(contents) => {
|
|
1085
|
+
const gitdir = ospath.join(worktreeGitdir, contents.trimEnd())
|
|
1086
|
+
const dir = ospath.basename(gitdir) === '.git' ? ospath.dirname(gitdir) : gitdir
|
|
1087
|
+
const name = ospath.basename(worktreeGitdir)
|
|
1088
|
+
return Object.assign(repo, { dir, gitdir, worktree: { gitdir: worktreeGitdir, name } })
|
|
1089
|
+
},
|
|
1090
|
+
() => repo
|
|
1091
|
+
)
|
|
1092
|
+
)
|
|
1093
|
+
}
|
|
1094
|
+
|
|
1095
|
+
function findWorktrees (repo, patterns, useWorktree) {
|
|
1096
|
+
const useLinkedWorktree = !!useWorktree.linked
|
|
1097
|
+
const mainWorktree = useWorktree.main
|
|
1098
|
+
? getCurrentBranchName(repo).then((branch) => {
|
|
1099
|
+
if (!branch) return
|
|
1100
|
+
return [branch, { head: repo.dir, name: undefined, symbolicNames: useLinkedWorktree ? ['/.'] : ['/.', '.'] }]
|
|
1101
|
+
})
|
|
1102
|
+
: Promise.resolve()
|
|
1103
|
+
if (!(useLinkedWorktree || patterns.length)) return mainWorktree.then((entry) => new Map(entry && [entry]))
|
|
1104
|
+
const worktreesDir = ospath.join(repo.dir, repo.dir === repo.gitdir ? '' : '.git', 'worktrees')
|
|
1035
1105
|
const patternCache = repo.cache[REF_PATTERN_CACHE_KEY]
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
.
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
: new Map()
|
|
1106
|
+
const scanWorktrees = patterns.length
|
|
1107
|
+
? fsp
|
|
1108
|
+
.readdir(worktreesDir)
|
|
1109
|
+
.then((worktreeNames) => filterRefs(worktreeNames, patterns, patternCache), invariably.emptyArray)
|
|
1110
|
+
.then((worktreeNames) => {
|
|
1111
|
+
if (useLinkedWorktree && !~worktreeNames.indexOf(useWorktree.linked)) worktreeNames.push(useWorktree.linked)
|
|
1112
|
+
return worktreeNames
|
|
1113
|
+
})
|
|
1114
|
+
: Promise.resolve(useLinkedWorktree ? [useWorktree.linked] : [])
|
|
1115
|
+
return scanWorktrees
|
|
1116
|
+
.then((worktreeNames) =>
|
|
1117
|
+
Promise.all(
|
|
1118
|
+
worktreeNames.map((name) => {
|
|
1119
|
+
const symbolicNames = useLinkedWorktree && name === useWorktree.linked ? ['.', 'HEAD'] : undefined
|
|
1120
|
+
const gitdir = ospath.resolve(worktreesDir, name)
|
|
1121
|
+
// NOTE branch name defaults to worktree name if HEAD is detached
|
|
1122
|
+
return getCurrentBranchName(Object.assign({}, repo, { gitdir })).then((branch = name) =>
|
|
1123
|
+
fsp
|
|
1124
|
+
.readFile(ospath.join(gitdir, 'gitdir'), 'utf8')
|
|
1125
|
+
.then((contents) => [branch, { head: ospath.dirname(contents.trimEnd()), name, symbolicNames }])
|
|
1057
1126
|
)
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
)
|
|
1127
|
+
})
|
|
1128
|
+
)
|
|
1129
|
+
)
|
|
1130
|
+
.then((entries) => new Map(entries))
|
|
1131
|
+
.then((worktrees) => mainWorktree.then((result) => (result ? worktrees.set(result[0], result[1]) : worktrees)))
|
|
1064
1132
|
}
|
|
1065
1133
|
|
|
1066
1134
|
async function gracefulPromiseAllWithLimit (tasks, limit = Infinity) {
|
package/lib/compute-origin.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const { posix: path } = require('path')
|
|
3
|
+
const { posix: path } = require('node:path')
|
|
4
4
|
const posixify = require('./posixify')
|
|
5
5
|
const removeGitSuffix = require('./remove-git-suffix')
|
|
6
6
|
|
|
7
|
-
const EDIT_URL_TEMPLATE_VAR_RX = /\{(web_url|ref(?:hash|name|type)
|
|
7
|
+
const EDIT_URL_TEMPLATE_VAR_RX = /\{(web_url|ref(?:hash|name|type)?|path)\}/g
|
|
8
8
|
const HOSTED_GIT_REPO_RX = /^(?:https?:\/\/|.+@)(git(?:hub|lab)\.com|bitbucket\.org|pagure\.io)[/:](.+?)(?:\.git)?$/
|
|
9
9
|
|
|
10
10
|
function computeOrigin (url, authStatus, gitdir, ref, startPath, worktreePath = undefined, editUrl = true) {
|
|
@@ -33,14 +33,16 @@ 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
|
}
|
|
41
42
|
} else if (editUrl) {
|
|
42
43
|
const vars = {
|
|
43
44
|
path: () => (startPath ? path.join(startPath, '%s') : '%s'),
|
|
45
|
+
ref: () => 'refs/' + (reftype === 'branch' ? 'heads' : reftype) + '/' + refname,
|
|
44
46
|
refhash: () => refhash,
|
|
45
47
|
reftype: () => reftype,
|
|
46
48
|
refname: () => refname,
|
package/lib/filter-refs.js
CHANGED
|
@@ -4,9 +4,11 @@ const { makeMatcherRx, refMatcherOpts: getMatcherOpts, MATCH_ALL_RX } = require(
|
|
|
4
4
|
|
|
5
5
|
function compileRx (pattern, opts) {
|
|
6
6
|
if (pattern === '*' || pattern === '**') return MATCH_ALL_RX
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
const rx =
|
|
8
|
+
pattern.charAt() === '!' // we handle negate ourselves
|
|
9
|
+
? Object.defineProperty(makeMatcherRx((pattern = pattern.substr(1)), opts), 'negated', { value: true })
|
|
10
|
+
: makeMatcherRx(pattern, opts)
|
|
11
|
+
return Object.defineProperty(rx, 'pattern', { value: pattern })
|
|
10
12
|
}
|
|
11
13
|
|
|
12
14
|
function createMatcher (patterns, cache = Object.assign(new Map(), { braces: new Map() })) {
|
|
@@ -14,8 +16,8 @@ function createMatcher (patterns, cache = Object.assign(new Map(), { braces: new
|
|
|
14
16
|
(pattern) => cache.get(pattern) || cache.set(pattern, compileRx(pattern, getMatcherOpts(cache))).get(pattern)
|
|
15
17
|
)
|
|
16
18
|
if (rxs[0].negated) rxs.unshift(MATCH_ALL_RX)
|
|
17
|
-
return (candidate) => {
|
|
18
|
-
let matched
|
|
19
|
+
return (candidate, onMatch) => {
|
|
20
|
+
let matched, symbolic
|
|
19
21
|
for (const rx of rxs) {
|
|
20
22
|
let voteIfMatched = true
|
|
21
23
|
if (matched) {
|
|
@@ -24,17 +26,23 @@ function createMatcher (patterns, cache = Object.assign(new Map(), { braces: new
|
|
|
24
26
|
} else if (rx.negated) {
|
|
25
27
|
continue
|
|
26
28
|
}
|
|
27
|
-
if (rx.test(candidate))
|
|
29
|
+
if (rx.test(candidate) || (symbolic && rx.test(symbolic) && (candidate = symbolic))) {
|
|
30
|
+
if (onMatch) {
|
|
31
|
+
if (!(matched = onMatch(candidate, rx))) continue
|
|
32
|
+
;[symbolic, candidate] = [candidate, matched]
|
|
33
|
+
}
|
|
34
|
+
matched = voteIfMatched && candidate
|
|
35
|
+
}
|
|
28
36
|
}
|
|
29
37
|
return matched
|
|
30
38
|
}
|
|
31
39
|
}
|
|
32
40
|
|
|
33
|
-
function filterRefs (candidates, patterns, cache) {
|
|
41
|
+
function filterRefs (candidates, patterns, cache, onMatch) {
|
|
34
42
|
if (!(patterns = patterns.filter(compact)).length) return []
|
|
35
|
-
const
|
|
43
|
+
const match = createMatcher(patterns, cache)
|
|
36
44
|
return candidates.reduce((accum, candidate) => {
|
|
37
|
-
if (
|
|
45
|
+
if ((candidate = match(candidate, onMatch))) accum.push(candidate)
|
|
38
46
|
return accum
|
|
39
47
|
}, [])
|
|
40
48
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const { homedir } = require('os')
|
|
3
|
+
const { homedir } = require('node:os')
|
|
4
4
|
const expandPath = require('@antora/expand-path-helper')
|
|
5
|
-
const { promises: fsp } = require('fs')
|
|
5
|
+
const { promises: fsp } = require('node:fs')
|
|
6
6
|
const invariably = require('./invariably')
|
|
7
|
-
const ospath = require('path')
|
|
7
|
+
const ospath = require('node:path')
|
|
8
8
|
|
|
9
9
|
class GitCredentialManagerStore {
|
|
10
10
|
configure ({ config, startDir }) {
|
|
@@ -86,11 +86,11 @@ class GitCredentialManagerStore {
|
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
async approved ({ url }) {
|
|
89
|
-
this.urls[url] = 'approved'
|
|
89
|
+
this.urls[url] = (url in this.urls ? this.urls[url] + ',' : '') + 'approved'
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
async rejected ({ url, auth }) {
|
|
93
|
-
this.urls[url] = 'rejected'
|
|
93
|
+
this.urls[url] = (url in this.urls ? this.urls[url] + ',' : '') + 'rejected'
|
|
94
94
|
const statusCode = 401
|
|
95
95
|
const statusMessage = 'HTTP Basic: Access Denied'
|
|
96
96
|
const err = new Error(`HTTP Error: ${statusCode} ${statusMessage}`)
|
package/lib/git.js
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
const zlib = require('node:zlib')
|
|
4
|
+
const { promisify } = require('node:util')
|
|
5
|
+
|
|
6
|
+
module.exports = ((pakoModuleId) => {
|
|
7
|
+
const git = require('isomorphic-git')
|
|
8
|
+
require(pakoModuleId).inflate = promisify(zlib.inflate)
|
|
9
|
+
return git
|
|
10
|
+
})('pako')
|
package/lib/matcher.js
CHANGED
|
@@ -17,7 +17,7 @@ const BASE_OPTS = {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
module.exports = {
|
|
20
|
-
MATCH_ALL_RX: { test: () => true },
|
|
20
|
+
MATCH_ALL_RX: Object.defineProperty({ test: () => true }, 'pattern', { value: '*' }),
|
|
21
21
|
expandBraces,
|
|
22
22
|
makeMatcherRx: makeRe,
|
|
23
23
|
pathMatcherOpts: Object.assign({}, BASE_OPTS, { dot: false }),
|
package/lib/posixify.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const deepFlatten = require('./deep-flatten')
|
|
4
|
-
const { promises: fsp } = require('fs')
|
|
4
|
+
const { promises: fsp } = require('node:fs')
|
|
5
5
|
const git = require('./git')
|
|
6
6
|
const invariably = require('./invariably')
|
|
7
7
|
const { expandBraces, makeMatcherRx, pathMatcherOpts: MATCHER_OPTS } = require('./matcher')
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@antora/content-aggregator",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.2.0-alpha.10",
|
|
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)",
|
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
"homepage": "https://antora.org",
|
|
14
14
|
"repository": {
|
|
15
15
|
"type": "git",
|
|
16
|
-
"url": "git+https://gitlab.com/antora/antora.git"
|
|
16
|
+
"url": "git+https://gitlab.com/antora/antora.git",
|
|
17
|
+
"directory": "packages/content-aggregator"
|
|
17
18
|
},
|
|
18
19
|
"bugs": {
|
|
19
20
|
"url": "https://gitlab.com/antora/antora/issues"
|
|
@@ -32,7 +33,7 @@
|
|
|
32
33
|
},
|
|
33
34
|
"dependencies": {
|
|
34
35
|
"@antora/expand-path-helper": "~3.0",
|
|
35
|
-
"@antora/logger": "3.
|
|
36
|
+
"@antora/logger": "3.2.0-alpha.10",
|
|
36
37
|
"@antora/user-require-helper": "~3.0",
|
|
37
38
|
"braces": "~3.0",
|
|
38
39
|
"cache-directory": "~2.0",
|
|
@@ -48,7 +49,7 @@
|
|
|
48
49
|
"vinyl": "~3.0"
|
|
49
50
|
},
|
|
50
51
|
"engines": {
|
|
51
|
-
"node": ">=
|
|
52
|
+
"node": ">=18.0.0"
|
|
52
53
|
},
|
|
53
54
|
"files": [
|
|
54
55
|
"lib/"
|
|
@@ -65,7 +66,7 @@
|
|
|
65
66
|
],
|
|
66
67
|
"scripts": {
|
|
67
68
|
"test": "_mocha",
|
|
68
|
-
"prepublishOnly": "npx -y downdoc --prepublish",
|
|
69
|
-
"postpublish": "npx -y downdoc --postpublish"
|
|
69
|
+
"prepublishOnly": "npx -y downdoc@latest --prepublish",
|
|
70
|
+
"postpublish": "npx -y downdoc@latest --postpublish"
|
|
70
71
|
}
|
|
71
72
|
}
|