Skip to content
This repository has been archived by the owner on Jun 27, 2020. It is now read-only.

Commit

Permalink
app/scriptpack: scriptpack-rebuild command
Browse files Browse the repository at this point in the history
  • Loading branch information
mitchellh committed Dec 16, 2015
1 parent bbbea95 commit a95dad3
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 6 deletions.
69 changes: 65 additions & 4 deletions builtin/app/scriptpack/app.go
Expand Up @@ -2,12 +2,17 @@ package scriptpackapp

import (
"fmt"
"os/exec"
"path/filepath"
"strings"

"github.com/hashicorp/otto/app"
"github.com/hashicorp/otto/appfile"
"github.com/hashicorp/otto/builtin/app/go"
"github.com/hashicorp/otto/helper/bindata"
"github.com/hashicorp/otto/helper/compile"
execHelper "github.com/hashicorp/otto/helper/exec"
"github.com/hashicorp/otto/helper/router"
"github.com/hashicorp/otto/helper/vagrant"
)

Expand All @@ -25,12 +30,28 @@ func (a *App) Implicit(ctx *app.Context) (*appfile.File, error) {
}

func (a *App) Compile(ctx *app.Context) (*app.CompileResult, error) {
// Get the import path for this
path, err := goapp.DetectImportPath(ctx)
if err != nil {
return nil, err
}
if path == "" {
return nil, fmt.Errorf(
"Your ScriptPack development folder must be within your GOPATH like\n" +
"a standard Go project. This is required for the dev environment\n" +
"to function properly. Please put this folder in a proper GOPATH\n" +
"location.")
}

var opts compile.AppOptions
opts = compile.AppOptions{
Ctx: ctx,
Bindata: &bindata.Data{
Asset: Asset,
AssetDir: AssetDir,
Context: map[string]interface{}{
"working_gopath": path,
},
},
}

Expand All @@ -46,22 +67,47 @@ func (a *App) Deploy(ctx *app.Context) error {
}

func (a *App) Dev(ctx *app.Context) error {
// Build the actual development environment
return vagrant.Dev(&vagrant.DevOptions{
r := vagrant.Dev(&vagrant.DevOptions{
Instructions: strings.TrimSpace(devInstructions),
}).Route(ctx)
})

// Add our customer actions
r.Actions["scriptpack-rebuild"] = &router.SimpleAction{
ExecuteFunc: a.actionRebuild,
SynopsisText: actionRebuildSyn,
HelpText: strings.TrimSpace(actionRebuildHelp),
}

return r.Route(ctx)
}

func (a *App) DevDep(dst, src *app.Context) (*app.DevDep, error) {
return nil, fmt.Errorf("A ScriptPack can't be a dependency")
}

func (a *App) actionRebuild(rctx router.Context) error {
ctx := rctx.(*app.Context)

// Get the path to the rebuild binary
path := filepath.Join(ctx.Dir, "rebuild", "rebuild.go")

// Run it to regenerate the contents
cmd := exec.Command("go", "run", path)
if err := execHelper.Run(ctx.Ui, cmd); err != nil {
return err
}

// Success
ctx.Ui.Raw("ScriptPack data rebuilt!\n")
return nil
}

const devInstructions = `
A development environment has been created for testing this ScriptPack.
Anytime you change the contents of the ScriptPack, you must run
"otto dev scriptpack-rebuild". This will update the contents in the
dev environment.
dev environment. This is a very fast operation.
To run tests, you can use "otto dev scriptpack-test" with the path
to the directory or BATS test file to run. This will be automatically
Expand All @@ -72,3 +118,18 @@ const buildErr = `
Build and deploy aren't supported for ScriptPacks since it doesn't
make a lot of sense.
`

const (
actionRebuildSyn = "Rebuild ScriptPack output for dev and test"
)

const actionRebuildHelp = `
Usage: otto dev scriptpack-rebuild
Rebuilds the ScriptPack files and dependencies into a single directory
for dev and test within the development environment.
This command must be run before running tests after making any changes
to the ScriptPack.
`
33 changes: 33 additions & 0 deletions builtin/app/scriptpack/data/common/rebuild/rebuild.go.tpl
@@ -0,0 +1,33 @@
package main

import (
"fmt"
"log"
"io/ioutil"
"os"
"path/filepath"

sp "{{ working_gopath }}"
)

func main() {
// Logs don't matter for this since it should always work. If it
// doesn't, it will show up in the error output.
log.SetOutput(ioutil.Discard)
path := filepath.Join("{{ path.working }}", "_staging")
if err := os.RemoveAll(path); err !=nil {
fmt.Fprintf(os.Stderr, err.Error()+"\n")
os.Exit(1)
}

if err := os.MkdirAll(path, 0755); err != nil {
fmt.Fprintf(os.Stderr, err.Error()+"\n")
os.Exit(1)
}

if err := sp.ScriptPack.Write(path); err !=nil {
fmt.Fprintf(os.Stderr, err.Error()+"\n")
os.Exit(1)
}
}
9 changes: 7 additions & 2 deletions helper/exec/exec.go
Expand Up @@ -22,13 +22,15 @@ func Run(uiVal ui.Ui, cmd *exec.Cmd) error {
cmd.Stderr = out_w

// Copy output to the UI until we can't.
output := false
uiDone := make(chan struct{})
go func() {
defer close(uiDone)
var buf [1024]byte
for {
n, err := out_r.Read(buf[:])
if n > 0 {
output = true
uiVal.Raw(string(buf[:n]))
}

Expand Down Expand Up @@ -57,8 +59,11 @@ func Run(uiVal ui.Ui, cmd *exec.Cmd) error {
out_w.Close()
<-uiDone

// Output one extra newline to separate output from Otto
uiVal.Message("")
if output {
// Output one extra newline to separate output from Otto. We only
// do this if there was any output to begin with.
uiVal.Message("")
}

// Return the output from the command
return err
Expand Down

0 comments on commit a95dad3

Please sign in to comment.