This commit is contained in:
Sergey Zhemoytel 2024-11-21 14:20:10 +03:00
parent cb816f8d66
commit f40022f203
5 changed files with 268 additions and 229 deletions

View file

@ -2,6 +2,7 @@ nexus:
url: "http://127.0.0.1:8081" url: "http://127.0.0.1:8081"
username: "your-nexus-username" username: "your-nexus-username"
password: "your-nexus-password" password: "your-nexus-password"
repository: "my-repository"
gitea: gitea:
url: "http://127.0.0.1:3000" url: "http://127.0.0.1:3000"

View file

@ -1,35 +1,36 @@
package config package config
import ( import (
"os" "os"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
) )
type Config struct { type Config struct {
Nexus struct { Nexus struct {
URL string `yaml:"url"` URL string `yaml:"url"`
Username string `yaml:"username"` Username string `yaml:"username"`
Password string `yaml:"password"` Password string `yaml:"password"`
} `yaml:"nexus"` Repository string `yaml:"repository"`
Gitea struct { } `yaml:"nexus"`
URL string `yaml:"url"` Gitea struct {
Token string `yaml:"token"` URL string `yaml:"url"`
Username string `yaml:"username"` Token string `yaml:"token"`
Repo string `yaml:"repo"` Username string `yaml:"username"`
} `yaml:"gitea"` Repo string `yaml:"repo"`
} `yaml:"gitea"`
} }
func LoadConfig(filename string) (*Config, error) { func LoadConfig(filename string) (*Config, error) {
data, err := os.ReadFile(filename) data, err := os.ReadFile(filename)
if err != nil { if err != nil {
return nil, err return nil, err
} }
var config Config var config Config
err = yaml.Unmarshal(data, &config) err = yaml.Unmarshal(data, &config)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &config, nil return &config, nil
} }

View file

@ -1,73 +1,94 @@
package core package core
import ( import (
"flag" "flag"
"log" "log"
"strings"
"tvoygit.ru/djam/artmigrator/config" "tvoygit.ru/djam/artmigrator/config"
"tvoygit.ru/djam/artmigrator/repository/gitea" "tvoygit.ru/djam/artmigrator/repository/gitea"
"tvoygit.ru/djam/artmigrator/repository/nexus" "tvoygit.ru/djam/artmigrator/repository/nexus"
) )
type App struct { type App struct {
Config *config.Config Config *config.Config
} }
func NewApp(configFile string) (*App, error) { func NewApp(configFile string) (*App, error) {
log.Println("Загрузка конфигурации из файла", configFile) log.Println("Загрузка конфигурации из файла", configFile)
cfg, err := config.LoadConfig(configFile) cfg, err := config.LoadConfig(configFile)
if err != nil { if err != nil {
return nil, err return nil, err
} }
flag.StringVar(&cfg.Nexus.URL, "nexus-url", cfg.Nexus.URL, "Nexus URL") flag.StringVar(&cfg.Nexus.URL, "nexus-url", cfg.Nexus.URL, "Nexus URL")
flag.StringVar(&cfg.Nexus.Username, "nexus-username", cfg.Nexus.Username, "Nexus Username") flag.StringVar(&cfg.Nexus.Username, "nexus-username", cfg.Nexus.Username, "Nexus Username")
flag.StringVar(&cfg.Nexus.Password, "nexus-password", cfg.Nexus.Password, "Nexus Password") flag.StringVar(&cfg.Nexus.Password, "nexus-password", cfg.Nexus.Password, "Nexus Password")
flag.StringVar(&cfg.Gitea.URL, "gitea-url", cfg.Gitea.URL, "Gitea URL") flag.StringVar(&cfg.Gitea.URL, "gitea-url", cfg.Gitea.URL, "Gitea URL")
flag.StringVar(&cfg.Gitea.Token, "gitea-token", cfg.Gitea.Token, "Gitea Token") flag.StringVar(&cfg.Gitea.Token, "gitea-token", cfg.Gitea.Token, "Gitea Token")
flag.Parse() flag.Parse()
return &App{Config: cfg}, nil return &App{Config: cfg}, nil
} }
func (a *App) Run() error { func (a *App) Run() error {
log.Println("Начало процесса загрузки артефакта") log.Println("Начало процесса загрузки артефакта")
nexusClient := nexus.NewClient(a.Config.Nexus.URL, a.Config.Nexus.Username, a.Config.Nexus.Password) nexusClient := nexus.NewClient(a.Config.Nexus.URL, a.Config.Nexus.Username, a.Config.Nexus.Password)
log.Println("Авторизация в Nexus прошла успешно") log.Println("Авторизация в Nexus прошла успешно")
giteaClient := gitea.NewClient(a.Config.Gitea.URL, a.Config.Gitea.Token, a.Config) giteaClient := gitea.NewClient(a.Config.Gitea.URL, a.Config.Gitea.Token, a.Config)
log.Println("Авторизация в Gitea прошла успешно") log.Println("Авторизация в Gitea прошла успешно")
repository := "your-repository-name" repository := a.Config.Nexus.Repository
log.Println("Начало процесса загрузки артефактов...") log.Println("Начало процесса загрузки артефактов...")
artifacts, err := nexusClient.GetArtifacts(repository) artifacts, err := nexusClient.GetArtifacts(repository)
if err != nil { if err != nil {
return err return err
} }
log.Printf("Найдены артефакты для загрузки в Gitea: %v", artifacts) log.Printf("Найдены артефакты для загрузки в Gitea: %v", artifacts)
if len(artifacts) == 0 { if len(artifacts) == 0 {
log.Println("Нет артефактов для загрузки в Gitea") log.Println("Нет артефактов для загрузки в Gitea")
} else { } else {
for _, artifact := range artifacts { for _, artifact := range artifacts {
log.Printf("Загрузка артефакта %s из репозитория Nexus...", artifact) log.Printf("Загрузка артефакта %s из репозитория Nexus...", artifact)
data, err := nexusClient.GetArtifactData(repository, artifact) data, err := nexusClient.GetArtifactData(repository, artifact)
if err != nil { if err != nil {
log.Printf("Ошибка загрузки артефакта %s: %v", artifact, err) log.Printf("Ошибка загрузки артефакта %s: %v", artifact, err)
continue continue
} }
log.Printf("Артефакт %s загружен из репозитория Nexus", artifact) log.Printf("Артефакт %s загружен из репозитория Nexus", artifact)
log.Printf("Загрузка артефакта %s в репозиторий Gitea...", artifact) // Изменение функции Run для загрузки артефактов в Gitea
err = giteaClient.UploadArtifact(artifact, data) parts := strings.Split(artifact, "/")
if err != nil { if len(parts) < 4 {
log.Printf("Ошибка загрузки артефакта %s в Gitea: %v", artifact, err) log.Printf("Некорректный формат артефакта %s", artifact)
} else { continue
log.Printf("Артефакт %s успешно загружен в Gitea", artifact) }
} groupId := parts[0]
} artifactId := parts[1]
} version := parts[2]
log.Println("Процесс загрузки артефактов завершен.") fileParts := strings.Split(parts[3], ".")
return nil if len(fileParts) < 2 {
log.Printf("Некорректный формат файла %s", parts[3])
continue
}
if fileParts[len(fileParts)-1] == "md5" || fileParts[len(fileParts)-1] == "sha1" {
log.Printf("Пропускаем файл %s, так как он имеет расширение .md5 или .sha1", artifact)
continue
}
packaging := fileParts[len(fileParts)-1]
log.Printf("Загрузка артефакта %s в репозиторий Gitea...", artifact)
err = giteaClient.UploadArtifact(groupId, artifactId, version, packaging, data)
if err != nil {
log.Printf("Ошибка загрузки артефакта %s в Gitea: %v", artifact, err)
} else {
log.Printf("Артефакт %s успешно загружен в Gitea", artifact)
}
}
}
log.Println("Процесс загрузки артефактов завершен.")
return nil
} }

View file

@ -1,106 +1,109 @@
package gitea package gitea
import ( import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"log" "log"
"net/http" "net/http"
"tvoygit.ru/djam/artmigrator/config" "tvoygit.ru/djam/artmigrator/config"
"tvoygit.ru/djam/artmigrator/logger" "tvoygit.ru/djam/artmigrator/logger"
) )
type Client struct { type Client struct {
BaseURL string BaseURL string
HTTPClient *http.Client HTTPClient *http.Client
Token string Token string
Config *config.Config Config *config.Config
} }
func NewClient(baseURL, token string, config *config.Config) *Client { func NewClient(baseURL, token string, config *config.Config) *Client {
return &Client{ return &Client{
BaseURL: baseURL, BaseURL: baseURL,
HTTPClient: &http.Client{}, HTTPClient: &http.Client{},
Token: token, Token: token,
Config: config, Config: config,
} }
} }
func (c *Client) ArtifactExists(artifact string) (bool, error) { func (c *Client) ArtifactExists(artifact string) (bool, error) {
log.Printf("Проверка наличия артефакта %s в репозитории Gitea", artifact) log.Printf("Проверка наличия артефакта %s в репозитории Gitea", artifact)
url := fmt.Sprintf("%s/api/v1/repos/%s/%s/contents/%s", c.BaseURL, c.Config.Gitea.Username, c.Config.Gitea.Repo, artifact) url := fmt.Sprintf("%s/api/v1/repos/%s/%s/contents/%s", c.BaseURL, c.Config.Gitea.Username, c.Config.Gitea.Repo, artifact)
req, err := http.NewRequest("GET", url, nil) req, err := http.NewRequest("GET", url, nil)
if err != nil { if err != nil {
return false, err return false, err
} }
req.Header.Add("Authorization", fmt.Sprintf("token %s", c.Token)) req.Header.Add("Authorization", fmt.Sprintf("token %s", c.Token))
resp, err := c.HTTPClient.Do(req) resp, err := c.HTTPClient.Do(req)
if err != nil { if err != nil {
return false, err return false, err
} }
defer resp.Body.Close() defer resp.Body.Close()
if resp.StatusCode == http.StatusNotFound { if resp.StatusCode == http.StatusNotFound {
log.Printf("Артефакт %s не существует в репозитории Gitea", artifact) log.Printf("Артефакт %s не существует в репозитории Gitea", artifact)
return false, nil return false, nil
} }
log.Printf("Артефакт %s существует в репозитории Gitea", artifact) log.Printf("Артефакт %s существует в репозитории Gitea", artifact)
return true, nil return true, nil
} }
type UploadArtifactRequest struct { type UploadArtifactRequest struct {
Content string `json:"content"` Content string `json:"content"`
Message string `json:"message"` Message string `json:"message"`
} }
func (c *Client) UploadArtifact(artifactPath string, data []byte) error { func (c *Client) UploadArtifact(groupId, artifactId, version, packaging string, data []byte) error {
log.Printf("Загрузка артефакта %s в репозиторий Gitea", artifactPath) log.Printf("Загрузка артефакта %s-%s-%s.%s в репозиторий Gitea", groupId, artifactId, version, packaging)
url := fmt.Sprintf("%s/api/v1/repos/%s/%s/contents/%s?ref=master", c.BaseURL, c.Config.Gitea.Username, c.Config.Gitea.Repo, artifactPath) url := fmt.Sprintf("%s/api/v1/packages/%s/maven", c.BaseURL, c.Config.Gitea.Repo)
request := UploadArtifactRequest{ request := map[string]string{
Content: string(data), "groupId": groupId,
Message: "Upload artifact", "artifactId": artifactId,
} "version": version,
jsonRequest, err := json.Marshal(request) "packaging": packaging,
if err != nil { "file": fmt.Sprintf("%s-%s-%s.%s", artifactId, version, packaging, packaging),
return err }
} jsonRequest, err := json.Marshal(request)
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonRequest)) if err != nil {
if err != nil { return err
return err }
} req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonRequest))
req.Header.Add("Authorization", fmt.Sprintf("token %s", c.Token)) if err != nil {
req.Header.Add("Content-Type", "application/json") return err
}
req.Header.Add("Authorization", fmt.Sprintf("token %s", c.Token))
req.Header.Add("Content-Type", "application/json")
logger.Logger.Printf("Upload artifact request: %s", req.URL) logger.Logger.Printf("Upload artifact request: %s", req.URL)
logger.Logger.Printf("Upload artifact headers: %v", req.Header) logger.Logger.Printf("Upload artifact headers: %v", req.Header)
logger.Logger.Printf("Upload artifact body: %s", jsonRequest) logger.Logger.Printf("Upload artifact body: %s", jsonRequest)
resp, err := c.HTTPClient.Do(req) resp, err := c.HTTPClient.Do(req)
if err != nil { if err != nil {
logger.Logger.Printf("Upload artifact error: %v", err) logger.Logger.Printf("Upload artifact error: %v", err)
return err return err
} }
defer resp.Body.Close() defer resp.Body.Close()
logger.Logger.Printf("Upload artifact response status code: %d", resp.StatusCode) logger.Logger.Printf("Upload artifact response status code: %d", resp.StatusCode)
logger.Logger.Printf("Upload artifact response headers: %v", resp.Header) logger.Logger.Printf("Upload artifact response headers: %v", resp.Header)
body, err := ioutil.ReadAll(resp.Body) body, err := ioutil.ReadAll(resp.Body)
if err != nil { if err != nil {
logger.Logger.Printf("Upload artifact error reading response body: %v", err) logger.Logger.Printf("Upload artifact error reading response body: %v", err)
return err return err
} }
logger.Logger.Printf("Upload artifact response body: %s", body) logger.Logger.Printf("Upload artifact response body: %s", body)
if resp.StatusCode != http.StatusCreated { if resp.StatusCode != http.StatusCreated {
logger.Logger.Printf("Failed to upload artifact: %s", body) logger.Logger.Printf("Failed to upload artifact: %s", body)
return fmt.Errorf("failed to upload artifact") return fmt.Errorf("failed to upload artifact")
} }
log.Printf("Артефакт %s загружен в репозиторий Gitea", artifactPath) log.Printf("Артефакт %s-%s-%s.%s загружен в репозиторий Gitea", groupId, artifactId, version, packaging)
return nil return nil
} }

View file

@ -1,104 +1,117 @@
package nexus package nexus
import ( import (
"fmt" "encoding/json"
"io/ioutil" "fmt"
"log" "io/ioutil"
"net/http" "log"
"strings" "net/http"
) )
type Client struct { type Client struct {
BaseURL string BaseURL string
HTTPClient *http.Client HTTPClient *http.Client
Username string Username string
Password string Password string
} }
func NewClient(baseURL, username, password string) *Client { func NewClient(baseURL, username, password string) *Client {
return &Client{ return &Client{
BaseURL: baseURL, BaseURL: baseURL,
HTTPClient: &http.Client{}, HTTPClient: &http.Client{},
Username: username, Username: username,
Password: password, Password: password,
} }
} }
func (c *Client) GetArtifacts(repository string) ([]string, error) { func (c *Client) GetArtifacts(repository string) ([]string, error) {
log.Printf("Получение артефактов из репозитория Nexus") url := fmt.Sprintf("%s/service/rest/v1/search/assets?sort=repository&repository=%s", c.BaseURL, repository)
url := fmt.Sprintf("%s/repository/%s/", c.BaseURL, repository) req, err := http.NewRequest("GET", url, nil)
req, err := http.NewRequest("GET", url, nil) if err != nil {
if err != nil { return nil, err
return nil, err }
} req.SetBasicAuth(c.Username, c.Password)
req.SetBasicAuth(c.Username, c.Password)
resp, err := c.HTTPClient.Do(req) log.Printf("Запрос на получение артефактов: %s", req.URL)
if err != nil { log.Printf("Заголовки запроса: %v", req.Header)
return nil, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body) resp, err := c.HTTPClient.Do(req)
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer resp.Body.Close()
log.Printf("Артефакты получены из репозитория Nexus") log.Printf("Код ответа: %d", resp.StatusCode)
artifacts := strings.Split(string(body), "\n") log.Printf("Заголовки ответа: %v", resp.Header)
var result []string
for _, artifact := range artifacts { body, err := ioutil.ReadAll(resp.Body)
if strings.Contains(artifact, ".jar") || strings.Contains(artifact, ".pom") { if err != nil {
result = append(result, artifact) return nil, err
} }
}
return result, nil log.Printf("Тело ответа: %s", string(body))
var assets struct {
Items []struct {
DownloadUrl string `json:"downloadUrl"`
} `json:"items"`
}
err = json.Unmarshal(body, &assets)
if err != nil {
return nil, err
}
var result []string
for _, asset := range assets.Items {
result = append(result, asset.DownloadUrl)
}
return result, nil
} }
func (c *Client) GetArtifactData(repository, artifact string) ([]byte, error) { func (c *Client) GetArtifactData(repository, artifact string) ([]byte, error) {
log.Printf("Загрузка артефакта %s из репозитория Nexus", artifact) log.Printf("Загрузка артефакта %s из репозитория Nexus", artifact)
url := fmt.Sprintf("%s/repository/%s/%s", c.BaseURL, repository, artifact) url := fmt.Sprintf("%s/repository/%s/%s", c.BaseURL, repository, artifact)
req, err := http.NewRequest("GET", url, nil) req, err := http.NewRequest("GET", url, nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
req.SetBasicAuth(c.Username, c.Password) req.SetBasicAuth(c.Username, c.Password)
resp, err := c.HTTPClient.Do(req) resp, err := c.HTTPClient.Do(req)
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer resp.Body.Close() defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body) body, err := ioutil.ReadAll(resp.Body)
if err != nil { if err != nil {
return nil, err return nil, err
} }
log.Printf("Артефакт %s загружен из репозитория Nexus", artifact) log.Printf("Артефакт %s загружен из репозитория Nexus", artifact)
return body, nil return body, nil
} }
func (c *Client) ArtifactExists(artifact string) (bool, error) { func (c *Client) ArtifactExists(artifact string) (bool, error) {
log.Printf("Проверка наличия артефакта %s в репозитории Nexus", artifact) log.Printf("Проверка наличия артефакта %s в репозитории Nexus", artifact)
url := fmt.Sprintf("%s/repository/%s/%s", c.BaseURL, "your-repository-name", artifact) url := fmt.Sprintf("%s/repository/%s/%s", c.BaseURL, "your-repository-name", artifact)
req, err := http.NewRequest("GET", url, nil) req, err := http.NewRequest("GET", url, nil)
if err != nil { if err != nil {
return false, err return false, err
} }
req.SetBasicAuth(c.Username, c.Password) req.SetBasicAuth(c.Username, c.Password)
resp, err := c.HTTPClient.Do(req) resp, err := c.HTTPClient.Do(req)
if err != nil { if err != nil {
return false, err return false, err
} }
defer resp.Body.Close() defer resp.Body.Close()
if resp.StatusCode == http.StatusNotFound { if resp.StatusCode == http.StatusNotFound {
log.Printf("Артефакт %s не существует в репозитории Nexus", artifact) log.Printf("Артефакт %s не существует в репозитории Nexus", artifact)
return false, nil return false, nil
} }
log.Printf("Артефакт %s существует в репозитории Nexus", artifact) log.Printf("Артефакт %s существует в репозитории Nexus", artifact)
return true, nil return true, nil
} }