Added basic remote repository functionality

This commit is contained in:
2024-08-28 10:34:27 +03:00
parent 743918702a
commit 123697e1dc
5 changed files with 280 additions and 16 deletions
+16 -7
View File
@@ -2,14 +2,16 @@ package utils
import (
"gopkg.in/yaml.v3"
"log"
"os"
)
type BPMConfigStruct struct {
CompilationEnv []string `yaml:"compilation_env"`
SilentCompilation bool `yaml:"silent_compilation"`
BinaryOutputDir string `yaml:"binary_output_dir"`
CompilationDir string `yaml:"compilation_dir"`
CompilationEnv []string `yaml:"compilation_env"`
SilentCompilation bool `yaml:"silent_compilation"`
BinaryOutputDir string `yaml:"binary_output_dir"`
CompilationDir string `yaml:"compilation_dir"`
Repositories []*Repository `yaml:"repositories"`
}
var BPMConfig BPMConfigStruct = BPMConfigStruct{
@@ -21,14 +23,21 @@ var BPMConfig BPMConfigStruct = BPMConfigStruct{
func ReadConfig() {
if _, err := os.Stat("/etc/bpm.conf"); os.IsNotExist(err) {
return
log.Fatal(err)
}
bytes, err := os.ReadFile("/etc/bpm.conf")
if err != nil {
return
log.Fatal(err)
}
err = yaml.Unmarshal(bytes, &BPMConfig)
if err != nil {
return
log.Fatal(err)
}
for _, repo := range BPMConfig.Repositories {
repo.Entries = make(map[string]*RepositoryEntry)
err := repo.ReadLocalDatabase()
if err != nil {
log.Fatal(err)
}
}
}
+9
View File
@@ -403,6 +403,15 @@ func CreateReadableInfo(showArchitecture, showType, showPackageRelations, showRe
appendMap("Conditional conflicting packages", pkgInfo.ConditionalConflicts)
appendMap("Conditional optional dependencies", pkgInfo.ConditionalOptional)
}
if showRemoteInfo {
arr := make([]string, 0)
for _, repo := range BPMConfig.Repositories {
if repo.ContainsPackage(pkgInfo.Name) {
arr = append(arr, repo.Name)
}
}
appendArray("Repositories", arr)
}
if showInstallationReason {
if IsPackageInstalled(pkgInfo.Name, rootDir) {
ret = append(ret, "Installed: yes")
+161
View File
@@ -0,0 +1,161 @@
package utils
import (
"errors"
"gopkg.in/yaml.v3"
"io"
"net/http"
"net/url"
"os"
"path"
"strings"
)
type Repository struct {
Name string `yaml:"name"`
Source string `yaml:"source"`
Disabled bool `yaml:"disabled"`
Entries map[string]*RepositoryEntry
}
type RepositoryEntry struct {
Info PackageInfo `yaml:"info"`
Download string `yaml:"download"`
}
func (repo *Repository) ContainsPackage(pkg string) bool {
_, ok := repo.Entries[pkg]
return ok
}
func (repo *Repository) ReadLocalDatabase() error {
repoFile := "/var/lib/bpm/repositories/" + repo.Name + ".bpmdb"
if _, err := os.Stat(repoFile); err != nil {
return nil
}
bytes, err := os.ReadFile(repoFile)
if err != nil {
return err
}
data := string(bytes)
for _, b := range strings.Split(data, "---") {
entry := RepositoryEntry{
Info: PackageInfo{
Name: "",
Description: "",
Version: "",
Url: "",
License: "",
Arch: "",
Type: "",
Keep: make([]string, 0),
Depends: make([]string, 0),
ConditionalDepends: make(map[string][]string),
MakeDepends: make([]string, 0),
ConditionalMakeDepends: make(map[string][]string),
Conflicts: make([]string, 0),
ConditionalConflicts: make(map[string][]string),
Optional: make([]string, 0),
ConditionalOptional: make(map[string][]string),
Provides: make([]string, 0),
},
Download: "",
}
err := yaml.Unmarshal([]byte(b), &entry)
if err != nil {
return err
}
repo.Entries[entry.Info.Name] = &entry
}
return nil
}
func (repo *Repository) SyncLocalDatabase() error {
repoFile := "/var/lib/bpm/repositories/" + repo.Name + ".bpmdb"
err := os.MkdirAll(path.Dir(repoFile), 0755)
if err != nil {
return err
}
u, err := url.JoinPath(repo.Source, "database.bpmdb")
if err != nil {
return err
}
resp, err := http.Get(u)
if err != nil {
return err
}
defer resp.Body.Close()
out, err := os.Create(repoFile)
if err != nil {
return err
}
defer out.Close()
_, err = io.Copy(out, resp.Body)
return nil
}
func GetRepository(name string) *Repository {
for _, repo := range BPMConfig.Repositories {
if repo.Name == name {
return repo
}
}
return nil
}
func GetRepositoryEntry(str string) (*RepositoryEntry, error) {
split := strings.Split(str, "/")
if len(split) == 1 {
pkgName := strings.TrimSpace(split[0])
if pkgName == "" {
return nil, errors.New("could not find repository entry for this package")
}
for _, repo := range BPMConfig.Repositories {
if repo.ContainsPackage(pkgName) {
return repo.Entries[pkgName], nil
}
}
return nil, errors.New("could not find repository entry for this package")
} else if len(split) == 2 {
repoName := strings.TrimSpace(split[0])
pkgName := strings.TrimSpace(split[1])
if repoName == "" || pkgName == "" {
return nil, errors.New("could not find repository entry for this package")
}
repo := GetRepository(repoName)
if repo == nil || !repo.ContainsPackage(pkgName) {
return nil, errors.New("could not find repository entry for this package")
}
return repo.Entries[pkgName], nil
} else {
return nil, errors.New("could not find repository entry for this package")
}
}
func (repo *Repository) FetchPackage(pkg, savePath string) (string, error) {
if !repo.ContainsPackage(pkg) {
return "", errors.New("Could not fetch package '" + pkg + "'")
}
entry := repo.Entries[pkg]
resp, err := http.Get(entry.Download)
if err != nil {
return "", err
}
defer resp.Body.Close()
out, err := os.Create(savePath)
if err != nil {
return "", err
}
defer out.Close()
_, err = io.Copy(out, resp.Body)
return savePath, nil
}