первичная итерация генератора из aur пакетов
	
		
			
	
		
	
	
		
	
		
			Some checks failed
		
		
	
	
		
			
				
	
				Update alr-git / changelog (push) Failing after 25s
				
			
		
		
	
	
				
					
				
			
		
			Some checks failed
		
		
	
	Update alr-git / changelog (push) Failing after 25s
				
			This commit is contained in:
		
							
								
								
									
										23
									
								
								gen.go
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								gen.go
									
									
									
									
									
								
							| @@ -61,6 +61,29 @@ func GenCmd() *cli.Command { | |||||||
| 					}) | 					}) | ||||||
| 				}, | 				}, | ||||||
| 			}, | 			}, | ||||||
|  | 			{ | ||||||
|  | 				Name:  "aur", | ||||||
|  | 				Usage: gotext.Get("Generate a ALR script for an AUR package"), | ||||||
|  | 				Flags: []cli.Flag{ | ||||||
|  | 					&cli.StringFlag{ | ||||||
|  | 						Name:     "name", | ||||||
|  | 						Aliases:  []string{"n"}, | ||||||
|  | 						Required: true, | ||||||
|  | 						Usage:    gotext.Get("Name of the AUR package"), | ||||||
|  | 					}, | ||||||
|  | 					&cli.StringFlag{ | ||||||
|  | 						Name:    "version", | ||||||
|  | 						Aliases: []string{"v"}, | ||||||
|  | 						Usage:   gotext.Get("Version of the package (optional, uses latest if not specified)"), | ||||||
|  | 					}, | ||||||
|  | 				}, | ||||||
|  | 				Action: func(c *cli.Context) error { | ||||||
|  | 					return gen.AUR(os.Stdout, gen.AUROptions{ | ||||||
|  | 						Name:    c.String("name"), | ||||||
|  | 						Version: c.String("version"), | ||||||
|  | 					}) | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										668
									
								
								internal/gen/aur.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										668
									
								
								internal/gen/aur.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,668 @@ | |||||||
|  | // This file was originally part of the project "LURE - Linux User REpository", created by Elara Musayelyan. | ||||||
|  | // It has been modified as part of "ALR - Any Linux Repository" by the ALR Authors. | ||||||
|  | // | ||||||
|  | // ALR - Any Linux Repository | ||||||
|  | // Copyright (C) 2025 The ALR Authors | ||||||
|  | // | ||||||
|  | // This program is free software: you can redistribute it and/or modify | ||||||
|  | // it under the terms of the GNU General Public License as published by | ||||||
|  | // the Free Software Foundation, either version 3 of the License, or | ||||||
|  | // (at your option) any later version. | ||||||
|  | // | ||||||
|  | // This program is distributed in the hope that it will be useful, | ||||||
|  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  | // GNU General Public License for more details. | ||||||
|  | // | ||||||
|  | // You should have received a copy of the GNU General Public License | ||||||
|  | // along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  | ||||||
|  | package gen | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	_ "embed" | ||||||
|  | 	"encoding/json" | ||||||
|  | 	"fmt" | ||||||
|  | 	"io" | ||||||
|  | 	"net/http" | ||||||
|  | 	"net/url" | ||||||
|  | 	"regexp" | ||||||
|  | 	"strings" | ||||||
|  | 	"text/template" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // Встраиваем шаблон для AUR пакетов | ||||||
|  | // | ||||||
|  | //go:embed tmpls/aur.tmpl.sh | ||||||
|  | var aurTmpl string | ||||||
|  |  | ||||||
|  | // AUROptions содержит параметры для генерации шаблона AUR | ||||||
|  | type AUROptions struct { | ||||||
|  | 	Name    string // Имя пакета в AUR | ||||||
|  | 	Version string // Версия пакета (опционально, если не указана - берется последняя) | ||||||
|  | 	CreateDir bool  // Создавать ли директорию для пакета и дополнительные файлы | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // aurAPIResponse представляет структуру ответа от API AUR | ||||||
|  | type aurAPIResponse struct { | ||||||
|  | 	Version      int         `json:"version"`      // Версия API | ||||||
|  | 	Type         string      `json:"type"`         // Тип ответа | ||||||
|  | 	ResultCount  int         `json:"resultcount"`  // Количество результатов | ||||||
|  | 	Results      []aurResult `json:"results"`      // Массив результатов | ||||||
|  | 	Error        string      `json:"error"`        // Сообщение об ошибке (если есть) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // aurResult содержит информацию о пакете из AUR | ||||||
|  | type aurResult struct { | ||||||
|  | 	ID             int      `json:"ID"` | ||||||
|  | 	Name           string   `json:"Name"` | ||||||
|  | 	PackageBaseID  int      `json:"PackageBaseID"` | ||||||
|  | 	PackageBase    string   `json:"PackageBase"` | ||||||
|  | 	Version        string   `json:"Version"` | ||||||
|  | 	Description    string   `json:"Description"` | ||||||
|  | 	URL            string   `json:"URL"` | ||||||
|  | 	NumVotes       int      `json:"NumVotes"` | ||||||
|  | 	Popularity     float64  `json:"Popularity"` | ||||||
|  | 	OutOfDate      *int     `json:"OutOfDate"` | ||||||
|  | 	Maintainer     string   `json:"Maintainer"` | ||||||
|  | 	FirstSubmitted int      `json:"FirstSubmitted"` | ||||||
|  | 	LastModified   int      `json:"LastModified"` | ||||||
|  | 	URLPath        string   `json:"URLPath"` | ||||||
|  | 	License        []string `json:"License"` | ||||||
|  | 	Keywords       []string `json:"Keywords"` | ||||||
|  | 	Depends        []string `json:"Depends"` | ||||||
|  | 	MakeDepends    []string `json:"MakeDepends"` | ||||||
|  | 	OptDepends     []string `json:"OptDepends"` | ||||||
|  | 	CheckDepends   []string `json:"CheckDepends"` | ||||||
|  | 	Conflicts      []string `json:"Conflicts"` | ||||||
|  | 	Provides       []string `json:"Provides"` | ||||||
|  | 	Replaces       []string `json:"Replaces"` | ||||||
|  | 	// Дополнительные поля для данных из PKGBUILD | ||||||
|  | 	Sources      []string `json:"-"` | ||||||
|  | 	Checksums    []string `json:"-"` | ||||||
|  | 	BuildFunc    string   `json:"-"` | ||||||
|  | 	PackageFunc  string   `json:"-"` | ||||||
|  | 	PrepareFunc  string   `json:"-"` | ||||||
|  | 	PackageType  string   `json:"-"`  // python, go, rust, cpp, nodejs, bin, git | ||||||
|  | 	HasDesktop   bool     `json:"-"`  // Есть ли desktop файлы | ||||||
|  | 	HasSystemd   bool     `json:"-"`  // Есть ли systemd сервисы | ||||||
|  | 	HasVersion   bool     `json:"-"`  // Есть ли функция version() | ||||||
|  | 	HasScripts   []string `json:"-"`  // Дополнительные скрипты (postinstall, postremove, etc) | ||||||
|  | 	HasPatches   bool     `json:"-"`  // Есть ли патчи | ||||||
|  | 	Architectures []string `json:"-"` // Поддерживаемые архитектуры | ||||||
|  | 	 | ||||||
|  | 	// Автоматически определяемые файлы для install-* команд | ||||||
|  | 	BinaryFiles  []string `json:"-"`  // Исполняемые файлы для install-binary | ||||||
|  | 	LicenseFiles []string `json:"-"`  // Лицензионные файлы для install-license | ||||||
|  | 	ManualFiles  []string `json:"-"`  // Man страницы для install-manual | ||||||
|  | 	DesktopFiles []string `json:"-"`  // Desktop файлы для install-desktop | ||||||
|  | 	ServiceFiles []string `json:"-"`  // Systemd сервисы для install-systemd | ||||||
|  | 	CompletionFiles map[string]string `json:"-"` // Файлы автодополнения по типу (bash, zsh, fish) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Вспомогательные методы для шаблона | ||||||
|  | func (r aurResult) LicenseString() string { | ||||||
|  | 	if len(r.License) == 0 { | ||||||
|  | 		return "custom:Unknown" | ||||||
|  | 	} | ||||||
|  | 	// Форматируем лицензии для alr.sh | ||||||
|  | 	licenses := make([]string, len(r.License)) | ||||||
|  | 	for i, l := range r.License { | ||||||
|  | 		licenses[i] = fmt.Sprintf("'%s'", l) | ||||||
|  | 	} | ||||||
|  | 	return strings.Join(licenses, " ") | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (r aurResult) DependsString() string { | ||||||
|  | 	if len(r.Depends) == 0 { | ||||||
|  | 		return "" | ||||||
|  | 	} | ||||||
|  | 	deps := make([]string, len(r.Depends)) | ||||||
|  | 	for i, d := range r.Depends { | ||||||
|  | 		// Убираем версионные ограничения для простоты | ||||||
|  | 		dep := strings.Split(d, ">=")[0] | ||||||
|  | 		dep = strings.Split(dep, "<=")[0] | ||||||
|  | 		dep = strings.Split(dep, "=")[0] | ||||||
|  | 		dep = strings.Split(dep, ">")[0] | ||||||
|  | 		dep = strings.Split(dep, "<")[0] | ||||||
|  | 		deps[i] = fmt.Sprintf("'%s'", dep) | ||||||
|  | 	} | ||||||
|  | 	return strings.Join(deps, " ") | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (r aurResult) MakeDependsString() string { | ||||||
|  | 	if len(r.MakeDepends) == 0 { | ||||||
|  | 		return "" | ||||||
|  | 	} | ||||||
|  | 	deps := make([]string, len(r.MakeDepends)) | ||||||
|  | 	for i, d := range r.MakeDepends { | ||||||
|  | 		// Убираем версионные ограничения для простоты | ||||||
|  | 		dep := strings.Split(d, ">=")[0] | ||||||
|  | 		dep = strings.Split(dep, "<=")[0] | ||||||
|  | 		dep = strings.Split(dep, "=")[0] | ||||||
|  | 		dep = strings.Split(dep, ">")[0] | ||||||
|  | 		dep = strings.Split(dep, "<")[0] | ||||||
|  | 		deps[i] = fmt.Sprintf("'%s'", dep) | ||||||
|  | 	} | ||||||
|  | 	return strings.Join(deps, " ") | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (r aurResult) GitURL() string { | ||||||
|  | 	// Формируем URL для клонирования из AUR | ||||||
|  | 	return fmt.Sprintf("https://aur.archlinux.org/%s.git", r.PackageBase) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (r aurResult) ArchitecturesString() string { | ||||||
|  | 	if len(r.Architectures) == 0 { | ||||||
|  | 		return "'all'" | ||||||
|  | 	} | ||||||
|  | 	archs := make([]string, len(r.Architectures)) | ||||||
|  | 	for i, arch := range r.Architectures { | ||||||
|  | 		archs[i] = fmt.Sprintf("'%s'", arch) | ||||||
|  | 	} | ||||||
|  | 	return strings.Join(archs, " ") | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (r aurResult) OptDependsString() string { | ||||||
|  | 	if len(r.OptDepends) == 0 { | ||||||
|  | 		return "" | ||||||
|  | 	} | ||||||
|  | 	optDeps := make([]string, 0, len(r.OptDepends)) | ||||||
|  | 	for _, dep := range r.OptDepends { | ||||||
|  | 		// Форматируем опциональные зависимости для alr.sh | ||||||
|  | 		parts := strings.SplitN(dep, ": ", 2) | ||||||
|  | 		if len(parts) == 2 { | ||||||
|  | 			optDeps = append(optDeps, fmt.Sprintf("'%s: %s'", parts[0], parts[1])) | ||||||
|  | 		} else { | ||||||
|  | 			optDeps = append(optDeps, fmt.Sprintf("'%s'", dep)) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return strings.Join(optDeps, "\n\t") | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (r aurResult) ScriptsString() string { | ||||||
|  | 	if len(r.HasScripts) == 0 { | ||||||
|  | 		return "" | ||||||
|  | 	} | ||||||
|  | 	scripts := make([]string, len(r.HasScripts)) | ||||||
|  | 	for i, script := range r.HasScripts { | ||||||
|  | 		scripts[i] = fmt.Sprintf("['%s']='%s.sh'", script, script) | ||||||
|  | 	} | ||||||
|  | 	return strings.Join(scripts, "\n\t") | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GenerateInstallCommands генерирует команды install-* для шаблона | ||||||
|  | func (r aurResult) GenerateInstallCommands() string { | ||||||
|  | 	var commands []string | ||||||
|  | 	 | ||||||
|  | 	// install-binary команды | ||||||
|  | 	for _, binary := range r.BinaryFiles { | ||||||
|  | 		if binary == "./"+r.Name { | ||||||
|  | 			commands = append(commands, fmt.Sprintf("\tinstall-binary %s", binary)) | ||||||
|  | 		} else { | ||||||
|  | 			commands = append(commands, fmt.Sprintf("\tinstall-binary %s %s", binary, r.Name)) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	// install-license команды | ||||||
|  | 	for _, license := range r.LicenseFiles { | ||||||
|  | 		if license == "LICENSE" || license == "./LICENSE" { | ||||||
|  | 			commands = append(commands, fmt.Sprintf("\tinstall-license %s %s/LICENSE", license, r.Name)) | ||||||
|  | 		} else { | ||||||
|  | 			commands = append(commands, fmt.Sprintf("\tinstall-license %s %s/LICENSE", license, r.Name)) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	// install-manual команды | ||||||
|  | 	for _, manual := range r.ManualFiles { | ||||||
|  | 		commands = append(commands, fmt.Sprintf("\tinstall-manual %s", manual)) | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	// install-desktop команды | ||||||
|  | 	for _, desktop := range r.DesktopFiles { | ||||||
|  | 		commands = append(commands, fmt.Sprintf("\tinstall-desktop %s", desktop)) | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	// install-systemd команды | ||||||
|  | 	for _, service := range r.ServiceFiles { | ||||||
|  | 		if strings.Contains(service, "user") { | ||||||
|  | 			commands = append(commands, fmt.Sprintf("\tinstall-systemd-user %s", service)) | ||||||
|  | 		} else { | ||||||
|  | 			commands = append(commands, fmt.Sprintf("\tinstall-systemd %s", service)) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	// install-completion команды | ||||||
|  | 	for shell, file := range r.CompletionFiles { | ||||||
|  | 		switch shell { | ||||||
|  | 		case "bash": | ||||||
|  | 			commands = append(commands, fmt.Sprintf("\tinstall-completion bash %s < %s", r.Name, file)) | ||||||
|  | 		case "zsh": | ||||||
|  | 			commands = append(commands, fmt.Sprintf("\tinstall-completion zsh %s < %s", r.Name, file)) | ||||||
|  | 		case "fish": | ||||||
|  | 			commands = append(commands, fmt.Sprintf("\t%s completion fish | install-completion fish %s", r.Name, r.Name)) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	if len(commands) == 0 { | ||||||
|  | 		return "\t# TODO: Добавьте команды установки файлов" | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	return strings.Join(commands, "\n") | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // fetchPKGBUILD загружает PKGBUILD файл для пакета | ||||||
|  | func fetchPKGBUILD(packageBase string) (string, error) { | ||||||
|  | 	// URL для raw PKGBUILD | ||||||
|  | 	pkgbuildURL := fmt.Sprintf("https://aur.archlinux.org/cgit/aur.git/plain/PKGBUILD?h=%s", packageBase) | ||||||
|  | 	 | ||||||
|  | 	res, err := http.Get(pkgbuildURL) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "", fmt.Errorf("failed to fetch PKGBUILD: %w", err) | ||||||
|  | 	} | ||||||
|  | 	defer res.Body.Close() | ||||||
|  | 	 | ||||||
|  | 	if res.StatusCode != 200 { | ||||||
|  | 		return "", fmt.Errorf("failed to fetch PKGBUILD: status %s", res.Status) | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	data, err := io.ReadAll(res.Body) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "", fmt.Errorf("failed to read PKGBUILD: %w", err) | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	return string(data), nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // parseSources извлекает источники из PKGBUILD | ||||||
|  | func parseSources(pkgbuild string) []string { | ||||||
|  | 	var sources []string | ||||||
|  | 	 | ||||||
|  | 	// Регулярное выражение для поиска массива source | ||||||
|  | 	// Поддерживает как однострочные, так и многострочные определения | ||||||
|  | 	sourceRegex := regexp.MustCompile(`(?ms)source=\((.*?)\)`) | ||||||
|  | 	matches := sourceRegex.FindStringSubmatch(pkgbuild) | ||||||
|  | 	 | ||||||
|  | 	if len(matches) > 1 { | ||||||
|  | 		// Извлекаем содержимое массива source | ||||||
|  | 		sourceContent := matches[1] | ||||||
|  | 		 | ||||||
|  | 		// Разбираем элементы массива | ||||||
|  | 		// Учитываем кавычки и переносы строк | ||||||
|  | 		elemRegex := regexp.MustCompile(`['"]([^'"]+)['"]`) | ||||||
|  | 		elements := elemRegex.FindAllStringSubmatch(sourceContent, -1) | ||||||
|  | 		 | ||||||
|  | 		for _, elem := range elements { | ||||||
|  | 			if len(elem) > 1 { | ||||||
|  | 				source := elem[1] | ||||||
|  | 				// Заменяем переменные версии | ||||||
|  | 				source = strings.ReplaceAll(source, "$pkgver", "${version}") | ||||||
|  | 				source = strings.ReplaceAll(source, "${pkgver}", "${version}") | ||||||
|  | 				source = strings.ReplaceAll(source, "$pkgname", "${name}") | ||||||
|  | 				source = strings.ReplaceAll(source, "${pkgname}", "${name}") | ||||||
|  | 				// Обрабатываем другие переменные (упрощенно) | ||||||
|  | 				source = strings.ReplaceAll(source, "$_commit", "${_commit}") | ||||||
|  | 				source = strings.ReplaceAll(source, "${_commit}", "${_commit}") | ||||||
|  | 				sources = append(sources, source) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	// Если источники не найдены в source=(), проверяем source_x86_64 и другие архитектуры | ||||||
|  | 	if len(sources) == 0 { | ||||||
|  | 		archSourceRegex := regexp.MustCompile(`(?ms)source_(?:x86_64|aarch64)=\((.*?)\)`) | ||||||
|  | 		matches = archSourceRegex.FindStringSubmatch(pkgbuild) | ||||||
|  | 		if len(matches) > 1 { | ||||||
|  | 			sourceContent := matches[1] | ||||||
|  | 			elemRegex := regexp.MustCompile(`['"]([^'"]+)['"]`) | ||||||
|  | 			elements := elemRegex.FindAllStringSubmatch(sourceContent, -1) | ||||||
|  | 			 | ||||||
|  | 			for _, elem := range elements { | ||||||
|  | 				if len(elem) > 1 { | ||||||
|  | 					source := elem[1] | ||||||
|  | 					source = strings.ReplaceAll(source, "$pkgver", "${version}") | ||||||
|  | 					source = strings.ReplaceAll(source, "${pkgver}", "${version}") | ||||||
|  | 					source = strings.ReplaceAll(source, "$pkgname", "${name}") | ||||||
|  | 					source = strings.ReplaceAll(source, "${pkgname}", "${name}") | ||||||
|  | 					sources = append(sources, source) | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	return sources | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // parseChecksums извлекает контрольные суммы из PKGBUILD | ||||||
|  | func parseChecksums(pkgbuild string) []string { | ||||||
|  | 	var checksums []string | ||||||
|  | 	 | ||||||
|  | 	// Пробуем разные типы контрольных сумм | ||||||
|  | 	for _, hashType := range []string{"sha256sums", "sha512sums", "sha1sums", "md5sums", "b2sums"} { | ||||||
|  | 		regex := regexp.MustCompile(fmt.Sprintf(`(?ms)%s=\((.*?)\)`, hashType)) | ||||||
|  | 		matches := regex.FindStringSubmatch(pkgbuild) | ||||||
|  | 		 | ||||||
|  | 		if len(matches) > 1 { | ||||||
|  | 			content := matches[1] | ||||||
|  | 			elemRegex := regexp.MustCompile(`['"]([^'"]+)['"]`) | ||||||
|  | 			elements := elemRegex.FindAllStringSubmatch(content, -1) | ||||||
|  | 			 | ||||||
|  | 			for _, elem := range elements { | ||||||
|  | 				if len(elem) > 1 { | ||||||
|  | 					checksums = append(checksums, elem[1]) | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			 | ||||||
|  | 			if len(checksums) > 0 { | ||||||
|  | 				break // Используем первый найденный тип хешей | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	return checksums | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // parseFunctions извлекает функции build(), package() и prepare() из PKGBUILD | ||||||
|  | func parseFunctions(pkgbuild string) (buildFunc, packageFunc, prepareFunc string) { | ||||||
|  | 	// Извлекаем функцию build() | ||||||
|  | 	buildRegex := regexp.MustCompile(`(?ms)^build\(\)\s*\{(.*?)^\}`) | ||||||
|  | 	if matches := buildRegex.FindStringSubmatch(pkgbuild); len(matches) > 1 { | ||||||
|  | 		buildFunc = strings.TrimSpace(matches[1]) | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	// Извлекаем функцию package() | ||||||
|  | 	packageRegex := regexp.MustCompile(`(?ms)^package\(\)\s*\{(.*?)^\}`) | ||||||
|  | 	if matches := packageRegex.FindStringSubmatch(pkgbuild); len(matches) > 1 { | ||||||
|  | 		packageFunc = strings.TrimSpace(matches[1]) | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	// Извлекаем функцию prepare() | ||||||
|  | 	prepareRegex := regexp.MustCompile(`(?ms)^prepare\(\)\s*\{(.*?)^\}`) | ||||||
|  | 	if matches := prepareRegex.FindStringSubmatch(pkgbuild); len(matches) > 1 { | ||||||
|  | 		prepareFunc = strings.TrimSpace(matches[1]) | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	return buildFunc, packageFunc, prepareFunc | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // detectInstallableFiles анализирует PKGBUILD и определяет файлы для install-* команд | ||||||
|  | func detectInstallableFiles(pkg *aurResult, pkgbuild string) { | ||||||
|  | 	// Инициализируем карту для файлов автодополнения | ||||||
|  | 	pkg.CompletionFiles = make(map[string]string) | ||||||
|  | 	 | ||||||
|  | 	// Для простоты, добавляем стандартные файлы для типа пакета | ||||||
|  | 	switch pkg.PackageType { | ||||||
|  | 	case "go": | ||||||
|  | 		pkg.BinaryFiles = append(pkg.BinaryFiles, "./"+pkg.Name) | ||||||
|  | 	case "rust": | ||||||
|  | 		pkg.BinaryFiles = append(pkg.BinaryFiles, "./target/release/"+pkg.Name) | ||||||
|  | 	case "cpp", "meson": | ||||||
|  | 		pkg.BinaryFiles = append(pkg.BinaryFiles, "./"+pkg.Name) // обычно в корне после сборки | ||||||
|  | 	case "bin": | ||||||
|  | 		pkg.BinaryFiles = append(pkg.BinaryFiles, "./"+pkg.Name) | ||||||
|  | 	default: | ||||||
|  | 		if pkg.PackageType != "python" && pkg.PackageType != "nodejs" { | ||||||
|  | 			pkg.BinaryFiles = append(pkg.BinaryFiles, "./"+pkg.Name) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	// Ищем лицензионные файлы для install-license с более точными паттернами | ||||||
|  | 	licenseRegex := regexp.MustCompile(`(?i)\b(LICENSE|COPYING|COPYRIGHT|LICENCE)(?:\.[a-zA-Z0-9]+)?\b`) | ||||||
|  | 	licenseMatches := licenseRegex.FindAllString(pkgbuild, -1) | ||||||
|  | 	for _, match := range licenseMatches { | ||||||
|  | 		// Фильтруем только реальные файлы лицензий | ||||||
|  | 		if strings.Contains(strings.ToLower(match), "license") ||  | ||||||
|  | 		   strings.Contains(strings.ToLower(match), "copying") ||  | ||||||
|  | 		   strings.Contains(strings.ToLower(match), "copyright") { | ||||||
|  | 			if !contains(pkg.LicenseFiles, "./"+match) { | ||||||
|  | 				pkg.LicenseFiles = append(pkg.LicenseFiles, "./"+match) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	// Если не найдены лицензионные файлы, добавляем стандартные | ||||||
|  | 	if len(pkg.LicenseFiles) == 0 { | ||||||
|  | 		pkg.LicenseFiles = append(pkg.LicenseFiles, "LICENSE") | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	// Ищем man страницы для install-manual с более точными паттернами | ||||||
|  | 	manRegex := regexp.MustCompile(`\b\w+\.(?:1|2|3|4|5|6|7|8)(?:\.gz)?\b`) | ||||||
|  | 	manMatches := manRegex.FindAllString(pkgbuild, -1) | ||||||
|  | 	for _, match := range manMatches { | ||||||
|  | 		// Проверяем, что это не переменная или часть кода | ||||||
|  | 		if !strings.Contains(match, "$") && !strings.Contains(match, "{") { | ||||||
|  | 			if !contains(pkg.ManualFiles, "./"+match) { | ||||||
|  | 				pkg.ManualFiles = append(pkg.ManualFiles, "./"+match) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	// Ищем desktop файлы для install-desktop | ||||||
|  | 	desktopRegex := regexp.MustCompile(`[^/\s]*\.desktop`) | ||||||
|  | 	desktopMatches := desktopRegex.FindAllString(pkgbuild, -1) | ||||||
|  | 	for _, match := range desktopMatches { | ||||||
|  | 		if !contains(pkg.DesktopFiles, "./"+match) { | ||||||
|  | 			pkg.DesktopFiles = append(pkg.DesktopFiles, "./"+match) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	// Ищем systemd сервисы для install-systemd | ||||||
|  | 	serviceRegex := regexp.MustCompile(`[^/\s]*\.service`) | ||||||
|  | 	serviceMatches := serviceRegex.FindAllString(pkgbuild, -1) | ||||||
|  | 	for _, match := range serviceMatches { | ||||||
|  | 		if !contains(pkg.ServiceFiles, "./"+match) { | ||||||
|  | 			pkg.ServiceFiles = append(pkg.ServiceFiles, "./"+match) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	// Ищем файлы автодополнения | ||||||
|  | 	completionPatterns := map[string]string{ | ||||||
|  | 		"bash": `completions?/.*\.bash|bash-completion`, | ||||||
|  | 		"zsh":  `completions?/.*\.zsh|zsh.*completion`, | ||||||
|  | 		"fish": `completions?/.*\.fish|fish.*completion`, | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	for shell, pattern := range completionPatterns { | ||||||
|  | 		regex := regexp.MustCompile(fmt.Sprintf(`(?i)%s`, pattern)) | ||||||
|  | 		matches := regex.FindAllString(pkgbuild, -1) | ||||||
|  | 		if len(matches) > 0 { | ||||||
|  | 			pkg.CompletionFiles[shell] = matches[0] | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // contains проверяет, содержит ли слайс строк указанную строку | ||||||
|  | func contains(slice []string, item string) bool { | ||||||
|  | 	for _, s := range slice { | ||||||
|  | 		if s == item { | ||||||
|  | 			return true | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return false | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // detectPackageType определяет тип пакета на основе имени, зависимостей и источников | ||||||
|  | func detectPackageType(pkg *aurResult, pkgbuild string) { | ||||||
|  | 	name := strings.ToLower(pkg.Name) | ||||||
|  | 	 | ||||||
|  | 	// Определяем тип на основе имени пакета | ||||||
|  | 	switch { | ||||||
|  | 	case strings.HasPrefix(name, "python") || strings.HasPrefix(name, "python3-"): | ||||||
|  | 		pkg.PackageType = "python" | ||||||
|  | 	case strings.Contains(name, "nodejs") || strings.Contains(name, "node-"): | ||||||
|  | 		pkg.PackageType = "nodejs" | ||||||
|  | 	case strings.HasSuffix(name, "-bin"): | ||||||
|  | 		pkg.PackageType = "bin" | ||||||
|  | 	case strings.HasSuffix(name, "-git"): | ||||||
|  | 		pkg.PackageType = "git" | ||||||
|  | 		pkg.HasVersion = true // Git пакеты обычно имеют функцию version() | ||||||
|  | 	case strings.Contains(name, "rust") || hasRustSources(pkg.Sources): | ||||||
|  | 		pkg.PackageType = "rust" | ||||||
|  | 	case strings.Contains(name, "go-") || hasGoSources(pkg.Sources): | ||||||
|  | 		pkg.PackageType = "go" | ||||||
|  | 	case strings.Contains(name, "-rust") || strings.Contains(name, "paru") || strings.Contains(name, "cargo-"): | ||||||
|  | 		pkg.PackageType = "rust" | ||||||
|  | 	default: | ||||||
|  | 		// Определяем по зависимостям сборки | ||||||
|  | 		for _, dep := range pkg.MakeDepends { | ||||||
|  | 			depLower := strings.ToLower(dep) | ||||||
|  | 			switch { | ||||||
|  | 			case strings.Contains(depLower, "meson") || strings.Contains(depLower, "ninja"): | ||||||
|  | 				pkg.PackageType = "meson" | ||||||
|  | 			case strings.Contains(depLower, "cmake") || strings.Contains(depLower, "gcc") || strings.Contains(depLower, "clang"): | ||||||
|  | 				pkg.PackageType = "cpp" | ||||||
|  | 			case strings.Contains(depLower, "python"): | ||||||
|  | 				pkg.PackageType = "python" | ||||||
|  | 			case strings.Contains(depLower, "go"): | ||||||
|  | 				pkg.PackageType = "go" | ||||||
|  | 			case strings.Contains(depLower, "rust") || strings.Contains(depLower, "cargo"): | ||||||
|  | 				pkg.PackageType = "rust" | ||||||
|  | 			case strings.Contains(depLower, "npm") || strings.Contains(depLower, "nodejs"): | ||||||
|  | 				pkg.PackageType = "nodejs" | ||||||
|  | 			} | ||||||
|  | 			if pkg.PackageType != "" { | ||||||
|  | 				break | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	// Определяем архитектуры на основе типа пакета | ||||||
|  | 	if pkg.PackageType == "bin" { | ||||||
|  | 		pkg.Architectures = []string{"amd64"} // Бинарные пакеты обычно специфичны для архитектуры | ||||||
|  | 	} else { | ||||||
|  | 		pkg.Architectures = []string{"all"} // Исходный код собирается для любой архитектуры | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	// Определяем наличие desktop файлов | ||||||
|  | 	pkg.HasDesktop = strings.Contains(pkgbuild, ".desktop") ||  | ||||||
|  | 		strings.Contains(pkgbuild, "install-desktop") || | ||||||
|  | 		strings.Contains(pkgbuild, "xdg-desktop") | ||||||
|  | 	 | ||||||
|  | 	// Определяем наличие systemd сервисов | ||||||
|  | 	pkg.HasSystemd = strings.Contains(pkgbuild, ".service") || | ||||||
|  | 		strings.Contains(pkgbuild, "systemctl") || | ||||||
|  | 		strings.Contains(pkgbuild, "install-systemd") | ||||||
|  | 	 | ||||||
|  | 	// Определяем наличие функции version() для -git пакетов | ||||||
|  | 	pkg.HasVersion = strings.Contains(pkgbuild, "pkgver()") ||  | ||||||
|  | 		(strings.HasSuffix(name, "-git") && strings.Contains(pkgbuild, "git describe")) | ||||||
|  | 	 | ||||||
|  | 	// Определяем наличие патчей | ||||||
|  | 	pkg.HasPatches = strings.Contains(pkgbuild, "patch ") ||  | ||||||
|  | 		strings.Contains(pkgbuild, ".patch") || | ||||||
|  | 		strings.Contains(pkgbuild, ".diff") | ||||||
|  | 	 | ||||||
|  | 	// Определяем дополнительные скрипты | ||||||
|  | 	if strings.Contains(pkgbuild, "post_install") { | ||||||
|  | 		pkg.HasScripts = append(pkg.HasScripts, "postinstall") | ||||||
|  | 	} | ||||||
|  | 	if strings.Contains(pkgbuild, "pre_remove") || strings.Contains(pkgbuild, "post_remove") { | ||||||
|  | 		pkg.HasScripts = append(pkg.HasScripts, "postremove") | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // hasRustSources проверяет, содержат ли источники Rust проекты | ||||||
|  | func hasRustSources(sources []string) bool { | ||||||
|  | 	for _, src := range sources { | ||||||
|  | 		if strings.Contains(src, "crates.io") || strings.Contains(src, "Cargo.toml") { | ||||||
|  | 			return true | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return false | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // hasGoSources проверяет, содержат ли источники Go проекты | ||||||
|  | func hasGoSources(sources []string) bool { | ||||||
|  | 	for _, src := range sources { | ||||||
|  | 		if strings.Contains(src, "github.com") && strings.Contains(src, "/go") { | ||||||
|  | 			return true | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return false | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // AUR генерирует шаблон alr.sh на основе пакета из AUR | ||||||
|  | func AUR(w io.Writer, opts AUROptions) error { | ||||||
|  | 	// Создаем шаблон с функциями | ||||||
|  | 	tmpl, err := template.New("aur"). | ||||||
|  | 		Funcs(funcs). | ||||||
|  | 		Parse(aurTmpl) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Формируем URL запроса к AUR API | ||||||
|  | 	apiURL := "https://aur.archlinux.org/rpc/v5/info" | ||||||
|  | 	params := url.Values{} | ||||||
|  | 	params.Add("arg[]", opts.Name) | ||||||
|  | 	fullURL := fmt.Sprintf("%s?%s", apiURL, params.Encode()) | ||||||
|  |  | ||||||
|  | 	// Выполняем запрос к AUR API | ||||||
|  | 	res, err := http.Get(fullURL) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return fmt.Errorf("failed to fetch AUR package info: %w", err) | ||||||
|  | 	} | ||||||
|  | 	defer res.Body.Close() | ||||||
|  |  | ||||||
|  | 	if res.StatusCode != 200 { | ||||||
|  | 		return fmt.Errorf("AUR API returned status: %s", res.Status) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Декодируем ответ | ||||||
|  | 	var resp aurAPIResponse | ||||||
|  | 	err = json.NewDecoder(res.Body).Decode(&resp) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return fmt.Errorf("failed to decode AUR response: %w", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Проверяем наличие ошибки в ответе | ||||||
|  | 	if resp.Error != "" { | ||||||
|  | 		return fmt.Errorf("AUR API error: %s", resp.Error) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Проверяем, что пакет найден | ||||||
|  | 	if resp.ResultCount == 0 { | ||||||
|  | 		return fmt.Errorf("package '%s' not found in AUR", opts.Name) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Берем первый результат | ||||||
|  | 	pkg := resp.Results[0] | ||||||
|  |  | ||||||
|  | 	// Если указана версия, проверяем соответствие | ||||||
|  | 	if opts.Version != "" && pkg.Version != opts.Version { | ||||||
|  | 		// Предупреждаем, но продолжаем с актуальной версией из AUR | ||||||
|  | 		fmt.Fprintf(w, "# WARNING: Requested version %s, but AUR has %s\n", opts.Version, pkg.Version) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Загружаем PKGBUILD для получения источников | ||||||
|  | 	pkgbuild, err := fetchPKGBUILD(pkg.PackageBase) | ||||||
|  | 	if err != nil { | ||||||
|  | 		// Если не удалось загрузить PKGBUILD, используем fallback на AUR репозиторий | ||||||
|  | 		fmt.Fprintf(w, "# WARNING: Could not fetch PKGBUILD: %v\n", err) | ||||||
|  | 		fmt.Fprintf(w, "# Using AUR repository as source\n") | ||||||
|  | 		pkg.Sources = []string{fmt.Sprintf("%s::git+%s", pkg.Name, pkg.GitURL())} | ||||||
|  | 		pkg.Checksums = []string{"SKIP"} | ||||||
|  | 	} else { | ||||||
|  | 		// Извлекаем источники из PKGBUILD | ||||||
|  | 		pkg.Sources = parseSources(pkgbuild) | ||||||
|  | 		pkg.Checksums = parseChecksums(pkgbuild) | ||||||
|  | 		pkg.BuildFunc, pkg.PackageFunc, pkg.PrepareFunc = parseFunctions(pkgbuild) | ||||||
|  | 		 | ||||||
|  | 		// Определяем тип пакета | ||||||
|  | 		detectPackageType(&pkg, pkgbuild) | ||||||
|  | 		 | ||||||
|  | 		// Определяем файлы для install-* команд | ||||||
|  | 		detectInstallableFiles(&pkg, pkgbuild) | ||||||
|  | 		 | ||||||
|  | 		// Если источники не найдены, используем fallback | ||||||
|  | 		if len(pkg.Sources) == 0 { | ||||||
|  | 			fmt.Fprintf(w, "# WARNING: No sources found in PKGBUILD\n") | ||||||
|  | 			fmt.Fprintf(w, "# Using AUR repository as source\n") | ||||||
|  | 			pkg.Sources = []string{fmt.Sprintf("%s::git+%s", pkg.Name, pkg.GitURL())} | ||||||
|  | 			pkg.Checksums = []string{"SKIP"} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Выполняем шаблон | ||||||
|  | 	return tmpl.Execute(w, pkg) | ||||||
|  | } | ||||||
							
								
								
									
										133
									
								
								internal/gen/tmpls/aur.tmpl.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								internal/gen/tmpls/aur.tmpl.sh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,133 @@ | |||||||
|  | # This file was originally part of the project "LURE - Linux User REpository", created by Elara Musayelyan. | ||||||
|  | # It has been modified as part of "ALR - Any Linux Repository" by the ALR Authors. | ||||||
|  | # | ||||||
|  | # ALR - Any Linux Repository | ||||||
|  | # Copyright (C) 2025 The ALR Authors | ||||||
|  | # | ||||||
|  | # This program is free software: you can redistribute it and/or modify | ||||||
|  | # it under the terms of the GNU General Public License as published by | ||||||
|  | # the Free Software Foundation, either version 3 of the License, or | ||||||
|  | # (at your option) any later version. | ||||||
|  | # | ||||||
|  | # This program is distributed in the hope that it will be useful, | ||||||
|  | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  | # GNU General Public License for more details. | ||||||
|  | # | ||||||
|  | # You should have received a copy of the GNU General Public License | ||||||
|  | # along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  | ||||||
|  | # Generated from AUR package: {{.Name}} | ||||||
|  | # Package type: {{.PackageType}} | ||||||
|  | # AUR votes: {{.NumVotes}} | Popularity: {{printf "%.2f" .Popularity}} | ||||||
|  | # Original maintainer: {{.Maintainer}} | ||||||
|  | # Adapted for ALR by automation | ||||||
|  |  | ||||||
|  | name='{{.Name}}' | ||||||
|  | version='{{.Version}}' | ||||||
|  | release='1' | ||||||
|  | desc='{{.Description}}' | ||||||
|  | {{if ne .Description ""}}desc_ru='{{.Description}}'{{end}} | ||||||
|  | homepage='{{.URL}}' | ||||||
|  | maintainer="Евгений Храмов <xpamych@yandex.ru> (imported from AUR)" | ||||||
|  | {{if ne .Description ""}}maintainer_ru="Евгений Храмов <xpamych@yandex.ru> (импортирован из AUR)"{{end}} | ||||||
|  | architectures=({{.ArchitecturesString}}) | ||||||
|  | license=({{.LicenseString}}) | ||||||
|  | {{if .Provides}}provides=({{range .Provides}}'{{.}}' {{end}}){{end}} | ||||||
|  | {{if .Conflicts}}conflicts=({{range .Conflicts}}'{{.}}' {{end}}){{end}} | ||||||
|  | {{if .Replaces}}replaces=({{range .Replaces}}'{{.}}' {{end}}){{end}} | ||||||
|  |  | ||||||
|  | # Базовые зависимости | ||||||
|  | {{if .DependsString}}deps=({{.DependsString}}){{else}}deps=(){{end}} | ||||||
|  | {{if .MakeDependsString}}build_deps=({{.MakeDependsString}}){{else}}build_deps=(){{end}} | ||||||
|  |  | ||||||
|  | # Зависимости для конкретных дистрибутивов (адаптируйте под нужды пакета) | ||||||
|  | {{if .DependsString}}deps_arch=({{.DependsString}}) | ||||||
|  | deps_debian=({{.DependsString}}) | ||||||
|  | deps_altlinux=({{.DependsString}}) | ||||||
|  | deps_alpine=({{.DependsString}}){{end}} | ||||||
|  |  | ||||||
|  | {{if and .MakeDependsString (ne .PackageType "bin")}}# Зависимости сборки для конкретных дистрибутивов | ||||||
|  | build_deps_arch=({{.MakeDependsString}}) | ||||||
|  | build_deps_debian=({{.MakeDependsString}}) | ||||||
|  | build_deps_altlinux=({{.MakeDependsString}}) | ||||||
|  | build_deps_alpine=({{.MakeDependsString}}){{end}} | ||||||
|  |  | ||||||
|  | {{if .OptDependsString}}# Опциональные зависимости | ||||||
|  | opt_deps=( | ||||||
|  | 	{{.OptDependsString}} | ||||||
|  | ){{end}} | ||||||
|  |  | ||||||
|  | # Источники из PKGBUILD | ||||||
|  | sources=({{range .Sources}}"{{.}}" {{end}}) | ||||||
|  | checksums=({{range .Checksums}}'{{.}}' {{end}}) | ||||||
|  |  | ||||||
|  | {{if .HasVersion}}# Функция версии для Git-пакетов | ||||||
|  | version() { | ||||||
|  | 	cd "$srcdir/{{.Name}}" | ||||||
|  | 	git-version | ||||||
|  | } | ||||||
|  | {{end}} | ||||||
|  |  | ||||||
|  | {{if .ScriptsString}}# Дополнительные скрипты | ||||||
|  | scripts=( | ||||||
|  | 	{{.ScriptsString}} | ||||||
|  | ){{end}} | ||||||
|  |  | ||||||
|  | {{if or .PrepareFunc .HasPatches}}prepare() { | ||||||
|  | 	cd "$srcdir"{{if .PrepareFunc}} | ||||||
|  | 	# Из PKGBUILD: | ||||||
|  | 	{{.PrepareFunc}}{{else}} | ||||||
|  | 	# Применение патчей и подготовка исходников | ||||||
|  | 	# Раскомментируйте и адаптируйте при необходимости: | ||||||
|  | 	# patch -p1 < "${scriptdir}/fix.patch"{{end}} | ||||||
|  | }{{else}}# prepare() { | ||||||
|  | # 	cd "$srcdir" | ||||||
|  | # 	# Применение патчей и подготовка исходников при необходимости | ||||||
|  | # 	# patch -p1 < "${scriptdir}/fix.patch" | ||||||
|  | # }{{end}} | ||||||
|  |  | ||||||
|  | {{if ne .PackageType "bin"}}build() { | ||||||
|  | 	cd "$srcdir"{{if .BuildFunc}} | ||||||
|  | 	# Из PKGBUILD: | ||||||
|  | 	{{.BuildFunc}}{{else}} | ||||||
|  | 	 | ||||||
|  | 	# TODO: Адаптируйте команды сборки под конкретный проект ({{.PackageType}}) | ||||||
|  | 	{{if eq .PackageType "meson"}}# Для Meson проектов: | ||||||
|  | 	meson setup build --prefix=/usr --buildtype=release | ||||||
|  | 	ninja -C build -j $(nproc){{else if eq .PackageType "cpp"}}# Для C/C++ проектов: | ||||||
|  | 	mkdir -p build && cd build | ||||||
|  | 	cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr | ||||||
|  | 	make -j$(nproc){{else if eq .PackageType "go"}}# Для Go проектов: | ||||||
|  | 	go build -buildmode=pie -trimpath -ldflags "-s -w" -o {{.Name}}{{else if eq .PackageType "python"}}# Для Python проектов: | ||||||
|  | 	python -m build --wheel --no-isolation{{else if eq .PackageType "nodejs"}}# Для Node.js проектов: | ||||||
|  | 	npm ci --production | ||||||
|  | 	npm run build{{else if eq .PackageType "rust"}}# Для Rust проектов: | ||||||
|  | 	cargo build --release --locked{{else if eq .PackageType "git"}}# Для Git проектов (обычно исходный код): | ||||||
|  | 	make -j$(nproc){{else}}# Стандартная сборка: | ||||||
|  | 	make -j$(nproc){{end}}{{end}} | ||||||
|  | }{{else}}# Бинарный пакет - сборка не требуется{{end}} | ||||||
|  |  | ||||||
|  | package() { | ||||||
|  | 	cd "$srcdir"{{if .PackageFunc}} | ||||||
|  | 	# Из PKGBUILD (адаптировано для ALR): | ||||||
|  | 	{{.PackageFunc}} | ||||||
|  | 	 | ||||||
|  | 	# Автоматически сгенерированные команды установки: | ||||||
|  | {{.GenerateInstallCommands}}{{else}} | ||||||
|  | 	 | ||||||
|  | 	# TODO: Адаптируйте установку файлов под конкретный проект {{.Name}} | ||||||
|  | 	{{if eq .PackageType "meson"}}# Для Meson проектов: | ||||||
|  | 	meson install -C build --destdir="$pkgdir"{{else if eq .PackageType "cpp"}}# Для C/C++ проектов: | ||||||
|  | 	cd build | ||||||
|  | 	make DESTDIR="$pkgdir" install{{else if eq .PackageType "go"}}# Для Go проектов: | ||||||
|  | 	# Исполняемый файл уже собран в корне{{else if eq .PackageType "python"}}# Для Python проектов: | ||||||
|  | 	pip install --root="$pkgdir/" . --no-deps --disable-pip-version-check{{else if eq .PackageType "nodejs"}}# Для Node.js проектов: | ||||||
|  | 	npm install -g --prefix="$pkgdir/usr" .{{else if eq .PackageType "rust"}}# Для Rust проектов: | ||||||
|  | 	# Исполняемый файл в target/release/{{else if eq .PackageType "bin"}}# Бинарный пакет: | ||||||
|  | 	# Файлы уже распакованы{{else}}# Стандартная установка: | ||||||
|  | 	make DESTDIR="$pkgdir" install{{end}} | ||||||
|  | 	 | ||||||
|  | 	# Автоматически сгенерированные команды установки: | ||||||
|  | {{.GenerateInstallCommands}}{{end}} | ||||||
|  | } | ||||||
| @@ -1,19 +1,3 @@ | |||||||
| // ALR - Any Linux Repository |  | ||||||
| // Copyright (C) 2025 The ALR Authors |  | ||||||
| // |  | ||||||
| // This program is free software: you can redistribute it and/or modify |  | ||||||
| // it under the terms of the GNU General Public License as published by |  | ||||||
| // the Free Software Foundation, either version 3 of the License, or |  | ||||||
| // (at your option) any later version. |  | ||||||
| // |  | ||||||
| // This program is distributed in the hope that it will be useful, |  | ||||||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the |  | ||||||
| // GNU General Public License for more details. |  | ||||||
| // |  | ||||||
| // You should have received a copy of the GNU General Public License |  | ||||||
| // along with this program.  If not, see <http://www.gnu.org/licenses/>. |  | ||||||
|  |  | ||||||
| // DO NOT EDIT MANUALLY. This file is generated. | // DO NOT EDIT MANUALLY. This file is generated. | ||||||
| package alrsh | package alrsh | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user