diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5fe054ac..824e9b26 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,10 +1,9 @@ # Contributing 1. [About this document](#about-this-document) -3. [Getting the code](#getting-the-code) -4. [Setting up an environment](#setting-up-an-environment) -5. [Local development](#local-development) -7. [Submitting a Pull Request](#submitting-a-pull-request) +1. [Getting the code](#getting-the-code) +1. [Local development](#local-development) +1. [Submitting a Pull Request](#submitting-a-pull-request) ## About this document @@ -54,10 +53,10 @@ If you are a member of the `OpsLevel` GitHub organization, you will have push ac First make sure you have working [golang development environment](https://learn.gopherguides.com/courses/preparing-your-environment-for-go-development) setup. -You will also need an [OpsLevel API Token](https://app.opslevel.com/api_tokens) from your account to successfully make API calls against. Once you have the API token its best to put it in your terminal's environment +You will also need an [OpsLevel API Token](https://app.opslevel.com/api_tokens) from your account to successfully make API calls against. Once you have the API token it is best to put it in your terminal's environment ```sh -export OPSLEVEL_API_TOKEN=XXXXXXXXX + export OPSLEVEL_API_TOKEN=XXXXXXXXX ``` ### Local Development Testing @@ -97,9 +96,9 @@ Follow the prompts to create your change entry - remember this is what will show ## Submitting a Pull Request -OpsLevel provides a CI environment to test changes through Github Actions. For example, if you submit a pull request to the repo, GitHub will trigger automated code checks and tests upon approval from an OpsLevel maintainer. +OpsLevel provides a CI environment to test changes through GitHub Actions. For example, if you submit a pull request to the repo, GitHub will trigger automated code checks and tests upon approval from an OpsLevel maintainer. A maintainer will review your PR. They may suggest code revision for style or clarity, or request that you add unit or integration test(s). These are good things! We believe that, with a little bit of help, anyone can contribute high-quality code. -- First time contributors should note code checks + unit tests require a maintainer to approve. +- First time contributors should be aware that code checks + unit tests require a maintainer to approve. Once all tests are passing and your PR has been approved, a maintainer will merge your changes into the active development branch. And that's it! It will be available in the next release that is cut. Happy developing :tada: diff --git a/README.md b/README.md index 494ed68f..59cad127 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,18 @@

- - - - - - - - - - - - - - + + License + + Go Report Card + + Release + + Stability: Experimental + + Contributors + + Activity + + Downloads

[![Overall](https://img.shields.io/endpoint?style=flat&url=https%3A%2F%2Fapp.opslevel.com%2Fapi%2Fservice_level%2FEaWapOq9VQj5FvymQEgCPNJcbF-TOibHn89Arw7d_OY)](https://app.opslevel.com/services/opslevel_cli/maturity-report) @@ -99,7 +99,7 @@ Chaos Z2lkOi8vb3BzbGV2ZWwvQ2F0ZWdvcnkvOTY8 ### Enable shell autocompletion We have the ability to generate autocompletion scripts for the shell's `bash`, `zsh`, `fish` and `powershell`. To generate -the completion script for MacOS zsh: +the completion script for macOS zsh: ```sh opslevel completion zsh > /usr/local/share/zsh/site-functions/_opslevel diff --git a/ci/deploy-deb.sh b/ci/deploy-deb.sh index 33e66acf..21e239a2 100755 --- a/ci/deploy-deb.sh +++ b/ci/deploy-deb.sh @@ -1,21 +1,23 @@ #!/bin/bash +set -e + DEBIAN_RELEASES=$(debian-distro-info --supported) UBUNTU_RELEASES=$(ubuntu-distro-info --supported-esm) mkdir -p cli-repo/deb cd cli-repo/deb -for release in ${DEBIAN_RELEASES[@]} ${UBUNTU_RELEASES[@]}; do +for release in "${DEBIAN_RELEASES[@]}" "${UBUNTU_RELEASES[@]}"; do echo "Removing deb package of $release" - reprepro -A i386 remove $release opslevel - reprepro -A amd64 remove $release opslevel + reprepro -A i386 remove "$release" opslevel + reprepro -A amd64 remove "$release" opslevel done -for release in ${DEBIAN_RELEASES[@]} ${UBUNTU_RELEASES[@]}; do +for release in "${DEBIAN_RELEASES[@]}" "${UBUNTU_RELEASES[@]}"; do echo "Adding deb package to $release" - reprepro includedeb $release ../../src/dist/*linux-64bit.deb - reprepro includedeb $release ../../src/dist/*linux-32bit.deb + reprepro includedeb "$release" ../../src/dist/*linux-64bit.deb + reprepro includedeb "$release" ../../src/dist/*linux-32bit.deb done git add . diff --git a/ci/deploy-rpm.sh b/ci/deploy-rpm.sh index 06f5dab3..a4f603f4 100755 --- a/ci/deploy-rpm.sh +++ b/ci/deploy-rpm.sh @@ -1,24 +1,26 @@ #!/bin/bash +set -e + function create_rpm_repo () { version=$1 rpm_path=rpm/releases/${version}/x86_64 RPM_EL=$(find ../src/dist -type f -name "*64bit.rpm" -printf "%f\n" | head -n1 | sed -e "s/_/-/g" -e "s/-linux/.el$version/" -e "s/-64bit/.x86_64/") - echo $RPM_EL + echo "$RPM_EL" - mkdir -p $rpm_path - cp ../src/dist/*64bit.rpm ${rpm_path}/${RPM_EL} + mkdir -p "$rpm_path" + cp ../src/dist/*64bit.rpm "${rpm_path}/${RPM_EL}" - createrepo --update $rpm_path + createrepo --update "$rpm_path" } cd cli-repo VERSIONS=(5 6 7 8) -for version in ${VERSIONS[@]}; do +for version in "${VERSIONS[@]}"; do echo "Processing RHEL/CentOS $version..." - create_rpm_repo $version + create_rpm_repo "$version" done git add . diff --git a/src/build.sh b/src/build.sh index d8846069..f4402606 100755 --- a/src/build.sh +++ b/src/build.sh @@ -1,3 +1,3 @@ #! /bin/sh -go build -o $(which opslevel) \ No newline at end of file +go build -o "$(which opslevel)" \ No newline at end of file diff --git a/src/cmd/check.go b/src/cmd/check.go index 62594dcd..91125924 100644 --- a/src/cmd/check.go +++ b/src/cmd/check.go @@ -15,8 +15,8 @@ import ( var getCheckCmd = &cobra.Command{ Use: "check ID", - Short: "Get details about a rubic check", - Long: `Get details about a rubic check`, + Short: "Get details about a rubric check", + Long: `Get details about a rubric check`, Args: cobra.ExactArgs(1), ArgAliases: []string{"ID"}, Run: func(cmd *cobra.Command, args []string) { @@ -214,11 +214,11 @@ func updateCheck(input CheckInputType, usePrompts bool) (*opslevel.Check, error) // Resolving foreign keys -func (self *CheckInputType) resolveCategoryAliases(client *opslevel.Client, usePrompt bool) error { - if item, ok := self.Spec["category"]; ok { - delete(self.Spec, "category") +func (checkInputType *CheckInputType) resolveCategoryAliases(client *opslevel.Client, usePrompt bool) error { + if item, ok := checkInputType.Spec["category"]; ok { + delete(checkInputType.Spec, "category") if value, ok := opslevel.Cache.TryGetCategory(item.(string)); ok { - self.Spec["categoryId"] = value.Id + checkInputType.Spec["categoryId"] = value.Id return nil } else { fmt.Printf("%s is not a valid category, please select a valid category\n", item.(string)) @@ -229,9 +229,9 @@ func (self *CheckInputType) resolveCategoryAliases(client *opslevel.Client, useP if promptErr != nil { return promptErr } - self.Spec["categoryId"] = category.Id + checkInputType.Spec["categoryId"] = category.Id } else { - if self.IsUpdateInput() { + if checkInputType.IsUpdateInput() { return nil } @@ -240,11 +240,11 @@ func (self *CheckInputType) resolveCategoryAliases(client *opslevel.Client, useP return nil } -func (self *CheckInputType) resolveLevelAliases(client *opslevel.Client, usePrompt bool) error { - if item, ok := self.Spec["level"]; ok { - delete(self.Spec, "level") +func (checkInputType *CheckInputType) resolveLevelAliases(client *opslevel.Client, usePrompt bool) error { + if item, ok := checkInputType.Spec["level"]; ok { + delete(checkInputType.Spec, "level") if value, ok := opslevel.Cache.TryGetLevel(item.(string)); ok { - self.Spec["levelId"] = value.Id + checkInputType.Spec["levelId"] = value.Id return nil } else { fmt.Printf("%s is not a valid level, please select a valid level\n", item.(string)) @@ -255,9 +255,9 @@ func (self *CheckInputType) resolveLevelAliases(client *opslevel.Client, useProm if promptErr != nil { return promptErr } - self.Spec["levelId"] = level.Id + checkInputType.Spec["levelId"] = level.Id } else { - if self.IsUpdateInput() { + if checkInputType.IsUpdateInput() { return nil } @@ -266,11 +266,11 @@ func (self *CheckInputType) resolveLevelAliases(client *opslevel.Client, useProm return nil } -func (self *CheckInputType) resolveTeamAliases(client *opslevel.Client, usePrompt bool) error { - if item, ok := self.Spec["owner"]; ok { - delete(self.Spec, "owner") +func (checkInputType *CheckInputType) resolveTeamAliases(client *opslevel.Client, usePrompt bool) error { + if item, ok := checkInputType.Spec["owner"]; ok { + delete(checkInputType.Spec, "owner") if value, ok := opslevel.Cache.TryGetTeam(item.(string)); ok { - self.Spec["ownerId"] = value.Id + checkInputType.Spec["ownerId"] = value.Id return nil } else { fmt.Printf("%s is not a valid team, please select a valid team\n", item.(string)) @@ -282,7 +282,7 @@ func (self *CheckInputType) resolveTeamAliases(client *opslevel.Client, usePromp return promptErr } if team.Id != "" { - self.Spec["ownerId"] = team.Id + checkInputType.Spec["ownerId"] = team.Id } } else { log.Warn().Msg("no value supplied for field 'owner'") @@ -290,11 +290,11 @@ func (self *CheckInputType) resolveTeamAliases(client *opslevel.Client, usePromp return nil } -func (self *CheckInputType) resolveFilterAliases(client *opslevel.Client, usePrompt bool) error { - if item, ok := self.Spec["filter"]; ok { - delete(self.Spec, "filter") +func (checkInputType *CheckInputType) resolveFilterAliases(client *opslevel.Client, usePrompt bool) error { + if item, ok := checkInputType.Spec["filter"]; ok { + delete(checkInputType.Spec, "filter") if value, ok := opslevel.Cache.TryGetFilter(item.(string)); ok { - self.Spec["filterId"] = value.Id + checkInputType.Spec["filterId"] = value.Id return nil } else { fmt.Printf("%s is not a valid filter, please select a valid filter\n", item.(string)) @@ -306,7 +306,7 @@ func (self *CheckInputType) resolveFilterAliases(client *opslevel.Client, usePro return promptErr } if filter.Id != "" { - self.Spec["filterId"] = filter.Id + checkInputType.Spec["filterId"] = filter.Id } } else { log.Warn().Msg("no value supplied for field 'filter'") @@ -314,11 +314,11 @@ func (self *CheckInputType) resolveFilterAliases(client *opslevel.Client, usePro return nil } -func (self *CheckInputType) resolveIntegrationAliases(client *opslevel.Client, usePrompt bool) error { - if item, ok := self.Spec["integration"]; ok { - delete(self.Spec, "integration") +func (checkInputType *CheckInputType) resolveIntegrationAliases(client *opslevel.Client, usePrompt bool) error { + if item, ok := checkInputType.Spec["integration"]; ok { + delete(checkInputType.Spec, "integration") if value, ok := opslevel.Cache.TryGetIntegration(item.(string)); ok { - self.Spec["integrationId"] = value.Id + checkInputType.Spec["integrationId"] = value.Id return nil } else { fmt.Printf("%s is not a valid integration, please select a valid integration\n", item.(string)) @@ -329,9 +329,9 @@ func (self *CheckInputType) resolveIntegrationAliases(client *opslevel.Client, u if promptErr != nil { return promptErr } - self.Spec["integrationId"] = integration.Id + checkInputType.Spec["integrationId"] = integration.Id } else { - if self.IsUpdateInput() { + if checkInputType.IsUpdateInput() { return nil } @@ -444,8 +444,8 @@ type CheckInputType struct { Spec map[string]interface{} } -func (self *CheckInputType) IsUpdateInput() bool { - _, ok := self.Spec["id"] +func (checkInputType *CheckInputType) IsUpdateInput() bool { + _, ok := checkInputType.Spec["id"] return ok } diff --git a/src/cmd/dependency.go b/src/cmd/dependency.go index 29e645fb..c44c5c66 100644 --- a/src/cmd/dependency.go +++ b/src/cmd/dependency.go @@ -8,7 +8,7 @@ import ( ) // CLIServiceDependencyCreateInput This is used to make the user facing CLI experience better -// than a straight passthrough to the API types which are overly verbose +// than a straight pass through to the API types which are overly verbose type CLIServiceDependencyCreateInput struct { Source string `json:"source"` Target string `json:"target"` diff --git a/src/cmd/deploy.go b/src/cmd/deploy.go index c49cbea7..f6297ec4 100644 --- a/src/cmd/deploy.go +++ b/src/cmd/deploy.go @@ -34,7 +34,7 @@ type Commit struct { AuthoringDate *time.Time `json:"authoring_date,omitempty" yaml:"authoring-date"` } -// DeployRequest represents a structured request to the OpsLevel deploys webhook endpoint +// DeployEvent represents a structured request to the OpsLevel deploys webhook endpoint type DeployEvent struct { Service string `validate:"required" json:"service"` Deployer Deployer `validate:"required" json:"deployer"` diff --git a/src/cmd/policy.go b/src/cmd/policy.go index f396c757..4f9eadd5 100644 --- a/src/cmd/policy.go +++ b/src/cmd/policy.go @@ -83,11 +83,11 @@ func toASTValue[T astMarshallable](input T) (ast.Value, error) { } func getKeyFromMapByMaxValue(m map[string]float64) string { - max := float64(0) + maxValue := float64(0) var output string for k, v := range m { - if v > max { - max = v + if v > maxValue { + maxValue = v output = k } } diff --git a/src/cmd/rubric.go b/src/cmd/rubric.go index 82e9231a..ebb453e7 100644 --- a/src/cmd/rubric.go +++ b/src/cmd/rubric.go @@ -39,8 +39,8 @@ var createCategoryCmd = &cobra.Command{ var getCategoryCmd = &cobra.Command{ Use: "category ID", Aliases: []string{"cat"}, - Short: "Get details about a rubic category", - Long: `Get details about a rubic category`, + Short: "Get details about a rubric category", + Long: `Get details about a rubric category`, Args: cobra.ExactArgs(1), ArgAliases: []string{"ID"}, Run: func(cmd *cobra.Command, args []string) { @@ -113,8 +113,8 @@ var createLevelCmd = &cobra.Command{ var getLevelCmd = &cobra.Command{ Use: "level ID", - Short: "Get details about a rubic level", - Long: `Get details about a rubic level`, + Short: "Get details about a rubric level", + Long: `Get details about a rubric level`, Args: cobra.ExactArgs(1), ArgAliases: []string{"ID"}, Run: func(cmd *cobra.Command, args []string) { diff --git a/src/cmd/tag.go b/src/cmd/tag.go index 3e954389..7981e4ce 100644 --- a/src/cmd/tag.go +++ b/src/cmd/tag.go @@ -102,7 +102,7 @@ opslevel get tag --type=Service my-service-alias foo tags, err := result.GetTags(client, nil) cobra.CheckErr(err) - output := []opslevel.Tag{} + output := make([]opslevel.Tag, 0) for _, tag := range tags.Nodes { if tagKey == tag.Key { output = append(output, tag) diff --git a/src/cmd/terraform.go b/src/cmd/terraform.go index c347cf94..3260bd82 100644 --- a/src/cmd/terraform.go +++ b/src/cmd/terraform.go @@ -118,7 +118,7 @@ func getIntegrationTerraformName(integration opslevel.IntegrationId) string { return makeTerraformSlug(fmt.Sprintf("%s_%s", integration.Type, integration.Name)) } -// Given a field that could be a multiline string - this will return it with the correct formating +// Given a field that could be a multiline string - this will return it with the correct formatting func buildMultilineStringArg(fieldName string, fieldContents string) string { if len(fieldContents) > 0 { if len(strings.Split(fieldContents, "\n")) > 1 { @@ -203,7 +203,7 @@ func flattenAliases(aliases []string) string { } func flattenTags(tags []opslevel.Tag) string { - tagStrings := []string{} + tagStrings := make([]string, len(tags)) for _, tag := range tags { tagStrings = append(tagStrings, fmt.Sprintf("%s:%s", tag.Key, tag.Value)) } @@ -525,7 +525,7 @@ func exportChecks(c *opslevel.Client, shell *os.File, directory string) { servicePropertyCheckFile := newFile(fmt.Sprintf("%s/opslevel_checks_service_property.tf", directory), false) tagDefinedCheckFile := newFile(fmt.Sprintf("%s/opslevel_checks_tag_defined.tf", directory), false) toolUsageCheckFile := newFile(fmt.Sprintf("%s/opslevel_checks_tool_usage.tf", directory), false) - hasDocumenationCheckFile := newFile(fmt.Sprintf("%s/opslevel_checks_has_documentation.tf", directory), false) + hasDocumentationCheckFile := newFile(fmt.Sprintf("%s/opslevel_checks_has_documentation.tf", directory), false) gitBranchProtectionCheckFile := newFile(fmt.Sprintf("%s/opslevel_checks_git_branch_protection.tf", directory), false) serviceDependencyCheckFile := newFile(fmt.Sprintf("%s/opslevel_checks_service_dependency.tf", directory), false) @@ -542,7 +542,7 @@ func exportChecks(c *opslevel.Client, shell *os.File, directory string) { defer servicePropertyCheckFile.Close() defer tagDefinedCheckFile.Close() defer toolUsageCheckFile.Close() - defer hasDocumenationCheckFile.Close() + defer hasDocumentationCheckFile.Close() defer gitBranchProtectionCheckFile.Close() defer serviceDependencyCheckFile.Close() @@ -619,7 +619,7 @@ func exportChecks(c *opslevel.Client, shell *os.File, directory string) { checkExtras = templateConfig(toolUsageCheckConfig, casted.ToolCategory, flattenPredicate("tool_name_predicate", casted.ToolNamePredicate), flattenPredicate("environment_predicate", casted.EnvironmentPredicate)) case opslevel.CheckTypeHasDocumentation: casted := check.HasDocumentationCheckFragment - activeFile = hasDocumenationCheckFile + activeFile = hasDocumentationCheckFile checkTypeTerraformName = "has_documentation" checkExtras = templateConfig(hasDocumentationCheckConfig, casted.DocumentType, casted.DocumentSubtype) case opslevel.CheckTypeGitBranchProtection: diff --git a/src/common/helpers.go b/src/common/helpers.go index 6228cbd4..2d44c3d3 100644 --- a/src/common/helpers.go +++ b/src/common/helpers.go @@ -17,7 +17,7 @@ func GetArg(args []string, index int, defaultValue string) string { func WasFound(condition bool, key string) { if condition { - cobra.CheckErr(fmt.Errorf("Not found - '%s'", key)) + cobra.CheckErr(fmt.Errorf("not found - '%s'", key)) } } @@ -36,13 +36,13 @@ func YamlPrint(object interface{}) { } func MinInt(values ...int) int { - min := values[0] + minValue := values[0] for _, val := range values { - if val < min { - min = val + if val < minValue { + minValue = val } } - return min + return minValue } diff --git a/src/common/helpers_test.go b/src/common/helpers_test.go index 6ffb3fb4..b08a7d0f 100644 --- a/src/common/helpers_test.go +++ b/src/common/helpers_test.go @@ -3,7 +3,7 @@ package common_test import ( "testing" - common "github.com/opslevel/cli/common" + "github.com/opslevel/cli/common" "github.com/rocktavious/autopilot" ) diff --git a/src/common/output_test.go b/src/common/output_test.go index 7001eb17..f3848043 100644 --- a/src/common/output_test.go +++ b/src/common/output_test.go @@ -6,7 +6,7 @@ import ( "strings" "testing" - common "github.com/opslevel/cli/common" + "github.com/opslevel/cli/common" "github.com/rocktavious/autopilot" ) @@ -26,7 +26,7 @@ func captureOutput() string { func TestPrettyPrint(t *testing.T) { // Arrange - trimmedTestString := strings.TrimRight(captureOutput(), "\n") // captureOuput adds an extra newline + trimmedTestString := strings.TrimRight(captureOutput(), "\n") // captureOutput adds an extra newline // Act // Assert autopilot.Equals(t, "\"< > & alan was here & < >\"", trimmedTestString) diff --git a/src/common/prompts.go b/src/common/prompts.go index 36727255..16a76d75 100644 --- a/src/common/prompts.go +++ b/src/common/prompts.go @@ -160,7 +160,7 @@ func PromptForIntegration(client *opslevel.Client) (*opslevel.Integration, error {{ "Type:" | faint }} {{ .Type }}`, } - filteredList := []opslevel.Integration{} + filteredList := make([]opslevel.Integration, 0) for _, val := range list { if val.Type == "generic" { filteredList = append(filteredList, val)