Skip to content

Commit

Permalink
Relax rules on code blocks, allowing three spaces (resolves #35)
Browse files Browse the repository at this point in the history
Fix issue with packages that appear in both vendor/ and GOPATH (resolves #34)
'Open Terminal' support for linux/windows/etc (resolves #28)
  • Loading branch information
KyleBanks committed Mar 24, 2017
1 parent a2d39f0 commit ab50720
Show file tree
Hide file tree
Showing 20 changed files with 346 additions and 146 deletions.
2 changes: 0 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,5 @@ go:
before_install:
- go get github.com/mattn/goveralls

# Note: Need to ignore all cmd/goggles files because gallium will not work on the linix travis instances.
script:
- rm -rf cmd/goggles/
- $HOME/gopath/bin/goveralls -service=travis-ci -ignore server/assets/bindata_assetfs.go
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ assets:
npm install ; \
gulp

@go-bindata-assetfs -ignore=node_modules -pkg assets static/... ; \
@go-bindata-assetfs -ignore=node_modules\|.DS_Store -pkg assets static/... ; \
mv bindata_assetfs.go server/assets/
.PHONY: assets

Expand Down
24 changes: 15 additions & 9 deletions cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import (
"os"

"github.com/KyleBanks/goggles"
"github.com/KyleBanks/goggles/conf"
"github.com/KyleBanks/goggles/pkg/sys"
"github.com/KyleBanks/goggles/server"
"github.com/KyleBanks/goggles/server/api"
)

const (
Expand All @@ -24,35 +24,41 @@ var (

// Index is the URL of the root index.html file.
Index = fmt.Sprintf("http://127.0.0.1:%v/static/index.html", port)

defaultProvider api.Provider = provider{goggles.Resolver{}}
)

func init() {
initConfig()

log.Printf("$GOPATH=%v, srcdir=%v", sys.Gopath(), sys.Srcdir())
}

func initConfig() {
c := defaultProvider.Preferences()

// Update the $GOPATH if a custom value is set.
c := conf.Get()
if c != nil && len(c.Gopath) > 0 {
if len(c.Gopath) > 0 {
sys.SetGopath(c.Gopath)
}

log.Printf("$GOPATH=%v, srcdir=%v", sys.Gopath(), sys.Srcdir())
}

// StartServer starts the application server.
func StartServer() {
p := provider{goggles.Resolver{}}
api := server.New(p)
api := server.New(defaultProvider)
addr := fmt.Sprintf(":%v", port)

log.Fatal(http.ListenAndServe(addr, api))
}

// OpenAbout opens the 'About' page in a web browser.
func OpenAbout() {
sys.OpenBrowser(aboutURL)
defaultProvider.OpenBrowser(aboutURL)
}

// OpenThanks opens the 'Thanks' page in a web browser.
func OpenThanks() {
sys.OpenBrowser(thanksURL)
defaultProvider.OpenBrowser(thanksURL)
}

// Quit terminates the running application.
Expand Down
61 changes: 61 additions & 0 deletions cmd/cmd_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package cmd

import (
"reflect"
"testing"

"github.com/KyleBanks/goggles/conf"
"github.com/KyleBanks/goggles/pkg/sys"
)

func Test_initConfig(t *testing.T) {
tests := []struct {
in string
expect []string
}{
{"", sys.Gopath()},
{"/foo/bar", []string{"/foo/bar"}},
{"/foo/bar:/foo/bar/baz", []string{"/foo/bar", "/foo/bar/baz"}},
}

for idx, tt := range tests {
defaultProvider = &mockProvider{
preferencesFn: func() *conf.Config {
return &conf.Config{Gopath: tt.in}
},
}

initConfig()

if out := sys.Gopath(); !reflect.DeepEqual(out, tt.expect) {
t.Fatalf("[%v] Unexpected Gopath, expected=%v, got=%v", idx, tt.expect, out)
}
}
}

func Test_OpenLinks(t *testing.T) {
tests := []struct {
expect string
fn func()
}{
{aboutURL, OpenAbout},
{thanksURL, OpenThanks},
}

for _, tt := range tests {
var called bool
defaultProvider = &mockProvider{
OpenBrowserFn: func(s string) {
if s != tt.expect {
t.Fatalf("Unexpected URL, expected=%v, got=%v", tt.expect, s)
}
called = true
},
}

tt.fn()
if !called {
t.Fatal("Expected OpenBrowser to be called")
}
}
}
11 changes: 6 additions & 5 deletions cmd/goggles/goggles.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ import (
)

func main() {
go func() {
time.Sleep(time.Millisecond * 500)
sys.OpenBrowser(cmd.Index)
}()

go openBrowser(time.Millisecond * 500)
cmd.StartServer()
}

func openBrowser(delay time.Duration) {
time.Sleep(delay)
sys.OpenBrowser(cmd.Index)
}
50 changes: 50 additions & 0 deletions cmd/provider_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package cmd

import (
"testing"

"github.com/KyleBanks/goggles"
"github.com/KyleBanks/goggles/conf"
"github.com/KyleBanks/goggles/pkg/sys"
)

type mockProvider struct {
ListFn func() ([]*goggles.Package, error)
DetailsFn func(string) (*goggles.Package, error)

OpenFileExplorerFn func(string)
OpenTerminalFn func(string)
OpenBrowserFn func(string)

preferencesFn func() *conf.Config
updatePreferencesFn func(*conf.Config)
}

func (m *mockProvider) List() ([]*goggles.Package, error) { return m.ListFn() }
func (m *mockProvider) Details(n string) (*goggles.Package, error) { return m.DetailsFn(n) }
func (m *mockProvider) OpenFileExplorer(n string) { m.OpenFileExplorerFn(n) }
func (m *mockProvider) OpenTerminal(n string) { m.OpenTerminalFn(n) }
func (m *mockProvider) OpenBrowser(n string) { m.OpenBrowserFn(n) }
func (m *mockProvider) Preferences() *conf.Config { return m.preferencesFn() }
func (m *mockProvider) UpdatePreferences(c *conf.Config) { m.updatePreferencesFn(c) }

func TestProvider_Preferences(t *testing.T) {
var p provider

c := p.Preferences()
if c == nil {
t.Fatal("Unexpected nil Config")
}
}

func TestProvider_UpdatePreferences(t *testing.T) {
var p provider

c := p.Preferences()
sys.SetGopath("/not/a/real/gopath")
p.UpdatePreferences(c)

if sys.RawGopath() != c.Gopath {
t.Fatalf("Unexpected RawGopath, expected=%v, got=%v", c.Gopath, sys.RawGopath())
}
}
12 changes: 12 additions & 0 deletions conf/conf.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package conf

import (
"github.com/KyleBanks/go-kit/storage"
"github.com/KyleBanks/goggles/pkg/sys"
)

type saveLoader interface {
Expand All @@ -14,13 +15,24 @@ var store saveLoader = storage.NewFileStore("goggles", "goggles.conf")

// Config contains Goggles configuration.
type Config struct {
// user configurable

Gopath string `json:"gopath"`

// system values
// these values will be ignored in the persisted file

CanOpenTerminal bool `json:"canOpenTerminal"`
}

// Get returns the persisted Config.
func Get() *Config {
var c Config
store.Load(&c)

// Apply system-configurations
c.CanOpenTerminal = sys.CanOpenTerminal

return &c
}

Expand Down
4 changes: 4 additions & 0 deletions conf/conf_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package conf

import (
"testing"

"github.com/KyleBanks/goggles/pkg/sys"
)

type mockSaveLoader struct {
Expand All @@ -28,6 +30,8 @@ func Test_Get(t *testing.T) {
c := Get()
if c.Gopath != expect {
t.Fatalf("Expected Config returned, expected=%v, got=%v", expect, c)
} else if c.CanOpenTerminal != sys.CanOpenTerminal {
t.Fatalf("Unexpected CanOpenTerminal, expected=%v, got=%v", !c.CanOpenTerminal, c.CanOpenTerminal)
}
}

Expand Down
43 changes: 39 additions & 4 deletions package.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,14 @@ func NewPackage(path string) (*Package, error) {
ResolveInternal: false,
MaxDepth: 1,
}

// Need to Chdir into the package directory.
//
// This only applies because the Goggles application itself is a package,
// and if you have Goggles and one of its dependencies in your GOPATH,
// the resolver will assume you want to import the dependency from goggles/vendor/.
os.Chdir(sys.AbsPath(path))

if err := t.Resolve(path); err != nil {
return nil, err
}
Expand All @@ -88,7 +96,7 @@ func (p *Package) makeDocs() error {
Name: doc.Name,
Repository: repo(p.Name),
Import: fmt.Sprintf("import \"%v\"", p.Name),
Usage: doc.Doc,
Usage: p.cleanDoc(doc.Doc),

Constants: p.printValues(doc.Consts),
Variables: p.printValues(doc.Vars),
Expand All @@ -113,13 +121,17 @@ func (p *Package) parseDocs() (*doc.Package, error) {
}

for _, pkg := range pkgs {
return doc.New(pkg, ".", 0), nil
return doc.New(pkg, sys.AbsPath(p.Name), 0), nil
}

return nil, nil
}

func (p *Package) printValues(vals []*doc.Value) string {
if vals == nil {
return ""
}

var b bytes.Buffer
for _, v := range vals {
fmt.Fprintf(&b, "%s\n%s", p.printToken(v.Decl), p.printToken(v.Doc))
Expand All @@ -129,6 +141,10 @@ func (p *Package) printValues(vals []*doc.Value) string {

func (p *Package) printFuncs(funcs []*doc.Func) []Doc {
var docs []Doc
if funcs == nil {
return docs
}

for _, f := range funcs {
var receiver string
if f.Recv != "" {
Expand All @@ -139,7 +155,7 @@ func (p *Package) printFuncs(funcs []*doc.Func) []Doc {
Type: FunctionDoc,

Name: f.Name,
Usage: f.Doc,
Usage: p.cleanDoc(f.Doc),
Header: fmt.Sprintf("func %v%v", receiver, f.Name),
Declaration: p.printToken(f.Decl),
})
Expand All @@ -150,12 +166,16 @@ func (p *Package) printFuncs(funcs []*doc.Func) []Doc {

func (p *Package) printTypes(types []*doc.Type) []Doc {
var docs []Doc
if types == nil {
return docs
}

for _, t := range types {
d := Doc{
Type: TypeDoc,

Name: t.Name,
Usage: t.Doc,
Usage: p.cleanDoc(t.Doc),
Header: fmt.Sprintf("type %v", t.Name),
Declaration: p.printToken(t.Decl),

Expand Down Expand Up @@ -185,6 +205,21 @@ func (p *Package) printToken(t interface{}) string {
return b.String()
}

func (p *Package) cleanDoc(doc string) string {
lines := strings.Split(doc, "\n")
for i, line := range lines {

// Be a little more lenient on the code blocks, allow three spaces
// instead of requiring four.
//replace(/\n +/g, '\n\t')
if strings.HasPrefix(line, " ") && !strings.HasPrefix(line, " ") {
lines[i] = " " + line
}
}

return strings.Join(lines, "\n")
}

// hasTravis returns true if the current Package or the root directory of the repository
// has a .travis.yml file present.
func (p *Package) hasTravis() bool {
Expand Down
22 changes: 22 additions & 0 deletions package_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,25 @@ func Test_NewPackage(t *testing.T) {
t.Fatalf("Unexpected Name, expected=%v, got=%v", path, p.Name)
}
}

func Test_cleanDoc(t *testing.T) {
tests := []struct {
in string
out string
}{
// Code blocks
{" example", " example"}, // 3 -> 4 spaces
{" example", " example"}, // >= 4 stays the same
{" example", " example"}, // < 3 stays the same
{" example\n\texample", " example\n\texample"}, // multiple lines
{"\texample", "\texample"}, // tabs
{"\texample\n example\n example", "\texample\n example\n example"}, // tabs, three spaces and four spaces
}

for idx, tt := range tests {
var p Package
if out := p.cleanDoc(tt.in); out != tt.out {
t.Fatalf("[%v] Unexpected doc, expected=%v, got=%v", idx, tt.out, out)
}
}
}
Loading

0 comments on commit ab50720

Please sign in to comment.