Skip to content

Commit

Permalink
Merge pull request #13 from zsqk/feat-git-changes
Browse files Browse the repository at this point in the history
feat: new fn gitChanges
  • Loading branch information
iugo committed Sep 7, 2022
2 parents fe99528 + 13e9509 commit 1528d1f
Show file tree
Hide file tree
Showing 3 changed files with 185 additions and 2 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

some functions for deno

功能:
通用 JS 功能 (浏览器环境兼容):

- hash
- SHA1
Expand All @@ -15,6 +15,10 @@ some functions for deno
- SHA512
- Uint8Array to hex string tools

依赖 Deno 运行时的功能:

- `gitChanges` 查看 Git 变动.

说明:

- csv2array 使用 Deno 标准库
Expand Down
98 changes: 97 additions & 1 deletion deno/git.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,102 @@
import { pullGitRepo } from './git.ts';
import { assertEquals } from 'https://deno.land/[email protected]/testing/asserts.ts';
import { gitChanges, pullGitRepo } from './git.ts';

Deno.test('pullGitRepo', async () => {
const res = await pullGitRepo('https://github.com/zsqk/deno-fn.git');
console.log(res);
});

Deno.test('gitChanges-newfile', async () => {
const path = await pullGitRepo('https://github.com/zsqk/deno-fn.git');
console.log(path);

Deno.writeTextFileSync(path + '/deno-fn/test.txt', '');
const res1 = await gitChanges(path + '/deno-fn');
assertEquals(res1, {
stagedFiles: [],
notStagedFiles: [{ type: 'newfile', fileName: 'test.txt' }],
});

const p2 = Deno.run({ cmd: ['git', 'add', '.'], cwd: path + '/deno-fn' });
await p2.status();
p2.close();

const res2 = await gitChanges(path + '/deno-fn');
assertEquals(res2, {
stagedFiles: [{ type: 'newfile', fileName: 'test.txt' }],
notStagedFiles: [],
});
});

Deno.test('gitChanges-modified', async () => {
const path = await pullGitRepo('https://github.com/zsqk/deno-fn.git');
console.log(path);

Deno.writeTextFileSync(path + '/deno-fn/README.md', '');
const res1 = await gitChanges(path + '/deno-fn');
assertEquals(res1, {
stagedFiles: [],
notStagedFiles: [{ type: 'modified', fileName: 'README.md' }],
});

const p2 = Deno.run({ cmd: ['git', 'add', '.'], cwd: path + '/deno-fn' });
await p2.status();
p2.close();

const res2 = await gitChanges(path + '/deno-fn');
assertEquals(res2, {
stagedFiles: [{ type: 'modified', fileName: 'README.md' }],
notStagedFiles: [],
});
});

Deno.test('gitChanges-rename', async () => {
const path = await pullGitRepo('https://github.com/zsqk/deno-fn.git');
console.log(path);

Deno.rename(path + '/deno-fn/README.md', path + '/deno-fn/README1.md');
const res1 = await gitChanges(path + '/deno-fn');
assertEquals(res1, {
stagedFiles: [],
notStagedFiles: [
{ type: 'deleted', fileName: 'README.md' },
{ type: 'newfile', fileName: 'README1.md' },
],
});

const p2 = Deno.run({ cmd: ['git', 'add', '.'], cwd: path + '/deno-fn' });
await p2.status();
p2.close();

const res2 = await gitChanges(path + '/deno-fn');
assertEquals(res2, {
stagedFiles: [{
type: 'renamed',
fileNameOld: 'README.md',
fileNameNew: 'README1.md',
}],
notStagedFiles: [],
});
});

Deno.test('gitChanges-delete', async () => {
const path = await pullGitRepo('https://github.com/zsqk/deno-fn.git');
console.log(path);

Deno.removeSync(path + '/deno-fn/README.md');
const res1 = await gitChanges(path + '/deno-fn');
assertEquals(res1, {
stagedFiles: [],
notStagedFiles: [{ type: 'deleted', fileName: 'README.md' }],
});

const p2 = Deno.run({ cmd: ['git', 'add', '.'], cwd: path + '/deno-fn' });
await p2.status();
p2.close();

const res2 = await gitChanges(path + '/deno-fn');
assertEquals(res2, {
stagedFiles: [{ type: 'deleted', fileName: 'README.md' }],
notStagedFiles: [],
});
});
83 changes: 83 additions & 0 deletions deno/git.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,86 @@ export async function pullGitRepo(repo: string, opt: {

return tempPath;
}

/**
* 查看本地 Git 仓库的变动
* @param repoPath repo 在本地的 path
*/
export async function gitChanges(repoPath: string) {
const res = Deno.run({
cmd: ['git', 'status', '--short'],
stdout: 'piped',
stderr: 'piped',
cwd: repoPath,
});
const output = new TextDecoder('utf-8').decode(await res.output());
const errMsg = new TextDecoder('utf-8').decode(await res.stderrOutput());
const status = await res.status();
res.close();
if (!status.success) {
throw new Error(`${status.code} ${errMsg}`);
}

type Changes =
| { type: 'modified'; fileName: string }
| { type: 'deleted'; fileName: string }
| { type: 'renamed'; fileNameOld: string; fileNameNew: string }
| { type: 'newfile'; fileName: string };

const stagedFiles: Changes[] = [];
const notStagedFiles: Changes[] = [];
for (const change of output.split('\n')) {
const type = change.slice(0, 2);
const fileName = change.slice(3);
if (type === '??') {
notStagedFiles.push({ type: 'newfile', fileName });
continue;
}
if (type === '!!') {
continue;
}
switch (type[0]) {
case 'A':
stagedFiles.push({ type: 'newfile', fileName });
break;

case 'M':
stagedFiles.push({ type: 'modified', fileName });
break;

case 'D':
stagedFiles.push({ type: 'deleted', fileName });
break;

case 'R': {
const [fileNameOld, fileNameNew] = fileName.trim().split(' -> ');
stagedFiles.push({
type: 'renamed',
fileNameNew,
fileNameOld,
});
break;
}

default:
// TODO: C, U
break;
}

switch (type[1]) {
case 'M':
notStagedFiles.push({ type: 'modified', fileName });
break;

case 'D':
notStagedFiles.push({ type: 'deleted', fileName });
break;

default:
// TODO: A, R, C, U
break;
}
}

return { stagedFiles, notStagedFiles };
}

0 comments on commit 1528d1f

Please sign in to comment.