Add a scaffold script that replaces the bq prefix with the new project name.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
72
scripts/apply-name.mjs
Normal file
72
scripts/apply-name.mjs
Normal file
@@ -0,0 +1,72 @@
|
||||
import { readdir, readFile, rename, writeFile } from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
|
||||
const projectName = process.argv[2];
|
||||
const root = path.resolve(process.argv[3] ?? process.cwd());
|
||||
|
||||
if (!projectName || !/^[a-z][a-z0-9-]*$/.test(projectName)) {
|
||||
console.error('用法: node scripts/apply-name.mjs <项目名> [目录]');
|
||||
console.error('项目名需为小写字母开头,只含小写字母、数字和连字符');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const skipDirs = new Set(['node_modules', '.git', 'dist', '.react-router', 'scripts', 'doc']);
|
||||
const textExtensions = new Set([
|
||||
'.ts',
|
||||
'.tsx',
|
||||
'.js',
|
||||
'.mjs',
|
||||
'.cjs',
|
||||
'.scss',
|
||||
'.css',
|
||||
'.json',
|
||||
'.html',
|
||||
'.svg',
|
||||
]);
|
||||
|
||||
function replaceBqPrefix(text) {
|
||||
return text.replace(/(^|[^A-Za-z0-9])bq/g, `$1${projectName}`);
|
||||
}
|
||||
|
||||
async function rewriteFile(file) {
|
||||
const text = await readFile(file, 'utf8');
|
||||
const next =
|
||||
path.basename(file) === 'package-lock.json'
|
||||
? text.replaceAll('"name": "bq_react"', `"name": "${replaceBqPrefix('bq_react')}"`)
|
||||
: replaceBqPrefix(text);
|
||||
if (next !== text) await writeFile(file, next);
|
||||
}
|
||||
|
||||
function shouldRewrite(file, inSrc) {
|
||||
if (inSrc) return textExtensions.has(path.extname(file));
|
||||
const base = path.basename(file);
|
||||
return base === 'package.json' || base === 'package-lock.json';
|
||||
}
|
||||
|
||||
async function processDir(dir) {
|
||||
const relativeDir = path.relative(root, dir);
|
||||
const inSrc = relativeDir === 'src' || relativeDir.startsWith(`src${path.sep}`);
|
||||
const entries = await readdir(dir, { withFileTypes: true });
|
||||
|
||||
for (const entry of entries) {
|
||||
if (skipDirs.has(entry.name)) continue;
|
||||
const full = path.join(dir, entry.name);
|
||||
if (entry.isDirectory()) {
|
||||
await processDir(full);
|
||||
} else if (entry.isFile() && shouldRewrite(full, inSrc)) {
|
||||
await rewriteFile(full);
|
||||
}
|
||||
}
|
||||
|
||||
if (!inSrc) return;
|
||||
|
||||
const after = await readdir(dir, { withFileTypes: true });
|
||||
for (const entry of after) {
|
||||
const nextName = replaceBqPrefix(entry.name);
|
||||
if (nextName === entry.name) continue;
|
||||
await rename(path.join(dir, entry.name), path.join(dir, nextName));
|
||||
}
|
||||
}
|
||||
|
||||
await processDir(root);
|
||||
console.log(`已将 bq 前缀替换为 ${projectName}`);
|
||||
69
scripts/create.sh
Executable file
69
scripts/create.sh
Executable file
@@ -0,0 +1,69 @@
|
||||
#!/usr/bin/env bash
|
||||
# 从公开 GitHub 仓库创建项目,并把源码中的 bq 前缀换成项目名。
|
||||
# 用法:
|
||||
# curl -fsSL https://raw.githubusercontent.com/bqbqbqbqbq-l/bq_react/v0.1.0/scripts/create.sh | bash -s -- shop
|
||||
set -euo pipefail
|
||||
|
||||
OWNER="bqbqbqbqbq-l"
|
||||
REPO="bq_react"
|
||||
REF="${BQ_REF:-v0.1.0}"
|
||||
NAME="${1:-}"
|
||||
|
||||
if [[ ! "$NAME" =~ ^[a-z][a-z0-9-]*$ ]]; then
|
||||
echo "用法: curl -fsSL https://raw.githubusercontent.com/${OWNER}/${REPO}/${REF}/scripts/create.sh | bash -s -- <项目名>" >&2
|
||||
echo "项目名需为小写字母开头,只含小写字母、数字和连字符" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -e "$NAME" ]]; then
|
||||
echo "目录已存在: $NAME" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
command -v gh >/dev/null 2>&1 || {
|
||||
echo "需要 GitHub CLI。安装后执行: gh auth login" >&2
|
||||
exit 1
|
||||
}
|
||||
command -v node >/dev/null 2>&1 || {
|
||||
echo "需要 Node.js" >&2
|
||||
exit 1
|
||||
}
|
||||
gh auth status >/dev/null 2>&1 || {
|
||||
echo "请先登录 GitHub CLI: gh auth login" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
TMP="$(mktemp -d)"
|
||||
cleanup() { rm -rf "$TMP"; }
|
||||
trap cleanup EXIT
|
||||
|
||||
ARCHIVE="$TMP/src.tar.gz"
|
||||
if ! gh api "repos/${OWNER}/${REPO}/tarball/${REF}" >"$ARCHIVE"; then
|
||||
echo "下载失败。请确认 ${OWNER}/${REPO} 上存在引用 ${REF}。" >&2
|
||||
exit 1
|
||||
fi
|
||||
if ! tar -tzf "$ARCHIVE" >/dev/null 2>&1; then
|
||||
echo "下载到的不是源码包。GitHub 返回:" >&2
|
||||
head -c 500 "$ARCHIVE" >&2 || true
|
||||
echo >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p "$TMP/src"
|
||||
tar -xzf "$ARCHIVE" -C "$TMP/src"
|
||||
shopt -s nullglob
|
||||
entries=("$TMP/src"/*)
|
||||
if [[ ${#entries[@]} -ne 1 || ! -d "${entries[0]}" ]]; then
|
||||
echo "压缩包结构异常" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mv "${entries[0]}" "$NAME"
|
||||
node "$NAME/scripts/apply-name.mjs" "$NAME" "$NAME"
|
||||
rm -rf "$NAME/scripts"
|
||||
git init -b main "$NAME" >/dev/null
|
||||
(cd "$NAME" && npm install)
|
||||
|
||||
echo "项目已创建: $NAME"
|
||||
echo "bq 前缀已替换为 ${NAME},例如包名 ${NAME}_react"
|
||||
echo "下一步: cd $NAME && npm run dev"
|
||||
Reference in New Issue
Block a user