Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 15 additions & 7 deletions cmd/goa/gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ type Generator struct {
// Output is the absolute path to the output directory.
Output string

// ServiceOutput is the absolute path to the example service output directory.
ServiceOutput string

// DesignVersion is the major component of the Goa version used by the design DSL.
// DesignVersion is either 2 or 3.
DesignVersion int
Expand All @@ -45,7 +48,7 @@ type Generator struct {
}

// NewGenerator creates a Generator.
func NewGenerator(cmd, path, output string, debug bool) *Generator {
func NewGenerator(cmd, path, output, serviceOutput string, debug bool) *Generator {
bin := "goa"
if runtime.GOOS == "windows" {
bin += ".exe"
Expand Down Expand Up @@ -96,6 +99,7 @@ func NewGenerator(cmd, path, output string, debug bool) *Generator {
Command: cmd,
DesignPath: path,
Output: output,
ServiceOutput: serviceOutput,
DesignVersion: version,
hasVendorDirectory: hasVendorDirectory,
bin: bin,
Expand Down Expand Up @@ -229,7 +233,7 @@ func (g *Generator) Run(debug bool) ([]string, error) {
cmdl = fmt.Sprintf("$ %s%s", rawcmd, cmdl)
}

args := []string{"--version=" + strconv.Itoa(g.DesignVersion), "--output=" + g.Output, "--cmd=" + cmdl, "--debug=" + strconv.FormatBool(debug)}
args := []string{"--version=" + strconv.Itoa(g.DesignVersion), "--output=" + g.Output, "--service-output=" + g.ServiceOutput, "--cmd=" + cmdl, "--debug=" + strconv.FormatBool(debug)}
cmd := exec.Command(filepath.Join(g.tmpDir, g.bin), args...)
out, err := cmd.CombinedOutput()
if err != nil {
Expand Down Expand Up @@ -307,17 +311,21 @@ func cleanupDirs(cmd, output string) []string {
// mainT is the template for the generator main.
const mainT = `func main() {
var (
out = flag.String("output", "", "")
version = flag.String("version", "", "")
cmdl = flag.String("cmd", "", "")
debug = flag.Bool("debug", false, "")
out = flag.String("output", "", "")
serviceOut = flag.String("service-output", "", "")
version = flag.String("version", "", "")
cmdl = flag.String("cmd", "", "")
debug = flag.Bool("debug", false, "")
ver int
)
{
flag.Parse()
if *out == "" {
fail("missing output flag")
}
if *serviceOut == "" {
*serviceOut = *out
}
if *version == "" {
fail("missing version flag")
}
Expand Down Expand Up @@ -366,7 +374,7 @@ const mainT = `func main() {
{{- end }}

startGenerate := time.Now()
outputs, err := generator.Generate(*out, {{ printf "%q" .Command }}, *debug)
outputs, err := generator.Generate(*out, {{ printf "%q" .Command }}, *serviceOut, *debug)
if err != nil {
fail(err.Error())
}
Expand Down
30 changes: 21 additions & 9 deletions cmd/goa/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,16 @@ func main() {
}

var (
output = "."
debug bool
output = "."
serviceOutput = ""
debug bool
)
if len(os.Args) > offset+1 {
var (
fset = flag.NewFlagSet("default", flag.ExitOnError)
o = fset.String("o", "", "output `directory`")
out = fset.String("output", output, "output `directory`")
fset = flag.NewFlagSet("default", flag.ExitOnError)
o = fset.String("o", "", "output `directory`")
out = fset.String("output", output, "output `directory`")
serviceOut = fset.String("service-output", "", "service output `directory`")
)
fset.BoolVar(&debug, "debug", false, "Print debug information")

Expand All @@ -62,9 +64,16 @@ func main() {
if output == "" {
output = *out
}
serviceOutput = *serviceOut
if serviceOutput == "" {
serviceOutput = output
}
}
if serviceOutput == "" {
serviceOutput = output
}

if err := gen(cmd, path, output, debug); err != nil {
if err := gen(cmd, path, output, serviceOutput, debug); err != nil {
fmt.Fprintln(os.Stderr, err.Error())
os.Exit(1)
}
Expand All @@ -76,7 +85,7 @@ var (
gen = generate
)

func generate(cmd, path, output string, debug bool) error {
func generate(cmd, path, output, serviceOutput string, debug bool) error {
var (
files []string
err error
Expand All @@ -99,7 +108,7 @@ func generate(cmd, path, output string, debug bool) error {
}

startNewGen = time.Now()
tmp = NewGenerator(cmd, path, output, debug)
tmp = NewGenerator(cmd, path, output, serviceOutput, debug)
if debug {
fmt.Fprintf(os.Stderr, "[TIMING] NewGenerator took %v\n", time.Since(startNewGen))
}
Expand Down Expand Up @@ -146,7 +155,7 @@ Learn more at https://goa.design.

Usage:
goa gen PACKAGE [--output DIRECTORY] [--debug]
goa example PACKAGE [--output DIRECTORY] [--debug]
goa example PACKAGE [--output DIRECTORY] [--service-output DIRECTORY] [--debug]
goa version

Commands:
Expand All @@ -165,6 +174,9 @@ Flags:
-o, -output DIRECTORY
output directory, defaults to the current working directory

-service-output DIRECTORY
service example output directory, defaults to the output directory

-debug
Print debug information (mainly intended for Goa developers)

Expand Down
47 changes: 29 additions & 18 deletions cmd/goa/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,37 +12,44 @@ func TestCmdLine(t *testing.T) {
testOutput = "testOutput"
)
var (
usageCalled bool
cmd string
path, output string
debug bool
usageCalled bool
cmd string
path, output string
serviceOutput string
debug bool
)

usage = func() { usageCalled = true }
gen = func(c string, p, o string, d bool) error { cmd, path, output, debug = c, p, o, d; return nil }
gen = func(c, p, o, so string, d bool) error {
cmd, path, output, serviceOutput, debug = c, p, o, so, d
return nil
}
defer func() {
usage = help
gen = generate
}()

cases := map[string]struct {
CmdLine string
ExpectedUsage bool
ExpectedCommand string
ExpectedPath string
ExpectedOutput string
ExpectedDebug bool
CmdLine string
ExpectedUsage bool
ExpectedCommand string
ExpectedPath string
ExpectedOutput string
ExpectedServiceOutput string
ExpectedDebug bool
}{
"gen": {"gen " + testPkg, false, "gen", testPkg, ".", false},
"gen": {"gen " + testPkg, false, "gen", testPkg, ".", ".", false},
"example default": {"example " + testPkg, false, "example", testPkg, ".", ".", false},

"invalid": {"invalid " + testPkg, true, "", "", "", false},
"empty": {"", true, "", "", "", false},
"invalid gen": {"invalid gen" + testPkg, true, "", "", "", false},
"invalid": {"invalid " + testPkg, true, "", "", "", "", false},
"empty": {"", true, "", "", "", "", false},
"invalid gen": {"invalid gen" + testPkg, true, "", "", "", "", false},

"output": {"gen " + testPkg + " -output " + testOutput, false, "gen", testPkg, testOutput, false},
"output short": {"gen " + testPkg + " -o " + testOutput, false, "gen", testPkg, testOutput, false},
"output": {"gen " + testPkg + " -output " + testOutput, false, "gen", testPkg, testOutput, testOutput, false},
"output short": {"gen " + testPkg + " -o " + testOutput, false, "gen", testPkg, testOutput, testOutput, false},
"service-output": {"example " + testPkg + " -service-output " + testOutput, false, "example", testPkg, ".", testOutput, false},

"debug": {"gen " + testPkg + " -debug", false, "gen", testPkg, ".", true},
"debug": {"gen " + testPkg + " -debug", false, "gen", testPkg, ".", ".", true},
}

for k, c := range cases {
Expand All @@ -53,6 +60,7 @@ func TestCmdLine(t *testing.T) {
cmd = ""
path = ""
output = ""
serviceOutput = ""
debug = false
}

Expand All @@ -70,6 +78,9 @@ func TestCmdLine(t *testing.T) {
if output != c.ExpectedOutput {
t.Errorf("%s: Expected output to be %s but got %s", k, c.ExpectedOutput, output)
}
if serviceOutput != c.ExpectedServiceOutput {
t.Errorf("%s: Expected service output to be %s but got %s", k, c.ExpectedServiceOutput, serviceOutput)
}
if debug != c.ExpectedDebug {
t.Errorf("%s: Expected debug to be %v but got %v", k, c.ExpectedDebug, debug)
}
Expand Down
9 changes: 8 additions & 1 deletion codegen/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ type (
SectionTemplates []*SectionTemplate
// Path returns the file path relative to the output directory.
Path string
// OutputDir overrides the base directory used when rendering the file.
// When empty, Render uses the directory passed as argument.
OutputDir string
// SkipExist indicates whether the file should be skipped if one
// already exists at the given path.
SkipExist bool
Expand Down Expand Up @@ -70,7 +73,11 @@ func (f *File) Section(name string) []*SectionTemplate {
// happens the smallest integer value greater than 1 to make it unique. Renders
// returns the computed path.
func (f *File) Render(dir string) (string, error) {
base, err := filepath.Abs(dir)
baseDir := dir
if f.OutputDir != "" {
baseDir = f.OutputDir
}
base, err := filepath.Abs(baseDir)
if err != nil {
return "", err
}
Expand Down
4 changes: 2 additions & 2 deletions codegen/generator/example.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (

// Example iterates through the roots and returns files that implement an
// example service, server, and client.
func Example(genpkg string, roots []eval.Root) ([]*codegen.File, error) {
func Example(genpkg string, roots []eval.Root, serviceOutput string) ([]*codegen.File, error) {
var files []*codegen.File
for _, root := range roots {
r, ok := root.(*expr.RootExpr)
Expand All @@ -25,7 +25,7 @@ func Example(genpkg string, roots []eval.Root) ([]*codegen.File, error) {
services := service.NewServicesData(r)

// example service implementation
if fs := service.ExampleServiceFiles(genpkg, r, services); len(fs) != 0 {
if fs := service.ExampleServiceFiles(genpkg, r, services, serviceOutput); len(fs) != 0 {
files = append(files, fs...)
}

Expand Down
4 changes: 2 additions & 2 deletions codegen/generator/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (
)

// Generate runs the code generation algorithms.
func Generate(dir, cmd string, debug bool) (outputs []string, err1 error) {
func Generate(dir, cmd, serviceOutput string, debug bool) (outputs []string, err1 error) {
startGenerate := time.Now()
if debug {
fmt.Fprintf(os.Stderr, "[TIMING] [generate] Starting generator.Generate()\n")
Expand Down Expand Up @@ -119,7 +119,7 @@ func Generate(dir, cmd string, debug bool) (outputs []string, err1 error) {
start := time.Now()
for i, gen := range genfuncs {
genStart := time.Now()
fs, err := gen(genpkg, roots)
fs, err := gen(genpkg, roots, serviceOutput)
if err != nil {
return nil, err
}
Expand Down
Loading