Skip to content

Commit 694b600

Browse files
fix: 实现 nameMode 逻辑,支持自动添加时间戳
- 在 ProcessUserCreation 中实现 nameMode 判断和时间戳生成 - 修改 ensureUser 接受实际的 username 和 email 参数 - 修改 createGroupsWithOutput 和 ensureGroup 支持组路径时间戳 - 修改 createProjectsWithOutput 支持项目路径时间戳 - 实现模式继承(项目继承组,组继承用户)
1 parent 7b3248c commit 694b600

File tree

1 file changed

+95
-22
lines changed

1 file changed

+95
-22
lines changed

internal/processor/processor.go

Lines changed: 95 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,37 @@ type ResourceProcessor struct {
2121

2222
// ProcessUserCreation 处理单个用户的创建流程
2323
func (p *ResourceProcessor) ProcessUserCreation(userSpec types.UserSpec) (*types.UserOutput, error) {
24+
// 确定 nameMode
25+
nameMode := userSpec.NameMode
26+
if nameMode == "" {
27+
nameMode = "prefix" // 默认为 prefix 模式
28+
}
29+
30+
// 根据 nameMode 生成实际的 username 和 email
31+
var actualUsername, actualEmail string
32+
if nameMode == "name" {
33+
// name 模式:直接使用配置文件中的名称
34+
actualUsername = userSpec.Username
35+
actualEmail = userSpec.Email
36+
log.Printf(" 使用 name 模式(不添加时间戳)\n")
37+
} else {
38+
// prefix 模式:添加时间戳
39+
actualUsername = utils.GenerateUsernameWithTimestamp(userSpec.Username)
40+
actualEmail = utils.GenerateEmailWithTimestamp(userSpec.Email)
41+
log.Printf(" 使用 prefix 模式(添加时间戳)\n")
42+
}
43+
44+
log.Printf(" 用户名: %s\n", actualUsername)
45+
log.Printf(" 邮箱: %s\n", actualEmail)
46+
2447
output := &types.UserOutput{
25-
Username: userSpec.Username,
26-
Email: userSpec.Email,
48+
Username: actualUsername,
49+
Email: actualEmail,
2750
Name: userSpec.Name,
2851
}
2952

3053
// 1. 创建或获取用户
31-
userID, err := p.ensureUser(userSpec)
54+
userID, err := p.ensureUser(userSpec, actualUsername, actualEmail)
3255
if err != nil {
3356
return nil, err
3457
}
@@ -37,7 +60,7 @@ func (p *ResourceProcessor) ProcessUserCreation(userSpec types.UserSpec) (*types
3760
// 2. 创建 Personal Access Token (如果配置了)
3861
if userSpec.Token != nil {
3962
log.Printf(" 创建 Personal Access Token...\n")
40-
tokenValue, actualExpiresAt, err := p.createPersonalAccessToken(userID, userSpec.Username, userSpec.Token)
63+
tokenValue, actualExpiresAt, err := p.createPersonalAccessToken(userID, actualUsername, userSpec.Token)
4164
if err != nil {
4265
log.Printf(" ⚠ 创建 Token 失败: %v\n", err)
4366
} else {
@@ -56,7 +79,7 @@ func (p *ResourceProcessor) ProcessUserCreation(userSpec types.UserSpec) (*types
5679
// 3. 创建组和项目
5780
if len(userSpec.Groups) > 0 {
5881
log.Printf(" 创建 %d 个组...\n", len(userSpec.Groups))
59-
groupOutputs, err := p.createGroupsWithOutput(userSpec.Username, userSpec.Groups)
82+
groupOutputs, err := p.createGroupsWithOutput(actualUsername, userSpec.Groups, nameMode)
6083
if err != nil {
6184
return output, err
6285
}
@@ -95,36 +118,42 @@ func (p *ResourceProcessor) createPersonalAccessToken(userID int, username strin
95118
}
96119

97120
// ensureUser 确保用户存在,如果不存在则创建
98-
func (p *ResourceProcessor) ensureUser(userSpec types.UserSpec) (int, error) {
99-
existingUser, err := p.Client.GetUser(userSpec.Username)
121+
func (p *ResourceProcessor) ensureUser(userSpec types.UserSpec, actualUsername, actualEmail string) (int, error) {
122+
existingUser, err := p.Client.GetUser(actualUsername)
100123
if err != nil {
101124
log.Printf(" ⚠ 检查用户失败: %v\n", err)
102125
}
103126

104127
if existingUser != nil {
105-
log.Printf(" ⚠ 用户 '%s' 已存在 (ID: %d)\n", userSpec.Username, existingUser.ID)
128+
log.Printf(" ⚠ 用户 '%s' 已存在 (ID: %d)\n", actualUsername, existingUser.ID)
106129
return existingUser.ID, nil
107130
}
108131

109-
log.Printf(" 创建用户: %s\n", userSpec.Username)
110-
user, err := p.Client.CreateUser(userSpec.Username, userSpec.Email, userSpec.Name, userSpec.Password)
132+
log.Printf(" 创建用户: %s\n", actualUsername)
133+
user, err := p.Client.CreateUser(actualUsername, actualEmail, userSpec.Name, userSpec.Password)
111134
if err != nil {
112-
return 0, fmt.Errorf("创建用户 %s: %w", userSpec.Username, err)
135+
return 0, fmt.Errorf("创建用户 %s: %w", actualUsername, err)
113136
}
114137

115138
log.Printf(" ✓ 用户创建成功 (ID: %d)\n", user.ID)
116139
return user.ID, nil
117140
}
118141

119142
// createGroupsWithOutput 创建多个组及其项目并返回输出结果
120-
func (p *ResourceProcessor) createGroupsWithOutput(username string, groups []types.GroupSpec) ([]types.GroupOutput, error) {
143+
func (p *ResourceProcessor) createGroupsWithOutput(username string, groups []types.GroupSpec, userNameMode string) ([]types.GroupOutput, error) {
121144
var groupOutputs []types.GroupOutput
122145

123146
for j, groupSpec := range groups {
124147
log.Printf(" ------------------------------------------\n")
125148
log.Printf(" 处理组 [%d/%d]: %s\n", j+1, len(groups), groupSpec.Name)
126149

127-
groupID, groupPath, err := p.ensureGroup(username, groupSpec)
150+
// 确定组的 nameMode(如果组没有指定,则继承用户的 nameMode)
151+
groupNameMode := groupSpec.NameMode
152+
if groupNameMode == "" {
153+
groupNameMode = userNameMode
154+
}
155+
156+
groupID, groupPath, err := p.ensureGroup(username, groupSpec, groupNameMode)
128157
if err != nil {
129158
log.Printf(" ⚠ 创建组失败 %s: %v\n", groupSpec.Path, err)
130159
continue
@@ -140,7 +169,7 @@ func (p *ResourceProcessor) createGroupsWithOutput(username string, groups []typ
140169
// 创建组下的项目
141170
if len(groupSpec.Projects) > 0 {
142171
log.Printf(" 创建 %d 个项目...\n", len(groupSpec.Projects))
143-
projectOutputs, err := p.createProjectsWithOutput(username, groupID, groupPath, groupSpec.Projects)
172+
projectOutputs, err := p.createProjectsWithOutput(username, groupID, groupPath, groupSpec.Projects, groupNameMode)
144173
if err != nil {
145174
log.Printf(" ⚠ 创建项目失败: %v\n", err)
146175
}
@@ -153,19 +182,38 @@ func (p *ResourceProcessor) createGroupsWithOutput(username string, groups []typ
153182
}
154183

155184
// ensureGroup 确保组存在,如果不存在则创建
156-
func (p *ResourceProcessor) ensureGroup(username string, groupSpec types.GroupSpec) (int, string, error) {
157-
existingGroup, _ := p.Client.GetGroup(groupSpec.Path)
185+
func (p *ResourceProcessor) ensureGroup(username string, groupSpec types.GroupSpec, nameMode string) (int, string, error) {
186+
// 根据 nameMode 生成实际的 group path
187+
var actualGroupPath string
188+
if nameMode == "name" {
189+
// name 模式:直接使用配置文件中的名称
190+
actualGroupPath = groupSpec.Path
191+
if actualGroupPath == "" {
192+
actualGroupPath = groupSpec.Name
193+
}
194+
log.Printf(" 使用 name 模式,组 path: %s\n", actualGroupPath)
195+
} else {
196+
// prefix 模式:添加时间戳
197+
if groupSpec.Path == "" {
198+
actualGroupPath = utils.GenerateGroupPathWithTimestamp(groupSpec.Name)
199+
} else {
200+
actualGroupPath = utils.GenerateGroupPathWithTimestamp(groupSpec.Path)
201+
}
202+
log.Printf(" 使用 prefix 模式,生成组 path: %s\n", actualGroupPath)
203+
}
204+
205+
existingGroup, _ := p.Client.GetGroup(actualGroupPath)
158206

159207
if existingGroup != nil {
160208
log.Printf(" ⚠ 组 '%s' 已存在 (ID: %d)\n", existingGroup.Path, existingGroup.ID)
161209
return existingGroup.ID, existingGroup.Path, nil
162210
}
163211

164-
log.Printf(" 创建组: %s\n", groupSpec.Name)
212+
log.Printf(" 创建组: %s (path: %s)\n", groupSpec.Name, actualGroupPath)
165213
group, err := p.Client.CreateGroup(
166214
username,
167215
groupSpec.Name,
168-
groupSpec.Path,
216+
actualGroupPath,
169217
utils.GetVisibility(groupSpec.Visibility),
170218
)
171219
if err != nil {
@@ -177,11 +225,36 @@ func (p *ResourceProcessor) ensureGroup(username string, groupSpec types.GroupSp
177225
}
178226

179227
// createProjectsWithOutput 创建多个项目并返回输出结果
180-
func (p *ResourceProcessor) createProjectsWithOutput(username string, groupID int, groupPath string, projects []types.ProjectSpec) ([]types.ProjectOutput, error) {
228+
func (p *ResourceProcessor) createProjectsWithOutput(username string, groupID int, groupPath string, projects []types.ProjectSpec, groupNameMode string) ([]types.ProjectOutput, error) {
181229
var projectOutputs []types.ProjectOutput
182230

183231
for _, projSpec := range projects {
184-
fullPath := fmt.Sprintf("%s/%s", groupPath, projSpec.Path)
232+
// 确定项目的 nameMode(如果项目没有指定,则继承组的 nameMode)
233+
projectNameMode := projSpec.NameMode
234+
if projectNameMode == "" {
235+
projectNameMode = groupNameMode
236+
}
237+
238+
// 根据 nameMode 生成实际的 project path
239+
var actualProjectPath string
240+
if projectNameMode == "name" {
241+
// name 模式:直接使用配置文件中的名称
242+
actualProjectPath = projSpec.Path
243+
if actualProjectPath == "" {
244+
actualProjectPath = projSpec.Name
245+
}
246+
log.Printf(" 使用 name 模式,项目 path: %s\n", actualProjectPath)
247+
} else {
248+
// prefix 模式:添加时间戳
249+
if projSpec.Path == "" {
250+
actualProjectPath = utils.GenerateProjectPathWithTimestamp(projSpec.Name)
251+
} else {
252+
actualProjectPath = utils.GenerateProjectPathWithTimestamp(projSpec.Path)
253+
}
254+
log.Printf(" 使用 prefix 模式,生成项目 path: %s\n", actualProjectPath)
255+
}
256+
257+
fullPath := fmt.Sprintf("%s/%s", groupPath, actualProjectPath)
185258
existingProj, _ := p.Client.GetProject(fullPath)
186259

187260
var projectID int
@@ -192,12 +265,12 @@ func (p *ResourceProcessor) createProjectsWithOutput(username string, groupID in
192265
projectID = existingProj.ID
193266
webURL = existingProj.WebURL
194267
} else {
195-
log.Printf(" 创建项目: %s\n", projSpec.Name)
268+
log.Printf(" 创建项目: %s (path: %s)\n", projSpec.Name, actualProjectPath)
196269
project, err := p.Client.CreateProject(
197270
username,
198271
groupID,
199272
projSpec.Name,
200-
projSpec.Path,
273+
actualProjectPath,
201274
projSpec.Description,
202275
utils.GetVisibility(projSpec.Visibility),
203276
)

0 commit comments

Comments
 (0)