From ccce234ae387d70482672df2df1f5e0777e6bd7f Mon Sep 17 00:00:00 2001 From: Gregory Ballantine Date: Mon, 19 Sep 2022 14:38:27 -0400 Subject: [PATCH] Added the 'new' command, which creates a new minecraft server instance --- cmd/new.go | 92 ++++++++++++++++++++++++++++++++++++++++++++++++ cmd/root.go | 5 +++ util/env.go | 23 ++++++++++++ util/env_test.go | 29 +++++++++++++++ 4 files changed, 149 insertions(+) create mode 100644 cmd/new.go create mode 100644 util/env.go create mode 100644 util/env_test.go diff --git a/cmd/new.go b/cmd/new.go new file mode 100644 index 0000000..ed3f8ee --- /dev/null +++ b/cmd/new.go @@ -0,0 +1,92 @@ +package cmd + +import ( + "fmt" + "io" + "log" + "net/http" + "os" + + "github.com/spf13/cobra" + + "git.metaunix.net/BitGoblin/mcst/util" +) + +var ( + serverName string + minecraftVersion string +) + +var newCmd = &cobra.Command{ + Use: "new", + Short: "Create a new Minecraft server instance.", + Long: `Create a new Minecraft server instance.`, + Run: func(cmd *cobra.Command, args []string) { + log.Printf("Creating new server with name '%s', and version '%s'\n", serverName, minecraftVersion) + + serverDirectoryPath := util.ResolveTilde(fmt.Sprintf("~/%s", serverName)) + + err := os.Mkdir(serverDirectoryPath, 0755) + if err != nil && !os.IsExist(err) { + log.Fatal(err) + } + + var serverJarURL string = "https://piston-data.mojang.com/v1/objects/f69c284232d7c7580bd89a5a4931c3581eae1378/server.jar" + var serverFilePath string = fmt.Sprintf("%s/server_%s.jar", serverDirectoryPath, minecraftVersion) + + log.Printf("Downloading %s to %s\n", serverJarURL, serverFilePath) + file, err := os.Create(serverFilePath) + if err != nil { + log.Fatal(err) + } + + client := http.Client{ + CheckRedirect: func(r *http.Request, via []*http.Request) error { + r.URL.Opaque = r.URL.Path + return nil + }, + } + + // Put content on file + resp, err := client.Get(serverJarURL) + if err != nil { + log.Fatal(err) + } + defer resp.Body.Close() + + _, err = io.Copy(file, resp.Body) + defer file.Close() + + // create the shell script to start the server + log.Printf("Creating start.sh shell script.\n") + var scriptFilePath string = fmt.Sprintf("%s/start.sh", serverDirectoryPath) + scriptFile, err := os.Create(scriptFilePath) + if err != nil { + log.Fatalf("Unable to open file: %v", err) + } + defer scriptFile.Close() + + // add text to the file + _, err = scriptFile.WriteString(fmt.Sprintf("#!/bin/sh\n\ncd %s\njava -Xmx2048M -Xms2048M -jar server_%s.jar nogui", serverDirectoryPath, minecraftVersion)) + if err != nil { + log.Fatalf("Unable to write data: %v", err) + } + + // set permissions on the script + err = os.Chmod(scriptFilePath, 0755) + if err != nil { + log.Fatalf("Unable to change script permissions: %v", err) + } + }, +} + +func init() { + // bind flags to variables + newCmd.Flags().StringVarP(&serverName, "server-name", "n", "", "The name for your new server.") + newCmd.MarkFlagRequired("server-name") + newCmd.Flags().StringVarP(&minecraftVersion, "minecraft-version", "m", "", "Minecraft Java Edition server version to use.") + newCmd.MarkFlagRequired("minecraft-version") + + // add this command to the command root + rootCmd.AddCommand(newCmd) +} diff --git a/cmd/root.go b/cmd/root.go index 74bf5a2..0de37bc 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -7,6 +7,10 @@ import ( "github.com/spf13/cobra" ) +var ( + version string +) + var rootCmd = &cobra.Command{ Use: "mcst", Short: "MCST is a tool to manage Minecraft Java edition servers.", @@ -15,6 +19,7 @@ var rootCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { log.Printf("This is a test.") }, + Version: version, } func Start() { diff --git a/util/env.go b/util/env.go new file mode 100644 index 0000000..3e81436 --- /dev/null +++ b/util/env.go @@ -0,0 +1,23 @@ +package util + +import ( + "path/filepath" + "os/user" + "strings" +) + +func ResolveTilde(path string) string { + usr, _ := user.Current() + dir := usr.HomeDir + + if path == "~" { + // In case of "~", which won't be caught by the "else if" + path = dir + } else if strings.HasPrefix(path, "~/") { + // Use strings.HasPrefix so we don't match paths like + // "/something/~/something/" + path = filepath.Join(dir, path[2:]) + } + + return path +} diff --git a/util/env_test.go b/util/env_test.go new file mode 100644 index 0000000..962d2f8 --- /dev/null +++ b/util/env_test.go @@ -0,0 +1,29 @@ +package util + +import ( + "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/suite" +) + +// define our test suite struct +type EnvTestSuite struct { + suite.Suite +} + +// the tilde should expand to user's home directory +func (s *EnvTestSuite) TestResolveTilde() { + resolvedPath := ResolveTilde("~") + assert.NotEqual(s.T(), resolvedPath, "~") +} + +// ensure the tilde + relative path gets expanded fully +func (s *EnvTestSuite) TestResolveTildePath() { + resolvedPath := ResolveTilde("~/test") + assert.NotEqual(s.T(), resolvedPath, "~/test") +} + +// this is needed to run the test suite +func TestEnvTestSuite(t *testing.T) { + suite.Run(t, new(EnvTestSuite)) +}