From 81bf1d97db4c36b68fa0dde8fe5ea5e9acca9cdf Mon Sep 17 00:00:00 2001 From: Agustindeleon Date: Sun, 26 Oct 2025 13:53:39 -0300 Subject: [PATCH] feat: phase defaults in global config --- main.go | 9 ++++++ types/configuration.go | 72 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 79 insertions(+), 2 deletions(-) diff --git a/main.go b/main.go index 4b4ab21..490894f 100644 --- a/main.go +++ b/main.go @@ -108,6 +108,8 @@ func LoadSeclang(input string) types.ConfigurationList { // PrintSeclang writes seclang directives to files specified in directive list ids. func PrintSeclang(configList types.ConfigurationList, dir string) error { + configList.PhaseDefaultsToSeclang() + unfDirs := types.FromCRSLangToUnformattedDirectives(configList) for _, dirList := range unfDirs.DirectiveList { @@ -126,6 +128,13 @@ func ToCRSLang(configList types.ConfigurationList) *types.ConfigurationList { configListWithConditions := types.ToDirectiveWithConditions(configList) configListWithConditions.ExtractDefaultValues() + + err := configListWithConditions.ExtractPhaseDefaults() + + if err != nil { + panic(err) + } + return configListWithConditions } diff --git a/types/configuration.go b/types/configuration.go index bf54fb9..da255e9 100644 --- a/types/configuration.go +++ b/types/configuration.go @@ -1,12 +1,20 @@ package types import ( + "fmt" "slices" ) +type PhaseDefaults struct { + Comment string `yaml:"comment,omitempty"` + Transformations Transformations `yaml:",inline"` + Actions *SeclangActions `yaml:"actions"` +} + type DefaultConfigs struct { - Version string `yaml:"version,omitempty"` - Tags []string `yaml:"tags,omitempty"` + Version string `yaml:"version,omitempty"` + Tags []string `yaml:"tags,omitempty"` + Phases map[string]PhaseDefaults `yaml:"phases,omitempty"` } type ConfigurationList struct { @@ -93,3 +101,63 @@ func (c *ConfigurationList) ExtractDefaultValues() { c.Global.Version = version c.Global.Tags = tags } + +// ExtractPhaseDefaults extract default actions from the directive list and add it to the global config +func (c *ConfigurationList) ExtractPhaseDefaults() error { + defaultActions := map[string]PhaseDefaults{} + + for _, dirList := range c.DirectiveList { + for _, directive := range dirList.Directives { + if directive.GetKind() == DefaultActionKind { + da, ok := directive.(DefaultAction) + if !ok { + return fmt.Errorf("Error: casting directive to DefaultAction") + } + pd := PhaseDefaults{ + Comment: da.Metadata.Comment, + Transformations: da.Transformations, + Actions: CopyActions(*da.Actions), + } + _, ok = defaultActions[da.Metadata.Phase] + if ok { + return fmt.Errorf("Error: duplicate default actions for phase %s", da.Metadata.Phase) + } + defaultActions[da.Metadata.Phase] = pd + } + } + } + + for i := range c.DirectiveList { + c.DirectiveList[i].Directives = slices.DeleteFunc(c.DirectiveList[i].Directives, func(d SeclangDirective) bool { + return d.GetKind() == DefaultActionKind + }) + } + + c.Global.Phases = defaultActions + return nil +} + +// ExtractPhaseDefaults extract default actions from the directive list and add it to the global config +func (c *ConfigurationList) PhaseDefaultsToSeclang() error { + if len(c.Global.Phases) > 0 { + seclangDirs := []SeclangDirective{} + for p, v := range c.Global.Phases { + da := NewDefaultAction() + da.Metadata.SetComment(v.Comment) + da.Metadata.SetPhase(p) + da.Actions = CopyActions(*v.Actions) + seclangDirs = append(seclangDirs, *da) + } + + if len(c.DirectiveList) != 0 { + c.DirectiveList[0].Directives = append(seclangDirs, c.DirectiveList[0].Directives...) + } else { + dirList := DirectiveList{} + dirList.Id = "crs-setup" + dirList.Directives = seclangDirs + c.DirectiveList = append(c.DirectiveList, dirList) + } + } + + return nil +}