This commit is contained in:
wheelchairy 2025-02-04 18:30:33 +03:00
parent 0fe28fc047
commit b6ea0e0f59
18 changed files with 245 additions and 49 deletions

View File

@ -3,7 +3,6 @@ package cmd
import ( import (
"fmt" "fmt"
"train/pkg/installer" "train/pkg/installer"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )

View File

@ -4,7 +4,6 @@ import (
"fmt" "fmt"
"os" "os"
"train/pkg/installer" "train/pkg/installer"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )

View File

@ -3,7 +3,6 @@ package cmd
import ( import (
"fmt" "fmt"
"train/pkg/installer" "train/pkg/installer"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )

View File

@ -4,7 +4,6 @@ import (
"fmt" "fmt"
"os" "os"
"train/pkg/installer" "train/pkg/installer"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )

View File

@ -4,7 +4,6 @@ import (
"fmt" "fmt"
"os" "os"
"train/pkg/config" "train/pkg/config"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )

View File

@ -1,9 +1,8 @@
package cmd package cmd
import ( import (
"fmt"
"os" "os"
"fmt"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )

View File

@ -4,7 +4,6 @@ import (
"fmt" "fmt"
"os" "os"
"train/pkg/installer" "train/pkg/installer"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )

View File

@ -1,6 +1,5 @@
{ {
"repositories": [ "repositories": [
"http://xn--80abmlgju2eo3byb.xn--p1ai/sklad/" "https://xn--80abmlgju2eo3byb.xn--p1ai/sklad"
], ]
}
} }

2
go.mod
View File

@ -2,7 +2,7 @@ module train
go 1.18 go 1.18
require github.com/spf13/cobra v1.7.0 // или актуальная версия require github.com/spf13/cobra v1.7.0
require ( require (
github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect

View File

@ -0,0 +1,58 @@
package autoupdate
import (
"fmt"
"io/ioutil"
"net/http"
"os"
"os/exec"
)
func CheckForUpdates(updateURL string) (bool, string, error) {
resp, err := http.Get(updateURL)
if err != nil {
return false, "", err
}
defer resp.Body.Close()
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return false, "", err
}
latestVersion := string(data)
currentVersion := "1.0.0"
if latestVersion != currentVersion {
return true, latestVersion, nil
}
return false, currentVersion, nil
}
func AutoUpdate(updateURL string) error {
available, latest, err := CheckForUpdates(updateURL)
if err != nil {
return err
}
if available {
fmt.Printf("Доступна новая версия: %s. Запускаем обновление...\n", latest)
resp, err := http.Get(updateURL + "/binary") // предположим, что по этому URL лежит бинарник
if err != nil {
return err
}
defer resp.Body.Close()
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
tmpFile := "/tmp/train_new"
if err := ioutil.WriteFile(tmpFile, data, 0755); err != nil {
return err
}
cmd := exec.Command(tmpFile)
if err := cmd.Start(); err != nil {
return err
}
os.Exit(0)
} else {
fmt.Println("Обновлений не найдено.")
}
return nil
}

50
pkg/cache/cache.go vendored Normal file
View File

@ -0,0 +1,50 @@
package cache
import (
"fmt"
"io/ioutil"
"net/http"
"os"
"path/filepath"
)
var cacheDir = "./cache"
func GetCachedFile(url string) (string, error) {
if err := os.MkdirAll(cacheDir, os.ModePerm); err != nil {
return "", err
}
fileName := filepath.Join(cacheDir, filepath.Base(url))
if _, err := os.Stat(fileName); err == nil {
return fileName, nil
}
return "", nil
}
func SaveToCache(url string, data []byte) (string, error) {
if err := os.MkdirAll(cacheDir, os.ModePerm); err != nil {
return "", err
}
fileName := filepath.Join(cacheDir, filepath.Base(url))
if err := ioutil.WriteFile(fileName, data, 0644); err != nil {
return "", err
}
fmt.Printf("Сохранено в кэш: %s\n", fileName)
return fileName, nil
}
func DownloadWithCache(url string) (string, error) {
if cached, err := GetCachedFile(url); err == nil && cached != "" {
return cached, nil
}
resp, err := http.Get(url)
if err != nil {
return "", err
}
defer resp.Body.Close()
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", err
}
return SaveToCache(url, data)
}

View File

@ -8,20 +8,23 @@ import (
) )
type Config struct { type Config struct {
Repositories []string `json:"repositories"` Repositories []string `json:"repositories"`
Packages map[string]string `json:"packages"`
} }
var configFile = "./config.json" var configFile = "./config.json"
func LoadConfig() (*Config, error) { func LoadConfig() (*Config, error) {
if _, err := os.Stat(configFile); os.IsNotExist(err) { if _, err := os.Stat(configFile); os.IsNotExist(err) {
cfg := &Config{Repositories: []string{}} cfg := &Config{
Repositories: []string{},
Packages: make(map[string]string),
}
if err := SaveConfig(cfg); err != nil { if err := SaveConfig(cfg); err != nil {
return nil, err return nil, err
} }
return cfg, nil return cfg, nil
} }
data, err := ioutil.ReadFile(configFile) data, err := ioutil.ReadFile(configFile)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -0,0 +1,16 @@
package dependencies
import (
"fmt"
"train/pkg/installer"
)
func InstallDependencies(deps []string) error {
for _, dep := range deps {
fmt.Printf("Устанавливаем зависимость: %s\n", dep)
if err := installer.InstallPackage(dep); err != nil {
return fmt.Errorf("не удалось установить зависимость %s: %v", dep, err)
}
}
return nil
}

View File

@ -18,7 +18,6 @@ type Manifest struct {
Dependencies []string `json:"dependencies"` Dependencies []string `json:"dependencies"`
Build []string `json:"build"` Build []string `json:"build"`
Binaries map[string]string `json:"binaries"` Binaries map[string]string `json:"binaries"`
runtime.GOOS+"_"+runtime.GOARCH
} }
func FetchManifest(name string) (*Manifest, error) { func FetchManifest(name string) (*Manifest, error) {
@ -26,33 +25,40 @@ func FetchManifest(name string) (*Manifest, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
if url, ok := cfg.Packages[name]; ok {
return fetchManifestFromURL(url)
}
var lastErr error var lastErr error
for _, repo := range cfg.Repositories { for _, repo := range cfg.Repositories {
url := fmt.Sprintf("%s/%s/manifest.json", repo, name) url := fmt.Sprintf("%s/%s/manifest.json", repo, name)
resp, err := http.Get(url) m, err := fetchManifestFromURL(url)
if err != nil { if err == nil {
lastErr = err return m, nil
continue
} }
defer resp.Body.Close() lastErr = err
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 { if lastErr == nil {
lastErr = errors.New("не найден ни один репозиторий") lastErr = errors.New("не найден ни один репозиторий")
} }
return nil, lastErr return nil, lastErr
} }
func fetchManifestFromURL(url string) (*Manifest, error) {
resp, err := http.Get(url)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
return nil, errors.New("манифест пакета не найден по ссылке " + url)
}
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
var m Manifest
if err := json.Unmarshal(data, &m); err != nil {
return nil, err
}
return &m, nil
}

15
pkg/plugin/plugin.go Normal file
View File

@ -0,0 +1,15 @@
package plugin
import (
"fmt"
"plugin"
)
func LoadPlugin(path string) (*plugin.Plugin, error) {
p, err := plugin.Open(path)
if err != nil {
return nil, err
}
fmt.Printf("Плагин загружен: %s\n", path)
return p, nil
}

BIN
pkg/security/.DS_Store vendored Normal file

Binary file not shown.

14
pkg/security/security.go Normal file
View File

@ -0,0 +1,14 @@
package security
import (
"os/exec"
"fmt"
)
func VerifySignature(filePath, sigPath string) error {
out, err := exec.Command("gpg", "--verify", sigPath, filePath).CombinedOutput()
if err != nil {
return fmt.Errorf("gpg verification failed: %s", string(out))
}
return nil
}

42
pkg/version/version.go Normal file
View File

@ -0,0 +1,42 @@
package version
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"path/filepath"
)
type VersionInfo struct {
Package string `json:"package"`
Version string `json:"version"`
}
var versionDir = "./versions"
func SaveVersionInfo(pkgName, ver string) error {
if err := os.MkdirAll(versionDir, os.ModePerm); err != nil {
return err
}
info := VersionInfo{Package: pkgName, Version: ver}
data, err := json.MarshalIndent(info, "", " ")
if err != nil {
return err
}
filePath := filepath.Join(versionDir, pkgName+".json")
return ioutil.WriteFile(filePath, data, 0644)
}
func GetVersionInfo(pkgName string) (*VersionInfo, error) {
filePath := filepath.Join(versionDir, pkgName+".json")
data, err := ioutil.ReadFile(filePath)
if err != nil {
return nil, err
}
var info VersionInfo
if err := json.Unmarshal(data, &info); err != nil {
return nil, err
}
return &info, nil
}