package main import ( "fmt" "os" "path/filepath" "strings" "git.rawtext.club/slope-lang/slp/operators" ) const ( version string = "1.2" globalText string = " (\033[36mglobal\033[0m)" globalPath string = "/usr/local/lib/slope/modules/" banner string = "\033[32;1mslp - slope package manager\033[0m" helptext string = ` slp deps [[-g]] [file] # install the dependencies of 'file' slp fetch # fetches the updated registry slp gen [[-s|--solo]] # creates new module dir/skeleton slp help # print usage information slp install [[-g]] [module...] # installs module(s) slp installed [[-g]] # lists all installed packages slp list # lists all available packages slp local [[-g]] [filepath] # installs the module at filepath slp remove [[-g]] [module...] # removes module(s) slp search [term...] # searches for modules slp show [module...] # shows details for module(s) slp update [[-g]] [module...] # updates module(s) slp update-all [[-g]] [module...] # updates all installed modules slp version # print the current slp version Operations that accept a -g flag will attempt to install a module systemwide (this may require root access). A --global flag may be passed in lieu of a -g flag if desired for clarity. slp gen will automatically init a git repository in the created folder. The -s/--solo flag will change that behavior to create a solo repository instead. The install location for global modules is: /usr/local/lib/slope/modules Globals modules must be dealt with separately from local modules and cannot be combined in a single command.` ) func main() { arg := os.Args if len(arg) <= 1 || arg[1] == "--help" || arg[1] == "-h" || arg[1] == "help" { printHelp() return } else if arg[1] == "version" || arg[1] == "-v" || arg[1] == "--version" { fmt.Println(version) return } global := false globalTxt := "" modules := arg[2:] if len(arg) > 3 && (arg[2] == "-g" || arg[2] == "--global") { checkGlobalEnv() global = true modules = arg[3:] globalTxt = globalText } MainSwitch: switch arg[1] { case "deps": if len(modules) == 0 { fmt.Fprint(os.Stderr, "The 'deps' command requires a path to a slope file: `slp deps [file]`\n") break } mods, err := operators.Deps(modules[0]) if err != nil { fmt.Println(err) os.Exit(1) } modules = mods arg[1] = "install" goto MainSwitch case "fetch": err := operators.Fetch() if err != nil { fmt.Fprintf(os.Stderr, "%s\n", err.Error()) os.Exit(1) } case "list": err := operators.List() if err != nil { fmt.Fprintf(os.Stderr, "%s\n", err.Error()) os.Exit(1) } case "local": locals := make([]string, 0, 5) for _, mod := range modules { fmt.Printf("Installing from local \033[3m%s\033[0m%s\n", mod, globalTxt) err := operators.LocalInstall(mod, global) if err != nil { fmt.Fprintf(os.Stderr, " \033[2m└\033[0m \033[31mERROR:\033[0m %s\n\n", err.Error()) continue } locals = append(locals, mod) fmt.Print(" \033[2m└\033[0m \033[32mdone\033[0m\n\n") } printStat("\033[1;32m", "LOCALED", locals) case "installed": if len(arg) > 2 && (arg[2] == "-g" || arg[2] == "--global") { global = true globalTxt = globalText } err := operators.ShowInstalled(global, globalTxt) if err != nil { fmt.Fprintf(os.Stderr, "%s\n", err.Error()) os.Exit(1) } case "gen": solo := false if len(arg) > 2 && arg[2] == "-s" || arg[2] == "--solo" { solo = true } err := operators.Generate(solo) if err != nil { fmt.Fprintf(os.Stderr, "%s\n", err.Error()) os.Exit(1) } case "install": installs := make([]string, 0, 5) for _, mod := range modules { fmt.Printf("Installing \033[3m%s\033[0m%s\n", mod, globalTxt) err := operators.Install(mod, global) if err != nil { fmt.Fprintf(os.Stderr, " \033[2m└\033[0m \033[31mERROR:\033[0m %s\n\n", err.Error()) continue } installs = append(installs, mod) fmt.Fprint(os.Stderr, " \033[2m└\033[0m \033[32mdone\033[0m\n\n") } printStat("\033[1;32m", "INSTALLED", installs) case "remove": removes := make([]string, 0, 5) for _, mod := range modules { fmt.Printf("Removing \033[3m%s\033[0m%s\n", mod, globalTxt) err := operators.Remove(mod, global) if err != nil { fmt.Println(err) continue } removes = append(removes, mod) fmt.Print(" \033[2m└\033[0m \033[32mdone\033[0m\n\n") } printStat("\033[1;31m", "REMOVED", removes) case "update": updates := make([]string, 0, 5) for _, mod := range modules { if mod == "package.json" { continue } fmt.Printf("Updating \033[3m%s\033[0m%s\n", mod, globalTxt) err := operators.Update(mod, global) if err != nil { fmt.Println(err) continue } updates = append(updates, mod) fmt.Print(" \033[2m└\033[0m \033[32mdone\033[0m\n\n") } printStat("\033[1;36m", "UPDATED", updates) case "update-all": baseDir := operators.GetModBaseDir() if global { baseDir = operators.GlobalPath } mods, _ := filepath.Glob(filepath.Join(baseDir, "*")) for i := range mods { mods[i] = filepath.Base(mods[i]) } modules = mods arg[1] = "update" goto MainSwitch case "search": for _, term := range modules { fmt.Printf("searching for %q\n\n", term) err := operators.Search(term) if err != nil { fmt.Println(err) continue } } case "show": for _, mod := range modules { err := operators.Show(mod) if err != nil { fmt.Println(err) continue } } default: fmt.Fprintf(os.Stderr, "Unknown command %s\n\n%s\n", arg[1], helptext) } } func printStat(color, prefix string, pkgs []string) { count := len(pkgs) if count > 0 { fmt.Printf("%s%10s\033[0m ", color, prefix) if count > 1 { fmt.Printf("%d packages", count) } else { fmt.Printf("1 package") } fmt.Printf(" (%s)\n", strings.Join(pkgs, ", ")) } } func checkGlobalEnv() { err := os.MkdirAll(globalPath, 0755) if err != nil { fmt.Fprintf(os.Stderr, "\033[1;31mError:\033[0m Unable to access global environment.\n\nAre you root? Using a \033[3m-g\033[0m or \033[3m--global\033[0m flag accesses the /usr/local/lib heirarchy,\nwhich will require root access on most systems\n") os.Exit(1) } } func printHelp() { fmt.Printf("%s\n%s\n", banner, helptext) }