Skip to content

Commit e24977a

Browse files
feat: 添加 user delete 命令支持按用户名删除
- 添加 user delete 命令,支持通过 --username 参数指定用户名删除 - 支持删除多个用户,用户名之间用逗号分隔 - 自动删除用户下的所有项目(包括个人项目和组内项目) - 自动删除用户拥有的所有组 - 更新 README 文档,添加使用示例 使用示例: gitlab-cli user delete --username user1 gitlab-cli user delete --username user1,user2,user3
1 parent 3d99dbf commit e24977a

File tree

3 files changed

+117
-0
lines changed

3 files changed

+117
-0
lines changed

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,18 @@ export GITLAB_TOKEN=your-personal-access-token
8080
# 2. 清理时使用输出文件
8181
./bin/gitlab-cli user cleanup \
8282
-f output.yaml
83+
84+
# 根据用户名删除用户及其所有资源(项目和组)
85+
./bin/gitlab-cli user delete \
86+
--host https://your-gitlab.com \
87+
--token your-token \
88+
--username user1
89+
90+
# 删除多个用户(用逗号分隔)
91+
./bin/gitlab-cli user delete \
92+
--host https://your-gitlab.com \
93+
--token your-token \
94+
--username user1,user2,user3
8395
```
8496

8597
## 📖 配置文件示例

internal/cli/cmd.go

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ func buildUserCommand(cfg *config.CLIConfig) *cobra.Command {
4848

4949
userCmd.AddCommand(buildUserCreateCommand(cfg))
5050
userCmd.AddCommand(buildUserCleanupCommand(cfg))
51+
userCmd.AddCommand(buildUserDeleteCommand(cfg))
5152

5253
return userCmd
5354
}
@@ -88,6 +89,32 @@ func buildUserCleanupCommand(cfg *config.CLIConfig) *cobra.Command {
8889
return cmd
8990
}
9091

92+
// buildUserDeleteCommand 构建用户删除命令
93+
func buildUserDeleteCommand(cfg *config.CLIConfig) *cobra.Command {
94+
var usernames string
95+
96+
cmd := &cobra.Command{
97+
Use: "delete",
98+
Short: "删除指定用户名的用户及其项目和组",
99+
Long: `根据用户名删除用户及其所有资源(项目和组)。
100+
支持删除多个用户,用户名之间用逗号分隔。
101+
102+
示例:
103+
gitlab-cli user delete --username user1
104+
gitlab-cli user delete --username user1,user2,user3`,
105+
RunE: func(cmd *cobra.Command, args []string) error {
106+
return runUserDelete(cfg, usernames)
107+
},
108+
}
109+
110+
cmd.Flags().StringVar(&usernames, "username", "", "要删除的用户名(多个用户用逗号分隔)")
111+
cmd.Flags().StringVar(&cfg.GitLabHost, "host", "", "GitLab 主机地址")
112+
cmd.Flags().StringVar(&cfg.GitLabToken, "token", "", "GitLab Personal Access Token")
113+
cmd.MarkFlagRequired("username")
114+
115+
return cmd
116+
}
117+
91118
// runUserCreate 执行用户创建命令
92119
func runUserCreate(cfg *config.CLIConfig) error {
93120
gitlabClient, err := initializeClient(cfg)
@@ -196,6 +223,45 @@ func runUserCleanup(cfg *config.CLIConfig) error {
196223
return nil
197224
}
198225

226+
// runUserDelete 执行用户删除命令
227+
func runUserDelete(cfg *config.CLIConfig, usernames string) error {
228+
gitlabClient, err := initializeClient(cfg)
229+
if err != nil {
230+
return err
231+
}
232+
233+
// 解析用户名列表(以逗号分隔)
234+
usernameList := strings.Split(usernames, ",")
235+
// 去除空格
236+
for i, username := range usernameList {
237+
usernameList[i] = strings.TrimSpace(username)
238+
}
239+
240+
log.Printf("\n准备删除 %d 个用户\n\n", len(usernameList))
241+
242+
proc := &processor.ResourceProcessor{Client: gitlabClient}
243+
244+
for i, username := range usernameList {
245+
if username == "" {
246+
continue
247+
}
248+
249+
log.Printf("==========================================\n")
250+
log.Printf("处理 [%d/%d]: %s\n", i+1, len(usernameList), username)
251+
log.Printf("==========================================\n")
252+
253+
if err := proc.ProcessUserDelete(username); err != nil {
254+
log.Printf(" ⚠ 删除用户 %s 时出错: %v\n", username, err)
255+
continue
256+
}
257+
}
258+
259+
log.Println("========================================")
260+
log.Println("✓ 批量删除完成")
261+
log.Println("========================================")
262+
return nil
263+
}
264+
199265
// initializeClient 初始化并验证 GitLab 客户端
200266
func initializeClient(cfg *config.CLIConfig) (*client.GitLabClient, error) {
201267
if err := config.LoadGitLabCredentials(cfg); err != nil {

internal/processor/processor.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -609,3 +609,42 @@ func (p *ResourceProcessor) deleteUser(userID int, username string) error {
609609

610610
return nil
611611
}
612+
613+
// ========================================
614+
// 用户删除流程(根据用户名)
615+
// ========================================
616+
617+
// ProcessUserDelete 根据用户名删除用户及其所有资源
618+
func (p *ResourceProcessor) ProcessUserDelete(username string) error {
619+
user, err := p.Client.GetUser(username)
620+
if err != nil {
621+
log.Printf(" ⚠ 检查用户失败: %v\n", err)
622+
return nil
623+
}
624+
625+
if user == nil {
626+
log.Printf(" 用户不存在,跳过: %s\n\n", username)
627+
return nil
628+
}
629+
630+
log.Printf(" 找到用户 '%s' (ID: %d, 邮箱: %s)\n", user.Username, user.ID, user.Email)
631+
632+
// 1. 删除用户级项目(不属于任何组的项目)
633+
log.Printf(" 删除用户级项目...\n")
634+
p.deleteUserProjects(username)
635+
636+
// 2. 删除用户拥有的所有组
637+
p.deleteUserOwnedGroups(username)
638+
639+
// 3. 等待数据同步
640+
log.Printf(" 等待 GitLab 内部数据同步 (10秒)...\n")
641+
time.Sleep(10 * time.Second)
642+
643+
// 4. 删除用户
644+
if err := p.deleteUser(user.ID, username); err != nil {
645+
log.Printf(" ⚠ 删除用户失败: %v\n\n", err)
646+
return err
647+
}
648+
649+
return nil
650+
}

0 commit comments

Comments
 (0)