Добавление первой итерации генерации плагина .star

This commit is contained in:
2025-09-11 17:43:21 +03:00
parent 990e091e8b
commit 5b2b370a39
8 changed files with 1017 additions and 16 deletions

BIN
cmd/analyze-repo/analyze-repo Executable file

Binary file not shown.

232
cmd/analyze-repo/main.go Normal file
View File

@@ -0,0 +1,232 @@
package main
import (
"encoding/json"
"fmt"
"os"
"path/filepath"
"regexp"
"strings"
"github.com/pelletier/go-toml/v2"
"github.com/spf13/pflag"
"gitea.plemya-x.ru/Plemya-x/ALR-updater/internal/config"
"gitea.plemya-x.ru/Plemya-x/ALR-updater/internal/generator"
)
type AnalysisResult struct {
PackageName string `json:"package_name"`
Version string `json:"version"`
GitHubRepo string `json:"github_repo,omitempty"`
Sources []string `json:"sources,omitempty"`
Description string `json:"description,omitempty"`
Homepage string `json:"homepage,omitempty"`
PackageType string `json:"package_type"`
HasPlugin bool `json:"has_plugin"`
PluginGenerated bool `json:"can_generate_plugin"`
}
func main() {
configPath := pflag.StringP("config", "c", "/etc/alr-updater/config.toml", "Path to config file")
pluginDir := pflag.StringP("plugin-dir", "p", "/etc/alr-updater/plugins", "Path to plugin directory")
repoName := pflag.StringP("repo", "r", "alr-repo", "Repository name to analyze")
outputFormat := pflag.StringP("format", "f", "table", "Output format: table, json")
generateMissing := pflag.BoolP("generate", "g", false, "Generate missing plugins")
pflag.Parse()
// Загружаем конфигурацию
cfg := &config.Config{}
fl, err := os.Open(*configPath)
if err != nil {
fmt.Printf("Error opening config file: %v\n", err)
os.Exit(1)
}
defer fl.Close()
err = toml.NewDecoder(fl).Decode(cfg)
if err != nil {
fmt.Printf("Error decoding config file: %v\n", err)
os.Exit(1)
}
// Создаем генератор плагинов
gen, err := generator.NewPluginGenerator(cfg, *pluginDir)
if err != nil {
fmt.Printf("Error creating plugin generator: %v\n", err)
os.Exit(1)
}
// Сканируем репозиторий
packages, err := gen.ScanRepository(*repoName)
if err != nil {
fmt.Printf("Error scanning repository: %v\n", err)
os.Exit(1)
}
// Получаем список существующих плагинов
existingPlugins := make(map[string]bool)
pluginFiles, err := filepath.Glob(filepath.Join(*pluginDir, "*.star"))
if err == nil {
for _, pluginFile := range pluginFiles {
pluginName := strings.TrimSuffix(filepath.Base(pluginFile), ".star")
existingPlugins[pluginName] = true
}
}
// Подготавливаем результаты анализа
var results []AnalysisResult
var canGenerate []generator.DetectedPackage
for _, pkg := range packages {
result := AnalysisResult{
PackageName: pkg.Name,
Version: pkg.Version,
GitHubRepo: pkg.GitHubRepo,
Sources: pkg.Sources,
Description: pkg.Description,
Homepage: pkg.Homepage,
PackageType: pkg.PackageType,
HasPlugin: existingPlugins[pkg.Name],
PluginGenerated: pkg.GitHubRepo != "" && pkg.PackageType == "github_release",
}
results = append(results, result)
if !result.HasPlugin && result.PluginGenerated {
canGenerate = append(canGenerate, pkg)
}
}
// Добавляем пакеты с существующими плагинами
repoPath := filepath.Join(cfg.ReposBaseDir, *repoName)
err = filepath.Walk(repoPath, func(path string, info os.FileInfo, err error) error {
if err != nil || info.Name() != "alr.sh" {
return err
}
packageName := filepath.Base(filepath.Dir(path))
if existingPlugins[packageName] {
// Проверяем, есть ли уже в результатах
found := false
for _, r := range results {
if r.PackageName == packageName {
found = true
break
}
}
if !found {
// Добавляем пакет с существующим плагином
pkgInfo := analyzePackageFile(path)
result := AnalysisResult{
PackageName: packageName,
Version: pkgInfo.Version,
Sources: pkgInfo.Sources,
Description: pkgInfo.Description,
Homepage: pkgInfo.Homepage,
PackageType: "has_plugin",
HasPlugin: true,
}
results = append(results, result)
}
}
return nil
})
// Выводим результаты
if *outputFormat == "json" {
output, _ := json.MarshalIndent(results, "", " ")
fmt.Println(string(output))
} else {
printTable(results, canGenerate)
}
// Генерируем недостающие плагины
if *generateMissing {
fmt.Printf("\n🚀 Generating %d missing plugins...\n", len(canGenerate))
for _, pkg := range canGenerate {
err := gen.GeneratePlugin(pkg, *repoName)
if err != nil {
fmt.Printf("❌ Error generating plugin for %s: %v\n", pkg.Name, err)
}
}
fmt.Printf("✅ Plugin generation completed!\n")
}
}
func analyzePackageFile(alrFile string) generator.PackageInfo {
content, err := os.ReadFile(alrFile)
if err != nil {
return generator.PackageInfo{Name: filepath.Base(filepath.Dir(alrFile))}
}
info := generator.PackageInfo{
Name: filepath.Base(filepath.Dir(alrFile)),
}
lines := strings.Split(string(content), "\n")
for _, line := range lines {
line = strings.TrimSpace(line)
if strings.HasPrefix(line, "version=") {
versionMatch := regexp.MustCompile(`version=['"]?([^'"]+)['"]?`).FindStringSubmatch(line)
if len(versionMatch) > 1 {
info.Version = versionMatch[1]
}
}
if strings.Contains(line, "github.com") || strings.Contains(line, "https://") {
urlMatch := regexp.MustCompile(`https://[^\s"']+`).FindAllString(line, -1)
info.Sources = append(info.Sources, urlMatch...)
}
if strings.HasPrefix(line, "desc=") {
descMatch := regexp.MustCompile(`desc=['"]?([^'"]+)['"]?`).FindStringSubmatch(line)
if len(descMatch) > 1 {
info.Description = descMatch[1]
}
}
}
return info
}
func printTable(results []AnalysisResult, canGenerate []generator.DetectedPackage) {
fmt.Printf("📊 Анализ репозитория\n")
fmt.Printf("═══════════════════════════════════════════════════════════════════════════════════\n")
withPlugins := 0
withoutPlugins := 0
canGenerateCount := len(canGenerate)
for _, r := range results {
if r.HasPlugin {
withPlugins++
} else {
withoutPlugins++
}
}
fmt.Printf("📦 Всего пакетов: %d\n", len(results))
fmt.Printf("✅ С плагинами: %d\n", withPlugins)
fmt.Printf("❌ Без плагинов: %d\n", withoutPlugins)
fmt.Printf("🤖 Можно сгенерировать: %d\n", canGenerateCount)
if canGenerateCount > 0 {
fmt.Printf("\n🎯 Пакеты для автогенерации:\n")
fmt.Printf("─────────────────────────────────────────────────────────────────────────────────\n")
for _, pkg := range canGenerate {
fmt.Printf("📦 %-25s │ %s\n", pkg.Name, pkg.GitHubRepo)
}
fmt.Printf("\n💡 Запустите с флагом --generate для создания плагинов\n")
}
if withoutPlugins > canGenerateCount {
fmt.Printf("\n⚠ Пакеты требующие ручной настройки:\n")
fmt.Printf("─────────────────────────────────────────────────────────────────────────────────\n")
for _, r := range results {
if !r.HasPlugin && !r.PluginGenerated {
fmt.Printf("📦 %-25s │ %s\n", r.PackageName, r.PackageType)
}
}
}
}