Skip to content

Commit

Permalink
Add beginnings of plugin install command
Browse files Browse the repository at this point in the history
  • Loading branch information
jacobwgillespie committed Nov 21, 2015
1 parent 293e010 commit a0ab402
Show file tree
Hide file tree
Showing 9 changed files with 277 additions and 3 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
mc
server.yml
*.exe
*.*~
*.swp
Expand Down
5 changes: 3 additions & 2 deletions command.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ import (
)

type Command struct {
Run func(cmd *Command, args []string)
Flag flag.FlagSet
Run func(cmd *Command, args []string)
Flag flag.FlagSet
NeedsServer bool

Usage string // first word must be command name
Category string
Expand Down
59 changes: 59 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package main

import (
"io/ioutil"
"os"

"github.com/the-obsidian/mc/plugin"

"gopkg.in/yaml.v2"
)

type Config struct {
Plugins []*plugin.Plugin

unknownKeys []string
}

func NewConfigFromString(data string) (*Config, error) {
c := Config{}

err := yaml.Unmarshal([]byte(data), &c)
if err != nil {
return nil, err
}

for _, plugin := range c.Plugins {
err = plugin.Init()
if err != nil {
return nil, err
}
}

return &c, nil
}

func NewConfigFromFile(path string) (*Config, error) {
data, err := ioutil.ReadFile(path)
if err != nil {
return nil, err
}

return NewConfigFromString(string(data))
}

func (c *Config) InstallPlugins() error {
err := os.MkdirAll("plugins", 0755)
if err != nil {
return err
}

for _, plugin := range c.Plugins {
err = plugin.Install()
if err != nil {
return err
}
}

return nil
}
38 changes: 38 additions & 0 deletions install.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package main

import "os"

var cmdInstall = &Command{
NeedsServer: true,
Usage: "install",
Category: "app",
Short: "install dependencies",
Long: `
Install installs any required dependencies.
Examples:
$ mc install
`,
}

func init() {
cmdInstall.Run = runInstall
}

func runInstall(cmd *Command, args []string) {
if len(args) != 0 {
printUsageTo(os.Stderr)
os.Exit(2)
}

config, err := NewConfigFromFile("server.yml")
if err != nil {
printFatal("Error reading config file: %v", err)
}

err = config.InstallPlugins()
if err != nil {
printFatal("failed to install plugins: %v", err)
}
}
9 changes: 8 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
)

var commands = []*Command{
//cmdInstall,
cmdInstall,
//cmdVersion,
cmdHelp,

Expand Down Expand Up @@ -56,6 +56,13 @@ func main() {
cmd.Flag.Usage = func() {
cmd.PrintUsage()
}

if cmd.NeedsServer {
if exists, err := fileExists("server.yml"); err != nil || !exists {
printFatal("server.yml not found - is this a server directory?")
}
}

if err := cmd.Flag.Parse(args[1:]); err == flag.ErrHelp {
cmdHelp.Run(cmdHelp, args[:1])
} else if err != nil {
Expand Down
101 changes: 101 additions & 0 deletions plugin/plugin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package plugin

import (
"crypto/sha1"
"fmt"
"os"
"path"

"github.com/hashicorp/go-getter"
"github.com/the-obsidian/mc/util"
)

type Plugin struct {
Name string
URI string
Sha string
Processors []Processor `yaml:"-"`

originalProcessors []map[string]interface{} `yaml:"processors"`
}

func (p *Plugin) Init() error {
for _, pr := range p.originalProcessors {
processor, err := NewProcessorFromConfig(p, pr)
if err != nil {
return err
}
p.Processors = append(p.Processors, processor)
}

return nil
}

func (p *Plugin) Install() error {
dest := path.Join(".", "plugins", p.Name+".jar")
tmpDir := path.Join(".", ".tmp", "plugins", p.Name)
tmpDownload := path.Join(tmpDir, "download")
hash := sha1.New()

checksumValue, err := decodeChecksum(p.Sha)
if err != nil {
return err
}

if exists, err := util.FileExists(dest); err != nil {
return err
} else if exists {
err = checksum(dest, hash, checksumValue)
if err == nil {
return nil
}
}

err = os.MkdirAll(tmpDir, 0755)
if err != nil {
return err
}

err = getter.GetFile(tmpDownload, p.URI)
if err != nil {
return err
}

err = checksum(tmpDownload, hash, checksumValue)
if err != nil {
return fmt.Errorf("failed to checksum download: %v", err)
}

err = os.Rename(tmpDownload, dest)
if err != nil {
return err
}

return nil
}

type Processor interface {
Process()
}

func NewProcessorFromConfig(p *Plugin, config map[string]interface{}) (Processor, error) {
switch config["type"] {
case "unzip":
pr := &UnzipProcessor{
Type: "unzip",
Files: config["files"].([]string),
}
return pr, nil
default:
return nil, fmt.Errorf("invalid processor type: %v", config["type"])
}

return nil, nil
}

type UnzipProcessor struct {
Type string
Files []string
}

func (pr *UnzipProcessor) Process() {}
40 changes: 40 additions & 0 deletions plugin/util.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package plugin

import (
"bytes"
"encoding/hex"
"fmt"
"hash"
"io"
"os"
)

func decodeChecksum(data string) ([]byte, error) {
b, err := hex.DecodeString(data)
if err != nil {
return nil, fmt.Errorf("invalid checksum: %s", err)
}
return b, nil
}

func checksum(source string, h hash.Hash, v []byte) error {
f, err := os.Open(source)
if err != nil {
return fmt.Errorf("Failed to open file for checksum: %s", err)
}
defer f.Close()

if _, err := io.Copy(h, f); err != nil {
return fmt.Errorf("Failed to hash: %s", err)
}

if actual := h.Sum(nil); !bytes.Equal(actual, v) {
return fmt.Errorf(
"Checksums did not match.\nExpected: %s\nGot: %s",
hex.EncodeToString(v),
hex.EncodeToString(actual),
)
}

return nil
}
13 changes: 13 additions & 0 deletions util.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,23 @@ package main
import (
"fmt"
"log"
"os"

"github.com/mgutz/ansi"
)

// exists returns whether the given file or directory exists or not
func fileExists(path string) (bool, error) {
_, err := os.Stat(path)
if err == nil {
return true, nil
}
if os.IsNotExist(err) {
return false, nil
}
return false, err
}

func printError(message string, args ...interface{}) {
log.Println(colorizeMessage("red", "error:", message, args...))
}
Expand Down
14 changes: 14 additions & 0 deletions util/util.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package util

import "os"

func FileExists(path string) (bool, error) {
_, err := os.Stat(path)
if err == nil {
return true, nil
}
if os.IsNotExist(err) {
return false, nil
}
return false, err
}

0 comments on commit a0ab402

Please sign in to comment.