2022-12-02 02:24:13 +01:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2022-12-03 18:56:36 +01:00
|
|
|
"encoding/json"
|
2022-12-02 02:24:13 +01:00
|
|
|
"fmt"
|
|
|
|
"os"
|
2022-12-21 00:28:30 +01:00
|
|
|
"strings"
|
|
|
|
|
|
|
|
"gopkg.in/yaml.v3"
|
2022-12-02 02:24:13 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
type Command struct {
|
|
|
|
Name string
|
|
|
|
Description string
|
2022-12-05 14:13:58 +01:00
|
|
|
Action CommandAction
|
2022-12-02 02:24:13 +01:00
|
|
|
Arguments []string
|
|
|
|
IsVarargs bool
|
|
|
|
}
|
|
|
|
|
2022-12-05 14:13:58 +01:00
|
|
|
type CommandAction func([]string, []string) (string, error)
|
|
|
|
|
2022-12-02 02:24:13 +01:00
|
|
|
var commands = []Command{
|
|
|
|
{
|
|
|
|
Name: "install",
|
|
|
|
Description: "Install one or more mod archives into modman",
|
2022-12-03 18:56:36 +01:00
|
|
|
Arguments: []string{"game name", "archive path"},
|
2022-12-02 02:24:13 +01:00
|
|
|
IsVarargs: true,
|
|
|
|
|
2022-12-05 14:13:58 +01:00
|
|
|
Action: func(requiredArguments []string, providedArguments []string) (string, error) {
|
2022-12-22 01:34:41 +01:00
|
|
|
if len(providedArguments) < len(requiredArguments) {
|
2022-12-21 00:28:30 +01:00
|
|
|
return "", fmt.Errorf("expected %s folowed by at least one %ss",
|
|
|
|
requiredArguments[0], requiredArguments[1])
|
2022-12-03 18:56:36 +01:00
|
|
|
}
|
2022-12-02 02:24:13 +01:00
|
|
|
|
2022-12-22 02:39:41 +01:00
|
|
|
var archivePaths = providedArguments[1:]
|
|
|
|
|
2022-12-23 15:58:59 +01:00
|
|
|
if game, openGameError := LoadGame(providedArguments[0]); openGameError == nil {
|
|
|
|
if installError := game.InstallMods(archivePaths); installError != nil {
|
|
|
|
return "", installError
|
2022-12-22 00:32:30 +01:00
|
|
|
}
|
2022-12-22 02:39:41 +01:00
|
|
|
}
|
|
|
|
|
2022-12-23 15:58:59 +01:00
|
|
|
if len(archivePaths) > 1 {
|
|
|
|
return "mods installed", nil
|
2022-12-02 02:24:13 +01:00
|
|
|
}
|
|
|
|
|
2022-12-22 02:39:41 +01:00
|
|
|
return "mod installed", nil
|
2022-12-02 02:24:13 +01:00
|
|
|
},
|
|
|
|
},
|
|
|
|
|
2022-12-22 01:34:41 +01:00
|
|
|
{
|
|
|
|
Name: "register",
|
|
|
|
Description: "Registers the data directory path of game for management under the given name",
|
|
|
|
Arguments: []string{"data path", "game name"},
|
|
|
|
IsVarargs: false,
|
|
|
|
|
|
|
|
Action: func(requiredArguments []string, providedArguments []string) (string, error) {
|
|
|
|
if len(providedArguments) < len(requiredArguments) {
|
|
|
|
return "", fmt.Errorf("expected %s folowed by at least one %ss",
|
|
|
|
requiredArguments[0], requiredArguments[1])
|
|
|
|
}
|
|
|
|
|
|
|
|
var dataPath = providedArguments[0]
|
|
|
|
var gameName = providedArguments[1]
|
|
|
|
|
|
|
|
if registerGameError := RegisterGame(gameName, dataPath); registerGameError != nil {
|
|
|
|
return "", registerGameError
|
|
|
|
}
|
|
|
|
|
|
|
|
return fmt.Sprintf("Registered %s at %s", gameName, dataPath), nil
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
2022-12-02 02:24:13 +01:00
|
|
|
{
|
|
|
|
Name: "remove",
|
|
|
|
Description: "Remove one or more mods from modman",
|
2022-12-03 18:56:36 +01:00
|
|
|
Arguments: []string{"game name", "mod name"},
|
2022-12-02 02:24:13 +01:00
|
|
|
IsVarargs: true,
|
|
|
|
|
2022-12-05 14:13:58 +01:00
|
|
|
Action: func(requiredArguments []string, providedArguments []string) (string, error) {
|
|
|
|
if len(providedArguments) < len(requiredArguments) {
|
|
|
|
return "", fmt.Errorf("expected %s followed by one or more %ss",
|
|
|
|
requiredArguments[0], requiredArguments[1])
|
2022-12-03 18:56:36 +01:00
|
|
|
}
|
|
|
|
|
2022-12-23 15:58:59 +01:00
|
|
|
var modNames = providedArguments[1:]
|
2022-12-22 00:32:30 +01:00
|
|
|
|
2022-12-23 15:58:59 +01:00
|
|
|
if game, openGameError := LoadGame(providedArguments[0]); openGameError == nil {
|
|
|
|
for _, name := range modNames {
|
|
|
|
if removeError := game.RemoveMod(name); removeError != nil {
|
|
|
|
return "", removeError
|
|
|
|
}
|
2022-12-22 00:32:30 +01:00
|
|
|
}
|
2022-12-23 15:58:59 +01:00
|
|
|
} else {
|
|
|
|
return "", openGameError
|
|
|
|
}
|
2022-12-22 00:32:30 +01:00
|
|
|
|
2022-12-23 15:58:59 +01:00
|
|
|
if len(modNames) > 1 {
|
|
|
|
return "removed mods", nil
|
2022-12-03 18:56:36 +01:00
|
|
|
}
|
|
|
|
|
2022-12-23 15:58:59 +01:00
|
|
|
return "removed mod", nil
|
2022-12-02 02:24:13 +01:00
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
Name: "rename",
|
|
|
|
Description: "Rename a mod within modman",
|
2022-12-03 18:56:36 +01:00
|
|
|
Arguments: []string{"game name", "mod name", "new name"},
|
2022-12-02 02:24:13 +01:00
|
|
|
IsVarargs: false,
|
|
|
|
|
2022-12-05 14:13:58 +01:00
|
|
|
Action: func(requiredArguments []string, providedArguments []string) (string, error) {
|
|
|
|
if len(providedArguments) != len(requiredArguments) {
|
|
|
|
return "", fmt.Errorf("expected %s followed by %s and %s",
|
|
|
|
requiredArguments[0], requiredArguments[1], requiredArguments[2])
|
2022-12-03 18:56:36 +01:00
|
|
|
}
|
|
|
|
|
2022-12-23 15:58:59 +01:00
|
|
|
if game, openGameError := LoadGame(providedArguments[0]); openGameError == nil {
|
|
|
|
if renameError := game.RenameMod(providedArguments[1], providedArguments[2]); renameError != nil {
|
|
|
|
return "", renameError
|
2022-12-03 18:56:36 +01:00
|
|
|
}
|
2022-12-23 15:58:59 +01:00
|
|
|
} else {
|
|
|
|
return "", openGameError
|
2022-12-03 18:56:36 +01:00
|
|
|
}
|
|
|
|
|
2022-12-22 00:32:30 +01:00
|
|
|
return "renamed", nil
|
2022-12-02 02:24:13 +01:00
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
2022-12-03 18:56:36 +01:00
|
|
|
Name: "manifest",
|
|
|
|
Description: "Retrieve a manifest of all installed mods",
|
|
|
|
Arguments: []string{"game name", "format"},
|
2022-12-02 02:24:13 +01:00
|
|
|
IsVarargs: false,
|
|
|
|
|
2022-12-05 14:13:58 +01:00
|
|
|
Action: func(requiredArguments []string, providedArguments []string) (string, error) {
|
|
|
|
if len(providedArguments) != len(requiredArguments) {
|
|
|
|
return "", fmt.Errorf("expected %s followed by %s",
|
|
|
|
requiredArguments[0], requiredArguments[1])
|
2022-12-03 18:56:36 +01:00
|
|
|
}
|
|
|
|
|
2022-12-23 15:58:59 +01:00
|
|
|
var manifestBuilder = strings.Builder{}
|
2022-12-03 18:56:36 +01:00
|
|
|
|
2022-12-23 15:58:59 +01:00
|
|
|
if game, openGameError := LoadGame(providedArguments[0]); openGameError == nil {
|
|
|
|
var format = providedArguments[1]
|
2022-12-03 18:56:36 +01:00
|
|
|
|
2022-12-23 15:58:59 +01:00
|
|
|
if formatter, exists := formatters[format]; exists {
|
|
|
|
if formatError := formatter(&manifestBuilder, game.Mods); formatError != nil {
|
|
|
|
return "", formatError
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return "", fmt.Errorf("unsupported format: `%s`", format)
|
2022-12-03 18:56:36 +01:00
|
|
|
}
|
2022-12-23 15:58:59 +01:00
|
|
|
} else {
|
|
|
|
return "", openGameError
|
2022-12-03 18:56:36 +01:00
|
|
|
}
|
|
|
|
|
2022-12-22 00:32:30 +01:00
|
|
|
return manifestBuilder.String(), nil
|
2022-12-02 02:24:13 +01:00
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
Name: "deploy",
|
2022-12-21 00:28:30 +01:00
|
|
|
Description: "Deploy all specified mods in order of listing",
|
2022-12-05 14:13:58 +01:00
|
|
|
Arguments: []string{"game name", "mod name"},
|
|
|
|
IsVarargs: true,
|
|
|
|
|
2022-12-22 01:34:41 +01:00
|
|
|
Action: func(requiredArguments []string, providedArguments []string) (string, error) {
|
2022-12-23 16:49:29 +01:00
|
|
|
if len(providedArguments) < len(requiredArguments) {
|
2022-12-05 14:13:58 +01:00
|
|
|
return "", fmt.Errorf("expected %s followed by one or more %ss",
|
|
|
|
requiredArguments[0], requiredArguments[1])
|
|
|
|
}
|
|
|
|
|
2022-12-23 16:49:29 +01:00
|
|
|
if game, openGameError := LoadGame(providedArguments[0]); openGameError == nil {
|
2022-12-23 15:58:59 +01:00
|
|
|
if deployError := game.Deploy(providedArguments[1:]); deployError != nil {
|
2022-12-22 00:32:30 +01:00
|
|
|
return "", deployError
|
|
|
|
}
|
2022-12-23 15:58:59 +01:00
|
|
|
} else {
|
|
|
|
return "", openGameError
|
2022-12-05 14:13:58 +01:00
|
|
|
}
|
|
|
|
|
2022-12-21 00:28:30 +01:00
|
|
|
return "deployed", nil
|
2022-12-05 14:13:58 +01:00
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
2022-12-21 00:28:30 +01:00
|
|
|
Name: "clean",
|
|
|
|
Description: "Clean all deployed mods",
|
|
|
|
Arguments: []string{"game name"},
|
|
|
|
IsVarargs: false,
|
2022-12-05 14:13:58 +01:00
|
|
|
|
|
|
|
Action: func(requiredArguments []string, arguments []string) (string, error) {
|
2022-12-21 00:33:20 +01:00
|
|
|
if len(arguments) != len(requiredArguments) {
|
|
|
|
return "", fmt.Errorf("expected %s", requiredArguments[0])
|
|
|
|
}
|
|
|
|
|
2022-12-23 15:58:59 +01:00
|
|
|
if game, openGameError := LoadGame(arguments[0]); openGameError == nil {
|
|
|
|
if cleanError := game.Clean(); cleanError != nil {
|
|
|
|
return "", cleanError
|
2022-12-22 00:32:30 +01:00
|
|
|
}
|
2022-12-23 15:58:59 +01:00
|
|
|
} else {
|
|
|
|
return "", openGameError
|
2022-12-21 00:33:20 +01:00
|
|
|
}
|
|
|
|
|
2022-12-21 00:28:30 +01:00
|
|
|
return "cleaned", nil
|
2022-12-02 02:24:13 +01:00
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2022-12-21 00:28:30 +01:00
|
|
|
var formatters = map[string]func(*strings.Builder, any) error{
|
|
|
|
"json": func(builder *strings.Builder, data any) error {
|
|
|
|
var encoder = json.NewEncoder(builder)
|
2022-12-03 19:27:53 +01:00
|
|
|
|
2022-12-21 00:28:30 +01:00
|
|
|
if encodeError := encoder.Encode(data); encodeError != nil {
|
|
|
|
return encodeError
|
2022-12-03 19:27:53 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
},
|
|
|
|
|
2022-12-21 00:28:30 +01:00
|
|
|
"yaml": func(builder *strings.Builder, data any) error {
|
|
|
|
var encoder = yaml.NewEncoder(builder)
|
2022-12-03 18:56:36 +01:00
|
|
|
|
2022-12-21 00:28:30 +01:00
|
|
|
encoder.SetIndent(2)
|
|
|
|
|
|
|
|
if encodeError := encoder.Encode(data); encodeError != nil {
|
|
|
|
return encodeError
|
2022-12-03 18:56:36 +01:00
|
|
|
}
|
|
|
|
|
2022-12-21 00:28:30 +01:00
|
|
|
return nil
|
2022-12-03 18:56:36 +01:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2022-12-02 02:24:13 +01:00
|
|
|
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 {
|
2022-12-05 14:13:58 +01:00
|
|
|
var response, actionError = command.Action(command.Arguments, os.Args[2:])
|
2022-12-02 02:24:13 +01:00
|
|
|
|
2022-12-03 18:56:36 +01:00
|
|
|
if actionError != nil {
|
|
|
|
fmt.Fprintln(os.Stderr, actionError.Error())
|
2022-12-02 02:24:13 +01:00
|
|
|
os.Exit(1)
|
|
|
|
}
|
|
|
|
|
2022-12-03 18:56:36 +01:00
|
|
|
if len(response) != 0 {
|
|
|
|
fmt.Println(response)
|
|
|
|
}
|
2022-12-02 02:24:13 +01:00
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
2022-12-03 18:56:36 +01:00
|
|
|
|
|
|
|
fmt.Fprintf(os.Stderr, "unknown command: `%s`\n", commandName)
|
2022-12-02 02:24:13 +01:00
|
|
|
}
|