Repository: pantsbuild/pants

Issue:
helm backend doesn't pass --debug to template despite (misleading!) "Use --debug flag to render out invalid YAML"
**Describe the bug**
```
$ tree src/chart/foo/
src/chart/foo/
├── BUILD
├── Chart.yaml
├── templates
│   ├── app.yaml
│   └── _helpers.tpl
└── values.yaml

1 directory, 5 files
```

```
$ cat src/chart/foo/BUILD 
helm_chart(
    name="foo"
)

helm_deployment(dependencies=[":foo"],
                name="deployfoo")
```

```
$ cat src/chart/foo/templates/app.yaml 
{{ include "doesnotexist" (list $ .) }}
```

So trying to deploy this contrived example gives 
```
$ ./pants experimental-deploy src/chart/foo:deployfoo
15:33:50.61 [INFO] Initialization options changed: reinitializing scheduler...
15:33:53.65 [INFO] Scheduler initialized.
15:33:54.09 [ERROR] 1 Exception encountered:

Engine traceback:
  in `experimental-deploy` goal

ProcessExecutionFailure: Process 'Rendering Helm deployment src/chart/foo:deployfoo' failed with exit code 1.
stdout:

stderr:
Error: template: foo/templates/app.yaml:1:3: executing "foo/templates/app.yaml" at <include "doesnotexist" (list $ .)>: error calling include: template: no template "doesnotexist" associated with template "gotpl"

Use --debug flag to render out invalid YAML



Use `--keep-sandboxes=on_failure` to preserve the process chroot for inspection.
```

So, following the suggestion in the error message:
```
$ ./pants --keep-sandboxes=on_failure  experimental-deploy src/chart/foo:deployfoo -- --debug
15:34:39.94 [INFO] Initialization options changed: reinitializing scheduler...
15:34:43.04 [INFO] Scheduler initialized.
15:34:43.48 [INFO] Preserving local process execution dir /tmp/pants-sandbox-C9BdhW for Rendering Helm deployment src/chart/foo:deployfoo
15:34:43.49 [ERROR] 1 Exception encountered:

Engine traceback:
  in `experimental-deploy` goal

ProcessExecutionFailure: Process 'Rendering Helm deployment src/chart/foo:deployfoo' failed with exit code 1.
stdout:

stderr:
Error: template: foo/templates/app.yaml:1:3: executing "foo/templates/app.yaml" at <include "doesnotexist" (list $ .)>: error calling include: template: no template "doesnotexist" associated with template "gotpl"

Use --debug flag to render out invalid YAML
```

Huh I thought I did use the `--debug` flag.

```
$ cat /tmp/pants-sandbox-C9BdhW/__run.sh 
#!/bin/bash
# This command line should execute the same process as pants did internally.
export HELM_CACHE_HOME=__cache HELM_CONFIG_HOME=__config HELM_DATA_HOME=__data HOME=/home/ecsb PATH=$'/home/ecsb/.cargo/bin:/home/ecsb/bin/:/home/ecsb/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/bin:/usr/lib/llvm/15/bin:/usr/lib/llvm/14/bin'
cd /tmp/pants-sandbox-C9BdhW
__helm/linux-amd64/helm template deployfoo foo --output-dir __out --values __values/src/chart/foo/Chart.yaml,__values/src/chart/foo/values.yaml
```
^^ No flag

But!  to add to that confusion... if I manually add the flag to the sandbox it isn't all that helpful after all
```
$ pwd
/tmp/pants-sandbox-C9BdhW
$ tail -1 __run.sh 
__helm/linux-amd64/helm template deployfoo foo --output-dir __out --values __values/src/chart/foo/Chart.yaml,__values/src/chart/foo/values.yaml --debug
$ ./__run.sh 
install.go:192: [debug] Original chart version: ""
install.go:209: [debug] CHART PATH: /tmp/pants-sandbox-C9BdhW/foo


Error: template: foo/templates/app.yaml:1:3: executing "foo/templates/app.yaml" at <include "doesnotexist" (list $ .)>: error calling include: template: no template "doesnotexist" associated with template "gotpl"
helm.go:84: [debug] template: foo/templates/app.yaml:1:3: executing "foo/templates/app.yaml" at <include "doesnotexist" (list $ .)>: error calling include: template: no template "doesnotexist" associated with template "gotpl"
```

Since the original message comes from helm I'm not sure what to suggest.   But the behavior where stdout says "use this flag!" and then pants swallows the flag when you use it doesn't feel great.

**Pants version**
2.16.0.dev5

**OS**
Linux

**Additional info**
Add any other information about the problem here, such as attachments or links to gists, if relevant.



Discussion:
ah, so, looks like the args are passed through to the `helm upgrade` but not to the calls to `helm template` before that.

Resolving patch:
diff --git a/src/python/pants/backend/helm/util_rules/tool.py b/src/python/pants/backend/helm/util_rules/tool.py
--- a/src/python/pants/backend/helm/util_rules/tool.py
+++ b/src/python/pants/backend/helm/util_rules/tool.py
@@ -440,10 +440,12 @@ async def setup_helm(
 
 @rule
 async def helm_process(
-    request: HelmProcess, helm_binary: HelmBinary, helm_subsytem: HelmSubsystem
+    request: HelmProcess,
+    helm_binary: HelmBinary,
+    helm_subsystem: HelmSubsystem,
 ) -> Process:
     global_extra_env = await Get(
-        EnvironmentVars, EnvironmentVarsRequest(helm_subsytem.extra_env_vars)
+        EnvironmentVars, EnvironmentVarsRequest(helm_subsystem.extra_env_vars)
     )
 
     # Helm binary's setup parameters go last to prevent end users overriding any of its values.
@@ -455,8 +457,21 @@ async def helm_process(
     }
     append_only_caches = {**request.extra_append_only_caches, **helm_binary.append_only_caches}
 
+    argv = [helm_binary.path, *request.argv]
+
+    # A special case for "--debug".
+    # This ensures that it is applied to all operations in the chain,
+    # not just the final one.
+    # For example, we want this applied to the call to `template`, not just the call to `install`
+    # Also, we can be helpful and automatically forward a request to debug Pants to also debug Helm
+    debug_requested = "--debug" in helm_subsystem.valid_args() or (
+        0 < logger.getEffectiveLevel() <= LogLevel.DEBUG.level
+    )
+    if debug_requested and "--debug" not in request.argv:
+        argv.append("--debug")
+
     return Process(
-        [helm_binary.path, *request.argv],
+        argv,
         input_digest=request.input_digest,
         immutable_input_digests=immutable_input_digests,
         env=env,
diff --git a/src/python/pants/util/logging.py b/src/python/pants/util/logging.py
--- a/src/python/pants/util/logging.py
+++ b/src/python/pants/util/logging.py
@@ -17,7 +17,7 @@ class LogLevel(Enum):
 
     NB: The `logging` module uses the opposite integer ordering of levels from Rust's `log` crate,
     but the ordering implementation of this enum inverts its comparison to make its ordering align
-    with Rust's.
+    with Rust's. That is, TRACE > DEBUG > INFO > WARN > ERROR
     """
 
     TRACE = ("trace", TRACE)


Test patch: