/** * Copyright 2023 Kapeta Inc. * SPDX-License-Identifier: BUSL-1.1 */ import download from 'download-git-repo'; import { PredefinedBlock } from './predefined'; import * as fs from 'node:fs'; import path from 'path'; import { GeneratedFile, GeneratedResult } from '@kapeta/codegen'; export class Archetype { public async cloneRepository( predefinedBlock: PredefinedBlock, targetDir: string, basePath: string ): Promise { const downloadDirectory = `${targetDir}/download`; await this.downloadRepo( predefinedBlock.getGitRepo().owner + '/' + predefinedBlock.getGitRepo().repo, downloadDirectory ); await this.copyToBasePathAndRemoveDownload(downloadDirectory, predefinedBlock.getGitRepo().path, basePath); return this.convertToGeneratedResult(basePath); } private async copyToBasePathAndRemoveDownload(downloadDirectory: string, subPath: string, targetDir: string) { const fullSourcePath = path.resolve(`${downloadDirectory}/${subPath}`); const fullDestinationPath = path.resolve(targetDir); try { await fs.promises.cp(fullSourcePath, fullDestinationPath, { recursive: true }); console.log(`Directory copied: ${fullSourcePath} -> ${fullDestinationPath}`); } catch (err) { console.error(`Error copying directory: ${err}`); } finally { await fs.promises.rm(downloadDirectory, { recursive: true, force: true }); } } private async convertToGeneratedResult(basePath: string): Promise { const generatedFiles: GeneratedFile[] = []; async function traverse(currentPath: string, basePath: string): Promise { const files = await fs.promises.readdir(currentPath, { withFileTypes: true }); for (const file of files) { const fullPath = path.join(currentPath, file.name); if (file.isFile()) { const stats = await fs.promises.stat(fullPath); const mode = stats.mode.toString(8); const permissions = stats.mode.toString(8).slice(-3); const content = await fs.promises.readFile(fullPath); const generatedFile: GeneratedFile = { filename: fullPath.replace(basePath + '/', ''), content: content.toString(), mode: mode, permissions: permissions, }; generatedFiles.push(generatedFile); } else if (file.isDirectory()) { await traverse(fullPath, basePath); } } } await traverse(basePath, basePath); return { files: generatedFiles } as GeneratedResult; } private downloadRepo(url: string, dest: string): Promise { return new Promise((resolve, reject) => { download(url, dest, function (err: Error) { if (err) { reject(err); } else { resolve(); } }); }); } }