mirror of
https://github.com/go-i2p/gitlab-to-gitea.git
synced 2025-06-07 18:24:23 -04:00
148 lines
4.4 KiB
Go
148 lines
4.4 KiB
Go
// groups.go
|
|
|
|
// Package migration handles the migration of data from GitLab to Gitea
|
|
package migration
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/xanzy/go-gitlab"
|
|
|
|
"github.com/go-i2p/gitlab-to-gitea/utils"
|
|
)
|
|
|
|
// organizationCreateRequest represents the data needed to create an organization in Gitea
|
|
type organizationCreateRequest struct {
|
|
Description string `json:"description"`
|
|
FullName string `json:"full_name"`
|
|
Location string `json:"location"`
|
|
Username string `json:"username"`
|
|
Website string `json:"website"`
|
|
}
|
|
|
|
// ImportGroup imports a single GitLab group to Gitea as an organization
|
|
func (m *Manager) ImportGroup(group *gitlab.Group) error {
|
|
cleanName := utils.CleanName(group.Name)
|
|
|
|
utils.PrintInfo(fmt.Sprintf("Importing group %s...", cleanName))
|
|
|
|
// Check if organization already exists
|
|
if exists, err := m.organizationExists(cleanName); err != nil {
|
|
return fmt.Errorf("failed to check if organization exists: %w", err)
|
|
} else if exists {
|
|
utils.PrintWarning(fmt.Sprintf("Group %s already exists in Gitea, skipping!", cleanName))
|
|
return nil
|
|
}
|
|
|
|
// Get group members
|
|
members, err := m.gitlabClient.GetGroupMembers(group.ID)
|
|
if err != nil {
|
|
utils.PrintWarning(fmt.Sprintf("Error fetching members for group %s: %v", group.Name, err))
|
|
members = []*gitlab.GroupMember{}
|
|
}
|
|
|
|
utils.PrintInfo(fmt.Sprintf("Found %d GitLab members for group %s", len(members), cleanName))
|
|
|
|
// Create organization request
|
|
orgReq := organizationCreateRequest{
|
|
Description: group.Description,
|
|
FullName: group.FullName,
|
|
Location: "",
|
|
Username: cleanName,
|
|
Website: "",
|
|
}
|
|
|
|
// Call Gitea API to create organization
|
|
var result map[string]interface{}
|
|
err = m.giteaClient.Post("/orgs", orgReq, &result)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to create organization %s: %w", cleanName, err)
|
|
}
|
|
|
|
utils.PrintInfo(fmt.Sprintf("Group %s imported!", cleanName))
|
|
|
|
// Import group members
|
|
if err := m.importGroupMembers(members, cleanName); err != nil {
|
|
utils.PrintWarning(fmt.Sprintf("Error importing members for group %s: %v", cleanName, err))
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// importGroupMembers imports group members to the first team in an organization
|
|
func (m *Manager) importGroupMembers(members []*gitlab.GroupMember, orgName string) error {
|
|
// Get existing teams
|
|
var teams []map[string]interface{}
|
|
err := m.giteaClient.Get(fmt.Sprintf("/orgs/%s/teams", orgName), &teams)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to get teams for organization %s: %w", orgName, err)
|
|
}
|
|
|
|
if len(teams) == 0 {
|
|
return fmt.Errorf("no teams found for organization %s", orgName)
|
|
}
|
|
|
|
firstTeam := teams[0]
|
|
teamID := int(firstTeam["id"].(float64))
|
|
teamName := firstTeam["name"].(string)
|
|
|
|
utils.PrintInfo(fmt.Sprintf("Organization teams fetched, importing users to first team: %s", teamName))
|
|
|
|
// Add members to the team
|
|
for _, member := range members {
|
|
cleanUsername := utils.NormalizeUsername(member.Username)
|
|
|
|
exists, err := m.memberExists(cleanUsername, teamID)
|
|
if err != nil {
|
|
utils.PrintWarning(fmt.Sprintf("Error checking if member %s exists: %v", cleanUsername, err))
|
|
continue
|
|
}
|
|
|
|
if exists {
|
|
utils.PrintWarning(fmt.Sprintf("Member %s already exists for team %s, skipping!", member.Username, teamName))
|
|
continue
|
|
}
|
|
|
|
// Add member to team
|
|
err = m.giteaClient.Put(fmt.Sprintf("/teams/%d/members/%s", teamID, cleanUsername), nil, nil)
|
|
if err != nil {
|
|
utils.PrintError(fmt.Sprintf("Failed to add member %s to team %s: %v", member.Username, teamName, err))
|
|
continue
|
|
}
|
|
|
|
utils.PrintInfo(fmt.Sprintf("Member %s added to team %s!", member.Username, teamName))
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// organizationExists checks if an organization exists in Gitea
|
|
func (m *Manager) organizationExists(orgName string) (bool, error) {
|
|
var org map[string]interface{}
|
|
err := m.giteaClient.Get("/orgs/"+orgName, &org)
|
|
if err != nil {
|
|
if isNotFoundError(err) {
|
|
return false, nil
|
|
}
|
|
return false, fmt.Errorf("error checking if organization exists: %w", err)
|
|
}
|
|
return true, nil
|
|
}
|
|
|
|
// memberExists checks if a user is a member of a team
|
|
func (m *Manager) memberExists(username string, teamID int) (bool, error) {
|
|
var members []map[string]interface{}
|
|
err := m.giteaClient.Get(fmt.Sprintf("/teams/%d/members", teamID), &members)
|
|
if err != nil {
|
|
return false, fmt.Errorf("failed to get team members: %w", err)
|
|
}
|
|
|
|
for _, member := range members {
|
|
if member["username"].(string) == username {
|
|
return true, nil
|
|
}
|
|
}
|
|
|
|
return false, nil
|
|
}
|