Skip to content

WIP: SC2016: for yq, only warn about undeclared $variables - #1

Draft
gkrimer wants to merge 2 commits into
masterfrom
sc2016-yq-undeclared-vars
Draft

gkrimer wants to merge 2 commits into
masterfrom
sc2016-yq-undeclared-vars

Conversation

@gkrimer

@gkrimer gkrimer commented Sep 29, 2026

Copy link
Copy Markdown
Owner

WIP, not submitted upstream. Alternative to / follow-up for koalaman#3541, which exempts yq from SC2016 entirely (same as jq).

A single-quoted $name in a yq expression is either a yq variable (.a as $id | $id) or a shell variable the user expected to expand ('.x = "$VAR"'). mikefarah/yq variables only exist if the expression declares them, and an undeclared one is silently null:

❯ VAR=v1 yq '.x = $VAR' v.yaml; echo "exit=$?"
...
x: null
exit=0

So instead of exempting yq, warn only on $names the command doesn't declare with as $name / ref $name, or pass with --arg/--argjson (kislyuk/yq). Other $ forms (${...}, $(...), $1) still warn. Declarations are collected across all single-quoted parts of the command, so a spliced value ('a as $x | '"$shell"' | $x') doesn't break it.

Line koalaman#3541 This
yq '.metadata.name as $id | $id' deployment.yaml quiet quiet
yq -i '.a ref $r | $r = 1' f.yaml quiet quiet
yq '.x = "$VAR"' f.yaml quiet SC2016
yq '.x = $VAR' f.yaml quiet SC2016
yq '.a' '$HOME/f.yaml' quiet SC2016

Testing

  • Tests prop_checkSingleQuotedVariables26–37; cabal test passes.
  • Mutation tested; each mutant fails exactly the tests meant to catch it:
    M1 no yq branch (old behavior):        ...26, 27, 28, 29, 30, 37
    M2 blanket exemption:                  ...31, 32, 33, 34, 35, 36
    M3 no ref:                             ...28
    M4 ignore --arg:                       ...29
    M5 no word boundary:                   ...34
    M6 ignore non-variable $ forms:        ...35
    M7 declarations from this piece only:  ...37
    
  • End to end, --norc on instrumentl/ai-service deploy/tests/*.sh: 0 SC2016 (0.11.0 reports 8).

Open questions

  • Declarations count across the whole command, so $x declared in one argument allows $x in another.
  • kislyuk/yq jq built-ins ($ENV, $__loc__) and destructuring (. as {"a": $x}) still warn, same as today.
  • Message still says "use double quotes"; for yq strenv() is the right advice.
  • Same logic could replace jq's blanket exemption (-- could also check that user provides --arg), but that changes existing behavior.

Written by Claude on behalf of @gkrimer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant