@git.zone/cli
Version:
A comprehensive CLI tool for enhancing and managing local development workflows with gitzone utilities, focusing on project setup, version control, code formatting, and template management.
246 lines • 20.5 kB
JavaScript
import * as plugins from './meta.plugins.js';
import * as paths from '../paths.js';
import * as interfaces from './meta.interfaces.js';
import { logger } from '../gitzone.logging.js';
export class Meta {
cwd;
dirName;
filePaths;
constructor(cwdArg) {
this.cwd = cwdArg;
this.dirName = plugins.path.basename(this.cwd);
this.filePaths = {
metaJson: plugins.path.join(this.cwd, './.meta.json'),
gitIgnore: plugins.path.join(this.cwd, './.gitignore'),
packageJson: plugins.path.join(this.cwd, './package.json'),
};
}
/**
* the meta repo data
*/
metaRepoData;
smartshellInstance = new plugins.smartshell.Smartshell({
executor: 'bash',
});
/**
* sorts the metaRepoData
*/
async sortMetaRepoData() {
const stringifiedMetadata = plugins.smartjson.stringify(this.metaRepoData, []);
this.metaRepoData = plugins.smartjson.parse(stringifiedMetadata);
}
/**
* reads the meta file from disk
*/
async readDirectory() {
await this.syncToRemote(true);
logger.log('info', `reading directory`);
const metaFileExists = await plugins.smartfs
.file(this.filePaths.metaJson)
.exists();
if (!metaFileExists) {
throw new Error(`meta file does not exist at ${this.filePaths.metaJson}`);
}
const content = (await plugins.smartfs
.file(this.filePaths.metaJson)
.encoding('utf8')
.read());
this.metaRepoData = JSON.parse(content);
}
/**
* generates the gitignore file and stores it on disk
*/
async generateGitignore() {
await this.sortMetaRepoData();
let gitignoreString = `# ignored repo directories\n`;
gitignoreString += `.nogit/\n`;
gitignoreString += `.pnpm-store/\n`;
for (const key of Object.keys(this.metaRepoData.projects)) {
gitignoreString = `${gitignoreString}${key}\n`;
}
return gitignoreString;
}
/**
* write to disk
*/
async writeToDisk() {
// write .meta.json to disk
await plugins.smartfs
.file(this.filePaths.metaJson)
.encoding('utf8')
.write(JSON.stringify(this.metaRepoData, null, 2));
// write .gitignore to disk
await plugins.smartfs
.file(this.filePaths.gitIgnore)
.encoding('utf8')
.write(await this.generateGitignore());
}
/**
* push to remote
*/
async syncToRemote(gitCleanArg = false) {
logger.log('info', `syncing from origin master`);
await this.smartshellInstance.exec(`cd ${this.cwd} && git pull origin master`);
if (gitCleanArg) {
logger.log('info', `cleaning the repository from old directories`);
await this.smartshellInstance.exec(`cd ${this.cwd} && git clean -fd`);
}
logger.log('info', `syncing to remote origin master`);
await this.smartshellInstance.exec(`cd ${this.cwd} && git push origin master`);
}
/**
* update the locally cloned repositories
*/
async updateLocalRepos() {
await this.syncToRemote();
const metaContent = (await plugins.smartfs
.file(this.filePaths.metaJson)
.encoding('utf8')
.read());
const projects = JSON.parse(metaContent).projects;
const entries = await plugins.smartfs.directory(this.cwd).list();
const preExistingFolders = [];
for (const entry of entries) {
try {
const stats = await plugins.smartfs
.file(plugins.path.join(this.cwd, entry.path))
.stat();
if (stats.isDirectory) {
preExistingFolders.push(entry.name);
}
}
catch {
// Skip entries that can't be accessed
}
}
for (const preExistingFolderArg of preExistingFolders) {
if (preExistingFolderArg !== '.git' &&
!Object.keys(projects).find((projectFolder) => projectFolder.startsWith(preExistingFolderArg))) {
const response = await plugins.smartinteraction.SmartInteract.getCliConfirmation(`Do you want to delete superfluous directory >>${preExistingFolderArg}<< ?`, true);
if (response) {
logger.log('warn', `Deleting >>${preExistingFolderArg}<<!`);
}
else {
logger.log('warn', `Not deleting ${preExistingFolderArg} by request!`);
}
}
}
await this.readDirectory();
await this.sortMetaRepoData();
const missingRepos = [];
for (const key of Object.keys(this.metaRepoData.projects)) {
const fullPath = plugins.path.join(this.cwd, key);
try {
const stats = await plugins.smartfs.file(fullPath).stat();
if (stats.isDirectory) {
logger.log('ok', `${key} -> is already cloned`);
}
else {
missingRepos.push(key);
}
}
catch {
missingRepos.push(key);
}
}
logger.log('info', `found ${missingRepos.length} missing repos`);
for (const missingRepo of missingRepos) {
await this.smartshellInstance.exec(`cd ${this.cwd} && git clone ${this.metaRepoData.projects[missingRepo]} ${missingRepo}`);
}
logger.log('info', `write changes to disk`);
await this.writeToDisk();
logger.log('info', `persist changes with a git commit`);
await this.smartshellInstance.exec(`cd ${this.cwd} && git add -A && git commit -m "updated structure"`);
await this.syncToRemote();
// go recursive
const listEntries = await plugins.smartfs.directory(this.cwd).list();
const folders = [];
for (const entry of listEntries) {
try {
const stats = await plugins.smartfs
.file(plugins.path.join(this.cwd, entry.path))
.stat();
if (stats.isDirectory) {
folders.push(entry.name);
}
}
catch {
// Skip entries that can't be accessed
}
}
const childMetaRepositories = [];
for (const folder of folders) {
logger.log('info', folder);
}
console.log('Recursion still needs to be implemented');
}
// project manipulation
/**
* init a new meta project
*/
async initProject() {
await this.syncToRemote(true);
const fileExists = await plugins.smartfs
.file(this.filePaths.metaJson)
.exists();
if (!fileExists) {
await plugins.smartfs
.file(this.filePaths.metaJson)
.encoding('utf8')
.write(JSON.stringify({
projects: {},
}));
logger.log(`success`, `created a new .meta.json in directory ${this.cwd}`);
await plugins.smartfs
.file(this.filePaths.packageJson)
.encoding('utf8')
.write(JSON.stringify({
name: this.dirName,
version: '1.0.0',
}));
logger.log(`success`, `created a new package.json in directory ${this.cwd}`);
}
else {
logger.log(`error`, `directory ${this.cwd} already has a .metaJson file. Doing nothing.`);
}
await this.smartshellInstance.exec(`cd ${this.cwd} && git add -A && git commit -m "feat(project): init meta project for ${this.dirName}"`);
await this.updateLocalRepos();
}
/**
* adds a project
*/
async addProject(projectNameArg, gitUrlArg) {
await this.readDirectory();
const existingProject = this.metaRepoData.projects[projectNameArg];
if (existingProject) {
throw new Error('Project already exists! Please remove it first before adding it again.');
}
this.metaRepoData.projects[projectNameArg] = gitUrlArg;
await this.sortMetaRepoData();
await this.writeToDisk();
await this.smartshellInstance.exec(`cd ${this.cwd} && git add -A && git commit -m "feat(project): add ${projectNameArg}"`);
await this.updateLocalRepos();
}
/**
* removes a project
*/
async removeProject(projectNameArg) {
await this.readDirectory();
const existingProject = this.metaRepoData.projects[projectNameArg];
if (!existingProject) {
logger.log('error', `Project ${projectNameArg} does not exist! So it cannot be removed`);
return;
}
delete this.metaRepoData.projects[projectNameArg];
logger.log('info', 'removing project from .meta.json');
await this.sortMetaRepoData();
await this.writeToDisk();
logger.log('info', 'removing directory from cwd');
await plugins.smartfs
.directory(plugins.path.join(paths.cwd, projectNameArg))
.recursive()
.delete();
await this.updateLocalRepos();
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWV0YS5jbGFzc2VzLm1ldGEuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9tb2RfbWV0YS9tZXRhLmNsYXNzZXMubWV0YS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLG1CQUFtQixDQUFDO0FBQzdDLE9BQU8sS0FBSyxLQUFLLE1BQU0sYUFBYSxDQUFDO0FBQ3JDLE9BQU8sS0FBSyxVQUFVLE1BQU0sc0JBQXNCLENBQUM7QUFFbkQsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBRS9DLE1BQU0sT0FBTyxJQUFJO0lBQ1IsR0FBRyxDQUFTO0lBQ1osT0FBTyxDQUFTO0lBQ2hCLFNBQVMsQ0FJZDtJQUVGLFlBQVksTUFBYztRQUN4QixJQUFJLENBQUMsR0FBRyxHQUFHLE1BQU0sQ0FBQztRQUNsQixJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUMvQyxJQUFJLENBQUMsU0FBUyxHQUFHO1lBQ2YsUUFBUSxFQUFFLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsY0FBYyxDQUFDO1lBQ3JELFNBQVMsRUFBRSxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLGNBQWMsQ0FBQztZQUN0RCxXQUFXLEVBQUUsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxnQkFBZ0IsQ0FBQztTQUMzRCxDQUFDO0lBQ0osQ0FBQztJQUVEOztPQUVHO0lBQ0ksWUFBWSxDQUEyQjtJQUN2QyxrQkFBa0IsR0FBRyxJQUFJLE9BQU8sQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDO1FBQzVELFFBQVEsRUFBRSxNQUFNO0tBQ2pCLENBQUMsQ0FBQztJQUVIOztPQUVHO0lBQ0ksS0FB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