diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
index ade5940..4de789f 100644
--- a/.github/workflows/lint.yml
+++ b/.github/workflows/lint.yml
@@ -23,7 +23,7 @@ jobs:
- name: Get golangci-lint cache dir
run: |
- linter_ver=1.55.2
+ linter_ver=1.64.8
go install github.com/golangci/golangci-lint/cmd/golangci-lint@v$linter_ver
dir=$(golangci-lint cache status | awk '/Dir/ { print $2 }')
echo "LINT_CACHE_DIR=$dir" >> $GITHUB_ENV
diff --git a/.golangci.yaml b/.golangci.yaml
new file mode 100644
index 0000000..df8f68a
--- /dev/null
+++ b/.golangci.yaml
@@ -0,0 +1,269 @@
+# See https://golangci-lint.run/usage/configuration/
+# Over time we should try tightening some of these.
+
+linters-settings:
+ dupl:
+ # goal: 100
+ threshold: 412
+
+ exhaustruct:
+ include:
+ # Gradually extend to cover more of the codebase.
+ - 'httpmw\.\w+'
+ # We want to enforce all values are specified when inserting or updating
+ # a database row. Ref: #9936
+ - 'github.com/coder/coder/v2/coderd/database\.[^G][^e][^t]\w+Params'
+ gocognit:
+ min-complexity: 300
+
+ goconst:
+ min-len: 4 # Min length of string consts (def 3).
+ min-occurrences: 3 # Min number of const occurrences (def 3).
+
+ gocritic:
+ enabled-checks:
+ # - appendAssign
+ # - appendCombine
+ # - assignOp
+ # - badCall
+ - badLock
+ - badRegexp
+ - boolExprSimplify
+ # - builtinShadow
+ - builtinShadowDecl
+ # - commentedOutCode
+ - commentedOutImport
+ - deferUnlambda
+ # - deprecatedComment
+ # - docStub
+ - dupImport
+ # - elseif
+ - emptyFallthrough
+ # - emptyStringTest
+ # - equalFold
+ # - evalOrder
+ # - exitAfterDefer
+ # - exposedSyncMutex
+ # - filepathJoin
+ - hexLiteral
+ # - httpNoBody
+ # - hugeParam
+ # - ifElseChain
+ # - importShadow
+ - indexAlloc
+ - initClause
+ - methodExprCall
+ # - nestingReduce
+ - nilValReturn
+ # - octalLiteral
+ # - paramTypeCombine
+ # - preferStringWriter
+ # - preferWriteByte
+ # - ptrToRefParam
+ # - rangeExprCopy
+ # - rangeValCopy
+ - regexpPattern
+ # - regexpSimplify
+ - ruleguard
+ # - sloppyReassign
+ - sortSlice
+ - sprintfQuotedString
+ - sqlQuery
+ # - stringConcatSimplify
+ # - stringXbytes
+ # - suspiciousSorting
+ - truncateCmp
+ - typeAssertChain
+ # - typeDefFirst
+ # - typeUnparen
+ # - unlabelStmt
+ # - unlambda
+ # - unnamedResult
+ # - unnecessaryBlock
+ # - unnecessaryDefer
+ # - unslice
+ - weakCond
+ # - whyNoLint
+ # - wrapperFunc
+ # - yodaStyleExpr
+ settings:
+ ruleguard:
+ failOn: all
+ rules: "${configDir}/scripts/rules.go"
+
+ staticcheck:
+ # https://staticcheck.io/docs/options#checks
+ # We disable SA1019 because it gets angry about our usage of xerrors. We
+ # intentionally xerrors because stack frame support didn't make it into the
+ # stdlib port.
+ checks: ["all", "-SA1019"]
+
+ goimports:
+ local-prefixes: coder.com,cdr.dev,go.coder.com,github.com/cdr,github.com/coder
+
+ importas:
+ no-unaliased: true
+
+ misspell:
+ locale: US
+ ignore-words:
+ - trialer
+
+ nestif:
+ # goal: 10
+ min-complexity: 20
+
+ revive:
+ # see https://github.com/mgechev/revive#available-rules for details.
+ ignore-generated-header: true
+ severity: warning
+ rules:
+ - name: atomic
+ - name: bare-return
+ - name: blank-imports
+ - name: bool-literal-in-expr
+ - name: call-to-gc
+ - name: confusing-naming
+ - name: confusing-results
+ - name: constant-logical-expr
+ - name: context-as-argument
+ - name: context-keys-type
+ - name: deep-exit
+ - name: defer
+ - name: dot-imports
+ - name: duplicated-imports
+ - name: early-return
+ - name: empty-block
+ - name: empty-lines
+ - name: error-naming
+ - name: error-return
+ - name: error-strings
+ - name: errorf
+ - name: exported
+ - name: flag-parameter
+ - name: get-return
+ - name: identical-branches
+ - name: if-return
+ - name: import-shadowing
+ - name: increment-decrement
+ - name: indent-error-flow
+ # - name: modifies-parameter
+ - name: modifies-value-receiver
+ - name: package-comments
+ - name: range
+ - name: receiver-naming
+ - name: redefines-builtin-id
+ - name: string-of-int
+ - name: struct-tag
+ - name: superfluous-else
+ - name: time-naming
+ - name: unconditional-recursion
+ - name: unexported-naming
+ - name: unexported-return
+ - name: unhandled-error
+ - name: unnecessary-stmt
+ - name: unreachable-code
+ - name: unused-parameter
+ exclude: "**/*_test.go"
+ - name: unused-receiver
+ - name: var-declaration
+ - name: var-naming
+ - name: waitgroup-by-value
+
+ # irrelevant as of Go v1.22: https://go.dev/blog/loopvar-preview
+ govet:
+ disable:
+ - loopclosure
+ gosec:
+ excludes:
+ # Implicit memory aliasing of items from a range statement (irrelevant as of Go v1.22)
+ - G601
+
+issues:
+ exclude-dirs:
+ - coderd/database/dbmem
+ - node_modules
+ - .git
+
+ exclude-files:
+ - scripts/rules.go
+
+ # Rules listed here: https://github.com/securego/gosec#available-rules
+ exclude-rules:
+ - path: _test\.go
+ linters:
+ # We use assertions rather than explicitly checking errors in tests
+ - errcheck
+ - forcetypeassert
+ - exhaustruct # This is unhelpful in tests.
+ - path: scripts/*
+ linters:
+ - exhaustruct
+ - path: scripts/rules.go
+ linters:
+ - ALL
+
+ fix: true
+ max-issues-per-linter: 0
+ max-same-issues: 0
+
+run:
+ timeout: 10m
+
+# Over time, add more and more linters from
+# https://golangci-lint.run/usage/linters/ as the code improves.
+linters:
+ disable-all: true
+ enable:
+ - asciicheck
+ - bidichk
+ - bodyclose
+ - dogsled
+ - errcheck
+ - errname
+ - errorlint
+ - exhaustruct
+ - forcetypeassert
+ - gocritic
+ # gocyclo is may be useful in the future when we start caring
+ # about testing complexity, but for the time being we should
+ # create a good culture around cognitive complexity.
+ # - gocyclo
+ - gocognit
+ - nestif
+ - goimports
+ - gomodguard
+ - gosec
+ - gosimple
+ - govet
+ - importas
+ - ineffassign
+ - makezero
+ - misspell
+ - nilnil
+ - noctx
+ - paralleltest
+ - revive
+
+ # These don't work until the following issue is solved.
+ # https://github.com/golangci/golangci-lint/issues/2649
+ # - rowserrcheck
+ # - sqlclosecheck
+ # - structcheck
+ # - wastedassign
+
+ - staticcheck
+ - tenv
+ # In Go, it's possible for a package to test it's internal functionality
+ # without testing any exported functions. This is enabled to promote
+ # decomposing a package before testing it's internals. A function caller
+ # should be able to test most of the functionality from exported functions.
+ #
+ # There are edge-cases to this rule, but they should be carefully considered
+ # to avoid structural inconsistency.
+ - testpackage
+ - tparallel
+ - typecheck
+ - unconvert
+ - unused
+ - dupl
\ No newline at end of file
diff --git a/attr.go b/attr.go
deleted file mode 100644
index 3d81418..0000000
--- a/attr.go
+++ /dev/null
@@ -1,112 +0,0 @@
-package preview
-
-import (
- "fmt"
-
- "github.com/aquasecurity/trivy/pkg/iac/terraform"
- "github.com/hashicorp/hcl/v2"
- "github.com/zclconf/go-cty/cty"
-)
-
-type attributeParser struct {
- block *terraform.Block
- diags hcl.Diagnostics
-}
-
-func newAttributeParser(block *terraform.Block) *attributeParser {
- return &attributeParser{
- block: block,
- diags: make(hcl.Diagnostics, 0),
- }
-}
-
-func (a *attributeParser) attr(key string) *expectedAttribute {
- return &expectedAttribute{
- Key: key,
- p: a,
- }
-}
-
-type expectedAttribute struct {
- Key string
- diag hcl.Diagnostics
- p *attributeParser
-}
-
-func (a *expectedAttribute) error(diag hcl.Diagnostics) *expectedAttribute {
- if a.diag != nil {
- return a // already have an error, don't overwrite
- }
-
- a.p.diags = a.p.diags.Extend(diag)
- a.diag = diag
- return a
-}
-
-func (a *expectedAttribute) required() *expectedAttribute {
- attr := a.p.block.GetAttribute(a.Key)
- if attr.IsNil() {
- r := a.p.block.HCLBlock().Body.MissingItemRange()
- a.error(hcl.Diagnostics{
- {
- Severity: hcl.DiagError,
- Summary: fmt.Sprintf("Missing required attribute %q", a.Key),
- // This is the error word for word from 'terraform apply'
- Detail: fmt.Sprintf("The argument %q is required, but no definition is found.", a.Key),
- Subject: &r,
- Extra: nil,
- },
- })
- }
-
- return a
-}
-
-func (a *expectedAttribute) tryString() string {
- attr := a.p.block.GetAttribute(a.Key)
- if attr.IsNil() {
- return ""
- }
-
- if attr.Type() != cty.String {
- return ""
- }
-
- return attr.Value().AsString()
-}
-
-func (a *expectedAttribute) string() string {
- attr := a.p.block.GetAttribute(a.Key)
- if attr.IsNil() {
- return ""
- }
-
- if attr.Type() != cty.String {
- a.expectedTypeError(attr, "string")
- return ""
- }
-
- return attr.Value().AsString()
-}
-
-func (a *expectedAttribute) expectedTypeError(attr *terraform.Attribute, expectedType string) {
- var fn string
- if attr.IsNil() || attr.Type().Equals(cty.NilType) {
- fn = "nil"
- } else {
- fn = attr.Type().FriendlyName()
- }
-
- a.error(hcl.Diagnostics{
- {
- Severity: hcl.DiagError,
- Summary: "Invalid attribute type",
- Detail: fmt.Sprintf("The attribute %q must be of type %q, found type %q", attr.Name(), expectedType, fn),
- Subject: &attr.HCLAttribute().Range,
- Context: &a.p.block.HCLBlock().DefRange,
- Expression: attr.HCLAttribute().Expr,
-
- EvalContext: a.p.block.Context().Inner(),
- },
- })
-}
diff --git a/cli/clidisplay/resources.go b/cli/clidisplay/resources.go
index ac93025..e19c3e3 100644
--- a/cli/clidisplay/resources.go
+++ b/cli/clidisplay/resources.go
@@ -30,23 +30,11 @@ func WorkspaceTags(writer io.Writer, tags types.TagBlocks) hcl.Diagnostics {
k, v := tag.AsStrings()
tableWriter.AppendRow(table.Row{k, v, ""})
continue
- //diags = diags.Extend(tDiags)
- //if !diags.HasErrors() {
- // tableWriter.AppendRow(table.Row{k, v, ""})
- // continue
- //}
}
k := tag.KeyString()
refs := tag.References()
tableWriter.AppendRow(table.Row{k, "??", strings.Join(refs, "\n")})
-
- //refs := tb.AllReferences()
- //refsStr := make([]string, 0, len(refs))
- //for _, ref := range refs {
- // refsStr = append(refsStr, ref.String())
- //}
- //tableWriter.AppendRow(table.Row{unknown, "???", strings.Join(refsStr, "\n")})
}
}
_, _ = fmt.Fprintln(writer, tableWriter.Render())
@@ -55,7 +43,7 @@ func WorkspaceTags(writer io.Writer, tags types.TagBlocks) hcl.Diagnostics {
func Parameters(writer io.Writer, params []types.Parameter, files map[string]*hcl.File) {
tableWriter := table.NewWriter()
- //tableWriter.SetTitle("Parameters")
+ // tableWriter.SetTitle("Parameters")
tableWriter.SetStyle(table.StyleLight)
tableWriter.Style().Options.SeparateColumns = false
row := table.Row{"Parameter"}
@@ -66,15 +54,15 @@ func Parameters(writer io.Writer, params []types.Parameter, files map[string]*hc
if p.FormType == provider.ParameterFormTypeMultiSelect {
_ = json.Unmarshal([]byte(strVal), &selections)
}
- //value := p.Value.Value
+ // value := p.Value.Value
//
- //if value.IsNull() {
+ // if value.IsNull() {
// strVal = "null"
- //} else if !p.Value.Value.IsKnown() {
+ // } else if !p.Value.Value.IsKnown() {
// strVal = "unknown"
- //} else if value.Type().Equals(cty.String) {
+ // } else if value.Type().Equals(cty.String) {
// strVal = value.AsString()
- //} else {
+ // } else {
// strVal = value.GoString()
//}
@@ -86,7 +74,6 @@ func Parameters(writer io.Writer, params []types.Parameter, files map[string]*hc
var out bytes.Buffer
WriteDiagnostics(&out, files, hcl.Diagnostics(p.Diagnostics))
tableWriter.AppendRow(table.Row{out.String()})
-
}
tableWriter.AppendSeparator()
@@ -100,29 +87,29 @@ func formatOptions(selected []string, options []*types.ParameterOption) string {
found := false
for _, opt := range options {
- str.WriteString(sep)
+ _, _ = str.WriteString(sep)
prefix := "[ ]"
if slices.Contains(selected, opt.Value.AsString()) {
prefix = "[X]"
found = true
}
- str.WriteString(fmt.Sprintf("%s %s (%s)", prefix, opt.Name, opt.Value.AsString()))
+ _, _ = str.WriteString(fmt.Sprintf("%s %s (%s)", prefix, opt.Name, opt.Value.AsString()))
if opt.Description != "" {
- str.WriteString(fmt.Sprintf("\n %s", maxLength(opt.Description, 25)))
+ _, _ = str.WriteString(fmt.Sprintf("\n %s", maxLength(opt.Description, 25)))
}
sep = "\n"
}
if !found {
- str.WriteString(sep)
- str.WriteString(fmt.Sprintf("= %s", selected))
+ _, _ = str.WriteString(sep)
+ _, _ = str.WriteString(fmt.Sprintf("= %s", selected))
}
return str.String()
}
-func maxLength(s string, max int) string {
- if len(s) > max {
- return s[:max] + "..."
+func maxLength(s string, m int) string {
+ if len(s) > m {
+ return s[:m] + "..."
}
return s
}
diff --git a/cli/env.go b/cli/env.go
index 1cf189f..f86704d 100644
--- a/cli/env.go
+++ b/cli/env.go
@@ -10,7 +10,7 @@ import (
"github.com/coder/serpent"
)
-func (r *RootCmd) SetEnv() *serpent.Command {
+func (*RootCmd) SetEnv() *serpent.Command {
var (
vars []string
groups []string
@@ -38,7 +38,7 @@ func (r *RootCmd) SetEnv() *serpent.Command {
},
},
Hidden: false,
- Handler: func(i *serpent.Invocation) error {
+ Handler: func(_ *serpent.Invocation) error {
for _, val := range vars {
parts := strings.Split(val, "=")
if len(parts) != 2 {
@@ -49,7 +49,7 @@ func (r *RootCmd) SetEnv() *serpent.Command {
if err != nil {
return err
}
- fmt.Println("CODER_PARAMETER_" + hex.EncodeToString(sum[:]) + "=" + parts[1])
+ _, _ = fmt.Println("CODER_PARAMETER_" + hex.EncodeToString(sum[:]) + "=" + parts[1])
}
return nil
diff --git a/cli/plan.go b/cli/plan.go
index c5e174b..c07c498 100644
--- a/cli/plan.go
+++ b/cli/plan.go
@@ -10,7 +10,7 @@ import (
"github.com/coder/serpent"
)
-func (r *RootCmd) TerraformPlan() *serpent.Command {
+func (*RootCmd) TerraformPlan() *serpent.Command {
cmd := &serpent.Command{
Use: "plan",
Short: "Runs `terraform init -upgrade` and `terraform plan`, saving the output.",
@@ -54,6 +54,7 @@ func (r *RootCmd) TerraformPlan() *serpent.Command {
var indented bytes.Buffer
_ = json.Indent(&indented, buf.Bytes(), "", " ")
+ //nolint:gosec // these files are not a secret
_ = os.WriteFile("plan.json", indented.Bytes(), 0644)
return nil
},
diff --git a/cli/root.go b/cli/root.go
index 56dfb8d..ab1afc5 100644
--- a/cli/root.go
+++ b/cli/root.go
@@ -106,11 +106,11 @@ func (r *RootCmd) Root() *serpent.Command {
clidisplay.Parameters(os.Stdout, output.Parameters, output.Files)
if !output.ModuleOutput.IsNull() && !(output.ModuleOutput.Type().IsObjectType() && output.ModuleOutput.LengthInt() == 0) {
- fmt.Println("Module output")
+ _, _ = fmt.Println("Module output")
data, _ := ctyjson.Marshal(output.ModuleOutput, output.ModuleOutput.Type())
var buf bytes.Buffer
_ = json.Indent(&buf, data, "", " ")
- fmt.Println(buf.String())
+ _, _ = fmt.Println(buf.String())
}
return nil
@@ -122,6 +122,7 @@ func (r *RootCmd) Root() *serpent.Command {
return cmd
}
+//nolint:unused
func hclExpr(expr string) hcl.Expression {
file, diags := hclsyntax.ParseConfig([]byte(fmt.Sprintf(`expr = %s`, expr)), "test.tf", hcl.InitialPos)
if diags.HasErrors() {
diff --git a/cli/static/index.html b/cli/static/index.html
deleted file mode 100644
index 5fa349f..0000000
--- a/cli/static/index.html
+++ /dev/null
@@ -1,55 +0,0 @@
-
-
-
-
-
- Codestin Search App
-
-
-
-
-WebSocket JSON Preview
-
-
-
-
-
-Output:
-
-
-
diff --git a/cli/web.go b/cli/web.go
index 0b9d9ac..4ffe954 100644
--- a/cli/web.go
+++ b/cli/web.go
@@ -3,7 +3,6 @@ package cli
import (
"bufio"
"context"
- "embed"
"encoding/json"
"fmt"
"io/fs"
@@ -13,6 +12,7 @@ import (
"os/exec"
"path/filepath"
"slices"
+ "time"
"github.com/go-chi/chi"
@@ -24,13 +24,9 @@ import (
"github.com/coder/websocket"
)
-//go:embed static/*
-var static embed.FS
-
type responseRecorder struct {
http.ResponseWriter
- headerWritten bool
- logger slog.Logger
+ logger slog.Logger
}
// Implement Hijacker interface for WebSocket support
@@ -54,7 +50,7 @@ func debugMiddleware(logger slog.Logger) func(http.Handler) http.Handler {
}
}
-func (r *RootCmd) WebsocketServer() *serpent.Command {
+func (*RootCmd) WebsocketServer() *serpent.Command {
var (
address string
siteDir string
@@ -132,7 +128,7 @@ func (r *RootCmd) WebsocketServer() *serpent.Command {
}
_ = json.NewEncoder(rw).Encode(availableUsers)
})
- mux.HandleFunc("/directories", func(rw http.ResponseWriter, r *http.Request) {
+ mux.HandleFunc("/directories", func(rw http.ResponseWriter, _ *http.Request) {
entries, err := fs.ReadDir(dataDirFS, ".")
if err != nil {
http.Error(rw, "Could not read directory", http.StatusInternalServerError)
@@ -163,9 +159,10 @@ func (r *RootCmd) WebsocketServer() *serpent.Command {
srv := &http.Server{
Addr: address,
Handler: mux,
- BaseContext: func(listener net.Listener) context.Context {
+ BaseContext: func(_ net.Listener) context.Context {
return ctx
},
+ ReadHeaderTimeout: time.Second * 30,
}
if siteDir != "" {
@@ -184,7 +181,6 @@ func (r *RootCmd) WebsocketServer() *serpent.Command {
// Kill the server if pnpm exits
_ = srv.Shutdown(ctx)
}()
-
}
logger.Info(ctx, "Starting server", slog.F("address", address))
@@ -197,7 +193,6 @@ func (r *RootCmd) WebsocketServer() *serpent.Command {
func websocketHandler(logger slog.Logger, dirFS fs.FS) func(rw http.ResponseWriter, r *http.Request) {
return func(rw http.ResponseWriter, r *http.Request) {
-
logger.Debug(r.Context(), "WebSocket connection attempt",
slog.F("remote_addr", r.RemoteAddr),
slog.F("path", r.URL.Path),
diff --git a/cmd/preview/main.go b/cmd/preview/main.go
index a035d2c..795ee4f 100644
--- a/cmd/preview/main.go
+++ b/cmd/preview/main.go
@@ -5,8 +5,9 @@ import (
"log"
"os"
- "github.com/coder/preview/cli"
"github.com/hashicorp/hcl/v2"
+
+ "github.com/coder/preview/cli"
)
func main() {
@@ -29,6 +30,5 @@ func main() {
}
}
log.Fatal(err.Error())
- os.Exit(1)
}
}
diff --git a/extract/parameter.go b/extract/parameter.go
index 3851635..6cbd791 100644
--- a/extract/parameter.go
+++ b/extract/parameter.go
@@ -159,6 +159,7 @@ func ParameterFromBlock(block *terraform.Block) (*types.Parameter, hcl.Diagnosti
if ctyType != cty.NilType && pVal.Value.Type().Equals(cty.String) {
// TODO: Wish we could support more types, but only string types are
// allowed.
+ //nolint:gocritic // string type asserted
valStr := pVal.Value.AsString()
// Apply validations to the parameter value
for _, v := range p.Validations {
@@ -328,6 +329,7 @@ func requiredString(block *terraform.Block, key string) (string, *hcl.Diagnostic
return "", diag
}
+ // nolint:gocritic // string type asserted
return tyVal.AsString(), nil
}
@@ -400,6 +402,7 @@ func nullableString(block *terraform.Block, key string) *string {
return nil
}
+ //nolint:gocritic // string type asserted
str := val.AsString()
return &str
}
@@ -414,6 +417,7 @@ func optionalString(block *terraform.Block, key string) string {
return ""
}
+ //nolint:gocritic // string type asserted
return val.AsString()
}
diff --git a/go.mod b/go.mod
index 7ea2251..634edb1 100644
--- a/go.mod
+++ b/go.mod
@@ -98,6 +98,7 @@ require (
github.com/pion/udp v0.1.4 // indirect
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
+ github.com/quasilyte/go-ruleguard/dsl v0.3.22 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/robfig/cron/v3 v3.0.1 // indirect
github.com/samber/lo v1.49.1 // indirect
diff --git a/go.sum b/go.sum
index c22d751..3cdb559 100644
--- a/go.sum
+++ b/go.sum
@@ -1118,6 +1118,8 @@ github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:Om
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
+github.com/quasilyte/go-ruleguard/dsl v0.3.22 h1:wd8zkOhSNr+I+8Qeciml08ivDt1pSXe60+5DqOpCjPE=
+github.com/quasilyte/go-ruleguard/dsl v0.3.22/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU=
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
diff --git a/hclext/merge.go b/hclext/merge.go
index 8c2919c..caeb762 100644
--- a/hclext/merge.go
+++ b/hclext/merge.go
@@ -1,6 +1,8 @@
package hclext
-import "github.com/zclconf/go-cty/cty"
+import (
+ "github.com/zclconf/go-cty/cty"
+)
func MergeObjects(a, b cty.Value) cty.Value {
output := make(map[string]cty.Value)
@@ -9,6 +11,11 @@ func MergeObjects(a, b cty.Value) cty.Value {
output[key] = val
}
b.ForEachElement(func(key, val cty.Value) (stop bool) {
+ // TODO: Should this error be captured?
+ if key.Type() != cty.String {
+ return true
+ }
+ //nolint:gocritic // string type asserted above
k := key.AsString()
old := output[k]
if old.IsKnown() && isNotEmptyObject(old) && isNotEmptyObject(val) {
diff --git a/hclext/references.go b/hclext/references.go
index e9f38e9..ba23e3f 100644
--- a/hclext/references.go
+++ b/hclext/references.go
@@ -65,12 +65,14 @@ func CreateDotReferenceFromTraversal(traversals ...hcl.Traversal) string {
case hcl.TraverseAttr:
refParts = append(refParts, part.Name)
case hcl.TraverseIndex:
- if part.Key.Type().Equals(cty.String) {
+ switch {
+ case part.Key.Type().Equals(cty.String):
+ //nolint:gocritic // string type asserted above
refParts = append(refParts, fmt.Sprintf("[%s]", part.Key.AsString()))
- } else if part.Key.Type().Equals(cty.Number) {
+ case part.Key.Type().Equals(cty.Number):
idx, _ := part.Key.AsBigFloat().Int64()
refParts = append(refParts, fmt.Sprintf("[%d]", idx))
- } else {
+ default:
refParts = append(refParts, fmt.Sprintf("[?? %q]", part.Key.Type().FriendlyName()))
}
}
diff --git a/hclext/vartypes.go b/hclext/vartypes.go
deleted file mode 100644
index 40c8329..0000000
--- a/hclext/vartypes.go
+++ /dev/null
@@ -1,43 +0,0 @@
-package hclext
-
-import (
- "github.com/hashicorp/hcl/v2"
- "github.com/hashicorp/hcl/v2/ext/typeexpr"
- "github.com/hashicorp/hcl/v2/hclsyntax"
- "github.com/zclconf/go-cty/cty"
-)
-
-func DecodeVarType(exp hcl.Expression) (cty.Type, *typeexpr.Defaults, error) {
- // This block converts the string literals "string" -> string
- // Coder used to allow literal strings, instead of types as keywords. So
- // we have to handle these cases for backwards compatibility.
- if tpl, ok := exp.(*hclsyntax.TemplateExpr); ok && len(tpl.Parts) == 1 {
- if lit, ok := tpl.Parts[0].(*hclsyntax.LiteralValueExpr); ok && lit.Val.Type() == cty.String {
- keyword := lit.Val.AsString()
-
- exp = &hclsyntax.ScopeTraversalExpr{
- Traversal: []hcl.Traverser{
- hcl.TraverseRoot{
- Name: keyword,
- SrcRange: exp.Range(),
- },
- },
- SrcRange: exp.Range(),
- }
- }
- }
-
- // Special-case the shortcuts for list(any) and map(any) which aren't hcl.
- switch hcl.ExprAsKeyword(exp) {
- case "list":
- return cty.List(cty.DynamicPseudoType), nil, nil
- case "map":
- return cty.Map(cty.DynamicPseudoType), nil, nil
- }
-
- t, def, diag := typeexpr.TypeConstraintWithDefaults(exp)
- if diag.HasErrors() {
- return cty.NilType, nil, diag
- }
- return t, def, nil
-}
diff --git a/internal/verify/exec.go b/internal/verify/exec.go
index 6801e48..1294025 100644
--- a/internal/verify/exec.go
+++ b/internal/verify/exec.go
@@ -129,7 +129,7 @@ func InstallTerraforms(ctx context.Context, t *testing.T, installables ...src.In
return execPaths
}
-func LatestTerraformVersion(ctx context.Context) *releases.LatestVersion {
+func LatestTerraformVersion(_ context.Context) *releases.LatestVersion {
return &releases.LatestVersion{
Product: product.Terraform,
}
@@ -158,10 +158,10 @@ func TerraformVersions(ctx context.Context, constraints version.Constraints) ([]
}
include := make([]*releases.ExactVersion, 0)
- for _, src := range srcs {
- ev, ok := src.(*releases.ExactVersion)
+ for _, s := range srcs {
+ ev, ok := s.(*releases.ExactVersion)
if !ok {
- return nil, fmt.Errorf("failed to cast src to ExactVersion, type was %T", src)
+ return nil, fmt.Errorf("failed to cast src to ExactVersion, type was %T", s)
}
include = append(include, ev)
@@ -212,7 +212,7 @@ func CopyTFFS(dir string, fsys fs.FS) error {
}
if _, err := io.Copy(w, r); err != nil {
- w.Close()
+ _ = w.Close()
return &os.PathError{Op: "Copy", Path: newPath, Err: err}
}
return w.Close()
diff --git a/log.go b/log.go
deleted file mode 100644
index db34405..0000000
--- a/log.go
+++ /dev/null
@@ -1,15 +0,0 @@
-package preview
-
-import (
- "os"
-
- tlog "github.com/aquasecurity/trivy/pkg/log"
-)
-
-func init() {
- ll := tlog.New(tlog.NewHandler(os.Stderr, &tlog.Options{
- Level: tlog.LevelDebug,
- }))
- var _ = ll
- //tlog.SetDefault(ll)
-}
diff --git a/mark.go b/mark.go
deleted file mode 100644
index d97e634..0000000
--- a/mark.go
+++ /dev/null
@@ -1,10 +0,0 @@
-package preview
-
-import (
- "github.com/hashicorp/hcl/v2"
- "github.com/zclconf/go-cty/cty"
-)
-
-func markWithDiagnostic(v cty.Value, diag hcl.Diagnostics) cty.Value {
- return v.Mark(diag)
-}
diff --git a/owner.go b/owner.go
index a300a30..dbd7ad8 100644
--- a/owner.go
+++ b/owner.go
@@ -12,10 +12,10 @@ import (
func workspaceOwnerHook(_ fs.FS, input Input) (func(ctx *tfcontext.Context, blocks terraform.Blocks, inputVars map[string]cty.Value), error) {
ownerValue, err := input.Owner.ToCtyValue()
if err != nil {
- return nil, xerrors.Errorf("failed to convert owner value", err)
+ return nil, xerrors.Errorf("failed to convert owner value: %w", err)
}
- return func(ctx *tfcontext.Context, blocks terraform.Blocks, inputVars map[string]cty.Value) {
+ return func(_ *tfcontext.Context, blocks terraform.Blocks, _ map[string]cty.Value) {
for _, block := range blocks.OfType("data") {
// TODO: Does it have to be me?
if block.TypeLabel() == "coder_workspace_owner" && block.NameLabel() == "me" {
diff --git a/parameter.go b/parameter.go
index e56660b..c5d691b 100644
--- a/parameter.go
+++ b/parameter.go
@@ -39,7 +39,7 @@ func parameters(modules terraform.Modules) ([]types.Parameter, hcl.Diagnostics)
var detail strings.Builder
for _, p := range v {
if p.Source != nil {
- detail.WriteString(fmt.Sprintf("block %q at %s\n",
+ _, _ = detail.WriteString(fmt.Sprintf("block %q at %s\n",
p.Source.Type()+"."+strings.Join(p.Source.Labels(), "."),
p.Source.HCLBlock().TypeRange))
}
diff --git a/paramhook.go b/paramhook.go
index ec10a33..03eadc5 100644
--- a/paramhook.go
+++ b/paramhook.go
@@ -15,7 +15,7 @@ import (
// is resolvable. The resolvable parameter will be accessible on the next
// iteration.
func parameterContextsEvalHook(input Input) func(ctx *tfcontext.Context, blocks terraform.Blocks, inputVars map[string]cty.Value) {
- return func(ctx *tfcontext.Context, blocks terraform.Blocks, inputVars map[string]cty.Value) {
+ return func(ctx *tfcontext.Context, blocks terraform.Blocks, _ map[string]cty.Value) {
data := blocks.OfType("data")
for _, block := range data {
if block.TypeLabel() != "coder_parameter" {
@@ -32,6 +32,7 @@ func parameterContextsEvalHook(input Input) func(ctx *tfcontext.Context, blocks
continue // Ignore the errors at this point
}
+ //nolint:gocritic // string type asserted
name := nameVal.AsString()
var value cty.Value
pv, ok := input.RichParameterValue(name)
@@ -156,9 +157,9 @@ func isForEachKey(key cty.Value) bool {
func evaluateCoderParameterDefault(b *terraform.Block) (cty.Value, bool) {
attributes := b.Attributes()
- //typeAttr, exists := attributes["type"]
- //valueType := cty.String // TODO: Default to string?
- //if exists {
+ // typeAttr, exists := attributes["type"]
+ // valueType := cty.String // TODO: Default to string?
+ // if exists {
// typeVal := typeAttr.Value()
// if !typeVal.Type().Equals(cty.String) || !typeVal.IsWhollyKnown() {
// // TODO: Mark this value somehow
@@ -187,7 +188,7 @@ func evaluateCoderParameterDefault(b *terraform.Block) (cty.Value, bool) {
//
//// TODO: We should support different tf types, but at present the tf
//// schema is static. So only string is allowed
- //var val cty.Value
+ // var val cty.Value
def, exists := attributes["default"]
if !exists {
diff --git a/plan.go b/plan.go
index 8458c24..2714bc8 100644
--- a/plan.go
+++ b/plan.go
@@ -23,9 +23,9 @@ func planJSONHook(dfs fs.FS, input Input) (func(ctx *tfcontext.Context, blocks t
var contents io.Reader = bytes.NewReader(input.PlanJSON)
// Also accept `{}` as an empty plan. If this is stored in postgres or another json
// type, then `{}` is the "empty" value.
- if len(input.PlanJSON) == 0 || bytes.Compare(input.PlanJSON, []byte("{}")) == 0 {
+ if len(input.PlanJSON) == 0 || bytes.Equal(input.PlanJSON, []byte("{}")) {
if input.PlanJSONPath == "" {
- return func(ctx *tfcontext.Context, blocks terraform.Blocks, inputVars map[string]cty.Value) {}, nil
+ return func(_ *tfcontext.Context, _ terraform.Blocks, _ map[string]cty.Value) {}, nil
}
var err error
@@ -40,7 +40,7 @@ func planJSONHook(dfs fs.FS, input Input) (func(ctx *tfcontext.Context, blocks t
return nil, fmt.Errorf("unable to parse plan JSON: %w", err)
}
- return func(ctx *tfcontext.Context, blocks terraform.Blocks, inputVars map[string]cty.Value) {
+ return func(_ *tfcontext.Context, blocks terraform.Blocks, _ map[string]cty.Value) {
loaded := make(map[*tfjson.StateModule]bool)
// Do not recurse to child blocks.
@@ -110,22 +110,6 @@ func priorPlanModule(plan *tfjson.Plan, block *terraform.Block) *tfjson.StateMod
return current
}
-func matchingBlock(block *terraform.Block, planMod *tfjson.StateModule) *tfjson.StateResource {
- ref := block.Reference()
- matchKey := keyMatcher(ref.RawKey())
-
- for _, resource := range planMod.Resources {
- if ref.BlockType().ShortName() == string(resource.Mode) &&
- ref.TypeLabel() == resource.Type &&
- ref.NameLabel() == resource.Name &&
- matchKey(resource.Index) {
-
- return resource
- }
- }
- return nil
-}
-
func loadResourcesToContext(ctx *tfcontext.Context, resources []*tfjson.StateResource) error {
for _, resource := range resources {
if resource.Mode != "data" {
@@ -224,24 +208,7 @@ func parsePlanJSON(reader io.Reader) (*tfjson.Plan, error) {
return plan, json.NewDecoder(reader).Decode(plan)
}
-func keyMatcher(key cty.Value) func(to any) bool {
- switch {
- case key.Type().Equals(cty.Number):
- idx, _ := key.AsBigFloat().Int64()
- return func(to any) bool {
- asInt, ok := toInt(to)
- return ok && asInt == idx
- }
-
- case key.Type().Equals(cty.String):
- // TODO: handle key strings
- }
-
- return func(to any) bool {
- return true
- }
-}
-
+//nolint:gosec // Maybe handle overflow at some point
func toInt(to any) (int64, bool) {
switch typed := to.(type) {
case uint:
diff --git a/plan_test.go b/plan_test.go
index af268e8..b3d0edd 100644
--- a/plan_test.go
+++ b/plan_test.go
@@ -14,6 +14,8 @@ func TestPlanJSONHook(t *testing.T) {
t.Parallel()
t.Run("Empty plan", func(t *testing.T) {
+ t.Parallel()
+
dirFS := os.DirFS("testdata/static")
_, diags := preview.Preview(t.Context(), preview.Input{
PlanJSONPath: "",
diff --git a/preview.go b/preview.go
index 96447ff..ed51211 100644
--- a/preview.go
+++ b/preview.go
@@ -58,8 +58,8 @@ func Preview(ctx context.Context, input Input, dir fs.FS) (output *Output, diagn
// TODO: Fix logging. There is no way to pass in an instanced logger to
// the parser.
- //slog.SetLogLoggerLevel(slog.LevelDebug)
- //slog.SetDefault(slog.New(log.NewHandler(os.Stderr, nil)))
+ // slog.SetLogLoggerLevel(slog.LevelDebug)
+ // slog.SetDefault(slog.New(log.NewHandler(os.Stderr, nil)))
varFiles, err := tfVarFiles("", dir)
if err != nil {
@@ -127,7 +127,7 @@ func Preview(ctx context.Context, input Input, dir fs.FS) (output *Output, diagn
},
}
}
-
+
outputs := hclext.ExportOutputs(modules)
diags := make(hcl.Diagnostics, 0)
diff --git a/preview_test.go b/preview_test.go
index 0c91d36..5bba3a9 100644
--- a/preview_test.go
+++ b/preview_test.go
@@ -504,12 +504,14 @@ func (a assertParam) optVals(opts ...string) assertParam {
})
}
+//nolint:unused
func (a assertParam) opts(opts ...types.ParameterOption) assertParam {
return a.extend(func(t *testing.T, parameter types.Parameter) {
assert.ElementsMatch(t, opts, parameter.Options, "parameter options equality check")
})
}
+//nolint:revive
func (a assertParam) extend(f assertParam) assertParam {
if a == nil {
a = func(t *testing.T, parameter types.Parameter) {}
diff --git a/previewe2e_test.go b/previewe2e_test.go
index 4471611..3a9adb2 100644
--- a/previewe2e_test.go
+++ b/previewe2e_test.go
@@ -47,7 +47,7 @@ import (
// The goal of the test is to compare `tfstate` with the output of `preview`.
// If `preview`'s implementation of terraform is incorrect, the test will fail.
// TODO: Adding varied parameter inputs would be a good idea.
-// TODO: Add workspace tag comparisions.
+// TODO: Add workspace tag comparisons.
func Test_VerifyE2E(t *testing.T) {
t.Parallel()
@@ -80,7 +80,7 @@ func Test_VerifyE2E(t *testing.T) {
continue
}
- entryFiles, err := fs.ReadDir(dirFs, filepath.Join(entry.Name()))
+ entryFiles, err := fs.ReadDir(dirFs, entry.Name())
require.NoError(t, err, "reading test data dir")
if !slices.ContainsFunc(entryFiles, func(entry fs.DirEntry) bool {
return filepath.Ext(entry.Name()) == ".tf"
@@ -135,8 +135,9 @@ func Test_VerifyE2E(t *testing.T) {
require.NoError(t, err, "terraform show plan")
pd, err := json.Marshal(plan)
- require.NoError(t, err, "marshalling plan")
+ require.NoError(t, err, "marshaling plan")
+ //nolint:gosec // unit test
err = os.WriteFile(filepath.Join(wp, "plan.json"), pd, 0644)
require.NoError(t, err, "writing plan.json")
diff --git a/scripts/rules.go b/scripts/rules.go
new file mode 100644
index 0000000..8634f12
--- /dev/null
+++ b/scripts/rules.go
@@ -0,0 +1,35 @@
+// Package gorules defines custom lint rules for ruleguard.
+//
+// golangci-lint runs these rules via go-critic, which includes support
+// for ruleguard. All Go files in this directory define lint rules
+// in the Ruleguard DSL; see:
+//
+// - https://go-ruleguard.github.io/by-example/
+// - https://pkg.go.dev/github.com/quasilyte/go-ruleguard/dsl
+//
+// You run one of the following commands to execute your go rules only:
+//
+// golangci-lint run
+// golangci-lint run --disable-all --enable=gocritic
+//
+// Note: don't forget to run `golangci-lint cache clean`!
+package gorules
+
+import "github.com/quasilyte/go-ruleguard/dsl"
+
+// asStringsIsDangerous checks for the use of AsString() on cty.Value.
+// This function can panic if not used correctly, so the cty.Type must be known
+// before calling. Ignore this lint if you are confident in your usage.
+func asStringsIsDangerous(m dsl.Matcher) {
+ m.Import("github.com/zclconf/go-cty/cty")
+
+ m.Match(
+ `$v.AsString()`,
+ ).
+ Where(
+ m["v"].Type.Is("cty.Value") &&
+ // Ignore unit tests
+ !m.File().Name.Matches(`_test\.go$`),
+ ).
+ Report("'AsStrings()' can result in a panic if the type is not known. Ignore this linter with caution")
+}
diff --git a/site/genweb/main.go b/site/genweb/main.go
index 153cb97..fd04236 100644
--- a/site/genweb/main.go
+++ b/site/genweb/main.go
@@ -59,6 +59,7 @@ func main() {
}
if outFile != nil {
+ //nolint:gosec
_ = os.WriteFile(*outFile, []byte(output), 0644)
} else {
_, _ = fmt.Println(output)
diff --git a/source.go b/source.go
index a1c5064..27d22c8 100644
--- a/source.go
+++ b/source.go
@@ -7,6 +7,7 @@ import (
"github.com/hashicorp/hcl/v2"
)
+//nolint:unused
func source(r hcl.Range, files map[string]*hcl.File) ([]byte, error) {
file, ok := files[r.Filename]
if !ok {
diff --git a/types/owner.go b/types/owner.go
index e714d5f..2962ca7 100644
--- a/types/owner.go
+++ b/types/owner.go
@@ -56,7 +56,7 @@ func (o *WorkspaceOwner) ToCtyValue() (cty.Value, error) {
)),
}))
if err != nil {
- return cty.Value{}, xerrors.Errorf("failed to convert owner value", err)
+ return cty.Value{}, xerrors.Errorf("failed to convert owner value: %w", err)
}
return ownerValue, nil
}
diff --git a/types/owner_test.go b/types/owner_test.go
index d8fb549..3361f3a 100644
--- a/types/owner_test.go
+++ b/types/owner_test.go
@@ -1,13 +1,17 @@
-package types
+package types_test
import (
"testing"
"github.com/stretchr/testify/require"
+
+ "github.com/coder/preview/types"
)
func TestToCtyValue(t *testing.T) {
- owner := WorkspaceOwner{
+ t.Parallel()
+
+ owner := types.WorkspaceOwner{
ID: "f6457744-3e16-45b2-b3b0-80c2df491c99",
Name: "Nissa",
FullName: "Nissa, Worldwaker",
@@ -15,7 +19,7 @@ func TestToCtyValue(t *testing.T) {
SSHPublicKey: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBSHXs/HCgZlpEBOXLvLw4KaOrhy1DM1Vw6M/HPVE/UA\n",
Groups: []string{"Everyone", "Planeswalkers", "Green"},
LoginType: "password",
- RBACRoles: []WorkspaceOwnerRBACRole{
+ RBACRoles: []types.WorkspaceOwnerRBACRole{
{Name: "User Admin"},
{Name: "Organization User Admin", OrgID: "5af9253a-ecde-4a71-b8f5-c8d15be9e52b"},
},
@@ -38,7 +42,9 @@ func TestToCtyValue(t *testing.T) {
}
func TestToCtyValueWithNilLists(t *testing.T) {
- owner := WorkspaceOwner{
+ t.Parallel()
+
+ owner := types.WorkspaceOwner{
ID: "f6457744-3e16-45b2-b3b0-80c2df491c99",
Name: "Nissa",
FullName: "Nissa, Worldwaker",
diff --git a/types/parameter.go b/types/parameter.go
index 6f58ff2..d5fbc67 100644
--- a/types/parameter.go
+++ b/types/parameter.go
@@ -90,7 +90,7 @@ func (v ParameterValidation) Valid(typ string, value string) error {
Monotonic: orZero(v.Monotonic),
Regex: orZero(v.Regex),
Error: v.Error,
- }).Valid(provider.OptionType(typ), value)
+ }).Valid(typ, value)
}
type ParameterOption struct {
diff --git a/types/primitive.go b/types/primitive.go
index ae81652..8f74317 100644
--- a/types/primitive.go
+++ b/types/primitive.go
@@ -7,6 +7,14 @@ import (
"github.com/zclconf/go-cty/cty"
)
+func CtyValueStringDefault(def string, val cty.Value) string {
+ str, err := CtyValueString(val)
+ if err != nil {
+ return def
+ }
+ return str
+}
+
// CtyValueString converts a cty.Value to a string.
// It supports only primitive types - bool, number, and string.
// As a special case, it also supports map[string]interface{} with key "value".
@@ -42,12 +50,12 @@ func CtyValueString(val cty.Value) (string, error) {
case cty.Bool:
if val.True() {
return "true", nil
- } else {
- return "false", nil
}
+ return "false", nil
case cty.Number:
return val.AsBigFloat().String(), nil
case cty.String:
+ //nolint:gocritic // string type asserted above
return val.AsString(), nil
// We may also have a map[string]interface{} with key "value".
case cty.Map(cty.String):
diff --git a/types/tags.go b/types/tags.go
index b4cb487..5fadebc 100644
--- a/types/tags.go
+++ b/types/tags.go
@@ -87,7 +87,7 @@ func (t Tag) KeyString() string {
return t.Key.AsString()
}
-func (t Tag) AsStrings() (string, string) {
+func (t Tag) AsStrings() (key string, value string) {
return t.KeyString(), t.Value.AsString()
}
diff --git a/types/value.go b/types/value.go
index 4cc269b..37f862b 100644
--- a/types/value.go
+++ b/types/value.go
@@ -80,6 +80,7 @@ func (s HCLString) AsString() string {
if s.Valid() && s.Value.IsKnown() {
switch {
case s.Value.Type().Equals(cty.String):
+ //nolint:gocritic // string type asserted
return s.Value.AsString()
case s.Value.Type().Equals(cty.Number):
// TODO: Float vs Int?
diff --git a/types/value_test.go b/types/value_test.go
index 099b0bd..fd904d6 100644
--- a/types/value_test.go
+++ b/types/value_test.go
@@ -82,6 +82,8 @@ func TestSafeHCLString(t *testing.T) {
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
+ t.Parallel()
+
require.Equal(t, tc.asString, tc.input.AsString())
require.Equal(t, tc.known, tc.input.IsKnown(), "known")
require.Equal(t, tc.valid, tc.input.Valid(), "valid")
diff --git a/web/websocket.go b/web/websocket.go
index a949199..d0ec8ce 100644
--- a/web/websocket.go
+++ b/web/websocket.go
@@ -25,7 +25,6 @@ func (s *Session) Listen(ctx context.Context, conn *websocket.Conn) {
// Always close the connection at the end of the Listen.
defer conn.Close(websocket.StatusNormalClosure, "closing connection")
<-ctx.Done()
- return
}
func (s *Session) readLoop(ctx context.Context, cancel func(), conn *websocket.Conn) {
diff --git a/workspacetags.go b/workspacetags.go
index 8f7702b..d3f6c76 100644
--- a/workspacetags.go
+++ b/workspacetags.go
@@ -47,8 +47,8 @@ func workspaceTags(modules terraform.Modules, files map[string]*hcl.File) (types
continue
}
- //tagsObj, ok := tagsAttr.HCLAttribute().Expr.(*hclsyntax.ObjectConsExpr)
- //if !ok {
+ // tagsObj, ok := tagsAttr.HCLAttribute().Expr.(*hclsyntax.ObjectConsExpr)
+ // if !ok {
// diags = diags.Append(&hcl.Diagnostic{
// Severity: hcl.DiagError,
// Summary: "Incorrect type for \"tags\" attribute",
@@ -75,7 +75,7 @@ func workspaceTags(modules terraform.Modules, files map[string]*hcl.File) (types
return false
})
- //for _, item := range tagsObj.Items {
+ // for _, item := range tagsObj.Items {
// tag, tagDiag := newTag(tagsObj, files, item, evCtx)
// if tagDiag != nil {
// diags = diags.Append(tagDiag)
@@ -95,16 +95,16 @@ func workspaceTags(modules terraform.Modules, files map[string]*hcl.File) (types
}
// newTag creates a workspace tag from its hcl expression.
-func newTag(srcRange *hcl.Range, files map[string]*hcl.File, key, val cty.Value) (types.Tag, *hcl.Diagnostic) {
- //key, kdiags := expr.KeyExpr.Value(evCtx)
- //val, vdiags := expr.ValueExpr.Value(evCtx)
+func newTag(srcRange *hcl.Range, _ map[string]*hcl.File, key, val cty.Value) (types.Tag, *hcl.Diagnostic) {
+ // key, kdiags := expr.KeyExpr.Value(evCtx)
+ // val, vdiags := expr.ValueExpr.Value(evCtx)
// TODO: ???
- //if kdiags.HasErrors() {
+ // if kdiags.HasErrors() {
// key = cty.UnknownVal(cty.String)
//}
- //if vdiags.HasErrors() {
+ // if vdiags.HasErrors() {
// val = cty.UnknownVal(cty.String)
//}
@@ -125,7 +125,7 @@ func newTag(srcRange *hcl.Range, files map[string]*hcl.File, key, val cty.Value)
if !val.Type().Equals(cty.NilType) {
fr = val.Type().FriendlyName()
}
- //r := expr.ValueExpr.Range()
+ // r := expr.ValueExpr.Range()
return types.Tag{}, &hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: "Invalid value type for tag",
@@ -150,14 +150,14 @@ func newTag(srcRange *hcl.Range, files map[string]*hcl.File, key, val cty.Value)
},
}
- //ks, err := source(expr.KeyExpr.Range(), files)
- //if err == nil {
+ // ks, err := source(expr.KeyExpr.Range(), files)
+ // if err == nil {
// src := string(ks)
// tag.Key.Source = &src
//}
//
- //vs, err := source(expr.ValueExpr.Range(), files)
- //if err == nil {
+ // vs, err := source(expr.ValueExpr.Range(), files)
+ // if err == nil {
// src := string(vs)
// tag.Value.Source = &src
//}