Add "echo" as logger
This allow to test ouput, and specify ouput other then os.Stdout
This commit is contained in:
parent
23e4547e52
commit
5fd9bc851b
33
app/app.go
33
app/app.go
@ -2,10 +2,13 @@ package app
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"gitlab.com/revalus/grm/commands"
|
||||
"gitlab.com/revalus/grm/config"
|
||||
"gitlab.com/revalus/grm/echo"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -19,15 +22,12 @@ const (
|
||||
type GitRepositoryManager struct {
|
||||
cliArguments config.CliArguments
|
||||
configuration config.Configuration
|
||||
console ConsoleOutput
|
||||
}
|
||||
|
||||
func (g *GitRepositoryManager) Parse(args []string) {
|
||||
co := ConsoleOutput{}
|
||||
|
||||
checkCriticalError := func(err error) {
|
||||
if err != nil {
|
||||
co.ErrorfMsg("%v", err.Error())
|
||||
fmt.Printf("Error: %v", err.Error())
|
||||
os.Exit(2)
|
||||
}
|
||||
}
|
||||
@ -43,21 +43,22 @@ func (g *GitRepositoryManager) Parse(args []string) {
|
||||
|
||||
configuration, err := config.GetRepositoryConfig(configFileContent, fileExcension)
|
||||
checkCriticalError(err)
|
||||
co.Color = arguments.Color
|
||||
|
||||
g.console = co
|
||||
g.cliArguments = arguments
|
||||
g.configuration = configuration
|
||||
}
|
||||
|
||||
func (g *GitRepositoryManager) Run() int {
|
||||
func (g *GitRepositoryManager) Run(w io.Writer) int {
|
||||
|
||||
echo.Color(g.cliArguments.Color)
|
||||
echo.Output(w)
|
||||
|
||||
exitCode := 0
|
||||
|
||||
if len(g.cliArguments.LimitTags) != 0 {
|
||||
err := g.limitTags()
|
||||
if err != nil {
|
||||
g.console.ErrorfMsg(err.Error())
|
||||
echo.ErrorfMsg(err.Error())
|
||||
exitCode = 1
|
||||
}
|
||||
}
|
||||
@ -65,40 +66,40 @@ func (g *GitRepositoryManager) Run() int {
|
||||
if g.cliArguments.LimitName != "" {
|
||||
err := g.limitName()
|
||||
if err != nil {
|
||||
g.console.ErrorfMsg(err.Error())
|
||||
echo.ErrorfMsg(err.Error())
|
||||
exitCode = 1
|
||||
}
|
||||
}
|
||||
|
||||
if g.cliArguments.Sync && exitCode == 0 {
|
||||
g.console.InfoFMsg("Synchronizing repositories")
|
||||
echo.InfoFMsg("Synchronizing repositories")
|
||||
sync := commands.NewSynchronizer(g.configuration.Workspace)
|
||||
g.runCommand(sync)
|
||||
g.console.InfoFMsg("All repositories are synced")
|
||||
echo.InfoFMsg("All repositories are synced")
|
||||
}
|
||||
|
||||
if g.cliArguments.Status && exitCode == 0 {
|
||||
g.console.InfoFMsg("Current status of repositories")
|
||||
echo.InfoFMsg("Current status of repositories")
|
||||
status := commands.NewStatusChecker(g.configuration.Workspace)
|
||||
g.runCommand(status)
|
||||
}
|
||||
|
||||
if g.cliArguments.Version {
|
||||
g.console.InfoFMsg("Current version: %v", VERSION)
|
||||
echo.InfoFMsg("Current version: %v", VERSION)
|
||||
}
|
||||
return exitCode
|
||||
}
|
||||
|
||||
func (g GitRepositoryManager) describeStatus(status commands.CommandStatus) {
|
||||
if status.Error {
|
||||
g.console.ErrorStatusF("Repository \"%v\": an error occurred: %v", status.Name, status.Message)
|
||||
echo.RedMessageF("Repository \"%v\": an error occurred: %v", status.Name, status.Message)
|
||||
return
|
||||
}
|
||||
|
||||
if status.Changed {
|
||||
g.console.ChangedStatusF("Repository \"%v\": %v", status.Name, status.Message)
|
||||
echo.YellowMessageF("Repository \"%v\": %v", status.Name, status.Message)
|
||||
} else {
|
||||
g.console.UnchangedStatusF("Repository \"%v\": %v", status.Name, status.Message)
|
||||
echo.GreenMessageF("Repository \"%v\": %v", status.Name, status.Message)
|
||||
}
|
||||
}
|
||||
|
||||
|
112
app/app_test.go
112
app/app_test.go
@ -8,6 +8,7 @@ import (
|
||||
|
||||
"gitlab.com/revalus/grm/commands"
|
||||
"gitlab.com/revalus/grm/config"
|
||||
"gitlab.com/revalus/grm/echo"
|
||||
)
|
||||
|
||||
type FakeCommandToTest struct {
|
||||
@ -15,6 +16,21 @@ type FakeCommandToTest struct {
|
||||
triggerChanged bool
|
||||
}
|
||||
|
||||
type ExpectedMessageTester struct {
|
||||
expectedMessages []string
|
||||
}
|
||||
|
||||
func (emt ExpectedMessageTester) Write(p []byte) (n int, err error) {
|
||||
msg := string(p)
|
||||
if !checkIsItemInSlice(msg, emt.expectedMessages) {
|
||||
panic(fmt.Sprintf("the message \"%v\"does not match any of the given patterns: %#v", msg, emt.expectedMessages))
|
||||
} else {
|
||||
fmt.Println(msg)
|
||||
}
|
||||
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func (fk FakeCommandToTest) Command(repoCfg config.RepositoryConfig, cmdStatus chan commands.CommandStatus) {
|
||||
status := commands.CommandStatus{
|
||||
Name: repoCfg.Name,
|
||||
@ -100,7 +116,7 @@ func TestParseApplication(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func Example_test_sync_output() {
|
||||
func TestOutputFromSync(t *testing.T) {
|
||||
grm := GitRepositoryManager{
|
||||
configuration: config.Configuration{
|
||||
Workspace: "/tmp",
|
||||
@ -108,19 +124,20 @@ func Example_test_sync_output() {
|
||||
cliArguments: config.CliArguments{
|
||||
Sync: true,
|
||||
Version: true,
|
||||
},
|
||||
console: ConsoleOutput{
|
||||
Color: false,
|
||||
Color: false,
|
||||
},
|
||||
}
|
||||
grm.Run()
|
||||
// Output:
|
||||
// Info: Synchronizing repositories
|
||||
// Info: All repositories are synced
|
||||
// Info: Current version: 0.3.0
|
||||
emt := ExpectedMessageTester{
|
||||
expectedMessages: []string{
|
||||
"Info: Synchronizing repositories\n",
|
||||
"Info: All repositories are synced\n",
|
||||
fmt.Sprintf("Info: Current version: %v\n", VERSION),
|
||||
},
|
||||
}
|
||||
grm.Run(emt)
|
||||
}
|
||||
|
||||
func Example_limit_test_tags() {
|
||||
func TestLimitTags(t *testing.T) {
|
||||
grm := GitRepositoryManager{
|
||||
cliArguments: config.CliArguments{
|
||||
LimitTags: []string{"example"},
|
||||
@ -132,22 +149,24 @@ func Example_limit_test_tags() {
|
||||
{Name: "notExample"},
|
||||
},
|
||||
},
|
||||
console: ConsoleOutput{
|
||||
Color: false,
|
||||
},
|
||||
}
|
||||
fakeCommand := FakeCommandToTest{
|
||||
triggerError: false,
|
||||
triggerChanged: false,
|
||||
}
|
||||
emt := ExpectedMessageTester{
|
||||
expectedMessages: []string{
|
||||
"Repository \"example1\": response from fake command\n",
|
||||
"Repository \"example2\": response from fake command\n",
|
||||
},
|
||||
}
|
||||
echo.Color(false)
|
||||
echo.Output(emt)
|
||||
grm.limitTags()
|
||||
grm.runCommand(fakeCommand)
|
||||
// Output:
|
||||
// Repository "example1": response from fake command
|
||||
// Repository "example2": response from fake command
|
||||
}
|
||||
|
||||
func Example_limit_name() {
|
||||
func TestLimitName(t *testing.T) {
|
||||
grm := GitRepositoryManager{
|
||||
cliArguments: config.CliArguments{
|
||||
LimitName: "notExample",
|
||||
@ -159,21 +178,22 @@ func Example_limit_name() {
|
||||
{Name: "notExample"},
|
||||
},
|
||||
},
|
||||
console: ConsoleOutput{
|
||||
Color: false,
|
||||
},
|
||||
}
|
||||
fakeCommand := FakeCommandToTest{
|
||||
triggerError: false,
|
||||
triggerChanged: false,
|
||||
}
|
||||
emt := ExpectedMessageTester{
|
||||
expectedMessages: []string{
|
||||
"Repository \"notExample\": response from fake command\n",
|
||||
},
|
||||
}
|
||||
echo.Color(false)
|
||||
echo.Output(emt)
|
||||
grm.limitName()
|
||||
grm.runCommand(fakeCommand)
|
||||
// Output:
|
||||
// Repository "notExample": response from fake command
|
||||
}
|
||||
|
||||
func Example_run_with_limit_not_existing_name() {
|
||||
func TestRunWithNotExistingNameInLimit(t *testing.T) {
|
||||
grm := GitRepositoryManager{
|
||||
cliArguments: config.CliArguments{
|
||||
LimitName: "not-existing-name",
|
||||
@ -185,16 +205,20 @@ func Example_run_with_limit_not_existing_name() {
|
||||
{Name: "notExample"},
|
||||
},
|
||||
},
|
||||
console: ConsoleOutput{
|
||||
Color: false,
|
||||
}
|
||||
emt := ExpectedMessageTester{
|
||||
expectedMessages: []string{
|
||||
"Error: no repository was found with the specified name\n",
|
||||
},
|
||||
}
|
||||
grm.Run()
|
||||
// Output:
|
||||
// Error: no repository was found with the specified name
|
||||
echo.Color(false)
|
||||
status := grm.Run(emt)
|
||||
if status != 1 {
|
||||
t.Errorf("Expected to get status %v, instead o this got %v", 1, status)
|
||||
}
|
||||
}
|
||||
|
||||
func Example_run_with_limit_not_existing_tags() {
|
||||
func TestRunWithNotExistingTagsInLimit(t *testing.T) {
|
||||
grm := GitRepositoryManager{
|
||||
cliArguments: config.CliArguments{
|
||||
LimitTags: []string{"not-existing-tag"},
|
||||
@ -206,16 +230,20 @@ func Example_run_with_limit_not_existing_tags() {
|
||||
{Name: "notExample"},
|
||||
},
|
||||
},
|
||||
console: ConsoleOutput{
|
||||
Color: false,
|
||||
}
|
||||
emt := ExpectedMessageTester{
|
||||
expectedMessages: []string{
|
||||
"Error: no repository was found with the specified tags\n",
|
||||
},
|
||||
}
|
||||
grm.Run()
|
||||
// Output:
|
||||
// Error: no repository was found with the specified tags
|
||||
echo.Color(false)
|
||||
status := grm.Run(emt)
|
||||
if status != 1 {
|
||||
t.Errorf("Expected to get status %v, instead o this got %v", 1, status)
|
||||
}
|
||||
}
|
||||
|
||||
func Example_test_status_output() {
|
||||
func TestGetStatusOutput(t *testing.T) {
|
||||
grm := GitRepositoryManager{
|
||||
configuration: config.Configuration{
|
||||
Workspace: "/tmp",
|
||||
@ -223,11 +251,17 @@ func Example_test_status_output() {
|
||||
cliArguments: config.CliArguments{
|
||||
Status: true,
|
||||
},
|
||||
console: ConsoleOutput{
|
||||
Color: false,
|
||||
}
|
||||
emt := ExpectedMessageTester{
|
||||
expectedMessages: []string{
|
||||
"Info: Current status of repositories\n",
|
||||
},
|
||||
}
|
||||
grm.Run()
|
||||
echo.Color(false)
|
||||
status := grm.Run(emt)
|
||||
if status != 0 {
|
||||
t.Errorf("Expected to get status %v, instead o this got %v", 1, status)
|
||||
}
|
||||
// Output:
|
||||
// Info: Current status of repositories
|
||||
}
|
||||
|
@ -1,61 +0,0 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
const (
|
||||
colorReset = "\033[0m"
|
||||
colorRed = "\033[31m"
|
||||
colorGreen = "\033[32m"
|
||||
colorYellow = "\033[33m"
|
||||
colorBlue = "\033[34m"
|
||||
)
|
||||
|
||||
type ConsoleOutput struct {
|
||||
Color bool
|
||||
}
|
||||
|
||||
func (co ConsoleOutput) ErrorfMsg(format string, a ...interface{}) {
|
||||
msg := fmt.Sprintf(format, a...)
|
||||
if co.Color {
|
||||
msg = fmt.Sprintf("%vError:%v %v", colorRed, colorReset, msg)
|
||||
} else {
|
||||
msg = fmt.Sprintf("Error: %v", msg)
|
||||
}
|
||||
fmt.Println(msg)
|
||||
}
|
||||
|
||||
func (co ConsoleOutput) InfoFMsg(format string, a ...interface{}) {
|
||||
msg := fmt.Sprintf(format, a...)
|
||||
if co.Color {
|
||||
msg = fmt.Sprintf("%vInfo:%v %v", colorBlue, colorReset, msg)
|
||||
} else {
|
||||
msg = fmt.Sprintf("Info: %v", msg)
|
||||
}
|
||||
fmt.Println(msg)
|
||||
}
|
||||
|
||||
func (co ConsoleOutput) UnchangedStatusF(format string, a ...interface{}) {
|
||||
msg := fmt.Sprintf(format, a...)
|
||||
if co.Color {
|
||||
msg = fmt.Sprintf("%v%v%v", colorGreen, msg, colorReset)
|
||||
}
|
||||
fmt.Println(msg)
|
||||
}
|
||||
|
||||
func (co ConsoleOutput) ChangedStatusF(format string, a ...interface{}) {
|
||||
msg := fmt.Sprintf(format, a...)
|
||||
if co.Color {
|
||||
msg = fmt.Sprintf("%v%v%v", colorYellow, msg, colorReset)
|
||||
}
|
||||
fmt.Println(msg)
|
||||
}
|
||||
|
||||
func (co ConsoleOutput) ErrorStatusF(format string, a ...interface{}) {
|
||||
msg := fmt.Sprintf(format, a...)
|
||||
if co.Color {
|
||||
msg = fmt.Sprintf("%v%v%v", colorRed, msg, colorReset)
|
||||
}
|
||||
fmt.Println(msg)
|
||||
}
|
72
echo/echo.go
Normal file
72
echo/echo.go
Normal file
@ -0,0 +1,72 @@
|
||||
package echo
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
const (
|
||||
colorReset = "\033[0m"
|
||||
colorRed = "\033[31m"
|
||||
colorGreen = "\033[32m"
|
||||
colorYellow = "\033[33m"
|
||||
colorBlue = "\033[34m"
|
||||
)
|
||||
|
||||
var (
|
||||
useColor bool = false
|
||||
output io.Writer = os.Stdout
|
||||
)
|
||||
|
||||
func Color(enabled bool) {
|
||||
useColor = enabled
|
||||
}
|
||||
|
||||
func Output(writer io.Writer) {
|
||||
output = writer
|
||||
}
|
||||
|
||||
func ErrorfMsg(format string, a ...interface{}) error {
|
||||
msg := fmt.Sprintf(format, a...)
|
||||
if useColor {
|
||||
msg = fmt.Sprintf("%vError:%v %v", colorRed, colorReset, msg)
|
||||
} else {
|
||||
msg = fmt.Sprintf("Error: %v", msg)
|
||||
}
|
||||
return write(msg)
|
||||
}
|
||||
|
||||
func InfoFMsg(format string, a ...interface{}) error {
|
||||
msg := fmt.Sprintf(format, a...)
|
||||
if useColor {
|
||||
msg = fmt.Sprintf("%vInfo:%v %v", colorBlue, colorReset, msg)
|
||||
} else {
|
||||
msg = fmt.Sprintf("Info: %v", msg)
|
||||
}
|
||||
return write(msg)
|
||||
}
|
||||
|
||||
func GreenMessageF(format string, a ...interface{}) error {
|
||||
return writeWithColor(fmt.Sprintf(format, a...), colorGreen)
|
||||
}
|
||||
|
||||
func YellowMessageF(format string, a ...interface{}) error {
|
||||
return writeWithColor(fmt.Sprintf(format, a...), colorYellow)
|
||||
}
|
||||
func RedMessageF(format string, a ...interface{}) error {
|
||||
return writeWithColor(fmt.Sprintf(format, a...), colorRed)
|
||||
}
|
||||
|
||||
func writeWithColor(msg string, color string) error {
|
||||
if useColor {
|
||||
return write(fmt.Sprintf("%v%v%v", color, msg, colorReset))
|
||||
}
|
||||
return write(msg)
|
||||
|
||||
}
|
||||
|
||||
func write(msg string) error {
|
||||
_, err := fmt.Fprintln(output, msg)
|
||||
return err
|
||||
}
|
151
echo/echo_test.go
Normal file
151
echo/echo_test.go
Normal file
@ -0,0 +1,151 @@
|
||||
package echo
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type ExpectedMessageTester struct {
|
||||
expectedMessage string
|
||||
}
|
||||
|
||||
func (emt ExpectedMessageTester) Write(p []byte) (n int, err error) {
|
||||
msg := string(p)
|
||||
if msg != emt.expectedMessage {
|
||||
return 0, fmt.Errorf("expected to get \"%v\", instead of this got \"%v\"", msg, emt.expectedMessage)
|
||||
}
|
||||
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func TestOverwriteColor(t *testing.T) {
|
||||
Color(false)
|
||||
if useColor {
|
||||
t.Error("Expected that \"useColor\" will be false")
|
||||
}
|
||||
Color(true)
|
||||
if !useColor {
|
||||
t.Error("Expected that \"useColor\" will be true")
|
||||
}
|
||||
}
|
||||
|
||||
func TestOverwriteWriter(t *testing.T) {
|
||||
Output(os.Stderr)
|
||||
if output != os.Stderr {
|
||||
t.Error("Expected to receive addresses on os.Stderr")
|
||||
}
|
||||
Output(os.Stdout)
|
||||
if output != os.Stdout {
|
||||
t.Error("Expected to receive addresses on os.Stdout")
|
||||
}
|
||||
}
|
||||
|
||||
func TestErrorfMsgWithoutColor(t *testing.T) {
|
||||
useColor = false
|
||||
output = ExpectedMessageTester{
|
||||
expectedMessage: "Error: test message\n",
|
||||
}
|
||||
err := ErrorfMsg("test message")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestErrorfMsgWithColor(t *testing.T) {
|
||||
useColor = true
|
||||
output = ExpectedMessageTester{
|
||||
expectedMessage: "\033[31mError:\033[0m test message\n",
|
||||
}
|
||||
err := ErrorfMsg("test message")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInfoMsgFWithoutColor(t *testing.T) {
|
||||
useColor = false
|
||||
output = ExpectedMessageTester{
|
||||
expectedMessage: "Info: test message\n",
|
||||
}
|
||||
err := InfoFMsg("test message")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInfoMsgFWithColor(t *testing.T) {
|
||||
useColor = true
|
||||
output = ExpectedMessageTester{
|
||||
expectedMessage: "\033[34mInfo:\033[0m test message\n",
|
||||
}
|
||||
err := InfoFMsg("test message")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGreenMessageWithoutColor(t *testing.T) {
|
||||
useColor = false
|
||||
output = ExpectedMessageTester{
|
||||
expectedMessage: "test message\n",
|
||||
}
|
||||
err := GreenMessageF("test message")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGreenMessageWithColor(t *testing.T) {
|
||||
useColor = true
|
||||
output = ExpectedMessageTester{
|
||||
expectedMessage: "\033[32mtest message\033[0m\n",
|
||||
}
|
||||
err := GreenMessageF("test message")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestYellowMessageWithout(t *testing.T) {
|
||||
useColor = false
|
||||
output = ExpectedMessageTester{
|
||||
expectedMessage: "test message\n",
|
||||
}
|
||||
err := YellowMessageF("test message")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestYellowMessageWithColor(t *testing.T) {
|
||||
useColor = true
|
||||
output = ExpectedMessageTester{
|
||||
expectedMessage: "\033[33mtest message\033[0m\n",
|
||||
}
|
||||
err := YellowMessageF("test message")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRedMessageWithout(t *testing.T) {
|
||||
useColor = false
|
||||
output = ExpectedMessageTester{
|
||||
expectedMessage: "test message\n",
|
||||
}
|
||||
err := RedMessageF("test message")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
func TestRedMessageWithColor(t *testing.T) {
|
||||
useColor = true
|
||||
output = ExpectedMessageTester{
|
||||
expectedMessage: "\033[31mtest message\033[0m\n",
|
||||
}
|
||||
err := RedMessageF("test message")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user