Skip to content

Commit

Permalink
Improve headers.
Browse files Browse the repository at this point in the history
  • Loading branch information
monopole committed Nov 13, 2023
1 parent 53f56eb commit 6831b4b
Show file tree
Hide file tree
Showing 17 changed files with 134 additions and 51 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@ myrepos [{path/to/config/file}]

By default, the path to the configuration file is `$HOME/.myrepos.yml`.

For an example, see [example_myrepos.yml](example_myrepos.yml).
Example configuration file: [example_myrepos.yml](example_myrepos.yml)

For a detailed explanation of configuration fields, see [config.go](internal/config/config.go).
Detailed explanation of configuration fields: [config.go](internal/config/config.go)
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@ go 1.19

require (
github.com/spf13/cobra v1.2.1
github.com/stretchr/testify v1.7.0
gopkg.in/yaml.v3 v3.0.1
)

require (
github.com/TwiN/go-color v1.4.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
)
3 changes: 3 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
Expand Down Expand Up @@ -193,6 +194,7 @@ github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FI
github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
Expand All @@ -218,6 +220,7 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
Expand Down
2 changes: 1 addition & 1 deletion internal/config/config.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package pkg
package config

import (
"fmt"
Expand Down
10 changes: 7 additions & 3 deletions internal/runner/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,15 @@ func (r *Runner) Run(args ...string) error {
if err != nil {
if msg, isCommon := r.commonError(err); isCommon {
return fmt.Errorf(
"%s while running: %s", msg, cmd.String())
"%s (was running: %s)", msg, cmd.String())
}
if cmd.Dir == "" {
return fmt.Errorf("%w (was running %q)\n %s",
err, cmd.String(), r.GetOutput())
}
return fmt.Errorf(
"in dir %s running %q %w\n%s",
cmd.Dir, cmd.String(), err, r.GetOutput())
"%w (was running %q in dir %q)\n %s",
err, cmd.String(), cmd.Dir, r.GetOutput())
}
return err
})
Expand Down
40 changes: 40 additions & 0 deletions internal/ssh/checkssh.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package ssh

import (
"fmt"
"strings"
"time"

"github.com/monopole/myrepos/internal/runner"
)

const (
NoSshAgentErr = `start an ssh-agent using: eval $(ssh-agent)`
NoSshKeysErr = `add keys to your ssh-agent using: ssh-add`
)

func ErrIfNoSshAgent() error {
r, err := runner.NewRunner("ps", 2*time.Second, nil)
if err != nil {
return err
}
if err = r.Run("-ef"); err != nil {
return err
}
if !strings.Contains(r.GetOutput(), "ssh-agent") {
return fmt.Errorf(NoSshAgentErr)
}
return nil
}

func ErrIfNoSshKeys() error {
r, err := runner.NewRunner("ssh-add", 2*time.Second, nil)
if err != nil {
return err
}
err = r.Run("-l")
if strings.Contains(r.GetOutput(), "The agent has no identities.") {
return fmt.Errorf(NoSshKeysErr)
}
return err
}
15 changes: 15 additions & 0 deletions internal/ssh/checkssh_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package ssh_test

import (
. "github.com/monopole/myrepos/internal/ssh"
"github.com/stretchr/testify/assert"
"testing"
)

func TestCheckForSshAgent(t *testing.T) {
assert.NoError(t, ErrIfNoSshAgent())
}

func TestCheckForSshIdentities(t *testing.T) {
assert.NoError(t, ErrIfNoSshKeys())
}
2 changes: 1 addition & 1 deletion internal/tree/orgnode.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func (n *OrgNode) AbsPath() file.Path {
return n.parent.AbsPath().Append(n.nameDir)
}

func MakeOrgNode(p *ServerNode, orgName pkg.OrgName, names []pkg.RepoName) (on *OrgNode, err error) {
func MakeOrgNode(p *ServerNode, orgName config.OrgName, names []config.RepoName) (on *OrgNode, err error) {
dirName, origin, upstream := orgName.Parse()
on = &OrgNode{
parent: p,
Expand Down
2 changes: 1 addition & 1 deletion internal/tree/reponode.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func (n *RepoNode) IsAFork() bool {
return n.parent.nameOrigin != n.parent.nameUpstream
}

func MakeRepoNode(p *OrgNode, name pkg.RepoName) (n *RepoNode, err error) {
func MakeRepoNode(p *OrgNode, name config.RepoName) (n *RepoNode, err error) {
return &RepoNode{
parent: p,
Name: string(name),
Expand Down
6 changes: 3 additions & 3 deletions internal/tree/rootnode.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ func (n *RootNode) AbsPath() file.Path {
return n.absPath
}

func MakeRootNode(c *pkg.Config) (rn *RootNode, err error) {
func MakeRootNode(c *config.Config) (rn *RootNode, err error) {
rn = &RootNode{
absPath: absRootDir(c),
}
serverSpecs := make(map[pkg.ServerDomain]*ServerSpec)
serverSpecs := make(map[config.ServerDomain]*ServerSpec)
for d, opts := range c.ServerOpts {
serverSpecs[d], err = FromServerOpts(&opts)
if err != nil {
Expand All @@ -50,7 +50,7 @@ func MakeRootNode(c *pkg.Config) (rn *RootNode, err error) {
return rn, nil
}

func absRootDir(c *pkg.Config) file.Path {
func absRootDir(c *config.Config) file.Path {
if c.Path == "" {
return file.Home()
}
Expand Down
8 changes: 4 additions & 4 deletions internal/tree/servernode.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
type ServerNode struct {
parent *RootNode
spec *ServerSpec
domain pkg.ServerDomain
domain config.ServerDomain
children []*OrgNode
}

Expand All @@ -28,13 +28,13 @@ func (n *ServerNode) ServerSpec() *ServerSpec {
return n.spec
}

func (n *ServerNode) Domain() pkg.ServerDomain {
func (n *ServerNode) Domain() config.ServerDomain {
return n.domain
}

func MakeServerNode(
p *RootNode, n pkg.ServerDomain,
spec *ServerSpec, orgMap map[pkg.OrgName][]pkg.RepoName) (sn *ServerNode, err error) {
p *RootNode, n config.ServerDomain,
spec *ServerSpec, orgMap map[config.OrgName][]config.RepoName) (sn *ServerNode, err error) {
sn = &ServerNode{
parent: p,
spec: spec,
Expand Down
5 changes: 3 additions & 2 deletions internal/tree/serverspec.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ package tree

import (
"fmt"
"github.com/monopole/myrepos/internal/config"
"time"

"github.com/monopole/myrepos/internal/config"
)

type ServerSpec struct {
Expand Down Expand Up @@ -39,7 +40,7 @@ func MakeServerSpec() *ServerSpec {
}

// FromServerOpts creates a ServerSpec from its serialized form.
func FromServerOpts(s *pkg.ServerOpts) (result *ServerSpec, err error) {
func FromServerOpts(s *config.ServerOpts) (result *ServerSpec, err error) {
result = MakeServerSpec()
if s.Timeout != "" {
result.timeout, err = time.ParseDuration(s.Timeout)
Expand Down
35 changes: 27 additions & 8 deletions internal/visitor/cloner.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,31 @@ package visitor

import (
"fmt"
"strconv"

"github.com/TwiN/go-color"
"github.com/monopole/myrepos/internal/runner"
"github.com/monopole/myrepos/internal/tree"
)

const (
repoNameFieldSize = 40
spaces = " "
)

var (
fmtHeader = "%-" + strconv.Itoa(repoNameFieldSize) + "s"
fmtReport = "%" + strconv.Itoa(repoNameFieldSize) + "s%30s %s\n"
)

func indent(i int) string {
return spaces[:i*2]
}

func header(i int, arg string) string {
return fmt.Sprintf(fmtHeader, indent(i)+arg)
}

type Cloner struct {
lastErr error
fatalErr error
Expand Down Expand Up @@ -36,20 +56,21 @@ func (v *Cloner) VisitRootNode(n *tree.RootNode) {
v.fatal(fmt.Errorf("%q exists but isn't a directory", n.AbsPath()))
return
}
indent(0)
fmt.Println(color.InBlackOverWhite(n.AbsPath()))
fmt.Println(color.InBlackOverGray(header(0, string(n.AbsPath()))))
}

func (v *Cloner) VisitServerNode(n *tree.ServerNode) {
// TODO: Use some simple git command, e.g.
// git remote show origin
// to comfirm that the server is reachable.
if v.fatalErr != nil {
return
}
if exists, isDir := n.AbsPath().Exists(); exists && !isDir {
v.fatal(fmt.Errorf("%q exists but isn't a directory", n.AbsPath()))
return
}
indent(1)
fmt.Println(color.YellowBackground, n.Domain(), color.Reset)
fmt.Println(color.InBlackOverGreen(header(1, string(n.Domain()))))
}

func (v *Cloner) VisitOrgNode(n *tree.OrgNode) {
Expand All @@ -60,8 +81,7 @@ func (v *Cloner) VisitOrgNode(n *tree.OrgNode) {
v.fatal(fmt.Errorf("%q exists but isn't a directory", n.AbsPath()))
return
}
indent(2)
fmt.Println(color.CyanBackground, n.NameDir(), color.Reset)
fmt.Println(color.InBlackOverBlue(header(2, string(n.NameDir()))))
}

func (v *Cloner) VisitRepoNode(n *tree.RepoNode) {
Expand Down Expand Up @@ -101,6 +121,5 @@ func (v *Cloner) reportErr(n *tree.RepoNode, err error) {
}

func (v *Cloner) reportStatus(n *tree.RepoNode, outcome Outcome, status string) {
indent(3)
fmt.Printf("%30s%30s %s\n", n.Name, outcome, status)
fmt.Printf(fmtReport, n.Name, outcome, status)
}
10 changes: 6 additions & 4 deletions internal/visitor/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package visitor
import (
"fmt"
"github.com/monopole/myrepos/internal/runner"
"github.com/monopole/myrepos/internal/ssh"
"github.com/monopole/myrepos/internal/tree"
"path"
"strings"
Expand All @@ -12,10 +13,11 @@ const gitProgram = "git"

// commonErrs maps common error substrings to one line summaries.
var commonErrs = map[string]string{
"Could not resolve hostname": "cannot reach host",
"Connection refused": "cannot reach host",
"You have unstaged changes": "unstaged changes - commit or stash first",
"Operation timed out": "timed out - is repo accessible?",
"Could not resolve hostname": "cannot reach host",
"Connection refused": "cannot reach host",
"You have unstaged changes": "unstaged changes - commit or stash first",
"Operation timed out": "timed out - is repo accessible?",
"Permission denied (publickey)": ssh.NoSshKeysErr,
}

const (
Expand Down
11 changes: 4 additions & 7 deletions internal/visitor/printer.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,18 @@ type Printer struct {
}

func (v *Printer) VisitRootNode(n *tree.RootNode) {
indent(0)
fmt.Println(n.AbsPath())
fmt.Println(indent(0), n.AbsPath())
}

func (v *Printer) VisitServerNode(n *tree.ServerNode) {
indent(1)
fmt.Println(n.Domain())
fmt.Println(indent(1), n.Domain())
}

func (v *Printer) VisitOrgNode(n *tree.OrgNode) {
indent(2)
fmt.Print(indent(2))
fmt.Printf("%s|%s|%s\n", n.NameDir(), n.NameOrigin(), n.NameUpstream())
}

func (v *Printer) VisitRepoNode(n *tree.RepoNode) {
indent(3)
fmt.Println(n.Name)
fmt.Println(indent(3), n.Name)
}
9 changes: 0 additions & 9 deletions internal/visitor/utils.go

This file was deleted.

Loading

0 comments on commit 6831b4b

Please sign in to comment.