mirror of https://github.com/go-gitea/gitea
Use binary version of revive linter (#15739)
Use the common `go get` method to install and run the revive linter, removing the useless build/lint.go and related vendor libraries.pull/15802/head
parent
a69fb523a7
commit
c3802dcc0f
@ -1,325 +0,0 @@
|
||||
// Copyright 2020 The Gitea Authors. All rights reserved.
|
||||
// Copyright (c) 2018 Minko Gechev. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/mgechev/dots"
|
||||
"github.com/mgechev/revive/formatter"
|
||||
"github.com/mgechev/revive/lint"
|
||||
"github.com/mgechev/revive/rule"
|
||||
"github.com/mitchellh/go-homedir"
|
||||
"github.com/pelletier/go-toml"
|
||||
)
|
||||
|
||||
func fail(err string) {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
var defaultRules = []lint.Rule{
|
||||
&rule.VarDeclarationsRule{},
|
||||
&rule.PackageCommentsRule{},
|
||||
&rule.DotImportsRule{},
|
||||
&rule.BlankImportsRule{},
|
||||
&rule.ExportedRule{},
|
||||
&rule.VarNamingRule{},
|
||||
&rule.IndentErrorFlowRule{},
|
||||
&rule.IfReturnRule{},
|
||||
&rule.RangeRule{},
|
||||
&rule.ErrorfRule{},
|
||||
&rule.ErrorNamingRule{},
|
||||
&rule.ErrorStringsRule{},
|
||||
&rule.ReceiverNamingRule{},
|
||||
&rule.IncrementDecrementRule{},
|
||||
&rule.ErrorReturnRule{},
|
||||
&rule.UnexportedReturnRule{},
|
||||
&rule.TimeNamingRule{},
|
||||
&rule.ContextKeysType{},
|
||||
&rule.ContextAsArgumentRule{},
|
||||
}
|
||||
|
||||
var allRules = append([]lint.Rule{
|
||||
&rule.ArgumentsLimitRule{},
|
||||
&rule.CyclomaticRule{},
|
||||
&rule.FileHeaderRule{},
|
||||
&rule.EmptyBlockRule{},
|
||||
&rule.SuperfluousElseRule{},
|
||||
&rule.ConfusingNamingRule{},
|
||||
&rule.GetReturnRule{},
|
||||
&rule.ModifiesParamRule{},
|
||||
&rule.ConfusingResultsRule{},
|
||||
&rule.DeepExitRule{},
|
||||
&rule.UnusedParamRule{},
|
||||
&rule.UnreachableCodeRule{},
|
||||
&rule.AddConstantRule{},
|
||||
&rule.FlagParamRule{},
|
||||
&rule.UnnecessaryStmtRule{},
|
||||
&rule.StructTagRule{},
|
||||
&rule.ModifiesValRecRule{},
|
||||
&rule.ConstantLogicalExprRule{},
|
||||
&rule.BoolLiteralRule{},
|
||||
&rule.RedefinesBuiltinIDRule{},
|
||||
&rule.ImportsBlacklistRule{},
|
||||
&rule.FunctionResultsLimitRule{},
|
||||
&rule.MaxPublicStructsRule{},
|
||||
&rule.RangeValInClosureRule{},
|
||||
&rule.RangeValAddress{},
|
||||
&rule.WaitGroupByValueRule{},
|
||||
&rule.AtomicRule{},
|
||||
&rule.EmptyLinesRule{},
|
||||
&rule.LineLengthLimitRule{},
|
||||
&rule.CallToGCRule{},
|
||||
&rule.DuplicatedImportsRule{},
|
||||
&rule.ImportShadowingRule{},
|
||||
&rule.BareReturnRule{},
|
||||
&rule.UnusedReceiverRule{},
|
||||
&rule.UnhandledErrorRule{},
|
||||
&rule.CognitiveComplexityRule{},
|
||||
&rule.StringOfIntRule{},
|
||||
}, defaultRules...)
|
||||
|
||||
var allFormatters = []lint.Formatter{
|
||||
&formatter.Stylish{},
|
||||
&formatter.Friendly{},
|
||||
&formatter.JSON{},
|
||||
&formatter.NDJSON{},
|
||||
&formatter.Default{},
|
||||
&formatter.Unix{},
|
||||
&formatter.Checkstyle{},
|
||||
&formatter.Plain{},
|
||||
}
|
||||
|
||||
func getFormatters() map[string]lint.Formatter {
|
||||
result := map[string]lint.Formatter{}
|
||||
for _, f := range allFormatters {
|
||||
result[f.Name()] = f
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func getLintingRules(config *lint.Config) []lint.Rule {
|
||||
rulesMap := map[string]lint.Rule{}
|
||||
for _, r := range allRules {
|
||||
rulesMap[r.Name()] = r
|
||||
}
|
||||
|
||||
lintingRules := []lint.Rule{}
|
||||
for name := range config.Rules {
|
||||
rule, ok := rulesMap[name]
|
||||
if !ok {
|
||||
fail("cannot find rule: " + name)
|
||||
}
|
||||
lintingRules = append(lintingRules, rule)
|
||||
}
|
||||
|
||||
return lintingRules
|
||||
}
|
||||
|
||||
func parseConfig(path string) *lint.Config {
|
||||
config := &lint.Config{}
|
||||
file, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
fail("cannot read the config file")
|
||||
}
|
||||
err = toml.Unmarshal(file, config)
|
||||
if err != nil {
|
||||
fail("cannot parse the config file: " + err.Error())
|
||||
}
|
||||
return config
|
||||
}
|
||||
|
||||
func normalizeConfig(config *lint.Config) {
|
||||
if config.Confidence == 0 {
|
||||
config.Confidence = 0.8
|
||||
}
|
||||
severity := config.Severity
|
||||
if severity != "" {
|
||||
for k, v := range config.Rules {
|
||||
if v.Severity == "" {
|
||||
v.Severity = severity
|
||||
}
|
||||
config.Rules[k] = v
|
||||
}
|
||||
for k, v := range config.Directives {
|
||||
if v.Severity == "" {
|
||||
v.Severity = severity
|
||||
}
|
||||
config.Directives[k] = v
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func getConfig() *lint.Config {
|
||||
config := defaultConfig()
|
||||
if configPath != "" {
|
||||
config = parseConfig(configPath)
|
||||
}
|
||||
normalizeConfig(config)
|
||||
return config
|
||||
}
|
||||
|
||||
func getFormatter() lint.Formatter {
|
||||
formatters := getFormatters()
|
||||
formatter := formatters["default"]
|
||||
if formatterName != "" {
|
||||
f, ok := formatters[formatterName]
|
||||
if !ok {
|
||||
fail("unknown formatter " + formatterName)
|
||||
}
|
||||
formatter = f
|
||||
}
|
||||
return formatter
|
||||
}
|
||||
|
||||
func buildDefaultConfigPath() string {
|
||||
var result string
|
||||
if homeDir, err := homedir.Dir(); err == nil {
|
||||
result = filepath.Join(homeDir, "revive.toml")
|
||||
if _, err := os.Stat(result); err != nil {
|
||||
result = ""
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func defaultConfig() *lint.Config {
|
||||
defaultConfig := lint.Config{
|
||||
Confidence: 0.0,
|
||||
Severity: lint.SeverityWarning,
|
||||
Rules: map[string]lint.RuleConfig{},
|
||||
}
|
||||
for _, r := range defaultRules {
|
||||
defaultConfig.Rules[r.Name()] = lint.RuleConfig{}
|
||||
}
|
||||
return &defaultConfig
|
||||
}
|
||||
|
||||
func normalizeSplit(strs []string) []string {
|
||||
res := []string{}
|
||||
for _, s := range strs {
|
||||
t := strings.Trim(s, " \t")
|
||||
if len(t) > 0 {
|
||||
res = append(res, t)
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func getPackages() [][]string {
|
||||
globs := normalizeSplit(flag.Args())
|
||||
if len(globs) == 0 {
|
||||
globs = append(globs, ".")
|
||||
}
|
||||
|
||||
packages, err := dots.ResolvePackages(globs, normalizeSplit(excludePaths))
|
||||
if err != nil {
|
||||
fail(err.Error())
|
||||
}
|
||||
|
||||
return packages
|
||||
}
|
||||
|
||||
type arrayFlags []string
|
||||
|
||||
func (i *arrayFlags) String() string {
|
||||
return strings.Join([]string(*i), " ")
|
||||
}
|
||||
|
||||
func (i *arrayFlags) Set(value string) error {
|
||||
*i = append(*i, value)
|
||||
return nil
|
||||
}
|
||||
|
||||
var configPath string
|
||||
var excludePaths arrayFlags
|
||||
var formatterName string
|
||||
var help bool
|
||||
|
||||
var originalUsage = flag.Usage
|
||||
|
||||
func init() {
|
||||
flag.Usage = func() {
|
||||
originalUsage()
|
||||
}
|
||||
// command line help strings
|
||||
const (
|
||||
configUsage = "path to the configuration TOML file, defaults to $HOME/revive.toml, if present (i.e. -config myconf.toml)"
|
||||
excludeUsage = "list of globs which specify files to be excluded (i.e. -exclude foo/...)"
|
||||
formatterUsage = "formatter to be used for the output (i.e. -formatter stylish)"
|
||||
)
|
||||
|
||||
defaultConfigPath := buildDefaultConfigPath()
|
||||
|
||||
flag.StringVar(&configPath, "config", defaultConfigPath, configUsage)
|
||||
flag.Var(&excludePaths, "exclude", excludeUsage)
|
||||
flag.StringVar(&formatterName, "formatter", "", formatterUsage)
|
||||
flag.Parse()
|
||||
}
|
||||
|
||||
func main() {
|
||||
config := getConfig()
|
||||
formatter := getFormatter()
|
||||
packages := getPackages()
|
||||
|
||||
revive := lint.New(func(file string) ([]byte, error) {
|
||||
return ioutil.ReadFile(file)
|
||||
})
|
||||
|
||||
lintingRules := getLintingRules(config)
|
||||
|
||||
failures, err := revive.Lint(packages, lintingRules, *config)
|
||||
if err != nil {
|
||||
fail(err.Error())
|
||||
}
|
||||
|
||||
formatChan := make(chan lint.Failure)
|
||||
exitChan := make(chan bool)
|
||||
|
||||
var output string
|
||||
go (func() {
|
||||
output, err = formatter.Format(formatChan, *config)
|
||||
if err != nil {
|
||||
fail(err.Error())
|
||||
}
|
||||
exitChan <- true
|
||||
})()
|
||||
|
||||
exitCode := 0
|
||||
for f := range failures {
|
||||
if f.Confidence < config.Confidence {
|
||||
continue
|
||||
}
|
||||
if exitCode == 0 {
|
||||
exitCode = config.WarningCode
|
||||
}
|
||||
if c, ok := config.Rules[f.RuleName]; ok && c.Severity == lint.SeverityError {
|
||||
exitCode = config.ErrorCode
|
||||
}
|
||||
if c, ok := config.Directives[f.RuleName]; ok && c.Severity == lint.SeverityError {
|
||||
exitCode = config.ErrorCode
|
||||
}
|
||||
|
||||
formatChan <- f
|
||||
}
|
||||
|
||||
close(formatChan)
|
||||
<-exitChan
|
||||
if output != "" {
|
||||
fmt.Println(output)
|
||||
}
|
||||
|
||||
os.Exit(exitCode)
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
*.test
|
||||
*.out
|
||||
.devcontainer/
|
@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021 Salvador Cavadini
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
@ -1,52 +0,0 @@
|
||||
# garif
|
||||
|
||||
A GO package to create and manipulate SARIF logs.
|
||||
|
||||
SARIF, from _Static Analysis Results Interchange Format_, is a standard JSON-based format for the output of static analysis tools defined and promoted by [OASIS](https://www.oasis-open.org/).
|
||||
|
||||
Current supported version of the standard is [SARIF-v2.1.0](https://docs.oasis-open.org/sarif/sarif/v2.1.0/csprd01/sarif-v2.1.0-csprd01.html
|
||||
).
|
||||
|
||||
## Usage
|
||||
|
||||
The package provides access to every element of the SARIF model, therefore you are free to manipulate it at every detail.
|
||||
|
||||
The package also provides constructors functions (`New...`) and decorators methods (`With...`) that simplify the creation of SARIF files for common use cases.
|
||||
|
||||
Using these constructors and decorators we can easily create the example SARIF file of the [Microsoft SARIF pages](https://github.com/microsoft/sarif-tutorials/blob/master/docs/1-Introduction.md)
|
||||
|
||||
|
||||
```go
|
||||
import to `github.com/chavacava/garif`
|
||||
|
||||
// ...
|
||||
|
||||
rule := garif.NewRule("no-unused-vars").
|
||||
WithHelpUri("https://eslint.org/docs/rules/no-unused-vars").
|
||||
WithShortDescription("disallow unused variables").
|
||||
WithProperties("category", "Variables")
|
||||
|
||||
driver := garif.NewDriver("ESLint").
|
||||
WithInformationUri("https://eslint.org").
|
||||
WithRules(rule)
|
||||
|
||||
run := garif.NewRun(NewTool(driver)).
|
||||
WithArtifactsURIs("file:///C:/dev/sarif/sarif-tutorials/samples/Introduction/simple-example.js")
|
||||
|
||||
run.WithResult(rule.Id, "'x' is assigned a value but never used.", "file:///C:/dev/sarif/sarif-tutorials/samples/Introduction/simple-example.js", 1, 5)
|
||||
|
||||
logFile := garif.NewLogFile([]*Run{run}, Version210)
|
||||
|
||||
logFile.Write(os.Stdout)
|
||||
```
|
||||
|
||||
## Why this package?
|
||||
This package was initiated during my works on adding to [`revive`](https://github.com/mgechev/revive) a SARIF output formatter.
|
||||
I've tried to use [go-sarif](https://github.com/owenrumney/go-sarif) by [Owen Rumney](https://github.com/owenrumney) but it is too focused in the use case of the static analyzer [tfsec](https://tfsec.dev) so I've decided to create a package flexible enough to generate SARIF files in broader cases.
|
||||
|
||||
## More information about SARIF
|
||||
For more information about SARIF, you can visit the [Oasis Open](https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=sarif) site.
|
||||
|
||||
|
||||
## Contributing
|
||||
Of course, contributions are welcome!
|
@ -1,338 +0,0 @@
|
||||
package garif
|
||||
|
||||
// NewAddress creates a valid Address
|
||||
func NewAddress() *Address {
|
||||
return &Address{}
|
||||
}
|
||||
|
||||
// NewArtifact creates a valid Artifact
|
||||
func NewArtifact() *Artifact {
|
||||
return &Artifact{}
|
||||
}
|
||||
|
||||
// NewArtifactChange creates a valid ArtifactChange
|
||||
func NewArtifactChange(location *ArtifactLocation, replacements ...*Replacement) *ArtifactChange {
|
||||
return &ArtifactChange{
|
||||
ArtifactLocation: location,
|
||||
Replacements: replacements,
|
||||
}
|
||||
}
|
||||
|
||||
// NewArtifactContent creates a valid ArtifactContent
|
||||
func NewArtifactContent() *ArtifactContent {
|
||||
return &ArtifactContent{}
|
||||
}
|
||||
|
||||
// NewArtifactLocation creates a valid ArtifactLocation
|
||||
func NewArtifactLocation() *ArtifactLocation {
|
||||
return &ArtifactLocation{}
|
||||
}
|
||||
|
||||
// NewAttachment creates a valid Attachment
|
||||
func NewAttachment(location *ArtifactLocation) *Attachment {
|
||||
return &Attachment{ArtifactLocation: location}
|
||||
}
|
||||
|
||||
// NewCodeFlow creates a valid CodeFlow
|
||||
func NewCodeFlow(threadFlows ...*ThreadFlow) *CodeFlow {
|
||||
return &CodeFlow{ThreadFlows: threadFlows}
|
||||
}
|
||||
|
||||
// NewConfigurationOverride creates a valid ConfigurationOverride
|
||||
func NewConfigurationOverride(configuration *ReportingConfiguration, descriptor *ReportingDescriptorReference) *ConfigurationOverride {
|
||||
return &ConfigurationOverride{
|
||||
Configuration: configuration,
|
||||
Descriptor: descriptor,
|
||||
}
|
||||
}
|
||||
|
||||
// NewConversion creates a valid Conversion
|
||||
func NewConversion(tool *Tool) *Conversion {
|
||||
return &Conversion{Tool: tool}
|
||||
}
|
||||
|
||||
// NewEdge creates a valid Edge
|
||||
func NewEdge(id, sourceNodeId, targetNodeId string) *Edge {
|
||||
return &Edge{
|
||||
Id: id,
|
||||
SourceNodeId: sourceNodeId,
|
||||
TargetNodeId: targetNodeId,
|
||||
}
|
||||
}
|
||||
|
||||
// NewEdgeTraversal creates a valid EdgeTraversal
|
||||
func NewEdgeTraversal(edgeId string) *EdgeTraversal {
|
||||
return &EdgeTraversal{
|
||||
EdgeId: edgeId,
|
||||
}
|
||||
}
|
||||
|
||||
// NewException creates a valid Exception
|
||||
func NewException() *Exception {
|
||||
return &Exception{}
|
||||
}
|
||||
|
||||
// NewExternalProperties creates a valid ExternalProperties
|
||||
func NewExternalProperties() *ExternalProperties {
|
||||
return &ExternalProperties{}
|
||||
}
|
||||
|
||||
// NewExternalPropertyFileReference creates a valid ExternalPropertyFileReference
|
||||
func NewExternalPropertyFileReference() *ExternalPropertyFileReference {
|
||||
return &ExternalPropertyFileReference{}
|
||||
}
|
||||
|
||||
// NewExternalPropertyFileReferences creates a valid ExternalPropertyFileReferences
|
||||
func NewExternalPropertyFileReferences() *ExternalPropertyFileReferences {
|
||||
return &ExternalPropertyFileReferences{}
|
||||
}
|
||||
|
||||
// NewFix creates a valid Fix
|
||||
func NewFix(artifactChanges ...*ArtifactChange) *Fix {
|
||||
return &Fix{
|
||||
ArtifactChanges: artifactChanges,
|
||||
}
|
||||
}
|
||||
|
||||
// NewGraph creates a valid Graph
|
||||
func NewGraph() *Graph {
|
||||
return &Graph{}
|
||||
}
|
||||
|
||||
// NewGraphTraversal creates a valid GraphTraversal
|
||||
func NewGraphTraversal() *GraphTraversal {
|
||||
return &GraphTraversal{}
|
||||
}
|
||||
|
||||
// NewInvocation creates a valid Invocation
|
||||
func NewInvocation(executionSuccessful bool) *Invocation {
|
||||
return &Invocation{
|
||||
ExecutionSuccessful: executionSuccessful,
|
||||
}
|
||||
}
|
||||
|
||||
// NewLocation creates a valid Location
|
||||
func NewLocation() *Location {
|
||||
return &Location{}
|
||||
}
|
||||
|
||||
// NewLocationRelationship creates a valid LocationRelationship
|
||||
func NewLocationRelationship(target int) *LocationRelationship {
|
||||
return &LocationRelationship{
|
||||
Target: target,
|
||||
}
|
||||
}
|
||||
|
||||
type LogFileVersion string
|
||||
|
||||
const Version210 LogFileVersion = "2.1.0"
|
||||
|
||||
// NewLogFile creates a valid LogFile
|
||||
func NewLogFile(runs []*Run, version LogFileVersion) *LogFile {
|
||||
return &LogFile{
|
||||
Runs: runs,
|
||||
Version: version,
|
||||
}
|
||||
}
|
||||
|
||||
// NewLogicalLocation creates a valid LogicalLocation
|
||||
func NewLogicalLocation() *LogicalLocation {
|
||||
return &LogicalLocation{}
|
||||
}
|
||||
|
||||
// NewMessage creates a valid Message
|
||||
func NewMessage() *Message {
|
||||
return &Message{}
|
||||
}
|
||||
|
||||
// NewMessageFromText creates a valid Message with the given text
|
||||
func NewMessageFromText(text string) *Message {
|
||||
return &Message{
|
||||
Text: text,
|
||||
}
|
||||
}
|
||||
|
||||
// NewMultiformatMessageString creates a valid MultiformatMessageString
|
||||
func NewMultiformatMessageString(text string) *MultiformatMessageString {
|
||||
return &MultiformatMessageString{
|
||||
Text: text,
|
||||
}
|
||||
}
|
||||
|
||||
// NewNode creates a valid Node
|
||||
func NewNode(id string) *Node {
|
||||
return &Node{
|
||||
Id: id,
|
||||
}
|
||||
}
|
||||
|
||||
// NewNotification creates a valid Notification
|
||||
func NewNotification(message *Message) *Notification {
|
||||
return &Notification{
|
||||
Message: message,
|
||||
}
|
||||
}
|
||||
|
||||
// NewPhysicalLocation creates a valid PhysicalLocation
|
||||
func NewPhysicalLocation() *PhysicalLocation {
|
||||
return &PhysicalLocation{}
|
||||
}
|
||||
|
||||
// NewPropertyBag creates a valid PropertyBag
|
||||
func NewPropertyBag() *PropertyBag {
|
||||
return &PropertyBag{}
|
||||
}
|
||||
|
||||
// NewRectangle creates a valid Rectangle
|
||||
func NewRectangle() *Rectangle {
|
||||
return &Rectangle{}
|
||||
}
|
||||
|
||||
// NewRegion creates a valid Region
|
||||
func NewRegion() *Region {
|
||||
return &Region{}
|
||||
}
|
||||
|
||||
// NewReplacement creates a valid Replacement
|
||||
func NewReplacement(deletedRegion *Region) *Replacement {
|
||||
return &Replacement{
|
||||
DeletedRegion: deletedRegion,
|
||||
}
|
||||
}
|
||||
|
||||
// NewReportingConfiguration creates a valid ReportingConfiguration
|
||||
func NewReportingConfiguration() *ReportingConfiguration {
|
||||
return &ReportingConfiguration{}
|
||||
}
|
||||
|
||||
// NewReportingDescriptor creates a valid ReportingDescriptor
|
||||
func NewReportingDescriptor(id string) *ReportingDescriptor {
|
||||
return &ReportingDescriptor{
|
||||
Id: id,
|
||||
}
|
||||
}
|
||||
|
||||
// NewRule is an alias for NewReportingDescriptor
|
||||
func NewRule(id string) *ReportingDescriptor {
|
||||
return NewReportingDescriptor(id)
|
||||
}
|
||||
|
||||
// NewReportingDescriptorReference creates a valid ReportingDescriptorReference
|
||||
func NewReportingDescriptorReference() *ReportingDescriptorReference {
|
||||
return &ReportingDescriptorReference{}
|
||||
}
|
||||
|
||||
// NewReportingDescriptorRelationship creates a valid ReportingDescriptorRelationship
|
||||
func NewReportingDescriptorRelationship(target *ReportingDescriptorReference) *ReportingDescriptorRelationship {
|
||||
return &ReportingDescriptorRelationship{
|
||||
Target: target,
|
||||
}
|
||||
}
|
||||
|
||||
// NewResult creates a valid Result
|
||||
func NewResult(message *Message) *Result {
|
||||
return &Result{
|
||||
Message: message,
|
||||
}
|
||||
}
|
||||
|
||||
// NewResultProvenance creates a valid ResultProvenance
|
||||
func NewResultProvenance() *ResultProvenance {
|
||||
return &ResultProvenance{}
|
||||
}
|
||||
|
||||
// NewRun creates a valid Run
|
||||
func NewRun(tool *Tool) *Run {
|
||||
return &Run{
|
||||
Tool: tool,
|
||||
}
|
||||
}
|
||||
|
||||
// NewRunAutomationDetails creates a valid RunAutomationDetails
|
||||
func NewRunAutomationDetails() *RunAutomationDetails {
|
||||
return &RunAutomationDetails{}
|
||||
}
|
||||
|
||||
// New creates a valid
|
||||
func NewSpecialLocations() *SpecialLocations {
|
||||
return &SpecialLocations{}
|
||||
}
|
||||
|
||||
// NewStack creates a valid Stack
|
||||
func NewStack(frames ...*StackFrame) *Stack {
|
||||
return &Stack{
|
||||
Frames: frames,
|
||||
}
|
||||
}
|
||||
|
||||
// NewStackFrame creates a valid StackFrame
|
||||
func NewStackFrame() *StackFrame {
|
||||
return &StackFrame{}
|
||||
}
|
||||
|
||||
// NewSuppression creates a valid Suppression
|
||||
func NewSuppression(kind string) *Suppression {
|
||||
return &Suppression{
|
||||
Kind: kind,
|
||||
}
|
||||
}
|
||||
|
||||
// NewThreadFlow creates a valid ThreadFlow
|
||||
func NewThreadFlow(locations []*ThreadFlowLocation) *ThreadFlow {
|
||||
return &ThreadFlow{
|
||||
Locations: locations,
|
||||
}
|
||||
}
|
||||
|
||||
// NewThreadFlowLocation creates a valid ThreadFlowLocation
|
||||
func NewThreadFlowLocation() *ThreadFlowLocation {
|
||||
return &ThreadFlowLocation{}
|
||||
}
|
||||
|
||||
// NewTool creates a valid Tool
|
||||
func NewTool(driver *ToolComponent) *Tool {
|
||||
return &Tool{
|
||||
Driver: driver,
|
||||
}
|
||||
}
|
||||
|
||||
// NewToolComponent creates a valid ToolComponent
|
||||
func NewToolComponent(name string) *ToolComponent {
|
||||
return &ToolComponent{
|
||||
Name: name,
|
||||
}
|
||||
}
|
||||
|
||||
// NewDriver is an alias for NewToolComponent
|
||||
func NewDriver(name string) *ToolComponent {
|
||||
return NewToolComponent(name)
|
||||
}
|
||||
|
||||
// NewToolComponentReference creates a valid ToolComponentReference
|
||||
func NewToolComponentReference() *ToolComponentReference {
|
||||
return &ToolComponentReference{}
|
||||
}
|
||||
|
||||
// NewTranslationMetadata creates a valid TranslationMetadata
|
||||
func NewTranslationMetadata(name string) *TranslationMetadata {
|
||||
return &TranslationMetadata{
|
||||
Name: name,
|
||||
}
|
||||
}
|
||||
|
||||
// NewVersionControlDetails creates a valid VersionControlDetails
|
||||
func NewVersionControlDetails(repositoryUri string) *VersionControlDetails {
|
||||
return &VersionControlDetails{
|
||||
RepositoryUri: repositoryUri,
|
||||
}
|
||||
}
|
||||
|
||||
// NewWebRequest creates a valid WebRequest
|
||||
func NewWebRequest() *WebRequest {
|
||||
return &WebRequest{}
|
||||
}
|
||||
|
||||
// NewWebResponse creates a valid WebResponse
|
||||
func NewWebResponse() *WebResponse {
|
||||
return &WebResponse{}
|
||||
}
|
@ -1,94 +0,0 @@
|
||||
package garif
|
||||
|
||||
// WithLineColumn sets a physical location with the given line and column
|
||||
func (l *Location) WithLineColumn(line, column int) *Location {
|
||||
if l.PhysicalLocation == nil {
|
||||
l.PhysicalLocation = NewPhysicalLocation()
|
||||
}
|
||||
|
||||
l.PhysicalLocation.Region = NewRegion()
|
||||
l.PhysicalLocation.Region.StartLine = line
|
||||
l.PhysicalLocation.Region.StartColumn = column
|
||||
|
||||
return l
|
||||
}
|
||||
|
||||
// WithURI sets a physical location with the given URI
|
||||
func (l *Location) WithURI(uri string) *Location {
|
||||
if l.PhysicalLocation == nil {
|
||||
l.PhysicalLocation = NewPhysicalLocation()
|
||||
}
|
||||
|
||||
l.PhysicalLocation.ArtifactLocation = NewArtifactLocation()
|
||||
l.PhysicalLocation.ArtifactLocation.Uri = uri
|
||||
|
||||
return l
|
||||
}
|
||||
|
||||
// WithKeyValue sets (overwrites) the value of the given key
|
||||
func (b PropertyBag) WithKeyValue(key string, value interface{}) PropertyBag {
|
||||
b[key] = value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithHelpUri sets the help URI for this ReportingDescriptor
|
||||
func (r *ReportingDescriptor) WithHelpUri(uri string) *ReportingDescriptor {
|
||||
r.HelpUri = uri
|
||||
return r
|
||||
}
|
||||
|
||||
// WithProperties adds the key & value to the properties of this ReportingDescriptor
|
||||
func (r *ReportingDescriptor) WithProperties(key string, value interface{}) *ReportingDescriptor {
|
||||
if r.Properties == nil {
|
||||
r.Properties = NewPropertyBag()
|
||||
}
|
||||
|
||||
r.Properties.WithKeyValue(key, value)
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
// WithArtifactsURIs adds the given URI as artifacts of this Run
|
||||
func (r *Run) WithArtifactsURIs(uris ...string) *Run {
|
||||
if r.Artifacts == nil {
|
||||
r.Artifacts = []*Artifact{}
|
||||
}
|
||||
|
||||
for _, uri := range uris {
|
||||
a := NewArtifact()
|
||||
a.Location = NewArtifactLocation()
|
||||
a.Location.Uri = uri
|
||||
r.Artifacts = append(r.Artifacts, a)
|
||||
}
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
// WithResult adds a result to this Run
|
||||
func (r *Run) WithResult(ruleId string, message string, uri string, line int, column int) *Run {
|
||||
if r.Results == nil {
|
||||
r.Results = []*Result{}
|
||||
}
|
||||
|
||||
msg := NewMessage()
|
||||
msg.Text = message
|
||||
result := NewResult(msg)
|
||||
location := NewLocation().WithURI(uri).WithLineColumn(line, column)
|
||||
|
||||
result.Locations = append(result.Locations, location)
|
||||
result.RuleId = ruleId
|
||||
r.Results = append(r.Results, result)
|
||||
return r
|
||||
}
|
||||
|
||||
// WithInformationUri sets the information URI
|
||||
func (t *ToolComponent) WithInformationUri(uri string) *ToolComponent {
|
||||
t.InformationUri = uri
|
||||
return t
|
||||
}
|
||||
|
||||
// WithRules sets (overwrites) the rules
|
||||
func (t *ToolComponent) WithRules(rules ...*ReportingDescriptor) *ToolComponent {
|
||||
t.Rules = rules
|
||||
return t
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
// Package garif defines all the GO structures required to model a SARIF log file.
|
||||
// These structures were created using the JSON-schema sarif-schema-2.1.0.json of SARIF logfiles
|
||||
// available at https://github.com/oasis-tcs/sarif-spec/tree/master/Schemata.
|
||||
//
|
||||
// The package provides constructors for all structures (see constructors.go) These constructors
|
||||
// ensure that the returned structure instantiation is valid with respect to the JSON schema and
|
||||
// should be used in place of plain structure instantiation.
|
||||
// The root structure is LogFile.
|
||||
//
|
||||
// The package provides utility decorators for the most commonly used structures (see decorators.go)
|
||||
package garif
|
@ -1,5 +0,0 @@
|
||||
module github.com/chavacava/garif
|
||||
|
||||
go 1.16
|
||||
|
||||
require github.com/stretchr/testify v1.7.0
|
@ -1,11 +0,0 @@
|
||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
@ -1,26 +0,0 @@
|
||||
package garif
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
)
|
||||
|
||||
// Write writes the JSON
|
||||
func (l *LogFile) Write(w io.Writer) error {
|
||||
marshal, err := json.Marshal(l)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = w.Write(marshal)
|
||||
return err
|
||||
}
|
||||
|
||||
// PrettyWrite writes indented JSON
|
||||
func (l *LogFile) PrettyWrite(w io.Writer) error {
|
||||
marshal, err := json.MarshalIndent(l, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = w.Write(marshal)
|
||||
return err
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,20 +0,0 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013 Fatih Arslan
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@ -1,173 +0,0 @@
|
||||
# color [](https://github.com/fatih/color/actions) [](https://pkg.go.dev/github.com/fatih/color)
|
||||
|
||||
Color lets you use colorized outputs in terms of [ANSI Escape
|
||||
Codes](http://en.wikipedia.org/wiki/ANSI_escape_code#Colors) in Go (Golang). It
|
||||
has support for Windows too! The API can be used in several ways, pick one that
|
||||
suits you.
|
||||
|
||||

|
||||
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
go get github.com/fatih/color
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Standard colors
|
||||
|
||||
```go
|
||||
// Print with default helper functions
|
||||
color.Cyan("Prints text in cyan.")
|
||||
|
||||
// A newline will be appended automatically
|
||||
color.Blue("Prints %s in blue.", "text")
|
||||
|
||||
// These are using the default foreground colors
|
||||
color.Red("We have red")
|
||||
color.Magenta("And many others ..")
|
||||
|
||||
```
|
||||
|
||||
### Mix and reuse colors
|
||||
|
||||
```go
|
||||
// Create a new color object
|
||||
c := color.New(color.FgCyan).Add(color.Underline)
|
||||
c.Println("Prints cyan text with an underline.")
|
||||
|
||||
// Or just add them to New()
|
||||
d := color.New(color.FgCyan, color.Bold)
|
||||
d.Printf("This prints bold cyan %s\n", "too!.")
|
||||
|
||||
// Mix up foreground and background colors, create new mixes!
|
||||
red := color.New(color.FgRed)
|
||||
|
||||
boldRed := red.Add(color.Bold)
|
||||
boldRed.Println("This will print text in bold red.")
|
||||
|
||||
whiteBackground := red.Add(color.BgWhite)
|
||||
whiteBackground.Println("Red text with white background.")
|
||||
```
|
||||
|
||||
### Use your own output (io.Writer)
|
||||
|
||||
```go
|
||||
// Use your own io.Writer output
|
||||
color.New(color.FgBlue).Fprintln(myWriter, "blue color!")
|
||||
|
||||
blue := color.New(color.FgBlue)
|
||||
blue.Fprint(writer, "This will print text in blue.")
|
||||
```
|
||||
|
||||
### Custom print functions (PrintFunc)
|
||||
|
||||
```go
|
||||
// Create a custom print function for convenience
|
||||
red := color.New(color.FgRed).PrintfFunc()
|
||||
red("Warning")
|
||||
red("Error: %s", err)
|
||||
|
||||
// Mix up multiple attributes
|
||||
notice := color.New(color.Bold, color.FgGreen).PrintlnFunc()
|
||||
notice("Don't forget this...")
|
||||
```
|
||||
|
||||
### Custom fprint functions (FprintFunc)
|
||||
|
||||
```go
|
||||
blue := color.New(FgBlue).FprintfFunc()
|
||||
blue(myWriter, "important notice: %s", stars)
|
||||
|
||||
// Mix up with multiple attributes
|
||||
success := color.New(color.Bold, color.FgGreen).FprintlnFunc()
|
||||
success(myWriter, "Don't forget this...")
|
||||
```
|
||||
|
||||
### Insert into noncolor strings (SprintFunc)
|
||||
|
||||
```go
|
||||
// Create SprintXxx functions to mix strings with other non-colorized strings:
|
||||
yellow := color.New(color.FgYellow).SprintFunc()
|
||||
red := color.New(color.FgRed).SprintFunc()
|
||||
fmt.Printf("This is a %s and this is %s.\n", yellow("warning"), red("error"))
|
||||
|
||||
info := color.New(color.FgWhite, color.BgGreen).SprintFunc()
|
||||
fmt.Printf("This %s rocks!\n", info("package"))
|
||||
|
||||
// Use helper functions
|
||||
fmt.Println("This", color.RedString("warning"), "should be not neglected.")
|
||||
fmt.Printf("%v %v\n", color.GreenString("Info:"), "an important message.")
|
||||
|
||||
// Windows supported too! Just don't forget to change the output to color.Output
|
||||
fmt.Fprintf(color.Output, "Windows support: %s", color.GreenString("PASS"))
|
||||
```
|
||||
|
||||
### Plug into existing code
|
||||
|
||||
```go
|
||||
// Use handy standard colors
|
||||
color.Set(color.FgYellow)
|
||||
|
||||
fmt.Println("Existing text will now be in yellow")
|
||||
fmt.Printf("This one %s\n", "too")
|
||||
|
||||
color.Unset() // Don't forget to unset
|
||||
|
||||
// You can mix up parameters
|
||||
color.Set(color.FgMagenta, color.Bold)
|
||||
defer color.Unset() // Use it in your function
|
||||
|
||||
fmt.Println("All text will now be bold magenta.")
|
||||
```
|
||||
|
||||
### Disable/Enable color
|
||||
|
||||
There might be a case where you want to explicitly disable/enable color output. the
|
||||
`go-isatty` package will automatically disable color output for non-tty output streams
|
||||
(for example if the output were piped directly to `less`)
|
||||
|
||||
`Color` has support to disable/enable colors both globally and for single color
|
||||
definitions. For example suppose you have a CLI app and a `--no-color` bool flag. You
|
||||
can easily disable the color output with:
|
||||
|
||||
```go
|
||||
|
||||
var flagNoColor = flag.Bool("no-color", false, "Disable color output")
|
||||
|
||||
if *flagNoColor {
|
||||
color.NoColor = true // disables colorized output
|
||||
}
|
||||
```
|
||||
|
||||
It also has support for single color definitions (local). You can
|
||||
disable/enable color output on the fly:
|
||||
|
||||
```go
|
||||
c := color.New(color.FgCyan)
|
||||
c.Println("Prints cyan text")
|
||||
|
||||
c.DisableColor()
|
||||
c.Println("This is printed without any color")
|
||||
|
||||
c.EnableColor()
|
||||
c.Println("This prints again cyan...")
|
||||
```
|
||||
|
||||
## Todo
|
||||
|
||||
* Save/Return previous values
|
||||
* Evaluate fmt.Formatter interface
|
||||
|
||||
|
||||
## Credits
|
||||
|
||||
* [Fatih Arslan](https://github.com/fatih)
|
||||
* Windows support via @mattn: [colorable](https://github.com/mattn/go-colorable)
|
||||
|
||||
## License
|
||||
|
||||
The MIT License (MIT) - see [`LICENSE.md`](https://github.com/fatih/color/blob/master/LICENSE.md) for more details
|
||||
|
@ -1,603 +0,0 @@
|
||||
package color
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/mattn/go-colorable"
|
||||
"github.com/mattn/go-isatty"
|
||||
)
|
||||
|
||||
var (
|
||||
// NoColor defines if the output is colorized or not. It's dynamically set to
|
||||
// false or true based on the stdout's file descriptor referring to a terminal
|
||||
// or not. This is a global option and affects all colors. For more control
|
||||
// over each color block use the methods DisableColor() individually.
|
||||
NoColor = os.Getenv("TERM") == "dumb" ||
|
||||
(!isatty.IsTerminal(os.Stdout.Fd()) && !isatty.IsCygwinTerminal(os.Stdout.Fd()))
|
||||
|
||||
// Output defines the standard output of the print functions. By default
|
||||
// os.Stdout is used.
|
||||
Output = colorable.NewColorableStdout()
|
||||
|
||||
// Error defines a color supporting writer for os.Stderr.
|
||||
Error = colorable.NewColorableStderr()
|
||||
|
||||
// colorsCache is used to reduce the count of created Color objects and
|
||||
// allows to reuse already created objects with required Attribute.
|
||||
colorsCache = make(map[Attribute]*Color)
|
||||
colorsCacheMu sync.Mutex // protects colorsCache
|
||||
)
|
||||
|
||||
// Color defines a custom color object which is defined by SGR parameters.
|
||||
type Color struct {
|
||||
params []Attribute
|
||||
noColor *bool
|
||||
}
|
||||
|
||||
// Attribute defines a single SGR Code
|
||||
type Attribute int
|
||||
|
||||
const escape = "\x1b"
|
||||
|
||||
// Base attributes
|
||||
const (
|
||||
Reset Attribute = iota
|
||||
Bold
|
||||
Faint
|
||||
Italic
|
||||
Underline
|
||||
BlinkSlow
|
||||
BlinkRapid
|
||||
ReverseVideo
|
||||
Concealed
|
||||
CrossedOut
|
||||
)
|
||||
|
||||
// Foreground text colors
|
||||
const (
|
||||
FgBlack Attribute = iota + 30
|
||||
FgRed
|
||||
FgGreen
|
||||
FgYellow
|
||||
FgBlue
|
||||
FgMagenta
|
||||
FgCyan
|
||||
FgWhite
|
||||
)
|
||||
|
||||
// Foreground Hi-Intensity text colors
|
||||
const (
|
||||
FgHiBlack Attribute = iota + 90
|
||||
FgHiRed
|
||||
FgHiGreen
|
||||
FgHiYellow
|
||||
FgHiBlue
|
||||
FgHiMagenta
|
||||
FgHiCyan
|
||||
FgHiWhite
|
||||
)
|
||||
|
||||
// Background text colors
|
||||
const (
|
||||
BgBlack Attribute = iota + 40
|
||||
BgRed
|
||||
BgGreen
|
||||
BgYellow
|
||||
BgBlue
|
||||
BgMagenta
|
||||
BgCyan
|
||||
BgWhite
|
||||
)
|
||||
|
||||
// Background Hi-Intensity text colors
|
||||
const (
|
||||
BgHiBlack Attribute = iota + 100
|
||||
BgHiRed
|
||||
BgHiGreen
|
||||
BgHiYellow
|
||||
BgHiBlue
|
||||
BgHiMagenta
|
||||
BgHiCyan
|
||||
BgHiWhite
|
||||
)
|
||||
|
||||
// New returns a newly created color object.
|
||||
func New(value ...Attribute) *Color {
|
||||
c := &Color{params: make([]Attribute, 0)}
|
||||
c.Add(value...)
|
||||
return c
|
||||
}
|
||||
|
||||
// Set sets the given parameters immediately. It will change the color of
|
||||
// output with the given SGR parameters until color.Unset() is called.
|
||||
func Set(p ...Attribute) *Color {
|
||||
c := New(p...)
|
||||
c.Set()
|
||||
return c
|
||||
}
|
||||
|
||||
// Unset resets all escape attributes and clears the output. Usually should
|
||||
// be called after Set().
|
||||
func Unset() {
|
||||
if NoColor {
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Fprintf(Output, "%s[%dm", escape, Reset)
|
||||
}
|
||||
|
||||
// Set sets the SGR sequence.
|
||||
func (c *Color) Set() *Color {
|
||||
if c.isNoColorSet() {
|
||||
return c
|
||||
}
|
||||
|
||||
fmt.Fprintf(Output, c.format())
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *Color) unset() {
|
||||
if c.isNoColorSet() {
|
||||
return
|
||||
}
|
||||
|
||||
Unset()
|
||||
}
|
||||
|
||||
func (c *Color) setWriter(w io.Writer) *Color {
|
||||
if c.isNoColorSet() {
|
||||
return c
|
||||
}
|
||||
|
||||
fmt.Fprintf(w, c.format())
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *Color) unsetWriter(w io.Writer) {
|
||||
if c.isNoColorSet() {
|
||||
return
|
||||
}
|
||||
|
||||
if NoColor {
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Fprintf(w, "%s[%dm", escape, Reset)
|
||||
}
|
||||
|
||||
// Add is used to chain SGR parameters. Use as many as parameters to combine
|
||||
// and create custom color objects. Example: Add(color.FgRed, color.Underline).
|
||||
func (c *Color) Add(value ...Attribute) *Color {
|
||||
c.params = append(c.params, value...)
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *Color) prepend(value Attribute) {
|
||||
c.params = append(c.params, 0)
|
||||
copy(c.params[1:], c.params[0:])
|
||||
c.params[0] = value
|
||||
}
|
||||
|
||||
// Fprint formats using the default formats for its operands and writes to w.
|
||||
// Spaces are added between operands when neither is a string.
|
||||
// It returns the number of bytes written and any write error encountered.
|
||||
// On Windows, users should wrap w with colorable.NewColorable() if w is of
|
||||
// type *os.File.
|
||||
func (c *Color) Fprint(w io.Writer, a ...interface{}) (n int, err error) {
|
||||
c.setWriter(w)
|
||||
defer c.unsetWriter(w)
|
||||
|
||||
return fmt.Fprint(w, a...)
|
||||
}
|
||||
|
||||
// Print formats using the default formats for its operands and writes to
|
||||
// standard output. Spaces are added between operands when neither is a
|
||||
// string. It returns the number of bytes written and any write error
|
||||
// encountered. This is the standard fmt.Print() method wrapped with the given
|
||||
// color.
|
||||
func (c *Color) Print(a ...interface{}) (n int, err error) {
|
||||
c.Set()
|
||||
defer c.unset()
|
||||
|
||||
return fmt.Fprint(Output, a...)
|
||||
}
|
||||
|
||||
// Fprintf formats according to a format specifier and writes to w.
|
||||
// It returns the number of bytes written and any write error encountered.
|
||||
// On Windows, users should wrap w with colorable.NewColorable() if w is of
|
||||
// type *os.File.
|
||||
func (c *Color) Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {
|
||||
c.setWriter(w)
|
||||
defer c.unsetWriter(w)
|
||||
|
||||
return fmt.Fprintf(w, format, a...)
|
||||
}
|
||||
|
||||
// Printf formats according to a format specifier and writes to standard output.
|
||||
// It returns the number of bytes written and any write error encountered.
|
||||
// This is the standard fmt.Printf() method wrapped with the given color.
|
||||
func (c *Color) Printf(format string, a ...interface{}) (n int, err error) {
|
||||
c.Set()
|
||||
defer c.unset()
|
||||
|
||||
return fmt.Fprintf(Output, format, a...)
|
||||
}
|
||||
|
||||
// Fprintln formats using the default formats for its operands and writes to w.
|
||||
// Spaces are always added between operands and a newline is appended.
|
||||
// On Windows, users should wrap w with colorable.NewColorable() if w is of
|
||||
// type *os.File.
|
||||
func (c *Color) Fprintln(w io.Writer, a ...interface{}) (n int, err error) {
|
||||
c.setWriter(w)
|
||||
defer c.unsetWriter(w)
|
||||
|
||||
return fmt.Fprintln(w, a...)
|
||||
}
|
||||
|
||||
// Println formats using the default formats for its operands and writes to
|
||||
// standard output. Spaces are always added between operands and a newline is
|
||||
// appended. It returns the number of bytes written and any write error
|
||||
// encountered. This is the standard fmt.Print() method wrapped with the given
|
||||
// color.
|
||||
func (c *Color) Println(a ...interface{}) (n int, err error) {
|
||||
c.Set()
|
||||
defer c.unset()
|
||||
|
||||
return fmt.Fprintln(Output, a...)
|
||||
}
|
||||
|
||||
// Sprint is just like Print, but returns a string instead of printing it.
|
||||
func (c *Color) Sprint(a ...interface{}) string {
|
||||
return c.wrap(fmt.Sprint(a...))
|
||||
}
|
||||
|
||||
// Sprintln is just like Println, but returns a string instead of printing it.
|
||||
func (c *Color) Sprintln(a ...interface{}) string {
|
||||
return c.wrap(fmt.Sprintln(a...))
|
||||
}
|
||||
|
||||
// Sprintf is just like Printf, but returns a string instead of printing it.
|
||||
func (c *Color) Sprintf(format string, a ...interface{}) string {
|
||||
return c.wrap(fmt.Sprintf(format, a...))
|
||||
}
|
||||
|
||||
// FprintFunc returns a new function that prints the passed arguments as
|
||||
// colorized with color.Fprint().
|
||||
func (c *Color) FprintFunc() func(w io.Writer, a ...interface{}) {
|
||||
return func(w io.Writer, a ...interface{}) {
|
||||
c.Fprint(w, a...)
|
||||
}
|
||||
}
|
||||
|
||||
// PrintFunc returns a new function that prints the passed arguments as
|
||||
// colorized with color.Print().
|
||||
func (c *Color) PrintFunc() func(a ...interface{}) {
|
||||
return func(a ...interface{}) {
|
||||
c.Print(a...)
|
||||
}
|
||||
}
|
||||
|
||||
// FprintfFunc returns a new function that prints the passed arguments as
|
||||
// colorized with color.Fprintf().
|
||||
func (c *Color) FprintfFunc() func(w io.Writer, format string, a ...interface{}) {
|
||||
return func(w io.Writer, format string, a ...interface{}) {
|
||||
c.Fprintf(w, format, a...)
|
||||
}
|
||||
}
|
||||
|
||||
// PrintfFunc returns a new function that prints the passed arguments as
|
||||
// colorized with color.Printf().
|
||||
func (c *Color) PrintfFunc() func(format string, a ...interface{}) {
|
||||
return func(format string, a ...interface{}) {
|
||||
c.Printf(format, a...)
|
||||
}
|
||||
}
|
||||
|
||||
// FprintlnFunc returns a new function that prints the passed arguments as
|
||||
// colorized with color.Fprintln().
|
||||
func (c *Color) FprintlnFunc() func(w io.Writer, a ...interface{}) {
|
||||
return func(w io.Writer, a ...interface{}) {
|
||||
c.Fprintln(w, a...)
|
||||
|