From 140cd3c64be25f1a31bd442e076142897aa86a9a Mon Sep 17 00:00:00 2001 From: EnumDev Date: Wed, 10 Jun 2026 11:41:35 +0300 Subject: [PATCH] Changes in package format --- src/bpm/main.go | 6 +-- src/bpmlib/compilation.go | 63 +++++++++++++++++++------------- src/bpmlib/installed_packages.go | 47 +++++++++++++++++++----- src/bpmlib/packages.go | 18 ++++----- 4 files changed, 87 insertions(+), 47 deletions(-) diff --git a/src/bpm/main.go b/src/bpm/main.go index 4981f8c..9ef78cf 100644 --- a/src/bpm/main.go +++ b/src/bpm/main.go @@ -92,7 +92,7 @@ func main() { currentFlagSet.String("installation-reason", "", "Specify the installation reason to use for the specified packages") currentFlagSet.BoolP("reinstall", "r", false, "Reinstall the specified packages") currentFlagSet.IntP("jobs", "j", bpmlib.CompilationBPMConfig.CompilationJobs, "Set the amount of concurrent processes to use for source package compilation") - currentFlagSet.BoolP("skip-checks", "s", false, "Skip the check function in source.sh scripts") + currentFlagSet.BoolP("skip-checks", "s", false, "Skip the check function in recipe.sh scripts") setupFlagsAndHelp(currentFlagSet, fmt.Sprintf("bpm %s ", subcommand), "Install the specified packages", os.Args[2:]) installPackages() @@ -141,7 +141,7 @@ func main() { currentFlagSet.BoolP("yes", "y", false, "Enter 'yes' in all prompts") currentFlagSet.BoolP("no-sync", "n", false, "Do not sync databases") currentFlagSet.Bool("allow-downgrades", false, "Allow package downgrades") - currentFlagSet.BoolP("skip-checks", "s", false, "Skip the check function in source.sh scripts") + currentFlagSet.BoolP("skip-checks", "s", false, "Skip the check function in recipe.sh scripts") currentFlagSet.IntP("jobs", "j", bpmlib.CompilationBPMConfig.CompilationJobs, "Set the amount of concurrent processes to use for source package compilation") setupFlagsAndHelp(currentFlagSet, fmt.Sprintf("bpm %s ", subcommand), "Update installed packages", os.Args[2:]) @@ -161,7 +161,7 @@ func main() { currentFlagSet.BoolP("force", "f", false, "Bypass warnings during package compilation") currentFlagSet.BoolP("yes", "y", false, "Enter 'yes' in all prompts") currentFlagSet.BoolP("depends", "d", false, "Install required dependencies for package compilation") - currentFlagSet.BoolP("skip-checks", "s", false, "Skip the check function in source.sh scripts") + currentFlagSet.BoolP("skip-checks", "s", false, "Skip the check function in recipe.sh scripts") currentFlagSet.BoolP("keep", "k", false, "Keep compilation files after successful package compilation") currentFlagSet.BoolP("output-directory", "o", false, "Set the output directory for the binary packages") currentFlagSet.Int("output-fd", -1, "Set the file descriptor output package names will be written to") diff --git a/src/bpmlib/compilation.go b/src/bpmlib/compilation.go index 473a068..85bc2bd 100644 --- a/src/bpmlib/compilation.go +++ b/src/bpmlib/compilation.go @@ -96,8 +96,8 @@ func CompileSourcePackage(archiveFilename, outputDirectory string, compilationJo return nil, err } - // Extract source.sh file - err = extractTarballFile(archiveFilename, "source.sh", tempDirectory, uid, gid) + // Extract recipe.sh file + err = extractTarballFile(archiveFilename, "recipe.sh", tempDirectory, uid, gid) if err != nil { return nil, err } @@ -166,10 +166,10 @@ func CompileSourcePackage(archiveFilename, outputDirectory string, compilationJo env = append(env, "CMAKE_BUILD_PARALLEL_LEVEL="+strconv.Itoa(compilationJobs)) env = append(env, "CARGO_BUILD_JOBS="+strconv.Itoa(compilationJobs)) - // Execute prepare and build functions in source.sh script + // Execute prepare and build functions in recipe.sh script cmd := exec.Command("bash", "-c", - "set -a\n"+ // Source and export functions and variables in source.sh script - ". \"${BPM_WORKDIR}\"/source.sh\n"+ + "set -a\n"+ // Source and export functions and variables in recipe.sh script + ". \"${BPM_WORKDIR}\"/recipe.sh\n"+ "set +a\n"+ "[[ $(type -t prepare) == \"function\" ]] && { echo \"Running prepare() function...\"; bash -e -c 'cd \"$BPM_WORKDIR\" && prepare' || exit 1; }\n"+ // Run prepare() function if it exists "[[ $(type -t build) == \"function\" ]] && { echo \"Running build() function...\"; bash -e -c 'cd \"$BPM_SOURCE\" && build' || exit 1; }\n"+ // Run build() function if it exists @@ -187,11 +187,11 @@ func CompileSourcePackage(archiveFilename, outputDirectory string, compilationJo return nil, err } - // Execute check function in source.sh script if not skipping checks + // Execute check function in recipe.sh script if not skipping checks if !skipChecks { cmd = exec.Command("bash", "-c", - "set -a\n"+ // Source and export functions and variables in source.sh script - ". \"${BPM_WORKDIR}\"/source.sh\n"+ + "set -a\n"+ // Source and export functions and variables in recipe.sh script + ". \"${BPM_WORKDIR}\"/recipe.sh\n"+ "set +a\n"+ "[[ $(type -t check) == \"function\" ]] && { echo \"Running check() function...\"; bash -e -c 'cd \"$BPM_SOURCE\" && check' || exit 1; }\n"+ // Run check() function if it exists "exit 0") @@ -238,10 +238,10 @@ func CompileSourcePackage(archiveFilename, outputDirectory string, compilationJo packageFunctionName = "package_" + pkg.Name } - // Execute package function in source.sh script and generate package file list + // Execute package function in recipe.sh script and generate package file list cmd = exec.Command("bash", "-c", - "set -a\n"+ // Source and export functions and variables in source.sh script - ". \"${BPM_WORKDIR}\"/source.sh\n"+ + "set -a\n"+ // Source and export functions and variables in recipe.sh script + ". \"${BPM_WORKDIR}\"/recipe.sh\n"+ "set +a\n"+ "echo \"Running "+packageFunctionName+"() function...\"\n"+ "( cd \"$BPM_SOURCE\" && fakeroot -s \"$BPM_WORKDIR\"/fakeroot_file bash -e -c '"+packageFunctionName+"' ) || exit 1\n") // Run package() function @@ -329,7 +329,7 @@ func CompileSourcePackage(archiveFilename, outputDirectory string, compilationJo // Generate package file list fmt.Println("Generating package file list...") - cmd = exec.Command("bash", "-c", "fakeroot -i \"$BPM_WORKDIR\"/fakeroot_file find \"$BPM_OUTPUT\" -mindepth 1 -printf \"%P %#m %U %G %s\\n\" > \"$BPM_WORKDIR\"/pkg.files") + cmd = exec.Command("bash", "-c", "fakeroot -i \"$BPM_WORKDIR\"/fakeroot_file find \"$BPM_OUTPUT\" -mindepth 1 -printf \"%P %#m %U %G %s\\n\" > \"$BPM_WORKDIR\"/files.txt") cmd.Dir = tempDirectory cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr @@ -345,7 +345,15 @@ func CompileSourcePackage(archiveFilename, outputDirectory string, compilationJo // Create gzip-compressed archive for the package files fmt.Println("Generating compressed file archive...") - cmd = exec.Command("bash", "-c", fmt.Sprintf("find %s -printf \"%%P\\n\" | fakeroot -i %s/fakeroot_file tar -czf files.tar.gz --no-recursion -C %s -T -", "output_"+pkg.Name, tempDirectory, "output_"+pkg.Name)) + cmd = exec.Command("bash", "-c", fmt.Sprintf(`find %s -printf "%%P\n" | fakeroot -i %s/fakeroot_file tar czf files.tar.gz \ + --sort=name \ + --pax-option=exthdr.name=%%d/PaxHeaders/%%f,delete=atime,delete=ctime \ + --mtime="UTC 1970-01-01" \ + --numeric-owner \ + --no-recursion \ + -C %s \ + -T -`, + "output_"+pkg.Name, tempDirectory, "output_"+pkg.Name)) cmd.Dir = tempDirectory cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr @@ -380,26 +388,31 @@ func CompileSourcePackage(archiveFilename, outputDirectory string, compilationJo } pkgInfoBytes = append(pkgInfoBytes, '\n') - // Create pkg.info file - err = os.WriteFile(path.Join(tempDirectory, "pkg.info"), pkgInfoBytes, 0644) + // Create info.yml file + err = os.WriteFile(path.Join(tempDirectory, "info.yml"), pkgInfoBytes, 0644) if err != nil { return nil, err } - // Change pkg.info file owner - err = os.Chown(path.Join(tempDirectory, "pkg.info"), uid, gid) + // Change info.yml file owner + err = os.Chown(path.Join(tempDirectory, "info.yml"), uid, gid) if err != nil { return nil, err } // Get files to include in BPM archive bpmArchiveFiles := make([]string, 0) - bpmArchiveFiles = append(bpmArchiveFiles, "pkg.info", "pkg.files", "files.tar.gz") // Base files + bpmArchiveFiles = append(bpmArchiveFiles, "info.yml", "files.txt", "files.tar.gz") // Base files bpmArchiveFiles = append(bpmArchiveFiles, packageScripts...) // Package scripts // Create final BPM archive fmt.Println("Generating final BPM archive...") - cmd = exec.Command("bash", "-c", "tar -cf final-archive.bpm --owner=0 --group=0 -C \"$BPM_WORKDIR\" "+strings.Join(bpmArchiveFiles, " ")) + cmd = exec.Command("tar", "cf", "final-archive.bpm", + "--sort=name", + "--pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime", + "--mtime=UTC 1970-01-01", + "--owner=0", "--group=0", "--numeric-owner") + cmd.Args = append(cmd.Args, bpmArchiveFiles...) cmd.Dir = tempDirectory cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr @@ -417,8 +430,8 @@ func CompileSourcePackage(archiveFilename, outputDirectory string, compilationJo return nil, fmt.Errorf("BPM archive could not be created: %s", err) } - // Remove pkg.info file - err = os.Remove(path.Join(tempDirectory, "pkg.info")) + // Remove info.yml file + err = os.Remove(path.Join(tempDirectory, "info.yml")) if err != nil { return nil, err } @@ -725,8 +738,8 @@ func showPackageFiles(archiveFilename string) error { return nil } - // Print pkg.info content - err = printTarballContent("pkg.info") + // Print info.yml content + err = printTarballContent("info.yml") if err != nil { return err } @@ -748,8 +761,8 @@ func showPackageFiles(archiveFilename string) error { } } - // Print source.sh content - err = printTarballContent("source.sh") + // Print recipe.sh content + err = printTarballContent("recipe.sh") if err != nil { return err } diff --git a/src/bpmlib/installed_packages.go b/src/bpmlib/installed_packages.go index 6760ecd..b4137ed 100644 --- a/src/bpmlib/installed_packages.go +++ b/src/bpmlib/installed_packages.go @@ -63,7 +63,7 @@ func InitializeLocalPackageInformation(rootDir string) (err error) { } // Read package info - infoData, err := os.ReadFile(path.Join(installedDir, item.Name(), "info")) + infoData, err := os.ReadFile(path.Join(installedDir, item.Name(), "info.yml")) if err != nil { return err } @@ -220,7 +220,7 @@ func getPackageFiles(pkg, rootDir string) []*PackageFileEntry { var pkgFiles []*PackageFileEntry installedDir := path.Join(rootDir, "var/lib/bpm/installed/") pkgDir := path.Join(installedDir, pkg) - files := path.Join(pkgDir, "files") + files := path.Join(pkgDir, "files.txt") if _, err := os.Stat(installedDir); os.IsNotExist(err) { return nil } @@ -280,7 +280,7 @@ func getPackageLocalInfo(pkg, rootDir string) PackageLocalInfo { installedDir := path.Join(rootDir, "var/lib/bpm/installed/") pkgDir := path.Join(installedDir, pkg) - localInfoFile := path.Join(path.Join(pkgDir, "local")) + localInfoFile := path.Join(path.Join(pkgDir, "local.yml")) if _, err := os.Stat(localInfoFile); os.IsNotExist(err) { return localInfo @@ -304,7 +304,7 @@ func SetPackageLocalInfo(pkg string, localInfo PackageLocalInfo, rootDir string) installedDir := path.Join(rootDir, "var/lib/bpm/installed/") pkgDir := path.Join(installedDir, pkg) - localFile, err := os.OpenFile(path.Join(pkgDir, "local"), os.O_WRONLY|os.O_CREATE, 0644) + localFile, err := os.OpenFile(path.Join(pkgDir, "local.yml"), os.O_WRONLY|os.O_CREATE, 0644) if err != nil { return err } @@ -332,10 +332,35 @@ func UpgradePersistentData(rootDir string) error { for _, entry := range dirEntries { pkgDir := path.Join(persistentDataDir, "installed", entry.Name()) + // Rename 'info' file to 'info.yml' + if _, err := os.Stat(path.Join(pkgDir, "info")); err == nil { + fmt.Printf("Moving 'info' to 'info.yml' for package (%s)\n", entry.Name()) + err := os.Rename(path.Join(pkgDir, "info"), path.Join(pkgDir, "info.yml")) + if err != nil { + return err + } + } + + // Rename 'files' file to 'files.txt' + if _, err := os.Stat(path.Join(pkgDir, "files")); err == nil { + fmt.Printf("Moving 'files' to 'files.txt' for package (%s)\n", entry.Name()) + err := os.Rename(path.Join(pkgDir, "files"), path.Join(pkgDir, "files.txt")) + if err != nil { + return err + } + } + + // Rename 'local' file to 'local.yml' + if _, err := os.Stat(path.Join(pkgDir, "local")); err == nil { + fmt.Printf("Moving 'local' to 'local.yml' for package (%s)\n", entry.Name()) + err := os.Rename(path.Join(pkgDir, "local"), path.Join(pkgDir, "local.yml")) + if err != nil { + return err + } + } + // Generate default local package information file - if _, err := os.Stat(path.Join(pkgDir, "local")); err != nil && !os.IsNotExist(err) { - return err - } else if os.IsNotExist(err) { + if _, err := os.Stat(path.Join(pkgDir, "local.yml")); os.IsNotExist(err) { fmt.Printf("Generating local package information for package (%s)\n", entry.Name()) out, err := yaml.Marshal(PackageLocalInfo{ @@ -347,10 +372,12 @@ func UpgradePersistentData(rootDir string) error { return err } - err = os.WriteFile(path.Join(pkgDir, "local"), out, 0644) + err = os.WriteFile(path.Join(pkgDir, "local.yml"), out, 0644) if err != nil { return err } + } else if err != nil { + return err } // Move installation reason to local package information file @@ -359,7 +386,7 @@ func UpgradePersistentData(rootDir string) error { } else if err == nil { fmt.Printf("Moving installation reason to local package information for package (%s)\n", entry.Name()) - data, err := os.ReadFile(path.Join(pkgDir, "local")) + data, err := os.ReadFile(path.Join(pkgDir, "local.yml")) if err != nil { return err } @@ -377,7 +404,7 @@ func UpgradePersistentData(rootDir string) error { return err } - err = os.WriteFile(path.Join(pkgDir, "local"), out, 0644) + err = os.WriteFile(path.Join(pkgDir, "local.yml"), out, 0644) if err != nil { return err } diff --git a/src/bpmlib/packages.go b/src/bpmlib/packages.go index 731000f..e3e0ff5 100644 --- a/src/bpmlib/packages.go +++ b/src/bpmlib/packages.go @@ -163,7 +163,7 @@ func GetPackageInfoRaw(filename string) (string, error) { if err != nil { return "", err } - if header.Name == "pkg.info" { + if header.Name == "info.yml" { bs, _ := io.ReadAll(tr) err := file.Close() if err != nil { @@ -172,7 +172,7 @@ func GetPackageInfoRaw(filename string) (string, error) { return string(bs), nil } } - return "", errors.New("pkg.info not found in archive") + return "", errors.New("info.yml not found in archive") } func ReadPackage(filename string) (*BPMPackage, error) { @@ -198,13 +198,13 @@ func ReadPackage(filename string) (*BPMPackage, error) { if err != nil { return nil, err } - if header.Name == "pkg.info" { + if header.Name == "info.yml" { bs, _ := io.ReadAll(tr) pkgInfo, err = ReadPackageInfo(string(bs)) if err != nil { return nil, err } - } else if header.Name == "pkg.files" { + } else if header.Name == "files.txt" { bs, _ := io.ReadAll(tr) for _, line := range strings.Split(string(bs), "\n") { if strings.TrimSpace(line) == "" { @@ -212,7 +212,7 @@ func ReadPackage(filename string) (*BPMPackage, error) { } stringEntry := strings.Split(strings.TrimSpace(line), " ") if len(stringEntry) < 5 { - return nil, errors.New("pkg.files is not formatted correctly") + return nil, errors.New("files.txt is not formatted correctly") } octalPerms, err := strconv.ParseUint(stringEntry[len(stringEntry)-4], 8, 32) if err != nil { @@ -242,7 +242,7 @@ func ReadPackage(filename string) (*BPMPackage, error) { } if pkgInfo == nil { - return nil, errors.New("pkg.info not found in archive") + return nil, errors.New("info.yml not found in archive") } return &BPMPackage{ PkgInfo: pkgInfo, @@ -1034,12 +1034,12 @@ func installPackage(filename string, installationReason InstallationReason, root return err } - f, err := os.Create(path.Join(pkgDir, "files")) + f, err := os.Create(path.Join(pkgDir, "files.txt")) if err != nil { return err } - tarballFile, err := readTarballFile(filename, "pkg.files") + tarballFile, err := readTarballFile(filename, "files.txt") if err != nil { return err } @@ -1050,7 +1050,7 @@ func installPackage(filename string, installationReason InstallationReason, root return err } - f, err = os.Create(path.Join(pkgDir, "info")) + f, err = os.Create(path.Join(pkgDir, "info.yml")) if err != nil { return err }