@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.
174 lines • 16.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 {
constructor(cwdArg) {
this.smartshellInstance = new plugins.smartshell.Smartshell({
executor: 'bash',
});
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'),
};
}
/**
* 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 = plugins.smartfile.fs.fileExistsSync(this.filePaths.metaJson);
if (!metaFileExists) {
throw new Error(`meta file does not exist at ${this.filePaths.metaJson}`);
}
this.metaRepoData = plugins.smartfile.fs.toObjectSync(this.filePaths.metaJson);
}
/**
* 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
plugins.smartfile.memory.toFsSync(JSON.stringify(this.metaRepoData, null, 2), this.filePaths.metaJson);
// write .gitignore to disk
plugins.smartfile.memory.toFsSync(await this.generateGitignore(), this.filePaths.gitIgnore);
}
/**
* 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 projects = plugins.smartfile.fs.toObjectSync(this.filePaths.metaJson).projects;
const preExistingFolders = plugins.smartfile.fs.listFoldersSync(this.cwd);
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)) {
plugins.smartfile.fs.isDirectory(key)
? logger.log('ok', `${key} -> is already cloned`)
: 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 folders = await plugins.smartfile.fs.listFolders(this.cwd);
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.smartfile.fs.fileExists(this.filePaths.metaJson);
if (!fileExists) {
await plugins.smartfile.memory.toFs(JSON.stringify({
projects: {},
}), this.filePaths.metaJson);
logger.log(`success`, `created a new .meta.json in directory ${this.cwd}`);
await plugins.smartfile.memory.toFs(JSON.stringify({
name: this.dirName,
version: '1.0.0',
}), this.filePaths.packageJson);
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.smartfile.fs.remove(plugins.path.join(paths.cwd, projectNameArg));
await this.updateLocalRepos();
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWV0YS5jbGFzc2VzLm1ldGEuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9tb2RfbWV0YS9tZXRhLmNsYXNzZXMubWV0YS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLG1CQUFtQixDQUFDO0FBQzdDLE9BQU8sS0FBSyxLQUFLLE1BQU0sYUFBYSxDQUFDO0FBQ3JDLE9BQU8sS0FBSyxVQUFVLE1BQU0sc0JBQXNCLENBQUM7QUFFbkQsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBRS9DLE1BQU0sT0FBTyxJQUFJO0lBU2YsWUFBWSxNQUFjO1FBY25CLHVCQUFrQixHQUFHLElBQUksT0FBTyxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUM7WUFDNUQsUUFBUSxFQUFFLE1BQU07U0FDakIsQ0FBQyxDQUFDO1FBZkQsSUFBSSxDQUFDLEdBQUcsR0FBRyxNQUFNLENBQUM7UUFDbEIsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDL0MsSUFBSSxDQUFDLFNBQVMsR0FBRztZQUNmLFFBQVEsRUFBRSxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLGNBQWMsQ0FBQztZQUNyRCxTQUFTLEVBQUUsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxjQUFjLENBQUM7WUFDdEQsV0FBVyxFQUFFLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsZ0JBQWdCLENBQUM7U0FDM0QsQ0FBQztJQUNKLENBQUM7SUFVRDs7T0FFRztJQUNJLEtBQUssQ0FBQyxnQkFBZ0I7UUFDM0IsTUFBTSxtQkFBbUIsR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FDckQsSUFBSSxD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