@antora/content-aggregator 3.2.0-alpha.10 → 3.2.0-alpha.11

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.
@@ -116,6 +116,8 @@ async function collectFiles (sourcesByUrl, loadOpts, concurrency, fetchedUrls =
116
116
  const loadOptsForUrl = Object.assign({}, loadOpts)
117
117
  if (loadOpts.fetch.always && fetchedUrls.length && ~fetchedUrls.indexOf(url)) loadOptsForUrl.fetch.always = false
118
118
  if (tagsSpecified(sources)) loadOptsForUrl.fetch.tags = true
119
+ const commits = commitsRequested(sources)
120
+ if (commits) loadOptsForUrl.fetch.commits = commits
119
121
  return loadRepository.bind(null, url, loadOptsForUrl, { url, sources })
120
122
  })
121
123
  return gracefulPromiseAllWithLimit(loadTasks, concurrency.fetch).then(([results, rejections]) => {
@@ -177,6 +179,7 @@ async function loadRepository (url, opts, result = {}) {
177
179
  const fetchOpts = buildFetchOptions(repo, progress, displayUrl, credentials, gitPlugins, fetch, 'fetch')
178
180
  await git
179
181
  .fetch(fetchOpts)
182
+ .then(() => ensureOids(fetchOpts))
180
183
  .then(() => {
181
184
  authStatus = identifyAuthStatus(credentialManager, credentials, url)
182
185
  return git.setConfig(Object.assign({ path: 'remote.origin.private', value: authStatus }, repo))
@@ -198,6 +201,7 @@ async function loadRepository (url, opts, result = {}) {
198
201
  await git
199
202
  .clone(fetchOpts)
200
203
  .then(() => git.resolveRef(Object.assign({ ref: 'HEAD', depth: 1 }, repo)))
204
+ .then(() => ensureOids(fetchOpts))
201
205
  .then(() => {
202
206
  authStatus = identifyAuthStatus(credentialManager, credentials, url)
203
207
  return git.setConfig(Object.assign({ path: 'remote.origin.private', value: authStatus }, repo))
@@ -279,12 +283,12 @@ async function selectStartPathsForRepository (repo, sources) {
279
283
  }
280
284
  }
281
285
  } else {
282
- const { url, branches, tags } = source
286
+ const { url, branches, tags, commits } = source
283
287
  const startPathInfo =
284
288
  'startPaths' in source
285
289
  ? { 'start paths': source.startPaths || undefined }
286
290
  : { 'start path': source.startPath || undefined }
287
- const sourceInfo = yaml.dump({ url, branches, tags, ...startPathInfo }, { flowLevel: 1 }).trimRight()
291
+ const sourceInfo = yaml.dump({ url, branches, tags, commits, ...startPathInfo }, { flowLevel: 1 }).trimRight()
288
292
  logger.info(`No matching references found for content source entry (${sourceInfo.replace(NEWLINE_RX, ' | ')})`)
289
293
  }
290
294
  }
@@ -293,7 +297,7 @@ async function selectStartPathsForRepository (repo, sources) {
293
297
 
294
298
  // QUESTION should we resolve HEAD to a ref eagerly to avoid having to do a match on it?
295
299
  async function selectReferences (source, repo, remote) {
296
- let { branches: branchPatterns, tags: tagPatterns, worktrees: worktreePatterns } = source
300
+ let { branches: branchPatterns, tags: tagPatterns, commits, worktrees: worktreePatterns } = source
297
301
  const managed = 'url' in repo
298
302
  const isBare = managed || repo.noCheckout
299
303
  const patternCache = repo.cache[REF_PATTERN_CACHE_KEY]
@@ -309,11 +313,20 @@ async function selectReferences (source, repo, remote) {
309
313
  const tags = await git.listTags(repo)
310
314
  if (tags.length) {
311
315
  for (const shortname of filterRefs(tags, tagPatterns, patternCache)) {
312
- // NOTE tags are stored using symbol keys to distinguish them from branches
313
- refs.set(Symbol(shortname), { shortname, fullname: 'tags/' + shortname, type: 'tag', head: noWorktree })
316
+ // NOTE tags are stored using Buffer keys to distinguish them from commits and branches
317
+ refs.set(Buffer.from(shortname), { shortname, fullname: 'tags/' + shortname, type: 'tag', head: noWorktree })
314
318
  }
315
319
  }
316
320
  }
321
+ if (
322
+ commits &&
323
+ (commits = Array.isArray(commits) ? commits.map((commit) => String(commit)) : commits.split(CSV_RX)).length
324
+ ) {
325
+ for (const oid of commits) {
326
+ // NOTE commits are stored using Symbol keys to distinguish them from tags and branches
327
+ refs.set(Symbol(oid), { oid, shortname: oid, fullname: 'commits/' + oid, type: 'commit' })
328
+ }
329
+ }
317
330
  if (
318
331
  !branchPatterns ||
319
332
  !(branchPatterns = Array.isArray(branchPatterns)
@@ -456,9 +469,11 @@ async function selectStartPaths (source, repo, ref) {
456
469
  const displayUrl = url || repo.dir
457
470
  const worktreePath = ref.head
458
471
  if (!worktreePath) {
459
- ref.oid = await git.resolveRef(
460
- Object.assign(ref.detached ? { ref: 'HEAD', depth: 1 } : { ref: 'refs/' + ref.fullname }, repo)
461
- )
472
+ ref.oid = ref.oid
473
+ ? await git.expandOid(Object.assign({ oid: ref.oid }, repo)).catch(() => ref.oid)
474
+ : await git.resolveRef(
475
+ Object.assign(ref.detached ? { ref: 'HEAD', depth: 1 } : { ref: 'refs/' + ref.fullname }, repo)
476
+ )
462
477
  }
463
478
  if ('startPaths' in source) {
464
479
  let startPaths
@@ -825,6 +840,7 @@ function buildFetchOptions (repo, progress, displayUrl, credentialsFromUrl, gitP
825
840
  } else if (!fetch.tags) {
826
841
  opts.noTags = true
827
842
  }
843
+ if (fetch.commits) opts.oids = fetch.commits
828
844
  return opts
829
845
  }
830
846
 
@@ -859,7 +875,10 @@ function createProgressListener (progress, progressLabel, operation) {
859
875
  // NOTE leave room for indeterminate progress at end of bar; this isn't strictly needed for a bare clone
860
876
  progressBar.scaleFactor = Math.max(0, (ticks - 1) / ticks)
861
877
  progressBar.tick(0)
862
- return Object.assign(onGitProgress.bind(progressBar), { finish: onGitComplete.bind(progressBar) })
878
+ return Object.assign(onGitProgress.bind(progressBar), {
879
+ finish: onGitComplete.bind(progressBar),
880
+ reset: () => progressBar.update(0),
881
+ })
863
882
  }
864
883
 
865
884
  function formatProgressBar (label, maxLabelWidth, operation) {
@@ -975,6 +994,16 @@ function tagsSpecified (sources) {
975
994
  return sources.some(({ tags }) => tags && (Array.isArray(tags) ? tags.length : true))
976
995
  }
977
996
 
997
+ function commitsRequested (sources) {
998
+ if (!sources.some(({ commits }) => commits && (Array.isArray(commits) ? commits.length : true))) return
999
+ const result = new Set()
1000
+ for (const { commits } of sources) {
1001
+ if (!commits) continue
1002
+ for (const commit of Array.isArray(commits) ? commits : commits.split(CSV_RX)) result.add(String(commit))
1003
+ }
1004
+ return [...result]
1005
+ }
1006
+
978
1007
  function loadGitPlugins (gitConfig, networkConfig, startDir) {
979
1008
  const plugins = new Map((git.cores || git.default.cores || new Map()).get(GIT_CORE))
980
1009
  for (const [name, request] of Object.entries(gitConfig.plugins || {})) {
@@ -1164,4 +1193,27 @@ async function promiseAllWithLimit (tasks, limit = Infinity) {
1164
1193
  return Promise.all(started)
1165
1194
  }
1166
1195
 
1196
+ async function ensureOids (opts) {
1197
+ if (!opts.oids) return
1198
+ let prevShallowCommits = await getShallowCommits(opts)
1199
+ if (prevShallowCommits == null) return
1200
+ let oids = opts.oids.slice()
1201
+ const deepenOpts = Object.assign({}, opts, { relative: true })
1202
+ const format = 'deflated'
1203
+ while (oids.length) {
1204
+ deepenOpts.onProgress?.reset()
1205
+ await git.fetch(deepenOpts)
1206
+ const shallowCommits = await getShallowCommits(opts)
1207
+ if (shallowCommits == null || shallowCommits === prevShallowCommits) break
1208
+ prevShallowCommits = shallowCommits
1209
+ oids = await Promise.all(
1210
+ oids.map((oid) => git.readObject(Object.assign({ oid, format }, opts)).then(invariably.void, () => oid))
1211
+ ).then((results) => results.filter((it) => it))
1212
+ }
1213
+ }
1214
+
1215
+ function getShallowCommits ({ gitdir }) {
1216
+ return fsp.readFile(ospath.join(gitdir, 'shallow'), 'utf8').catch(invariably.void)
1217
+ }
1218
+
1167
1219
  module.exports = aggregateContent
@@ -42,7 +42,7 @@ function computeOrigin (url, authStatus, gitdir, ref, startPath, worktreePath =
42
42
  } else if (editUrl) {
43
43
  const vars = {
44
44
  path: () => (startPath ? path.join(startPath, '%s') : '%s'),
45
- ref: () => 'refs/' + (reftype === 'branch' ? 'heads' : reftype) + '/' + refname,
45
+ ref: () => 'refs/' + (reftype === 'branch' ? 'head' : reftype) + 's/' + refname,
46
46
  refhash: () => refhash,
47
47
  reftype: () => reftype,
48
48
  refname: () => refname,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antora/content-aggregator",
3
- "version": "3.2.0-alpha.10",
3
+ "version": "3.2.0-alpha.11",
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)",
@@ -33,7 +33,7 @@
33
33
  },
34
34
  "dependencies": {
35
35
  "@antora/expand-path-helper": "~3.0",
36
- "@antora/logger": "3.2.0-alpha.10",
36
+ "@antora/logger": "3.2.0-alpha.11",
37
37
  "@antora/user-require-helper": "~3.0",
38
38
  "braces": "~3.0",
39
39
  "cache-directory": "~2.0",