summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Majewsky <majewsky@gmx.net>2017-05-09 22:00:15 +0200
committerStefan Majewsky <majewsky@gmx.net>2017-05-09 22:00:15 +0200
commit58a4af83e0caf09744dd698b5be937205b81e733 (patch)
treebcb6b4e587baaabce07c67e971e8459445eef367
parenta92faf7689fa01595fd613ddd3880e9c301ed558 (diff)
downloadgofu-58a4af83e0caf09744dd698b5be937205b81e733.tar.gz
refactor package rtree towards testability
-rw-r--r--main.go9
-rw-r--r--pkg/earlyerrors/errors.go42
-rw-r--r--pkg/rtree/index.go22
-rw-r--r--pkg/rtree/init.go99
-rw-r--r--pkg/rtree/main.go4
-rw-r--r--pkg/rtree/remote.go37
-rw-r--r--pkg/rtree/repo.go14
7 files changed, 109 insertions, 118 deletions
diff --git a/main.go b/main.go
index 03dc9de..ea34c2e 100644
--- a/main.go
+++ b/main.go
@@ -23,19 +23,10 @@ import (
"os"
"path/filepath"
- "github.com/majewsky/gofu/pkg/cli"
- "github.com/majewsky/gofu/pkg/earlyerrors"
"github.com/majewsky/gofu/pkg/rtree"
)
func main() {
- if len(earlyerrors.Get()) > 0 {
- for _, msg := range earlyerrors.Get() {
- cli.Interface.ShowError(msg)
- }
- os.Exit(255)
- }
-
os.Exit(execApplet(filepath.Base(os.Args[0]), os.Args[1:], true))
}
diff --git a/pkg/earlyerrors/errors.go b/pkg/earlyerrors/errors.go
deleted file mode 100644
index edde0f8..0000000
--- a/pkg/earlyerrors/errors.go
+++ /dev/null
@@ -1,42 +0,0 @@
-/*******************************************************************************
-*
-* Copyright 2017 Stefan Majewsky <majewsky@gmx.net>
-*
-* This program is free software: you can redistribute it and/or modify it under
-* the terms of the GNU General Public License as published by the Free Software
-* Foundation, either version 3 of the License, or (at your option) any later
-* version.
-*
-* This program is distributed in the hope that it will be useful, but WITHOUT ANY
-* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License along with
-* this program. If not, see <http://www.gnu.org/licenses/>.
-*
-*******************************************************************************/
-
-//Package earlyerrors can be used to cache errors that occurred during func
-//init(). These errors can then be displayed by func main().
-package earlyerrors
-
-import "fmt"
-
-var errs []string
-
-//Put submits an error message.
-func Put(err string) {
- if err != "" {
- errs = append(errs, err)
- }
-}
-
-//Putf builds and submits an error message.
-func Putf(err string, args ...interface{}) {
- Put(fmt.Sprintf(err, args...))
-}
-
-//Get returns all collected errors, or an empty slice if there were none.
-func Get() []string {
- return errs
-}
diff --git a/pkg/rtree/index.go b/pkg/rtree/index.go
index 49ef385..c7d6097 100644
--- a/pkg/rtree/index.go
+++ b/pkg/rtree/index.go
@@ -29,7 +29,6 @@ import (
"strings"
"github.com/majewsky/gofu/pkg/cli"
- "github.com/majewsky/gofu/pkg/earlyerrors"
yaml "gopkg.in/yaml.v2"
)
@@ -39,22 +38,10 @@ type Index struct {
Repos []*Repo `yaml:"repos"`
}
-var indexPath string
-
-func init() {
- homeDir := os.Getenv("HOME")
- if homeDir == "" {
- earlyerrors.Put("$HOME is not set (rtree needs the HOME variable to locate its index file)")
- } else {
- indexPath = filepath.Join(homeDir, ".rtree/index.yaml")
- }
-}
-
//ReadIndex reads the index file.
func ReadIndex() (*Index, []error) {
//read contents of index file
- path := indexPath
- buf, err := ioutil.ReadFile(path)
+ buf, err := ioutil.ReadFile(IndexPath)
if err != nil {
if os.IsNotExist(err) {
return &Index{Repos: nil}, nil
@@ -73,7 +60,7 @@ func ReadIndex() (*Index, []error) {
var errs []error
missing := func(key string, args ...interface{}) {
errs = append(errs, fmt.Errorf("read %s: missing \"%s\"",
- path, fmt.Sprintf(key, args...),
+ IndexPath, fmt.Sprintf(key, args...),
))
}
for idx, repo := range index.Repos {
@@ -110,12 +97,11 @@ func (i *Index) Write() error {
return err
}
- path := indexPath
- err = os.MkdirAll(filepath.Dir(path), 0755)
+ err = os.MkdirAll(filepath.Dir(IndexPath), 0755)
if err != nil {
return err
}
- err = ioutil.WriteFile(path, buf, 0644)
+ err = ioutil.WriteFile(IndexPath, buf, 0644)
if err != nil {
return err
}
diff --git a/pkg/rtree/init.go b/pkg/rtree/init.go
new file mode 100644
index 0000000..1d2dc10
--- /dev/null
+++ b/pkg/rtree/init.go
@@ -0,0 +1,99 @@
+/*******************************************************************************
+*
+* Copyright 2017 Stefan Majewsky <majewsky@gmx.net>
+*
+* This program is free software: you can redistribute it and/or modify it under
+* the terms of the GNU General Public License as published by the Free Software
+* Foundation, either version 3 of the License, or (at your option) any later
+* version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT ANY
+* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along with
+* this program. If not, see <http://www.gnu.org/licenses/>.
+*
+*******************************************************************************/
+
+package rtree
+
+import (
+ "os"
+ "path/filepath"
+ "regexp"
+ "strings"
+
+ "github.com/majewsky/gofu/pkg/cli"
+)
+
+//RemoteAlias describes an alias that can be used in a Git remote URL (as
+//defined by the "url.<base>.insteadOf" directive in man:git-config(1)).
+type RemoteAlias struct {
+ Alias string
+ Replacement string
+}
+
+//IndexPath is where the index file is stored.
+var IndexPath string
+
+//RootPath is the directory below which all repositories are located. Its value
+//is $GOPATH/src to match the repository layout created by `go get`.
+var RootPath string
+
+//RemoteAliases is the list of remote aliases that is used by ExpandRemoteURL().
+var RemoteAliases []*RemoteAlias
+
+//Init initializes the global variables of this package to their standard
+//values, unless they are already populated. Unit tests shall set IndexPath,
+//RootPath etc. before calling Exec(), such that this function becomes a no-op
+//when called by Exec().
+//
+//Returns false if initialization failed.
+func Init() bool {
+ ok := true //until shown otherwise
+
+ if IndexPath == "" {
+ homeDir := os.Getenv("HOME")
+ if homeDir == "" {
+ cli.Interface.ShowError("$HOME is not set (rtree needs the HOME variable to locate its index file)")
+ ok = false //but keep going to report all errors at once
+ } else {
+ IndexPath = filepath.Join(homeDir, ".rtree/index.yaml")
+ }
+ }
+
+ if RootPath == "" {
+ gopath := os.Getenv("GOPATH")
+ if gopath == "" {
+ cli.Interface.ShowError("$GOPATH is not set (rtree needs the GOPATH variable to know where to look for and place repos)")
+ ok = false //but keep going to report all errors at once
+ } else {
+ RootPath = filepath.Join(gopath, "src")
+ }
+ }
+
+ if RemoteAliases == nil {
+ out, err := cli.Interface.CaptureStdout(cli.Command{
+ Program: []string{"git", "config", "--global", "-l"},
+ })
+ if err != nil {
+ cli.Interface.ShowError(err.Error())
+ ok = false //but keep going to report all errors at once
+ }
+
+ rx := regexp.MustCompile(`^url\.([^=]+)\.insteadof=(.+)$`)
+ for _, line := range strings.Split(out, "\n") {
+ match := rx.FindStringSubmatch(line)
+ if match == nil {
+ continue
+ }
+ RemoteAliases = append(RemoteAliases, &RemoteAlias{
+ Alias: match[2],
+ Replacement: match[1],
+ })
+ }
+ }
+
+ return ok
+}
diff --git a/pkg/rtree/main.go b/pkg/rtree/main.go
index 581fa7e..f08126e 100644
--- a/pkg/rtree/main.go
+++ b/pkg/rtree/main.go
@@ -27,6 +27,10 @@ import (
//Exec executes the rtree applet and does not return. The argument is os.Args
//minus the leading "rtree" or "gofu rtree".
func Exec(args []string) int {
+ if !Init() {
+ return 1
+ }
+
if len(args) == 0 {
return usage()
}
diff --git a/pkg/rtree/remote.go b/pkg/rtree/remote.go
index 8f88deb..0c4e880 100644
--- a/pkg/rtree/remote.go
+++ b/pkg/rtree/remote.go
@@ -23,41 +23,8 @@ import (
"path/filepath"
"regexp"
"strings"
-
- "github.com/majewsky/gofu/pkg/cli"
- "github.com/majewsky/gofu/pkg/earlyerrors"
)
-//remoteAlias describes an alias that can be used in a Git remote URL (as
-//defined by the "url.<base>.insteadOf" directive in man:git-config(1)).
-type remoteAlias struct {
- Alias string
- Replacement string
-}
-
-var remoteAliases []*remoteAlias
-
-func init() {
- out, err := cli.Interface.CaptureStdout(cli.Command{
- Program: []string{"git", "config", "--global", "-l"},
- })
- if err != nil {
- earlyerrors.Put(err.Error())
- }
-
- rx := regexp.MustCompile(`^url\.([^=]+)\.insteadof=(.+)$`)
- for _, line := range strings.Split(out, "\n") {
- match := rx.FindStringSubmatch(line)
- if match == nil {
- continue
- }
- remoteAliases = append(remoteAliases, &remoteAlias{
- Alias: match[2],
- Replacement: match[1],
- })
- }
-}
-
//ExpandRemoteURL derive the canonical URL for a given remote by substituting
//aliases defined in the system-wide and user-global Git config. For example,
//with
@@ -68,8 +35,8 @@ func init() {
//
//and the input "gh:foo/bar", this function returns "git://github.com/foo/bar".
func ExpandRemoteURL(remoteURL string) string {
- var best *remoteAlias
- for _, current := range remoteAliases {
+ var best *RemoteAlias
+ for _, current := range RemoteAliases {
if strings.HasPrefix(remoteURL, current.Alias) {
if best == nil || len(best.Alias) < len(current.Alias) {
best = current
diff --git a/pkg/rtree/repo.go b/pkg/rtree/repo.go
index 636e3a7..790db92 100644
--- a/pkg/rtree/repo.go
+++ b/pkg/rtree/repo.go
@@ -26,22 +26,8 @@ import (
"strings"
"github.com/majewsky/gofu/pkg/cli"
- "github.com/majewsky/gofu/pkg/earlyerrors"
)
-//RootPath is the directory below which all repositories are located. Its value
-//is $GOPATH/src to match the repository layout created by `go get`.
-var RootPath string
-
-func init() {
- gopath := os.Getenv("GOPATH")
- if gopath == "" {
- earlyerrors.Put("$GOPATH is not set (rtree needs the GOPATH variable to know where to look for and place repos)")
- } else {
- RootPath = filepath.Join(gopath, "src")
- }
-}
-
//Repo describes the entry for a repository in the index file.
type Repo struct {
//CheckoutPath shall be relative to the RootPath.