@@ -2,15 +2,38 @@ import { $ } from "execa";
22import { chdir } from "node:process" ;
33import ora from "ora" ;
44import chalk from "chalk" ;
5- import { createRepo } from "../api/github" ;
5+ import { createRepo , deleteRepo , getCurrentUser } from "../api/github" ;
66import { debug } from "./index" ;
77import { DOWNLOAD_CONFIG , MESSAGES } from "../constants" ;
8+ import { DEFAULT_BRANCH } from "../constants" ;
9+ // 存储已创建的远程仓库信息,用于错误时清理
10+ let createdRepoInfo : { owner : string ; repo : string ; token : string } | null =
11+ null ;
812const spinner = ora ( {
913 text : chalk . cyan ( "🚀 正在初始化项目..." ) ,
1014 spinner : DOWNLOAD_CONFIG . spinner . type ,
1115 color : DOWNLOAD_CONFIG . spinner . color ,
1216} ) ;
1317
18+ // 清理远程仓库的函数
19+ export async function cleanupRemoteRepo ( ) {
20+ if ( createdRepoInfo ) {
21+ try {
22+ console . log ( chalk . yellow ( "🗑️ 正在清理远程仓库..." ) ) ;
23+ await deleteRepo (
24+ createdRepoInfo . owner ,
25+ createdRepoInfo . repo ,
26+ createdRepoInfo . token
27+ ) ;
28+ console . log ( chalk . green ( "✅ 远程仓库已清理" ) ) ;
29+ } catch ( error ) {
30+ console . log ( chalk . red ( "❌ 清理远程仓库失败:" ) , error ) ;
31+ } finally {
32+ createdRepoInfo = null ;
33+ }
34+ }
35+ }
36+
1437export async function init ( pkg : Record < string , string > ) {
1538 let sshUrl = "" ;
1639 try {
@@ -58,8 +81,8 @@ export async function initREPO(pkg: Record<string, unknown>) {
5881 } ,
5982 token
6083 ) ;
61- const result = await res ?. json ( ) ;
62- const { ssh_url, html_url, message } = result ;
84+ const result = ( await res ?. json ( ) ) as any ;
85+ const { ssh_url, html_url, message } = result || { } ;
6386 pkg . homepage = `${ html_url } #readme` ;
6487 if (
6588 typeof pkg . repository === "object" &&
@@ -71,6 +94,20 @@ export async function initREPO(pkg: Record<string, unknown>) {
7194 if ( typeof pkg . bugs === "object" && pkg . bugs && "url" in pkg . bugs )
7295 pkg . bugs . url = `${ html_url } /issues` ;
7396 if ( ssh_url ) {
97+ // 获取用户信息并保存仓库信息,用于错误时清理
98+ try {
99+ const userRes = await getCurrentUser ( token ) ;
100+ const userData = ( await userRes ?. json ( ) ) as any ;
101+ if ( userData ?. login ) {
102+ createdRepoInfo = {
103+ owner : userData . login ,
104+ repo : pkg . name as string ,
105+ token : token ,
106+ } ;
107+ }
108+ } catch ( userError ) {
109+ console . log ( chalk . yellow ( "⚠️ 获取用户信息失败,无法设置自动清理" ) ) ;
110+ }
74111 spinner . succeed ( chalk . green ( MESSAGES . success . repoCreated ) ) ;
75112 return ssh_url ;
76113 } else {
@@ -82,7 +119,12 @@ export async function initREPO(pkg: Record<string, unknown>) {
82119 console . log ( chalk . gray ( MESSAGES . tips . regenerateToken ) ) ;
83120 throw new Error ( "授权失败,请检查权限" ) ;
84121 }
85- if ( message ?. includes ( "name already exists" ) ) {
122+ if (
123+ message ?. includes ( "name already exists" ) ||
124+ result ?. errors ?. some ( ( error : any ) =>
125+ error . message ?. includes ( "name already exists" )
126+ )
127+ ) {
86128 spinner . fail ( chalk . red ( MESSAGES . error . repoExists ) ) ;
87129 console . log ( chalk . yellow ( MESSAGES . tips . tryDifferentName ) ) ;
88130 throw new Error ( "仓库名称已存在" ) ;
@@ -107,7 +149,7 @@ export async function initGIT(name: string, sshURL: string) {
107149 // Git初始化
108150 await $ `git init` ;
109151 // 切换 main 分支
110- await $ `git checkout -b main ` ;
152+ await $ `git checkout -b ${ DEFAULT_BRANCH } ` ;
111153
112154 if ( sshURL ) {
113155 // 初始化远程仓库
@@ -119,6 +161,11 @@ export async function initGIT(name: string, sshURL: string) {
119161 } catch ( error ) {
120162 spinner . fail ( chalk . red ( MESSAGES . error . gitInitFailed ) ) ;
121163 debug ( error ) ;
164+
165+ // 如果已创建远程仓库,则清理
166+ if ( createdRepoInfo ) {
167+ await cleanupRemoteRepo ( ) ;
168+ }
122169 throw error ;
123170 } finally {
124171 chdir ( `../` ) ;
@@ -137,6 +184,11 @@ export async function initInstall(name: string) {
137184 console . log ( chalk . gray ( MESSAGES . tips . network ) ) ;
138185 console . log ( chalk . gray ( MESSAGES . tips . manualInstall ) ) ;
139186 debug ( error ) ;
187+
188+ // 如果已创建远程仓库,则清理
189+ if ( createdRepoInfo ) {
190+ await cleanupRemoteRepo ( ) ;
191+ }
140192 throw error ;
141193 } finally {
142194 chdir ( `../` ) ;
@@ -160,11 +212,15 @@ export async function initCommitPush(name: string) {
160212 await $ `git commit --no-verify --message ${ "Initial commit" } ` ;
161213 // Git推送到远程仓库
162214 await $ `git config pull.rebase false` ;
163- await $ `git pull origin main --allow-unrelated-histories` . catch ( ( ) => {
164- // 如果远程仓库为空,pull 可能会失败,这是正常的
165- } ) ;
215+ await $ `git pull origin ${ DEFAULT_BRANCH } --allow-unrelated-histories` . catch (
216+ ( ) => {
217+ // 如果远程仓库为空,pull 可能会失败,这是正常的
218+ }
219+ ) ;
166220 // Git推送到远程仓库
167- await $ `git push origin main` ;
221+ await $ `git push origin ${ DEFAULT_BRANCH } ` ;
222+ // 推送成功,清除仓库信息,避免误删除
223+ createdRepoInfo = null ;
168224 spinner . succeed ( chalk . green ( MESSAGES . success . codePushed ) ) ;
169225 } catch ( error ) {
170226 spinner . fail ( chalk . red ( MESSAGES . error . pushFailed ) ) ;
@@ -173,6 +229,16 @@ export async function initCommitPush(name: string) {
173229 console . log ( chalk . gray ( MESSAGES . tips . checkRepoAccess ) ) ;
174230 console . log ( chalk . gray ( MESSAGES . tips . manualPush ) ) ;
175231 debug ( error ) ;
232+
233+ // 检查是否是远程仓库同名错误,如果不是则清理远程仓库
234+ const errorMessage = error ?. toString ( ) || "" ;
235+ if (
236+ ! errorMessage . includes ( "already exists" ) &&
237+ ! errorMessage . includes ( "name already exists" ) &&
238+ createdRepoInfo
239+ ) {
240+ await cleanupRemoteRepo ( ) ;
241+ }
176242 // 不抛出错误,允许项目创建继续完成
177243 } finally {
178244 chdir ( `../` ) ;
0 commit comments