-
Notifications
You must be signed in to change notification settings - Fork 35
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
…ormat. (#551) Adds two fields to the import CSV immediately before tags. One is for the Owner and should be empty or contain a single value in the form 'John Doe <[email protected]>'. The second is for contributors, and should be empty or a list of one or more values in the previous format, separated by commas. As this would be a comma-delimited field within a CSV, the whole value should be surrounded by quotes. This breaks compatibility with any existing import CSVs since it adds columns in the middle (necessary since the number of tags is unbounded and as such the tag list must come last). Fixes #538 @jortel Do you think we can get away with adding this to migration 11, or do you think I should create a new one? --------- Signed-off-by: Sam Lucidi <[email protected]>
- Loading branch information
Showing
6 changed files
with
138 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -277,6 +277,54 @@ func (m *Manager) createApplication(imp *model.Import) (ok bool) { | |
} | ||
} | ||
|
||
if imp.Owner != "" { | ||
name, email, parsed := parseStakeholder(imp.Owner) | ||
if !parsed { | ||
imp.ErrorMessage = fmt.Sprintf("Could not parse Owner '%s'.", imp.Owner) | ||
return | ||
} | ||
owner, found := m.findStakeholder(email) | ||
if !found { | ||
if imp.ImportSummary.CreateEntities { | ||
var err error | ||
owner, err = m.createStakeholder(name, email) | ||
if err != nil { | ||
imp.ErrorMessage = fmt.Sprintf("Owner '%s' could not be created.", imp.Owner) | ||
return | ||
} | ||
} else { | ||
imp.ErrorMessage = fmt.Sprintf("Owner '%s' could not be found.", imp.Owner) | ||
return | ||
} | ||
} | ||
app.OwnerID = &owner.ID | ||
} | ||
if imp.Contributors != "" { | ||
fields := strings.Split(imp.Contributors, ",") | ||
for _, f := range fields { | ||
name, email, parsed := parseStakeholder(f) | ||
if !parsed { | ||
imp.ErrorMessage = fmt.Sprintf("Could not parse Contributor '%s'.", f) | ||
return | ||
} | ||
contributor, found := m.findStakeholder(email) | ||
if !found { | ||
if imp.ImportSummary.CreateEntities { | ||
var err error | ||
contributor, err = m.createStakeholder(name, email) | ||
if err != nil { | ||
imp.ErrorMessage = fmt.Sprintf("Contributor '%s' could not be created.", imp.Owner) | ||
return | ||
} | ||
} else { | ||
imp.ErrorMessage = fmt.Sprintf("Contributor '%s' could not be found.", imp.Owner) | ||
return | ||
} | ||
} | ||
app.Contributors = append(app.Contributors, contributor) | ||
} | ||
} | ||
|
||
result := m.DB.Create(app) | ||
if result.Error != nil { | ||
imp.ErrorMessage = result.Error.Error() | ||
|
@@ -295,6 +343,25 @@ func (m *Manager) createApplication(imp *model.Import) (ok bool) { | |
return | ||
} | ||
|
||
func (m *Manager) createStakeholder(name string, email string) (stakeholder model.Stakeholder, err error) { | ||
stakeholder.Name = name | ||
stakeholder.Email = email | ||
err = m.DB.Create(&stakeholder).Error | ||
if err != nil { | ||
err = liberr.Wrap(err) | ||
} | ||
return | ||
} | ||
|
||
func (m *Manager) findStakeholder(email string) (stakeholder model.Stakeholder, found bool) { | ||
result := m.DB.First(&stakeholder, "email = ?", email) | ||
if result.Error != nil { | ||
return | ||
} | ||
found = true | ||
return | ||
} | ||
|
||
// | ||
// normalizedName transforms given name to be comparable as same with similar names | ||
// Example: normalizedName(" F oo-123 bar! ") returns "foo123bar!" | ||
|
@@ -304,3 +371,20 @@ func normalizedName(name string) (normName string) { | |
normName = invalidSymbols.ReplaceAllString(normName, "") | ||
return | ||
} | ||
|
||
// | ||
// parseStakeholder attempts to parse a stakeholder's name and an email address | ||
// out of a string like `John Smith <[email protected]>`. The pattern is very | ||
// simple and treats anything before the first bracket as the name, | ||
// and anything within the brackets as the email. | ||
func parseStakeholder(s string) (name string, email string, parsed bool) { | ||
pattern := regexp.MustCompile("(.+)\\s<(.+@.+)>") | ||
matches := pattern.FindStringSubmatch(strings.TrimSpace(s)) | ||
if len(matches) != 3 { | ||
return | ||
} | ||
parsed = true | ||
name = matches[1] | ||
email = strings.ToLower(matches[2]) | ||
return | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
Record Type 1,Application Name,Description,Comments,Business Service,Dependency,Dependency Direction,Binary Group,Binary Artifact,Binary Version,Binary Packaging,Repository Type,Repository URL,Repository Branch,Repository Path,Tag Category 1,Tag 1,Tag Category 2,Tag 2,Tag Category 3,Tag 3,Tag Category 4,Tag 4,Tag Category 5,Tag 5,Tag Category 6,Tag 6,Tag Category 7,Tag 7,Tag Category 8,Tag 8,Tag Category 9,Tag 9,Tag Category 10,Tag 10,Tag Category 11,Tag 11,Tag Category 12,Tag 12,Tag Category 13,Tag 13,Tag Category 14,Tag 14,Tag Category 15,Tag 15,Tag Category 16,Tag 16,Tag Category 17,Tag 17,Tag Category 18,Tag 18,Tag Category 19,Tag 19,Tag Category 20,Tag 20 | ||
1,Customers,Legacy Customers management service,,Retail,,,corp.acme.demo,customers-tomcat,0.0.1-SNAPSHOT,war,git,https://git-acme.local/customers.git,,,Operating System,RHEL 8,Database,Oracle,Language,Java,Runtime,Tomcat,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, | ||
1,Inventory,Inventory service,,Retail,,,corp.acme.demo,inventory,0.1.1-SNAPSHOT,war,git,https://git-acme.local/inventory.git,,,Operating System,RHEL 8,Database,Postgresql,Language,Java,Runtime,Quarkus,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, | ||
1,Gateway,API Gateway,,Retail,,,corp.acme.demo,gateway,0.1.1-SNAPSHOT,war,git,https://git-acme.local/gateway.git,,,Operating System,RHEL 8,,,Language,Java,Runtime,Spring Boot,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, | ||
Record Type 1,Application Name,Description,Comments,Business Service,Dependency,Dependency Direction,Binary Group,Binary Artifact,Binary Version,Binary Packaging,Repository Type,Repository URL,Repository Branch,Repository Path,Owner,Contributors,Tag Category 1,Tag 1,Tag Category 2,Tag 2,Tag Category 3,Tag 3,Tag Category 4,Tag 4,Tag Category 5,Tag 5,Tag Category 6,Tag 6,Tag Category 7,Tag 7,Tag Category 8,Tag 8,Tag Category 9,Tag 9,Tag Category 10,Tag 10,Tag Category 11,Tag 11,Tag Category 12,Tag 12,Tag Category 13,Tag 13,Tag Category 14,Tag 14,Tag Category 15,Tag 15,Tag Category 16,Tag 16,Tag Category 17,Tag 17,Tag Category 18,Tag 18,Tag Category 19,Tag 19,Tag Category 20,Tag 20 | ||
1,Customers,Legacy Customers management service,,Retail,,,corp.acme.demo,customers-tomcat,0.0.1-SNAPSHOT,war,git,https://git-acme.local/customers.git,,,John Doe <[email protected]>,,Operating System,RHEL 8,Database,Oracle,Language,Java,Runtime,Tomcat,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, | ||
1,Inventory,Inventory service,,Retail,,,corp.acme.demo,inventory,0.1.1-SNAPSHOT,war,git,https://git-acme.local/inventory.git,,,,"John Doe <[email protected]>, Jane Smith <[email protected]>",Operating System,RHEL 8,Database,Postgresql,Language,Java,Runtime,Quarkus,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, | ||
1,Gateway,API Gateway,,Retail,,,corp.acme.demo,gateway,0.1.1-SNAPSHOT,war,git,https://git-acme.local/gateway.git,,,John Doe <[email protected]>,"John Doe <[email protected]>, Jane Smith <[email protected]>",Operating System,RHEL 8,,,Language,Java,Runtime,Spring Boot,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, | ||
2,Gateway,,,,Inventory,southbound | ||
2,Gateway,,,,Customers,southbound |