init
This commit is contained in:
commit
0fe28fc047
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
installed*
|
||||||
|
repo
|
||||||
|
train
|
23
cmd/info.go
Normal file
23
cmd/info.go
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"train/pkg/installer"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
var infoCmd = &cobra.Command{
|
||||||
|
Use: "info [package]",
|
||||||
|
Short: "Выводит информацию о пакете",
|
||||||
|
Args: cobra.ExactArgs(1),
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
pkgName := args[0]
|
||||||
|
info, err := installer.GetPackageInfo(pkgName)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Ошибка получения информации: %v\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Printf("Информация о пакете %s:\n%s\n", pkgName, info)
|
||||||
|
},
|
||||||
|
}
|
24
cmd/install.go
Normal file
24
cmd/install.go
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"train/pkg/installer"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
var installCmd = &cobra.Command{
|
||||||
|
Use: "install [package]",
|
||||||
|
Short: "Устанавливает указанный пакет",
|
||||||
|
Args: cobra.MinimumNArgs(1),
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
pkgName := args[0]
|
||||||
|
fmt.Printf("Установка пакета: %s\n", pkgName)
|
||||||
|
if err := installer.InstallPackage(pkgName); err != nil {
|
||||||
|
fmt.Printf("Ошибка установки: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
fmt.Printf("Пакет %s успешно установлен.\n", pkgName)
|
||||||
|
},
|
||||||
|
}
|
24
cmd/list.go
Normal file
24
cmd/list.go
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"train/pkg/installer"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
var listCmd = &cobra.Command{
|
||||||
|
Use: "list",
|
||||||
|
Short: "Список установленных пакетов",
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
pkgs, err := installer.ListInstalledPackages()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Ошибка получения списка: %v\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println("Установленные пакеты:")
|
||||||
|
for _, p := range pkgs {
|
||||||
|
fmt.Println(" -", p)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
24
cmd/remove.go
Normal file
24
cmd/remove.go
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"train/pkg/installer"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
var removeCmd = &cobra.Command{
|
||||||
|
Use: "remove [package]",
|
||||||
|
Short: "Удаляет указанный пакет",
|
||||||
|
Args: cobra.MinimumNArgs(1),
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
pkgName := args[0]
|
||||||
|
fmt.Printf("Удаление пакета: %s\n", pkgName)
|
||||||
|
if err := installer.RemovePackage(pkgName); err != nil {
|
||||||
|
fmt.Printf("Ошибка удаления: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
fmt.Printf("Пакет %s успешно удалён.\n", pkgName)
|
||||||
|
},
|
||||||
|
}
|
64
cmd/repo.go
Normal file
64
cmd/repo.go
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"train/pkg/config"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
var repoCmd = &cobra.Command{
|
||||||
|
Use: "repo",
|
||||||
|
Short: "Управление репозиториями пакетов",
|
||||||
|
}
|
||||||
|
|
||||||
|
var repoAddCmd = &cobra.Command{
|
||||||
|
Use: "add [url]",
|
||||||
|
Short: "Добавляет новый репозиторий",
|
||||||
|
Args: cobra.ExactArgs(1),
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
url := args[0]
|
||||||
|
if err := config.AddRepository(url); err != nil {
|
||||||
|
fmt.Printf("Ошибка: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
fmt.Printf("Репозиторий %s успешно добавлен.\n", url)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var repoRemoveCmd = &cobra.Command{
|
||||||
|
Use: "remove [url]",
|
||||||
|
Short: "Удаляет репозиторий",
|
||||||
|
Args: cobra.ExactArgs(1),
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
url := args[0]
|
||||||
|
if err := config.RemoveRepository(url); err != nil {
|
||||||
|
fmt.Printf("Ошибка: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
fmt.Printf("Репозиторий %s успешно удалён.\n", url)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var repoListCmd = &cobra.Command{
|
||||||
|
Use: "list",
|
||||||
|
Short: "Список добавленных репозиториев",
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
cfg, err := config.LoadConfig()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Ошибка загрузки конфигурации: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
fmt.Println("Добавленные репозитории:")
|
||||||
|
for _, r := range cfg.Repositories {
|
||||||
|
fmt.Println(" -", r)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
repoCmd.AddCommand(repoAddCmd)
|
||||||
|
repoCmd.AddCommand(repoRemoveCmd)
|
||||||
|
repoCmd.AddCommand(repoListCmd)
|
||||||
|
}
|
29
cmd/root.go
Normal file
29
cmd/root.go
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
var rootCmd = &cobra.Command{
|
||||||
|
Use: "train",
|
||||||
|
Short: "Train - легковесный пакетный менеджер",
|
||||||
|
}
|
||||||
|
|
||||||
|
func Execute() {
|
||||||
|
if err := rootCmd.Execute(); err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
rootCmd.AddCommand(installCmd)
|
||||||
|
rootCmd.AddCommand(removeCmd)
|
||||||
|
rootCmd.AddCommand(updateCmd)
|
||||||
|
rootCmd.AddCommand(listCmd)
|
||||||
|
rootCmd.AddCommand(infoCmd)
|
||||||
|
rootCmd.AddCommand(repoCmd)
|
||||||
|
}
|
24
cmd/update.go
Normal file
24
cmd/update.go
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"train/pkg/installer"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
var updateCmd = &cobra.Command{
|
||||||
|
Use: "update [package]",
|
||||||
|
Short: "Обновляет указанный пакет (удаление + установка)",
|
||||||
|
Args: cobra.ExactArgs(1),
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
pkgName := args[0]
|
||||||
|
fmt.Printf("Обновление пакета: %s\n", pkgName)
|
||||||
|
if err := installer.UpdatePackage(pkgName); err != nil {
|
||||||
|
fmt.Printf("Ошибка обновления: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
fmt.Printf("Пакет %s успешно обновлён.\n", pkgName)
|
||||||
|
},
|
||||||
|
}
|
6
config.json
Normal file
6
config.json
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"repositories": [
|
||||||
|
"http://xn--80abmlgju2eo3byb.xn--p1ai/sklad/"
|
||||||
|
],
|
||||||
|
}
|
||||||
|
}
|
10
go.mod
Normal file
10
go.mod
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
module train
|
||||||
|
|
||||||
|
go 1.18
|
||||||
|
|
||||||
|
require github.com/spf13/cobra v1.7.0 // или актуальная версия
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||||
|
github.com/spf13/pflag v1.0.5 // indirect
|
||||||
|
)
|
10
go.sum
Normal file
10
go.sum
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||||
|
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||||
|
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||||
|
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
|
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
|
||||||
|
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
|
||||||
|
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||||
|
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
9
main.go
Normal file
9
main.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"train/cmd"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
cmd.Execute()
|
||||||
|
}
|
77
pkg/config/config.go
Normal file
77
pkg/config/config.go
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
Repositories []string `json:"repositories"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var configFile = "./config.json"
|
||||||
|
|
||||||
|
func LoadConfig() (*Config, error) {
|
||||||
|
if _, err := os.Stat(configFile); os.IsNotExist(err) {
|
||||||
|
cfg := &Config{Repositories: []string{}}
|
||||||
|
if err := SaveConfig(cfg); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return cfg, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := ioutil.ReadFile(configFile)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var cfg Config
|
||||||
|
if err := json.Unmarshal(data, &cfg); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &cfg, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func SaveConfig(cfg *Config) error {
|
||||||
|
data, err := json.MarshalIndent(cfg, "", " ")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return ioutil.WriteFile(configFile, data, 0644)
|
||||||
|
}
|
||||||
|
|
||||||
|
func AddRepository(repo string) error {
|
||||||
|
cfg, err := LoadConfig()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, r := range cfg.Repositories {
|
||||||
|
if r == repo {
|
||||||
|
return errors.New("репозиторий уже добавлен")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cfg.Repositories = append(cfg.Repositories, repo)
|
||||||
|
return SaveConfig(cfg)
|
||||||
|
}
|
||||||
|
|
||||||
|
func RemoveRepository(repo string) error {
|
||||||
|
cfg, err := LoadConfig()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
newRepos := []string{}
|
||||||
|
found := false
|
||||||
|
for _, r := range cfg.Repositories {
|
||||||
|
if r == repo {
|
||||||
|
found = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
newRepos = append(newRepos, r)
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
return errors.New("репозиторий не найден")
|
||||||
|
}
|
||||||
|
cfg.Repositories = newRepos
|
||||||
|
return SaveConfig(cfg)
|
||||||
|
}
|
254
pkg/installer/installer.go
Normal file
254
pkg/installer/installer.go
Normal file
@ -0,0 +1,254 @@
|
|||||||
|
package installer
|
||||||
|
|
||||||
|
import (
|
||||||
|
"archive/tar"
|
||||||
|
"compress/gzip"
|
||||||
|
"crypto/sha256"
|
||||||
|
"encoding/hex"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"train/pkg/manifest"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
binInstallDir = "./installed_bins" // for binary
|
||||||
|
buildInstallDir = "./installed_packages" // for build"
|
||||||
|
installDir = buildInstallDir // for func
|
||||||
|
)
|
||||||
|
|
||||||
|
func computeChecksum(filePath string) (string, error) {
|
||||||
|
data, err := ioutil.ReadFile(filePath)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
hash := sha256.Sum256(data)
|
||||||
|
return hex.EncodeToString(hash[:]), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func downloadFile(url string) (string, error) {
|
||||||
|
resp, err := http.Get(url)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
tmpFile, err := ioutil.TempFile("", "package_")
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
_, err = io.Copy(tmpFile, resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
tmpFile.Close()
|
||||||
|
return tmpFile.Name(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func unpackPackage(filePath, packageName string) error {
|
||||||
|
destDir := filepath.Join(buildInstallDir, packageName)
|
||||||
|
if err := os.MkdirAll(destDir, os.ModePerm); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
f, err := os.Open(filePath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
gzr, err := gzip.NewReader(f)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer gzr.Close()
|
||||||
|
|
||||||
|
tr := tar.NewReader(gzr)
|
||||||
|
|
||||||
|
for {
|
||||||
|
header, err := tr.Next()
|
||||||
|
if err == io.EOF {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
target := filepath.Join(destDir, header.Name)
|
||||||
|
|
||||||
|
switch header.Typeflag {
|
||||||
|
case tar.TypeDir:
|
||||||
|
if err := os.MkdirAll(target, os.FileMode(header.Mode)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
case tar.TypeReg:
|
||||||
|
outFile, err := os.Create(target)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err := io.Copy(outFile, tr); err != nil {
|
||||||
|
outFile.Close()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
outFile.Close()
|
||||||
|
default:
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func executeBuildCommands(commands []string, packageName string) error {
|
||||||
|
packagePath := filepath.Join(buildInstallDir, packageName)
|
||||||
|
for _, commandStr := range commands {
|
||||||
|
cmd := exec.Command("sh", "-c", commandStr)
|
||||||
|
cmd.Dir = packagePath
|
||||||
|
output, err := cmd.CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("команда '%s' завершилась с ошибкой: %s", commandStr, string(output))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func saveInstalledPackage(name string, m *manifest.Manifest) error {
|
||||||
|
packagePath := filepath.Join(buildInstallDir, name)
|
||||||
|
if err := os.MkdirAll(packagePath, os.ModePerm); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
jsonData, err := json.MarshalIndent(m, "", " ")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return ioutil.WriteFile(filepath.Join(packagePath, "manifest.json"), jsonData, 0644)
|
||||||
|
}
|
||||||
|
|
||||||
|
func removeInstalledPackageRecord(name string) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func InstallPackage(name string) error {
|
||||||
|
m, err := manifest.FetchManifest(name)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("не удалось получить манифест: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.ToLower(m.Mode) == "bin" {
|
||||||
|
platformKey := runtime.GOOS + "_" + runtime.GOARCH
|
||||||
|
binaryURL, ok := m.Binaries[platformKey]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("нет бинарного файла для платформы %s", platformKey)
|
||||||
|
}
|
||||||
|
packageFile, err := downloadFile(binaryURL)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("не удалось скачать бинарник: %w", err)
|
||||||
|
}
|
||||||
|
defer os.Remove(packageFile)
|
||||||
|
|
||||||
|
checksum, err := computeChecksum(packageFile)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("не удалось вычислить контрольную сумму: %w", err)
|
||||||
|
}
|
||||||
|
if checksum != m.Checksum {
|
||||||
|
return fmt.Errorf("контрольная сумма не совпадает, ожидалось %s, получено %s", m.Checksum, checksum)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := os.MkdirAll(binInstallDir, os.ModePerm); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
destPath := filepath.Join(binInstallDir, m.Name)
|
||||||
|
data, err := ioutil.ReadFile(packageFile)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := ioutil.WriteFile(destPath, data, 0755); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Printf("Бинарный пакет %s установлен в %s\n", m.Name, destPath)
|
||||||
|
return nil
|
||||||
|
} else if strings.ToLower(m.Mode) == "build" {
|
||||||
|
packageFile, err := downloadFile(m.Source)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("не удалось скачать пакет: %w", err)
|
||||||
|
}
|
||||||
|
defer os.Remove(packageFile)
|
||||||
|
|
||||||
|
checksum, err := computeChecksum(packageFile)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("не удалось вычислить контрольную сумму: %w", err)
|
||||||
|
}
|
||||||
|
if checksum != m.Checksum {
|
||||||
|
return fmt.Errorf("контрольная сумма не совпадает, ожидалось %s, получено %s", m.Checksum, checksum)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := unpackPackage(packageFile, name); err != nil {
|
||||||
|
return fmt.Errorf("не удалось распаковать пакет: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(m.Build) > 0 {
|
||||||
|
if err := executeBuildCommands(m.Build, name); err != nil {
|
||||||
|
return fmt.Errorf("ошибка выполнения команд сборки: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := saveInstalledPackage(name, m); err != nil {
|
||||||
|
return fmt.Errorf("не удалось сохранить информацию об установленном пакете: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors.New("неизвестный режим пакета")
|
||||||
|
}
|
||||||
|
|
||||||
|
func RemovePackage(name string) error {
|
||||||
|
packagePath := filepath.Join(buildInstallDir, name)
|
||||||
|
if _, err := os.Stat(packagePath); os.IsNotExist(err) {
|
||||||
|
return errors.New("пакет не найден")
|
||||||
|
}
|
||||||
|
if err := os.RemoveAll(packagePath); err != nil {
|
||||||
|
return fmt.Errorf("не удалось удалить пакет: %w", err)
|
||||||
|
}
|
||||||
|
removeInstalledPackageRecord(name)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func UpdatePackage(name string) error {
|
||||||
|
if err := RemovePackage(name); err != nil {
|
||||||
|
return fmt.Errorf("не удалось удалить пакет для обновления: %w", err)
|
||||||
|
}
|
||||||
|
if err := InstallPackage(name); err != nil {
|
||||||
|
return fmt.Errorf("не удалось установить пакет: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ListInstalledPackages() ([]string, error) {
|
||||||
|
var pkgs []string
|
||||||
|
entries, err := ioutil.ReadDir(buildInstallDir)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, entry := range entries {
|
||||||
|
if entry.IsDir() {
|
||||||
|
pkgs = append(pkgs, entry.Name())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pkgs, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetPackageInfo(name string) (string, error) {
|
||||||
|
infoFile := filepath.Join(buildInstallDir, name, "manifest.json")
|
||||||
|
data, err := ioutil.ReadFile(infoFile)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return string(data), nil
|
||||||
|
}
|
58
pkg/manifest/manifest.go
Normal file
58
pkg/manifest/manifest.go
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
package manifest
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"train/pkg/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Manifest struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Version string `json:"version"`
|
||||||
|
Mode string `json:"mode"`
|
||||||
|
Source string `json:"source"`
|
||||||
|
Checksum string `json:"checksum"`
|
||||||
|
Dependencies []string `json:"dependencies"`
|
||||||
|
Build []string `json:"build"`
|
||||||
|
Binaries map[string]string `json:"binaries"`
|
||||||
|
runtime.GOOS+"_"+runtime.GOARCH
|
||||||
|
}
|
||||||
|
|
||||||
|
func FetchManifest(name string) (*Manifest, error) {
|
||||||
|
cfg, err := config.LoadConfig()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var lastErr error
|
||||||
|
for _, repo := range cfg.Repositories {
|
||||||
|
url := fmt.Sprintf("%s/%s/manifest.json", repo, name)
|
||||||
|
resp, err := http.Get(url)
|
||||||
|
if err != nil {
|
||||||
|
lastErr = err
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
if resp.StatusCode != 200 {
|
||||||
|
lastErr = errors.New("пакет не найден в репозитории " + repo)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
data, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
lastErr = err
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
var m Manifest
|
||||||
|
if err := json.Unmarshal(data, &m); err != nil {
|
||||||
|
lastErr = err
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return &m, nil
|
||||||
|
}
|
||||||
|
if lastErr == nil {
|
||||||
|
lastErr = errors.New("не найден ни один репозиторий")
|
||||||
|
}
|
||||||
|
return nil, lastErr
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user