normalize line endings to LF and add envoy dockerfile in deploy/dev

This commit is contained in:
wwweww
2026-04-06 05:26:41 +08:00
parent 7ec8b2a8f0
commit c7a33d4174
39 changed files with 12916 additions and 12246 deletions
+200 -200
View File
@@ -1,200 +1,200 @@
import { search } from "@inquirer/prompts";
import { execa } from "execa";
import Fuse from "fuse.js";
import { glob } from "glob";
import { task } from "hereby";
import path from "node:path";
import fs from "node:fs/promises";
import { fileURLToPath } from "node:url";
import { parseArgs } from "node:util";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const { values } = parseArgs({
args: process.argv.slice(3),
options: {
server: { type: "string", short: "s", multiple: true }, // 服务名称
type: { type: "string", short: "t" }, // 生成类型:api, rpc, docker
imageName: { type: "string", short: "i" }, // 镜像名字
}
})
const Paths = {
root: __dirname,
desc: path.join(__dirname, "desc"),
app: path.join(__dirname, "app"),
getServiceName: (filePath) => path.basename(filePath, path.extname(filePath)),
getOutputDir: (serviceName) => path.join(__dirname, "app", serviceName),
pathlistToChoices: (filePaths) => filePaths.map(filePath => ({
title: Paths.getServiceName(filePath),
value: filePath,
})),
getDescFiles: async (pattern) => {
return await glob(pattern, { cwd: Paths.desc, absolute: true });
},
getAllApi: async () => {
const apiPattern = "api/*.api";
return Paths.pathlistToChoices(await Paths.getDescFiles(apiPattern));
},
getAllProto: async () => {
const protoPattern = "rpc/*.proto";
return Paths.pathlistToChoices(await Paths.getDescFiles(protoPattern));
},
getAllservice: async () => {
let all = [];
const services = await fs.readdir(Paths.app);
for (const service of services) {
const servicePath = path.join(Paths.app, service);
const svcTypes = await fs.readdir(servicePath);
svcTypes.map(svcType => all.push({
title: `${service} - ${svcType}`,
value: path.join(servicePath, svcType, svcType !== "rpc" ? `${service}.go` : "pb.go"),
}));
}
return all;
},
}
const Generators = {
async api(apiFile) {
const serviceName = Paths.getServiceName(apiFile);
const outputDir = path.join(Paths.getOutputDir(serviceName), 'api');
await fs.mkdir(outputDir, { recursive: true });
await run('goctl', [
'api', 'go',
'--api', apiFile,
'--dir', outputDir,
'--style', 'goZero'
]);
},
async rpc(protoFile) {
const serviceName = Paths.getServiceName(protoFile);
const outputDir = path.join(Paths.getOutputDir(serviceName), 'rpc');
await fs.mkdir(outputDir, { recursive: true });
await run('goctl', [
'rpc', 'protoc', protoFile,
`--proto_path=${path.join(Paths.desc, "rpc",)}`,
`--go_out=${outputDir}`,
`--go-grpc_out=${outputDir}`,
`--zrpc_out=${outputDir}`,
'--style=goZero',
]);
},
async docker(servicePath) {
const dockerFiles = await glob("DockerFile", { cwd: __dirname, absolute: true });
if (dockerFiles.length !== 0) {
fs.rm(dockerFiles[0], { force: true });
}
await run('goctl', [
"docker", "--go", path.relative(__dirname, servicePath)
])
}
};
const GenerateConfig = {
api: {
getChoices: () => Paths.getAllApi(),
prompt: "Select an API description file",
generate: (path) => Generators.api(path),
},
rpc: {
getChoices: () => Paths.getAllProto(),
prompt: "Select a proto file",
generate: (path) => Generators.rpc(path),
},
docker: {
getChoices: () => Paths.getAllservice(),
prompt: "Select a service to generate Dockerfile",
generate: (path) => Generators.docker(path),
}
};
async function run(cmd, args, opts = {}) {
console.log(`>> ${cmd} ${args.join(' ')}`);
return execa(cmd, args, {
stdio: 'inherit',
...opts
});
}
async function searchSelector(chooses, message) {
const fuse = new Fuse(chooses, {
keys: ['title'],
threshold: 0.4,
})
return search({
message,
source: async (term) => {
if (!term) {
return chooses.map(s => ({ name: s.title, value: s.value }));
}
const result = fuse.search(term);
return result.map(s => ({ name: s.item.title, value: s.item.value }));
}
})
}
async function generateHandle() {
const type = values.type;
if (!type || !GenerateConfig[type]) {
console.error("Please specify valid -t <api|rpc|docker>");
return;
}
const config = GenerateConfig[type];
const input = values.server
? (Array.isArray(values.server) ? values.server[0] : values.server)
: await searchSelector(await config.getChoices(), config.prompt);
await config.generate(input);
}
async function buildImage(imageName) {
await run("docker", ["build", "-t", imageName, "."])
}
export const init = task({
name: "init",
desc: "initialize the project",
run: async () => {
await run("go", ["install", "github.com/zeromicro/go-zero/tools/goctl@latest"]);
}
})
export const tidy = task({
name: "tidy",
desc: "tidy go.mod and go.sum",
run: async () => { run("go", ["mod", "tidy"]) },
})
export const build = task({
name: "build",
desc: "build docker image",
run: async () => {
if (values.imageName) {
buildImage(values.imageName);
} else {
console.error("Please specify image name with -i <imageName>");
}
}
})
export const gen = task({
name: "gen",
desc: "generate API/RPC service code",
run: generateHandle,
});
import { search } from "@inquirer/prompts";
import { execa } from "execa";
import Fuse from "fuse.js";
import { glob } from "glob";
import { task } from "hereby";
import path from "node:path";
import fs from "node:fs/promises";
import { fileURLToPath } from "node:url";
import { parseArgs } from "node:util";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const { values } = parseArgs({
args: process.argv.slice(3),
options: {
server: { type: "string", short: "s", multiple: true }, // 服务名称
type: { type: "string", short: "t" }, // 生成类型:api, rpc, docker
imageName: { type: "string", short: "i" }, // 镜像名字
}
})
const Paths = {
root: __dirname,
desc: path.join(__dirname, "desc"),
app: path.join(__dirname, "app"),
getServiceName: (filePath) => path.basename(filePath, path.extname(filePath)),
getOutputDir: (serviceName) => path.join(__dirname, "app", serviceName),
pathlistToChoices: (filePaths) => filePaths.map(filePath => ({
title: Paths.getServiceName(filePath),
value: filePath,
})),
getDescFiles: async (pattern) => {
return await glob(pattern, { cwd: Paths.desc, absolute: true });
},
getAllApi: async () => {
const apiPattern = "api/*.api";
return Paths.pathlistToChoices(await Paths.getDescFiles(apiPattern));
},
getAllProto: async () => {
const protoPattern = "rpc/*.proto";
return Paths.pathlistToChoices(await Paths.getDescFiles(protoPattern));
},
getAllservice: async () => {
let all = [];
const services = await fs.readdir(Paths.app);
for (const service of services) {
const servicePath = path.join(Paths.app, service);
const svcTypes = await fs.readdir(servicePath);
svcTypes.map(svcType => all.push({
title: `${service} - ${svcType}`,
value: path.join(servicePath, svcType, svcType !== "rpc" ? `${service}.go` : "pb.go"),
}));
}
return all;
},
}
const Generators = {
async api(apiFile) {
const serviceName = Paths.getServiceName(apiFile);
const outputDir = path.join(Paths.getOutputDir(serviceName), 'api');
await fs.mkdir(outputDir, { recursive: true });
await run('goctl', [
'api', 'go',
'--api', apiFile,
'--dir', outputDir,
'--style', 'goZero'
]);
},
async rpc(protoFile) {
const serviceName = Paths.getServiceName(protoFile);
const outputDir = path.join(Paths.getOutputDir(serviceName), 'rpc');
await fs.mkdir(outputDir, { recursive: true });
await run('goctl', [
'rpc', 'protoc', protoFile,
`--proto_path=${path.join(Paths.desc, "rpc",)}`,
`--go_out=${outputDir}`,
`--go-grpc_out=${outputDir}`,
`--zrpc_out=${outputDir}`,
'--style=goZero',
]);
},
async docker(servicePath) {
const dockerFiles = await glob("DockerFile", { cwd: __dirname, absolute: true });
if (dockerFiles.length !== 0) {
fs.rm(dockerFiles[0], { force: true });
}
await run('goctl', [
"docker", "--go", path.relative(__dirname, servicePath)
])
}
};
const GenerateConfig = {
api: {
getChoices: () => Paths.getAllApi(),
prompt: "Select an API description file",
generate: (path) => Generators.api(path),
},
rpc: {
getChoices: () => Paths.getAllProto(),
prompt: "Select a proto file",
generate: (path) => Generators.rpc(path),
},
docker: {
getChoices: () => Paths.getAllservice(),
prompt: "Select a service to generate Dockerfile",
generate: (path) => Generators.docker(path),
}
};
async function run(cmd, args, opts = {}) {
console.log(`>> ${cmd} ${args.join(' ')}`);
return execa(cmd, args, {
stdio: 'inherit',
...opts
});
}
async function searchSelector(chooses, message) {
const fuse = new Fuse(chooses, {
keys: ['title'],
threshold: 0.4,
})
return search({
message,
source: async (term) => {
if (!term) {
return chooses.map(s => ({ name: s.title, value: s.value }));
}
const result = fuse.search(term);
return result.map(s => ({ name: s.item.title, value: s.item.value }));
}
})
}
async function generateHandle() {
const type = values.type;
if (!type || !GenerateConfig[type]) {
console.error("Please specify valid -t <api|rpc|docker>");
return;
}
const config = GenerateConfig[type];
const input = values.server
? (Array.isArray(values.server) ? values.server[0] : values.server)
: await searchSelector(await config.getChoices(), config.prompt);
await config.generate(input);
}
async function buildImage(imageName) {
await run("docker", ["build", "-t", imageName, "."])
}
export const init = task({
name: "init",
desc: "initialize the project",
run: async () => {
await run("go", ["install", "github.com/zeromicro/go-zero/tools/goctl@latest"]);
}
})
export const tidy = task({
name: "tidy",
desc: "tidy go.mod and go.sum",
run: async () => { run("go", ["mod", "tidy"]) },
})
export const build = task({
name: "build",
desc: "build docker image",
run: async () => {
if (values.imageName) {
buildImage(values.imageName);
} else {
console.error("Please specify image name with -i <imageName>");
}
}
})
export const gen = task({
name: "gen",
desc: "generate API/RPC service code",
run: generateHandle,
});