Skip to content

Commit

Permalink
feat: update existence error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
jdkato committed Oct 1, 2020
1 parent 08647c5 commit ea629c9
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 33 deletions.
23 changes: 15 additions & 8 deletions check/check.go
Expand Up @@ -97,7 +97,6 @@ func NewManager(config *config.Config) (*Manager, error) {
fName := parts[1] + ".yml"
path = filepath.Join(mgr.Config.StylesPath, parts[0], fName)
if err = mgr.loadCheck(fName, path); err != nil {
fmt.Println("HMMMMMo")
return &mgr, err
}
}
Expand Down Expand Up @@ -593,7 +592,7 @@ func (mgr *Manager) addConsistencyCheck(chkName string, chkDef Consistency) {
}
}

func (mgr *Manager) addExistenceCheck(chkName string, chkDef Existence) {
func (mgr *Manager) addExistenceCheck(chkName, path string, chkDef Existence) error {

regex := makeRegexp(
mgr.Config.WordTemplate,
Expand All @@ -603,13 +602,21 @@ func (mgr *Manager) addExistenceCheck(chkName string, chkDef Existence) {
chkDef.Append)

regex = fmt.Sprintf(regex, strings.Join(chkDef.Tokens, "|"))

re, err := regexp.Compile(regex)
if core.CheckError(err, mgr.Config.Debug) {
fn := func(text string, file *core.File) []core.Alert {
return checkExistence(text, chkDef, file, re)
}
mgr.updateAllChecks(chkDef.Definition, fn, re.String())
if err != nil {
return core.NewE201FromPosition(
fmt.Sprintf("Failed to compile '%s': %s", chkName, err.Error()),
path,
1)
}

fn := func(text string, file *core.File) []core.Alert {
return checkExistence(text, chkDef, file, re)
}
mgr.updateAllChecks(chkDef.Definition, fn, re.String())

return nil
}

func (mgr *Manager) addRepetitionCheck(chkName string, chkDef Repetition) {
Expand Down Expand Up @@ -962,7 +969,7 @@ func (mgr *Manager) loadVocabRules() {
for term := range mgr.Config.RejectedTokens {
avoid.Tokens = append(avoid.Tokens, term)
}
mgr.addExistenceCheck("Vale.Avoid", avoid)
mgr.addExistenceCheck("Vale.Avoid", "", avoid)
}

if mgr.Config.LTPath != "" {
Expand Down
64 changes: 39 additions & 25 deletions check/definitions.go
Expand Up @@ -41,14 +41,6 @@ type Check struct {
Scope core.Selector
}

// A RuleError represents an error encoutered while processing an external YAML
// file.
//
// The idea here is that we can't panic due to the nature of how Vale is used:
//
type RuleError struct {
}

// Definition holds the common attributes of rule definitions.
type Definition struct {
Action core.Action
Expand Down Expand Up @@ -77,15 +69,17 @@ type NLPToken struct {
// Existence checks for the present of Tokens.
type Existence struct {
Definition `mapstructure:",squash"`
// `append` (`bool`): Adds `raw` to the end of `tokens`, assuming both are defined.
// `append` (`bool`): Adds `raw` to the end of `tokens`, assuming both are
// defined.
Append bool
// `ignorecase` (`bool`): Makes all matches case-insensitive.
Ignorecase bool
// `nonword` (`bool`): Removes the default word boundaries (`\b`).
Nonword bool
// `raw` (`array`): A list of tokens to be concatenated into a pattern.
Raw []string
// `tokens` (`array`): A list of tokens to be transformed into a non-capturing group.
// `tokens` (`array`): A list of tokens to be transformed into a
// non-capturing group.
Tokens []string
}

Expand All @@ -98,7 +92,8 @@ type Substitution struct {
Nonword bool
// `swap` (`map`): A sequence of `observed: expected` pairs.
Swap map[string]string
// `pos` (`string`): A regular expression matching tokens to parts of speech.
// `pos` (`string`): A regular expression matching tokens to parts of
// speech.
POS string
}

Expand All @@ -107,9 +102,11 @@ type Occurrence struct {
Definition `mapstructure:",squash"`
// `ignorecase` (`bool`): Makes all matches case-insensitive.
Ignorecase bool
// `max` (`int`): The maximum amount of times `token` may appear in a given scope.
// `max` (`int`): The maximum amount of times `token` may appear in a given
// scope.
Max int
// `min` (`int`): The minimum amount of times `token` has to appear in a given scope.
// `min` (`int`): The minimum amount of times `token` has to appear in a
// given scope.
Min int
// `token` (`string`): The token of interest.
Token string
Expand All @@ -123,7 +120,8 @@ type Repetition struct {
Ignorecase bool
// `alpha` (`bool`): Limits all matches to alphanumeric tokens.
Alpha bool
// `tokens` (`array`): A list of tokens to be transformed into a non-capturing group.
// `tokens` (`array`): A list of tokens to be transformed into a
// non-capturing group.
Tokens []string
}

Expand All @@ -134,7 +132,8 @@ type Consistency struct {
Nonword bool
// `ignorecase` (`bool`): Makes all matches case-insensitive.
Ignorecase bool
// `either` (`map`): A map of `option 1: option 2` pairs, of which only one may appear.
// `either` (`map`): A map of `option 1: option 2` pairs, of which only one
// may appear.
Either map[string]string
}

Expand All @@ -159,7 +158,8 @@ type Capitalization struct {
// `match` (`string`): $title, $sentence, $lower, $upper, or a pattern.
Match string
Check func(s string, ignore []string, re *regexp.Regexp) bool
// `style` (`string`): AP or Chicago; only applies when match is set to $title.
// `style` (`string`): AP or Chicago; only applies when match is set to
// $title.
Style string
// `exceptions` (`array`): An array of strings to be ignored.
Exceptions []string
Expand All @@ -173,7 +173,8 @@ type Capitalization struct {
// Readability checks the reading grade level of text.
type Readability struct {
Definition `mapstructure:",squash"`
// `metrics` (`array`): One or more of Gunning Fog, Coleman-Liau, Flesch-Kincaid, SMOG, and Automated Readability.
// `metrics` (`array`): One or more of Gunning Fog, Coleman-Liau,
// Flesch-Kincaid, SMOG, and Automated Readability.
Metrics []string
// `grade` (`float`): The highest acceptable score.
Grade float64
Expand All @@ -182,15 +183,20 @@ type Readability struct {
// Spelling checks text against a Hunspell dictionary.
type Spelling struct {
Definition `mapstructure:",squash"`
// `aff` (`string`): The fully-qualified path to a Hunspell-compatible `.aff` file.
// `aff` (`string`): The fully-qualified path to a Hunspell-compatible
// `.aff` file.
Aff string
// `custom` (`bool`): Turn off the default filters for acronyms, abbreviations, and numbers.
// `custom` (`bool`): Turn off the default filters for acronyms,
// abbreviations, and numbers.
Custom bool
// `dic` (`string`): The fully-qualified path to a Hunspell-compatible `.dic` file.
// `dic` (`string`): The fully-qualified path to a Hunspell-compatible
// `.dic` file.
Dic string
// `filters` (`array`): An array of patterns to ignore during spell checking.
// `filters` (`array`): An array of patterns to ignore during spell
// checking.
Filters []*regexp.Regexp
// `ignore` (`array`): An array of relative paths (from `StylesPath`) to files consisting of one word per line to ignore.
// `ignore` (`array`): An array of relative paths (from `StylesPath`) to
// files consisting of one word per line to ignore.
Ignore []string
Exceptions []string
Threshold int
Expand All @@ -213,10 +219,18 @@ type baseCheck map[string]interface{}
var checkBuilders = map[string]func(name, path string, generic baseCheck, mgr *Manager) error{
"existence": func(name, path string, generic baseCheck, mgr *Manager) error {
def := Existence{}
if err := mapstructure.Decode(generic, &def); err == nil {
mgr.addExistenceCheck(name, def)

err := mapstructure.Decode(generic, &def)
if err != nil {
return readStructureError(err, name, path)
}
return nil

err = validator.Validate(def)
if err != nil {
return readValueError(err, name, path)
}

return mgr.addExistenceCheck(name, path, def)
},
"substitution": func(name, path string, generic baseCheck, mgr *Manager) error {
def := Substitution{}
Expand Down

0 comments on commit ea629c9

Please sign in to comment.