@zjex/git-workflow 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/index.ts ADDED
@@ -0,0 +1,88 @@
1
+ // @ts-nocheck shebang handled by tsup banner
2
+
3
+ import { cac } from "cac";
4
+ import { checkGitRepo } from "./utils.js";
5
+ import { createBranch, deleteBranch } from "./commands/branch.js";
6
+ import { listTags, createTag } from "./commands/tag.js";
7
+ import { release } from "./commands/release.js";
8
+ import { init } from "./commands/init.js";
9
+ import { stash } from "./commands/stash.js";
10
+ import { showHelp } from "./commands/help.js";
11
+
12
+ declare const __VERSION__: string;
13
+
14
+ const cli = cac("gw");
15
+
16
+ cli
17
+ .command("feature", "创建 feature 分支")
18
+ .alias("feat")
19
+ .alias("f")
20
+ .option("--base <branch>", "指定基础分支")
21
+ .action((options: { base?: string }) => {
22
+ checkGitRepo();
23
+ return createBranch("feature", options.base);
24
+ });
25
+
26
+ cli
27
+ .command("hotfix", "创建 hotfix 分支")
28
+ .alias("fix")
29
+ .alias("h")
30
+ .option("--base <branch>", "指定基础分支")
31
+ .action((options: { base?: string }) => {
32
+ checkGitRepo();
33
+ return createBranch("hotfix", options.base);
34
+ });
35
+
36
+ cli
37
+ .command("delete [branch]", "删除本地/远程分支")
38
+ .alias("del")
39
+ .alias("d")
40
+ .action((branch?: string) => {
41
+ checkGitRepo();
42
+ return deleteBranch(branch);
43
+ });
44
+
45
+ cli
46
+ .command("tags [prefix]", "列出所有 tag,可按前缀过滤")
47
+ .alias("ts")
48
+ .action((prefix?: string) => {
49
+ checkGitRepo();
50
+ return listTags(prefix);
51
+ });
52
+
53
+ cli
54
+ .command("tag [prefix]", "交互式选择版本类型并创建 tag")
55
+ .alias("t")
56
+ .action((prefix?: string) => {
57
+ checkGitRepo();
58
+ return createTag(prefix);
59
+ });
60
+
61
+ cli
62
+ .command("release", "交互式选择版本号并更新 package.json")
63
+ .alias("r")
64
+ .action(() => {
65
+ return release();
66
+ });
67
+
68
+ cli.command("init", "初始化配置文件 .gwrc.json").action(() => {
69
+ return init();
70
+ });
71
+
72
+ cli
73
+ .command("stash", "交互式管理 stash")
74
+ .alias("s")
75
+ .alias("st")
76
+ .action(() => {
77
+ checkGitRepo();
78
+ return stash();
79
+ });
80
+
81
+ cli.help((sections) => {
82
+ sections.push({
83
+ body: showHelp(),
84
+ });
85
+ });
86
+ cli.version(__VERSION__);
87
+
88
+ cli.parse();
package/src/utils.ts ADDED
@@ -0,0 +1,82 @@
1
+ import { execSync, type ExecSyncOptions } from "child_process";
2
+
3
+ export interface Colors {
4
+ red: (s: string) => string;
5
+ green: (s: string) => string;
6
+ yellow: (s: string) => string;
7
+ dim: (s: string) => string;
8
+ }
9
+
10
+ export const colors: Colors = {
11
+ red: (s) => `\x1b[31m${s}\x1b[0m`,
12
+ green: (s) => `\x1b[32m${s}\x1b[0m`,
13
+ yellow: (s) => `\x1b[33m${s}\x1b[0m`,
14
+ dim: (s) => `\x1b[2m${s}\x1b[0m`,
15
+ };
16
+
17
+ export const TODAY: string = new Date()
18
+ .toISOString()
19
+ .slice(0, 10)
20
+ .replace(/-/g, "");
21
+
22
+ type KeysHelpTip = [string, string][];
23
+
24
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
25
+ export const theme: any = {
26
+ helpMode: "always",
27
+ style: {
28
+ keysHelpTip: (keys: KeysHelpTip): string => {
29
+ const tips = keys.map(([key, label]) => `${key} ${label}`).join(" • ");
30
+ return `\x1b[2m${tips} • Ctrl+C quit\x1b[0m`;
31
+ },
32
+ },
33
+ };
34
+
35
+ export function exec(cmd: string, silent: boolean = false): string {
36
+ try {
37
+ const options: ExecSyncOptions = {
38
+ encoding: "utf-8",
39
+ stdio: silent ? "pipe" : "inherit",
40
+ };
41
+ return execSync(cmd, options) as string;
42
+ } catch (e) {
43
+ if (silent) return "";
44
+ throw e;
45
+ }
46
+ }
47
+
48
+ export function execOutput(cmd: string): string {
49
+ try {
50
+ return execSync(cmd, { encoding: "utf-8" }).trim();
51
+ } catch {
52
+ return "";
53
+ }
54
+ }
55
+
56
+ export function checkGitRepo(): void {
57
+ try {
58
+ execSync("git rev-parse --is-inside-work-tree", { stdio: "pipe" });
59
+ } catch {
60
+ console.log(colors.red("错误: 当前目录不是 git 仓库"));
61
+ process.exit(1);
62
+ }
63
+ }
64
+
65
+ export function getMainBranch(): string {
66
+ const branches = execOutput("git branch -r")
67
+ .split("\n")
68
+ .map((b) => b.trim());
69
+ if (branches.includes("origin/main")) {
70
+ return "origin/main";
71
+ }
72
+ if (branches.includes("origin/master")) {
73
+ return "origin/master";
74
+ }
75
+ return "origin/main";
76
+ }
77
+
78
+ export type BranchType = "feature" | "hotfix";
79
+
80
+ export function divider(): void {
81
+ console.log(colors.dim("─".repeat(40)));
82
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,20 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "NodeNext",
5
+ "moduleResolution": "NodeNext",
6
+ "strict": true,
7
+ "esModuleInterop": true,
8
+ "skipLibCheck": true,
9
+ "outDir": "dist",
10
+ "rootDir": "src",
11
+ "declaration": true
12
+ },
13
+ "include": [
14
+ "src/**/*"
15
+ ],
16
+ "exclude": [
17
+ "node_modules",
18
+ "dist"
19
+ ]
20
+ }
package/tsup.config.ts ADDED
@@ -0,0 +1,18 @@
1
+ import { defineConfig } from "tsup";
2
+ import { readFileSync } from "fs";
3
+
4
+ const pkg = JSON.parse(readFileSync("package.json", "utf-8"));
5
+
6
+ export default defineConfig({
7
+ entry: ["src/index.ts"],
8
+ format: ["esm"],
9
+ clean: true,
10
+ shims: true,
11
+ minify: true,
12
+ banner: {
13
+ js: "#!/usr/bin/env node --no-warnings",
14
+ },
15
+ define: {
16
+ __VERSION__: JSON.stringify(pkg.version),
17
+ },
18
+ });