Skip to content

Commit

Permalink
Added build command
Browse files Browse the repository at this point in the history
  • Loading branch information
connerdouglass committed Nov 11, 2021
1 parent b5121d2 commit 4c82459
Show file tree
Hide file tree
Showing 7 changed files with 298 additions and 92 deletions.
10 changes: 10 additions & 0 deletions README.md
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
52 changes: 52 additions & 0 deletions cmd/crx/build.go
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)
}

}
44 changes: 15 additions & 29 deletions cmd/crx/main.go
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()
}

}
159 changes: 159 additions & 0 deletions lib/bundler.go
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

}
61 changes: 61 additions & 0 deletions lib/jar_template.go
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

}
Loading

0 comments on commit 4c82459

Please sign in to comment.