Добавление первой итерации генерации плагина .star
This commit is contained in:
BIN
cmd/analyze-repo/analyze-repo
Executable file
BIN
cmd/analyze-repo/analyze-repo
Executable file
Binary file not shown.
232
cmd/analyze-repo/main.go
Normal file
232
cmd/analyze-repo/main.go
Normal 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user