@@ -21,14 +21,37 @@ type ResourceProcessor struct {
2121
2222// ProcessUserCreation 处理单个用户的创建流程
2323func (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