Skip to content

Commit

Permalink
add flag to control colorful output (#433)
Browse files Browse the repository at this point in the history
  • Loading branch information
Reuven Harrison authored Nov 29, 2023
1 parent cf2e565 commit bfeaf3f
Show file tree
Hide file tree
Showing 218 changed files with 2,195 additions and 1,979 deletions.
256 changes: 128 additions & 128 deletions BREAKING-CHANGES-EXAMPLES.md

Large diffs are not rendered by default.

63 changes: 44 additions & 19 deletions checker/api_change.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
// ApiChange represnts a change in the Paths Section of an OpenAPI spec
type ApiChange struct {
Id string `json:"id,omitempty" yaml:"id,omitempty"`
Text string `json:"text,omitempty" yaml:"text,omitempty"`
Args []any
Comment string `json:"comment,omitempty" yaml:"comment,omitempty"`
Level Level `json:"level" yaml:"level"`
Operation string `json:"operation,omitempty" yaml:"operation,omitempty"`
Expand All @@ -25,29 +25,42 @@ type ApiChange struct {
SourceColumnEnd int `json:"-" yaml:"-"`
}

func (c ApiChange) GetSection() string {
return "paths"
}

func (c ApiChange) IsBreaking() bool {
return c.GetLevel().IsBreaking()
}

func (c ApiChange) MatchIgnore(ignorePath, ignoreLine string) bool {
func (c ApiChange) MatchIgnore(ignorePath, ignoreLine string, l Localizer) bool {
if ignorePath == "" {
return false
}
x := c.GetUncolorizedText(l)
return ignorePath == strings.ToLower(c.Path) &&
strings.Contains(ignoreLine, strings.ToLower(c.Operation+" "+c.Path)) &&
strings.Contains(ignoreLine, strings.ToLower(GetUncolorizedText(c)))
strings.Contains(ignoreLine, strings.ToLower(x))
}

func (c ApiChange) GetId() string {
return c.Id
}

func (c ApiChange) GetText() string {
return c.Text
func (c ApiChange) GetText(l Localizer) string {
return l(c.Id, colorizedValues(c.Args)...)
}

func (c ApiChange) GetArgs() []any {
return c.Args
}

func (c ApiChange) GetComment() string {
return c.Comment
func (c ApiChange) GetUncolorizedText(l Localizer) string {
return l(c.Id, quotedValues(c.Args)...)
}

func (c ApiChange) GetComment(l Localizer) string {
return l(c.Comment)
}

func (c ApiChange) GetLevel() Level {
Expand All @@ -66,6 +79,10 @@ func (c ApiChange) GetPath() string {
return c.Path
}

func (c ApiChange) GetSource() string {
return c.Source
}

func (c ApiChange) GetSourceFile() string {
return c.SourceFile
}
Expand All @@ -86,22 +103,30 @@ func (c ApiChange) GetSourceColumnEnd() int {
return c.SourceColumnEnd
}

func (c ApiChange) LocalizedError(l Localizer) string {
return fmt.Sprintf("%s %s %s, %s API %s %s %s [%s]. %s", c.Level, l("at"), c.Source, l("in"), c.Operation, c.Path, c.Text, c.Id, c.Comment)
}
func (c ApiChange) SingleLineError(l Localizer, colorMode ColorMode) string {
const format = "%s %s %s, %s API %s %s %s [%s]. %s"

func (c ApiChange) PrettyErrorText(l Localizer) string {
if IsPipedOutput() {
return c.LocalizedError(l)
if isColorEnabled(colorMode) {
return fmt.Sprintf(format, c.Level.PrettyString(), l("at"), c.Source, l("in"), color.InGreen(c.Operation), color.InGreen(c.Path), c.GetText(l), color.InYellow(c.Id), c.GetComment(l))
}

comment := ""
if c.Comment != "" {
comment = fmt.Sprintf("\n\t\t%s", c.Comment)
return fmt.Sprintf(format, c.Level.String(), l("at"), c.Source, l("in"), c.Operation, c.Path, c.GetUncolorizedText(l), c.Id, c.GetComment(l))

}

func (c ApiChange) MultiLineError(l Localizer, colorMode ColorMode) string {
const format = "%s\t[%s] %s %s\t\n\t%s API %s %s\n\t\t%s%s"

if isColorEnabled(colorMode) {
return fmt.Sprintf(format, c.Level.PrettyString(), color.InYellow(c.Id), l("at"), c.Source, l("in"), color.InGreen(c.Operation), color.InGreen(c.Path), c.GetText(l), multiLineComment(c.GetComment(l)))
}
return fmt.Sprintf("%s\t[%s] %s %s\t\n\t%s API %s %s\n\t\t%s%s", c.Level.PrettyString(), color.InYellow(c.Id), l("at"), c.Source, l("in"), color.InGreen(c.Operation), color.InGreen(c.Path), c.Text, comment)

return fmt.Sprintf(format, c.Level.String(), c.Id, l("at"), c.Source, l("in"), c.Operation, c.Path, c.GetUncolorizedText(l), multiLineComment(c.GetComment(l)))
}

func (c ApiChange) Error() string {
return fmt.Sprintf("%s at %s, in API %s %s %s [%s]. %s", c.Level, c.Source, c.Operation, c.Path, c.Text, c.Id, c.Comment)
func multiLineComment(comment string) string {
if comment == "" {
return ""
}
return fmt.Sprintf("\n\t\t%s", comment)
}
44 changes: 30 additions & 14 deletions checker/api_change_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import (
)

var apiChange = checker.ApiChange{
Id: "id",
Text: "text",
Comment: "comment",
Id: "change_id",
Args: []any{},
Comment: "comment_id",
Level: checker.ERR,
Operation: "GET",
OperationId: "123",
Expand All @@ -24,29 +24,45 @@ var apiChange = checker.ApiChange{
}

func TestApiChange(t *testing.T) {
require.Equal(t, "id", apiChange.GetId())
require.Equal(t, "text", apiChange.GetText())
require.Equal(t, "comment", apiChange.GetComment())
require.Equal(t, "paths", apiChange.GetSection())
require.Equal(t, "change_id", apiChange.GetId())
require.Equal(t, "comment", apiChange.GetComment(MockLocalizer))
require.Equal(t, checker.ERR, apiChange.GetLevel())
require.Equal(t, "GET", apiChange.GetOperation())
require.Equal(t, "123", apiChange.GetOperationId())
require.Equal(t, "/test", apiChange.GetPath())
require.Equal(t, "source", apiChange.GetSource())
require.Equal(t, "sourceFile", apiChange.GetSourceFile())
require.Equal(t, 1, apiChange.GetSourceLine())
require.Equal(t, 2, apiChange.GetSourceLineEnd())
require.Equal(t, 3, apiChange.GetSourceColumn())
require.Equal(t, 4, apiChange.GetSourceColumnEnd())
require.Equal(t, "error at source, in API GET /test text [id]. comment", apiChange.LocalizedError(checker.NewDefaultLocalizer()))
require.Equal(t, "error at source, in API GET /test text [id]. comment", apiChange.Error())
require.Equal(t, "error at source, in API GET /test This is a breaking change. [change_id]. comment", apiChange.SingleLineError(MockLocalizer, checker.ColorNever))
}

func MockLocalizer(originalKey string, args ...interface{}) string {
switch originalKey {
case "change_id":
return "This is a breaking change."
case "comment_id":
return "comment"
default:
return originalKey
}

}

func TestApiChange_MatchIgnore(t *testing.T) {
require.True(t, apiChange.MatchIgnore("/test", "error at source, in api get /test text [id]. comment"))
require.True(t, apiChange.MatchIgnore("/test", "error at source, in api get /test this is a breaking change. [change_id]. comment", MockLocalizer))
}

func TestApiChange_PrettyPiped(t *testing.T) {
piped := true
save := checker.SetPipedOutput(&piped)
defer checker.SetPipedOutput(save)
require.Equal(t, "error at source, in API GET /test text [id]. comment", apiChange.PrettyErrorText(checker.NewDefaultLocalizer()))
func TestApiChange_MultiLineError(t *testing.T) {
require.Equal(t, "error\t[change_id] at source\t\n\tin API GET /test\n\t\tThis is a breaking change.\n\t\tcomment", apiChange.MultiLineError(MockLocalizer, checker.ColorNever))
}

func TestApiChange_MultiLineError_NoComment(t *testing.T) {
apiChangeNoComment := apiChange
apiChangeNoComment.Comment = ""

require.Equal(t, "error\t[change_id] at source\t\n\tin API GET /test\n\t\tThis is a breaking change.", apiChangeNoComment.MultiLineError(MockLocalizer, checker.ColorNever))
}
6 changes: 5 additions & 1 deletion checker/api_change_unix_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,9 @@ func TestApiChange_PrettyNotPipedUnix(t *testing.T) {
piped := false
save := checker.SetPipedOutput(&piped)
defer checker.SetPipedOutput(save)
require.Equal(t, "\x1b[31merror\x1b[0m\t[\x1b[33mid\x1b[0m] at source\t\n\tin API \x1b[32mGET\x1b[0m \x1b[32m/test\x1b[0m\n\t\ttext\n\t\tcomment", apiChange.PrettyErrorText(checker.NewDefaultLocalizer()))
require.Equal(t, "\x1b[31merror\x1b[0m\t[\x1b[33mchange_id\x1b[0m] at source\t\n\tin API \x1b[32mGET\x1b[0m \x1b[32m/test\x1b[0m\n\t\tThis is a breaking change.\n\t\tcomment", apiChange.MultiLineError(MockLocalizer, checker.ColorAuto))
}

func TestApiChange_SingleLineError_WithColor(t *testing.T) {
require.Equal(t, "\x1b[31merror\x1b[0m at source, in API \x1b[32mGET\x1b[0m \x1b[32m/test\x1b[0m This is a breaking change. [\x1b[33mchange_id\x1b[0m]. comment", apiChange.SingleLineError(MockLocalizer, checker.ColorAlways))
}
2 changes: 1 addition & 1 deletion checker/api_change_windows_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ func TestApiChange_PrettyNotPipedWindows(t *testing.T) {
piped := false
save := checker.SetPipedOutput(&piped)
defer checker.SetPipedOutput(save)
require.Equal(t, "error\t[id] at source\t\n\tin API GET /test\n\t\ttext\n\t\tcomment", apiChange.PrettyErrorText(checker.NewDefaultLocalizer()))
require.Equal(t, "error\t[change_id] at source\t\n\tin API GET /test\n\t\tThis is a breaking change.\n\t\tcomment", apiChange.MultiLineError(MockLocalizer, checker.ColorAuto))
}
15 changes: 9 additions & 6 deletions checker/change.go
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
package checker

type Change interface {
GetSection() string
IsBreaking() bool
GetId() string
GetText() string
GetComment() string
GetText(l Localizer) string
GetArgs() []any
GetUncolorizedText(l Localizer) string
GetComment(l Localizer) string
GetLevel() Level
GetOperation() string
GetOperationId() string
GetPath() string
GetSource() string
GetSourceFile() string
GetSourceLine() int
GetSourceLineEnd() int
GetSourceColumn() int
GetSourceColumnEnd() int
MatchIgnore(ignorePath, ignoreLine string) bool
LocalizedError(l Localizer) string
PrettyErrorText(l Localizer) string
Error() string
MatchIgnore(ignorePath, ignoreLine string, l Localizer) bool
SingleLineError(l Localizer, colorMode ColorMode) string
MultiLineError(l Localizer, colorMode ColorMode) string
}
12 changes: 0 additions & 12 deletions checker/change_utils.go

This file was deleted.

13 changes: 10 additions & 3 deletions checker/changes.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,18 @@ func (changes Changes) Less(i, j int) bool {
return iv.GetOperation() < jv.GetOperation()
case iv.GetId() != jv.GetId():
return iv.GetId() < jv.GetId()
case iv.GetText() != jv.GetText():
return iv.GetText() < jv.GetText()
case len(iv.GetArgs()) != len(jv.GetArgs()):
return len(iv.GetArgs()) < len(jv.GetArgs())
default:
return iv.GetComment() < jv.GetComment()
for i, arg := range iv.GetArgs() {
ia := interfaceToString(arg)
ja := interfaceToString(jv.GetArgs()[i])
if ia != ja {
return ia < ja
}
}
}
return true
}

func (changes Changes) Swap(i, j int) {
Expand Down
27 changes: 0 additions & 27 deletions checker/changes_by_endpoint.go

This file was deleted.

8 changes: 0 additions & 8 deletions checker/changes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,22 @@ import (
var changes = checker.Changes{
checker.ApiChange{
Id: "api-deleted",
Text: "API deleted",
Level: checker.ERR,
Operation: "GET",
Path: "/test",
},
checker.ApiChange{
Id: "api-added",
Text: "API added",
Level: checker.INFO,
Operation: "GET",
Path: "/test",
},
checker.ComponentChange{
Id: "component-added",
Text: "component added",
Level: checker.INFO,
},
checker.SecurityChange{
Id: "security-added",
Text: "security added",
Level: checker.INFO,
},
}
Expand All @@ -51,7 +47,3 @@ func TestChanges_Count(t *testing.T) {
require.Equal(t, 0, lc[checker.WARN])
require.Equal(t, 1, lc[checker.ERR])
}

func TestChanges_Group(t *testing.T) {
require.Contains(t, checker.GroupChanges(changes), checker.Endpoint{Path: "/test", Operation: "GET"})
}
3 changes: 1 addition & 2 deletions checker/check-added-required-request-body.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const (
AddedRequiredRequestBodyId = "added-required-request-body"
)

func AddedRequiredRequestBodyCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes {
func AddedRequiredRequestBodyCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes {
result := make(Changes, 0)
if diffReport.PathsDiff == nil {
return result
Expand All @@ -27,7 +27,6 @@ func AddedRequiredRequestBodyCheck(diffReport *diff.Diff, operationsSources *dif
result = append(result, ApiChange{
Id: AddedRequiredRequestBodyId,
Level: ERR,
Text: config.Localize(AddedRequiredRequestBodyId),
Operation: operation,
OperationId: operationItem.Revision.OperationID,
Path: path,
Expand Down
3 changes: 1 addition & 2 deletions checker/check-api-added.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const (
EndpointAddedId = "endpoint-added"
)

func APIAddedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config Config) Changes {
func APIAddedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSourcesMap, config *Config) Changes {
result := make(Changes, 0)
if diffReport.PathsDiff == nil {
return result
Expand All @@ -19,7 +19,6 @@ func APIAddedCheck(diffReport *diff.Diff, operationsSources *diff.OperationsSour
result = append(result, ApiChange{
Id: EndpointAddedId,
Level: INFO,
Text: config.Localize(EndpointAddedId),
Operation: opName,
OperationId: opConfig.OperationID,
Path: path,
Expand Down
Loading

0 comments on commit bfeaf3f

Please sign in to comment.