smartgit/ts/smartgit.classes.gitrepo.ts

229 lines
6.3 KiB
TypeScript
Raw Permalink Normal View History

2022-07-31 13:14:18 +00:00
import * as plugins from './smartgit.plugins.js';
import { Smartgit } from './smartgit.classes.smartgit.js';
2016-11-21 23:07:36 +00:00
/**
* class GitRepo allows access to git directories from node
*/
export class GitRepo {
2019-06-18 13:17:50 +00:00
// STATIC
/**
* creates a new GitRepo Instance after cloning a project
*/
public static async fromCloningIntoDir(
smartgitRefArg: Smartgit,
fromArg: string,
toArg: string
): Promise<GitRepo> {
2019-06-18 13:41:03 +00:00
const dirArg = plugins.path.resolve(toArg);
await plugins.isomorphicGit.clone({
dir: toArg,
fs: smartgitRefArg.envDeps.fs,
http: smartgitRefArg.envDeps.http,
url: fromArg,
2019-06-18 13:41:03 +00:00
});
return new GitRepo(smartgitRefArg, toArg);
2019-06-18 13:41:03 +00:00
}
public static async fromCreatingRepoInDir(
smartgitRefArg: Smartgit,
dirArg: string
): Promise<GitRepo> {
2019-06-18 13:41:03 +00:00
dirArg = plugins.path.resolve(dirArg);
await plugins.isomorphicGit.init({
dir: dirArg,
fs: smartgitRefArg.envDeps.fs,
});
return new GitRepo(smartgitRefArg, dirArg);
2019-06-18 13:41:03 +00:00
}
public static async fromOpeningRepoDir(smartgitRefArg: Smartgit, dirArg: string) {
2019-06-18 13:41:03 +00:00
dirArg = plugins.path.resolve(dirArg);
return new GitRepo(smartgitRefArg, dirArg);
2019-06-18 13:41:03 +00:00
}
// INSTANCE
public smartgitRef: Smartgit;
public repoDir: string;
2019-06-18 13:41:03 +00:00
constructor(smartgitRefArg: Smartgit, repoDirArg: string) {
this.smartgitRef = smartgitRefArg;
this.repoDir = repoDirArg;
2019-06-18 13:17:50 +00:00
}
/**
2019-06-18 13:41:03 +00:00
* lists remotes
2019-06-18 13:17:50 +00:00
*/
public async listRemotes(): Promise<
{
remote: string;
url: string;
}[]
> {
const remotes = await plugins.isomorphicGit.listRemotes({
fs: this.smartgitRef.envDeps.fs,
dir: this.repoDir,
});
return remotes;
2019-06-18 13:17:50 +00:00
}
2019-08-27 14:02:04 +00:00
/**
2024-06-22 00:44:19 +00:00
* ensures the existence of a remote within a repository
2019-08-27 14:02:04 +00:00
* @param remoteNameArg
2020-08-15 13:51:24 +00:00
* @param remoteUrlArg
2019-08-27 14:02:04 +00:00
*/
2019-06-20 12:19:54 +00:00
public async ensureRemote(remoteNameArg: string, remoteUrlArg: string): Promise<void> {
const remotes = await this.listRemotes();
2022-07-31 13:18:04 +00:00
const existingRemote = remotes.find((itemArg) => itemArg.remote === remoteNameArg);
if (existingRemote) {
if (existingRemote.url !== remoteUrlArg) {
await plugins.isomorphicGit.deleteRemote({
remote: remoteNameArg,
fs: this.smartgitRef.envDeps.fs,
2022-07-31 13:18:04 +00:00
dir: this.repoDir,
});
} else {
return;
2022-07-31 13:18:04 +00:00
}
2019-06-20 12:19:54 +00:00
}
await plugins.isomorphicGit.addRemote({
remote: remoteNameArg,
fs: this.smartgitRef.envDeps.fs,
2022-07-31 13:18:04 +00:00
url: remoteUrlArg,
});
2019-06-20 12:19:54 +00:00
}
2019-06-18 13:17:50 +00:00
2019-06-18 13:41:03 +00:00
/**
* gets the url for a specific remote
*/
2019-06-20 12:19:54 +00:00
public async getUrlForRemote(remoteName: string): Promise<string> {
const remotes = await this.listRemotes();
2022-07-31 13:18:04 +00:00
const existingRemote = remotes.find((remoteArg) => remoteArg.remote === remoteName);
return existingRemote?.url;
2019-06-18 13:41:03 +00:00
}
public async pushBranchToRemote(branchName: string, remoteName: string) {
await plugins.isomorphicGit.push({
fs: this.smartgitRef.envDeps.fs,
http: this.smartgitRef.envDeps.http,
ref: branchName,
2022-07-31 13:18:04 +00:00
remote: remoteName,
});
2019-06-18 13:41:03 +00:00
}
2024-06-22 00:44:19 +00:00
/**
* Get the diff of the current uncommitted changes while excluding specified files
*/
public async getUncommittedDiff(excludeFiles: string[] = []): Promise<string[]> {
const statusMatrix = await plugins.isomorphicGit.statusMatrix({
fs: this.smartgitRef.envDeps.fs,
dir: this.repoDir,
});
const diffs: string[] = [];
for (const row of statusMatrix) {
const [filepath, head, workdir] = row;
if (excludeFiles.includes(filepath)) {
continue; // Skip excluded files
}
let headContent = '';
let workdirContent = '';
// Handle modified files
if (head !== 0 && workdir !== 0 && head !== workdir) {
headContent = await plugins.isomorphicGit
.readBlob({
2024-06-22 00:44:19 +00:00
fs: this.smartgitRef.envDeps.fs,
dir: this.repoDir,
oid: await plugins.isomorphicGit.resolveRef({
fs: this.smartgitRef.envDeps.fs,
dir: this.repoDir,
ref: 'HEAD',
}),
filepath,
})
.then((result) => new TextDecoder().decode(result.blob));
workdirContent = await this.smartgitRef.envDeps.fs.promises.readFile(
plugins.path.join(this.repoDir, filepath),
'utf8'
);
2024-06-22 00:44:19 +00:00
}
// Handle added files
if (head === 0 && workdir !== 0) {
workdirContent = await this.smartgitRef.envDeps.fs.promises.readFile(
plugins.path.join(this.repoDir, filepath),
'utf8'
);
2024-06-22 00:44:19 +00:00
}
// Handle deleted files
if (head !== 0 && workdir === 0) {
headContent = await plugins.isomorphicGit
.readBlob({
2024-06-22 00:44:19 +00:00
fs: this.smartgitRef.envDeps.fs,
dir: this.repoDir,
oid: await plugins.isomorphicGit.resolveRef({
fs: this.smartgitRef.envDeps.fs,
dir: this.repoDir,
ref: 'HEAD',
}),
filepath,
})
.then((result) => new TextDecoder().decode(result.blob));
2024-06-22 00:44:19 +00:00
}
if (headContent || workdirContent) {
const diff = plugins.diff.createTwoFilesPatch(
filepath,
filepath,
headContent,
workdirContent
);
2024-06-22 00:44:19 +00:00
diffs.push(diff);
}
}
return diffs;
}
2024-06-22 08:01:15 +00:00
/**
* Get all commit messages with their dates and package.json version at each commit
2024-06-22 08:01:15 +00:00
*/
public async getAllCommitMessages(): Promise<
{ date: string; version: string; message: string }[]
> {
2024-06-22 08:01:15 +00:00
const commits = await plugins.isomorphicGit.log({
fs: this.smartgitRef.envDeps.fs,
dir: this.repoDir,
});
const results = [];
for (const commit of commits) {
let version = 'unknown';
try {
const packageJsonBlob = await plugins.isomorphicGit.readBlob({
fs: this.smartgitRef.envDeps.fs,
dir: this.repoDir,
oid: commit.oid,
filepath: 'package.json',
});
const packageJson = JSON.parse(new TextDecoder().decode(packageJsonBlob.blob));
version = packageJson.version;
} catch (error) {
// If package.json does not exist or any error occurs, leave version as 'unknown'
}
results.push({
date: new plugins.smarttime.ExtendedDate(commit.commit.committer.timestamp * 1000).exportToHyphedSortableDate(),
version: version,
message: commit.commit.message,
});
}
return results;
2024-06-22 08:01:15 +00:00
}
2016-11-21 23:07:36 +00:00
}