Major Update 5
changes to main.go: ``` - implement functions to make the installer search return smarter - import regexp for regex in the search return ``` changes to aur.go: ``` - fix logic to properly manage the pkg.list ``` changes to flatpak.go: ``` - fix logic to properly manage the pkg.list ``` changes to installer_utils.go: ``` - remove pkg.list handling functions and move them to packagelist-manager.go ``` changes to packagelist-manager.go: ``` - created - had the functions for the pkg.list moved into into ``` changes to pacman.go: ``` - fix logic to properly manage the pkg.list ``` changes to snap.go: ``` - fix logic to properly manage the pkg.list (not currently finished) ```
This commit is contained in:
parent
a03338c61e
commit
1f01902801
58
cmd/main.go
58
cmd/main.go
|
@ -10,6 +10,7 @@ import (
|
||||||
"pixelridgesoftworks.com/AllPac/pkg/packagemanager"
|
"pixelridgesoftworks.com/AllPac/pkg/packagemanager"
|
||||||
"pixelridgesoftworks.com/AllPac/pkg/logger"
|
"pixelridgesoftworks.com/AllPac/pkg/logger"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
@ -99,28 +100,39 @@ func handleInstall(cmd *flag.FlagSet) {
|
||||||
|
|
||||||
for _, result := range searchResults {
|
for _, result := range searchResults {
|
||||||
fmt.Printf("Searching for package: %s\n", result.PackageName)
|
fmt.Printf("Searching for package: %s\n", result.PackageName)
|
||||||
if len(result.Results) == 0 {
|
|
||||||
fmt.Println("No sources found for package.")
|
// Filter for exact matches
|
||||||
|
exactMatches := filterExactMatches(result.PackageName, result.Results)
|
||||||
|
|
||||||
|
if len(exactMatches) == 0 {
|
||||||
|
fmt.Println("No exact matches found for package.")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceIndex := promptUserForSource(result.Results)
|
var selectedSource string
|
||||||
if sourceIndex < 0 || sourceIndex >= len(result.Results) {
|
if len(exactMatches) == 1 {
|
||||||
fmt.Println("Invalid selection. Skipping package.")
|
// Only one source available, use it automatically
|
||||||
continue
|
selectedSource = exactMatches[0].Source
|
||||||
|
} else {
|
||||||
|
// Multiple sources available, prompt the user to choose
|
||||||
|
sourceIndex := promptUserForSource(exactMatches)
|
||||||
|
if sourceIndex < 0 || sourceIndex >= len(exactMatches) {
|
||||||
|
fmt.Println("Invalid selection. Skipping package.")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
selectedSource = exactMatches[sourceIndex].Source
|
||||||
}
|
}
|
||||||
|
|
||||||
selectedSource := result.Results[sourceIndex].Source
|
|
||||||
fmt.Printf("Installing %s from %s...\n", result.PackageName, selectedSource)
|
fmt.Printf("Installing %s from %s...\n", result.PackageName, selectedSource)
|
||||||
|
|
||||||
switch selectedSource {
|
switch selectedSource {
|
||||||
case "pacman":
|
case "Pacman":
|
||||||
err = packagemanager.InstallPackagePacman(result.PackageName)
|
err = packagemanager.InstallPackagePacman(result.PackageName)
|
||||||
case "snap":
|
case "Snap":
|
||||||
err = packagemanager.InstallPackageSnap(result.PackageName)
|
err = packagemanager.InstallPackageSnap(result.PackageName)
|
||||||
case "flatpak":
|
case "Flatpak":
|
||||||
err = packagemanager.InstallPackageFlatpak(result.PackageName)
|
err = packagemanager.InstallPackageFlatpak(result.PackageName)
|
||||||
case "aur":
|
case "AUR":
|
||||||
_, err = packagemanager.CloneAndInstallFromAUR(fmt.Sprintf("https://aur.archlinux.org/%s.git", result.PackageName), false)
|
_, err = packagemanager.CloneAndInstallFromAUR(fmt.Sprintf("https://aur.archlinux.org/%s.git", result.PackageName), false)
|
||||||
default:
|
default:
|
||||||
fmt.Printf("Unknown source for package %s\n", result.PackageName)
|
fmt.Printf("Unknown source for package %s\n", result.PackageName)
|
||||||
|
@ -135,6 +147,30 @@ func handleInstall(cmd *flag.FlagSet) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// filters the search results to include only those with an exact match
|
||||||
|
func filterExactMatches(packageName string, sourceResults []packagemanager.SourceResult) []packagemanager.SourceResult {
|
||||||
|
var exactMatches []packagemanager.SourceResult
|
||||||
|
for _, sourceResult := range sourceResults {
|
||||||
|
var filteredResults []string
|
||||||
|
for _, result := range sourceResult.Results {
|
||||||
|
if isExactMatch(packageName, result) {
|
||||||
|
filteredResults = append(filteredResults, result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(filteredResults) > 0 {
|
||||||
|
exactMatches = append(exactMatches, packagemanager.SourceResult{Source: sourceResult.Source, Results: filteredResults})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return exactMatches
|
||||||
|
}
|
||||||
|
|
||||||
|
// checks if the given result string is an exact match for the package name
|
||||||
|
func isExactMatch(packageName, result string) bool {
|
||||||
|
pattern := fmt.Sprintf("^%s(?:-\\d+|\\-dev)?(?: - [^ ]+)?", regexp.QuoteMeta(packageName))
|
||||||
|
matched, _ := regexp.MatchString(pattern, result)
|
||||||
|
return matched
|
||||||
|
}
|
||||||
|
|
||||||
// handleUninstall handles the uninstall command for packages
|
// handleUninstall handles the uninstall command for packages
|
||||||
func handleUninstall(cmd *flag.FlagSet) {
|
func handleUninstall(cmd *flag.FlagSet) {
|
||||||
// Define a flag for accepting multiple package names
|
// Define a flag for accepting multiple package names
|
||||||
|
|
|
@ -11,21 +11,29 @@ import (
|
||||||
// AURPackageInfo represents the package information from the AUR
|
// AURPackageInfo represents the package information from the AUR
|
||||||
type AURPackageInfo struct {
|
type AURPackageInfo struct {
|
||||||
Version string `json:"Version"`
|
Version string `json:"Version"`
|
||||||
// Add other relevant fields
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateAURPackages updates specified AUR packages or all if no specific package is provided
|
// UpdateAURPackages updates specified AUR packages or all if no specific package is provided
|
||||||
func UpdateAURPackages(packageNames ...string) error {
|
func UpdateAURPackages(packageNames ...string) error {
|
||||||
pkgList, err := ReadPackageList()
|
pkgList, err := ReadPackageList()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("error reading package list: %v", err)
|
logger.Errorf("error reading package list: %v", err)
|
||||||
return fmt.Errorf("error reading package list: %v", err)
|
return fmt.Errorf("error reading package list: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If no specific packages are provided, update all AUR packages in the list
|
||||||
|
if len(packageNames) == 0 {
|
||||||
|
for packageName, pkgInfo := range pkgList {
|
||||||
|
if pkgInfo.Source == "aur" {
|
||||||
|
packageNames = append(packageNames, packageName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for _, packageName := range packageNames {
|
for _, packageName := range packageNames {
|
||||||
aurInfo, err := fetchAURPackageInfo(packageName)
|
aurInfo, err := fetchAURPackageInfo(packageName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("error fetching AUR package info for %s: %v", packageName, err)
|
logger.Errorf("error fetching AUR package info for %s: %v", packageName, err)
|
||||||
return fmt.Errorf("error fetching AUR package info for %s: %v", packageName, err)
|
return fmt.Errorf("error fetching AUR package info for %s: %v", packageName, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,9 +41,15 @@ func UpdateAURPackages(packageNames ...string) error {
|
||||||
if !ok || installedInfo.Version != aurInfo.Version {
|
if !ok || installedInfo.Version != aurInfo.Version {
|
||||||
_, err := CloneAndInstallFromAUR("https://aur.archlinux.org/" + packageName + ".git", true)
|
_, err := CloneAndInstallFromAUR("https://aur.archlinux.org/" + packageName + ".git", true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("error updating AUR package %s: %v", packageName, err)
|
logger.Errorf("error updating AUR package %s: %v", packageName, err)
|
||||||
return fmt.Errorf("error updating AUR package %s: %v", packageName, err)
|
return fmt.Errorf("error updating AUR package %s: %v", packageName, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update the package list with the new version
|
||||||
|
if err := UpdatePackageInList(packageName, "aur", aurInfo.Version); err != nil {
|
||||||
|
logger.Errorf("error updating package list for %s: %v", packageName, err)
|
||||||
|
return fmt.Errorf("error updating package list for %s: %v", packageName, err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -43,12 +57,33 @@ func UpdateAURPackages(packageNames ...string) error {
|
||||||
|
|
||||||
// UninstallAURPackage uninstalls a specified AUR package
|
// UninstallAURPackage uninstalls a specified AUR package
|
||||||
func UninstallAURPackage(packageName string) error {
|
func UninstallAURPackage(packageName string) error {
|
||||||
|
// Read the current package list
|
||||||
|
pkgList, err := ReadPackageList()
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("An error has occurred while reading the package list: %v", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the package is managed by AllPac
|
||||||
|
if _, exists := pkgList[packageName]; !exists {
|
||||||
|
logger.Infof("Package %s not found in the package list, may not be managed by AllPac. Skipping uninstallation.", packageName)
|
||||||
|
return nil // Skip this package as it's not managed by AllPac
|
||||||
|
}
|
||||||
|
|
||||||
// Uninstalling an AUR package is typically done with pacman
|
// Uninstalling an AUR package is typically done with pacman
|
||||||
cmd := exec.Command("sudo", "pacman", "-Rns", "--noconfirm", packageName)
|
cmd := exec.Command("sudo", "pacman", "-Rns", "--noconfirm", packageName)
|
||||||
if output, err := cmd.CombinedOutput(); err != nil {
|
if output, err := cmd.CombinedOutput(); err != nil {
|
||||||
logger.Errorf("error uninstalling AUR package: %s, %v", output, err)
|
logger.Errorf("error uninstalling AUR package: %s, %v", output, err)
|
||||||
return fmt.Errorf("error uninstalling AUR package: %s, %v", output, err)
|
return fmt.Errorf("error uninstalling AUR package: %s, %v", output, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove the package from the list after successful uninstallation
|
||||||
|
if err := RemovePackageFromList(packageName); err != nil {
|
||||||
|
logger.Errorf("An error has occurred while removing the package from the list: %v", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Infof("Package %s successfully uninstalled and removed from the package list", packageName)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,28 +11,90 @@ import (
|
||||||
|
|
||||||
// UpdateFlatpakPackages updates specified Flatpak packages or all if no specific package is provided
|
// UpdateFlatpakPackages updates specified Flatpak packages or all if no specific package is provided
|
||||||
func UpdateFlatpakPackages(packageNames ...string) error {
|
func UpdateFlatpakPackages(packageNames ...string) error {
|
||||||
var cmd *exec.Cmd
|
// Read the current package list
|
||||||
if len(packageNames) == 0 {
|
pkgList, err := ReadPackageList()
|
||||||
cmd = exec.Command("flatpak", "update", "-y")
|
if err != nil {
|
||||||
} else {
|
logger.Errorf("error reading package list: %v", err)
|
||||||
args := append([]string{"update", "-y"}, packageNames...)
|
return fmt.Errorf("error reading package list: %v", err)
|
||||||
cmd = exec.Command("flatpak", args...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if output, err := cmd.CombinedOutput(); err != nil {
|
// Determine which packages need updating
|
||||||
logger.Errorf("error updating Flatpak packages: %s, %v", output, err)
|
var packagesToUpdate []string
|
||||||
return fmt.Errorf("error updating Flatpak packages: %s, %v", output, err)
|
for _, packageName := range packageNames {
|
||||||
|
installedInfo, ok := pkgList[packageName]
|
||||||
|
if !ok {
|
||||||
|
logger.Infof("Package %s not managed by AllPac, skipping", packageName)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
availableVersion, err := GetFlatpakPackageVersion(packageName)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("error getting available version for Flatpak package %s: %v", packageName, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if installedInfo.Version != availableVersion {
|
||||||
|
packagesToUpdate = append(packagesToUpdate, packageName)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update the packages
|
||||||
|
if len(packagesToUpdate) > 0 {
|
||||||
|
args := append([]string{"update", "-y"}, packagesToUpdate...)
|
||||||
|
cmd := exec.Command("flatpak", args...)
|
||||||
|
if output, err := cmd.CombinedOutput(); err != nil {
|
||||||
|
logger.Errorf("error updating Flatpak packages: %s, %v", output, err)
|
||||||
|
return fmt.Errorf("error updating Flatpak packages: %s, %v", output, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the package list with the new versions
|
||||||
|
for _, packageName := range packagesToUpdate {
|
||||||
|
newVersion, err := GetFlatpakPackageVersion(packageName)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("error getting new version for Flatpak package %s after update: %v", packageName, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if err := UpdatePackageInList(packageName, "flatpak", newVersion); err != nil {
|
||||||
|
logger.Errorf("error updating package list for %s: %v", packageName, err)
|
||||||
|
return fmt.Errorf("error updating package list for %s: %v", packageName, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logger.Info("No Flatpak packages need updating")
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UninstallFlatpakPackage uninstalls a specified Flatpak package
|
// UninstallFlatpakPackage uninstalls a specified Flatpak package
|
||||||
func UninstallFlatpakPackage(packageName string) error {
|
func UninstallFlatpakPackage(packageName string) error {
|
||||||
|
// Read the current package list
|
||||||
|
pkgList, err := ReadPackageList()
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("An error has occurred while reading the package list: %v", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the package is managed by AllPac
|
||||||
|
if _, exists := pkgList[packageName]; !exists {
|
||||||
|
logger.Infof("Package %s not found in the package list, may not be managed by AllPac", packageName)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uninstalling the Flatpak package
|
||||||
cmd := exec.Command("flatpak", "uninstall", "-y", packageName)
|
cmd := exec.Command("flatpak", "uninstall", "-y", packageName)
|
||||||
if output, err := cmd.CombinedOutput(); err != nil {
|
if output, err := cmd.CombinedOutput(); err != nil {
|
||||||
logger.Errorf("error uninstalling Flatpak package: %s, %v", output, err)
|
logger.Errorf("error uninstalling Flatpak package: %s, %v", output, err)
|
||||||
return fmt.Errorf("error uninstalling Flatpak package: %s, %v", output, err)
|
return fmt.Errorf("error uninstalling Flatpak package: %s, %v", output, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove the package from the list after successful uninstallation
|
||||||
|
if err := RemovePackageFromList(packageName); err != nil {
|
||||||
|
logger.Errorf("An error has occurred while removing the package from the list: %v", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Infof("Package %s successfully uninstalled and removed from the package list", packageName)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,11 +3,9 @@ package packagemanager
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"os"
|
"os"
|
||||||
"os/user"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"fmt"
|
"fmt"
|
||||||
"encoding/json"
|
|
||||||
"pixelridgesoftworks.com/AllPac/pkg/logger"
|
"pixelridgesoftworks.com/AllPac/pkg/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -38,93 +36,6 @@ func ExtractVersionFromPKGBUILD(repoDir string) (string, error) {
|
||||||
return "", fmt.Errorf("pkgver not found in PKGBUILD")
|
return "", fmt.Errorf("pkgver not found in PKGBUILD")
|
||||||
}
|
}
|
||||||
|
|
||||||
type PackageInfo struct {
|
|
||||||
Source string `json:"source"`
|
|
||||||
Version string `json:"version"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type PackageList map[string]PackageInfo
|
|
||||||
|
|
||||||
const pkgListFilename = "pkg.list"
|
|
||||||
|
|
||||||
// getPkgListPath returns the file path for the package list
|
|
||||||
func GetPkgListPath() (string, error) {
|
|
||||||
usr, err := user.Current()
|
|
||||||
if err != nil {
|
|
||||||
logger.Errorf("error getting current user: %v", err)
|
|
||||||
return "", fmt.Errorf("error getting current user: %v", err)
|
|
||||||
}
|
|
||||||
return filepath.Join(usr.HomeDir, ".allpac", pkgListFilename), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// readPackageList reads the package list from the file
|
|
||||||
func ReadPackageList() (PackageList, error) {
|
|
||||||
pkgListPath, err := GetPkgListPath()
|
|
||||||
if err != nil {
|
|
||||||
logger.Errorf("An error has occured:", err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
file, err := os.Open(pkgListPath)
|
|
||||||
if err != nil {
|
|
||||||
if os.IsNotExist(err) {
|
|
||||||
return PackageList{}, nil // Return an empty list if file doesn't exist
|
|
||||||
}
|
|
||||||
logger.Errorf("error opening package list file: %v", err)
|
|
||||||
return nil, fmt.Errorf("error opening package list file: %v", err)
|
|
||||||
}
|
|
||||||
defer file.Close()
|
|
||||||
|
|
||||||
var pkgList PackageList
|
|
||||||
err = json.NewDecoder(file).Decode(&pkgList)
|
|
||||||
if err != nil {
|
|
||||||
logger.Errorf("error decoding package list: %v", err)
|
|
||||||
return nil, fmt.Errorf("error decoding package list: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return pkgList, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// writePackageList writes the package list to the file
|
|
||||||
func writePackageList(pkgList PackageList) error {
|
|
||||||
pkgListPath, err := GetPkgListPath()
|
|
||||||
if err != nil {
|
|
||||||
logger.Errorf("An error has occured:", err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
file, err := os.Create(pkgListPath)
|
|
||||||
if err != nil {
|
|
||||||
logger.Errorf("error creating package list file: %v", err)
|
|
||||||
return fmt.Errorf("error creating package list file: %v", err)
|
|
||||||
}
|
|
||||||
defer file.Close()
|
|
||||||
|
|
||||||
err = json.NewEncoder(file).Encode(pkgList)
|
|
||||||
if err != nil {
|
|
||||||
logger.Errorf("error encoding package list: %v", err)
|
|
||||||
return fmt.Errorf("error encoding package list: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// logInstallation logs the package installation details
|
|
||||||
func LogInstallation(packageName, source, version string) error {
|
|
||||||
pkgList, err := readPackageList()
|
|
||||||
if err != nil {
|
|
||||||
logger.Errorf("An error has occured:", err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
pkgList[packageName] = PackageInfo{
|
|
||||||
Source: source,
|
|
||||||
Version: version,
|
|
||||||
}
|
|
||||||
|
|
||||||
return writePackageList(pkgList)
|
|
||||||
}
|
|
||||||
|
|
||||||
// requestRootPermissions prompts the user for root permissions
|
// requestRootPermissions prompts the user for root permissions
|
||||||
func requestRootPermissions() bool {
|
func requestRootPermissions() bool {
|
||||||
fmt.Println("Root permissions are required to install AUR packages.")
|
fmt.Println("Root permissions are required to install AUR packages.")
|
||||||
|
|
229
pkg/packagemanager/packagelist-manager.go
Normal file
229
pkg/packagemanager/packagelist-manager.go
Normal file
|
@ -0,0 +1,229 @@
|
||||||
|
package packagemanager
|
||||||
|
|
||||||
|
import (
|
||||||
|
"pixelridgesoftworks.com/AllPac/pkg/logger"
|
||||||
|
"os"
|
||||||
|
"os/user"
|
||||||
|
"fmt"
|
||||||
|
"path/filepath"
|
||||||
|
"encoding/json"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PackageInfo struct {
|
||||||
|
Source string `json:"source"`
|
||||||
|
Version string `json:"version"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type PackageList map[string]PackageInfo
|
||||||
|
|
||||||
|
const pkgListFilename = "pkg.list"
|
||||||
|
|
||||||
|
// returns the file path for the package list
|
||||||
|
func GetPkgListPath() (string, error) {
|
||||||
|
usr, err := user.Current()
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("error getting current user: %v", err)
|
||||||
|
return "", fmt.Errorf("error getting current user: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
pkgListDir := filepath.Join(usr.HomeDir, ".allpac")
|
||||||
|
pkgListPath := filepath.Join(pkgListDir, pkgListFilename)
|
||||||
|
|
||||||
|
logger.Infof("Checking directory: %s", pkgListDir)
|
||||||
|
|
||||||
|
// Ensure the directory exists
|
||||||
|
if err := os.MkdirAll(pkgListDir, 0755); err != nil {
|
||||||
|
logger.Errorf("error creating directory: %v", err)
|
||||||
|
return "", fmt.Errorf("error creating directory: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the pkg.list file exists
|
||||||
|
if _, err := os.Stat(pkgListPath); os.IsNotExist(err) {
|
||||||
|
logger.Infof("pkg.list file does not exist, initializing: %s", pkgListPath)
|
||||||
|
// Create and initialize the file if it doesn't exist
|
||||||
|
if err := initializePkgListFile(pkgListPath); err != nil {
|
||||||
|
return "", err // Error already logged in initializePkgListFile
|
||||||
|
}
|
||||||
|
} else if err != nil {
|
||||||
|
logger.Errorf("error checking pkg.list file: %v", err)
|
||||||
|
return "", fmt.Errorf("error checking pkg.list file: %v", err)
|
||||||
|
} else {
|
||||||
|
logger.Infof("pkg.list file exists: %s", pkgListPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
return pkgListPath, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// creates a new pkg.list file with an empty JSON object
|
||||||
|
func initializePkgListFile(filePath string) error {
|
||||||
|
file, err := os.Create(filePath)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("error creating package list file: %v", err)
|
||||||
|
return fmt.Errorf("error creating package list file: %v", err)
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
logger.Infof("Writing empty JSON object to pkg.list file: %s", filePath)
|
||||||
|
|
||||||
|
if _, err := file.WriteString("{}"); err != nil {
|
||||||
|
logger.Errorf("error initializing package list file: %v", err)
|
||||||
|
return fmt.Errorf("error initializing package list file: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Infof("pkg.list file initialized successfully: %s", filePath)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// reads the package list from the file
|
||||||
|
func ReadPackageList() (PackageList, error) {
|
||||||
|
pkgListPath, err := GetPkgListPath()
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("An error has occurred: %v", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure the directory exists
|
||||||
|
if err := os.MkdirAll(filepath.Dir(pkgListPath), 0755); err != nil {
|
||||||
|
logger.Errorf("error creating directory: %v", err)
|
||||||
|
return nil, fmt.Errorf("error creating directory: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open or create the file
|
||||||
|
file, err := os.OpenFile(pkgListPath, os.O_RDWR|os.O_CREATE, 0600)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("error opening or creating package list file: %v", err)
|
||||||
|
return nil, fmt.Errorf("error opening or creating package list file: %v", err)
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
// Check if the file is empty
|
||||||
|
fileInfo, err := file.Stat()
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("error getting file info: %v", err)
|
||||||
|
return nil, fmt.Errorf("error getting file info: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if fileInfo.Size() == 0 {
|
||||||
|
// Initialize file with an empty JSON object
|
||||||
|
if _, err := file.WriteString("{}"); err != nil {
|
||||||
|
logger.Errorf("error initializing package list file: %v", err)
|
||||||
|
return nil, fmt.Errorf("error initializing package list file: %v", err)
|
||||||
|
}
|
||||||
|
if _, err := file.Seek(0, 0); err != nil { // Reset file pointer to the beginning
|
||||||
|
logger.Errorf("error seeking in package list file: %v", err)
|
||||||
|
return nil, fmt.Errorf("error seeking in package list file: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var pkgList PackageList
|
||||||
|
err = json.NewDecoder(file).Decode(&pkgList)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("error decoding package list: %v", err)
|
||||||
|
return nil, fmt.Errorf("error decoding package list: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return pkgList, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// writes the package list to the file
|
||||||
|
func writePackageList(pkgList PackageList) error {
|
||||||
|
pkgListPath, err := GetPkgListPath()
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("An error has occured:", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
file, err := os.Create(pkgListPath)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("error creating package list file: %v", err)
|
||||||
|
return fmt.Errorf("error creating package list file: %v", err)
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
err = json.NewEncoder(file).Encode(pkgList)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("error encoding package list: %v", err)
|
||||||
|
return fmt.Errorf("error encoding package list: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// logs the package installation details
|
||||||
|
func LogInstallation(packageName, source, version string) error {
|
||||||
|
pkgList, err := readPackageList()
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("An error has occured:", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
pkgList[packageName] = PackageInfo{
|
||||||
|
Source: source,
|
||||||
|
Version: version,
|
||||||
|
}
|
||||||
|
|
||||||
|
return writePackageList(pkgList)
|
||||||
|
}
|
||||||
|
|
||||||
|
// removes a package from the package list file
|
||||||
|
func RemovePackageFromList(packageName string) error {
|
||||||
|
// Read the current package list
|
||||||
|
pkgList, err := ReadPackageList()
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("An error has occurred while reading the package list: %v", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the package exists in the list
|
||||||
|
if _, exists := pkgList[packageName]; !exists {
|
||||||
|
logger.Infof("Package %s not found in the package list, no action taken", packageName)
|
||||||
|
return nil // No need to update the file if the package isn't there
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the package from the list
|
||||||
|
delete(pkgList, packageName)
|
||||||
|
logger.Infof("Package %s removed from the package list", packageName)
|
||||||
|
|
||||||
|
// Write the updated list back to the file
|
||||||
|
if err := writePackageList(pkgList); err != nil {
|
||||||
|
logger.Errorf("An error has occurred while writing the updated package list: %v", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// updates the details of a package in the package list file
|
||||||
|
func UpdatePackageInList(packageName, source, newVersion string) error {
|
||||||
|
// Read the current package list
|
||||||
|
pkgList, err := ReadPackageList()
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("An error has occurred while reading the package list: %v", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the package exists in the list
|
||||||
|
if pkgInfo, exists := pkgList[packageName]; exists {
|
||||||
|
// Update the package details
|
||||||
|
pkgInfo.Source = source
|
||||||
|
pkgInfo.Version = newVersion
|
||||||
|
pkgList[packageName] = pkgInfo
|
||||||
|
logger.Infof("Package %s updated in the package list", packageName)
|
||||||
|
} else {
|
||||||
|
logger.Infof("Package %s not found in the package list, adding new entry", packageName)
|
||||||
|
// If the package is not found, add it as a new entry
|
||||||
|
pkgList[packageName] = PackageInfo{
|
||||||
|
Source: source,
|
||||||
|
Version: newVersion,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the updated list back to the file
|
||||||
|
if err := writePackageList(pkgList); err != nil {
|
||||||
|
logger.Errorf("An error has occurred while writing the updated package list: %v", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -5,33 +5,116 @@ package packagemanager
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"strings"
|
||||||
"pixelridgesoftworks.com/AllPac/pkg/logger"
|
"pixelridgesoftworks.com/AllPac/pkg/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
// UpdatePacmanPackages updates specified Pacman packages or all if no specific package is provided
|
// updates specified Pacman packages or all if no specific package is provided
|
||||||
func UpdatePacmanPackages(packageNames ...string) error {
|
func UpdatePacmanPackages(packageNames ...string) error {
|
||||||
var cmd *exec.Cmd
|
// If no specific packages are provided, update all packages
|
||||||
if len(packageNames) == 0 {
|
if len(packageNames) == 0 {
|
||||||
cmd = exec.Command("sudo", "pacman", "-Syu")
|
logger.Info("No specific package names provided, updating all Pacman packages")
|
||||||
} else {
|
cmd := exec.Command("sudo", "pacman", "-Syu", "--noconfirm")
|
||||||
args := append([]string{"sudo", "pacman", "-S", "--noconfirm"}, packageNames...)
|
if output, err := cmd.CombinedOutput(); err != nil {
|
||||||
cmd = exec.Command(args[0], args[1:]...)
|
logger.Errorf("error updating all Pacman packages: %s, %v", string(output), err)
|
||||||
|
return fmt.Errorf("error updating all Pacman packages: %s, %v", string(output), err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// Read the current package list
|
||||||
|
pkgList, err := ReadPackageList()
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("error reading package list: %v", err)
|
||||||
|
return fmt.Errorf("error reading package list: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if output, err := cmd.CombinedOutput(); err != nil {
|
var packagesToUpdate []string
|
||||||
logger.Errorf("error updating Pacman packages: %s, %v", string(output), err)
|
for _, packageName := range packageNames {
|
||||||
return fmt.Errorf("error updating Pacman packages: %s, %v", string(output), err)
|
installedInfo, ok := pkgList[packageName]
|
||||||
|
if !ok {
|
||||||
|
logger.Infof("Package %s not managed by AllPac, skipping", packageName)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
latestVersion, err := GetPacmanLatestVersion(packageName)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("error getting latest version for Pacman package %s: %v", packageName, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if installedInfo.Version != latestVersion {
|
||||||
|
packagesToUpdate = append(packagesToUpdate, packageName)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(packagesToUpdate) > 0 {
|
||||||
|
args := append([]string{"sudo", "pacman", "-S", "--noconfirm"}, packagesToUpdate...)
|
||||||
|
cmd := exec.Command(args[0], args[1:]...)
|
||||||
|
if output, err := cmd.CombinedOutput(); err != nil {
|
||||||
|
logger.Errorf("error updating Pacman packages: %s, %v", string(output), err)
|
||||||
|
return fmt.Errorf("error updating Pacman packages: %s, %v", string(output), err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the package list with the new versions
|
||||||
|
for _, packageName := range packagesToUpdate {
|
||||||
|
newVersion, err := GetPacmanLatestVersion(packageName)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("error getting new version for Pacman package %s after update: %v", packageName, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if err := UpdatePackageInList(packageName, "pacman", newVersion); err != nil {
|
||||||
|
logger.Errorf("error updating package list for %s: %v", packageName, err)
|
||||||
|
return fmt.Errorf("error updating package list for %s: %v", packageName, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logger.Info("No Pacman packages need updating")
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UninstallPacmanPackage uninstalls a specified Pacman package
|
// uninstalls a specified Pacman package
|
||||||
func UninstallPacmanPackage(packageName string) error {
|
func UninstallPacmanPackage(packageName string) error {
|
||||||
|
// Read the current package list
|
||||||
|
pkgList, err := ReadPackageList()
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("An error has occurred while reading the package list: %v", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the package is managed by AllPac
|
||||||
|
if _, exists := pkgList[packageName]; !exists {
|
||||||
|
logger.Infof("Package %s not found in the package list, may not be managed by AllPac", packageName)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uninstalling the Pacman package
|
||||||
cmd := exec.Command("sudo", "pacman", "-Rns", "--noconfirm", packageName)
|
cmd := exec.Command("sudo", "pacman", "-Rns", "--noconfirm", packageName)
|
||||||
if output, err := cmd.CombinedOutput(); err != nil {
|
if output, err := cmd.CombinedOutput(); err != nil {
|
||||||
logger.Errorf("error uninstalling Pacman package: %s, %v", output, err)
|
logger.Errorf("error uninstalling Pacman package: %s, %v", output, err)
|
||||||
return fmt.Errorf("error uninstalling Pacman package: %s, %v", output, err)
|
return fmt.Errorf("error uninstalling Pacman package: %s, %v", output, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove the package from the list after successful uninstallation
|
||||||
|
if err := RemovePackageFromList(packageName); err != nil {
|
||||||
|
logger.Errorf("An error has occurred while removing the package from the list: %v", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Infof("Package %s successfully uninstalled and removed from the package list", packageName)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// retrieves the latest available version of a package from Pacman
|
||||||
|
func GetPacmanLatestVersion(packageName string) (string, error) {
|
||||||
|
cmd := exec.Command("pacman", "-Si", packageName)
|
||||||
|
output, err := cmd.CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("error getting package info from Pacman: %v", err)
|
||||||
|
}
|
||||||
|
// Parse the output to find the version
|
||||||
|
versionLine := strings.Split(string(output), "\n")[2]
|
||||||
|
version := strings.Fields(versionLine)[2]
|
||||||
|
return version, nil
|
||||||
|
}
|
||||||
|
|
|
@ -11,18 +11,48 @@ import (
|
||||||
|
|
||||||
// UpdateSnapPackages updates specified Snap packages or all if no specific package is provided
|
// UpdateSnapPackages updates specified Snap packages or all if no specific package is provided
|
||||||
func UpdateSnapPackages(packageNames ...string) error {
|
func UpdateSnapPackages(packageNames ...string) error {
|
||||||
|
// Read the current package list
|
||||||
|
pkgList, err := ReadPackageList()
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("error reading package list: %v", err)
|
||||||
|
return fmt.Errorf("error reading package list: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no specific packages are provided, update all Snap packages in the list
|
||||||
|
if len(packageNames) == 0 {
|
||||||
|
for packageName, pkgInfo := range pkgList {
|
||||||
|
if pkgInfo.Source == "snap" {
|
||||||
|
packageNames = append(packageNames, packageName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var cmd *exec.Cmd
|
var cmd *exec.Cmd
|
||||||
if len(packageNames) == 0 {
|
if len(packageNames) == 0 {
|
||||||
cmd = exec.Command("sudo", "snap", "refresh")
|
cmd = exec.Command("sudo", "snap", "refresh")
|
||||||
} else {
|
} else {
|
||||||
args := append([]string{"refresh"}, packageNames...)
|
args := append([]string{"refresh"}, packageNames...)
|
||||||
cmd = exec.Command(args[0], args[1:]...)
|
cmd = exec.Command("sudo", "snap", args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
if output, err := cmd.CombinedOutput(); err != nil {
|
if output, err := cmd.CombinedOutput(); err != nil {
|
||||||
logger.Errorf("error updating Snap packages: %s, %v", string(output), err)
|
logger.Errorf("error updating Snap packages: %s, %v", string(output), err)
|
||||||
return fmt.Errorf("error updating Snap packages: %s, %v", string(output), err)
|
return fmt.Errorf("error updating Snap packages: %s, %v", string(output), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update the package list with the new versions
|
||||||
|
for _, packageName := range packageNames {
|
||||||
|
newVersion, err := GetVersionFromSnap(packageName)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("error getting new version for Snap package %s after update: %v", packageName, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if err := UpdatePackageInList(packageName, "snap", newVersion); err != nil {
|
||||||
|
logger.Errorf("error updating package list for %s: %v", packageName, err)
|
||||||
|
return fmt.Errorf("error updating package list for %s: %v", packageName, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user