Skip to content

Commit

Permalink
Add support for go module when running generate command (onsi#578)
Browse files Browse the repository at this point in the history
Typo fix

This changes how `generate` command looks for import path. Now it will
try to find `go.mod` file and determine import path from there first,
and will fallback to old way otherwise.

[Fixes onsi#524]
  • Loading branch information
leninhasda authored and blgm committed Nov 19, 2019
1 parent 9059714 commit 9c89e3f
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 1 deletion.
81 changes: 81 additions & 0 deletions ginkgo/generate_command.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package main

import (
"bytes"
"flag"
"fmt"
"os"
"path/filepath"
"strconv"
"strings"
"text/template"
)
Expand Down Expand Up @@ -158,11 +160,90 @@ func formatSubject(name string) string {
return name
}

// moduleName returns module name from go.mod from given module root directory
func moduleName(modRoot string) string {
modFile, err := os.Open(filepath.Join(modRoot, "go.mod"))
if err != nil {
return ""
}

mod := make([]byte, 128)
_, err = modFile.Read(mod)
if err != nil {
return ""
}

slashSlash := []byte("//")
moduleStr := []byte("module")

for len(mod) > 0 {
line := mod
mod = nil
if i := bytes.IndexByte(line, '\n'); i >= 0 {
line, mod = line[:i], line[i+1:]
}
if i := bytes.Index(line, slashSlash); i >= 0 {
line = line[:i]
}
line = bytes.TrimSpace(line)
if !bytes.HasPrefix(line, moduleStr) {
continue
}
line = line[len(moduleStr):]
n := len(line)
line = bytes.TrimSpace(line)
if len(line) == n || len(line) == 0 {
continue
}

if line[0] == '"' || line[0] == '`' {
p, err := strconv.Unquote(string(line))
if err != nil {
return "" // malformed quoted string or multiline module path
}
return p
}

return string(line)
}

return "" // missing module path
}

func findModuleRoot(dir string) (root string) {
dir = filepath.Clean(dir)

// Look for enclosing go.mod.
for {
if fi, err := os.Stat(filepath.Join(dir, "go.mod")); err == nil && !fi.IsDir() {
return dir
}
d := filepath.Dir(dir)
if d == dir {
break
}
dir = d
}
return ""
}

func getPackageImportPath() string {
workingDir, err := os.Getwd()
if err != nil {
panic(err.Error())
}

// Try go.mod file first
modRoot := findModuleRoot(workingDir)
if modRoot != "" {
modName := moduleName(modRoot)
if modName != "" {
cd := strings.Replace(workingDir, modRoot, "", -1)
return modName + cd
}
}

// Fallback to GOPATH structure
sep := string(filepath.Separator)
paths := strings.Split(workingDir, sep+"src"+sep)
if len(paths) == 1 {
Expand Down
2 changes: 1 addition & 1 deletion types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ SuiteSummary represents the a summary of the test suite and is passed to both
Reporter.SpecSuiteWillBegin
Reporter.SpecSuiteDidEnd
this is unfortunate as these two methods should receive different objects. When running in parallel
this is unfortunate as these two methods should receive different objects. When running in parallel
each node does not deterministically know how many specs it will end up running.
Unfortunately making such a change would break backward compatibility.
Expand Down

0 comments on commit 9c89e3f

Please sign in to comment.