-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b5121d2
commit 4c82459
Showing
7 changed files
with
298 additions
and
92 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,13 @@ | ||
# @customrealms/cli | ||
|
||
CustomRealms command-line tools for setting up and compiling JavaScript Minecraft plugins. | ||
|
||
### Installation | ||
|
||
Install the CLI on your computer: | ||
|
||
```sh | ||
npm install -g @customrealms/cli | ||
``` | ||
|
||
### Start a project |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package main | ||
|
||
import ( | ||
"flag" | ||
"fmt" | ||
"os" | ||
"os/exec" | ||
|
||
"github.com/customrealms/cli/lib" | ||
) | ||
|
||
const DEFAULT_MC_VERSION = "1.17.1" | ||
|
||
func crxBuild() { | ||
|
||
var projectDir string | ||
var mcVersion string | ||
var outputFile string | ||
|
||
flag.StringVar(&projectDir, "p", ".", "plugin project directory") | ||
flag.StringVar(&mcVersion, "mc", DEFAULT_MC_VERSION, "Minecraft version number target") | ||
flag.StringVar(&outputFile, "o", "", "output JAR file path") | ||
|
||
flag.CommandLine.Parse(os.Args[2:]) | ||
|
||
if len(outputFile) == 0 { | ||
fmt.Println("Output JAR file is required: -o option") | ||
os.Exit(1) | ||
} | ||
|
||
// Build the local directory | ||
cmd := exec.Command("npm", "run", "build") | ||
cmd.Dir = projectDir | ||
if err := cmd.Run(); err != nil { | ||
panic(err) | ||
} | ||
|
||
// Define the specification for the JAR template | ||
jarTemplate := lib.JarTemplate{ | ||
MCVersion: mcVersion, | ||
} | ||
|
||
if err := lib.BundleJar( | ||
projectDir, | ||
&jarTemplate, | ||
mcVersion, | ||
outputFile, | ||
); err != nil { | ||
panic(err) | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,43 +1,29 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"strings" | ||
|
||
"github.com/customrealms/cli/lib" | ||
) | ||
|
||
const TEMPLATE_JAR = "/Users/conner/Projects/customrealms/bukkit-runtime/target/bukkit-runtime-jar-with-dependencies.jar" | ||
const output = "/Users/conner/Desktop/mcserver/plugins/bukkit-runtime-jar-with-dependencies.jar" | ||
const VERSION = "0.1.0" | ||
|
||
func main() { | ||
|
||
// Open the output file for the final JAR | ||
file, err := os.Create(output) | ||
if err != nil { | ||
panic(err) | ||
} | ||
defer file.Close() | ||
|
||
// Create a reader for the plugin source code | ||
pluginCode := strings.NewReader("setInterval(() => console.log('YOOOOOO'), 3000)") | ||
|
||
// Define the plugin.yml details for the plugin | ||
pluginYml := lib.PluginYml{ | ||
Name: "MyPlugin", | ||
ApiVersion: "1.17", | ||
Version: "0.0.1", | ||
Main: "io.customrealms.MainPlugin", | ||
// If there are no command line arguments | ||
if len(os.Args) <= 1 { | ||
fmt.Println("Missing command name: build, init") | ||
os.Exit(1) | ||
} | ||
|
||
// Produce the final JAR file | ||
if err := lib.CreateFinalJar( | ||
file, | ||
TEMPLATE_JAR, | ||
pluginCode, | ||
&pluginYml, | ||
); err != nil { | ||
panic(err) | ||
// Get the operation string | ||
switch os.Args[1] { | ||
case "version": | ||
fmt.Printf("customrealms-cli (crx) v%s\n", VERSION) | ||
case "init": | ||
fmt.Println("crx build ... is not yet implemented") | ||
os.Exit(1) | ||
case "build": | ||
crxBuild() | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
package lib | ||
|
||
import ( | ||
"archive/zip" | ||
"bytes" | ||
"encoding/json" | ||
"fmt" | ||
"io" | ||
"os" | ||
"path/filepath" | ||
"strings" | ||
) | ||
|
||
const JAR_MAIN_CLASS = "io.customrealms.MainPlugin" | ||
|
||
type PackageJSON struct { | ||
Name string `json:"name"` | ||
Version string `json:"version"` | ||
} | ||
|
||
func mcVersionToApiVersion(mcVersion string) string { | ||
parts := strings.Split(mcVersion, ".") | ||
return strings.Join(parts[:2], ".") | ||
} | ||
|
||
func BundleJar( | ||
projectDir string, | ||
jarTemplate *JarTemplate, | ||
mcVersion string, | ||
outputFile string, | ||
) error { | ||
|
||
// Download the jar template | ||
var jarTemplateBuf bytes.Buffer | ||
if err := jarTemplate.Download(&jarTemplateBuf); err != nil { | ||
return err | ||
} | ||
|
||
// Make sure the directory above the output file exists | ||
if err := os.MkdirAll(filepath.Dir(outputFile), 0777); err != nil { | ||
return err | ||
} | ||
|
||
// Open the output file for the final JAR | ||
file, err := os.Create(outputFile) | ||
if err != nil { | ||
return err | ||
} | ||
defer file.Close() | ||
|
||
// Create a reader for the plugin source code | ||
pluginCode, err := os.Open(filepath.Join(projectDir, "dist", "bundle.js")) | ||
if err != nil { | ||
return err | ||
} | ||
defer pluginCode.Close() | ||
|
||
// Read the package.json file | ||
packageJsonBytes, err := os.ReadFile(filepath.Join(projectDir, "package.json")) | ||
if err != nil { | ||
return err | ||
} | ||
var packageJson PackageJSON | ||
if err := json.Unmarshal(packageJsonBytes, &packageJson); err != nil { | ||
return err | ||
} | ||
|
||
// Define the plugin.yml details for the plugin | ||
pluginYml := PluginYml{ | ||
Name: packageJson.Name, | ||
ApiVersion: mcVersionToApiVersion(mcVersion), | ||
Version: packageJson.Version, | ||
Main: JAR_MAIN_CLASS, | ||
} | ||
|
||
// Produce the final JAR file | ||
if err := WriteJarFile( | ||
file, | ||
jarTemplateBuf.Bytes(), | ||
pluginCode, | ||
&pluginYml, | ||
); err != nil { | ||
return err | ||
} | ||
|
||
fmt.Println("Wrote JAR file to: ", outputFile) | ||
|
||
return nil | ||
|
||
} | ||
|
||
func WriteJarFile( | ||
writer io.Writer, | ||
templateJarData []byte, | ||
pluginSourceCode io.Reader, | ||
pluginYml *PluginYml, | ||
) error { | ||
|
||
fmt.Println("============================================================") | ||
fmt.Println("Generating final JAR file for your plugin") | ||
fmt.Println("============================================================") | ||
|
||
// Create the ZIP writer | ||
zw := zip.NewWriter(writer) | ||
defer zw.Close() | ||
|
||
// Create the ZIP reader from the base YML | ||
templateJarReader := bytes.NewReader(templateJarData) | ||
zr, err := zip.NewReader(templateJarReader, int64(len(templateJarData))) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
fmt.Println(" -> Copying template files to new JAR file") | ||
|
||
// Copy all the files back to the jar file | ||
for _, f := range zr.File { | ||
|
||
// Skip some files | ||
if f.Name == "plugin.js" || f.Name == "plugin.yml" { | ||
continue | ||
} | ||
|
||
// Copy the rest | ||
if err := zw.Copy(f); err != nil { | ||
return err | ||
} | ||
|
||
} | ||
|
||
fmt.Println(" -> Writing bundle JS code to JAR file") | ||
|
||
// Write the plugin code to the jar | ||
codeFile, err := zw.Create("plugin.js") | ||
if err != nil { | ||
return err | ||
} | ||
if _, err := io.Copy(codeFile, pluginSourceCode); err != nil { | ||
return err | ||
} | ||
|
||
fmt.Println(" -> Writing plugin.yml file to JAR file") | ||
|
||
// Write the plugin YML file to the jar | ||
ymlFile, err := zw.Create("plugin.yml") | ||
if err != nil { | ||
return err | ||
} | ||
if _, err := io.Copy(ymlFile, strings.NewReader(pluginYml.String())); err != nil { | ||
return err | ||
} | ||
|
||
fmt.Println(" -> DONE") | ||
fmt.Println() | ||
|
||
// We're done, no errors | ||
return nil | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
package lib | ||
|
||
import ( | ||
"fmt" | ||
"io" | ||
"net/http" | ||
"runtime" | ||
) | ||
|
||
type JarTemplate struct { | ||
Platform string | ||
MCVersion string | ||
} | ||
|
||
func (jt *JarTemplate) normalizePlatform() string { | ||
if len(jt.Platform) > 0 { | ||
return jt.Platform | ||
} | ||
if runtime.GOOS == "darwin" { | ||
return "macos" | ||
} | ||
return runtime.GOOS | ||
} | ||
|
||
func (jt *JarTemplate) getJarUrl() string { | ||
return fmt.Sprintf( | ||
"https://github.com/customrealms/bukkit-runtime/releases/latest/download/bukkit-runtime-%s-%s.jar", | ||
jt.normalizePlatform(), | ||
jt.MCVersion, | ||
) | ||
} | ||
|
||
func (jt *JarTemplate) Download(writer io.Writer) error { | ||
|
||
fmt.Println("============================================================") | ||
fmt.Println("Downloading JAR plugin runtime") | ||
fmt.Println("============================================================") | ||
|
||
// Get the JAR url | ||
jarUrl := jt.getJarUrl() | ||
|
||
// Download the JAR file | ||
fmt.Printf(" -> %s\n", jarUrl) | ||
res, err := http.Get(jarUrl) | ||
if err != nil { | ||
return err | ||
} | ||
defer res.Body.Close() | ||
|
||
// Pipe the response body to the writer | ||
if _, err := io.Copy(writer, res.Body); err != nil { | ||
return err | ||
} | ||
|
||
fmt.Println(" -> DONE") | ||
fmt.Println() | ||
|
||
// Return without error | ||
return nil | ||
|
||
} |
Oops, something went wrong.