UNPKG

@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
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWV0YS5jbGFzc2VzLm1ldGEuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9tb2RfbWV0YS9tZXRhLmNsYXNzZXMubWV0YS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLG1CQUFtQixDQUFDO0FBQzdDLE9BQU8sS0FBSyxLQUFLLE1BQU0sYUFBYSxDQUFDO0FBQ3JDLE9BQU8sS0FBSyxVQUFVLE1BQU0sc0JBQXNCLENBQUM7QUFFbkQsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBRS9DLE1BQU0sT0FBTyxJQUFJO0lBU2YsWUFBWSxNQUFjO1FBY25CLHVCQUFrQixHQUFHLElBQUksT0FBTyxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUM7WUFDNUQsUUFBUSxFQUFFLE1BQU07U0FDakIsQ0FBQyxDQUFDO1FBZkQsSUFBSSxDQUFDLEdBQUcsR0FBRyxNQUFNLENBQUM7UUFDbEIsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDL0MsSUFBSSxDQUFDLFNBQVMsR0FBRztZQUNmLFFBQVEsRUFBRSxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLGNBQWMsQ0FBQztZQUNyRCxTQUFTLEVBQUUsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxjQUFjLENBQUM7WUFDdEQsV0FBVyxFQUFFLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsZ0JBQWdCLENBQUM7U0FDM0QsQ0FBQztJQUNKLENBQUM7SUFVRDs7T0FFRztJQUNJLEtBQUssQ0FBQyxnQkFBZ0I7UUFDM0IsTUFBTSxtQkFBbUIsR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENB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