feat: add files() function
also add files-find-lang and files-find-doc helpers
This commit is contained in:
@ -156,7 +156,7 @@ func BuildPackage(ctx context.Context, opts types.BuildOpts) ([]string, []string
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
err = executeFunctions(ctx, dec, dirs, vars) // Выполняем специальные функции
|
||||
funcOut, err := executeFunctions(ctx, dec, dirs, vars) // Выполняем специальные функции
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@ -165,7 +165,7 @@ func BuildPackage(ctx context.Context, opts types.BuildOpts) ([]string, []string
|
||||
|
||||
pkgFormat := getPkgFormat(opts.Manager) // Получаем формат пакета
|
||||
|
||||
pkgInfo, err := buildPkgMetadata(ctx, vars, dirs, pkgFormat, info, append(repoDeps, builtNames...)) // Собираем метаданные пакета
|
||||
pkgInfo, err := buildPkgMetadata(ctx, vars, dirs, pkgFormat, info, append(repoDeps, builtNames...), funcOut.Contents) // Собираем метаданные пакета
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@ -428,40 +428,44 @@ func buildALRDeps(ctx context.Context, opts types.BuildOpts, vars *types.BuildVa
|
||||
return builtPaths, builtNames, repoDeps, nil
|
||||
}
|
||||
|
||||
type FunctionsOutput struct {
|
||||
Contents *[]string
|
||||
}
|
||||
|
||||
// Функция executeFunctions выполняет специальные функции ALR, такие как version(), prepare() и т.д.
|
||||
func executeFunctions(ctx context.Context, dec *decoder.Decoder, dirs types.Directories, vars *types.BuildVars) (err error) {
|
||||
func executeFunctions(ctx context.Context, dec *decoder.Decoder, dirs types.Directories, vars *types.BuildVars) (*FunctionsOutput, error) {
|
||||
version, ok := dec.GetFunc("version")
|
||||
if ok {
|
||||
slog.Info(gotext.Get("Executing version()"))
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
|
||||
err = version(
|
||||
err := version(
|
||||
ctx,
|
||||
interp.Dir(dirs.SrcDir),
|
||||
interp.StdIO(os.Stdin, buf, os.Stderr),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
newVer := strings.TrimSpace(buf.String())
|
||||
err = setVersion(ctx, dec.Runner, newVer)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
vars.Version = newVer
|
||||
|
||||
slog.Info("Updating version", "new", newVer)
|
||||
slog.Info(gotext.Get("Updating version"), "new", newVer)
|
||||
}
|
||||
|
||||
prepare, ok := dec.GetFunc("prepare")
|
||||
if ok {
|
||||
slog.Info(gotext.Get("Executing prepare()"))
|
||||
|
||||
err = prepare(ctx, interp.Dir(dirs.SrcDir))
|
||||
err := prepare(ctx, interp.Dir(dirs.SrcDir))
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
@ -469,9 +473,9 @@ func executeFunctions(ctx context.Context, dec *decoder.Decoder, dirs types.Dire
|
||||
if ok {
|
||||
slog.Info(gotext.Get("Executing build()"))
|
||||
|
||||
err = build(ctx, interp.Dir(dirs.SrcDir))
|
||||
err := build(ctx, interp.Dir(dirs.SrcDir))
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
@ -480,9 +484,9 @@ func executeFunctions(ctx context.Context, dec *decoder.Decoder, dirs types.Dire
|
||||
packageFn, ok := dec.GetFunc("package")
|
||||
if ok {
|
||||
slog.Info(gotext.Get("Executing package()"))
|
||||
err = packageFn(ctx, interp.Dir(dirs.SrcDir))
|
||||
err := packageFn(ctx, interp.Dir(dirs.SrcDir))
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
@ -502,11 +506,51 @@ func executeFunctions(ctx context.Context, dec *decoder.Decoder, dirs types.Dire
|
||||
break
|
||||
}
|
||||
|
||||
return nil
|
||||
output := &FunctionsOutput{}
|
||||
|
||||
files, ok := dec.GetFuncP("files", func(ctx context.Context, s *interp.Runner) error {
|
||||
// It should be done via interp.RunnerOption,
|
||||
// but due to the issues below, it cannot be done.
|
||||
// - https://github.com/mvdan/sh/issues/962
|
||||
// - https://github.com/mvdan/sh/issues/1125
|
||||
script, err := syntax.NewParser().Parse(strings.NewReader("cd $pkgdir && shopt -s globstar"), "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return s.Run(ctx, script)
|
||||
})
|
||||
|
||||
if ok {
|
||||
slog.Info(gotext.Get("Executing files()"))
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
|
||||
err := files(
|
||||
ctx,
|
||||
interp.Dir(dirs.PkgDir),
|
||||
interp.StdIO(os.Stdin, buf, os.Stderr),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
contents := strings.Fields(strings.TrimSpace(buf.String()))
|
||||
output.Contents = &contents
|
||||
}
|
||||
|
||||
return output, nil
|
||||
}
|
||||
|
||||
// Функция buildPkgMetadata создает метаданные для пакета, который будет собран.
|
||||
func buildPkgMetadata(ctx context.Context, 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,
|
||||
preferedContents *[]string,
|
||||
) (*nfpm.Info, error) {
|
||||
pkgInfo := getBasePkgInfo(vars)
|
||||
pkgInfo.Description = vars.Description
|
||||
pkgInfo.Platform = "linux"
|
||||
@ -541,7 +585,7 @@ func buildPkgMetadata(ctx context.Context, vars *types.BuildVars, dirs types.Dir
|
||||
pkgInfo.Arch = "all"
|
||||
}
|
||||
|
||||
contents, err := buildContents(vars, dirs)
|
||||
contents, err := buildContents(vars, dirs, preferedContents)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -574,21 +618,27 @@ func buildPkgMetadata(ctx context.Context, vars *types.BuildVars, dirs types.Dir
|
||||
|
||||
// Функция buildContents создает секцию содержимого пакета, которая содержит файлы,
|
||||
// которые будут включены в конечный пакет.
|
||||
func buildContents(vars *types.BuildVars, dirs types.Directories) ([]*files.Content, error) {
|
||||
func buildContents(vars *types.BuildVars, dirs types.Directories, preferedContents *[]string) ([]*files.Content, error) {
|
||||
contents := []*files.Content{}
|
||||
err := filepath.Walk(dirs.PkgDir, func(path string, fi os.FileInfo, err error) error {
|
||||
trimmed := strings.TrimPrefix(path, dirs.PkgDir)
|
||||
|
||||
processPath := func(path, trimmed string, prefered bool) error {
|
||||
fi, err := os.Lstat(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if fi.IsDir() {
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
// Если директория пустая, пропускаем её
|
||||
_, err = f.Readdirnames(1)
|
||||
if err != io.EOF {
|
||||
return nil
|
||||
if !prefered {
|
||||
_, err = f.Readdirnames(1)
|
||||
if err != io.EOF {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
contents = append(contents, &files.Content{
|
||||
@ -599,16 +649,14 @@ func buildContents(vars *types.BuildVars, dirs types.Directories) ([]*files.Cont
|
||||
MTime: fi.ModTime(),
|
||||
},
|
||||
})
|
||||
|
||||
return f.Close()
|
||||
return nil
|
||||
}
|
||||
// Если файл является символической ссылкой, прорабатываем это
|
||||
|
||||
if fi.Mode()&os.ModeSymlink != 0 {
|
||||
link, err := os.Readlink(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Удаляем pkgdir из пути символической ссылки
|
||||
link = strings.TrimPrefix(link, dirs.PkgDir)
|
||||
|
||||
contents = append(contents, &files.Content{
|
||||
@ -620,10 +668,9 @@ func buildContents(vars *types.BuildVars, dirs types.Directories) ([]*files.Cont
|
||||
Mode: fi.Mode(),
|
||||
},
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
// Обрабатываем обычные файлы
|
||||
|
||||
fileContent := &files.Content{
|
||||
Source: path,
|
||||
Destination: trimmed,
|
||||
@ -634,16 +681,35 @@ func buildContents(vars *types.BuildVars, dirs types.Directories) ([]*files.Cont
|
||||
},
|
||||
}
|
||||
|
||||
// Если файл должен быть сохранен, установите его тип как config|noreplace
|
||||
if slices.Contains(vars.Backup, trimmed) {
|
||||
fileContent.Type = "config|noreplace"
|
||||
}
|
||||
|
||||
contents = append(contents, fileContent)
|
||||
|
||||
return nil
|
||||
})
|
||||
return contents, err
|
||||
}
|
||||
|
||||
if preferedContents != nil {
|
||||
for _, trimmed := range *preferedContents {
|
||||
path := filepath.Join(dirs.PkgDir, trimmed)
|
||||
if err := processPath(path, trimmed, true); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
err := filepath.Walk(dirs.PkgDir, func(path string, fi os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
trimmed := strings.TrimPrefix(path, dirs.PkgDir)
|
||||
return processPath(path, trimmed, false)
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return contents, nil
|
||||
}
|
||||
|
||||
// Функция removeBuildDeps спрашивает у пользователя, хочет ли он удалить зависимости,
|
||||
|
Reference in New Issue
Block a user