import { promises as fs } from "fs"; import path from "path"; import os from "os"; const skeleton: Record = { "name": "PackageName", "version": "0.1.0", "vendor": "Center for Digital Resilience", "license": "AGPL-v3+", "url": "https://gitlab.com/digiresilience/link/zammad-addon-package-name", "buildhost": "", "builddate": "", "change_log": [ { "version": "0.0.1", "date": "2020-02-11", "log": "Some changes" } ], "description": [ { "language": "en", "text": "Change me" } ], "files": [] } const packageFile = async (actualPath: string): Promise => { console.log(`Packaging: ${actualPath}`); const packagePath = actualPath.slice(4); const data = await fs.readFile(actualPath, "utf-8"); const content = Buffer.from(data, "utf-8").toString("base64"); const fileStats = await fs.stat(actualPath); const permission = parseInt((fileStats.mode & 0o777).toString(8).slice(-3), 10); return { location: packagePath, permission, encode: "base64", content, }; } const packageFiles = async () => { const packagedFiles: any[] = []; const ignoredPatterns = [/\.gitkeep/]; const processDir = async (dir: string) => { const entries = await fs.readdir(dir, { withFileTypes: true }); for (const entry of entries) { const entryPath = path.join(dir, entry.name); if (entry.isDirectory()) { await processDir(entryPath); } else if (entry.isFile()) { if (!ignoredPatterns.some((pattern) => pattern.test(entry.name))) { packagedFiles.push(await packageFile(entryPath)); } } } }; await processDir("./src/"); return packagedFiles; } const underscore = (str: string) => { return str .replace(/([a-z\d])([A-Z])/g, "$1_$2") .replace(/([A-Z]+)([A-Z][a-z\d]+)/g, "$1_$2") .toLowerCase(); } const camelize = (str: string): string => { const camelizedStr = str.replace(/_([a-z])/g, (g) => g[1].toUpperCase()); return camelizedStr.charAt(0).toUpperCase() + camelizedStr.slice(1); } export const createZPM = async ({ name, version }: Record) => { const files = await packageFiles(); skeleton.files = files; skeleton.builddate = new Date().toISOString(); skeleton.buildhost = os.hostname(); const pkg = JSON.stringify(skeleton, null, 2); await fs.writeFile(`../../docker/zammad/auto_install/${name}-v${version}.zpm`, pkg, 'utf-8'); } export const createMigration = async ({ packageName}: Record) => { const rawName: string = await new Promise((resolve) => { process.stdin.setEncoding("utf-8"); process.stdout.write("Enter migration name: "); process.stdin.once("data", (data: string) => { resolve(data.trim()); }); }); const migrationBaseName = `${packageName}_${underscore(rawName)}`; const migrationName = camelize(migrationBaseName); const migrationTemplate = `class MIGRATION_NAME < ActiveRecord::Migration[5.2] def self.up # add your code here end def self.down # add your code here end end`; const contents = migrationTemplate.replace("MIGRATION_NAME", migrationName); const time = new Date().toISOString().replace(/[-:.]/g, "").slice(0, 14); const migrationFileName = `${time}_${migrationBaseName}.rb`; const addonDir = path.join("src", "db", "addon", skeleton["name"]); await fs.mkdir(addonDir, { recursive: true }); await fs.writeFile(path.join(addonDir, migrationFileName), contents); }