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

Add Sentinel HCL support #46

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 23 additions & 20 deletions builder/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,13 @@ func (c *BuildCommand) Synopsis() string {
return "Builds syntax files"
}

func (c *BuildCommand) newViper(filepath string) (*viper.Viper, error) {
v := viper.New()
v.SetConfigFile(filepath)
err := v.ReadInConfig()
return v, err
}

func (c *BuildCommand) Run(args []string) int {
// This currently uses the cwd to find all the files used here
// This can be improved in the future to accept User input or use some kind of
Expand All @@ -74,40 +81,36 @@ func (c *BuildCommand) Run(args []string) int {

// The _main.yml file is where all rules in the Patterns and the Repository are defined
// Each product file provides specific overrides for rules defined in _main.yml
// Here we build a main Viper instance to store the config we will merge in product specific maps to
mainFile := filepath.Join(wd, "../src/_main.yml")
c.Ui.Info(fmt.Sprintf("Pulling in main template: %s", mainFile))
mainViper := viper.New()
mainViper.SetConfigFile(mainFile)
if err := mainViper.ReadInConfig(); err == nil {
c.Ui.Info(fmt.Sprintf("Merging config file: %v", mainViper.ConfigFileUsed()))
} else {
c.Ui.Error(fmt.Sprintf("Error reading %v: %v", mainViper.ConfigFileUsed(), err))
return 1
}

var result *multierror.Error
// For each product defined, read the yml and merge into the main Viper instance
products := []string{"hcl", "terraform"}
products := []string{"hcl", "terraform", "sentinel-hcl"}
for _, product := range products {
c.Ui.Info(fmt.Sprintf("Evaluating %s", product))

// Here we build a main Viper instance to store the config we will merge in product specific maps.
// Note that the main viper configuration needs to be re-read for each product and errors here
// are terminal
mainViper, err := c.newViper(mainFile)
if err != nil {
c.Ui.Error(fmt.Sprintf("Error reading %v: %v", mainViper.ConfigFileUsed(), err.Error()))
result = multierror.Append(result, err)
return 1
}

productFile := filepath.Join(wd, fmt.Sprintf("../src/%s.yml", product))
c.Ui.Info(fmt.Sprintf("Processing: %s", productFile))

// Create a product Viper instance that reads each product yml for rules
productV := viper.New()
productV.SetConfigFile(productFile)
if err := productV.ReadInConfig(); err == nil {
c.Ui.Info(fmt.Sprintf("Merging config file: %v", productV.ConfigFileUsed()))
} else {
productV, err := c.newViper(productFile)
if err != nil {
c.Ui.Error(fmt.Sprintf("Error reading %v: %v", productV.ConfigFileUsed(), err.Error()))
result = multierror.Append(result, err)
continue
}
c.Ui.Info(fmt.Sprintf("Merging config file: %v", productV.ConfigFileUsed()))

// merge the product Viper map into the main Viper instance
// This overrides anything already loaded so each product can replace existing
// rules and/or provide new ones
if err := mainViper.MergeConfigMap(productV.AllSettings()); err != nil {
c.Ui.Error(fmt.Sprintf("Unable to merge values from %v: %v", productV.ConfigFileUsed(), err.Error()))
result = multierror.Append(result, err)
Expand All @@ -117,7 +120,7 @@ func (c *BuildCommand) Run(args []string) int {
// Export the merged map to a struct so we can write to file
c.Ui.Info(fmt.Sprintf("Building %s", product))
var config TextMateGrammar
err := mainViper.Unmarshal(&config)
err = mainViper.Unmarshal(&config)
if err != nil {
c.Ui.Error(fmt.Sprintf("Unable to merge values from %s: %s", productV.ConfigFileUsed(), err.Error()))
result = multierror.Append(result, err)
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@
"check": "prettier --check syntaxes/*.json",
"format": "prettier --write syntaxes/*.json",
"test": "npm run test:snap",
"test:snap": "npm run test:snap:hcl && npm run test:snap:sentinel && npm run test:snap:terraform",
"test:snap": "npm run test:snap:hcl && npm run test:snap:sentinel && npm run test:snap:terraform && npm run test:snap:sentinel-hcl",
"test:snap:update": "npm run test:snap:hcl -- -u && npm run test:snap:sentinel -- -u && npm run test:snap:terraform -- -u",
"test:snap:hcl": "npx vscode-tmgrammar-snap -s source.hcl -g syntaxes/hcl.tmGrammar.json \"tests/snapshot/hcl/*.hcl\"",
"test:snap:sentinel": "npx vscode-tmgrammar-snap -s source.sentinel -g syntaxes/sentinel.tmGrammar.json \"tests/snapshot/sentinel/*.sentinel\"",
"test:snap:sentinel-hcl": "npx vscode-tmgrammar-snap -s source.hcl.sentinel -g syntaxes/sentinel-hcl.tmGrammar.json \"tests/snapshot/sentinel-hcl/*.hcl\"",
"test:snap:terraform": "npx vscode-tmgrammar-snap -s source.hcl.terraform -g syntaxes/terraform.tmGrammar.json -g syntaxes/hcl.tmGrammar.json \"tests/snapshot/terraform/*.tf\""
},
"devDependencies": {
Expand Down
33 changes: 33 additions & 0 deletions src/sentinel-hcl.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
scopeName: source.hcl.sentinel
name: HashiCorp Sentinel Configuration
uuid: aa94bcc5-d57d-4d1f-a906-b8b8690e8c00
fileTypes:
- hcl
repository:
block:
name: meta.block.hcl
comment: This will match HCL blocks like `thing1 "one" "two" {` or `thing2 {`
# Sentinel attributes can include a forward slash in the name
begin: ([\w][\-\w]*)([\s\"\-\w\/]*)(\{)
beginCaptures:
"1":
patterns:
- match: \b(?!null|false|true)[[:alpha:]][[:alnum:]_-]*\b
comment: Block type
name: entity.name.type.hcl
"2":
patterns:
- name: variable.other.enummember.hcl
comment: Block label
match: '[\"\-\w\/]+'
"3":
name: punctuation.section.block.begin.hcl
end: \}
endCaptures:
"0":
name: punctuation.section.block.end.hcl
patterns:
- include: "#comments"
- include: "#attribute_definition"
- include: "#block"
- include: "#expressions"
Loading