Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
markbates committed Oct 19, 2016
0 parents commit 38a7e86
Show file tree
Hide file tree
Showing 10 changed files with 381 additions and 0 deletions.
29 changes: 29 additions & 0 deletions .gitignore
@@ -0,0 +1,29 @@
*.log
.DS_Store
doc
tmp
pkg
*.gem
*.pid
coverage
coverage.data
build/*
*.pbxuser
*.mode1v3
.svn
profile
.console_history
.sass-cache/*
.rake_tasks~
*.log.lck
solr/
.jhw-cache/
jhw.*
*.sublime*
node_modules/
dist/
generated/
.vendor/
bin/*
gin-bin
tasks/
22 changes: 22 additions & 0 deletions LICENSE
@@ -0,0 +1,22 @@
Copyright (c) 2016 Mark Bates

MIT License

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
80 changes: 80 additions & 0 deletions cmd/grifter.go
@@ -0,0 +1,80 @@
package cmd

import (
"html/template"
"io/ioutil"
"os"
"os/exec"
"path"

"github.com/markbates/going/randx"
)

type grifter struct {
CurrentDir string
BuildPath string
TasksPackagePath string
ExePath string
}

func newGrifter() (*grifter, error) {
g := &grifter{}

pwd, err := os.Getwd()
if err != nil {
return g, err
}
g.CurrentDir = pwd
base := randx.String(10)
g.BuildPath = path.Join(os.Getenv("GOPATH"), "src", "grift.build", base)
g.TasksPackagePath = path.Join("grift.build", base, "tasks")
return g, nil
}

func (g *grifter) Setup() error {
err := os.MkdirAll(g.BuildPath, 0777)
if err != nil {
return err
}

return g.Build()
}

func (g *grifter) Build() error {
err := g.copyTasks()
if err != nil {
return err
}

err = ioutil.WriteFile(path.Join(g.BuildPath, "tasks", "grift_loader.go"), []byte(loaderTmpl), 0644)
if err != nil {
return err
}

t, err := template.New("main").Parse(mainTmpl)
if err != nil {
return err
}

f, err := os.Create(path.Join(g.BuildPath, "main.go"))
if err != nil {
return err
}

err = t.Execute(f, g)
if err != nil {
return err
}

g.ExePath = path.Join(g.BuildPath, "main.go")
return nil
}

func (g *grifter) TearDown() error {
return os.RemoveAll(g.BuildPath)
}

func (g *grifter) copyTasks() error {
cp := exec.Command("cp", "-rv", path.Join(g.CurrentDir, "tasks"), g.BuildPath)
return cp.Run()
}
24 changes: 24 additions & 0 deletions cmd/list.go
@@ -0,0 +1,24 @@
package cmd

import (
"os"
"os/exec"

"github.com/spf13/cobra"
)

var listCmd = &cobra.Command{
Use: "list",
RunE: func(cmd *cobra.Command, args []string) error {
rargs := []string{"run", currentGrift.ExePath, "list"}
runner := exec.Command("go", rargs...)
runner.Stderr = os.Stderr
runner.Stdin = os.Stdin
runner.Stdout = os.Stdout
return runner.Run()
},
}

func init() {
RootCmd.AddCommand(listCmd)
}
37 changes: 37 additions & 0 deletions cmd/root.go
@@ -0,0 +1,37 @@
package cmd

import (
"fmt"
"os"

"github.com/spf13/cobra"
)

var currentGrift *grifter

var RootCmd = &cobra.Command{
Use: "grift",
DisableFlagParsing: true,
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
var err error
currentGrift, err = newGrifter()
if err != nil {
return err
}
err = currentGrift.Setup()
if err != nil {
return err
}
return currentGrift.Build()
},
PersistentPostRunE: func(c *cobra.Command, args []string) error {
return currentGrift.TearDown()
},
}

func Execute() {
if err := RootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(-1)
}
}
25 changes: 25 additions & 0 deletions cmd/run.go
@@ -0,0 +1,25 @@
package cmd

import (
"os"
"os/exec"

"github.com/spf13/cobra"
)

var runCmd = &cobra.Command{
Use: "run",
RunE: func(cmd *cobra.Command, args []string) error {
rargs := []string{"run", currentGrift.ExePath}
rargs = append(rargs, os.Args[2:]...)
runner := exec.Command("go", rargs...)
runner.Stdin = os.Stdin
runner.Stdout = os.Stdout
runner.Stderr = os.Stderr
return runner.Run()
},
}

func init() {
RootCmd.AddCommand(runCmd)
}
24 changes: 24 additions & 0 deletions cmd/templates.go
@@ -0,0 +1,24 @@
package cmd

var loaderTmpl = `
package tasks
func Load() {}
`

var mainTmpl = `
package main
import "{{.TasksPackagePath}}"
import "os"
import "log"
import "github.com/markbates/grift/grift"
func main() {
tasks.Load()
err := grift.Exec(os.Args[1:])
if err != nil {
log.Fatal(err)
}
}
`
21 changes: 21 additions & 0 deletions grift/context.go
@@ -0,0 +1,21 @@
package grift

type Context struct {
Args []string
data map[string]interface{}
}

func (c *Context) Get(key string) interface{} {
return c.data[key]
}

func (c *Context) Set(key string, val interface{}) {
c.data[key] = val
}

func NewContext() *Context {
return &Context{
Args: []string{},
data: map[string]interface{}{},
}
}
112 changes: 112 additions & 0 deletions grift/task.go
@@ -0,0 +1,112 @@
package grift

import (
"fmt"
"io"
"log"
"os"
"sort"
"sync"
)

var taskList = map[string]Task{}
var descriptions = map[string]string{}
var lock = &sync.Mutex{}

type Task func(c *Context) error

func Add(name string, task Task) error {
lock.Lock()
defer lock.Unlock()
if taskList[name] != nil {
fn := taskList[name]
taskList[name] = func(c *Context) error {
err := fn(c)
if err != nil {
return err
}
return task(c)
}
} else {
taskList[name] = task
}
return nil
}

func Set(name string, task Task) error {
lock.Lock()
defer lock.Unlock()
taskList[name] = task
return nil
}

func Rename(old string, new string) error {
lock.Lock()
defer lock.Unlock()
if taskList[old] == nil {
return fmt.Errorf("No task named %s defined!", old)
}
taskList[new] = taskList[old]
delete(taskList, old)
return nil
}

func Remove(name string) error {
lock.Lock()
defer lock.Unlock()
delete(taskList, name)
return nil
}

func Desc(name string, description string) error {
lock.Lock()
defer lock.Unlock()
descriptions[name] = description
return nil
}

func Run(name string, c *Context) error {
if taskList[name] == nil {
return fmt.Errorf("No task named %s defined!", name)
}
return taskList[name](c)
}

func TaskNames() []string {
keys := []string{}
for k := range taskList {
keys = append(keys, k)
}
sort.Strings(keys)
return keys
}

func Exec(args []string) error {
name := "default"
if len(args) >= 1 {
name = args[0]
}
switch name {
case "list":
PrintTasks(os.Stdout)
default:
c := NewContext()
c.Args = os.Args[2:]
err := Run(name, c)
if err != nil {
log.Fatal(err)
}
}
return nil
}

func PrintTasks(w io.Writer) {
for _, k := range TaskNames() {
m := fmt.Sprintf("grift run %s", k)
desc := descriptions[k]
if desc != "" {
m = fmt.Sprintf("%s | %s", m, desc)
}
fmt.Fprintln(w, m)
}
}
7 changes: 7 additions & 0 deletions main.go
@@ -0,0 +1,7 @@
package main

import "github.com/markbates/grift/cmd"

func main() {
cmd.Execute()
}

0 comments on commit 38a7e86

Please sign in to comment.