feat: new output.formats file configuration syntax (#4521)
This commit is contained in:
parent
b91c194126
commit
e3ed3ba1d6
@ -59,15 +59,25 @@ run:
|
|||||||
|
|
||||||
# output configuration options
|
# output configuration options
|
||||||
output:
|
output:
|
||||||
# Format: colored-line-number|line-number|json|colored-tab|tab|checkstyle|code-climate|junit-xml|github-actions|teamcity
|
# The formats used to render issues.
|
||||||
#
|
# Format: `colored-line-number`, `line-number`, `json`, `colored-tab`, `tab`, `checkstyle`, `code-climate`, `junit-xml`, `github-actions`, `teamcity`
|
||||||
# Multiple can be specified by separating them by comma, output can be provided
|
|
||||||
# for each of them by separating format name and path by colon symbol.
|
|
||||||
# Output path can be either `stdout`, `stderr` or path to the file to write to.
|
# Output path can be either `stdout`, `stderr` or path to the file to write to.
|
||||||
# Example: "checkstyle:report.xml,json:stdout,colored-line-number"
|
|
||||||
#
|
#
|
||||||
# Default: colored-line-number
|
# For the CLI flag (`--out-format`), multiple formats can be specified by separating them by comma.
|
||||||
format: json
|
# The output can be specified for each of them by separating format name and path by colon symbol.
|
||||||
|
# Example: "--out-format=checkstyle:report.xml,json:stdout,colored-line-number"
|
||||||
|
# The CLI flag (`--out-format`) override the configuration file.
|
||||||
|
#
|
||||||
|
# Default:
|
||||||
|
# formats:
|
||||||
|
# - format: colored-line-number
|
||||||
|
# path: stdout
|
||||||
|
formats:
|
||||||
|
- format: json
|
||||||
|
path: stderr
|
||||||
|
- format: checkstyle
|
||||||
|
path: report.xml
|
||||||
|
- format: colored-line-number
|
||||||
|
|
||||||
# Print lines of code with issue.
|
# Print lines of code with issue.
|
||||||
# Default: true
|
# Default: true
|
||||||
|
@ -451,15 +451,42 @@
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
"properties": {
|
"properties": {
|
||||||
"format": {
|
"formats": {
|
||||||
"description": "Output format to use.",
|
"description": "Output formats to use.",
|
||||||
"pattern": "^(,?(colored-line-number|line-number|json|colored-tab|tab|checkstyle|code-climate|junit-xml|github-actions|teamcity)(:[^,]+)?)+$",
|
"type": "array",
|
||||||
"default": "colored-line-number",
|
"items": {
|
||||||
"examples": [
|
"type": "object",
|
||||||
"colored-line-number",
|
"additionalProperties": false,
|
||||||
"checkstyle:report.json,colored-line-number",
|
"properties": {
|
||||||
"line-number:golangci-lint.out,colored-line-number:stdout"
|
"path": {
|
||||||
]
|
"default": "stdout",
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"enum": [ "stdout", "stderr" ]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"format": {
|
||||||
|
"default": "colored-line-number",
|
||||||
|
"enum": [
|
||||||
|
"colored-line-number",
|
||||||
|
"line-number",
|
||||||
|
"json",
|
||||||
|
"colored-tab",
|
||||||
|
"tab",
|
||||||
|
"checkstyle",
|
||||||
|
"code-climate",
|
||||||
|
"junit-xml",
|
||||||
|
"github-actions",
|
||||||
|
"teamcity"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["format"]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"print-issued-lines": {
|
"print-issued-lines": {
|
||||||
"description": "Print lines of code with issue.",
|
"description": "Print lines of code with issue.",
|
||||||
|
@ -63,8 +63,8 @@ func setupRunFlagSet(v *viper.Viper, fs *pflag.FlagSet) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func setupOutputFlagSet(v *viper.Viper, fs *pflag.FlagSet) {
|
func setupOutputFlagSet(v *viper.Viper, fs *pflag.FlagSet) {
|
||||||
internal.AddFlagAndBind(v, fs, fs.String, "out-format", "output.format", config.OutFormatColoredLineNumber,
|
internal.AddFlagAndBind(v, fs, fs.String, "out-format", "output.formats", config.OutFormatColoredLineNumber,
|
||||||
color.GreenString(fmt.Sprintf("Format of output: %s", strings.Join(config.OutFormats, "|"))))
|
color.GreenString(fmt.Sprintf("Formats of output: %s", strings.Join(config.AllOutputFormats, "|"))))
|
||||||
internal.AddFlagAndBind(v, fs, fs.Bool, "print-issued-lines", "output.print-issued-lines", true,
|
internal.AddFlagAndBind(v, fs, fs.Bool, "print-issued-lines", "output.print-issued-lines", true,
|
||||||
color.GreenString("Print lines of code with issue"))
|
color.GreenString("Print lines of code with issue"))
|
||||||
internal.AddFlagAndBind(v, fs, fs.Bool, "print-linter-name", "output.print-linter-name", true,
|
internal.AddFlagAndBind(v, fs, fs.Bool, "print-linter-name", "output.print-linter-name", true,
|
||||||
|
@ -61,7 +61,10 @@ func (l *Loader) Load() error {
|
|||||||
|
|
||||||
l.handleGoVersion()
|
l.handleGoVersion()
|
||||||
|
|
||||||
l.handleDeprecation()
|
err = l.handleDeprecation()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
err = l.handleEnableOnlyOption()
|
err = l.handleEnableOnlyOption()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -164,7 +167,7 @@ func (l *Loader) parseConfig() error {
|
|||||||
var configFileNotFoundError viper.ConfigFileNotFoundError
|
var configFileNotFoundError viper.ConfigFileNotFoundError
|
||||||
if errors.As(err, &configFileNotFoundError) {
|
if errors.As(err, &configFileNotFoundError) {
|
||||||
// Load configuration from flags only.
|
// Load configuration from flags only.
|
||||||
err = l.viper.Unmarshal(l.cfg)
|
err = l.viper.Unmarshal(l.cfg, customDecoderHook())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("can't unmarshal config by viper (flags): %w", err)
|
return fmt.Errorf("can't unmarshal config by viper (flags): %w", err)
|
||||||
}
|
}
|
||||||
@ -181,7 +184,7 @@ func (l *Loader) parseConfig() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Load configuration from all sources (flags, file).
|
// Load configuration from all sources (flags, file).
|
||||||
if err := l.viper.Unmarshal(l.cfg, fileDecoderHook()); err != nil {
|
if err := l.viper.Unmarshal(l.cfg, customDecoderHook()); err != nil {
|
||||||
return fmt.Errorf("can't unmarshal config by viper (flags, file): %w", err)
|
return fmt.Errorf("can't unmarshal config by viper (flags, file): %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,28 +282,47 @@ func (l *Loader) handleGoVersion() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Loader) handleDeprecation() {
|
func (l *Loader) handleDeprecation() error {
|
||||||
|
// Deprecated since v1.57.0
|
||||||
if len(l.cfg.Run.SkipFiles) > 0 {
|
if len(l.cfg.Run.SkipFiles) > 0 {
|
||||||
l.warn("The configuration option `run.skip-files` is deprecated, please use `issues.exclude-files`.")
|
l.warn("The configuration option `run.skip-files` is deprecated, please use `issues.exclude-files`.")
|
||||||
l.cfg.Issues.ExcludeFiles = l.cfg.Run.SkipFiles
|
l.cfg.Issues.ExcludeFiles = l.cfg.Run.SkipFiles
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deprecated since v1.57.0
|
||||||
if len(l.cfg.Run.SkipDirs) > 0 {
|
if len(l.cfg.Run.SkipDirs) > 0 {
|
||||||
l.warn("The configuration option `run.skip-dirs` is deprecated, please use `issues.exclude-dirs`.")
|
l.warn("The configuration option `run.skip-dirs` is deprecated, please use `issues.exclude-dirs`.")
|
||||||
l.cfg.Issues.ExcludeDirs = l.cfg.Run.SkipDirs
|
l.cfg.Issues.ExcludeDirs = l.cfg.Run.SkipDirs
|
||||||
}
|
}
|
||||||
|
|
||||||
// The 2 options are true by default.
|
// The 2 options are true by default.
|
||||||
|
// Deprecated since v1.57.0
|
||||||
if !l.cfg.Run.UseDefaultSkipDirs {
|
if !l.cfg.Run.UseDefaultSkipDirs {
|
||||||
l.warn("The configuration option `run.skip-dirs-use-default` is deprecated, please use `issues.exclude-dirs-use-default`.")
|
l.warn("The configuration option `run.skip-dirs-use-default` is deprecated, please use `issues.exclude-dirs-use-default`.")
|
||||||
}
|
}
|
||||||
l.cfg.Issues.UseDefaultExcludeDirs = l.cfg.Run.UseDefaultSkipDirs && l.cfg.Issues.UseDefaultExcludeDirs
|
l.cfg.Issues.UseDefaultExcludeDirs = l.cfg.Run.UseDefaultSkipDirs && l.cfg.Issues.UseDefaultExcludeDirs
|
||||||
|
|
||||||
// The 2 options are false by default.
|
// The 2 options are false by default.
|
||||||
|
// Deprecated since v1.57.0
|
||||||
if l.cfg.Run.ShowStats {
|
if l.cfg.Run.ShowStats {
|
||||||
l.warn("The configuration option `run.show-stats` is deprecated, please use `output.show-stats`")
|
l.warn("The configuration option `run.show-stats` is deprecated, please use `output.show-stats`")
|
||||||
}
|
}
|
||||||
l.cfg.Output.ShowStats = l.cfg.Run.ShowStats || l.cfg.Output.ShowStats
|
l.cfg.Output.ShowStats = l.cfg.Run.ShowStats || l.cfg.Output.ShowStats
|
||||||
|
|
||||||
|
// Deprecated since v1.57.0
|
||||||
|
if l.cfg.Output.Format != "" {
|
||||||
|
l.warn("The configuration option `output.format` is deprecated, please use `output.formats`")
|
||||||
|
|
||||||
|
var f OutputFormats
|
||||||
|
err := f.UnmarshalText([]byte(l.cfg.Output.Format))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unmarshal output format: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
l.cfg.Output.Formats = f
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Loader) handleEnableOnlyOption() error {
|
func (l *Loader) handleEnableOnlyOption() error {
|
||||||
@ -332,13 +354,13 @@ func (l *Loader) warn(format string) {
|
|||||||
l.log.Warnf(format)
|
l.log.Warnf(format)
|
||||||
}
|
}
|
||||||
|
|
||||||
func fileDecoderHook() viper.DecoderConfigOption {
|
func customDecoderHook() viper.DecoderConfigOption {
|
||||||
return viper.DecodeHook(mapstructure.ComposeDecodeHookFunc(
|
return viper.DecodeHook(mapstructure.ComposeDecodeHookFunc(
|
||||||
// Default hooks (https://github.com/spf13/viper/blob/518241257478c557633ab36e474dfcaeb9a3c623/viper.go#L135-L138).
|
// Default hooks (https://github.com/spf13/viper/blob/518241257478c557633ab36e474dfcaeb9a3c623/viper.go#L135-L138).
|
||||||
mapstructure.StringToTimeDurationHookFunc(),
|
mapstructure.StringToTimeDurationHookFunc(),
|
||||||
mapstructure.StringToSliceHookFunc(","),
|
mapstructure.StringToSliceHookFunc(","),
|
||||||
|
|
||||||
// Needed for forbidigo.
|
// Needed for forbidigo, and output.formats.
|
||||||
mapstructure.TextUnmarshallerHookFunc(),
|
mapstructure.TextUnmarshallerHookFunc(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ const (
|
|||||||
OutFormatTeamCity = "teamcity"
|
OutFormatTeamCity = "teamcity"
|
||||||
)
|
)
|
||||||
|
|
||||||
var OutFormats = []string{
|
var AllOutputFormats = []string{
|
||||||
OutFormatColoredLineNumber,
|
OutFormatColoredLineNumber,
|
||||||
OutFormatLineNumber,
|
OutFormatLineNumber,
|
||||||
OutFormatJSON,
|
OutFormatJSON,
|
||||||
@ -35,14 +35,17 @@ var OutFormats = []string{
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Output struct {
|
type Output struct {
|
||||||
Format string `mapstructure:"format"`
|
Formats OutputFormats `mapstructure:"formats"`
|
||||||
PrintIssuedLine bool `mapstructure:"print-issued-lines"`
|
PrintIssuedLine bool `mapstructure:"print-issued-lines"`
|
||||||
PrintLinterName bool `mapstructure:"print-linter-name"`
|
PrintLinterName bool `mapstructure:"print-linter-name"`
|
||||||
UniqByLine bool `mapstructure:"uniq-by-line"`
|
UniqByLine bool `mapstructure:"uniq-by-line"`
|
||||||
SortResults bool `mapstructure:"sort-results"`
|
SortResults bool `mapstructure:"sort-results"`
|
||||||
SortOrder []string `mapstructure:"sort-order"`
|
SortOrder []string `mapstructure:"sort-order"`
|
||||||
PathPrefix string `mapstructure:"path-prefix"`
|
PathPrefix string `mapstructure:"path-prefix"`
|
||||||
ShowStats bool `mapstructure:"show-stats"`
|
ShowStats bool `mapstructure:"show-stats"`
|
||||||
|
|
||||||
|
// Deprecated: use Formats instead.
|
||||||
|
Format string `mapstructure:"format"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *Output) Validate() error {
|
func (o *Output) Validate() error {
|
||||||
@ -64,5 +67,46 @@ func (o *Output) Validate() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, format := range o.Formats {
|
||||||
|
err := format.Validate()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type OutputFormat struct {
|
||||||
|
Format string `mapstructure:"format"`
|
||||||
|
Path string `mapstructure:"path"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *OutputFormat) Validate() error {
|
||||||
|
if o.Format == "" {
|
||||||
|
return errors.New("the format is required")
|
||||||
|
}
|
||||||
|
|
||||||
|
if !slices.Contains(AllOutputFormats, o.Format) {
|
||||||
|
return fmt.Errorf("unsupported output format %q", o.Format)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type OutputFormats []OutputFormat
|
||||||
|
|
||||||
|
func (p *OutputFormats) UnmarshalText(text []byte) error {
|
||||||
|
formats := strings.Split(string(text), ",")
|
||||||
|
|
||||||
|
for _, item := range formats {
|
||||||
|
format, path, _ := strings.Cut(item, ":")
|
||||||
|
|
||||||
|
*p = append(*p, OutputFormat{
|
||||||
|
Path: path,
|
||||||
|
Format: format,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -81,6 +81,86 @@ func TestOutput_Validate_error(t *testing.T) {
|
|||||||
},
|
},
|
||||||
expected: `the sort-order name "linter" is repeated several times`,
|
expected: `the sort-order name "linter" is repeated several times`,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
desc: "unsupported format",
|
||||||
|
settings: &Output{
|
||||||
|
Formats: []OutputFormat{
|
||||||
|
{
|
||||||
|
Format: "test",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: `unsupported output format "test"`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
err := test.settings.Validate()
|
||||||
|
require.EqualError(t, err, test.expected)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOutputFormat_Validate(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
desc string
|
||||||
|
settings *OutputFormat
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
desc: "only format",
|
||||||
|
settings: &OutputFormat{
|
||||||
|
Format: "json",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "format and path (relative)",
|
||||||
|
settings: &OutputFormat{
|
||||||
|
Format: "json",
|
||||||
|
Path: "./example.json",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "format and path (absolute)",
|
||||||
|
settings: &OutputFormat{
|
||||||
|
Format: "json",
|
||||||
|
Path: "/tmp/example.json",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
err := test.settings.Validate()
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOutputFormat_Validate_error(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
desc string
|
||||||
|
settings *OutputFormat
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
desc: "empty",
|
||||||
|
settings: &OutputFormat{},
|
||||||
|
expected: "the format is required",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "unsupported format",
|
||||||
|
settings: &OutputFormat{
|
||||||
|
Format: "test",
|
||||||
|
},
|
||||||
|
expected: `unsupported output format "test"`,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
@ -6,7 +6,6 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/golangci/golangci-lint/pkg/config"
|
"github.com/golangci/golangci-lint/pkg/config"
|
||||||
"github.com/golangci/golangci-lint/pkg/logutils"
|
"github.com/golangci/golangci-lint/pkg/logutils"
|
||||||
@ -54,11 +53,8 @@ func NewPrinter(log logutils.Log, cfg *config.Output, reportData *report.Data) (
|
|||||||
|
|
||||||
// Print prints issues based on the formats defined
|
// Print prints issues based on the formats defined
|
||||||
func (c *Printer) Print(issues []result.Issue) error {
|
func (c *Printer) Print(issues []result.Issue) error {
|
||||||
formats := strings.Split(c.cfg.Format, ",")
|
for _, format := range c.cfg.Formats {
|
||||||
|
err := c.printReports(issues, format)
|
||||||
for _, item := range formats {
|
|
||||||
format, path, _ := strings.Cut(item, ":")
|
|
||||||
err := c.printReports(issues, path, format)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -67,10 +63,10 @@ func (c *Printer) Print(issues []result.Issue) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Printer) printReports(issues []result.Issue, path, format string) error {
|
func (c *Printer) printReports(issues []result.Issue, format config.OutputFormat) error {
|
||||||
w, shouldClose, err := c.createWriter(path)
|
w, shouldClose, err := c.createWriter(format.Path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("can't create output for %s: %w", path, err)
|
return fmt.Errorf("can't create output for %s: %w", format.Path, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
@ -79,7 +75,7 @@ func (c *Printer) printReports(issues []result.Issue, path, format string) error
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
p, err := c.createPrinter(format, w)
|
p, err := c.createPrinter(format.Format, w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -140,7 +136,7 @@ func (c *Printer) createPrinter(format string, w io.Writer) (issuePrinter, error
|
|||||||
case config.OutFormatTeamCity:
|
case config.OutFormatTeamCity:
|
||||||
p = NewTeamCity(w)
|
p = NewTeamCity(w)
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("unknown output format %s", format)
|
return nil, fmt.Errorf("unknown output format %q", format)
|
||||||
}
|
}
|
||||||
|
|
||||||
return p, nil
|
return p, nil
|
||||||
|
@ -43,14 +43,21 @@ func TestPrinter_Print_stdout(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "stdout (implicit)",
|
desc: "stdout (implicit)",
|
||||||
cfg: &config.Output{
|
cfg: &config.Output{
|
||||||
Format: "line-number",
|
Formats: []config.OutputFormat{
|
||||||
|
{Format: "line-number"},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
expected: "golden-line-number.txt",
|
expected: "golden-line-number.txt",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc: "stdout (explicit)",
|
desc: "stdout (explicit)",
|
||||||
cfg: &config.Output{
|
cfg: &config.Output{
|
||||||
Format: "line-number:stdout",
|
Formats: []config.OutputFormat{
|
||||||
|
{
|
||||||
|
Format: "line-number",
|
||||||
|
Path: "stdout",
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
expected: "golden-line-number.txt",
|
expected: "golden-line-number.txt",
|
||||||
},
|
},
|
||||||
@ -92,7 +99,12 @@ func TestPrinter_Print_stderr(t *testing.T) {
|
|||||||
unmarshalFile(t, "in-report-data.json", data)
|
unmarshalFile(t, "in-report-data.json", data)
|
||||||
|
|
||||||
cfg := &config.Output{
|
cfg := &config.Output{
|
||||||
Format: "line-number:stderr",
|
Formats: []config.OutputFormat{
|
||||||
|
{
|
||||||
|
Format: "line-number",
|
||||||
|
Path: "stderr",
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
p, err := NewPrinter(logger, cfg, data)
|
p, err := NewPrinter(logger, cfg, data)
|
||||||
@ -126,7 +138,12 @@ func TestPrinter_Print_file(t *testing.T) {
|
|||||||
outputPath := filepath.Join(t.TempDir(), "report.txt")
|
outputPath := filepath.Join(t.TempDir(), "report.txt")
|
||||||
|
|
||||||
cfg := &config.Output{
|
cfg := &config.Output{
|
||||||
Format: "line-number:" + outputPath,
|
Formats: []config.OutputFormat{
|
||||||
|
{
|
||||||
|
Format: "line-number",
|
||||||
|
Path: outputPath,
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
p, err := NewPrinter(logger, cfg, data)
|
p, err := NewPrinter(logger, cfg, data)
|
||||||
@ -165,9 +182,20 @@ func TestPrinter_Print_multiple(t *testing.T) {
|
|||||||
outputPath := filepath.Join(t.TempDir(), "github-actions.txt")
|
outputPath := filepath.Join(t.TempDir(), "github-actions.txt")
|
||||||
|
|
||||||
cfg := &config.Output{
|
cfg := &config.Output{
|
||||||
Format: "github-actions:" + outputPath +
|
Formats: []config.OutputFormat{
|
||||||
",json" +
|
{
|
||||||
",line-number:stderr",
|
Format: "github-actions",
|
||||||
|
Path: outputPath,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Format: "json",
|
||||||
|
Path: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Format: "line-number",
|
||||||
|
Path: "stderr",
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
p, err := NewPrinter(logger, cfg, data)
|
p, err := NewPrinter(logger, cfg, data)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user