mirror of
https://github.com/go-task/task.git
synced 2026-06-29 15:44:30 +00:00
- mask secret values in `task --summary` (commands and vars listing) - mask resolved value of dynamic (sh) secrets in verbose logs - use masked command for platform-skipped verbose log - allow `secret` key in any position in a var definition (not only first) - add `value` to the JSON schema var definition - skip masking pass when no secret is present and dedup mask helpers - document that the `secret` flag is not propagated to derived variables
62 lines
1.6 KiB
Go
62 lines
1.6 KiB
Go
package templater
|
|
|
|
import (
|
|
"github.com/go-task/task/v3/taskfile/ast"
|
|
)
|
|
|
|
// MaskSecrets replaces template placeholders with their values, masking secrets.
|
|
// This function uses the Go templater to resolve all variables ({{.VAR}}) while
|
|
// masking secret ones as "*****".
|
|
func MaskSecrets(cmdTemplate string, vars *ast.Vars) string {
|
|
return MaskSecretsWithExtra(cmdTemplate, vars, nil)
|
|
}
|
|
|
|
// MaskSecretsWithExtra is like MaskSecrets but also resolves extra variables (e.g., loop vars).
|
|
func MaskSecretsWithExtra(cmdTemplate string, vars *ast.Vars, extra map[string]any) string {
|
|
if vars == nil {
|
|
vars = ast.NewVars()
|
|
}
|
|
|
|
// Fast path: if there are no secrets to mask, resolve the template directly
|
|
// without the extra DeepCopy + masking pass.
|
|
if !hasSecrets(vars) {
|
|
cache := &Cache{Vars: vars}
|
|
result := ReplaceWithExtra(cmdTemplate, cache, extra)
|
|
if cache.Err() != nil {
|
|
return cmdTemplate
|
|
}
|
|
return result
|
|
}
|
|
|
|
// Create a copy with secret values masked, leaving the originals untouched.
|
|
maskedVars := vars.DeepCopy()
|
|
for name, v := range maskedVars.All() {
|
|
if v.Secret {
|
|
maskedVars.Set(name, ast.Var{
|
|
Value: "*****",
|
|
Secret: true,
|
|
})
|
|
}
|
|
}
|
|
|
|
cache := &Cache{Vars: maskedVars}
|
|
result := ReplaceWithExtra(cmdTemplate, cache, extra)
|
|
|
|
// If there was an error, return the original template
|
|
if cache.Err() != nil {
|
|
return cmdTemplate
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
// hasSecrets reports whether any variable is marked as secret.
|
|
func hasSecrets(vars *ast.Vars) bool {
|
|
for _, v := range vars.All() {
|
|
if v.Secret {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|