Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions src/cli/check.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ import {
type ReferenceUpdateAction,
type RenameAction,
} from "../migrator.js";
import { MAX_STEP_FILE_PREVIEW_LINES, limitLines } from "./ui.js";
import {
MAX_STEP_FILE_PREVIEW_LINES,
createScanProgressBarReporter,
limitLines,
} from "./ui.js";

function getErrorMessage(err: unknown): string {
if (err instanceof Error) return err.message;
Expand All @@ -16,7 +20,10 @@ function getErrorMessage(err: unknown): string {

export async function runCheck(): Promise<void> {
try {
const plan = await planMigration();
const scanProgress = createScanProgressBarReporter(
Boolean(process.stdin.isTTY && process.stdout.isTTY),
);
const plan = await planMigration({ onProgress: scanProgress });

const renames = plan.actions.filter(
(a): a is RenameAction => a.type === "rename",
Expand All @@ -31,8 +38,7 @@ export async function runCheck(): Promise<void> {
if (
renames.length === 0 &&
frontmatters.length === 0 &&
references.length === 0 &&
true
references.length === 0
) {
process.stdout.write("OK: repo matches SimpleDoc conventions.\n");
return;
Expand Down
6 changes: 5 additions & 1 deletion src/cli/migrate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
import type { InstallAction } from "../installer.js";
import {
MAX_STEP_FILE_PREVIEW_LINES,
createScanProgressBarReporter,
limitLines,
noteWrapped,
promptConfirm,
Expand Down Expand Up @@ -182,7 +183,10 @@ export async function runMigrate(options: MigrateOptions): Promise<void> {
process.stderr.write(
"Planning changes (this may take a while on large repos)...\n",
);
const planAll = await planMigration();
const scanProgress = createScanProgressBarReporter(
Boolean(process.stdin.isTTY && process.stdout.isTTY),
);
const planAll = await planMigration({ onProgress: scanProgress });
const installStatus = await getInstallationStatus(planAll.repoRootAbs);

const installActionsAll = await buildInstallationActions({
Expand Down
30 changes: 30 additions & 0 deletions src/cli/ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,3 +128,33 @@ export async function promptSelect<T extends string>(
if (isCancel(value)) return null;
return value as T;
}

export function createScanProgressBarReporter(
enabled: boolean,
): (info: { phase: "scan"; current: number; total: number }) => void {
if (!enabled) return () => {};
let lastLineLength = 0;
let lastTick = 0;
return (info) => {
if (info.phase !== "scan") return;
const now = Date.now();
if (now - lastTick < 80 && info.current !== info.total) return;
lastTick = now;

const cols = process.stdout.columns ?? 80;
const barWidth = Math.max(10, Math.min(40, cols - 35));
const ratio = info.total === 0 ? 1 : info.current / info.total;
const filled = Math.min(barWidth, Math.round(barWidth * ratio));
const empty = Math.max(0, barWidth - filled);
const bar = `${"#".repeat(filled)}${"-".repeat(empty)}`;
const percent = Math.min(100, Math.round(ratio * 100));
const line = `Scanning repo files: [${bar}] ${info.current}/${info.total} ${percent}%`;
const padded =
line.length >= lastLineLength
? line
: `${line}${" ".repeat(lastLineLength - line.length)}`;
lastLineLength = padded.length;
process.stderr.write(`\r${padded}`);
if (info.current === info.total) process.stderr.write("\n");
};
}
12 changes: 11 additions & 1 deletion src/migrator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,11 @@ export type MigrationPlanOptions = {
forceUndatedPaths?: string[];
includeCanonicalRenames?: boolean;
normalizeDatePrefixedDocs?: boolean;
onProgress?: (info: {
phase: "scan";
current: number;
total: number;
}) => void;
git?: GitClient;
};

Expand All @@ -339,6 +344,7 @@ export async function planMigration(
const includeCanonicalRenames = options.includeCanonicalRenames ?? true;
const normalizeDatePrefixedDocs = options.normalizeDatePrefixedDocs ?? true;
const git = options.git ?? createGitClient();
const onProgress = options.onProgress;

const repoRootAbs = await git.getRepoRoot(cwd);
const dirty = await git.isDirty(repoRootAbs);
Expand All @@ -357,8 +363,12 @@ export async function planMigration(

const existingAll = await git.listRepoFiles(repoRootAbs);
const existingOnDisk: string[] = [];
for (const filePath of existingAll) {
const totalFiles = existingAll.length;
for (let idx = 0; idx < existingAll.length; idx++) {
const filePath = existingAll[idx]!;
if (await pathExists(repoRootAbs, filePath)) existingOnDisk.push(filePath);
if (onProgress)
onProgress({ phase: "scan", current: idx + 1, total: totalFiles });
}
const existingAllSet = new Set(existingOnDisk);

Expand Down