Skip to content

Commit

Permalink
Tech debt cleanup (#91)
Browse files Browse the repository at this point in the history
* Update to node v18

* Use latest vscode-tmgrammar-snap configuration options to simplify npm scripts

* Reread main configuration for each product

Previously it was thought that the main Viper configuration would be refreshed
after each merge however this turned out to be false.  This commit updates
the builder to refresh the main viper instance before being merged with the
product configuration.

* Remove deprecated iotuil usage

* Move syntax locations to variables

* Move to golang cmd pattern

* Add dependabot for npm

* Add build script command

* Recommend Go extension

* Update DEVELOPMENT with improved command line

---------

Co-authored-by: Glenn Sarti <glennsarti@users.noreply.github.com>
  • Loading branch information
jpogran and glennsarti authored Nov 10, 2023
1 parent fba1af5 commit ad29c91
Show file tree
Hide file tree
Showing 12 changed files with 314 additions and 432 deletions.
6 changes: 6 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,9 @@ updates:
schedule:
interval: "daily"
labels: ["dependencies"]
- package-ecosystem: "npm"
versioning-strategy: lockfile-only
directory: "/"
schedule:
interval: "daily"
labels: ["dependencies"]
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
16.13.2
18.17.1
2 changes: 1 addition & 1 deletion .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"recommendations": ["esbenp.prettier-vscode", "redhat.vscode-yaml"]
"recommendations": ["esbenp.prettier-vscode", "redhat.vscode-yaml", "go.golang"]
}
4 changes: 2 additions & 2 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ We are an open source project on GitHub and would enjoy your contributions! Plea

### Requirements

- Node >= 16.13.2
- Node >= 18.x
- npm >= 8.x
- Go >= 1.17

Expand All @@ -27,7 +27,7 @@ npm install
The following workflow is recommended to work on any of the HashiCorp TextMate grammars in this repo:

1. Add or modify grammar in the `src/_main.yml` or product specific YAML file in like `src/terraform.yml`.
1. Change directory to `builder` and run `go run main.go build`
1. Run `npm run build`
1. Add a new test case file or modify existing test case files inside the `tests/snapshot/<lang>` directory. Make sure to put the new file in the correct folder or it will not be tested.
1. Run `npm run test:snap:<lang>` until the tests pass.

Expand Down
206 changes: 0 additions & 206 deletions builder/main.go

This file was deleted.

112 changes: 112 additions & 0 deletions cmd/builder/build.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package main

import (
"fmt"
"os"
"path/filepath"
"strings"

"github.com/hashicorp/go-multierror"
"github.com/mitchellh/cli"
"github.com/spf13/viper"
)
type BuildCommand struct {
Ui cli.Ui
}

func (c *BuildCommand) Help() string {
helpText := `Usage: syntax build
` + c.Synopsis()
return strings.TrimSpace(helpText)
}

func (c *BuildCommand) Synopsis() string {
return "Builds syntax files"
}

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
// convention for where things are located
wd, err := os.Getwd()
if err != nil {
return 1
}

syntaxSourcePath := filepath.Join(wd, "src")
syntaxDeployPath := filepath.Join(wd, "syntaxes")

// 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
mainFile := filepath.Join(syntaxSourcePath, "_main.yml")

var result *multierror.Error
// For each product defined, read the yml and merge into the main Viper instance
products := []string{"hcl", "terraform"}
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()))
return 1
}

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

// Create a product Viper instance that reads each product yml for rules
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()))
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)
continue
}

// 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)
if err != nil {
c.Ui.Error(fmt.Sprintf("Unable to merge values from %s: %s", productV.ConfigFileUsed(), err.Error()))
result = multierror.Append(result, err)
continue
}

// Write the struct to JSON. We can modify this to include writing to other formats in the future
productGrammarFile := filepath.Join(syntaxDeployPath, fmt.Sprintf("%s.tmGrammar.json", product))
c.Ui.Info(fmt.Sprintf("Writing %s", productGrammarFile))
err = writeJSON(config, productGrammarFile)
if err != nil {
c.Ui.Error(fmt.Sprintf("Error writing grammar file: %v", err))
result = multierror.Append(result, err)
}
}

if result.ErrorOrNil() != nil {
return 1
} else {
return 0
}
}

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

0 comments on commit ad29c91

Please sign in to comment.