package main import ( "encoding/json" "fmt" "os" ) type Command struct { Name string Description string Action func([]string) (string, error) Arguments []string IsVarargs bool } var commands = []Command{ { Name: "install", Description: "Install one or more mod archives into modman", Arguments: []string{"game name", "archive path"}, IsVarargs: true, Action: func(arguments []string) (string, error) { var argumentCount = len(arguments) if argumentCount == 0 { return "", fmt.Errorf("expected game name") } var modsToInstall = arguments[1:] var installedMods = []string{} if gameError := WithGame(arguments[0], func(game *Game) error { var installed, installError = game.InstallMods(modsToInstall) if installError != nil { return installError } installedMods = installed return nil }); gameError != nil { return "", gameError } return fmt.Sprint(len(installedMods), " of ", len(modsToInstall), " installed"), nil }, }, { Name: "remove", Description: "Remove one or more mods from modman", Arguments: []string{"game name", "mod name"}, IsVarargs: true, Action: func(arguments []string) (string, error) { var argumentCount = len(arguments) if argumentCount == 0 { return "", fmt.Errorf("expected game name") } var modsToRemove = arguments[1:] var removedMods = []string{} if gameError := WithGame(arguments[0], func(game *Game) error { var removed, removeError = game.RemoveMods(modsToRemove) if removeError != nil { return removeError } removedMods = removed return nil }); gameError != nil { return "", gameError } return fmt.Sprint(len(removedMods), " of ", len(removedMods), " removed"), nil }, }, { Name: "rename", Description: "Rename a mod within modman", Arguments: []string{"game name", "mod name", "new name"}, IsVarargs: false, Action: func(arguments []string) (string, error) { if len(arguments) != 3 { return "", fmt.Errorf("expected game name followed by mod name and new name") } if gameError := WithGame(arguments[0], func(game *Game) error { if removeError := game.RenameMod(arguments[1], arguments[2]); removeError != nil { return removeError } return nil }); gameError != nil { return "", gameError } return "", nil }, }, { Name: "manifest", Description: "Retrieve a manifest of all installed mods", Arguments: []string{"game name", "format"}, IsVarargs: false, Action: func(arguments []string) (string, error) { if len(arguments) != 2 { return "", fmt.Errorf("expected game name followed by format") } var modManifest = "" if gameError := WithGame(arguments[0], func(game *Game) error { var format = arguments[1] var formatter, formatterExists = formatters[format] if !(formatterExists) { return fmt.Errorf("unsupported format: `%s`", format) } var formattedManifest, formatError = formatter(game.Mods) if formatError != nil { return formatError } // TODO: Reconsider if always casting formatted data to string for output is a good // idea. modManifest = string(formattedManifest) return nil }); gameError != nil { return "", gameError } return modManifest, nil }, }, { Name: "deploy", Description: "Deploy all installed and enabled mods", Arguments: []string{"game name"}, IsVarargs: false, Action: func(arguments []string) (string, error) { // TODO: Implement. return "", fmt.Errorf("not implemented") }, }, } var formatters = map[string]func(any) ([]byte, error){ "json": func(data any) ([]byte, error) { var marshalledJson, marshalError = json.Marshal(data) if marshalError != nil { return nil, marshalError } return marshalledJson, nil }, } func main() { var argCount = len(os.Args) if argCount == 1 { fmt.Println("Modman v0.1") fmt.Println("Enter one of the following commands following modman:") for i := range commands { var command = commands[i] fmt.Print("\t", command.Name) for j := range command.Arguments { fmt.Print(" [", command.Arguments[j], "]") } if command.IsVarargs { fmt.Println("...") } else { fmt.Println() } } return } var commandName = os.Args[1] for i := range commands { var command = commands[i] if command.Name == commandName { var response, actionError = command.Action(os.Args[2:]) if actionError != nil { fmt.Fprintln(os.Stderr, actionError.Error()) os.Exit(1) } if len(response) != 0 { fmt.Println(response) } return } } fmt.Fprintf(os.Stderr, "unknown command: `%s`\n", commandName) }