mirror of
https://github.com/EnumeratedDev/bpm-utils.git
synced 2026-09-24 06:26:13 +00:00
Compare commits
8
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
82777ebac1
|
||
|
|
b20766bddb
|
||
|
|
0ff9eb9cf2
|
||
|
|
4371b7f0e3
|
||
|
|
65849fdf86
|
||
|
|
a64ad39ca7
|
||
|
|
bf9874af6b
|
||
|
|
07a9e8c9d2
|
+22
-3
@@ -12,6 +12,7 @@ import (
|
||||
"path"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
flag "github.com/spf13/pflag"
|
||||
@@ -24,8 +25,9 @@ var skipCheck = flag.BoolP("skip-checks", "s", false, "Skip 'check' function whi
|
||||
var keepCompilationFiles = flag.BoolP("keep", "k", false, "Keep compilation files after successful package compilation")
|
||||
var installDepends = flag.BoolP("depends", "d", false, "Install package dependencies for compilation")
|
||||
var installPackage = flag.BoolP("install", "i", false, "Install compiled BPM package after compilation finishes")
|
||||
var compilationJobs = flag.IntP("jobs", "j", 0, "Set the amount of concurrent processes to use for source package compilation")
|
||||
var moveToBinaryDir = flag.BoolP("move", "m", false, "Move output packages to the current repository's binary directory")
|
||||
var updateChecksums = flag.BoolP("update-checksums", "u", false, "Update the checksums for all download entries")
|
||||
var updateInfo = flag.BoolP("update-info", "u", false, "Update the pkg.info file")
|
||||
var yesAll = flag.BoolP("yes", "y", false, "Accept all confirmation prompts")
|
||||
|
||||
func main() {
|
||||
@@ -56,6 +58,12 @@ func runChecks() {
|
||||
}
|
||||
|
||||
func createArchive() string {
|
||||
// Read BPM utils config
|
||||
config, err := bpmutilsshared.ReadBPMUtilsConfig()
|
||||
if err != nil {
|
||||
log.Fatalf("Error: failed to read config: %s", err)
|
||||
}
|
||||
|
||||
filesToInclude := make([]string, 0)
|
||||
|
||||
// Include base files
|
||||
@@ -84,8 +92,9 @@ func createArchive() string {
|
||||
log.Fatalf("Error: could not read package info: %s", err)
|
||||
}
|
||||
|
||||
// Update checksums
|
||||
if *updateChecksums {
|
||||
// Update pkg.info file
|
||||
if *updateInfo {
|
||||
// Update download checksums
|
||||
for i, download := range pkgInfo.Downloads {
|
||||
if download.Checksum == "skip" {
|
||||
continue
|
||||
@@ -99,6 +108,13 @@ func createArchive() string {
|
||||
pkgInfo.Downloads[i] = download
|
||||
}
|
||||
|
||||
// Add default maintainer
|
||||
if config.AddDefaultMaintainer {
|
||||
if !slices.Contains(pkgInfo.Maintainers, config.DefaultMaintainer) {
|
||||
pkgInfo.Maintainers = append(pkgInfo.Maintainers, config.DefaultMaintainer)
|
||||
}
|
||||
}
|
||||
|
||||
// Save yaml back to file
|
||||
var data bytes.Buffer
|
||||
encoder := yaml.NewEncoder(&data)
|
||||
@@ -174,6 +190,9 @@ func compilePackage(archive string) {
|
||||
if *installDepends {
|
||||
args = append(args, "-d")
|
||||
}
|
||||
if *compilationJobs > 0 {
|
||||
args = append(args, "-j"+strconv.Itoa(*compilationJobs))
|
||||
}
|
||||
if *yesAll {
|
||||
args = append(args, "-y")
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package main
|
||||
import (
|
||||
bpmutilsshared "bpm-utils-shared"
|
||||
"bufio"
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
@@ -85,6 +86,7 @@ func main() {
|
||||
flagset := flag.NewFlagSet("check-versions", flag.ExitOnError)
|
||||
flagset.BoolP("verbose", "v", false, "Show additional information about the current operation")
|
||||
flagset.BoolP("force", "f", false, "Force current operation to bypass certain conditions")
|
||||
flagset.BoolP("apply", "a", false, "Apply new versions to packages")
|
||||
setupFlagsAndHelp(flagset, fmt.Sprintf("bpm-repo %s <options>", subcommand), "Manage BPM repositories and databases", os.Args[2:])
|
||||
currentFlagSet = flagset
|
||||
|
||||
@@ -95,6 +97,22 @@ func main() {
|
||||
}
|
||||
|
||||
checkVersionsFunc(repo)
|
||||
case "compile-all", "a":
|
||||
// Setup flags and help
|
||||
flagset := flag.NewFlagSet("check-versions", flag.ExitOnError)
|
||||
flagset.BoolP("verbose", "v", false, "Show additional information about the current operation")
|
||||
flagset.BoolP("modified", "m", true, "Skip non-modified source packages")
|
||||
flagset.BoolP("show-order", "o", false, "Show the order in which all packages will be compiled and exit")
|
||||
setupFlagsAndHelp(flagset, fmt.Sprintf("bpm-repo %s <options>", subcommand), "Manage BPM repositories and databases", os.Args[2:])
|
||||
currentFlagSet = flagset
|
||||
|
||||
// Get current database
|
||||
repo := bpmutilsshared.GetRepository()
|
||||
if repo == "" {
|
||||
log.Fatal("Error: this command may only be run inside a BPM repository")
|
||||
}
|
||||
|
||||
compileAllPackagesFunc(repo)
|
||||
default:
|
||||
log.Println("Error: unknown subcommand")
|
||||
listSubcommands()
|
||||
@@ -126,6 +144,7 @@ func checkVersionsFunc(repo string) {
|
||||
// Get flags
|
||||
verbose, _ := currentFlagSet.GetBool("verbose")
|
||||
force, _ := currentFlagSet.GetBool("force")
|
||||
apply, _ := currentFlagSet.GetBool("apply")
|
||||
|
||||
// Read environment files
|
||||
err := readEnvFile(repo)
|
||||
@@ -241,6 +260,31 @@ func checkVersionsFunc(repo string) {
|
||||
OldVersion: pkgInfo.Version,
|
||||
NewVersion: latestVersion,
|
||||
}
|
||||
|
||||
// Apply new version
|
||||
pkgInfo.Version = latestVersion
|
||||
pkgInfo.Revision = 1
|
||||
if apply {
|
||||
var data bytes.Buffer
|
||||
encoder := yaml.NewEncoder(&data)
|
||||
encoder.SetIndent(2)
|
||||
encoder.Encode(pkgInfo)
|
||||
|
||||
// Write package information
|
||||
fmt.Println(path.Join(dir, "pkg.info"))
|
||||
err := os.WriteFile(path.Join(dir, "pkg.info"), data.Bytes(), 0644)
|
||||
if err != nil {
|
||||
log.Printf("Warning: could not write new version for package (%s) to file: %s", pkgInfo.Name, err)
|
||||
}
|
||||
|
||||
// Generate source package
|
||||
cmd := exec.Command("bpm-package")
|
||||
cmd.Stderr = os.Stderr
|
||||
if err := cmd.Run(); err != nil {
|
||||
log.Printf("Warning: could not generate source pacakge (%s): %s", pkgInfo.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -334,6 +378,130 @@ func listPackagesFunc(repo string) {
|
||||
}
|
||||
}
|
||||
|
||||
func compileAllPackagesFunc(repo string) {
|
||||
// Get flags
|
||||
verbose, _ := currentFlagSet.GetBool("verbose")
|
||||
modifiedOnly, _ := currentFlagSet.GetBool("modified")
|
||||
showOrder, _ := currentFlagSet.GetBool("show-order")
|
||||
|
||||
// Read BPM utils config
|
||||
config, err := bpmutilsshared.ReadBPMUtilsConfig()
|
||||
if err != nil {
|
||||
log.Fatalf("Error: failed to read config: %s", err)
|
||||
}
|
||||
|
||||
// Ensure database is updated
|
||||
bpmutilsshared.UpdateDatabases(repo)
|
||||
|
||||
// Read databases
|
||||
sourceDatabase, err := bpmutilsshared.ReadDatabase(path.Join(repo, "source/database.bpmdb"))
|
||||
if err != nil {
|
||||
log.Fatalf("Error: could not read source database: %s", err)
|
||||
}
|
||||
binaryDatabase, _ := bpmutilsshared.ReadDatabase(path.Join(repo, "binary/database.bpmdb"))
|
||||
|
||||
// Get all packages from database entries
|
||||
packages := slices.Collect(maps.Values(sourceDatabase.Entries))
|
||||
sort.Slice(packages, func(a, b int) bool {
|
||||
return packages[a].PackageInfo.Name < packages[b].PackageInfo.Name
|
||||
})
|
||||
|
||||
// Toposort packages using Depth-first search algorithm
|
||||
sorted := make([]bpmutilsshared.PackageInfo, 0)
|
||||
marked := make(map[string]int) // 0 = Unmarked, 1 = Temporary mark, 2 = Permanent mark
|
||||
var visit func(pkgInfo *bpmutilsshared.PackageInfo) error
|
||||
visit = func(pkgInfo *bpmutilsshared.PackageInfo) error {
|
||||
if mark, _ := marked[pkgInfo.Name]; mark == 2 {
|
||||
return nil
|
||||
} else if mark == 1 {
|
||||
return fmt.Errorf("Circular dependency found!")
|
||||
}
|
||||
|
||||
marked[pkgInfo.Name] = 1
|
||||
|
||||
// Get all dependencies
|
||||
depends := slices.Clone(pkgInfo.Depends)
|
||||
depends = append(depends, pkgInfo.MakeDepends...)
|
||||
|
||||
for _, depend := range depends {
|
||||
// Find package in repository
|
||||
dependEntry, ok := sourceDatabase.Entries[depend]
|
||||
if !ok {
|
||||
// Search for virtual package
|
||||
for _, entry := range sourceDatabase.Entries {
|
||||
if slices.Contains(entry.PackageInfo.Provides, depend) {
|
||||
dependEntry = entry
|
||||
ok = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
err := visit(dependEntry.PackageInfo)
|
||||
if err != nil && verbose {
|
||||
fmt.Printf("Circular dependency found! (%s -> %s)\n", pkgInfo.Name, dependEntry.PackageInfo.Name)
|
||||
}
|
||||
}
|
||||
|
||||
marked[pkgInfo.Name] = 2
|
||||
sorted = append(sorted, *pkgInfo)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, entry := range packages {
|
||||
if mark, _ := marked[entry.PackageInfo.Name]; mark != 2 {
|
||||
visit(entry.PackageInfo)
|
||||
}
|
||||
}
|
||||
|
||||
// Compile all packages in order
|
||||
for _, pkgInfo := range sorted {
|
||||
if modifiedOnly && binaryDatabase != nil {
|
||||
if binaryPkgInfo, ok := binaryDatabase.Entries[pkgInfo.Name]; ok && binaryPkgInfo.PackageInfo.GetFullVersion() == pkgInfo.GetFullVersion() {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if showOrder {
|
||||
fmt.Println(pkgInfo.Name)
|
||||
continue
|
||||
}
|
||||
|
||||
// Ensure installed packages are up-to-date
|
||||
cmd := exec.Command(config.PrivilegeEscalatorCmd, "sh", "-c", "bpm u -y")
|
||||
cmd.Stdin = os.Stdin
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
if err := cmd.Run(); err != nil {
|
||||
log.Fatalf("Error: could not update packages): %s", err)
|
||||
}
|
||||
|
||||
// Compile source package
|
||||
cmd = exec.Command("bpm-package", "-cdvumy")
|
||||
cmd.Stdin = os.Stdin
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
cmd.Dir = path.Join(repo, "source", pkgInfo.Name)
|
||||
if err := cmd.Run(); err != nil {
|
||||
log.Fatalf("Error: could not compile package (%s): %s", pkgInfo.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure installed packages are up-to-date
|
||||
cmd := exec.Command(config.PrivilegeEscalatorCmd, "sh", "-c", "bpm u -y")
|
||||
cmd.Stdin = os.Stdin
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
if err := cmd.Run(); err != nil {
|
||||
log.Fatalf("Error: could not update packages): %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func readEnvFile(repo string) error {
|
||||
data, err := os.ReadFile(path.Join(repo, ".env"))
|
||||
if os.IsNotExist(err) {
|
||||
@@ -367,6 +535,8 @@ func listSubcommands() {
|
||||
fmt.Println(" u, update-db Update update source and binary databases in current repositor")
|
||||
fmt.Println(" v, check-versions Manage BPM repositories and databases")
|
||||
fmt.Println(" l, list List packages")
|
||||
fmt.Println(" a, compile-all Compile all packages in the current repository")
|
||||
|
||||
}
|
||||
|
||||
func setupFlagsAndHelp(flagset *flag.FlagSet, usage, desc string, args []string) {
|
||||
|
||||
+10
-1
@@ -108,12 +108,18 @@ func replaceVariables(templateContents string) string {
|
||||
}
|
||||
|
||||
func createDirectory() {
|
||||
// Read BPM utils config
|
||||
config, err := bpmutilsshared.ReadBPMUtilsConfig()
|
||||
if err != nil {
|
||||
log.Fatalf("Error: failed to read config: %s", err)
|
||||
}
|
||||
|
||||
// Trim spaces
|
||||
*directory = strings.TrimSpace(*directory)
|
||||
*name = strings.TrimSpace(*name)
|
||||
|
||||
// Create directory
|
||||
err := os.Mkdir(*directory, 0755)
|
||||
err = os.Mkdir(*directory, 0755)
|
||||
if err != nil {
|
||||
log.Fatalf("Error: could not create directory: %s", err)
|
||||
}
|
||||
@@ -137,6 +143,9 @@ func createDirectory() {
|
||||
},
|
||||
},
|
||||
}
|
||||
if config.DefaultMaintainer != "" {
|
||||
pkgInfo.Maintainers = append(pkgInfo.Maintainers, config.DefaultMaintainer)
|
||||
}
|
||||
|
||||
var buffer bytes.Buffer
|
||||
encoder := yaml.NewEncoder(&buffer)
|
||||
|
||||
@@ -8,6 +8,8 @@ import (
|
||||
|
||||
type BPMUtilsConfig struct {
|
||||
PrivilegeEscalatorCmd string `yaml:"privilege_escalator_cmd"`
|
||||
DefaultMaintainer string `yaml:"default_maintainer,omitempty"`
|
||||
AddDefaultMaintainer bool `yaml:"add_default_maintainer,omitempty"`
|
||||
}
|
||||
|
||||
func ReadBPMUtilsConfig() (*BPMUtilsConfig, error) {
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/drone/envsubst"
|
||||
@@ -17,6 +18,7 @@ type PackageInfo struct {
|
||||
Revision int `yaml:"revision,omitempty"`
|
||||
Url string `yaml:"url,omitempty"`
|
||||
License string `yaml:"license,omitempty"`
|
||||
Maintainers []string `yaml:"maintainers,omitempty"`
|
||||
Arch string `yaml:"architecture,omitempty"`
|
||||
OutputArch string `yaml:"output_architecture,omitempty"`
|
||||
Type string `yaml:"type,omitempty"`
|
||||
@@ -75,6 +77,10 @@ func ReadPackageInfo(data []byte) (*PackageInfo, error) {
|
||||
return pkgInfo, nil
|
||||
}
|
||||
|
||||
func (pkgInfo *PackageInfo) GetFullVersion() string {
|
||||
return pkgInfo.Version + "-" + strconv.Itoa(pkgInfo.Revision)
|
||||
}
|
||||
|
||||
func ReadPacakgeInfoFromTarball(path string) (*PackageInfo, error) {
|
||||
// Extract package info using tar
|
||||
cmd := exec.Command("tar", "-x", "-f", path, "pkg.info", "-O")
|
||||
|
||||
Reference in New Issue
Block a user