mirror of
https://github.com/EnumeratedDev/bpm.git
synced 2026-09-26 15:36:13 +00:00
Compare commits
6
Commits
0.5.0
...
bc89db8cef
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bc89db8cef
|
||
|
|
ea6d722fa8
|
||
|
|
264a0f87ba
|
||
|
|
926b0e35fc
|
||
|
|
a4d1365e55 | ||
|
|
bc3fe6fd7e |
+15
-2
@@ -21,7 +21,7 @@ import (
|
||||
/* A simple-to-use package manager */
|
||||
/* ------------------------------------------------------- */
|
||||
|
||||
var bpmVer = "0.5.0"
|
||||
var bpmVer = "0.6.0"
|
||||
|
||||
var subcommand = "help"
|
||||
var subcommandArgs []string
|
||||
@@ -44,6 +44,7 @@ var showDatabaseInfo = false
|
||||
var installSrcPkgDepends = false
|
||||
var skipChecks = false
|
||||
var outputDirectory = ""
|
||||
var outputFd = -1
|
||||
var cleanupDependencies = false
|
||||
var cleanupMakeDependencies = false
|
||||
var cleanupCompilationFiles = false
|
||||
@@ -217,7 +218,7 @@ func resolveCommand() {
|
||||
for i, term := range searchTerms {
|
||||
nameResults := make([]*bpmlib.PackageInfo, 0)
|
||||
descResults := make([]*bpmlib.PackageInfo, 0)
|
||||
for _, db := range bpmlib.MainBPMConfig.Databases {
|
||||
for _, db := range bpmlib.BPMDatabases {
|
||||
for _, entry := range db.Entries {
|
||||
if strings.Contains(entry.Info.Name, term) {
|
||||
nameResults = append(nameResults, entry.Info)
|
||||
@@ -702,7 +703,17 @@ func resolveCommand() {
|
||||
}
|
||||
|
||||
for k, v := range outputBpmPackages {
|
||||
if outputFd < 0 {
|
||||
fmt.Printf("Package (%s) was successfully compiled! Binary package generated at: %s\n", k, v)
|
||||
} else {
|
||||
f := os.NewFile(uintptr(outputFd), "output_file_descrptor")
|
||||
defer f.Close()
|
||||
if f == nil {
|
||||
log.Printf("Warning: invalid file descriptor: %d", outputFd)
|
||||
break
|
||||
}
|
||||
fmt.Fprintln(f, v)
|
||||
}
|
||||
}
|
||||
|
||||
// Remove unused packages
|
||||
@@ -793,6 +804,7 @@ func printHelp() {
|
||||
fmt.Println(" -s skips the check function in source.sh scripts")
|
||||
fmt.Println(" -o sets output directory")
|
||||
fmt.Println(" -y skips the confirmation prompt")
|
||||
fmt.Println(" --fd=<file descriptor> Set the file descriptor output package names will be written to")
|
||||
|
||||
fmt.Println("\033[1m----------------\033[0m")
|
||||
}
|
||||
@@ -862,6 +874,7 @@ func resolveFlags() {
|
||||
compileFlagSet.BoolVar(&installSrcPkgDepends, "d", false, "Install required dependencies for package compilation")
|
||||
compileFlagSet.BoolVar(&skipChecks, "s", false, "Skip the check function in source.sh scripts")
|
||||
compileFlagSet.StringVar(&outputDirectory, "o", "", "Set output directory")
|
||||
compileFlagSet.IntVar(&outputFd, "fd", -1, "Set the file descriptor output package names will be written to")
|
||||
compileFlagSet.BoolVar(&verbose, "v", false, "Show additional information about what BPM is doing")
|
||||
compileFlagSet.BoolVar(&yesAll, "y", false, "Skip confirmation prompts")
|
||||
compileFlagSet.Usage = printHelp
|
||||
|
||||
+140
-47
@@ -1,11 +1,15 @@
|
||||
package bpmlib
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
@@ -31,12 +35,6 @@ func CompileSourcePackage(archiveFilename, outputDirectory string, skipChecks bo
|
||||
return nil, errors.New("cannot compile a non-source package")
|
||||
}
|
||||
|
||||
// Read compilation options file in current directory
|
||||
compilationOptions, err := readCompilationOptionsFile()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Get HOME directory
|
||||
homeDir, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
@@ -122,6 +120,12 @@ func CompileSourcePackage(archiveFilename, outputDirectory string, skipChecks bo
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Download files
|
||||
err = downloadPackageFiles(bpmpkg.PkgInfo, tempDirectory)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Setup environment for commands
|
||||
env := os.Environ()
|
||||
env = append(env, "HOME="+tempDirectory)
|
||||
@@ -131,12 +135,7 @@ func CompileSourcePackage(archiveFilename, outputDirectory string, skipChecks bo
|
||||
env = append(env, "BPM_PKG_NAME="+bpmpkg.PkgInfo.Name)
|
||||
env = append(env, "BPM_PKG_VERSION="+bpmpkg.PkgInfo.Version)
|
||||
env = append(env, "BPM_PKG_REVISION="+strconv.Itoa(bpmpkg.PkgInfo.Revision))
|
||||
// Check for architecture override in compilation options
|
||||
if val, ok := compilationOptions["ARCH"]; ok {
|
||||
env = append(env, "BPM_PKG_ARCH="+val)
|
||||
} else {
|
||||
env = append(env, "BPM_PKG_ARCH="+GetArch())
|
||||
}
|
||||
env = append(env, "BPM_PKG_ARCH="+bpmpkg.PkgInfo.OutputArch)
|
||||
env = append(env, CompilationBPMConfig.CompilationEnvironment...)
|
||||
|
||||
// Execute prepare and build functions in source.sh script
|
||||
@@ -259,14 +258,12 @@ func CompileSourcePackage(archiveFilename, outputDirectory string, skipChecks bo
|
||||
pkgInfo.Type = "binary"
|
||||
|
||||
// Set package architecture
|
||||
if val, ok := compilationOptions["ARCH"]; ok {
|
||||
pkgInfo.Arch = val
|
||||
} else {
|
||||
pkgInfo.Arch = GetArch()
|
||||
}
|
||||
pkgInfo.Arch = pkg.OutputArch
|
||||
pkgInfo.OutputArch = ""
|
||||
|
||||
// Remove split package field
|
||||
// Remove split package and downloads fields
|
||||
pkgInfo.SplitPackages = nil
|
||||
pkgInfo.Downloads = nil
|
||||
|
||||
// Marshal package info
|
||||
pkgInfoBytes, err := yaml.Marshal(pkgInfo)
|
||||
@@ -338,46 +335,142 @@ func CompileSourcePackage(archiveFilename, outputDirectory string, skipChecks bo
|
||||
return outputBpmPackages, nil
|
||||
}
|
||||
|
||||
func readCompilationOptionsFile() (options map[string]string, err error) {
|
||||
// Initialize options map
|
||||
options = make(map[string]string)
|
||||
func downloadPackageFiles(pkgInfo *PackageInfo, tempDirectory string) error {
|
||||
for _, download := range pkgInfo.Downloads {
|
||||
// Replace variables in download url
|
||||
downloadUrl := download.Url
|
||||
downloadUrl = os.Expand(downloadUrl, func(s string) string {
|
||||
switch s {
|
||||
case "BPM_PKG_VERSION":
|
||||
return pkgInfo.Version
|
||||
case "BPM_PKG_NAME":
|
||||
return pkgInfo.Name
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
})
|
||||
|
||||
// Check if file compilation options file exists
|
||||
stat, err := os.Stat(".compilation-options")
|
||||
switch download.Type {
|
||||
case "", "file":
|
||||
filepath := path.Join(tempDirectory, path.Base(downloadUrl))
|
||||
if download.Filepath != "" {
|
||||
filepath = download.Filepath
|
||||
}
|
||||
|
||||
err := downloadFile(downloadUrl, filepath, 0644)
|
||||
if err != nil {
|
||||
return nil, nil
|
||||
return err
|
||||
}
|
||||
|
||||
// Ensure it is a regular file
|
||||
if !stat.Mode().IsRegular() {
|
||||
return nil, fmt.Errorf("%s is not a regular file", stat.Name())
|
||||
}
|
||||
|
||||
// Read file data
|
||||
data, err := os.ReadFile(stat.Name())
|
||||
if download.Checksum != "skip" {
|
||||
f, err := os.Open(filepath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
h := sha256.New()
|
||||
_, err = io.Copy(h, f)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, line := range strings.Split(string(data), "\n") {
|
||||
// Trim line
|
||||
line = strings.TrimSpace(line)
|
||||
|
||||
// Skip empty lines
|
||||
if line == "" {
|
||||
continue
|
||||
if hex.EncodeToString(h.Sum(nil)) != download.Checksum {
|
||||
fmt.Printf("Downloaded file checksum: %x\n", h.Sum(nil))
|
||||
return fmt.Errorf("downloaded file checksums did not match")
|
||||
}
|
||||
} else {
|
||||
fmt.Println("Skipping checksum checking...")
|
||||
}
|
||||
|
||||
// Split line
|
||||
split := strings.SplitN(line, "=", 2)
|
||||
|
||||
// Throw error if line isn't valid
|
||||
if len(split) < 2 {
|
||||
return nil, fmt.Errorf("invalid line in compilation-options file: '%s'", line)
|
||||
if !download.NoExtract && (strings.Contains(filepath, ".tar") || strings.HasSuffix(filepath, ".tgz")) {
|
||||
cmd := exec.Command("tar", "xvf", filepath, "--strip-components="+strconv.Itoa(download.ExtractStripComponents))
|
||||
if download.ExtractToBPMSource {
|
||||
cmd.Args = append(cmd.Args, "-C", path.Join(tempDirectory, "source"))
|
||||
}
|
||||
|
||||
options[split[0]] = split[1]
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else if !download.NoExtract && strings.HasSuffix(filepath, ".zip") {
|
||||
cmd := exec.Command("unzip", filepath)
|
||||
if download.ExtractToBPMSource {
|
||||
cmd.Args = append(cmd.Args, "-d", path.Join(tempDirectory, "source"))
|
||||
} else {
|
||||
err := os.Mkdir(path.Join(tempDirectory, strings.TrimSuffix(path.Base(filepath), ".zip")), 0755)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return options, nil
|
||||
cmd.Args = append(cmd.Args, "-d", path.Join(tempDirectory, strings.TrimSuffix(path.Base(filepath), ".zip")))
|
||||
}
|
||||
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
case "git":
|
||||
// Replace variables in git branch
|
||||
gitBranch := download.GitBranch
|
||||
gitBranch = os.Expand(gitBranch, func(s string) string {
|
||||
switch s {
|
||||
case "BPM_PKG_VERSION":
|
||||
return pkgInfo.Version
|
||||
case "BPM_PKG_NAME":
|
||||
return pkgInfo.Name
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
})
|
||||
|
||||
cmd := exec.Command("git", "clone", "--depth=1", downloadUrl)
|
||||
if gitBranch != "" {
|
||||
cmd.Args = slices.Insert(cmd.Args, len(cmd.Args)-1, "--branch="+gitBranch)
|
||||
}
|
||||
if download.ExtractToBPMSource {
|
||||
cmd.Args = append(cmd.Args, path.Join(tempDirectory, "source"))
|
||||
}
|
||||
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if download.Checksum != "skip" {
|
||||
cmd := exec.Command("git", "rev-parse", "HEAD")
|
||||
if download.ExtractToBPMSource {
|
||||
cmd.Dir = path.Join(tempDirectory, "source")
|
||||
} else {
|
||||
cmd.Dir = path.Join(tempDirectory, strings.TrimSuffix(path.Base(downloadUrl), ".git"))
|
||||
}
|
||||
|
||||
branchChecksum, err := cmd.Output()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if strings.TrimSpace(string(branchChecksum)) != download.Checksum {
|
||||
fmt.Printf("Git branch checksum: %s\n", strings.TrimSpace(string(branchChecksum)))
|
||||
return fmt.Errorf("Cloned git repository checksum did not match")
|
||||
}
|
||||
} else {
|
||||
fmt.Println("Skipping checksum checking...")
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("unknown download type (%s)", download.Type)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -9,7 +9,13 @@ import (
|
||||
type MainBPMConfigStruct struct {
|
||||
IgnorePackages []string `yaml:"ignore_packages"`
|
||||
CleanupMakeDependencies bool `yaml:"cleanup_make_dependencies"`
|
||||
Databases []*BPMDatabase `yaml:"databases"`
|
||||
Databases []configDatabase `yaml:"databases"`
|
||||
}
|
||||
|
||||
type configDatabase struct {
|
||||
Name string `yaml:"name"`
|
||||
Source string `yaml:"source"`
|
||||
Disabled *bool `yaml:"disabled"`
|
||||
}
|
||||
|
||||
type CompilationBPMConfigStruct struct {
|
||||
|
||||
+46
-79
@@ -3,8 +3,6 @@ package bpmlib
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
@@ -14,27 +12,28 @@ import (
|
||||
)
|
||||
|
||||
type BPMDatabase struct {
|
||||
Name string `yaml:"name"`
|
||||
Source string `yaml:"source"`
|
||||
Disabled *bool `yaml:"disabled"`
|
||||
Entries map[string]*BPMDatabaseEntry
|
||||
DatabaseVersion int `yaml:"database_version"`
|
||||
Entries map[string]*BPMDatabaseEntry `yaml:"entries"`
|
||||
VirtualPackages map[string][]string
|
||||
Source string
|
||||
}
|
||||
|
||||
type BPMDatabaseEntry struct {
|
||||
Info *PackageInfo `yaml:"info"`
|
||||
Download string `yaml:"download"`
|
||||
Filepath string `yaml:"filepath"`
|
||||
DownloadSize uint64 `yaml:"download_size"`
|
||||
InstalledSize uint64 `yaml:"installed_size"`
|
||||
Database *BPMDatabase
|
||||
}
|
||||
|
||||
var BPMDatabases = make(map[string]*BPMDatabase)
|
||||
|
||||
func (db *BPMDatabase) ContainsPackage(pkg string) bool {
|
||||
_, ok := db.Entries[pkg]
|
||||
return ok
|
||||
}
|
||||
|
||||
func (db *BPMDatabase) ReadLocalDatabase() error {
|
||||
func (db *configDatabase) ReadLocalDatabase() error {
|
||||
dbFile := "/var/lib/bpm/databases/" + db.Name + ".bpmdb"
|
||||
if _, err := os.Stat(dbFile); err != nil {
|
||||
return nil
|
||||
@@ -45,37 +44,23 @@ func (db *BPMDatabase) ReadLocalDatabase() error {
|
||||
return err
|
||||
}
|
||||
|
||||
data := string(bytes)
|
||||
for _, b := range strings.Split(data, "---") {
|
||||
entry := BPMDatabaseEntry{
|
||||
Info: &PackageInfo{
|
||||
Name: "",
|
||||
Description: "",
|
||||
Version: "",
|
||||
Revision: 1,
|
||||
Url: "",
|
||||
License: "",
|
||||
Arch: "",
|
||||
Type: "",
|
||||
Keep: make([]string, 0),
|
||||
Depends: make([]string, 0),
|
||||
MakeDepends: make([]string, 0),
|
||||
OptionalDepends: make([]string, 0),
|
||||
Conflicts: make([]string, 0),
|
||||
Provides: make([]string, 0),
|
||||
},
|
||||
Download: "",
|
||||
DownloadSize: 0,
|
||||
InstalledSize: 0,
|
||||
Database: db,
|
||||
}
|
||||
err := yaml.Unmarshal([]byte(b), &entry)
|
||||
// Unmarshal yaml
|
||||
database := &BPMDatabase{}
|
||||
err = yaml.Unmarshal(bytes, database)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Create database entries
|
||||
// Initialize struct values
|
||||
database.VirtualPackages = make(map[string][]string)
|
||||
database.Source = db.Source
|
||||
|
||||
entriesToRemove := make([]string, 0)
|
||||
for entryName, entry := range database.Entries {
|
||||
entry.Database = database
|
||||
|
||||
if entry.Info.IsSplitPackage() {
|
||||
// Handle split packages
|
||||
for _, splitPkg := range entry.Info.SplitPackages {
|
||||
// Turn split package into json data
|
||||
splitPkgJson, err := yaml.Marshal(splitPkg)
|
||||
@@ -101,35 +86,41 @@ func (db *BPMDatabase) ReadLocalDatabase() error {
|
||||
splitPkgClone.Url = entry.Info.Url
|
||||
|
||||
// Create entry for split package
|
||||
db.Entries[splitPkg.Name] = &BPMDatabaseEntry{
|
||||
database.Entries[splitPkg.Name] = &BPMDatabaseEntry{
|
||||
Info: &splitPkgClone,
|
||||
Download: entry.Download,
|
||||
Filepath: entry.Filepath,
|
||||
DownloadSize: entry.DownloadSize,
|
||||
InstalledSize: 0,
|
||||
Database: db,
|
||||
Database: database,
|
||||
}
|
||||
|
||||
// Add virtual packages to database
|
||||
for _, p := range splitPkg.Provides {
|
||||
db.VirtualPackages[p] = append(db.VirtualPackages[p], splitPkg.Name)
|
||||
database.VirtualPackages[p] = append(database.VirtualPackages[p], splitPkg.Name)
|
||||
}
|
||||
|
||||
// Add current entry to list for removal
|
||||
entriesToRemove = append(entriesToRemove, entryName)
|
||||
}
|
||||
} else {
|
||||
// Create entry for package
|
||||
db.Entries[entry.Info.Name] = &entry
|
||||
|
||||
// Add virtual packages to database
|
||||
for _, p := range entry.Info.Provides {
|
||||
db.VirtualPackages[p] = append(db.VirtualPackages[p], entry.Info.Name)
|
||||
database.VirtualPackages[p] = append(database.VirtualPackages[p], entry.Info.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove entries
|
||||
for _, entryName := range entriesToRemove {
|
||||
delete(database.Entries, entryName)
|
||||
}
|
||||
|
||||
BPMDatabases[db.Name] = database
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *BPMDatabase) SyncLocalDatabaseFile() error {
|
||||
func (db *configDatabase) SyncLocalDatabaseFile() error {
|
||||
dbFile := "/var/lib/bpm/databases/" + db.Name + ".bpmdb"
|
||||
|
||||
// Get URL to database
|
||||
@@ -139,14 +130,10 @@ func (db *BPMDatabase) SyncLocalDatabaseFile() error {
|
||||
}
|
||||
|
||||
// Retrieve data from URL
|
||||
resp, err := http.Get(u)
|
||||
buffer, err := retrieveUrlData(u)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// Load data into byte buffer
|
||||
buffer, err := io.ReadAll(resp.Body)
|
||||
|
||||
// Unmarshal data to ensure it is a valid BPM database
|
||||
err = yaml.Unmarshal(buffer, &BPMDatabase{})
|
||||
@@ -174,10 +161,6 @@ func (db *BPMDatabase) SyncLocalDatabaseFile() error {
|
||||
|
||||
func ReadLocalDatabaseFiles() (err error) {
|
||||
for _, db := range MainBPMConfig.Databases {
|
||||
// Initialize struct values
|
||||
db.Entries = make(map[string]*BPMDatabaseEntry)
|
||||
db.VirtualPackages = make(map[string][]string)
|
||||
|
||||
// Read database
|
||||
err = db.ReadLocalDatabase()
|
||||
if err != nil {
|
||||
@@ -188,15 +171,6 @@ func ReadLocalDatabaseFiles() (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetDatabase(name string) *BPMDatabase {
|
||||
for _, db := range MainBPMConfig.Databases {
|
||||
if db.Name == name {
|
||||
return db
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetDatabaseEntry(str string) (*BPMDatabaseEntry, *BPMDatabase, error) {
|
||||
split := strings.Split(str, "/")
|
||||
if len(split) == 1 {
|
||||
@@ -204,7 +178,7 @@ func GetDatabaseEntry(str string) (*BPMDatabaseEntry, *BPMDatabase, error) {
|
||||
if pkgName == "" {
|
||||
return nil, nil, errors.New("could not find database entry for this package")
|
||||
}
|
||||
for _, db := range MainBPMConfig.Databases {
|
||||
for _, db := range BPMDatabases {
|
||||
if db.ContainsPackage(pkgName) {
|
||||
return db.Entries[pkgName], db, nil
|
||||
}
|
||||
@@ -216,7 +190,7 @@ func GetDatabaseEntry(str string) (*BPMDatabaseEntry, *BPMDatabase, error) {
|
||||
if dbName == "" || pkgName == "" {
|
||||
return nil, nil, errors.New("could not find database entry for this package")
|
||||
}
|
||||
db := GetDatabase(dbName)
|
||||
db := BPMDatabases[dbName]
|
||||
if db == nil || !db.ContainsPackage(pkgName) {
|
||||
return nil, nil, errors.New("could not find database entry for this package")
|
||||
}
|
||||
@@ -227,7 +201,7 @@ func GetDatabaseEntry(str string) (*BPMDatabaseEntry, *BPMDatabase, error) {
|
||||
}
|
||||
|
||||
func FindReplacement(pkg string) *BPMDatabaseEntry {
|
||||
for _, db := range MainBPMConfig.Databases {
|
||||
for _, db := range BPMDatabases {
|
||||
for _, entry := range db.Entries {
|
||||
for _, replaced := range entry.Info.Replaces {
|
||||
if replaced == pkg {
|
||||
@@ -241,7 +215,7 @@ func FindReplacement(pkg string) *BPMDatabaseEntry {
|
||||
}
|
||||
|
||||
func ResolveVirtualPackage(vpkg string) *BPMDatabaseEntry {
|
||||
for _, db := range MainBPMConfig.Databases {
|
||||
for _, db := range BPMDatabases {
|
||||
if v, ok := db.VirtualPackages[vpkg]; ok {
|
||||
for _, pkg := range v {
|
||||
return db.Entries[pkg]
|
||||
@@ -253,30 +227,23 @@ func ResolveVirtualPackage(vpkg string) *BPMDatabaseEntry {
|
||||
}
|
||||
|
||||
func (db *BPMDatabase) FetchPackage(pkg string) (string, error) {
|
||||
// Check if package exists in database
|
||||
if !db.ContainsPackage(pkg) {
|
||||
return "", errors.New("could not fetch package '" + pkg + "'")
|
||||
}
|
||||
|
||||
// Get package url from database
|
||||
entry := db.Entries[pkg]
|
||||
URL, err := url.JoinPath(db.Source, entry.Download)
|
||||
u, err := url.JoinPath(db.Source, entry.Filepath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
resp, err := http.Get(URL)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
err = os.MkdirAll("/var/cache/bpm/fetched/", 0755)
|
||||
// Download package from url
|
||||
err = downloadFile(u, path.Join("/var/cache/bpm/fetched/", path.Base(entry.Filepath)), 0644)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
out, err := os.Create("/var/cache/bpm/fetched/" + path.Base(entry.Download))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer out.Close()
|
||||
|
||||
_, err = io.Copy(out, resp.Body)
|
||||
return "/var/cache/bpm/fetched/" + path.Base(entry.Download), nil
|
||||
return path.Join("/var/cache/bpm/fetched/", path.Base(entry.Filepath)), nil
|
||||
}
|
||||
|
||||
@@ -164,14 +164,14 @@ func InstallPackages(rootDir string, forceInstallationReason InstallationReason,
|
||||
if rootDir != "/" {
|
||||
sourcePackages := make([]string, 0)
|
||||
for _, action := range operation.Actions {
|
||||
switch action.(type) {
|
||||
switch action := action.(type) {
|
||||
case *InstallPackageAction:
|
||||
if action.(*InstallPackageAction).BpmPackage.PkgInfo.Type == "source" {
|
||||
sourcePackages = append(sourcePackages, action.(*InstallPackageAction).BpmPackage.PkgInfo.Name)
|
||||
if action.BpmPackage.PkgInfo.Type == "source" {
|
||||
sourcePackages = append(sourcePackages, action.BpmPackage.PkgInfo.Name)
|
||||
}
|
||||
case *FetchPackageAction:
|
||||
if action.(*FetchPackageAction).DatabaseEntry.Info.Type == "source" {
|
||||
sourcePackages = append(sourcePackages, action.(*FetchPackageAction).DatabaseEntry.Info.Name)
|
||||
if action.DatabaseEntry.Info.Type == "source" {
|
||||
sourcePackages = append(sourcePackages, action.DatabaseEntry.Info.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package bpmlib
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
@@ -169,14 +168,11 @@ func GetAllPackageFiles(rootDir string, excludePackages ...string) (map[string][
|
||||
}
|
||||
bpmpkg := GetPackage(pkgName, rootDir)
|
||||
if bpmpkg == nil {
|
||||
return nil, errors.New(fmt.Sprintf("could not get BPM package (%s)", pkgName))
|
||||
return nil, fmt.Errorf("could not get BPM package (%s)", pkgName)
|
||||
}
|
||||
for _, entry := range bpmpkg.PkgFiles {
|
||||
if _, ok := ret[entry.Path]; ok {
|
||||
ret[entry.Path] = append(ret[entry.Path], bpmpkg)
|
||||
} else {
|
||||
ret[entry.Path] = []*BPMPackage{bpmpkg}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
package bpmlib
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func retrieveUrlData(u string) ([]byte, error) {
|
||||
resp, err := http.Get(u)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// Load data into byte buffer
|
||||
buffer, err := io.ReadAll(resp.Body)
|
||||
|
||||
return buffer, nil
|
||||
}
|
||||
|
||||
func downloadFile(u, filepath string, perm os.FileMode) error {
|
||||
if strings.HasSuffix(filepath, "/") {
|
||||
return fmt.Errorf("Filepath must not end in '/'")
|
||||
}
|
||||
|
||||
data, err := retrieveUrlData(u)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Create parent directories
|
||||
err = os.MkdirAll(path.Dir(filepath), 0755)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Create file
|
||||
file, err := os.Create(filepath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
// Copy data
|
||||
_, err = file.Write(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Set file permissions
|
||||
err = file.Chmod(perm)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -448,7 +448,7 @@ func (operation *BPMOperation) Execute(verbose, force bool) (err error) {
|
||||
var bpmpkg *BPMPackage
|
||||
|
||||
// Check if package has already been fetched from download link
|
||||
if _, ok := fetchedPackages[entry.Download]; !ok {
|
||||
if _, ok := fetchedPackages[entry.Filepath]; !ok {
|
||||
// Fetch package from database
|
||||
fetchedPackage, err := entry.Database.FetchPackage(entry.Info.Name)
|
||||
if err != nil {
|
||||
@@ -462,12 +462,12 @@ func (operation *BPMOperation) Execute(verbose, force bool) (err error) {
|
||||
}
|
||||
|
||||
// Add fetched package to map
|
||||
fetchedPackages[entry.Download] = fetchedPackage
|
||||
fetchedPackages[entry.Filepath] = fetchedPackage
|
||||
|
||||
fmt.Printf("Package (%s) was successfully fetched!\n", entry.Info.Name)
|
||||
} else {
|
||||
// Read fetched package
|
||||
bpmpkg, err = ReadPackage(fetchedPackages[entry.Download])
|
||||
bpmpkg, err = ReadPackage(fetchedPackages[entry.Filepath])
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not read package (%s): %s\n", entry.Info.Name, err)
|
||||
}
|
||||
@@ -477,14 +477,14 @@ func (operation *BPMOperation) Execute(verbose, force bool) (err error) {
|
||||
|
||||
if bpmpkg.PkgInfo.IsSplitPackage() {
|
||||
operation.Actions[i] = &InstallPackageAction{
|
||||
File: fetchedPackages[entry.Download],
|
||||
File: fetchedPackages[entry.Filepath],
|
||||
InstallationReason: action.(*FetchPackageAction).InstallationReason,
|
||||
BpmPackage: bpmpkg,
|
||||
SplitPackageToInstall: entry.Info.Name,
|
||||
}
|
||||
} else {
|
||||
operation.Actions[i] = &InstallPackageAction{
|
||||
File: fetchedPackages[entry.Download],
|
||||
File: fetchedPackages[entry.Filepath],
|
||||
InstallationReason: action.(*FetchPackageAction).InstallationReason,
|
||||
BpmPackage: bpmpkg,
|
||||
}
|
||||
|
||||
+19
-12
@@ -26,13 +26,14 @@ type BPMPackage struct {
|
||||
}
|
||||
|
||||
type PackageInfo struct {
|
||||
Name string `yaml:"name,omitempty"`
|
||||
Description string `yaml:"description,omitempty"`
|
||||
Version string `yaml:"version,omitempty"`
|
||||
Name string `yaml:"name"`
|
||||
Description string `yaml:"description"`
|
||||
Version string `yaml:"version"`
|
||||
Revision int `yaml:"revision,omitempty"`
|
||||
Url string `yaml:"url,omitempty"`
|
||||
License string `yaml:"license,omitempty"`
|
||||
Arch string `yaml:"architecture,omitempty"`
|
||||
OutputArch string `yaml:"output_architecture,omitempty"`
|
||||
Type string `yaml:"type,omitempty"`
|
||||
Keep []string `yaml:"keep,omitempty"`
|
||||
Depends []string `yaml:"depends,omitempty"`
|
||||
@@ -41,9 +42,21 @@ type PackageInfo struct {
|
||||
Conflicts []string `yaml:"conflicts,omitempty"`
|
||||
Replaces []string `yaml:"replaces,omitempty"`
|
||||
Provides []string `yaml:"provides,omitempty"`
|
||||
Downloads []PackageDownload `yaml:"downloads,omitempty"`
|
||||
SplitPackages []*PackageInfo `yaml:"split_packages,omitempty"`
|
||||
}
|
||||
|
||||
type PackageDownload struct {
|
||||
Url string `yaml:"url"`
|
||||
Type string `yaml:"type"`
|
||||
NoExtract bool `yaml:"no_extract"`
|
||||
ExtractToBPMSource bool `yaml:"extract_to_bpm_source"`
|
||||
ExtractStripComponents int `yaml:"extract_strip_components"`
|
||||
GitBranch string `yaml:"git_branch"`
|
||||
Filepath string `yaml:"filepath,omitempty"`
|
||||
Checksum string `yaml:"checksum"`
|
||||
}
|
||||
|
||||
type PackageFileEntry struct {
|
||||
Path string
|
||||
OctalPerms uint32
|
||||
@@ -177,10 +190,10 @@ func ReadPackage(filename string) (*BPMPackage, error) {
|
||||
}
|
||||
|
||||
file, err := os.Open(filename)
|
||||
defer file.Close()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
tr := tar.NewReader(file)
|
||||
for {
|
||||
@@ -303,14 +316,6 @@ func ReadPackageScripts(filename string) (map[string]string, error) {
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
type packageOperation uint8
|
||||
|
||||
const (
|
||||
packageOperationInstall packageOperation = 0
|
||||
packageOperationUpdate = 1
|
||||
packageOperationRemove = 2
|
||||
)
|
||||
|
||||
func executePackageScript(pkg, rootDir string, verbose bool, packageScript string) error {
|
||||
var bpmpkg *BPMPackage
|
||||
var err error
|
||||
@@ -420,6 +425,7 @@ func ReadPackageInfo(contents string) (*PackageInfo, error) {
|
||||
Url: "",
|
||||
License: "",
|
||||
Arch: "",
|
||||
OutputArch: GetArch(),
|
||||
Type: "",
|
||||
Keep: make([]string, 0),
|
||||
Depends: make([]string, 0),
|
||||
@@ -428,6 +434,7 @@ func ReadPackageInfo(contents string) (*PackageInfo, error) {
|
||||
Conflicts: make([]string, 0),
|
||||
Replaces: make([]string, 0),
|
||||
Provides: make([]string, 0),
|
||||
Downloads: make([]PackageDownload, 0),
|
||||
SplitPackages: make([]*PackageInfo, 0),
|
||||
}
|
||||
err := yaml.Unmarshal([]byte(contents), &pkgInfo)
|
||||
|
||||
Reference in New Issue
Block a user