64 lines
1.3 KiB
TypeScript
64 lines
1.3 KiB
TypeScript
import { execa } from 'execa';
|
|
import { KnownError } from './error.js';
|
|
|
|
export const assertGitRepo = async () => {
|
|
const { stdout, failed } = await execa('git', ['rev-parse', '--show-toplevel'], { reject: false });
|
|
|
|
if (failed) {
|
|
throw new KnownError('The current directory must be a Git repository!');
|
|
}
|
|
|
|
return stdout;
|
|
};
|
|
|
|
const excludeFromDiff = (path: string) => `:(exclude)${path}`;
|
|
|
|
const filesToExclude = [
|
|
'package-lock.json',
|
|
'pnpm-lock.yaml',
|
|
|
|
// yarn.lock, Cargo.lock, Gemfile.lock, Pipfile.lock, etc.
|
|
'*.lock',
|
|
].map(excludeFromDiff);
|
|
|
|
export const getStagedDiff = async (excludeFiles?: string[]) => {
|
|
const diffCached = ['diff', '--cached', '--diff-algorithm=minimal'];
|
|
const { stdout: files } = await execa(
|
|
'git',
|
|
[
|
|
...diffCached,
|
|
'--name-only',
|
|
...filesToExclude,
|
|
...(
|
|
excludeFiles
|
|
? excludeFiles.map(excludeFromDiff)
|
|
: []
|
|
),
|
|
],
|
|
);
|
|
|
|
if (!files) {
|
|
return;
|
|
}
|
|
|
|
const { stdout: diff } = await execa(
|
|
'git',
|
|
[
|
|
...diffCached,
|
|
...filesToExclude,
|
|
...(
|
|
excludeFiles
|
|
? excludeFiles.map(excludeFromDiff)
|
|
: []
|
|
),
|
|
],
|
|
);
|
|
|
|
return {
|
|
files: files.split('\n'),
|
|
diff,
|
|
};
|
|
};
|
|
|
|
export const getDetectedMessage = (files: string[]) => `Detected ${files.length.toLocaleString()} staged file${files.length > 1 ? 's' : ''}`;
|