refactor(populateCache): support onProgress; don’t read remote URL from Git config

This commit is contained in:
Anton Strogonoff 2021-11-29 03:06:19 +01:00
parent 6d43595383
commit d22df35cfc

View file

@ -1,7 +1,7 @@
import fs from 'fs';
import git from 'isomorphic-git';
import http from 'isomorphic-git/http/node';
import http, { GitProgressEvent } from 'isomorphic-git/http/node';
import { isVacantAndWriteable, pointsToLFS } from './util';
import downloadBlobFromPointer from './download';
@ -11,6 +11,9 @@ import { readPointer } from "./pointers";
const SYMLINK_MODE = 40960;
type ProgressHandler = (progress: GitProgressEvent) => void
/**
* Populates LFS cache for each repository object that is an LFS pointer.
*
@ -18,55 +21,60 @@ const SYMLINK_MODE = 40960;
*
* NOTE: If LFS cache path, as extracted from the pointer,
* is not writeable at the time of download start,
* the object will be silently skipped;
* if LFS cache path is not writeable at the time download completes,
* an error will be thrown.
* the object will be silently skipped.
*
* NOTE: This function skips objects silently in case of errors.
*
* NOTE: onProgress currently doesnt report loaded/total values accurately.
*/
export default async function populateCache(workDir: string, ref: string = 'HEAD') {
const remoteURL = await git.getConfig({
export default async function populateCache(
workDir: string,
remoteURL: string,
ref: string = 'HEAD',
onProgress?: ProgressHandler,
) {
await git.walk({
fs,
dir: workDir,
path: 'remote.origin.url',
});
if (remoteURL) {
await git.walk({
fs,
dir: workDir,
trees: [git.TREE({ ref })],
map: async function lfsDownloadingWalker(filepath, entries) {
if (entries === null || entries[0] === null) {
return null;
}
trees: [git.TREE({ ref })],
map: async function lfsDownloadingWalker(filepath, entries) {
const [entry] = entries;
const entryType = await entry.type();
if (entries === null || entries[0] === null) {
return null;
}
if (entryType === 'tree') {
// Walk children
return true;
onProgress?.({ phase: `skimming: ${filepath}`, loaded: 5, total: 10 });
} else if (entryType === 'blob' && (await entry.mode()) !== SYMLINK_MODE) {
const content = await entry.content();
const [entry] = entries;
const entryType = await entry.type();
if (content) {
const buff = Buffer.from(content.buffer);
if (entryType === 'tree') {
// Walk children
return true;
if (pointsToLFS(buff)) {
const pointer = readPointer({ dir: workDir, content: buff });
} else if (entryType === 'blob' && (await entry.mode()) !== SYMLINK_MODE) {
const content = await entry.content();
// Dont even start the download if LFS cache path is not accessible,
// or if it already exists
if (await isVacantAndWriteable(pointer.objectPath) === false)
return;
if (content) {
const buff = Buffer.from(content.buffer);
if (pointsToLFS(buff)) {
await downloadBlobFromPointer({ http, url: remoteURL }, pointer);
const pointer = readPointer({ dir: workDir, content: buff });
// Dont even start the download if LFS cache path is not accessible,
// or if it already exists
if (await isVacantAndWriteable(pointer.objectPath) === false)
return;
onProgress?.({ phase: `downloading: ${filepath}`, loaded: 5, total: 10 });
await downloadBlobFromPointer({ http, url: remoteURL }, pointer);
}
}
}
return;
}
});
}
return;
}
});
}