local-ticket-board 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/README.md ADDED
@@ -0,0 +1,18 @@
1
+ # local-ticket-board
2
+
3
+ Scaffold the **Git Kanban - Local Ticket Board** into any repo via `npx`.
4
+
5
+ ## Usage
6
+
7
+ ```bash
8
+ npx local-ticket-board@latest kanban
9
+ cd kanban
10
+ npm run dev
11
+ ```
12
+
13
+ ## Options
14
+
15
+ - `--template <git-url>`: Use a different git repo as the template.
16
+ - `--no-install`: Skip `npm install`.
17
+
18
+
@@ -0,0 +1,142 @@
1
+ #!/usr/bin/env node
2
+ import { spawnSync } from "node:child_process";
3
+ import fs from "node:fs";
4
+ import path from "node:path";
5
+
6
+ const DEFAULT_TEMPLATE = "https://github.com/Justbeingjustin/ticket-board.git";
7
+
8
+ function printHelp() {
9
+ console.log(`
10
+ local-ticket-board
11
+
12
+ Usage:
13
+ npx local-ticket-board@latest [directory] [--template <git-url>] [--no-install]
14
+
15
+ Examples:
16
+ npx local-ticket-board@latest kanban
17
+ npx local-ticket-board@latest apps/kanban --no-install
18
+ npx local-ticket-board@latest kanban --template https://github.com/you/your-template.git
19
+ `.trim());
20
+ }
21
+
22
+ function fail(message) {
23
+ console.error(`\nError: ${message}\n`);
24
+ process.exit(1);
25
+ }
26
+
27
+ function parseArgs(argv) {
28
+ const args = argv.slice(2);
29
+ let dir;
30
+ let template = DEFAULT_TEMPLATE;
31
+ let install = true;
32
+
33
+ for (let i = 0; i < args.length; i++) {
34
+ const a = args[i];
35
+ if (!a) continue;
36
+
37
+ if (a === "-h" || a === "--help") {
38
+ return { help: true };
39
+ }
40
+ if (a === "--no-install") {
41
+ install = false;
42
+ continue;
43
+ }
44
+ if (a === "--template") {
45
+ const v = args[i + 1];
46
+ if (!v) fail("--template requires a value");
47
+ template = v;
48
+ i++;
49
+ continue;
50
+ }
51
+ if (a.startsWith("-")) {
52
+ fail(`Unknown option: ${a}`);
53
+ }
54
+ if (!dir) {
55
+ dir = a;
56
+ continue;
57
+ }
58
+ fail(`Unexpected extra argument: ${a}`);
59
+ }
60
+
61
+ return { help: false, dir: dir ?? "kanban", template, install };
62
+ }
63
+
64
+ function run(cmd, cmdArgs, opts = {}) {
65
+ const res = spawnSync(cmd, cmdArgs, {
66
+ stdio: "inherit",
67
+ shell: process.platform === "win32",
68
+ ...opts,
69
+ });
70
+ if (res.status !== 0) {
71
+ fail(`Command failed: ${cmd} ${cmdArgs.join(" ")}`);
72
+ }
73
+ }
74
+
75
+ function rmIfExists(p) {
76
+ if (fs.existsSync(p)) {
77
+ fs.rmSync(p, { recursive: true, force: true });
78
+ }
79
+ }
80
+
81
+ function ensureTargetDirEmpty(targetDir) {
82
+ if (!fs.existsSync(targetDir)) return;
83
+ const entries = fs.readdirSync(targetDir);
84
+ if (entries.length > 0) {
85
+ fail(`Target directory is not empty: ${targetDir}`);
86
+ }
87
+ }
88
+
89
+ function setPackageNameIfPossible(targetDir, name) {
90
+ try {
91
+ const pkgPath = path.join(targetDir, "package.json");
92
+ if (!fs.existsSync(pkgPath)) return;
93
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
94
+ pkg.name = name;
95
+ fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n", "utf8");
96
+ } catch {
97
+ // best-effort
98
+ }
99
+ }
100
+
101
+ const parsed = parseArgs(process.argv);
102
+ if (parsed.help) {
103
+ printHelp();
104
+ process.exit(0);
105
+ }
106
+
107
+ const targetDir = path.resolve(process.cwd(), parsed.dir);
108
+ const targetBaseName = path.basename(targetDir);
109
+
110
+ ensureTargetDirEmpty(targetDir);
111
+
112
+ // Ensure parent folder exists (e.g. apps/kanban)
113
+ fs.mkdirSync(path.dirname(targetDir), { recursive: true });
114
+
115
+ console.log(`\nCreating Ticket Board in: ${targetDir}`);
116
+ console.log(`Template: ${parsed.template}\n`);
117
+
118
+ // Clone template repo
119
+ run("git", ["clone", "--depth", "1", parsed.template, targetDir]);
120
+
121
+ // Remove git history so it becomes "your" project
122
+ rmIfExists(path.join(targetDir, ".git"));
123
+
124
+ // Remove GitHub-only files if present
125
+ rmIfExists(path.join(targetDir, ".github"));
126
+
127
+ // If the template repo name differs, adjust package name
128
+ setPackageNameIfPossible(targetDir, targetBaseName);
129
+
130
+ if (parsed.install) {
131
+ console.log("\nInstalling dependencies...\n");
132
+ run("npm", ["install"], { cwd: targetDir });
133
+ }
134
+
135
+ console.log("\nDone.\n");
136
+ console.log("Next steps:");
137
+ console.log(` cd ${parsed.dir}`);
138
+ if (!parsed.install) console.log(" npm install");
139
+ console.log(" npm run dev");
140
+ console.log("");
141
+
142
+
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "local-ticket-board",
3
+ "version": "0.0.1",
4
+ "description": "Scaffold the Git Kanban local ticket board into any repo.",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/Justbeingjustin/ticket-board.git"
9
+ },
10
+ "homepage": "https://github.com/Justbeingjustin/ticket-board",
11
+ "bugs": {
12
+ "url": "https://github.com/Justbeingjustin/ticket-board/issues"
13
+ },
14
+ "type": "module",
15
+ "bin": {
16
+ "local-ticket-board": "bin/create-ticket-board.js"
17
+ },
18
+ "engines": {
19
+ "node": ">=18"
20
+ },
21
+ "files": [
22
+ "bin/"
23
+ ],
24
+ "keywords": [
25
+ "create",
26
+ "scaffold",
27
+ "nextjs",
28
+ "kanban"
29
+ ]
30
+ }
31
+
32
+