Continue addon reorg
This commit is contained in:
parent
7b13e6ff71
commit
e4450c37ee
17 changed files with 303 additions and 174 deletions
19
package-lock.json
generated
19
package-lock.json
generated
|
|
@ -22487,6 +22487,14 @@
|
||||||
"node": "^12.20.0 || >=14"
|
"node": "^12.20.0 || >=14"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/zammad-addon-common": {
|
||||||
|
"resolved": "packages/zammad-addon-common",
|
||||||
|
"link": true
|
||||||
|
},
|
||||||
|
"node_modules/zammad-addon-pgp": {
|
||||||
|
"resolved": "packages/zammad-addon-pgp",
|
||||||
|
"link": true
|
||||||
|
},
|
||||||
"node_modules/zen-observable": {
|
"node_modules/zen-observable": {
|
||||||
"version": "0.8.15",
|
"version": "0.8.15",
|
||||||
"resolved": "https://registry.npmjs.org/zen-observable/-/zen-observable-0.8.15.tgz",
|
"resolved": "https://registry.npmjs.org/zen-observable/-/zen-observable-0.8.15.tgz",
|
||||||
|
|
@ -25417,6 +25425,17 @@
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"packages/zammad-addon-common": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
|
"packages/zammad-addon-pgp": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"zammad-addon-common": "*"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
.PHONY: prep clean
|
|
||||||
|
|
||||||
build: prep
|
|
||||||
@./package.py
|
|
||||||
@find dist/ -iname "*szpm"
|
|
||||||
|
|
||||||
prep:
|
|
||||||
@mkdir -p dist
|
|
||||||
|
|
||||||
clean: prep
|
|
||||||
@rm -rf dist/*
|
|
||||||
|
|
||||||
fmt:
|
|
||||||
rufo src
|
|
||||||
|
|
||||||
new-migration:
|
|
||||||
@./new-migration.py
|
|
||||||
|
|
||||||
init:
|
|
||||||
@echo "Give your addon a name. No spaces."
|
|
||||||
@echo "Addon name?: "; \
|
|
||||||
read NAME; \
|
|
||||||
mkdir -p "src/db/addon/$${NAME}"; \
|
|
||||||
sed -i "s/NAME/$${NAME}/" base.szpm.template; \
|
|
||||||
mv base.szpm.template "$${NAME}.szpm.template"
|
|
||||||
|
|
||||||
test: build
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
{
|
|
||||||
"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": "First version with CDR secure defaults"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "0.0.2",
|
|
||||||
"date": "2020-02-11",
|
|
||||||
"log": "Fix bug when uninstalled"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": [
|
|
||||||
{
|
|
||||||
"language": "en",
|
|
||||||
"text": "Change me"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"files": []
|
|
||||||
}
|
|
||||||
2
packages/zammad-addon-common/dist/index.d.ts
vendored
Normal file
2
packages/zammad-addon-common/dist/index.d.ts
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
export declare const createZPM: () => Promise<void>;
|
||||||
|
export declare const createMigration: () => Promise<void>;
|
||||||
116
packages/zammad-addon-common/dist/index.js
vendored
Normal file
116
packages/zammad-addon-common/dist/index.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
packages/zammad-addon-common/dist/tsconfig.tsbuildinfo
vendored
Normal file
1
packages/zammad-addon-common/dist/tsconfig.tsbuildinfo
vendored
Normal file
File diff suppressed because one or more lines are too long
117
packages/zammad-addon-common/index.ts
Normal file
117
packages/zammad-addon-common/index.ts
Normal file
|
|
@ -0,0 +1,117 @@
|
||||||
|
import { promises as fs } from "fs";
|
||||||
|
import path from "path";
|
||||||
|
import os from "os";
|
||||||
|
|
||||||
|
const skeleton: Record<string, any> = {
|
||||||
|
"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<any> => {
|
||||||
|
console.log(`Packaging: ${actualPath}`);
|
||||||
|
const packagePath = actualPath.slice(6);
|
||||||
|
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 () => {
|
||||||
|
const files = await packageFiles();
|
||||||
|
skeleton.files = files;
|
||||||
|
skeleton.builddate = new Date().toISOString();
|
||||||
|
skeleton.buildhost = os.hostname();
|
||||||
|
const name = skeleton.name.toLowerCase();
|
||||||
|
const version = skeleton.version;
|
||||||
|
const pkg = JSON.stringify(skeleton, null, 2);
|
||||||
|
await fs.writeFile(`dist/${name}-v${version}.zpm`, pkg, 'utf-8');
|
||||||
|
}
|
||||||
|
|
||||||
|
export const createMigration = async () => {
|
||||||
|
const name = skeleton["name"].toLowerCase();
|
||||||
|
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 = `${name}_${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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -1,43 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
import os
|
|
||||||
import json
|
|
||||||
import glob
|
|
||||||
import inflection
|
|
||||||
from datetime import datetime
|
|
||||||
from collections import OrderedDict
|
|
||||||
|
|
||||||
migration_template = """class {} < ActiveRecord::Migration[5.2]
|
|
||||||
def self.up
|
|
||||||
# add your code here
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.down
|
|
||||||
# add your code here
|
|
||||||
end
|
|
||||||
end
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
def load_skeleton():
|
|
||||||
t = glob.glob('*.szpm.template')
|
|
||||||
if len(t) != 1:
|
|
||||||
raise Exception("Cannot find szpm template")
|
|
||||||
with open(t[0], 'r', encoding='utf-8') as f:
|
|
||||||
skeleton = json.load(f, object_pairs_hook=OrderedDict)
|
|
||||||
return skeleton
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
skeleton = load_skeleton()
|
|
||||||
name = skeleton["name"].lower()
|
|
||||||
raw_name = input("Enter migration name: ")
|
|
||||||
migration_base_name = "{}_{}".format(name, inflection.underscore(raw_name))
|
|
||||||
migration_name = inflection.camelize(migration_base_name, uppercase_first_letter=True)
|
|
||||||
contents = migration_template.format(migration_name)
|
|
||||||
time = datetime.utcnow().strftime("%Y%m%d%H%M%S")
|
|
||||||
migration_file_name = "{}_{}.rb".format(time, migration_base_name)
|
|
||||||
with open(os.path.join("src/db/addon/", skeleton["name"], migration_file_name), 'w') as f:
|
|
||||||
f.write(contents)
|
|
||||||
|
|
||||||
|
|
||||||
main()
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"build": "tsc"
|
||||||
},
|
},
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
|
|
|
||||||
|
|
@ -1,75 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
import os
|
|
||||||
import base64
|
|
||||||
import json
|
|
||||||
import datetime
|
|
||||||
import platform
|
|
||||||
import glob
|
|
||||||
import re
|
|
||||||
from collections import OrderedDict
|
|
||||||
|
|
||||||
# files matching this pattern are not included in the package
|
|
||||||
ignored_patterns = [
|
|
||||||
"\.gitkeep"
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def encode(fname):
|
|
||||||
data = open(fname, "r", encoding='utf-8').read().encode('utf-8')
|
|
||||||
return base64.b64encode(data).decode('utf-8')
|
|
||||||
|
|
||||||
|
|
||||||
def read_perm(fname):
|
|
||||||
return int(oct(os.stat(fname).st_mode & 0o777)[-3:])
|
|
||||||
|
|
||||||
|
|
||||||
def format_file(content, pkg_path, permission):
|
|
||||||
return OrderedDict(
|
|
||||||
location=pkg_path,
|
|
||||||
permission=permission,
|
|
||||||
encode="base64",
|
|
||||||
content=content)
|
|
||||||
|
|
||||||
|
|
||||||
def pkg_file(actual_path):
|
|
||||||
print(" Packaging: {}".format(actual_path))
|
|
||||||
pkg_path = actual_path[6:]
|
|
||||||
contents = encode(actual_path)
|
|
||||||
res = format_file(contents, pkg_path, read_perm(actual_path))
|
|
||||||
return res
|
|
||||||
|
|
||||||
|
|
||||||
def pkg_files():
|
|
||||||
pkged_files = []
|
|
||||||
for root, dirs, files in os.walk("./src/"):
|
|
||||||
for f in files:
|
|
||||||
if any(re.search(r, f) for r in ignored_patterns):
|
|
||||||
continue
|
|
||||||
actual_path = os.path.join(root, f)
|
|
||||||
pkged_files.append(pkg_file(actual_path))
|
|
||||||
return pkged_files
|
|
||||||
|
|
||||||
|
|
||||||
def load_skeleton():
|
|
||||||
t = glob.glob('*.szpm.template')
|
|
||||||
if len(t) != 1:
|
|
||||||
raise Exception("Cannot find szpm template")
|
|
||||||
with open(t[0], 'r', encoding='utf-8') as f:
|
|
||||||
skeleton = json.load(f, object_pairs_hook=OrderedDict)
|
|
||||||
return skeleton
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
files = pkg_files()
|
|
||||||
skeleton = load_skeleton()
|
|
||||||
skeleton["files"] = files
|
|
||||||
skeleton["builddate"] = datetime.datetime.utcnow().isoformat()
|
|
||||||
skeleton["buildhost"] = platform.node()
|
|
||||||
name = skeleton["name"].lower()
|
|
||||||
version = skeleton["version"]
|
|
||||||
pkg = json.dumps(skeleton, indent=2)
|
|
||||||
with open("dist/{}-v{}.szpm".format(name, version), "w", encoding='utf-8') as f:
|
|
||||||
f.write(pkg)
|
|
||||||
|
|
||||||
|
|
||||||
main()
|
|
||||||
3
packages/zammad-addon-common/test.js
Normal file
3
packages/zammad-addon-common/test.js
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
const { createZPM } = require("./dist/index.js");
|
||||||
|
|
||||||
|
console.log({ createZPM });
|
||||||
30
packages/zammad-addon-common/tsconfig.json
Normal file
30
packages/zammad-addon-common/tsconfig.json
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"incremental": true,
|
||||||
|
"target": "es2020",
|
||||||
|
"lib": [
|
||||||
|
"es2020"
|
||||||
|
],
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"module": "commonjs",
|
||||||
|
"declaration": true,
|
||||||
|
"inlineSourceMap": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"noUnusedLocals": false,
|
||||||
|
"noUnusedParameters": false,
|
||||||
|
"noImplicitReturns": true,
|
||||||
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
"traceResolution": false,
|
||||||
|
"listEmittedFiles": false,
|
||||||
|
"listFiles": false,
|
||||||
|
"pretty": true,
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"emitDecoratorMetadata": true,
|
||||||
|
"outDir": "dist",
|
||||||
|
"types": [
|
||||||
|
"node",
|
||||||
|
"jest"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
14
packages/zammad-addon-pgp/package.json
Normal file
14
packages/zammad-addon-pgp/package.json
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"name": "zammad-addon-pgp",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Adds PGP integration into [Zammad](https://zammad.org) via [Sequoia](https://sequoia-pgp.org).",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"zammad-addon-common": "*"
|
||||||
|
},
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC"
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue