@antora/content-aggregator
Advanced tools
Comparing version 3.1.1 to 3.2.0-alpha.1
@@ -191,4 +191,3 @@ 'use strict' | ||
.then(() => { | ||
const credentialManager = gitPlugins.credentialManager | ||
authStatus = credentials ? 'auth-embedded' : credentialManager.status({ url }) ? 'auth-required' : undefined | ||
authStatus = identifyAuthStatus(gitPlugins.credentialManager, credentials, url) | ||
return git.setConfig(Object.assign({ path: 'remote.origin.private', value: authStatus }, repo)) | ||
@@ -214,4 +213,3 @@ }) | ||
.then(() => { | ||
const credentialManager = gitPlugins.credentialManager | ||
authStatus = credentials ? 'auth-embedded' : credentialManager.status({ url }) ? 'auth-required' : undefined | ||
authStatus = identifyAuthStatus(gitPlugins.credentialManager, credentials, url) | ||
return git.setConfig(Object.assign({ path: 'remote.origin.private', value: authStatus }, repo)) | ||
@@ -228,4 +226,11 @@ }) | ||
} else if (await isDirectory((dir = expandPath(url, { dot: opts.startDir })))) { | ||
const gitdir = ospath.join(dir, '.git') | ||
repo = (await isDirectory(gitdir)) ? { cache, dir, fs, gitdir } : { cache, dir, fs, gitdir: dir, noCheckout: true } | ||
const dotgit = ospath.join(dir, '.git') | ||
const dotgitStat = await fsp.stat(dotgit).catch(() => ({ isFile: invariably.false, isDirectory: invariably.false })) | ||
if (dotgitStat.isDirectory()) { | ||
repo = { cache, dir, fs, gitdir: dotgit } | ||
} else if (dotgitStat.isFile()) { | ||
repo = await resolveRepositoryFromWorktree({ cache, dir, fs, gitdir: dotgit }) | ||
} else { | ||
repo = { cache, dir, fs, gitdir: dir, noCheckout: true } | ||
} | ||
try { | ||
@@ -279,3 +284,3 @@ await git.resolveRef(Object.assign({ ref: 'HEAD', depth: 1 }, repo)) | ||
async function selectReferences (source, repo, remote) { | ||
let { branches: branchPatterns, tags: tagPatterns, worktrees: worktreePatterns = '.' } = source | ||
let { branches: branchPatterns, tags: tagPatterns, worktrees: worktreePatterns } = source | ||
const isBare = repo.noCheckout | ||
@@ -300,2 +305,8 @@ const patternCache = repo.cache[REF_PATTERN_CACHE_KEY] | ||
if (!branchPatterns) return [...refs.values()] | ||
branchPatterns = Array.isArray(branchPatterns) | ||
? branchPatterns.map((pattern) => String(pattern)) | ||
: splitRefPatterns(String(branchPatterns)) | ||
if (!branchPatterns.length) return [...refs.values()] | ||
const worktreeName = repo.worktreeName // possibly switch to worktree property ({ name, dir}) in future | ||
if (worktreeName) branchPatterns = branchPatterns.map((it) => (it === 'HEAD' ? 'HEAD@' + worktreeName : it)) | ||
if (worktreePatterns) { | ||
@@ -310,6 +321,8 @@ if (worktreePatterns === '.') { | ||
: splitRefPatterns(String(worktreePatterns)) | ||
if (worktreeName) worktreePatterns = worktreePatterns.map((it) => (it === '@' ? worktreeName : it)) | ||
} | ||
} else { | ||
worktreePatterns = worktreePatterns === undefined ? [worktreeName || '.'] : [] | ||
} | ||
const branchPatternsString = String(branchPatterns) | ||
if (branchPatternsString === 'HEAD' || branchPatternsString === '.') { | ||
if (branchPatterns.length === 1 && (branchPatterns[0] === 'HEAD' || branchPatterns[0] === '.')) { | ||
const currentBranch = await getCurrentBranchName(repo, remote) | ||
@@ -326,7 +339,3 @@ if (currentBranch) { | ||
} | ||
} else if ( | ||
(branchPatterns = Array.isArray(branchPatterns) | ||
? branchPatterns.map((pattern) => String(pattern)) | ||
: splitRefPatterns(branchPatternsString)).length | ||
) { | ||
} else { | ||
let headBranchIdx | ||
@@ -356,4 +365,2 @@ // NOTE we can assume at least two entries if HEAD or . are present | ||
} | ||
} else { | ||
return [...refs.values()] | ||
} | ||
@@ -373,4 +380,16 @@ // NOTE isomorphic-git includes HEAD in list of remote branches (see https://isomorphic-git.org/docs/listBranches) | ||
const worktrees = await findWorktrees(repo, worktreePatterns) | ||
for (const shortname of filterRefs(localBranches, branchPatterns, patternCache)) { | ||
const head = worktrees.get(shortname) || noWorktree | ||
let onMatch | ||
if ((worktreePatterns.join('') || '.') !== '.') { | ||
const symbolicNames = new Map() | ||
worktrees.forEach(({ name, symbolicName = 'HEAD@' + name }, shortname) => { | ||
localBranches.push(symbolicName) | ||
symbolicNames.set(symbolicName, shortname) | ||
}) | ||
onMatch = (candidate, { pattern }) => { | ||
const shortname = symbolicNames.get(candidate) | ||
return shortname ? (pattern.startsWith('HEAD@') ? shortname : undefined) : candidate | ||
} | ||
} | ||
for (const shortname of filterRefs(localBranches, branchPatterns, patternCache, onMatch)) { | ||
const head = (worktrees.get(shortname) || { head: noWorktree }).head | ||
refs.set(shortname, { shortname, fullname: 'heads/' + shortname, type: 'branch', head }) | ||
@@ -394,11 +413,9 @@ } | ||
function getCurrentBranchName (repo, remote) { | ||
let refPromise | ||
if (repo.noCheckout) { | ||
refPromise = git | ||
.resolveRef(Object.assign({ ref: 'refs/remotes/' + remote + '/HEAD', depth: 2 }, repo)) | ||
.catch(() => git.resolveRef(Object.assign({ ref: 'HEAD', depth: 2 }, repo))) | ||
} else { | ||
refPromise = git.resolveRef(Object.assign({ ref: 'HEAD', depth: 2 }, repo)) | ||
} | ||
return refPromise.then((ref) => (ref.startsWith('refs/') ? ref.replace(SHORTEN_REF_RX, '') : undefined)) | ||
return ( | ||
repo.noCheckout && remote | ||
? git | ||
.resolveRef(Object.assign({ ref: 'refs/remotes/' + remote + '/HEAD', depth: 2 }, repo)) | ||
.catch(() => git.resolveRef(Object.assign({ ref: 'HEAD', depth: 2 }, repo))) | ||
: git.resolveRef(Object.assign({ ref: 'HEAD', depth: 2 }, repo)) | ||
).then((ref) => (ref.startsWith('refs/') ? ref.replace(SHORTEN_REF_RX, '') : undefined)) | ||
} | ||
@@ -836,7 +853,10 @@ | ||
function resolveCredentials (credentialsFromUrlHolder, url, auth) { | ||
const credentialsFromUrl = credentialsFromUrlHolder.get() | ||
const credentialsFromUrl = credentialsFromUrlHolder.get() || {} | ||
if ('Authorization' in auth.headers) { | ||
if (!credentialsFromUrl) return this.rejected({ url, auth }) | ||
credentialsFromUrlHolder.clear() | ||
} else if (credentialsFromUrl) { | ||
if ('username' in credentialsFromUrl) { | ||
credentialsFromUrlHolder.clear() | ||
} else { | ||
return this.rejected({ url, auth }) | ||
} | ||
} else if ('username' in credentialsFromUrl) { | ||
return credentialsFromUrl | ||
@@ -853,2 +873,11 @@ } else { | ||
function identifyAuthStatus (credentialManager, credentials, url) { | ||
const status = credentialManager.status({ url }) | ||
if (credentials) { | ||
return typeof status === 'string' && status.startsWith('requested,') ? 'auth-required' : 'auth-embedded' | ||
} else if (status != null) { | ||
return 'auth-required' | ||
} | ||
} | ||
/** | ||
@@ -898,3 +927,3 @@ * Generates a safe, unique folder name for a git URL. | ||
* @param {String} url - The URL to check. | ||
* @return {Boolean} A flag indicating whether the URL matches a directory on the local filesystem. | ||
* @returns {Boolean} A flag indicating whether the URL matches a directory on the local filesystem. | ||
*/ | ||
@@ -1022,37 +1051,52 @@ function isDirectory (url) { | ||
async function resolveRepositoryFromWorktree (repo) { | ||
return fsp | ||
.readFile(repo.gitdir, 'utf8') | ||
.then((contents) => contents.trimRight().substr(8)) | ||
.then((worktreeGitdir) => { | ||
const worktreeName = ospath.basename(worktreeGitdir) | ||
return fsp.readFile(ospath.join(worktreeGitdir, 'commondir'), 'utf8').then( | ||
(contents) => { | ||
const gitdir = ospath.join(worktreeGitdir, contents.trimRight()) | ||
return ospath.basename(gitdir) === '.git' | ||
? Object.assign(repo, { dir: ospath.dirname(gitdir), gitdir, worktreeName }) | ||
: Object.assign(repo, { dir: gitdir, gitdir, worktreeName }) | ||
}, | ||
() => repo | ||
) | ||
}) | ||
} | ||
function findWorktrees (repo, patterns) { | ||
if (!patterns.length) return new Map() | ||
const linkedOnly = patterns[0] === '.' ? !(patterns = patterns.slice(1)) : true | ||
let worktreesDir | ||
const mainWorktree = | ||
patterns[0] === '.' && (patterns = patterns.slice(1)) | ||
? getCurrentBranchName(repo).then((branch) => (branch ? [branch, { head: repo.dir, name: '.' }] : undefined)) | ||
: Promise.resolve() | ||
const worktreesDir = patterns.length ? ospath.join(repo.dir, '.git', 'worktrees') : undefined | ||
const patternCache = repo.cache[REF_PATTERN_CACHE_KEY] | ||
return ( | ||
patterns.length | ||
worktreesDir | ||
? fsp | ||
.readdir((worktreesDir = ospath.join(repo.dir, '.git', 'worktrees'))) | ||
.readdir(worktreesDir) | ||
.then((worktreeNames) => filterRefs(worktreeNames, patterns, patternCache), invariably.emptyArray) | ||
.then((worktreeNames) => | ||
worktreeNames.length | ||
? Promise.all( | ||
worktreeNames.map((worktreeName) => { | ||
const gitdir = ospath.resolve(worktreesDir, worktreeName) | ||
// NOTE uses name of worktree as branch name if HEAD is detached | ||
return git | ||
.currentBranch(Object.assign({}, repo, { gitdir })) | ||
.then((branch = worktreeName) => | ||
fsp | ||
.readFile(ospath.join(gitdir, 'gitdir'), 'utf8') | ||
.then((contents) => ({ branch, dir: ospath.dirname(contents.trimRight()) })) | ||
) | ||
}) | ||
).then((entries) => entries.reduce((accum, it) => accum.set(it.branch, it.dir), new Map())) | ||
: new Map() | ||
Promise.all( | ||
worktreeNames.map((worktreeName) => { | ||
const gitdir = ospath.resolve(worktreesDir, worktreeName) | ||
// NOTE branch name defaults to worktree name if HEAD is detached | ||
return git | ||
.currentBranch(Object.assign({}, repo, { gitdir })) | ||
.then((branch = worktreeName) => | ||
fsp | ||
.readFile(ospath.join(gitdir, 'gitdir'), 'utf8') | ||
.then((contents) => [branch, { head: ospath.dirname(contents.trimRight()), name: worktreeName }]) | ||
) | ||
}) | ||
) | ||
) | ||
: Promise.resolve(new Map()) | ||
).then((worktrees) => | ||
linkedOnly | ||
? worktrees | ||
: git.currentBranch(repo).then((branch) => (branch ? worktrees.set(branch, repo.dir) : worktrees)) | ||
) | ||
: Promise.resolve() | ||
).then((entries = []) => mainWorktree.then((entry) => new Map(entry ? entries.push(entry) && entries : entries))) | ||
} | ||
module.exports = aggregateContent |
@@ -7,3 +7,3 @@ 'use strict' | ||
const EDIT_URL_TEMPLATE_VAR_RX = /\{(web_url|ref(?:hash|name|type)|path)\}/g | ||
const EDIT_URL_TEMPLATE_VAR_RX = /\{(web_url|ref(?:hash|name|type)?|path)\}/g | ||
const HOSTED_GIT_REPO_RX = /^(?:https?:\/\/|.+@)(git(?:hub|lab)\.com|bitbucket\.org|pagure\.io)[/:](.+?)(?:\.git)?$/ | ||
@@ -45,2 +45,3 @@ | ||
path: () => (startPath ? path.join(startPath, '%s') : '%s'), | ||
ref: () => 'refs/' + (reftype === 'branch' ? 'heads' : reftype) + '/' + refname, | ||
refhash: () => refhash, | ||
@@ -47,0 +48,0 @@ reftype: () => reftype, |
@@ -7,5 +7,7 @@ 'use strict' | ||
if (pattern === '*' || pattern === '**') return MATCH_ALL_RX | ||
return pattern.charAt() === '!' // do our own negate | ||
? Object.defineProperty(makeMatcherRx(pattern.substr(1), opts), 'negated', { value: true }) | ||
: makeMatcherRx(pattern, opts) | ||
const rx = | ||
pattern.charAt() === '!' // we handle negate ourselves | ||
? Object.defineProperty(makeMatcherRx((pattern = pattern.substr(1)), opts), 'negated', { value: true }) | ||
: makeMatcherRx(pattern, opts) | ||
return Object.defineProperty(rx, 'pattern', { value: pattern }) | ||
} | ||
@@ -19,4 +21,4 @@ | ||
if (rxs[0].negated) rxs.unshift(MATCH_ALL_RX) | ||
return (candidate) => { | ||
let matched | ||
return (candidate, onMatch) => { | ||
let matched, symbolic | ||
for (const rx of rxs) { | ||
@@ -30,3 +32,9 @@ let voteIfMatched = true | ||
} | ||
if (rx.test(candidate)) matched = voteIfMatched | ||
if (rx.test(candidate) || (symbolic && rx.test(symbolic) && (candidate = symbolic))) { | ||
if (onMatch) { | ||
if (!(matched = onMatch(candidate, rx))) continue | ||
;[symbolic, candidate] = [candidate, matched] | ||
} | ||
matched = voteIfMatched && candidate | ||
} | ||
} | ||
@@ -37,6 +45,6 @@ return matched | ||
function filterRefs (candidates, patterns, cache = Object.assign(new Map(), { braces: new Map() })) { | ||
const isMatch = createMatcher(patterns, cache) | ||
function filterRefs (candidates, patterns, cache = Object.assign(new Map(), { braces: new Map() }), onMatch) { | ||
const match = createMatcher(patterns, cache) | ||
return candidates.reduce((accum, candidate) => { | ||
if (isMatch(candidate)) accum.push(candidate) | ||
if ((candidate = match(candidate, onMatch))) accum.push(candidate) | ||
return accum | ||
@@ -43,0 +51,0 @@ }, []) |
@@ -89,7 +89,7 @@ 'use strict' | ||
async approved ({ url }) { | ||
this.urls[url] = 'approved' | ||
this.urls[url] = (url in this.urls ? this.urls[url] + ',' : '') + 'approved' | ||
} | ||
async rejected ({ url, auth }) { | ||
this.urls[url] = 'rejected' | ||
this.urls[url] = (url in this.urls ? this.urls[url] + ',' : '') + 'rejected' | ||
const statusCode = 401 | ||
@@ -96,0 +96,0 @@ const statusMessage = 'HTTP Basic: Access Denied' |
@@ -25,3 +25,3 @@ 'use strict' | ||
module.exports = { | ||
MATCH_ALL_RX: { test: () => true }, | ||
MATCH_ALL_RX: Object.defineProperty({ test: () => true }, 'pattern', { value: '*' }), | ||
expandBraces, | ||
@@ -28,0 +28,0 @@ makeMatcherRx, |
{ | ||
"name": "@antora/content-aggregator", | ||
"version": "3.1.1", | ||
"version": "3.2.0-alpha.1", | ||
"description": "Fetches and aggregates content from distributed sources for use in an Antora documentation pipeline.", | ||
@@ -32,3 +32,3 @@ "license": "MPL-2.0", | ||
"@antora/expand-path-helper": "~2.0", | ||
"@antora/logger": "3.1.1", | ||
"@antora/logger": "3.2.0-alpha.1", | ||
"@antora/user-require-helper": "~2.0", | ||
@@ -38,4 +38,4 @@ "braces": "~3.0", | ||
"glob-stream": "~7.0", | ||
"hpagent": "~1.0", | ||
"isomorphic-git": "~1.19", | ||
"hpagent": "~1.1", | ||
"isomorphic-git": "~1.21", | ||
"js-yaml": "~4.1", | ||
@@ -42,0 +42,0 @@ "multi-progress": "~4.0", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
68992
1544
1
+ Added@antora/logger@3.2.0-alpha.1(transitive)
+ Addedfast-copy@3.0.2(transitive)
+ Addedhpagent@1.1.0(transitive)
+ Addedisomorphic-git@1.21.0(transitive)
+ Addedpino@8.7.0(transitive)
+ Addedpino-pretty@9.1.1(transitive)
- Removed@antora/logger@3.1.1(transitive)
- Removedfast-copy@2.1.7(transitive)
- Removedhpagent@1.0.0(transitive)
- Removedisomorphic-git@1.19.3(transitive)
- Removedpino@8.4.2(transitive)
- Removedpino-pretty@9.0.1(transitive)
Updated@antora/logger@3.2.0-alpha.1
Updatedhpagent@~1.1
Updatedisomorphic-git@~1.21