From 7c50a30987357e0769f1ccaa6073de0d0b79a240 Mon Sep 17 00:00:00 2001 From: RudideC Date: Sat, 18 May 2024 19:21:40 +0200 Subject: [PATCH] Wyst package manager --- .gitignore | 25 +++---------- Makefile | 32 ++++++++++++++++ go.mod | 3 ++ src/commands.go | 23 ++++++++++++ src/info.go | 36 ++++++++++++++++++ src/install.go | 98 +++++++++++++++++++++++++++++++++++++++++++++++++ src/main.go | 39 ++++++++++++++++++++ 7 files changed, 237 insertions(+), 19 deletions(-) create mode 100644 Makefile create mode 100644 go.mod create mode 100644 src/commands.go create mode 100644 src/info.go create mode 100644 src/install.go create mode 100644 src/main.go diff --git a/.gitignore b/.gitignore index 3b735ec..8915412 100644 --- a/.gitignore +++ b/.gitignore @@ -1,21 +1,8 @@ -# If you prefer the allow list template instead of the deny list, see community template: -# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore -# -# Binaries for programs and plugins -*.exe -*.exe~ -*.dll -*.so -*.dylib +# MacOS +.DS_Store -# Test binary, built with `go test -c` -*.test +# VSCode +.vscode -# Output of the go coverage tool, specifically when used with LiteIDE -*.out - -# Dependency directories (remove the comment below to include it) -# vendor/ - -# Go workspace file -go.work +# Output +/bin diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..21e9cde --- /dev/null +++ b/Makefile @@ -0,0 +1,32 @@ +# Project variables +BINARY_NAME = wpm +SOURCE_DIR = ./src +OUTPUT_DIR = ./bin + +# Go commands +BUILD_CMD = go build -o $(OUTPUT_DIR)/$(BINARY_NAME) $(SOURCE_DIR)/main.go +RUN_CMD = go run $(SOURCE_DIR)/main.go + +# Targets +.PHONY: all build run clean + +# Default target +all: build + +# Build the project +build: + @echo "Building the project..." + @mkdir -p $(OUTPUT_DIR) + @$(BUILD_CMD) + @echo "Build complete!" + +# Run the project using `go run` +run: + @echo "Running the project..." + @$(RUN_CMD) + +# Clean the output directory +clean: + @echo "Cleaning up..." + @rm -rf $(OUTPUT_DIR) + @echo "Clean complete!" diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..f7af208 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module github.com/RudideC/wyst-package-manager + +go 1.22.0 diff --git a/src/commands.go b/src/commands.go new file mode 100644 index 0000000..b435247 --- /dev/null +++ b/src/commands.go @@ -0,0 +1,23 @@ +package main + +import ( + "fmt" + "strings" +) + +func showHelp() { + fmt.Println("wpm - Wyst Package Manager") + fmt.Println("Commands:") + fmt.Println(" install [:version] - Install a package (version is optional)") + fmt.Println(" version - Show the wpm version") + fmt.Println(" help - Show this help message") + fmt.Println(" info - Show package information (author, description, versions)") +} + +func parsePackageArg(arg string) (string, string) { + parts := strings.Split(arg, ":") + if len(parts) == 2 { + return parts[0], parts[1] + } + return parts[0], "" +} diff --git a/src/info.go b/src/info.go new file mode 100644 index 0000000..41adf86 --- /dev/null +++ b/src/info.go @@ -0,0 +1,36 @@ +package main + +import ( + "encoding/json" + "fmt" + "net/http" +) + +func showPackageInfo(packageName string) { + url := fmt.Sprintf("https://raw.githubusercontent.com/wyst-lang/index/master/%s/index.json", packageName) + resp, err := http.Get(url) + if err != nil { + fmt.Printf("Error fetching package info: %v\n", err) + return + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + fmt.Printf("Error: %s\n", resp.Status) + return + } + + var pkgIndex PackageIndex + if err := json.NewDecoder(resp.Body).Decode(&pkgIndex); err != nil { + fmt.Printf("Error decoding package info: %v\n", err) + return + } + + fmt.Printf("Package: %s\n", packageName) + for version, info := range pkgIndex.Versions { + fmt.Printf("Version: %s\n", version) + fmt.Printf(" Author: %s\n", info.Author) + fmt.Printf(" Description: %s\n", info.Description) + fmt.Println() + } +} diff --git a/src/install.go b/src/install.go new file mode 100644 index 0000000..23d8b05 --- /dev/null +++ b/src/install.go @@ -0,0 +1,98 @@ +package main + +import ( + "encoding/json" + "fmt" + "io" + "net/http" + "os" + "path/filepath" +) + +type PackageVersion struct { + Author string `json:"author"` + Description string `json:"description"` + URL string `json:"url"` +} + +type PackageIndex struct { + Versions map[string]PackageVersion `json:"versions"` +} + +func installPackage(packageName, packageVersion string) { + url := fmt.Sprintf("https://raw.githubusercontent.com/wyst-lang/index/master/%s/index.json", packageName) + resp, err := http.Get(url) + if err != nil { + fmt.Printf("Error fetching package info: %v\n", err) + return + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + fmt.Printf("Error: %s\n", resp.Status) + return + } + + var pkgIndex PackageIndex + if err := json.NewDecoder(resp.Body).Decode(&pkgIndex); err != nil { + fmt.Printf("Error decoding package info: %v\n", err) + return + } + + if packageVersion == "" { + packageVersion = getLatestVersion(pkgIndex) + } + + pkgVersion, exists := pkgIndex.Versions[packageVersion] + if !exists { + fmt.Printf("Version %s not found for package %s\n", packageVersion, packageName) + return + } + + downloadAndSavePackage(pkgVersion.URL, packageName, packageVersion) +} + +func getLatestVersion(pkgIndex PackageIndex) string { + var latest string + for version := range pkgIndex.Versions { + if version > latest { + latest = version + } + } + return latest +} + +func downloadAndSavePackage(url, packageName, packageVersion string) { + resp, err := http.Get(url) + if err != nil { + fmt.Printf("Error downloading package: %v\n", err) + return + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + fmt.Printf("Error: %s\n", resp.Status) + return + } + + libDir := "lib" + if err := os.MkdirAll(libDir, 0755); err != nil { + fmt.Printf("Error creating lib directory: %v\n", err) + return + } + + filename := filepath.Base(url) + packageFile := filepath.Join(libDir, filename) + out, err := os.Create(packageFile) + if err != nil { + fmt.Printf("Error creating package file: %v\n", err) + return + } + defer out.Close() + + if _, err := io.Copy(out, resp.Body); err != nil { + fmt.Printf("Error saving package: %v\n", err) + } else { + fmt.Printf("Package %s version %s downloaded and saved successfully as %s\n", packageName, packageVersion, filename) + } +} diff --git a/src/main.go b/src/main.go new file mode 100644 index 0000000..63efd73 --- /dev/null +++ b/src/main.go @@ -0,0 +1,39 @@ +package main + +import ( + "fmt" + "os" +) + +const wpmVersion = "1.0.0" + +func main() { + if len(os.Args) < 2 { + showHelp() + return + } + + command := os.Args[1] + switch command { + case "install": + if len(os.Args) < 3 { + fmt.Println("Usage: wpm install [:version]") + return + } + packageName, packageVersion := parsePackageArg(os.Args[2]) + installPackage(packageName, packageVersion) + case "version": + fmt.Println("wpm version", wpmVersion) + case "help": + showHelp() + case "info": + if len(os.Args) < 3 { + fmt.Println("Usage: wpm info ") + return + } + showPackageInfo(os.Args[2]) + default: + fmt.Println("Unknown command:", command) + showHelp() + } +}