goherence/internal/lint/rules_when.go
2026-09-11 10:17:25 +03:00

45 lines
2.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package lint
import (
"regexp"
"github.com/vladimir/goherence/internal/parser"
)
// WhenGrammarRule разрешает в `when` только чистые предикаты:
// сравнения (==, !=, <, >, <=, >=), логику (and, or, not) и обращения
// к переменным. Вызов функций (sprig или любых других) в when запрещён —
// это первый и самый частый путь протащить в условие вычисление с
// побочным эффектом (случайные числа, текущее время, счётчики).
//
// Реализация первой версии — не полноценный парсер выражений, а
// консервативный regex-фильтр: ищем характерный синтаксис вызова функции
// `имя(...)` и паттерн `| filterName` (пайп — тоже вызов функции в Go-шаблонах).
// Ложные срабатывания возможны и это осознанный компромисс: лучше
// требовать явный allow_shell-подобный обход, чем пропустить реальный вызов.
type WhenGrammarRule struct{}
func (r *WhenGrammarRule) Name() string { return "when-grammar" }
var (
funcCallPattern = regexp.MustCompile(`[a-zA-Z_][a-zA-Z0-9_]*\s*\(`)
pipePattern = regexp.MustCompile(`\|\s*[a-zA-Z_]`)
)
func (r *WhenGrammarRule) Check(pb *parser.Playbook) []Violation {
var out []Violation
walkTasks(pb, func(loc string, t *parser.Task) {
if t.When == "" {
return
}
if funcCallPattern.MatchString(t.When) || pipePattern.MatchString(t.When) {
out = append(out, Violation{
Rule: r.Name(), Severity: Error, Location: loc,
Message: "when-выражение должно быть чистым предикатом " +
"(сравнения / and / or / not над переменными), вызовы функций и " +
"фильтры (|) внутри when запрещены: " + t.When,
})
}
})
return out
}