Compare commits

..

2 Commits

Author SHA1 Message Date
lukaszraczylo 129acb3cfe Create dependabot.yml 2023-10-20 10:19:00 +01:00
lukaszraczylo ca3d1b6da0 Use well tested logging sub-library. 2023-10-20 10:15:26 +01:00
7 changed files with 60 additions and 67 deletions
+11
View File
@@ -0,0 +1,11 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: "gomod" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "weekly"
+2 -1
View File
@@ -195,4 +195,5 @@ wording:
### Good to know ### Good to know
* Word matching uses fuzzy search AND is case INSENSITIVE * Word matching uses fuzzy search AND is case INSENSITIVE
* I do not recommend using common words ( like "the" from the example configuration ) * I do not recommend using common words ( like "the" from the example configuration )
* You can specify env variable `LOG_LEVEL=debug` to see what exactly happens during the calculations
+8 -8
View File
@@ -15,7 +15,7 @@ func updatePackage() bool {
ghToken, ghTokenSet := os.LookupEnv("GITHUB_TOKEN") ghToken, ghTokenSet := os.LookupEnv("GITHUB_TOKEN")
if ghTokenSet { if ghTokenSet {
binaryName := fmt.Sprintf("semver-gen-%s-%s", runtime.GOOS, runtime.GOARCH) binaryName := fmt.Sprintf("semver-gen-%s-%s", runtime.GOOS, runtime.GOARCH)
fmt.Println("Downloading", binaryName) logger.Info("semver-gen", map[string]interface{}{"message": "Checking for updates"})
gql := graphql.NewConnection() gql := graphql.NewConnection()
gql.SetEndpoint("https://api.github.com/graphql") gql.SetEndpoint("https://api.github.com/graphql")
@@ -43,13 +43,13 @@ func updatePackage() bool {
}` }`
result, err := gql.Query(query, variables, headers) result, err := gql.Query(query, variables, headers)
if err != nil { if err != nil {
fmt.Println("Query error", err) logger.Error("semver-gen", map[string]interface{}{"error": err.Error(), "message": "Unable to query GitHub API"})
return false return false
} }
output, ok := ask.For(result, "repository.latestRelease.releaseAssets.edges[0].node.downloadUrl").String("") output, ok := ask.For(result, "repository.latestRelease.releaseAssets.edges[0].node.downloadUrl").String("")
if !ok { if !ok {
fmt.Println("Unable to obtain download url for the binary", binaryName, output) logger.Error("semver-gen", map[string]interface{}{"error": "Unable to obtain download url for the binary", "binary": binaryName, "output": output})
return false return false
} }
if flag.Lookup("test.v") == nil && os.Getenv("CI") == "" { if flag.Lookup("test.v") == nil && os.Getenv("CI") == "" {
@@ -57,22 +57,22 @@ func updatePackage() bool {
g := got.New() g := got.New()
err = g.Download(output, downloadedBinaryPath) err = g.Download(output, downloadedBinaryPath)
if err != nil { if err != nil {
fmt.Println("Unable to download binary", err.Error()) logger.Error("semver-gen", map[string]interface{}{"error": err.Error(), "message": "Unable to download binary", "binaryPath": downloadedBinaryPath})
return false return false
} }
currentBinary, err := os.Executable() currentBinary, err := os.Executable()
if err != nil { if err != nil {
fmt.Println("Unable to obtain current binary path", err.Error()) logger.Error("semver-gen", map[string]interface{}{"error": err.Error(), "message": "Unable to obtain current binary path"})
return false return false
} }
err = os.Rename(downloadedBinaryPath, currentBinary) err = os.Rename(downloadedBinaryPath, currentBinary)
if err != nil { if err != nil {
fmt.Println("Unable to overwrite current binary", err.Error()) logger.Error("semver-gen", map[string]interface{}{"error": err.Error(), "message": "Unable to overwrite current binary"})
return false return false
} }
err = os.Chmod(currentBinary, 0777) err = os.Chmod(currentBinary, 0777)
if err != nil { if err != nil {
fmt.Println("Unable to make binary executable", err.Error()) logger.Error("semver-gen", map[string]interface{}{"error": err.Error(), "message": "Unable to make binary executable"})
return false return false
} }
} }
@@ -102,7 +102,7 @@ func checkLatestRelease() (string, bool) {
}` }`
result, err := gql.Query(query, variables, headers) result, err := gql.Query(query, variables, headers)
if err != nil { if err != nil {
fmt.Println("Query error >>", err) logger.Error("semver-gen", map[string]interface{}{"error": err.Error(), "message": "Unable to query GitHub API"})
return "", false return "", false
} }
output, _ := ask.For(result, "repository.releases.nodes[0].tag.name").String("") output, _ := ask.For(result, "repository.releases.nodes[0].tag.name").String("")
+4
View File
@@ -2,9 +2,12 @@ package cmd
import ( import (
"testing" "testing"
libpack_logging "github.com/lukaszraczylo/graphql-monitoring-proxy/logging"
) )
func Test_checkLatestRelease(t *testing.T) { func Test_checkLatestRelease(t *testing.T) {
logger = libpack_logging.NewLogger()
tests := []struct { tests := []struct {
name string name string
want string want string
@@ -26,6 +29,7 @@ func Test_checkLatestRelease(t *testing.T) {
} }
func Test_updatePackage(t *testing.T) { func Test_updatePackage(t *testing.T) {
logger = libpack_logging.NewLogger()
if testing.Short() { if testing.Short() {
t.Skip("Skipping test in short / CI mode") t.Skip("Skipping test in short / CI mode")
} }
+28 -34
View File
@@ -18,7 +18,6 @@ limitations under the License.
package cmd package cmd
import ( import (
"flag"
"fmt" "fmt"
"net/url" "net/url"
"os" "os"
@@ -33,6 +32,7 @@ import (
"github.com/go-git/go-git/v5/plumbing/object" "github.com/go-git/go-git/v5/plumbing/object"
"github.com/go-git/go-git/v5/plumbing/transport/http" "github.com/go-git/go-git/v5/plumbing/transport/http"
"github.com/lithammer/fuzzysearch/fuzzy" "github.com/lithammer/fuzzysearch/fuzzy"
libpack_logger "github.com/lukaszraczylo/graphql-monitoring-proxy/logging"
"github.com/lukaszraczylo/pandati" "github.com/lukaszraczylo/pandati"
"github.com/spf13/viper" "github.com/spf13/viper"
) )
@@ -41,6 +41,7 @@ var (
err error err error
repo *Setup repo *Setup
PKG_VERSION string PKG_VERSION string
logger *libpack_logger.LogConfig
) )
type Wording struct { type Wording struct {
@@ -96,34 +97,28 @@ type TagDetails struct {
func checkMatches(content []string, targets []string) bool { func checkMatches(content []string, targets []string) bool {
if fuzzy.MatchNormalizedFold(strings.Join(content, " "), "Merge branch") { if fuzzy.MatchNormalizedFold(strings.Join(content, " "), "Merge branch") {
debugPrint(fmt.Sprintln("Merge detected, ignoring commits within:", content)) logger.Debug("semver-gen", map[string]interface{}{"message": "Merge detected, ignoring commits within", "content": strings.Join(content, " ")})
return false return false
} }
var r []string var r []string
for _, tgt := range targets { for _, tgt := range targets {
r = fuzzy.FindNormalizedFold(tgt, content) r = fuzzy.FindNormalizedFold(tgt, content)
if len(r) > 0 { if len(r) > 0 {
debugPrint(fmt.Sprintln("Found match for ", tgt, "|", strings.Join(r, ","))) logger.Debug("semver-gen", map[string]interface{}{"message": "Found match", "target": tgt, "match": strings.Join(r, ","), "content": strings.Join(content, " ")})
return true return true
} }
} }
return false return false
} }
func debugPrint(content string) {
if params.varDebug && flag.Lookup("test.v") == nil {
fmt.Println("DEBUG:", content)
}
}
var extractNumber = regexp.MustCompile("[0-9]+") var extractNumber = regexp.MustCompile("[0-9]+")
func parseExistingSemver(tagName string, currentSemver SemVer) (semanticVersion SemVer) { func parseExistingSemver(tagName string, currentSemver SemVer) (semanticVersion SemVer) {
debugPrint(fmt.Sprintln("Parsing existing semver:", tagName)) logger.Debug("semver-gen", map[string]interface{}{"message": "Parsing existing semver", "tag": tagName})
var tagNameParts []string var tagNameParts []string
tagNameParts = strings.Split(tagName, ".") tagNameParts = strings.Split(tagName, ".")
if len(tagNameParts) < 3 { if len(tagNameParts) < 3 {
debugPrint("Unable to parse incompatible semver ( non x.y.z )") logger.Debug("semver-gen", map[string]interface{}{"message": "Unable to parse incompatible semver ( non x.y.z )"})
return currentSemver return currentSemver
} }
semanticVersion.Major, _ = strconv.Atoi(extractNumber.FindAllString(tagNameParts[0], -1)[0]) semanticVersion.Major, _ = strconv.Atoi(extractNumber.FindAllString(tagNameParts[0], -1)[0])
@@ -141,7 +136,7 @@ func (s *Setup) CalculateSemver() SemVer {
if params.varExisting || s.Force.Existing { if params.varExisting || s.Force.Existing {
for _, tagHash := range s.Tags { for _, tagHash := range s.Tags {
if commit.Hash == tagHash.Hash { if commit.Hash == tagHash.Hash {
debugPrint(fmt.Sprintln("Found existing tag:", tagHash.Name, "related to", commit.Message)) logger.Debug("semver-gen", map[string]interface{}{"message": "Found existing tag", "tag": tagHash.Name, "commit": strings.TrimSuffix(commit.Message, "\n")})
s.Semver = parseExistingSemver(tagHash.Name, s.Semver) s.Semver = parseExistingSemver(tagHash.Name, s.Semver)
continue continue
} }
@@ -150,7 +145,7 @@ func (s *Setup) CalculateSemver() SemVer {
if !params.varStrict && !s.Force.Strict { if !params.varStrict && !s.Force.Strict {
s.Semver.Patch++ s.Semver.Patch++
debugPrint(fmt.Sprintln("Incrementing patch (DEFAULT) on ", strings.TrimSuffix(commit.Message, "\n"), "| Semver:", s.getSemver())) logger.Debug("semver-gen", map[string]interface{}{"message": "Incrementing patch (DEFAULT)", "commit": strings.TrimSuffix(commit.Message, "\n"), "semver": s.getSemver()})
} }
commitSlice := strings.Fields(commit.Message) commitSlice := strings.Fields(commit.Message)
matchPatch := checkMatches(commitSlice, s.Wording.Patch) matchPatch := checkMatches(commitSlice, s.Wording.Patch)
@@ -159,14 +154,14 @@ func (s *Setup) CalculateSemver() SemVer {
matchReleaseCandidate := checkMatches(commitSlice, s.Wording.Release) matchReleaseCandidate := checkMatches(commitSlice, s.Wording.Release)
if matchPatch { if matchPatch {
s.Semver.Patch++ s.Semver.Patch++
debugPrint(fmt.Sprintln("Incrementing patch (WORDING) on ", strings.TrimSuffix(commit.Message, "\n"), "| Semver:", s.getSemver())) logger.Debug("semver-gen", map[string]interface{}{"message": "Incrementing patch (WORDING)", "commit": strings.TrimSuffix(commit.Message, "\n"), "semver": s.getSemver()})
continue continue
} }
if matchReleaseCandidate { if matchReleaseCandidate {
s.Semver.Release++ s.Semver.Release++
s.Semver.Patch = 1 s.Semver.Patch = 1
s.Semver.EnableReleaseCandidate = true s.Semver.EnableReleaseCandidate = true
debugPrint(fmt.Sprintln("Incrementing release candidate (WORDING) on ", strings.TrimSuffix(commit.Message, "\n"), "| Semver:", s.getSemver())) logger.Debug("semver-gen", map[string]interface{}{"message": "Incrementing release candidate (WORDING)", "commit": strings.TrimSuffix(commit.Message, "\n"), "semver": s.getSemver()})
continue continue
} }
if matchMinor { if matchMinor {
@@ -174,7 +169,7 @@ func (s *Setup) CalculateSemver() SemVer {
s.Semver.Patch = 1 s.Semver.Patch = 1
s.Semver.EnableReleaseCandidate = false s.Semver.EnableReleaseCandidate = false
s.Semver.Release = 0 s.Semver.Release = 0
debugPrint(fmt.Sprintln("Incrementing minor (WORDING) on ", strings.TrimSuffix(commit.Message, "\n"), "| Semver:", s.getSemver())) logger.Debug("semver-gen", map[string]interface{}{"message": "Incrementing minor (WORDING)", "commit": strings.TrimSuffix(commit.Message, "\n"), "semver": s.getSemver()})
continue continue
} }
if matchMajor { if matchMajor {
@@ -183,7 +178,7 @@ func (s *Setup) CalculateSemver() SemVer {
s.Semver.Patch = 1 s.Semver.Patch = 1
s.Semver.EnableReleaseCandidate = false s.Semver.EnableReleaseCandidate = false
s.Semver.Release = 0 s.Semver.Release = 0
debugPrint(fmt.Sprintln("Incrementing major (WORDING) on ", strings.TrimSuffix(commit.Message, "\n"), "| Semver:", s.getSemver())) logger.Debug("semver-gen", map[string]interface{}{"message": "Incrementing major (WORDING)", "commit": strings.TrimSuffix(commit.Message, "\n"), "semver": s.getSemver()})
continue continue
} }
} }
@@ -191,14 +186,14 @@ func (s *Setup) CalculateSemver() SemVer {
} }
func (s *Setup) ListExistingTags() { func (s *Setup) ListExistingTags() {
debugPrint(fmt.Sprintln("Listing existing tags")) logger.Debug("semver-gen", map[string]interface{}{"message": "Listing existing tags"})
refs, err := s.RepositoryHandler.Tags() refs, err := s.RepositoryHandler.Tags()
if err != nil { if err != nil {
panic(err) panic(err)
} }
if err := refs.ForEach(func(ref *plumbing.Reference) error { if err := refs.ForEach(func(ref *plumbing.Reference) error {
s.Tags = append(s.Tags, TagDetails{Name: ref.Name().Short(), Hash: ref.Hash().String()}) s.Tags = append(s.Tags, TagDetails{Name: ref.Name().Short(), Hash: ref.Hash().String()})
debugPrint(fmt.Sprintln("Found tag:", ref.Name().Short(), ref.Hash().String())) logger.Debug("semver-gen", map[string]interface{}{"message": "Found tag", "tag": ref.Name().Short(), "hash": ref.Hash().String()})
return nil return nil
}); err != nil { }); err != nil {
panic(err) panic(err)
@@ -225,11 +220,10 @@ func (s *Setup) ListCommits() ([]CommitDetails, error) {
return nil return nil
}) })
debugPrint(fmt.Sprintln("\n---COMMITS BEFORE CUT---\n", s.Commits)) logger.Debug("semver-gen", map[string]interface{}{"message": "Commits before cut", "commits": tmpResults})
for commitId, cmt := range tmpResults { for commitId, cmt := range tmpResults {
if s.Force.Commit != "" && cmt.Hash == s.Force.Commit { if s.Force.Commit != "" && cmt.Hash == s.Force.Commit {
debugPrint(fmt.Sprintln(">>>> FOUND MATCH", len(s.Commits), len(tmpResults[commitId:]))) logger.Debug("semver-gen", map[string]interface{}{"message": "Found commit match", "commit": cmt.Hash, "index": commitId})
s.Commits = tmpResults[commitId:] s.Commits = tmpResults[commitId:]
break break
} else { } else {
@@ -237,7 +231,7 @@ func (s *Setup) ListCommits() ([]CommitDetails, error) {
} }
} }
debugPrint(fmt.Sprintln("\n---COMMITS AFTER CUT---\n", s.Commits)) logger.Debug("semver-gen", map[string]interface{}{"message": "Commits after cut", "commits": s.Commits})
return s.Commits, err return s.Commits, err
} }
@@ -245,7 +239,7 @@ func (s *Setup) Prepare() error {
if !repo.UseLocal { if !repo.UseLocal {
u, err := url.Parse(s.RepositoryName) u, err := url.Parse(s.RepositoryName)
if err != nil { if err != nil {
fmt.Println("Unable to parse repository URL", s.RepositoryName, "Error:", err.Error()) logger.Error("semver-gen", map[string]interface{}{"message": "Unable to parse repository URL", "error": err.Error(), "url": s.RepositoryName})
return err return err
} }
s.RepositoryLocalPath = fmt.Sprintf("/tmp/semver/%s/%s", u.Path, s.RepositoryBranch) s.RepositoryLocalPath = fmt.Sprintf("/tmp/semver/%s/%s", u.Path, s.RepositoryBranch)
@@ -261,14 +255,14 @@ func (s *Setup) Prepare() error {
Tags: git.AllTags, Tags: git.AllTags,
}) })
if err != nil { if err != nil {
fmt.Println("Unable to reach repository", s.RepositoryName, "Error:", err.Error()) logger.Error("semver-gen", map[string]interface{}{"message": "Unable to clone repository", "error": err.Error(), "url": s.RepositoryName})
return err return err
} }
} else { } else {
s.RepositoryLocalPath = "./" s.RepositoryLocalPath = "./"
s.RepositoryHandler, err = git.PlainOpen(s.RepositoryLocalPath) s.RepositoryHandler, err = git.PlainOpen(s.RepositoryLocalPath)
if err != nil { if err != nil {
fmt.Println("Unable to reach repository", s.RepositoryName, "Error:", err.Error()) logger.Error("semver-gen", map[string]interface{}{"message": "Unable to open local repository", "error": err.Error(), "path": s.RepositoryLocalPath})
return err return err
} }
} }
@@ -278,15 +272,15 @@ func (s *Setup) Prepare() error {
func (s *Setup) ForcedVersioning() { func (s *Setup) ForcedVersioning() {
if !pandati.IsZero(s.Force.Major) { if !pandati.IsZero(s.Force.Major) {
debugPrint(fmt.Sprintln("Forced versioning (MAJOR)", s.Force.Major)) logger.Debug("semver-gen", map[string]interface{}{"message": "Forced versioning (MAJOR)", "major": s.Force.Major})
s.Semver.Major = s.Force.Major s.Semver.Major = s.Force.Major
} }
if !pandati.IsZero(s.Force.Minor) { if !pandati.IsZero(s.Force.Minor) {
debugPrint(fmt.Sprintln("Forced versioning (MINOR)", s.Force.Minor)) logger.Debug("semver-gen", map[string]interface{}{"message": "Forced versioning (MINOR)", "minor": s.Force.Minor})
s.Semver.Minor = s.Force.Minor s.Semver.Minor = s.Force.Minor
} }
if !pandati.IsZero(s.Force.Patch) { if !pandati.IsZero(s.Force.Patch) {
debugPrint(fmt.Sprintln("Forced versioning (PATCH)", s.Force.Patch)) logger.Debug("semver-gen", map[string]interface{}{"message": "Forced versioning (PATCH)", "patch": s.Force.Patch})
s.Semver.Patch = s.Force.Patch s.Semver.Patch = s.Force.Patch
} }
} }
@@ -312,15 +306,16 @@ func (s *Setup) getSemver() (semverReturned string) {
} }
func main() { func main() {
logger = libpack_logger.NewLogger()
if params.varShowVersion { if params.varShowVersion {
var outdatedMsg string var outdatedMsg string
latestRelease, latestRelaseOk := checkLatestRelease() latestRelease, latestRelaseOk := checkLatestRelease()
if PKG_VERSION != latestRelease && latestRelaseOk { if PKG_VERSION != latestRelease && latestRelaseOk {
outdatedMsg = fmt.Sprintf("(Latest available: %s)", latestRelease) outdatedMsg = fmt.Sprintf("(Latest available: %s)", latestRelease)
} }
fmt.Println("semver-gen", PKG_VERSION, "", outdatedMsg, "\tMore information: https://github.com/lukaszraczylo/semver-generator") logger.Info("semver-gen", map[string]interface{}{"version": PKG_VERSION, "outdated": outdatedMsg})
if outdatedMsg != "" { if outdatedMsg != "" {
fmt.Println("You can update automatically with: semver-gen -u") logger.Info("semver-gen", map[string]interface{}{"message": "You can update automatically with: semver-gen -u"})
} }
return return
} }
@@ -331,12 +326,11 @@ func main() {
if repo.Generate || params.varGenerateInTest { if repo.Generate || params.varGenerateInTest {
err := repo.ReadConfig(repo.LocalConfigFile) err := repo.ReadConfig(repo.LocalConfigFile)
if err != nil { if err != nil {
fmt.Println("Unable to find config file semver.yaml. Using defaults and flags.", repo.LocalConfigFile) logger.Error("semver-gen", map[string]interface{}{"message": "Unable to find config file semver.yaml. Using defaults and flags.", "file": repo.LocalConfigFile})
} }
err = repo.Prepare() err = repo.Prepare()
if err != nil { if err != nil {
fmt.Println("Unable to prepare repository") logger.Critical("semver-gen", map[string]interface{}{"message": "Unable to prepare repository", "error": err.Error()})
os.Exit(1)
} }
repo.ListCommits() repo.ListCommits()
if params.varExisting || repo.Force.Existing { if params.varExisting || repo.Force.Existing {
+6 -23
View File
@@ -21,6 +21,7 @@ import (
"testing" "testing"
git "github.com/go-git/go-git/v5" git "github.com/go-git/go-git/v5"
libpack_logging "github.com/lukaszraczylo/graphql-monitoring-proxy/logging"
"github.com/lukaszraczylo/pandati" "github.com/lukaszraczylo/pandati"
assertions "github.com/stretchr/testify/assert" assertions "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
@@ -36,13 +37,17 @@ var (
) )
func (suite *Tests) SetupTest() { func (suite *Tests) SetupTest() {
os.Chdir(testCurrentPath) err := os.Chdir(testCurrentPath)
if err != nil {
logger.Critical("main", map[string]interface{}{"error": err.Error(), "message": "Unable to change directory to test directory"})
}
assert = assertions.New(suite.T()) assert = assertions.New(suite.T())
params.varDebug = true params.varDebug = true
params.varRepoBranch = "main" params.varRepoBranch = "main"
} }
func TestSuite(t *testing.T) { func TestSuite(t *testing.T) {
logger = libpack_logging.NewLogger()
testCurrentPath, _ = os.Getwd() testCurrentPath, _ = os.Getwd()
suite.Run(t, new(Tests)) suite.Run(t, new(Tests))
} }
@@ -467,28 +472,6 @@ func (suite *Tests) TestSetup_CalculateSemver() {
} }
} }
func (suite *Tests) Test_debugPrint() {
type args struct {
content string
}
tests := []struct {
name string
args args
}{
{
name: "Test debug print",
args: args{
content: "Test debug",
},
},
}
for _, tt := range tests {
suite.T().Run(tt.name, func(t *testing.T) {
debugPrint(tt.args.content)
})
}
}
func (suite *Tests) Test_main() { func (suite *Tests) Test_main() {
type vars struct { type vars struct {
varRepoName string varRepoName string
+1 -1
View File
@@ -7,6 +7,7 @@ require (
github.com/lithammer/fuzzysearch v1.1.8 github.com/lithammer/fuzzysearch v1.1.8
github.com/lukaszraczylo/ask v0.0.0-20230927103145-2ff1123b4415 github.com/lukaszraczylo/ask v0.0.0-20230927103145-2ff1123b4415
github.com/lukaszraczylo/go-simple-graphql v1.1.35 github.com/lukaszraczylo/go-simple-graphql v1.1.35
github.com/lukaszraczylo/graphql-monitoring-proxy v0.5.26
github.com/lukaszraczylo/pandati v0.0.29 github.com/lukaszraczylo/pandati v0.0.29
github.com/melbahja/got v0.7.0 github.com/melbahja/got v0.7.0
github.com/spf13/cobra v1.7.0 github.com/spf13/cobra v1.7.0
@@ -35,7 +36,6 @@ require (
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/json-iterator/go v1.1.12 // indirect github.com/json-iterator/go v1.1.12 // indirect
github.com/kevinburke/ssh_config v1.2.0 // indirect github.com/kevinburke/ssh_config v1.2.0 // indirect
github.com/lukaszraczylo/graphql-monitoring-proxy v0.5.26 // indirect
github.com/magiconair/properties v1.8.7 // indirect github.com/magiconair/properties v1.8.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-isatty v0.0.20 // indirect