forked from Plemya-x/ALR
		
	feat: add find-provides and find-requires (rpm only)
This commit is contained in:
		@@ -41,7 +41,7 @@ import (
 | 
				
			|||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Импортируем пакеты для поддержки различных форматов пакетов (APK, DEB, RPM и ARCH).
 | 
						// Импортируем пакеты для поддержки различных форматов пакетов (APK, DEB, RPM и ARCH).
 | 
				
			||||||
	_ "github.com/goreleaser/nfpm/v2/apk"
 | 
						_ "github.com/goreleaser/nfpm/v2/apk"
 | 
				
			||||||
	_ "github.com/goreleaser/nfpm/v2/arch"
 | 
						_ "github.com/goreleaser/nfpm/v2/arch"
 | 
				
			||||||
	_ "github.com/goreleaser/nfpm/v2/deb"
 | 
						_ "github.com/goreleaser/nfpm/v2/deb"
 | 
				
			||||||
@@ -82,8 +82,8 @@ func BuildPackage(ctx context.Context, opts types.BuildOpts) ([]string, []string
 | 
				
			|||||||
		return nil, nil, err
 | 
							return nil, nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Первый проход предназначен для получения значений переменных и выполняется
 | 
						// Первый проход предназначен для получения значений переменных и выполняется
 | 
				
			||||||
    // до отображения скрипта, чтобы предотвратить выполнение вредоносного кода.
 | 
						// до отображения скрипта, чтобы предотвратить выполнение вредоносного кода.
 | 
				
			||||||
	vars, err := executeFirstPass(ctx, info, fl, opts.Script)
 | 
						vars, err := executeFirstPass(ctx, info, fl, opts.Script)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, nil, err
 | 
							return nil, nil, err
 | 
				
			||||||
@@ -91,8 +91,8 @@ func BuildPackage(ctx context.Context, opts types.BuildOpts) ([]string, []string
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	dirs := getDirs(ctx, vars, opts.Script)
 | 
						dirs := getDirs(ctx, vars, opts.Script)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Если флаг opts.Clean не установлен, и пакет уже собран,
 | 
						// Если флаг opts.Clean не установлен, и пакет уже собран,
 | 
				
			||||||
    // возвращаем его, а не собираем заново.
 | 
						// возвращаем его, а не собираем заново.
 | 
				
			||||||
	if !opts.Clean {
 | 
						if !opts.Clean {
 | 
				
			||||||
		builtPkgPath, ok, err := checkForBuiltPackage(opts.Manager, vars, getPkgFormat(opts.Manager), dirs.BaseDir)
 | 
							builtPkgPath, ok, err := checkForBuiltPackage(opts.Manager, vars, getPkgFormat(opts.Manager), dirs.BaseDir)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
@@ -104,7 +104,7 @@ func BuildPackage(ctx context.Context, opts types.BuildOpts) ([]string, []string
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Спрашиваем у пользователя, хочет ли он увидеть скрипт сборки.
 | 
						// Спрашиваем у пользователя, хочет ли он увидеть скрипт сборки.
 | 
				
			||||||
	err = cliutils.PromptViewScript(ctx, opts.Script, vars.Name, config.Config(ctx).PagerStyle, opts.Interactive)
 | 
						err = cliutils.PromptViewScript(ctx, opts.Script, vars.Name, config.Config(ctx).PagerStyle, opts.Interactive)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		log.Fatal("Failed to prompt user to view build script").Err(err).Send()
 | 
							log.Fatal("Failed to prompt user to view build script").Err(err).Send()
 | 
				
			||||||
@@ -112,9 +112,9 @@ func BuildPackage(ctx context.Context, opts types.BuildOpts) ([]string, []string
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	log.Info("Building package").Str("name", vars.Name).Str("version", vars.Version).Send()
 | 
						log.Info("Building package").Str("name", vars.Name).Str("version", vars.Version).Send()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Второй проход будет использоваться для выполнения реального кода,
 | 
						// Второй проход будет использоваться для выполнения реального кода,
 | 
				
			||||||
    // поэтому он не ограничен. Скрипт уже был показан
 | 
						// поэтому он не ограничен. Скрипт уже был показан
 | 
				
			||||||
    // пользователю к этому моменту, так что это должно быть безопасно.
 | 
						// пользователю к этому моменту, так что это должно быть безопасно.
 | 
				
			||||||
	dec, err := executeSecondPass(ctx, info, fl, dirs)
 | 
						dec, err := executeSecondPass(ctx, info, fl, dirs)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, nil, err
 | 
							return nil, nil, err
 | 
				
			||||||
@@ -133,7 +133,7 @@ func BuildPackage(ctx context.Context, opts types.BuildOpts) ([]string, []string
 | 
				
			|||||||
		os.Exit(1) // Если проверки не пройдены, выходим из программы
 | 
							os.Exit(1) // Если проверки не пройдены, выходим из программы
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Подготавливаем директории для сборки
 | 
						// Подготавливаем директории для сборки
 | 
				
			||||||
	err = prepareDirs(dirs)
 | 
						err = prepareDirs(dirs)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, nil, err
 | 
							return nil, nil, err
 | 
				
			||||||
@@ -170,7 +170,7 @@ func BuildPackage(ctx context.Context, opts types.BuildOpts) ([]string, []string
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	pkgFormat := getPkgFormat(opts.Manager) // Получаем формат пакета
 | 
						pkgFormat := getPkgFormat(opts.Manager) // Получаем формат пакета
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pkgInfo, err := buildPkgMetadata(vars, dirs, pkgFormat, info, append(repoDeps, builtNames...)) // Собираем метаданные пакета
 | 
						pkgInfo, err := buildPkgMetadata(ctx, vars, dirs, pkgFormat, info, append(repoDeps, builtNames...)) // Собираем метаданные пакета
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, nil, err
 | 
							return nil, nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -181,7 +181,7 @@ func BuildPackage(ctx context.Context, opts types.BuildOpts) ([]string, []string
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pkgName := packager.ConventionalFileName(pkgInfo) // Получаем имя файла пакета
 | 
						pkgName := packager.ConventionalFileName(pkgInfo) // Получаем имя файла пакета
 | 
				
			||||||
	pkgPath := filepath.Join(dirs.BaseDir, pkgName) // Определяем путь к пакету
 | 
						pkgPath := filepath.Join(dirs.BaseDir, pkgName)   // Определяем путь к пакету
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pkgFile, err := os.Create(pkgPath) // Создаём файл пакета
 | 
						pkgFile, err := os.Create(pkgPath) // Создаём файл пакета
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
@@ -200,14 +200,14 @@ func BuildPackage(ctx context.Context, opts types.BuildOpts) ([]string, []string
 | 
				
			|||||||
		return nil, nil, err
 | 
							return nil, nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Добавляем путь и имя только что собранного пакета в
 | 
						// Добавляем путь и имя только что собранного пакета в
 | 
				
			||||||
    // соответствующие срезы
 | 
						// соответствующие срезы
 | 
				
			||||||
	pkgPaths := append(builtPaths, pkgPath)
 | 
						pkgPaths := append(builtPaths, pkgPath)
 | 
				
			||||||
	pkgNames := append(builtNames, vars.Name)
 | 
						pkgNames := append(builtNames, vars.Name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Удаляем дубликаты из pkgPaths и pkgNames.
 | 
						// Удаляем дубликаты из pkgPaths и pkgNames.
 | 
				
			||||||
    // Дубликаты могут появиться, если несколько зависимостей
 | 
						// Дубликаты могут появиться, если несколько зависимостей
 | 
				
			||||||
    // зависят от одних и тех же пакетов.
 | 
						// зависят от одних и тех же пакетов.
 | 
				
			||||||
	pkgPaths = removeDuplicates(pkgPaths)
 | 
						pkgPaths = removeDuplicates(pkgPaths)
 | 
				
			||||||
	pkgNames = removeDuplicates(pkgNames)
 | 
						pkgNames = removeDuplicates(pkgNames)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -233,16 +233,16 @@ func parseScript(info *distro.OSRelease, script string) (*syntax.File, error) {
 | 
				
			|||||||
// Функция executeFirstPass выполняет парсированный скрипт в ограниченной среде,
 | 
					// Функция executeFirstPass выполняет парсированный скрипт в ограниченной среде,
 | 
				
			||||||
// чтобы извлечь переменные сборки без выполнения реального кода.
 | 
					// чтобы извлечь переменные сборки без выполнения реального кода.
 | 
				
			||||||
func executeFirstPass(ctx context.Context, info *distro.OSRelease, fl *syntax.File, script string) (*types.BuildVars, error) {
 | 
					func executeFirstPass(ctx context.Context, info *distro.OSRelease, fl *syntax.File, script string) (*types.BuildVars, error) {
 | 
				
			||||||
	scriptDir := filepath.Dir(script) // Получаем директорию скрипта
 | 
						scriptDir := filepath.Dir(script)                                        // Получаем директорию скрипта
 | 
				
			||||||
	env := createBuildEnvVars(info, types.Directories{ScriptDir: scriptDir}) // Создаём переменные окружения для сборки
 | 
						env := createBuildEnvVars(info, types.Directories{ScriptDir: scriptDir}) // Создаём переменные окружения для сборки
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	runner, err := interp.New(
 | 
						runner, err := interp.New(
 | 
				
			||||||
		interp.Env(expand.ListEnviron(env...)), // Устанавливаем окружение
 | 
							interp.Env(expand.ListEnviron(env...)),                               // Устанавливаем окружение
 | 
				
			||||||
		interp.StdIO(os.Stdin, os.Stdout, os.Stderr), // Устанавливаем стандартный ввод-вывод
 | 
							interp.StdIO(os.Stdin, os.Stdout, os.Stderr),                         // Устанавливаем стандартный ввод-вывод
 | 
				
			||||||
		interp.ExecHandler(helpers.Restricted.ExecHandler(handlers.NopExec)), // Ограничиваем выполнение
 | 
							interp.ExecHandler(helpers.Restricted.ExecHandler(handlers.NopExec)), // Ограничиваем выполнение
 | 
				
			||||||
		interp.ReadDirHandler(handlers.RestrictedReadDir(scriptDir)), // Ограничиваем чтение директорий
 | 
							interp.ReadDirHandler(handlers.RestrictedReadDir(scriptDir)),         // Ограничиваем чтение директорий
 | 
				
			||||||
		interp.StatHandler(handlers.RestrictedStat(scriptDir)), // Ограничиваем доступ к статистике файлов
 | 
							interp.StatHandler(handlers.RestrictedStat(scriptDir)),               // Ограничиваем доступ к статистике файлов
 | 
				
			||||||
		interp.OpenHandler(handlers.RestrictedOpen(scriptDir)), // Ограничиваем открытие файлов
 | 
							interp.OpenHandler(handlers.RestrictedOpen(scriptDir)),               // Ограничиваем открытие файлов
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
@@ -282,8 +282,8 @@ func executeSecondPass(ctx context.Context, info *distro.OSRelease, fl *syntax.F
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	fakeroot := handlers.FakerootExecHandler(2 * time.Second) // Настраиваем "fakeroot" для выполнения
 | 
						fakeroot := handlers.FakerootExecHandler(2 * time.Second) // Настраиваем "fakeroot" для выполнения
 | 
				
			||||||
	runner, err := interp.New(
 | 
						runner, err := interp.New(
 | 
				
			||||||
		interp.Env(expand.ListEnviron(env...)), // Устанавливаем окружение
 | 
							interp.Env(expand.ListEnviron(env...)),                    // Устанавливаем окружение
 | 
				
			||||||
		interp.StdIO(os.Stdin, os.Stdout, os.Stderr), // Устанавливаем стандартный ввод-вывод
 | 
							interp.StdIO(os.Stdin, os.Stdout, os.Stderr),              // Устанавливаем стандартный ввод-вывод
 | 
				
			||||||
		interp.ExecHandler(helpers.Helpers.ExecHandler(fakeroot)), // Обрабатываем выполнение через fakeroot
 | 
							interp.ExecHandler(helpers.Helpers.ExecHandler(fakeroot)), // Обрабатываем выполнение через fakeroot
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
@@ -396,30 +396,30 @@ func buildALRDeps(ctx context.Context, opts types.BuildOpts, vars *types.BuildVa
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		repoDeps = notFound
 | 
							repoDeps = notFound
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Если для некоторых пакетов есть несколько опций, упрощаем их все в один срез
 | 
							// Если для некоторых пакетов есть несколько опций, упрощаем их все в один срез
 | 
				
			||||||
		pkgs := cliutils.FlattenPkgs(ctx, found, "install", opts.Interactive)
 | 
							pkgs := cliutils.FlattenPkgs(ctx, found, "install", opts.Interactive)
 | 
				
			||||||
		scripts := GetScriptPaths(ctx, pkgs)
 | 
							scripts := GetScriptPaths(ctx, pkgs)
 | 
				
			||||||
		for _, script := range scripts {
 | 
							for _, script := range scripts {
 | 
				
			||||||
			newOpts := opts
 | 
								newOpts := opts
 | 
				
			||||||
			newOpts.Script = script
 | 
								newOpts.Script = script
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Собираем зависимости
 | 
								// Собираем зависимости
 | 
				
			||||||
			pkgPaths, pkgNames, err := BuildPackage(ctx, newOpts)
 | 
								pkgPaths, pkgNames, err := BuildPackage(ctx, newOpts)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				return nil, nil, nil, err
 | 
									return nil, nil, nil, err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Добавляем пути всех собранных пакетов в builtPaths
 | 
								// Добавляем пути всех собранных пакетов в builtPaths
 | 
				
			||||||
			builtPaths = append(builtPaths, pkgPaths...)
 | 
								builtPaths = append(builtPaths, pkgPaths...)
 | 
				
			||||||
            // Добавляем пути всех собранных пакетов в builtPaths
 | 
								// Добавляем пути всех собранных пакетов в builtPaths
 | 
				
			||||||
			builtNames = append(builtNames, pkgNames...)
 | 
								builtNames = append(builtNames, pkgNames...)
 | 
				
			||||||
            // Добавляем имя текущего пакета в builtNames
 | 
								// Добавляем имя текущего пакета в builtNames
 | 
				
			||||||
			builtNames = append(builtNames, filepath.Base(filepath.Dir(script)))
 | 
								builtNames = append(builtNames, filepath.Base(filepath.Dir(script)))
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Удаляем возможные дубликаты, которые могут быть введены, если
 | 
						// Удаляем возможные дубликаты, которые могут быть введены, если
 | 
				
			||||||
    // несколько зависимостей зависят от одних и тех же пакетов.
 | 
						// несколько зависимостей зависят от одних и тех же пакетов.
 | 
				
			||||||
	repoDeps = removeDuplicates(repoDeps)
 | 
						repoDeps = removeDuplicates(repoDeps)
 | 
				
			||||||
	builtPaths = removeDuplicates(builtPaths)
 | 
						builtPaths = removeDuplicates(builtPaths)
 | 
				
			||||||
	builtNames = removeDuplicates(builtNames)
 | 
						builtNames = removeDuplicates(builtNames)
 | 
				
			||||||
@@ -474,35 +474,35 @@ func executeFunctions(ctx context.Context, dec *decoder.Decoder, dirs types.Dire
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Выполнение всех функций, начинающихся с package_
 | 
						// Выполнение всех функций, начинающихся с package_
 | 
				
			||||||
    for {
 | 
						for {
 | 
				
			||||||
        packageFn, ok := dec.GetFunc("package")
 | 
							packageFn, ok := dec.GetFunc("package")
 | 
				
			||||||
        if ok {
 | 
							if ok {
 | 
				
			||||||
            log.Info("Executing package()").Send()
 | 
								log.Info("Executing package()").Send()
 | 
				
			||||||
            err = packageFn(ctx, interp.Dir(dirs.SrcDir))
 | 
								err = packageFn(ctx, interp.Dir(dirs.SrcDir))
 | 
				
			||||||
            if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
                return err
 | 
									return err
 | 
				
			||||||
            }
 | 
								}
 | 
				
			||||||
        }
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Проверка на наличие дополнительных функций package_*
 | 
							// Проверка на наличие дополнительных функций package_*
 | 
				
			||||||
        packageFuncName := "package_"
 | 
							packageFuncName := "package_"
 | 
				
			||||||
        if packageFunc, ok := dec.GetFunc(packageFuncName); ok {
 | 
							if packageFunc, ok := dec.GetFunc(packageFuncName); ok {
 | 
				
			||||||
            log.Info("Executing " + packageFuncName).Send()
 | 
								log.Info("Executing " + packageFuncName).Send()
 | 
				
			||||||
            err = packageFunc(ctx, interp.Dir(dirs.SrcDir))
 | 
								err = packageFunc(ctx, interp.Dir(dirs.SrcDir))
 | 
				
			||||||
            if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
                return err
 | 
									return err
 | 
				
			||||||
            }
 | 
								}
 | 
				
			||||||
        } else {
 | 
							} else {
 | 
				
			||||||
            break // Если больше нет функций package_*, выходим из цикла
 | 
								break // Если больше нет функций package_*, выходим из цикла
 | 
				
			||||||
        }
 | 
							}
 | 
				
			||||||
    }
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Функция buildPkgMetadata создает метаданные для пакета, который будет собран.
 | 
					// Функция buildPkgMetadata создает метаданные для пакета, который будет собран.
 | 
				
			||||||
func buildPkgMetadata(vars *types.BuildVars, dirs types.Directories, pkgFormat string, info *distro.OSRelease, deps []string) (*nfpm.Info, error) {
 | 
					func buildPkgMetadata(ctx context.Context, vars *types.BuildVars, dirs types.Directories, pkgFormat string, info *distro.OSRelease, deps []string) (*nfpm.Info, error) {
 | 
				
			||||||
	pkgInfo := getBasePkgInfo(vars)
 | 
						pkgInfo := getBasePkgInfo(vars)
 | 
				
			||||||
	pkgInfo.Description = vars.Description
 | 
						pkgInfo.Description = vars.Description
 | 
				
			||||||
	pkgInfo.Platform = "linux"
 | 
						pkgInfo.Platform = "linux"
 | 
				
			||||||
@@ -517,7 +517,7 @@ func buildPkgMetadata(vars *types.BuildVars, dirs types.Directories, pkgFormat s
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if pkgFormat == "apk" {
 | 
						if pkgFormat == "apk" {
 | 
				
			||||||
        // Alpine отказывается устанавливать пакеты, которые предоставляют сами себя, поэтому удаляем такие элементы
 | 
							// Alpine отказывается устанавливать пакеты, которые предоставляют сами себя, поэтому удаляем такие элементы
 | 
				
			||||||
		pkgInfo.Overridables.Provides = slices.DeleteFunc(pkgInfo.Overridables.Provides, func(s string) bool {
 | 
							pkgInfo.Overridables.Provides = slices.DeleteFunc(pkgInfo.Overridables.Provides, func(s string) bool {
 | 
				
			||||||
			return s == pkgInfo.Name
 | 
								return s == pkgInfo.Name
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
@@ -543,6 +543,17 @@ func buildPkgMetadata(vars *types.BuildVars, dirs types.Directories, pkgFormat s
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	pkgInfo.Overridables.Contents = contents
 | 
						pkgInfo.Overridables.Contents = contents
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if pkgFormat == "rpm" {
 | 
				
			||||||
 | 
							err = rpmFindProvides(ctx, pkgInfo, dirs)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							err = rpmFindRequires(ctx, pkgInfo, dirs)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return pkgInfo, nil
 | 
						return pkgInfo, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -559,7 +570,7 @@ func buildContents(vars *types.BuildVars, dirs types.Directories) ([]*files.Cont
 | 
				
			|||||||
				return err
 | 
									return err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Если директория пустая, пропускаем её
 | 
								// Если директория пустая, пропускаем её
 | 
				
			||||||
			_, err = f.Readdirnames(1)
 | 
								_, err = f.Readdirnames(1)
 | 
				
			||||||
			if err != io.EOF {
 | 
								if err != io.EOF {
 | 
				
			||||||
				return nil
 | 
									return nil
 | 
				
			||||||
@@ -576,13 +587,13 @@ func buildContents(vars *types.BuildVars, dirs types.Directories) ([]*files.Cont
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			return f.Close()
 | 
								return f.Close()
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
        // Если файл является символической ссылкой, прорабатываем это
 | 
							// Если файл является символической ссылкой, прорабатываем это
 | 
				
			||||||
		if fi.Mode()&os.ModeSymlink != 0 {
 | 
							if fi.Mode()&os.ModeSymlink != 0 {
 | 
				
			||||||
			link, err := os.Readlink(path)
 | 
								link, err := os.Readlink(path)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				return err
 | 
									return err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
            // Удаляем pkgdir из пути символической ссылки
 | 
								// Удаляем pkgdir из пути символической ссылки
 | 
				
			||||||
			link = strings.TrimPrefix(link, dirs.PkgDir)
 | 
								link = strings.TrimPrefix(link, dirs.PkgDir)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			contents = append(contents, &files.Content{
 | 
								contents = append(contents, &files.Content{
 | 
				
			||||||
@@ -597,7 +608,7 @@ func buildContents(vars *types.BuildVars, dirs types.Directories) ([]*files.Cont
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			return nil
 | 
								return nil
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
        // Обрабатываем обычные файлы
 | 
							// Обрабатываем обычные файлы
 | 
				
			||||||
		fileContent := &files.Content{
 | 
							fileContent := &files.Content{
 | 
				
			||||||
			Source:      path,
 | 
								Source:      path,
 | 
				
			||||||
			Destination: trimmed,
 | 
								Destination: trimmed,
 | 
				
			||||||
@@ -608,7 +619,7 @@ func buildContents(vars *types.BuildVars, dirs types.Directories) ([]*files.Cont
 | 
				
			|||||||
			},
 | 
								},
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Если файл должен быть сохранен, установите его тип как config|noreplace
 | 
							// Если файл должен быть сохранен, установите его тип как config|noreplace
 | 
				
			||||||
		if slices.Contains(vars.Backup, trimmed) {
 | 
							if slices.Contains(vars.Backup, trimmed) {
 | 
				
			||||||
			fileContent.Type = "config|noreplace"
 | 
								fileContent.Type = "config|noreplace"
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -744,9 +755,9 @@ func getSources(ctx context.Context, dirs types.Directories, bv *types.BuildVars
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if !strings.EqualFold(bv.Checksums[i], "SKIP") {
 | 
							if !strings.EqualFold(bv.Checksums[i], "SKIP") {
 | 
				
			||||||
            // Если контрольная сумма содержит двоеточие, используйте часть до двоеточия
 | 
								// Если контрольная сумма содержит двоеточие, используйте часть до двоеточия
 | 
				
			||||||
            // как алгоритм, а часть после как фактическую контрольную сумму.
 | 
								// как алгоритм, а часть после как фактическую контрольную сумму.
 | 
				
			||||||
            // В противном случае используйте sha256 по умолчанию с целой строкой как контрольной суммой.
 | 
								// В противном случае используйте sha256 по умолчанию с целой строкой как контрольной суммой.
 | 
				
			||||||
			algo, hashData, ok := strings.Cut(bv.Checksums[i], ":")
 | 
								algo, hashData, ok := strings.Cut(bv.Checksums[i], ":")
 | 
				
			||||||
			if ok {
 | 
								if ok {
 | 
				
			||||||
				checksum, err := hex.DecodeString(hashData)
 | 
									checksum, err := hex.DecodeString(hashData)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										77
									
								
								pkg/build/findDeps.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								pkg/build/findDeps.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,77 @@
 | 
				
			|||||||
 | 
					package build
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"bytes"
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
 | 
						"os/exec"
 | 
				
			||||||
 | 
						"path"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/goreleaser/nfpm/v2"
 | 
				
			||||||
 | 
						"plemya-x.ru/alr/internal/types"
 | 
				
			||||||
 | 
						"plemya-x.ru/alr/pkg/loggerctx"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func rpmFindDependencies(ctx context.Context, pkgInfo *nfpm.Info, dirs types.Directories, command string, updateFunc func(string)) error {
 | 
				
			||||||
 | 
						log := loggerctx.From(ctx)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if _, err := exec.LookPath(command); err != nil {
 | 
				
			||||||
 | 
							log.Info("Command not found on the system").Str("command", command).Send()
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var paths []string
 | 
				
			||||||
 | 
						for _, content := range pkgInfo.Contents {
 | 
				
			||||||
 | 
							if content.Type != "dir" {
 | 
				
			||||||
 | 
								paths = append(paths,
 | 
				
			||||||
 | 
									path.Join(dirs.PkgDir, content.Destination),
 | 
				
			||||||
 | 
								)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(paths) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cmd := exec.Command(command)
 | 
				
			||||||
 | 
						cmd.Stdin = bytes.NewBufferString(strings.Join(paths, "\n"))
 | 
				
			||||||
 | 
						cmd.Env = append(cmd.Env,
 | 
				
			||||||
 | 
							"RPM_BUILD_ROOT="+dirs.PkgDir,
 | 
				
			||||||
 | 
							"RPM_FINDPROV_METHOD=",
 | 
				
			||||||
 | 
							"RPM_FINDREQ_METHOD=",
 | 
				
			||||||
 | 
							"RPM_DATADIR=",
 | 
				
			||||||
 | 
							"RPM_SUBPACKAGE_NAME=",
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
						var out bytes.Buffer
 | 
				
			||||||
 | 
						var stderr bytes.Buffer
 | 
				
			||||||
 | 
						cmd.Stdout = &out
 | 
				
			||||||
 | 
						cmd.Stderr = &stderr
 | 
				
			||||||
 | 
						if err := cmd.Run(); err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dependencies := strings.Split(strings.TrimSpace(out.String()), "\n")
 | 
				
			||||||
 | 
						for _, dep := range dependencies {
 | 
				
			||||||
 | 
							updateFunc(dep)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func rpmFindProvides(ctx context.Context, pkgInfo *nfpm.Info, dirs types.Directories) error {
 | 
				
			||||||
 | 
						log := loggerctx.From(ctx)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return rpmFindDependencies(ctx, pkgInfo, dirs, "/usr/lib/rpm/find-provides", func(dep string) {
 | 
				
			||||||
 | 
							log.Info("Provided dependency found").Str("dep", dep).Send()
 | 
				
			||||||
 | 
							pkgInfo.Overridables.Provides = append(pkgInfo.Overridables.Provides, dep)
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func rpmFindRequires(ctx context.Context, pkgInfo *nfpm.Info, dirs types.Directories) error {
 | 
				
			||||||
 | 
						log := loggerctx.From(ctx)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return rpmFindDependencies(ctx, pkgInfo, dirs, "/usr/lib/rpm/find-requires", func(dep string) {
 | 
				
			||||||
 | 
							log.Info("Required dependency found").Str("dep", dep).Send()
 | 
				
			||||||
 | 
							pkgInfo.Overridables.Depends = append(pkgInfo.Overridables.Depends, dep)
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user