Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bash environment variable expansion not working for trivy #638

Closed
aaronmell opened this issue Feb 26, 2024 · 26 comments · Fixed by #645
Closed

Bash environment variable expansion not working for trivy #638

aaronmell opened this issue Feb 26, 2024 · 26 comments · Fixed by #645
Assignees
Labels

Comments

@aaronmell
Copy link

Describe the bug

I have the following pre-commit

    - id: terraform_trivy
      args:
        - --args=--config-policy="/Users/${USER}/PATH_TO_CUSTOM_POLICY/"

How can we reproduce it?

Running the pre-commit from above returns the following

2024-02-26T15:39:31.418-0500	FATAL	filesystem scan error: scan error: unable to initialize a scanner: unable to initialize a filesystem scanner: analyzer group error: post-analyzer init error: filesystem scanner init error: policy file "/Users/${USER}/PATH_TO_CUSTOM_POLICY" not found

If I replace ${USER} with my username it works fine

Environment information

  • OS:
    MacOS: Latest Darwin ARM

  • Tools availability and versions:

pre-commit 3.6.2
trivy Version: 0.49.1
  • .pre-commit-config.yaml:
file content
- repo: https://github.com/antonbabenko/pre-commit-terraform
  rev: v1.88.0
  hooks:
    - id: terraform_trivy
      args:
        - --args=--config-policy="/Users/${USER}/PATH_TO_CUSTOM_POLICY/"
@aaronmell aaronmell added area/local_installation bug Something isn't working labels Feb 26, 2024
@MaxymVlasov
Copy link
Collaborator

MaxymVlasov commented Mar 5, 2024

Are you sure that you have exported USER env var in the same shell where pre-commit is running?

Tested on rev: v1.88.0 && pre-commit 3.6.2

image

@yermulnik
Copy link
Collaborator

USER env var is set by login (e.g. see this answer: https://unix.stackexchange.com/a/76356/74805). Behavior may differ on macOS though, depending on user shell interpreter and other bits of user's environment.

I couldn't reproduce issue as well, though I'm on Linux and have no macOS to try and validate.

@MaxymVlasov What confused me was that the var didn't get expanded at all and passed through unchanged, which is unexpected and looks to be what can't happen 😲 This is an excerpt from the author's message:

policy file "/Users/${USER}/PATH_TO_CUSTOM_POLICY" not found

I have no clue what might went wrong on @aaronmell end 🤷🏻

@aaronmell
Copy link
Author

Im my case neither method worked. I tried explicitly setting it to a value with no success,

@aaronmell
Copy link
Author

Okay, so I eliminated the shells scripts as being the issue, I pulled the repo, and ran the script manually, and it worked as expected. Its only failing when I run pre-commit

@aaronmell
Copy link
Author

I was able to simplify my issue. If I run the script through python with the following commands

import subprocess
result = subprocess.run(['./terraform_trivy.sh', 'main', '--args=--config-policy="/Users/${USER}/PATH_TO_CUSTOM_POLICY/"'])

I get the same issue

If I add

echo ${USER}

to the top of a script I get the correct username.
Looking at the output with -x added and I see ${USER} in the args, and never MY_USERNAME, so somehow the expansion is failing silently.

I updated bash to the latest version on my mac, just to make sure that wasn't the cause, and same issue.

@yermulnik
Copy link
Collaborator

> git clone [email protected]:antonbabenko/pre-commit-terraform.git
Cloning into 'pre-commit-terraform'...
remote: Enumerating objects: 2163, done.
remote: Counting objects: 100% (890/890), done.
remote: Compressing objects: 100% (269/269), done.
remote: Total 2163 (delta 810), reused 654 (delta 621), pack-reused 1273
Receiving objects: 100% (2163/2163), 626.91 KiB | 873.00 KiB/s, done.
Resolving deltas: 100% (1477/1477), done.

> cd ./pre-commit-terraform/hooks/
> vim terraform_trivy.sh # edit to not actually run trivy but to only debug
> git diff
diff --git a/hooks/terraform_trivy.sh b/hooks/terraform_trivy.sh
index fd9a320..7a4af9a 100755
--- a/hooks/terraform_trivy.sh
+++ b/hooks/terraform_trivy.sh
@@ -17,7 +17,7 @@ function main {
     ARGS[i]=${ARGS[i]/__GIT_WORKING_DIR__/$(pwd)\/}
   done

-  common::per_dir_hook "$HOOK_ID" "${#ARGS[@]}" "${ARGS[@]}" "${FILES[@]}"
+  echo common::per_dir_hook "$HOOK_ID" "${#ARGS[@]}" "${ARGS[@]}" "${FILES[@]}"
 }

 #######################################################################

> # Notice the cmdline arg is wrapped into single quote to prevent var expansion for the sake of testing
> ./terraform_trivy.sh '--args=--config-policy="/Users/${USER}/PATH_TO_CUSTOM_POLICY/"'
Found ${USER} in:        '--config-policy=/Users/${USER}/PATH_TO_CUSTOM_POLICY/'
After ${USER} expansion: '--config-policy=/Users/giermulnik/PATH_TO_CUSTOM_POLICY/'

common::per_dir_hook terraform_trivy 1 --config-policy=/Users/giermulnik/PATH_TO_CUSTOM_POLICY/

> # Same thing with single quotes around starting here-doc marker: prevent shell var expansion
> python3 <<'EOF'
import subprocess
result = subprocess.run(['./terraform_trivy.sh', '--args=--config-policy="/Users/${USER}/PATH_TO_CUSTOM_POLICY/"'])
EOF
Found ${USER} in:        '--config-policy=/Users/${USER}/PATH_TO_CUSTOM_POLICY/'
After ${USER} expansion: '--config-policy=/Users/giermulnik/PATH_TO_CUSTOM_POLICY/'

common::per_dir_hook terraform_trivy 1 --config-policy=/Users/giermulnik/PATH_TO_CUSTOM_POLICY/

I cannot reproduce on Linux 🤷🏻

@MaxymVlasov
Copy link
Collaborator

MaxymVlasov commented Mar 7, 2024

@aaronmell please set .pre-commit-config.yaml to

repos:
- repo: https://github.com/antonbabenko/pre-commit-terraform
  rev: 919a99b176f93c83e95e67a071569e75cb2698f7
  hooks:
    - id: terraform_trivy
      args:
        - --args=--config-policy="/Users/${USER}/PATH_TO_CUSTOM_POLICY/"
      verbose: true

Run

PCT_LOG=trace  pre-commit run -a

and send the full output here with

<details><summary>Trace logs</summary>

```
INSERT OUTPUT HERE
```

</details>

@yermulnik
Copy link
Collaborator

@MaxymVlasov Are you sure about single quotes echo "BASH path: '$BASH'"? They prevent expansion.

@MaxymVlasov
Copy link
Collaborator

@yermulnik yes, as ' does not prevent anything, it's just a symbol inside string defined by ""

@yermulnik
Copy link
Collaborator

@yermulnik yes, as ' does not prevent anything, it's just a symbol inside string defined by ""

Oops, my bad, I missed that single quotes don't prevent expansion when used like that. TIL =)

@aaronmell
Copy link
Author

Terraform validate with trivy............................................�[41mFailed�[m
�[2m- hook id: terraform_trivy�[m
�[2m- duration: 0.46s�[m
�[2m- exit code: 1�[m

BASH path: '/opt/homebrew/bin/bash'
BASH_VERSION: 5.2.26(1)-release
BASHOPTS: checkwinsize:cmdhist:complete_fullquote:extquote:force_fignore:globasciiranges:globskipdots:hostcomplete:interactive_comments:patsub_replacement:progcomp:promptvars:sourcepath
OSTYPE: darwin23.2.0
��[2m
trace: 
       _common.sh:23: �[0mHOOK_ID=terraform_trivy.sh
��[2m
trace: 
       _common.sh:24: �[0mreadonly HOOK_ID=terraform_trivy
��[2m
trace: 
       _common.sh:24: �[0mHOOK_ID=terraform_trivy
�[2m
trace: 
       terraform_trivy.sh:72: �[0m'[' /Users/amell/.cache/pre-commit/repoqvxc_9u4/hooks/terraform_trivy.sh '!=' /Users/amell/.cache/pre-commit/repoqvxc_9u4/hooks/terraform_trivy.sh ']'
�[2m
trace: 
       terraform_trivy.sh:72: �[0mmain '--args=--config-policy="/Users/${USER}/PATH_TO_CUSTOM_POLICY/"' main.tf providers.tf
�[2m
trace: main main
       terraform_trivy.sh:11: �[0mcommon::initialize /Users/amell/.cache/pre-commit/repoqvxc_9u4/hooks
�[2m
trace: common::initialize main main
       _common.sh:32: �[0mlocal -r script_dir=/Users/amell/.cache/pre-commit/repoqvxc_9u4/hooks
�[2m
trace: common::initialize main main
       _common.sh:35: �[0m. /Users/amell/.cache/pre-commit/repoqvxc_9u4/hooks/../lib_getopt
�[2m
trace: main main
       terraform_trivy.sh:12: �[0mcommon::parse_cmdline '--args=--config-policy="/Users/${USER}/PATH_TO_CUSTOM_POLICY/"' main.tf providers.tf
�[2m
trace: common::parse_cmdline main main
       _common.sh:55: �[0mARGS=()
�[2m
trace: common::parse_cmdline main main
       _common.sh:55: �[0mHOOK_CONFIG=()
�[2m
trace: common::parse_cmdline main main
       _common.sh:55: �[0mFILES=()
�[2m
trace: common::parse_cmdline main main
       _common.sh:57: �[0mTF_INIT_ARGS=()
�[2m
trace: common::parse_cmdline main main
       _common.sh:59: �[0mENV_VARS=()
�[2m
trace: common::parse_cmdline main main
       _common.sh:61: �[0mlocal argv
��[2m
trace: common::parse_cmdline main main
       _common.sh:63: �[0mgetopt -o a:,h:,i:,e: --long args:,hook-config:,init-args:,tf-init-args:,envs:,env-vars: -- '--args=--config-policy="/Users/${USER}/PATH_TO_CUSTOM_POLICY/"' main.tf providers.tf
��[2m
trace: getopt common::parse_cmdline main main
       lib_getopt:485: �[0m_getopt_version_check
��[2m
trace: _getopt_version_check getopt common::parse_cmdline main main
       lib_getopt:471: �[0m[[ -z 5.2.26(1)-release ]]
��[2m
trace: _getopt_version_check getopt common::parse_cmdline main main
       lib_getopt:477: �[0m[[ 5.2.26(1)-release < 2.05b ]]
��[2m
trace: _getopt_version_check getopt common::parse_cmdline main main
       lib_getopt:482: �[0mreturn 0
��[2m
trace: getopt common::parse_cmdline main main
       lib_getopt:486: �[0m_getopt_main -o a:,h:,i:,e: --long args:,hook-config:,init-args:,tf-init-args:,envs:,env-vars: -- '--args=--config-policy="/Users/${USER}/PATH_TO_CUSTOM_POLICY/"' main.tf providers.tf
��[2m
trace: _getopt_main getopt common::parse_cmdline main main
       lib_getopt:39: �[0mdeclare parsed status
��[2m
trace: _getopt_main getopt common::parse_cmdline main main
       lib_getopt:40: �[0mdeclare short long= name flags=
��[2m
trace: _getopt_main getopt common::parse_cmdline main main
       lib_getopt:41: �[0mdeclare have_short=false
��[2m
trace: _getopt_main getopt common::parse_cmdline main main
       lib_getopt:53: �[0m[[ -n '' ]]
��[2m
trace: _getopt_main getopt common::parse_cmdline main main
       lib_getopt:53: �[0m[[ -o == [^-]* ]]
���[2m
trace: _getopt_main getopt common::parse_cmdline main main
       lib_getopt:64: �[0m_getopt_parse getopt ahl:n:o:qQs:TuV alternative,help,longoptions:,name:,options:,quiet,quiet-output,shell:,test,version p -o a:,h:,i:,e: --long args:,hook-config:,init-args:,tf-init-args:,envs:,env-vars: -- '--args=--config-policy="/Users/${USER}/PATH_TO_CUSTOM_POLICY/"' main.tf providers.tf
���[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:184: �[0mdeclare name=getopt short=ahl:n:o:qQs:TuV long=alternative,help,longoptions:,name:,options:,quiet,quiet-output,shell:,test,version flags=p
���[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:185: �[0mshift 4
���[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:189: �[0mdeclare -a longarr
���[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:190: �[0m_getopt_split longarr alternative,help,longoptions:,name:,options:,quiet,quiet-output,shell:,test,version
���[2m
trace: _getopt_split _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:407: �[0mdeclare IFS=,
���[2m
trace: _getopt_split,_getopt_parse,_getopt_main,getopt,common::parse_cmdline,main,main
       lib_getopt:408: �[0meval 'longarr=( $2 )'
����[2m
trace: _getopt_split,_getopt_parse,_getopt_main,getopt,common::parse_cmdline,main,main
       lib_getopt:408: �[0mlongarr=($2)
���[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:191: �[0mlongarr=("${longarr[@]/#/--}")
���[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:192: �[0mlongarr=("${longarr[@]%:}")
���[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:193: �[0mlongarr=("${longarr[@]%:}")
���[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:196: �[0mdeclare -a opts params
���[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:197: �[0mdeclare o alt_recycled=false error=0
���[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:199: �[0m[[ 8 -gt 0 ]]
���[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:200: �[0mcase $1 in
���[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:249: �[0m[[ p == *a* ]]
���[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:284: �[0mo=-o
���[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:285: �[0m[[ ahl:n:o:qQs:TuV == *\o::* ]]
���[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:291: �[0m[[ ahl:n:o:qQs:TuV == *\o:* ]]
���[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:292: �[0m[[ 2 -gt 2 ]]
���[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:294: �[0m[[ 8 -ge 2 ]]
���[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:295: �[0mshift
���[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:296: �[0mopts=("${opts[@]}" "$o" "$1")
���[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:334: �[0mshift
���[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:199: �[0m[[ 6 -gt 0 ]]
���[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:200: �[0mcase $1 in
���[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:225: �[0mo=--long
����[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:226: �[0m_getopt_resolve_abbrev --long --alternative --help --longoptions --name --options --quiet --quiet-output --shell --test --version
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:369: �[0mdeclare a q=--long
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:370: �[0mmatches=()
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:370: �[0mdeclare -a matches
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:371: �[0mshift
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:372: �[0mfor a in "$@"
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:373: �[0m[[ --long == \-\-\a\l\t\e\r\n\a\t\i\v\e ]]
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:377: �[0m[[ p == *a* ]]
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:381: �[0m[[ --alternative == \-\-\l\o\n\g* ]]
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:384: �[0m[[ p == *a* ]]
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:372: �[0mfor a in "$@"
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:373: �[0m[[ --long == \-\-\h\e\l\p ]]
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:377: �[0m[[ p == *a* ]]
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:381: �[0m[[ --help == \-\-\l\o\n\g* ]]
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:384: �[0m[[ p == *a* ]]
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:372: �[0mfor a in "$@"
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:373: �[0m[[ --long == \-\-\l\o\n\g\o\p\t\i\o\n\s ]]
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:377: �[0m[[ p == *a* ]]
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:381: �[0m[[ --longoptions == \-\-\l\o\n\g* ]]
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:383: �[0mmatches=("${matches[@]}" "$a")
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:372: �[0mfor a in "$@"
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:373: �[0m[[ --long == \-\-\n\a\m\e ]]
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:377: �[0m[[ p == *a* ]]
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:381: �[0m[[ --name == \-\-\l\o\n\g* ]]
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:384: �[0m[[ p == *a* ]]
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:372: �[0mfor a in "$@"
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:373: �[0m[[ --long == \-\-\o\p\t\i\o\n\s ]]
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:377: �[0m[[ p == *a* ]]
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:381: �[0m[[ --options == \-\-\l\o\n\g* ]]
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:384: �[0m[[ p == *a* ]]
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:372: �[0mfor a in "$@"
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:373: �[0m[[ --long == \-\-\q\u\i\e\t ]]
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:377: �[0m[[ p == *a* ]]
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:381: �[0m[[ --quiet == \-\-\l\o\n\g* ]]
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:384: �[0m[[ p == *a* ]]
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:372: �[0mfor a in "$@"
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:373: �[0m[[ --long == \-\-\q\u\i\e\t\-\o\u\t\p\u\t ]]
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:377: �[0m[[ p == *a* ]]
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:381: �[0m[[ --quiet-output == \-\-\l\o\n\g* ]]
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:384: �[0m[[ p == *a* ]]
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:372: �[0mfor a in "$@"
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:373: �[0m[[ --long == \-\-\s\h\e\l\l ]]
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:377: �[0m[[ p == *a* ]]
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:381: �[0m[[ --shell == \-\-\l\o\n\g* ]]
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:384: �[0m[[ p == *a* ]]
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:372: �[0mfor a in "$@"
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:373: �[0m[[ --long == \-\-\t\e\s\t ]]
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:377: �[0m[[ p == *a* ]]
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:381: �[0m[[ --test == \-\-\l\o\n\g* ]]
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:384: �[0m[[ p == *a* ]]
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:372: �[0mfor a in "$@"
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:373: �[0m[[ --long == \-\-\v\e\r\s\i\o\n ]]
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:377: �[0m[[ p == *a* ]]
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:381: �[0m[[ --version == \-\-\l\o\n\g* ]]
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:384: �[0m[[ p == *a* ]]
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:389: �[0mcase ${#matches[@]} in
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:396: �[0mprintf %s --longoptions
����[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:396: �[0mreturn 0
���[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:226: �[0mo=--longoptions
���[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:228: �[0m[[ ,alternative,help,longoptions:,name:,options:,quiet,quiet-output,shell:,test,version, == *,\l\o\n\g\o\p\t\i\o\n\s,* ]]
���[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:230: �[0m[[ ,alternative,help,longoptions:,name:,options:,quiet,quiet-output,shell:,test,version, == *,\l\o\n\g\o\p\t\i\o\n\s\:\:,* ]]
���[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:232: �[0m[[ ,alternative,help,longoptions:,name:,options:,quiet,quiet-output,shell:,test,version, == *,\l\o\n\g\o\p\t\i\o\n\s\:,* ]]
���[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:233: �[0m[[ 6 -ge 2 ]]
���[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:234: �[0mshift
���[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:235: �[0mopts=("${opts[@]}" "$o" "$1")
���[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:245: �[0malt_recycled=false
���[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:334: �[0mshift
���[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:199: �[0m[[ 4 -gt 0 ]]
���[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:200: �[0mcase $1 in
���[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:202: �[0mparams=("${params[@]}" "${@:2}")
���[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:203: �[0mbreak
���[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:337: �[0m[[ p == *Q* ]]
���[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:340: �[0mecho -n ' '
���[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:341: �[0m[[ p == *[cu]* ]]
���[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:344: �[0m[[ p == *t* ]]
���[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:347: �[0m_getopt_quote -o a:,h:,i:,e: --longoptions args:,hook-config:,init-args:,tf-init-args:,envs:,env-vars: -- '--args=--config-policy="/Users/${USER}/PATH_TO_CUSTOM_POLICY/"' main.tf providers.tf
���[2m
trace: _getopt_quote _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:413: �[0mdeclare s space= 'q='\'''
���[2m
trace: _getopt_quote _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:414: �[0mfor s in "$@"
���[2m
trace: _getopt_quote _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:415: �[0mprintf ''\''%s'\''' -o
���[2m
trace: _getopt_quote _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:416: �[0mspace=' '
���[2m
trace: _getopt_quote _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:414: �[0mfor s in "$@"
���[2m
trace: _getopt_quote _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:415: �[0mprintf ' '\''%s'\''' a:,h:,i:,e:
���[2m
trace: _getopt_quote _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:416: �[0mspace=' '
���[2m
trace: _getopt_quote _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:414: �[0mfor s in "$@"
���[2m
trace: _getopt_quote _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:415: �[0mprintf ' '\''%s'\''' --longoptions
���[2m
trace: _getopt_quote _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:416: �[0mspace=' '
���[2m
trace: _getopt_quote _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:414: �[0mfor s in "$@"
���[2m
trace: _getopt_quote _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:415: �[0mprintf ' '\''%s'\''' args:,hook-config:,init-args:,tf-init-args:,envs:,env-vars:
���[2m
trace: _getopt_quote _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:416: �[0mspace=' '
���[2m
trace: _getopt_quote _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:414: �[0mfor s in "$@"
���[2m
trace: _getopt_quote _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:415: �[0mprintf ' '\''%s'\''' --
���[2m
trace: _getopt_quote _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:416: �[0mspace=' '
���[2m
trace: _getopt_quote _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:414: �[0mfor s in "$@"
���[2m
trace: _getopt_quote _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:415: �[0mprintf ' '\''%s'\''' '--args=--config-policy="/Users/${USER}/PATH_TO_CUSTOM_POLICY/"'
���[2m
trace: _getopt_quote _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:416: �[0mspace=' '
���[2m
trace: _getopt_quote _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:414: �[0mfor s in "$@"
���[2m
trace: _getopt_quote _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:415: �[0mprintf ' '\''%s'\''' main.tf
���[2m
trace: _getopt_quote _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:416: �[0mspace=' '
���[2m
trace: _getopt_quote _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:414: �[0mfor s in "$@"
���[2m
trace: _getopt_quote _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:415: �[0mprintf ' '\''%s'\''' providers.tf
���[2m
trace: _getopt_quote _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:416: �[0mspace=' '
���[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:350: �[0mecho
���[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:353: �[0mreturn 0
��[2m
trace: _getopt_main getopt common::parse_cmdline main main
       lib_getopt:64: �[0mparsed=' '\''-o'\'' '\''a:,h:,i:,e:'\'' '\''--longoptions'\'' '\''args:,hook-config:,init-args:,tf-init-args:,envs:,env-vars:'\'' '\''--'\'' '\''--args=--config-policy="/Users/${USER}/PATH_TO_CUSTOM_POLICY/"'\'' '\''main.tf'\'' '\''providers.tf'\'''
��[2m
trace: _getopt_main getopt common::parse_cmdline main main
       lib_getopt:65: �[0mstatus=0
��[2m
trace: _getopt_main getopt common::parse_cmdline main main
       lib_getopt:66: �[0m[[ 0 != 0 ]]
��[2m
trace: _getopt_main getopt common::parse_cmdline main main
       lib_getopt:74: �[0meval 'set --  '\''-o'\'' '\''a:,h:,i:,e:'\'' '\''--longoptions'\'' '\''args:,hook-config:,init-args:,tf-init-args:,envs:,env-vars:'\'' '\''--'\'' '\''--args=--config-policy="/Users/${USER}/PATH_TO_CUSTOM_POLICY/"'\'' '\''main.tf'\'' '\''providers.tf'\'''
���[2m
trace: _getopt_main getopt common::parse_cmdline main main
       lib_getopt:74: �[0mset -- -o a:,h:,i:,e: --longoptions args:,hook-config:,init-args:,tf-init-args:,envs:,env-vars: -- '--args=--config-policy="/Users/${USER}/PATH_TO_CUSTOM_POLICY/"' main.tf providers.tf
��[2m
trace: _getopt_main getopt common::parse_cmdline main main
       lib_getopt:76: �[0m[[ 8 -gt 0 ]]
��[2m
trace: _getopt_main getopt common::parse_cmdline main main
       lib_getopt:77: �[0mcase $1 in
��[2m
trace: _getopt_main getopt common::parse_cmdline main main
       lib_getopt:95: �[0mshort=a:,h:,i:,e:
��[2m
trace: _getopt_main getopt common::parse_cmdline main main
       lib_getopt:96: �[0mhave_short=true
��[2m
trace: _getopt_main getopt common::parse_cmdline main main
       lib_getopt:97: �[0mshift
��[2m
trace: _getopt_main getopt common::parse_cmdline main main
       lib_getopt:133: �[0mshift
��[2m
trace: _getopt_main getopt common::parse_cmdline main main
       lib_getopt:76: �[0m[[ 6 -gt 0 ]]
��[2m
trace: _getopt_main getopt common::parse_cmdline main main
       lib_getopt:77: �[0mcase $1 in
��[2m
trace: _getopt_main getopt common::parse_cmdline main main
       lib_getopt:87: �[0mlong=args:,hook-config:,init-args:,tf-init-args:,envs:,env-vars:
��[2m
trace: _getopt_main getopt common::parse_cmdline main main
       lib_getopt:88: �[0mshift
��[2m
trace: _getopt_main getopt common::parse_cmdline main main
       lib_getopt:133: �[0mshift
��[2m
trace: _getopt_main getopt common::parse_cmdline main main
       lib_getopt:76: �[0m[[ 4 -gt 0 ]]
��[2m
trace: _getopt_main getopt common::parse_cmdline main main
       lib_getopt:77: �[0mcase $1 in
��[2m
trace: _getopt_main getopt common::parse_cmdline main main
       lib_getopt:129: �[0mshift
��[2m
trace: _getopt_main getopt common::parse_cmdline main main
       lib_getopt:130: �[0mbreak
��[2m
trace: _getopt_main getopt common::parse_cmdline main main
       lib_getopt:136: �[0mtrue
��[2m
trace: _getopt_main getopt common::parse_cmdline main main
       lib_getopt:149: �[0m[[ a:,h:,i:,e: == -* ]]
��[2m
trace: _getopt_main getopt common::parse_cmdline main main
       lib_getopt:154: �[0m[[ a:,h:,i:,e: == +* ]]
��[2m
trace: _getopt_main getopt common::parse_cmdline main main
       lib_getopt:163: �[0mflags=
��[2m
trace: _getopt_main getopt common::parse_cmdline main main
       lib_getopt:165: �[0m_getopt_parse getopt a:,h:,i:,e: args:,hook-config:,init-args:,tf-init-args:,envs:,env-vars: '' '--args=--config-policy="/Users/${USER}/PATH_TO_CUSTOM_POLICY/"' main.tf providers.tf
��[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:184: �[0mdeclare name=getopt short=a:,h:,i:,e: long=args:,hook-config:,init-args:,tf-init-args:,envs:,env-vars: flags=
��[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:185: �[0mshift 4
��[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:189: �[0mdeclare -a longarr
��[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:190: �[0m_getopt_split longarr args:,hook-config:,init-args:,tf-init-args:,envs:,env-vars:
��[2m
trace: _getopt_split _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:407: �[0mdeclare IFS=,
��[2m
trace: _getopt_split,_getopt_parse,_getopt_main,getopt,common::parse_cmdline,main,main
       lib_getopt:408: �[0meval 'longarr=( $2 )'
���[2m
trace: _getopt_split,_getopt_parse,_getopt_main,getopt,common::parse_cmdline,main,main
       lib_getopt:408: �[0mlongarr=($2)
��[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:191: �[0mlongarr=("${longarr[@]/#/--}")
��[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:192: �[0mlongarr=("${longarr[@]%:}")
��[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:193: �[0mlongarr=("${longarr[@]%:}")
��[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:196: �[0mdeclare -a opts params
��[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:197: �[0mdeclare o alt_recycled=false error=0
��[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:199: �[0m[[ 3 -gt 0 ]]
��[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:200: �[0mcase $1 in
��[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:206: �[0mo=--args
���[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:207: �[0m_getopt_resolve_abbrev --args --args --hook-config --init-args --tf-init-args --envs --env-vars
���[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:369: �[0mdeclare a q=--args
���[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:370: �[0mmatches=()
���[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:370: �[0mdeclare -a matches
���[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:371: �[0mshift
���[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:372: �[0mfor a in "$@"
���[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:373: �[0m[[ --args == \-\-\a\r\g\s ]]
���[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:375: �[0mmatches=("$a")
���[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:376: �[0mbreak
���[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:389: �[0mcase ${#matches[@]} in
���[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:396: �[0mprintf %s --args
���[2m
trace: _getopt_resolve_abbrev _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:396: �[0mreturn 0
��[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:207: �[0mo=--args
��[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:209: �[0m[[ ,args:,hook-config:,init-args:,tf-init-args:,envs:,env-vars:, == *,\a\r\g\s::,* ]]
��[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:211: �[0m[[ ,args:,hook-config:,init-args:,tf-init-args:,envs:,env-vars:, == *,\a\r\g\s:,* ]]
��[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:212: �[0mopts=("${opts[@]}" "$o" "${1#*=}")
��[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:221: �[0malt_recycled=false
��[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:334: �[0mshift
��[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:199: �[0m[[ 2 -gt 0 ]]
��[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:200: �[0mcase $1 in
��[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:324: �[0m[[ '' == *i* ]]
��[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:326: �[0m[[ '' == *p* ]]
��[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:330: �[0mparams=("${params[@]}" "$1")
��[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:334: �[0mshift
��[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:199: �[0m[[ 1 -gt 0 ]]
��[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:200: �[0mcase $1 in
��[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:324: �[0m[[ '' == *i* ]]
��[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:326: �[0m[[ '' == *p* ]]
��[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:330: �[0mparams=("${params[@]}" "$1")
��[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:334: �[0mshift
��[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:199: �[0m[[ 0 -gt 0 ]]
��[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:337: �[0m[[ '' == *Q* ]]
��[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:340: �[0mecho -n ' '
��[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:341: �[0m[[ '' == *[cu]* ]]
��[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:344: �[0m[[ '' == *t* ]]
��[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:347: �[0m_getopt_quote --args '--config-policy="/Users/${USER}/PATH_TO_CUSTOM_POLICY/"' -- main.tf providers.tf
��[2m
trace: _getopt_quote _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:413: �[0mdeclare s space= 'q='\'''
��[2m
trace: _getopt_quote _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:414: �[0mfor s in "$@"
��[2m
trace: _getopt_quote _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:415: �[0mprintf ''\''%s'\''' --args
��[2m
trace: _getopt_quote _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:416: �[0mspace=' '
��[2m
trace: _getopt_quote _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:414: �[0mfor s in "$@"
��[2m
trace: _getopt_quote _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:415: �[0mprintf ' '\''%s'\''' '--config-policy="/Users/${USER}/PATH_TO_CUSTOM_POLICY/"'
��[2m
trace: _getopt_quote _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:416: �[0mspace=' '
��[2m
trace: _getopt_quote _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:414: �[0mfor s in "$@"
��[2m
trace: _getopt_quote _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:415: �[0mprintf ' '\''%s'\''' --
��[2m
trace: _getopt_quote _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:416: �[0mspace=' '
��[2m
trace: _getopt_quote _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:414: �[0mfor s in "$@"
��[2m
trace: _getopt_quote _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:415: �[0mprintf ' '\''%s'\''' main.tf
��[2m
trace: _getopt_quote _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:416: �[0mspace=' '
��[2m
trace: _getopt_quote _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:414: �[0mfor s in "$@"
��[2m
trace: _getopt_quote _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:415: �[0mprintf ' '\''%s'\''' providers.tf
��[2m
trace: _getopt_quote _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:416: �[0mspace=' '
��[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:350: �[0mecho
��[2m
trace: _getopt_parse _getopt_main getopt common::parse_cmdline main main
       lib_getopt:353: �[0mreturn 0
��[2m
trace: getopt common::parse_cmdline main main
       lib_getopt:487: �[0mdeclare status=0
��[2m
trace: getopt common::parse_cmdline main main
       lib_getopt:488: �[0munset -f _getopt_main _getopt_err _getopt_parse _getopt_quote _getopt_quote_csh _getopt_resolve_abbrev _getopt_split _getopt_help _getopt_version_check
��[2m
trace: getopt common::parse_cmdline main main
       lib_getopt:491: �[0mreturn 0
�[2m
trace: common::parse_cmdline main main
       _common.sh:63: �[0margv=' '\''--args'\'' '\''--config-policy="/Users/${USER}/PATH_TO_CUSTOM_POLICY/"'\'' '\''--'\'' '\''main.tf'\'' '\''providers.tf'\'''
�[2m
trace: common::parse_cmdline main main
       _common.sh:64: �[0meval 'set --  '\''--args'\'' '\''--config-policy="/Users/${USER}/PATH_TO_CUSTOM_POLICY/"'\'' '\''--'\'' '\''main.tf'\'' '\''providers.tf'\'''
��[2m
trace: common::parse_cmdline main main
       _common.sh:64: �[0mset -- --args '--config-policy="/Users/${USER}/PATH_TO_CUSTOM_POLICY/"' -- main.tf providers.tf
�[2m
trace: common::parse_cmdline main main
       _common.sh:66: �[0mfor argv in "$@"
�[2m
trace: common::parse_cmdline main main
       _common.sh:67: �[0mcase $argv in
�[2m
trace: common::parse_cmdline main main
       _common.sh:69: �[0mshift
�[2m
trace: common::parse_cmdline main main
       _common.sh:83: �[0mread -r -d '' ARG
��[2m
trace: common::parse_cmdline main main
       _common.sh:67: �[0mecho '--config-policy="/Users/${USER}/PATH_TO_CUSTOM_POLICY/"'
��[2m
trace: common::parse_cmdline main main
       _common.sh:67: �[0mxargs printf '%s\0'
�[2m
trace: common::parse_cmdline main main
       _common.sh:84: �[0mARGS+=("$ARG")
�[2m
trace: common::parse_cmdline main main
       _common.sh:83: �[0mread -r -d '' ARG
�[2m
trace: common::parse_cmdline main main
       _common.sh:86: �[0mshift
�[2m
trace: common::parse_cmdline main main
       _common.sh:66: �[0mfor argv in "$@"
�[2m
trace: common::parse_cmdline main main
       _common.sh:67: �[0mcase $argv in
�[2m
trace: common::parse_cmdline main main
       _common.sh:66: �[0mfor argv in "$@"
�[2m
trace: common::parse_cmdline main main
       _common.sh:67: �[0mcase $argv in
�[2m
trace: common::parse_cmdline main main
       _common.sh:106: �[0mshift
�[2m
trace: common::parse_cmdline main main
       _common.sh:108: �[0mFILES=("$@")
�[2m
trace: common::parse_cmdline main main
       _common.sh:109: �[0mbreak
�[2m
trace: main main
       terraform_trivy.sh:13: �[0mcommon::export_provided_env_vars
�[2m
trace: common::export_provided_env_vars main main
       _common.sh:521: �[0menv_vars=()
�[2m
trace: common::export_provided_env_vars main main
       _common.sh:521: �[0mlocal -a -r env_vars
�[2m
trace: common::export_provided_env_vars main main
       _common.sh:523: �[0mlocal var
�[2m
trace: common::export_provided_env_vars main main
       _common.sh:524: �[0mlocal var_name
�[2m
trace: common::export_provided_env_vars main main
       _common.sh:525: �[0mlocal var_value
�[2m
trace: main main
       terraform_trivy.sh:14: �[0mcommon::parse_and_export_env_vars
�[2m
trace: common::parse_and_export_env_vars main main
       _common.sh:122: �[0mlocal arg_idx
�[2m
trace: common::parse_and_export_env_vars main main
       _common.sh:124: �[0mfor arg_idx in "${!ARGS[@]}"
�[2m
trace: common::parse_and_export_env_vars main main
       _common.sh:125: �[0mlocal 'arg=--config-policy=/Users/${USER}/PATH_TO_CUSTOM_POLICY/'
�[2m
trace: common::parse_and_export_env_vars main main
       _common.sh:128: �[0mtrue
�[2m
trace: common::parse_and_export_env_vars main main
       _common.sh:131: �[0m[[ --config-policy=/Users/${USER}/PATH_TO_CUSTOM_POLICY/ =~ .*\$\{[A-Z_][A-Z0-9_]+?}.* ]]
�[2m
trace: common::parse_and_export_env_vars main main
       _common.sh:147: �[0mbreak
�[2m
trace: main main
       terraform_trivy.sh:16: �[0mfor i in "${!ARGS[@]}"
��[2m
trace: main main
       terraform_trivy.sh:17: �[0mpwd
�[2m
trace: main main
       terraform_trivy.sh:17: �[0mARGS[i]='--config-policy=/Users/${USER}/PATH_TO_CUSTOM_POLICY/'
�[2m
trace: main main
       terraform_trivy.sh:20: �[0mcommon::per_dir_hook terraform_trivy 1 '--config-policy=/Users/${USER}/PATH_TO_CUSTOM_POLICY/' main.tf providers.tf
�[2m
trace: common::per_dir_hook main main
       _common.sh:272: �[0mlocal -r hook_id=terraform_trivy
�[2m
trace: common::per_dir_hook main main
       _common.sh:273: �[0mlocal -i args_array_length=1
�[2m
trace: common::per_dir_hook main main
       _common.sh:274: �[0mshift 2
�[2m
trace: common::per_dir_hook main main
       _common.sh:275: �[0margs=()
�[2m
trace: common::per_dir_hook main main
       _common.sh:275: �[0mlocal -a args
�[2m
trace: common::per_dir_hook main main
       _common.sh:278: �[0m(( args_array_length-- > 0 ))
�[2m
trace: common::per_dir_hook main main
       _common.sh:279: �[0margs+=("$1")
�[2m
trace: common::per_dir_hook main main
       _common.sh:280: �[0mshift
�[2m
trace: common::per_dir_hook main main
       _common.sh:278: �[0m(( args_array_length-- > 0 ))
�[2m
trace: common::per_dir_hook main main
       _common.sh:284: �[0mfiles=('main.tf' 'providers.tf')
�[2m
trace: common::per_dir_hook main main
       _common.sh:284: �[0mlocal -a -r files
��[2m
trace: common::per_dir_hook main main
       _common.sh:287: �[0mtype -t run_hook_on_whole_repo
�[2m
trace: common::per_dir_hook main main
       _common.sh:287: �[0m'[' function == function ']'
�[2m
trace: common::per_dir_hook main main
       _common.sh:289: �[0mcommon::is_hook_run_on_whole_repo terraform_trivy main.tf providers.tf
�[2m
trace: common::is_hook_run_on_whole_repo common::per_dir_hook main main
       _common.sh:162: �[0mlocal -r hook_id=terraform_trivy
�[2m
trace: common::is_hook_run_on_whole_repo common::per_dir_hook main main
       _common.sh:163: �[0mshift
�[2m
trace: common::is_hook_run_on_whole_repo common::per_dir_hook main main
       _common.sh:164: �[0mfiles=('main.tf' 'providers.tf')
�[2m
trace: common::is_hook_run_on_whole_repo common::per_dir_hook main main
       _common.sh:164: �[0mlocal -a -r files
����[2m
trace: common::is_hook_run_on_whole_repo common::per_dir_hook main main
       _common.sh:166: �[0mdirname /Users/amell/.cache/pre-commit/repoqvxc_9u4/hooks/_common.sh
���[2m
trace: common::is_hook_run_on_whole_repo common::per_dir_hook main main
       _common.sh:166: �[0mcd /Users/amell/.cache/pre-commit/repoqvxc_9u4/hooks
���[2m
trace: common::is_hook_run_on_whole_repo common::per_dir_hook main main
       _common.sh:166: �[0mpwd -P
��[2m
trace: common::is_hook_run_on_whole_repo common::per_dir_hook main main
       _common.sh:166: �[0mdirname /Users/amell/.cache/pre-commit/repoqvxc_9u4/hooks
�[2m
trace: common::is_hook_run_on_whole_repo common::per_dir_hook main main
       _common.sh:166: �[0mlocal -r root_config_dir=/Users/amell/.cache/pre-commit/repoqvxc_9u4
��[2m
trace: common::is_hook_run_on_whole_repo common::per_dir_hook main main
       _common.sh:168: �[0msed -n '/^- id: terraform_trivy$/,/^$/p' /Users/amell/.cache/pre-commit/repoqvxc_9u4/.pre-commit-hooks.yaml
�[2m
trace: common::is_hook_run_on_whole_repo common::per_dir_hook main main
       _common.sh:168: �[0mlocal -r 'hook_config_block=- id: terraform_trivy
  name: Terraform validate with trivy
  description: Static analysis of Terraform templates to spot potential security issues.
  require_serial: true
  entry: hooks/terraform_trivy.sh
  files: \.tf(vars)?$
  language: script'
��[2m
trace: common::is_hook_run_on_whole_repo common::per_dir_hook main main
       _common.sh:169: �[0mawk '$1 == "files:" {print $2; exit}'
�[2m
trace: common::is_hook_run_on_whole_repo common::per_dir_hook main main
       _common.sh:169: �[0mlocal -r 'included_files=\.tf(vars)?$'
��[2m
trace: common::is_hook_run_on_whole_repo common::per_dir_hook main main
       _common.sh:170: �[0mawk '$1 == "exclude:" {print $2; exit}'
�[2m
trace: common::is_hook_run_on_whole_repo common::per_dir_hook main main
       _common.sh:170: �[0mlocal -r excluded_files=
��[2m
trace: common::is_hook_run_on_whole_repo common::per_dir_hook main main
       _common.sh:172: �[0mprintf '%s\n' main.tf providers.tf
��[2m
trace: common::is_hook_run_on_whole_repo common::per_dir_hook main main
       _common.sh:172: �[0msort
��[2m
trace: common::is_hook_run_on_whole_repo common::per_dir_hook main main
       _common.sh:172: �[0mtr '\n' ' '
�[2m
trace: common::is_hook_run_on_whole_repo common::per_dir_hook main main
       _common.sh:172: �[0mlocal -r 'files_to_check=main.tf providers.tf '
�[2m
trace: common::is_hook_run_on_whole_repo common::per_dir_hook main main
       _common.sh:174: �[0mlocal all_files_that_can_be_checked
�[2m
trace: common::is_hook_run_on_whole_repo common::per_dir_hook main main
       _common.sh:176: �[0m'[' -z '' ']'
��[2m
trace: common::is_hook_run_on_whole_repo common::per_dir_hook main main
       _common.sh:177: �[0mgit ls-files
��[2m
trace: common::is_hook_run_on_whole_repo common::per_dir_hook main main
       _common.sh:177: �[0msort
��[2m
trace: common::is_hook_run_on_whole_repo common::per_dir_hook main main
       _common.sh:177: �[0mgrep -e '\.tf(vars)?$'
��[2m
trace: common::is_hook_run_on_whole_repo common::per_dir_hook main main
       _common.sh:177: �[0mtr '\n' ' '
�[2m
trace: common::is_hook_run_on_whole_repo common::per_dir_hook main main
       _common.sh:177: �[0mall_files_that_can_be_checked=
�[2m
trace: common::is_hook_run_on_whole_repo common::per_dir_hook main main
       _common.sh:182: �[0m'[' 'main.tf providers.tf ' == '' ']'
�[2m
trace: common::is_hook_run_on_whole_repo common::per_dir_hook main main
       _common.sh:185: �[0mreturn 1
�[2m
trace: common::per_dir_hook main main
       _common.sh:296: �[0mlocal index=0
�[2m
trace: common::per_dir_hook main main
       _common.sh:297: �[0mfor file_with_path in "${files[@]}"
�[2m
trace: common::per_dir_hook main main
       _common.sh:298: �[0mfile_with_path=main.tf
��[2m
trace: common::per_dir_hook main main
       _common.sh:300: �[0mdirname main.tf
�[2m
trace: common::per_dir_hook main main
       _common.sh:300: �[0mdir_paths[index]=.
�[2m
trace: common::per_dir_hook main main
       _common.sh:302: �[0m(( index += 1 ))
�[2m
trace: common::per_dir_hook main main
       _common.sh:297: �[0mfor file_with_path in "${files[@]}"
�[2m
trace: common::per_dir_hook main main
       _common.sh:298: �[0mfile_with_path=providers.tf
��[2m
trace: common::per_dir_hook main main
       _common.sh:300: �[0mdirname providers.tf
�[2m
trace: common::per_dir_hook main main
       _common.sh:300: �[0mdir_paths[index]=.
�[2m
trace: common::per_dir_hook main main
       _common.sh:302: �[0m(( index += 1 ))
�[2m
trace: common::per_dir_hook main main
       _common.sh:306: �[0mlocal change_dir_in_unique_part=false
�[2m
trace: common::per_dir_hook main main
       _common.sh:308: �[0mlocal parallelism_limit
�[2m
trace: common::per_dir_hook;main;main
       _common.sh:309: �[0mIFS=';'
�[2m
trace: common::per_dir_hook;main;main
       _common.sh:309: �[0mread -r -a configs
��[2m
trace: common::per_dir_hook main main
       _common.sh:338: �[0mcommon::get_cpu_num ''
��[2m
trace: common::get_cpu_num common::per_dir_hook main main
       _common.sh:198: �[0mlocal -r parallelism_ci_cpu_cores=
��[2m
trace: common::get_cpu_num common::per_dir_hook main main
       _common.sh:200: �[0mlocal millicpu
��[2m
trace: common::get_cpu_num common::per_dir_hook main main
       _common.sh:202: �[0m[[ -f /sys/fs/cgroup/cpu/cpu.cfs_quota_us ]]
��[2m
trace: common::get_cpu_num common::per_dir_hook main main
       _common.sh:239: �[0m[[ -f /sys/fs/cgroup/cpu.max ]]
��[2m
trace: common::get_cpu_num common::per_dir_hook main main
       _common.sh:255: �[0mnproc
��[2m
trace: common::get_cpu_num common::per_dir_hook main main
       _common.sh:255: �[0msysctl -n hw.ncpu
�[2m
trace: common::per_dir_hook main main
       _common.sh:338: �[0mCPU=12
�[2m
trace: common::per_dir_hook main main
       _common.sh:340: �[0mlocal parallelism_disabled=false
�[2m
trace: common::per_dir_hook main main
       _common.sh:342: �[0m[[ ! -n '' ]]
�[2m
trace: common::per_dir_hook main main
       _common.sh:344: �[0mparallelism_limit=11
�[2m
trace: common::per_dir_hook main main
       _common.sh:352: �[0m[[ 11 -lt 1 ]]
�[2m
trace: common::per_dir_hook main main
       _common.sh:365: �[0mpids=()
�[2m
trace: common::per_dir_hook main main
       _common.sh:365: �[0mlocal pids
��[2m
trace: common::per_dir_hook main main
       _common.sh:368: �[0mprintf '%s\n' . .
��[2m
trace: common::per_dir_hook main main
       _common.sh:368: �[0msort -u
�[2m
trace: common::per_dir_hook main main
       _common.sh:368: �[0mdir_paths_unique=('.')
�[2m
trace: common::per_dir_hook main main
       _common.sh:368: �[0mlocal -a dir_paths_unique
�[2m
trace: common::per_dir_hook main main
       _common.sh:370: �[0mlocal length=1
�[2m
trace: common::per_dir_hook main main
       _common.sh:371: �[0mlocal last_index=0
�[2m
trace: common::per_dir_hook main main
       _common.sh:373: �[0mlocal final_exit_code=0
�[2m
trace: common::per_dir_hook main main
       _common.sh:375: �[0mshopt -qo errexit
�[2m
trace: common::per_dir_hook main main
       _common.sh:375: �[0mERREXIT_IS_SET=true
�[2m
trace: common::per_dir_hook main main
       _common.sh:377: �[0mset +e
�[2m
trace: common::per_dir_hook main main
       _common.sh:379: �[0m(( i = 0 ))
�[2m
trace: common::per_dir_hook main main
       _common.sh:379: �[0m(( i < length ))
�[2m
trace: common::per_dir_hook main main
       _common.sh:380: �[0mdir_path=.
�[2m
trace: common::per_dir_hook main main
       _common.sh:388: �[0mpids+=("$!")
�[2m
trace: common::per_dir_hook main main
       _common.sh:382: �[0m[[ false == false ]]
�[2m
trace: common::per_dir_hook main main
       _common.sh:383: �[0mpushd .
�[2m
trace: common::per_dir_hook main main
       _common.sh:390: �[0m[[ false == true ]]
�[2m
trace: common::per_dir_hook main main
       _common.sh:391: �[0m[[ 0 -ne 0 ]]
�[2m
trace: common::per_dir_hook main main
       _common.sh:392: �[0m[[ 0 -eq 0 ]]
�[2m
trace: common::per_dir_hook main main
       _common.sh:394: �[0mfor pid in "${pids[@]}"
�[2m
trace: common::per_dir_hook main main
       _common.sh:386: �[0mper_dir_hook_unique_part . false false '--config-policy=/Users/${USER}/PATH_TO_CUSTOM_POLICY/'
�[2m
trace: common::per_dir_hook main main
       _common.sh:396: �[0mlocal exit_code=0
�[2m
trace: common::per_dir_hook main main
       _common.sh:397: �[0mwait 7203
�[2m
trace: per_dir_hook_unique_part common::per_dir_hook main main
       terraform_trivy.sh:39: �[0mlocal -r dir_path=.
�[2m
trace: per_dir_hook_unique_part common::per_dir_hook main main
       terraform_trivy.sh:41: �[0mlocal -r change_dir_in_unique_part=false
�[2m
trace: per_dir_hook_unique_part common::per_dir_hook main main
       terraform_trivy.sh:43: �[0mlocal -r parallelism_disabled=false
�[2m
trace: per_dir_hook_unique_part common::per_dir_hook main main
       terraform_trivy.sh:44: �[0mshift 3
�[2m
trace: per_dir_hook_unique_part common::per_dir_hook main main
       terraform_trivy.sh:45: �[0margs=('--config-policy=/Users/${USER}/PATH_TO_CUSTOM_POLICY/')
�[2m
trace: per_dir_hook_unique_part common::per_dir_hook main main
       terraform_trivy.sh:45: �[0mlocal -a -r args
��[2m
trace: per_dir_hook_unique_part common::per_dir_hook main main
       terraform_trivy.sh:48: �[0mpwd
�[2m
trace: per_dir_hook_unique_part common::per_dir_hook main main
       terraform_trivy.sh:48: �[0mtrivy conf /Users/amell/projects/trivy_test --exit-code=1 '--config-policy=/Users/${USER}/PATH_TO_CUSTOM_POLICY/'
2024-03-12T09:24:38.753-0400	�[34mINFO�[0m	Misconfiguration scanning is enabled
2024-03-12T09:24:38.755-0400	�[31mFATAL�[0m	filesystem scan error: scan error: unable to initialize a scanner: unable to initialize a filesystem scanner: analyzer group error: post-analyzer init error: terraform scanner init error: policy file "/Users/${USER}/PATH_TO_CUSTOM_POLICY" not found
�[2m
trace: per_dir_hook_unique_part common::per_dir_hook main main
       terraform_trivy.sh:51: �[0mlocal exit_code=1
�[2m
trace: per_dir_hook_unique_part common::per_dir_hook main main
       terraform_trivy.sh:52: �[0mreturn 1
�[2m
trace: common::per_dir_hook main main
       _common.sh:397: �[0mexit_code=1
�[2m
trace: common::per_dir_hook main main
       _common.sh:399: �[0m'[' 1 -ne 0 ']'
�[2m
trace: common::per_dir_hook main main
       _common.sh:400: �[0mfinal_exit_code=1
�[2m
trace: common::per_dir_hook main main
       _common.sh:404: �[0munset pids
�[2m
trace: common::per_dir_hook main main
       _common.sh:379: �[0m(( i++ ))
�[2m
trace: common::per_dir_hook main main
       _common.sh:379: �[0m(( i < length ))
�[2m
trace: common::per_dir_hook main main
       _common.sh:410: �[0m[[ -n true ]]
�[2m
trace: common::per_dir_hook main main
       _common.sh:410: �[0mset -e
�[2m
trace: common::per_dir_hook main main
       _common.sh:412: �[0mexit 1

@MaxymVlasov
Copy link
Collaborator

So, problem with

function common::parse_and_export_env_vars {
local arg_idx
for arg_idx in "${!ARGS[@]}"; do
local arg="${ARGS[$arg_idx]}"
# Repeat until all env vars will be expanded
while true; do
# Check if at least 1 env var exists in `$arg`
# shellcheck disable=SC2016 # '${' should not be expanded
if [[ "$arg" =~ .*'${'[A-Z_][A-Z0-9_]+?'}'.* ]]; then
# Get `ENV_VAR` from `.*${ENV_VAR}.*`
local env_var_name=${arg#*$\{}
env_var_name=${env_var_name%%\}*}
local env_var_value="${!env_var_name}"
# shellcheck disable=SC2016 # '${' should not be expanded
common::colorify "green" 'Found ${'"$env_var_name"'} in: '"'$arg'"
# Replace env var name with its value.
# `$arg` will be checked in `if` conditional, `$ARGS` will be used in the next functions.
# shellcheck disable=SC2016 # '${' should not be expanded
arg=${arg/'${'$env_var_name'}'/$env_var_value}
ARGS[$arg_idx]=$arg
# shellcheck disable=SC2016 # '${' should not be expanded
common::colorify "green" 'After ${'"$env_var_name"'} expansion: '"'$arg'\n"
continue
fi
break
done
done

To be specific - with

if [[ "$arg" =~ .*'${'[A-Z_][A-Z0-9_]+?'}'.* ]]; then

That how it evaluates on @aaronmell machine

trace: common::parse_and_export_env_vars main main
       _common.sh:131: [[ --config-policy=/Users/${USER}/PATH_TO_CUSTOM_POLICY/ =~ .*\$\{[A-Z_][A-Z0-9_]+?}.* ]]

trace: common::parse_and_export_env_vars main main
       _common.sh:147: break

To "not match"

And there is how it evaluates on my machine

race: common::parse_and_export_env_vars main main
       _common.sh:131: [[ --config-policy=/Users/${USER}/PATH_TO_CUSTOM_POLICY/ =~ .*\$\{[A-Z_][A-Z0-9_]+?}.* ]]

trace: common::parse_and_export_env_vars main main
       _common.sh:133: local 'env_var_name=USER}/PATH_TO_CUSTOM_POLICY/'

trace: common::parse_and_export_env_vars main main
       _common.sh:134: env_var_name=USER

trace: common::parse_and_export_env_vars main main
       _common.sh:135: local env_var_value=vm

trace: common::parse_and_export_env_vars main main
       _common.sh:137: common::colorify green 'Found ${USER} in:        '\''--config-policy=/Users/${USER}/PATH_TO_CUSTOM_POLICY/'\'''
...

So, the question is:

Why is the next construction evaluates to "not match"?

arg='--config-policy=/Users/${USER}/PATH_TO_CUSTOM_POLICY/'
if [[ "$arg" =~ .*'${'[A-Z_][A-Z0-9_]+?'}'.* ]]; then echo "match"; else echo "not match"; fi

@aaronmell could you please activate /opt/homebrew/bin/bash, run the script above, and post the result? Just to be sure that there is an issue with how bash interprets that's if

@MaxymVlasov
Copy link
Collaborator

From logs:

BASH path: '/opt/homebrew/bin/bash'
BASH_VERSION: 5.2.26(1)-release
➜ docker run -ti bash:5.2.26 
bash-5.2# arg='--config-policy=/Users/${USER}/PATH_TO_CUSTOM_POLICY/'
if [[ "$arg" =~ .*'${'[A-Z_][A-Z0-9_]+?'}'.* ]]; then echo "match"; else echo "not match"; fi
match
bash-5.2# 

Default macOS bash

➜ docker run -ti bash:3.2.57  
bash-3.2# arg='--config-policy=/Users/${USER}/PATH_TO_CUSTOM_POLICY/'
bash-3.2# if [[ "$arg" =~ .*'${'[A-Z_][A-Z0-9_]+?'}'.* ]]; then echo "match"; else echo "not match"; fi
match
bash-3.2# 

@aaronmell
Copy link
Author

/opt/homebrew/bin/bash
bash-5.2$ arg='--config-policy=/Users/${USER}/PATH_TO_CUSTOM_POLICY/'
if [[ "$arg" =~ .*'${'[A-Z_][A-Z0-9_]+?'}'.* ]]; then echo "match"; else echo "not match"; fi
not match

@MaxymVlasov MaxymVlasov added the help wanted Extra attention is needed label Mar 12, 2024
@MaxymVlasov
Copy link
Collaborator

That's the weirdest stuff that I have ever seen. @aaronmell your Mac on which processor? M1, M2 or M3?

@yermulnik
Copy link
Collaborator

@aaronmell Would you please also post the output of shopt -p?

@MaxymVlasov

> shopt -p | fgrep compat
shopt -u compat31
shopt -u compat32
shopt -u compat40
shopt -u compat41
shopt -u compat42
shopt -u compat43
shopt -u compat44

> arg='--config-policy=/Users/${USER}/PATH_TO_CUSTOM_POLICY/'
> shopt -p | fgrep compat | while read _ _ SHOPT; do echo -n "$SHOPT: "; shopt -s "$SHOPT"; [[ "$arg" =~ .*'${'[A-Z_][A-Z0-9_]+?'}'.* ]] && echo match || echo not match; done
compat31: not match
compat32: match
compat40: match
compat41: match
compat42: match
compat43: match
compat44: match

@MaxymVlasov
Copy link
Collaborator

Confirm that ? does not work in bash'es outside Linux (in DragonFly BSD same issue)

Will sent PR soon

@MaxymVlasov MaxymVlasov removed the help wanted Extra attention is needed label Mar 12, 2024
@yermulnik
Copy link
Collaborator

yermulnik commented Mar 12, 2024

If @aaronmell confirms `compat31 is set on his end, we may try and implement "fail-safe mechanism" 🤪

if [[ $BASHOPTS =~ :compat31: ]]; then
  <fail as of shell option incompatibility>
else
  <proceed with trivy with `--config-policy` opt>
fi

@yermulnik
Copy link
Collaborator

Confirm that ? does not work in bash'es outside Linux (in DragonFly BSD same issue)

You mean +? and "outside Linux" is "using the same version of Bash"?

@aaronmell
Copy link
Author

I'm running on an M2

shopt -p | fgrep compat
shopt -u compat31
shopt -u compat32
shopt -u compat40
shopt -u compat41
shopt -u compat42
shopt -u compat43
shopt -u compat44

@yermulnik
Copy link
Collaborator

I'm running on an M2

shopt -p | fgrep compat
shopt -u compat31
shopt -u compat32
shopt -u compat40
shopt -u compat41
shopt -u compat42
shopt -u compat43
shopt -u compat44

Would please post the full output of shopt -p so that we can try and reproduce locally with the same shell opts that you have set/unset?

@MaxymVlasov
Copy link
Collaborator

MaxymVlasov commented Mar 12, 2024

You mean +? and "outside Linux" is "using the same version of Bash"?

Yes.
Check from https://t.me/catops_chat/233230 to bottom

@yermulnik
Copy link
Collaborator

You mean +? and "outside Linux" is "using the same version of Bash"?

Yes. Check from t.me/catops_chat/233230 to bottom

Should probably just replace +? with * (which also would be more correct as would allow single-char vars).

@yermulnik
Copy link
Collaborator

(.* on both sides of regex make no sense btw)

@antonbabenko
Copy link
Owner

This issue has been resolved in version 1.88.2 🎉

@aaronmell
Copy link
Author

Verified the fix works. Thanks to everyone that helped!

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