UNPKG

@tianyio/quality-helper

Version:

统一项目规范的工具包

212 lines (211 loc) 6.45 kB
import { join as c, dirname as $ } from "path"; import o, { readFile as y, writeFile as j } from "fs/promises"; import { execFile as b, execSync as D } from "child_process"; import { fileURLToPath as x } from "url"; function k(e, r) { const t = JSON.parse(e), i = JSON.parse(r), s = { ...i }; for (const n in t) n in i ? typeof t[n] == "object" && !Array.isArray(t[n]) ? s[n] = k(t[n], i[n]) : t[n] !== i[n] && (s[n] = t[n], s[`${n}_bak`] = i[n]) : s[n] = t[n]; return s; } function v(e) { return e.split(` `).reduce((r, t) => { if (t.trim().startsWith("#")) return r[t] = "", r; const [i, s] = t.split("=").map((n) => n.trim()); return i && s && (r[i] = s), r; }, {}); } function P(e, r) { const t = v(e), i = v(r), s = { ...i }; for (const n in t) s[n] = t[n], n in i && t[n] !== i[n] && (s[`#${n}_bak`] = i[n]); return Object.entries(s).map(([n, a]) => n.startsWith("#") && !n.endsWith("_bak") ? n : `${n}=${a}`).join(` `); } async function h(e, r, t) { const i = c(e, t), s = c(r, t); if (!await o.stat(s).catch(() => !1)) { await o.copyFile(i, s), console.log(`✅ 创建新文件: ${s}`); return; } try { const [n, a] = await Promise.all([ o.readFile(i, "utf8"), o.readFile(s, "utf8") ]); let l = ""; t.endsWith(".json") ? (await k(n, a), l = JSON.stringify(l, null, 2)) : t.match(/\.(ts|js)$/) ? await o.copyFile(i, s) : l = P(n, a), await o.writeFile(s, l, "utf8"), console.log(`🔄 配置已更新: ${s}`); } catch (n) { await o.copyFile(i, s), console.warn(`⚠️ ${s} 合并失败,已覆盖`), console.warn(`⚠️ 失败原因:${n.message}`); } } async function N(e, r) { const t = c(e, "env"), i = c(r, "env"); try { await o.mkdir(i, { recursive: !0 }); } catch (a) { console.warn(`⚠️ 创建 env 文件夹失败: ${a.message}`); } const s = await o.readdir(t), n = []; for (const a of s) { h(t, i, a); const l = a.replace(/^\.env./, ""); n.push(l); } return n; } const O = { eslint: "9.29.0", "eslint-config-prettier": "10.1.5", "eslint-plugin-prettier": "5.5.0", "eslint-plugin-promise": "7.2.1", "eslint-plugin-vue": "10.2.0", prettier: "3.5.3", husky: "9.1.7", "lint-staged": "16.1.2", "@commitlint/cli": "19.8.1", "@commitlint/config-conventional": "19.8.1", "@typescript-eslint/eslint-plugin": "8.34.1", "@typescript-eslint/parser": "8.34.1" }; function E(e) { const r = {}; return e?.forEach((t) => { r[`build:${t}`] = `vite build --mode ${t}`; }), r; } async function J(e, r) { const t = c(e, "package.json"); let i = {}; try { await o.stat(t).catch(() => !1) && (i = JSON.parse(await o.readFile(t, "utf8"))); } catch (s) { console.warn(`⚠️ 读取 package.json 失败: ${s.message}`); } i.devDependencies = { ...i.devDependencies, ...O }, i.scripts = { ...i.scripts, ...E(r) }; try { await o.writeFile(t, JSON.stringify(i, null, 2), "utf8"), console.log("✅ package.json 已更新,请手动安装依赖"); } catch (s) { console.error(`❌ package.json 写入失败: ${s.message}`), process.exit(1); } } async function T(e, r) { const t = c(e, "config"), i = await o.readdir(t); for (const s of i) await h(t, r, s); } function S(e, r) { return new Promise((t, i) => { b(e, r, (s, n, a) => { if (s) return i(s); a && console.warn(a), t(n); }); }); } async function A(e) { try { await o.stat(c(e, ".git")).catch(() => (console.log("📦 初始化 Git 仓库..."), S("git", ["init", "--initial-branch=master"]))); } catch (r) { console.warn(`⚠️ Git 初始化失败: ${r.message}`); } } async function C(e, r) { await A(r); try { console.log("🔧 初始化 Git Hooks..."); const t = c(r, ".husky"); if (!await o.stat(t).catch(() => !1)) try { await S("npx", ["husky"]); } catch { await o.mkdir(t, { recursive: !0 }); } const i = c(e, ".husky"), s = await o.readdir(i); for (const n of s) h(i, t, n); } catch (t) { console.error("❌ Git Hooks 初始化失败:", t.message), process.exit(1); } } const g = c($(x(import.meta.url)), "..", "templates"), G = async (e = process.cwd()) => { let r = e; for (; ; ) try { return await o.access(c(r, "package.json")), r; } catch { const t = $(r); if (t === r) break; r = t; } return e; }; async function R() { const e = await G(); try { console.log("🚀 开始安装代码规范工具..."), process.version < "v22.0.0" && console.warn("⚠️ 推荐使用 Node.js v22+ 版本"); const r = await N(g, e); await J(e, r), await T(g, e), await C(g, e), console.log("🎉 完整开发规范已就绪!"); } catch (r) { console.error("❌ 安装失败:", r), process.exit(1); } } const H = (e) => `${e.getFullYear()}-${String(e.getMonth() + 1).padStart(2, "0")}-${String(e.getDate()).padStart(2, "0")} ${String(e.getHours()).padStart(2, "0")}:${String(e.getMinutes()).padStart(2, "0")}:${String(e.getSeconds()).padStart(2, "0")}.${String(e.getMilliseconds()).padStart(3, "0")}`; function m(e) { try { return D(e, { stdio: "pipe" }).toString(); } catch { return ""; } } function W() { const e = H(/* @__PURE__ */ new Date()), r = m("git describe --tags --exact-match").trim(), t = m("git rev-parse --short HEAD").trim(), i = m("git rev-parse --abbrev-ref HEAD").trim(); return { time: e, tag: r, hash: t, branch: i }; } function U() { return { name: "@tianyio/version-info", async config({ envDir: e, envPrefix: r }, { mode: t }) { let i = {}; try { i = W(); } catch (f) { return console.warn("⚠️ 版本信息生成失败:", f.message), {}; } e || (e = process.cwd()), r || (r = "VITE"); const s = `${r}_APP_VERSION`, n = `${s}='${JSON.stringify(i)}'`, a = c(e, `.env.${t}`), l = c(e, ".env"); let w = a, u = ""; try { u = await y(a, "utf-8"); } catch { try { u = await y(l, "utf-8"), w = l; } catch { } } const F = u.split(/\r?\n/); let d = !1; const p = F.filter((f) => f.trim() !== "").map((f) => f.startsWith(s) ? (d = !0, n) : f); return d || p.push(n), p.push(""), j(w, p.join(` `), "utf-8"); } }; } export { R as install, U as versionInfoPlugin };