diff --git a/bpm_package/bpm.bpm b/bpm_package/bpm.bpm new file mode 100644 index 0000000..2f32b1f Binary files /dev/null and b/bpm_package/bpm.bpm differ diff --git a/bpm_package/files/usr/bin/bpm b/bpm_package/files/usr/bin/bpm new file mode 100755 index 0000000..750f537 Binary files /dev/null and b/bpm_package/files/usr/bin/bpm differ diff --git a/bpm_package/pkg.info b/bpm_package/pkg.info new file mode 100644 index 0000000..d52d8b3 --- /dev/null +++ b/bpm_package/pkg.info @@ -0,0 +1,4 @@ +name: bpm +description: The Bubble Package Manager +version: 0.0.1 +type: binary diff --git a/main.go b/main.go index 4f3d82e..95d4a4c 100644 --- a/main.go +++ b/main.go @@ -1,8 +1,11 @@ package main import ( + "bufio" "fmt" "log" + "os" + "strings" ) /* ---BPM | Bubble Package Manager--- */ @@ -10,21 +13,135 @@ import ( /* A simple-to-use package manager */ /* ---------------------------------- */ +var bpmVer = "0.0.1" var rootDir string = "/" func main() { fmt.Printf("Running %s %s\n", getKernel(), getArch()) - //_, err := readPackage("test_hello_package/hello.bpm") + resolveCommand() + /*_, err := readPackage("test_hello_package/hello.bpm") err := installPackage("test_hello_package/hello.bpm", rootDir) if err != nil { log.Fatalf("Could not read package\nError: %s\n", err) } - pkgs, err := getInstalledPackages(rootDir) - if err != nil { - log.Fatalf("Could not get installed Packages!\nError: %s\n", err) - } - for _, pkg := range pkgs { - fmt.Println(pkg) - } - fmt.Println(getPackageFiles("hello")) + removePackage("hello")*/ +} + +func getArgs() []string { + return os.Args[1:] +} + +type commandType uint8 + +const ( + help commandType = iota + version + info + list + install + remove + cleanup +) + +func getCommandType() commandType { + if len(getArgs()) == 0 { + return help + } + cmd := getArgs()[0] + switch cmd { + case "version": + return version + case "info": + return info + case "list": + return list + case "install": + return install + case "remove": + return remove + case "cleanup": + return cleanup + default: + return help + } +} + +func resolveCommand() { + switch getCommandType() { + case version: + fmt.Println("Bubble Package Manager (BPM)") + fmt.Println("Version: " + bpmVer) + case info: + packages := getArgs()[1:] + if len(packages) == 0 { + fmt.Println("No packages were given") + return + } + for n, pkg := range packages { + info := getPackageInfo(pkg) + if info == nil { + fmt.Printf("Package (%s) could not be found\n", pkg) + continue + } + fmt.Print("---------------\n" + createInfoFile(*info)) + if n == len(packages)-1 { + fmt.Println("---------------") + } + } + case install: + files := getArgs()[1:] + if len(files) == 0 { + fmt.Println("No files were given to install") + return + } + for _, file := range files { + pkgInfo, err := readPackage(file) + if err != nil { + log.Fatalf("Could not read package\nError: %s\n", err) + } + fmt.Print("---------------\n" + createInfoFile(*pkgInfo)) + fmt.Println("---------------") + reader := bufio.NewReader(os.Stdin) + fmt.Print("Do you wish to install this package? [y\\N] ") + text, _ := reader.ReadString('\n') + if strings.TrimSpace(strings.ToLower(text)) != "y" && strings.TrimSpace(strings.ToLower(text)) != "yes" { + fmt.Printf("Skipping package (%s)...\n", pkgInfo.name) + continue + } + err = installPackage(file, rootDir) + if err != nil { + log.Fatalf("Could not install package\nError: %s\n", err) + } + fmt.Printf("Package (%s) was successfully installed!\n", pkgInfo.name) + } + case remove: + packages := getArgs()[1:] + if len(packages) == 0 { + fmt.Println("No packages were given") + return + } + for _, pkg := range packages { + pkgInfo := getPackageInfo(pkg) + if pkgInfo == nil { + fmt.Printf("Package (%s) could not be found\n", pkg) + continue + } + fmt.Print("---------------\n" + createInfoFile(*pkgInfo)) + fmt.Println("---------------") + reader := bufio.NewReader(os.Stdin) + fmt.Print("Do you wish to remove this package? [y\\N] ") + text, _ := reader.ReadString('\n') + if strings.TrimSpace(strings.ToLower(text)) != "y" && strings.TrimSpace(strings.ToLower(text)) != "yes" { + fmt.Printf("Skipping package (%s)...\n", pkgInfo.name) + continue + } + err := removePackage(pkg) + if err != nil { + log.Fatalf("Could not remove package\nError: %s\n", err) + } + fmt.Printf("Package (%s) was successfully removed!\n", pkgInfo.name) + } + default: + fmt.Println("help...") + } } diff --git a/package_utils.go b/package_utils.go index bf37d11..2f00654 100644 --- a/package_utils.go +++ b/package_utils.go @@ -5,6 +5,7 @@ import ( "bufio" "compress/gzip" "errors" + "fmt" "io" "os" "path" @@ -17,6 +18,7 @@ type packageInfo struct { name string description string version string + pkgType string depends []string provides []string } @@ -62,6 +64,9 @@ func readPackageInfo(contents string) (*packageInfo, error) { pkgInfo := packageInfo{} lines := strings.Split(contents, "\n") for num, line := range lines { + if len(strings.TrimSpace(line)) == 0 { + continue + } split := strings.SplitN(line, ":", 2) if len(split) != 2 { return nil, errors.New("invalid pkg.info format at line " + strconv.Itoa(num)) @@ -75,6 +80,8 @@ func readPackageInfo(contents string) (*packageInfo, error) { pkgInfo.description = split[1] case "version": pkgInfo.version = split[1] + case "type": + pkgInfo.pkgType = split[1] } } return &pkgInfo, nil @@ -85,6 +92,7 @@ func createInfoFile(pkgInfo packageInfo) string { ret = ret + "name: " + pkgInfo.name + "\n" ret = ret + "description: " + pkgInfo.description + "\n" ret = ret + "version: " + pkgInfo.version + "\n" + ret = ret + "type: " + pkgInfo.pkgType + "\n" return ret } @@ -198,7 +206,7 @@ func installPackage(filename, installDir string) error { return nil } -func getInstalledPackages(rootDir string) ([]string, error) { +func getInstalledPackages() ([]string, error) { dataDir := path.Join(rootDir, "var/lib/bpm/installed/") items, err := os.ReadDir(dataDir) if os.IsNotExist(err) { @@ -235,3 +243,66 @@ func getPackageFiles(pkg string) []string { } return ret } + +func getPackageInfo(pkg string) *packageInfo { + dataDir := path.Join(rootDir, "var/lib/bpm/installed/") + pkgDir := path.Join(dataDir, pkg) + files := path.Join(pkgDir, "info") + if _, err := os.Stat(dataDir); os.IsNotExist(err) { + return nil + } + if _, err := os.Stat(pkgDir); os.IsNotExist(err) { + return nil + } + file, err := os.Open(files) + if err != nil { + return nil + } + bs, err := io.ReadAll(file) + if err != nil { + return nil + } + info, err := readPackageInfo(string(bs)) + if err != nil { + return nil + } + return info +} + +func removePackage(pkg string) error { + dataDir := path.Join(rootDir, "var/lib/bpm/installed/") + pkgDir := path.Join(dataDir, pkg) + files := getPackageFiles(pkg) + for _, file := range files { + file = path.Join(rootDir, file) + stat, err := os.Stat(file) + if err != nil { + return err + } + if stat.IsDir() { + dir, err := os.ReadDir(file) + if err != nil { + return err + } + if len(dir) == 0 { + fmt.Println("Removing: " + file) + err := os.Remove(file) + if err != nil { + return err + } + } + } else { + fmt.Println("Removing: " + file) + err := os.Remove(file) + if err != nil { + return err + } + } + } + err := os.RemoveAll(pkgDir) + if err != nil { + return err + } + fmt.Println("Removing: " + pkgDir) + return nil +} diff --git a/test_hello_package/hello.bpm b/test_hello_package/hello.bpm index f25da83..a779dd4 100644 Binary files a/test_hello_package/hello.bpm and b/test_hello_package/hello.bpm differ diff --git a/test_hello_package/pkg.info b/test_hello_package/pkg.info index 38616ec..34646ad 100644 --- a/test_hello_package/pkg.info +++ b/test_hello_package/pkg.info @@ -1,3 +1,4 @@ name: hello description: A simple hello world program -version: 1.0 \ No newline at end of file +version: 1.0 +type: binary \ No newline at end of file