From 7f950ec40809f210f00b170fd12fe25b668c6e7f Mon Sep 17 00:00:00 2001 From: Aidan Reilly <74046732+aireilly@users.noreply.github.com> Date: Wed, 6 Mar 2024 10:23:28 +0000 Subject: [PATCH] Adding unset attr rule --- .../AsciiDoc/UnsetAttributes/.vale.ini | 5 ++ .../AsciiDoc/UnsetAttributes/testinvalid.adoc | 15 ++++++ .../AsciiDoc/UnsetAttributes/testvalid.adoc | 19 +++++++ .vale/styles/AsciiDoc/UnsetAttributes.yml | 42 +++++++++++++++ tengo-rule-scripts/UnsetAttributes.tengo | 51 +++++++++++++++++++ 5 files changed, 132 insertions(+) create mode 100644 .vale/fixtures/AsciiDoc/UnsetAttributes/.vale.ini create mode 100644 .vale/fixtures/AsciiDoc/UnsetAttributes/testinvalid.adoc create mode 100644 .vale/fixtures/AsciiDoc/UnsetAttributes/testvalid.adoc create mode 100644 .vale/styles/AsciiDoc/UnsetAttributes.yml create mode 100644 tengo-rule-scripts/UnsetAttributes.tengo diff --git a/.vale/fixtures/AsciiDoc/UnsetAttributes/.vale.ini b/.vale/fixtures/AsciiDoc/UnsetAttributes/.vale.ini new file mode 100644 index 000000000..66e3a990f --- /dev/null +++ b/.vale/fixtures/AsciiDoc/UnsetAttributes/.vale.ini @@ -0,0 +1,5 @@ +; Vale configuration file to test the `UnsetAttributes` rule +StylesPath = ../../../styles +MinAlertLevel = error +[*.adoc] +AsciiDoc.UnsetAttributes = YES diff --git a/.vale/fixtures/AsciiDoc/UnsetAttributes/testinvalid.adoc b/.vale/fixtures/AsciiDoc/UnsetAttributes/testinvalid.adoc new file mode 100644 index 000000000..5f0a58f89 --- /dev/null +++ b/.vale/fixtures/AsciiDoc/UnsetAttributes/testinvalid.adoc @@ -0,0 +1,15 @@ +:context: creating-infrastructure-machinesets + +ifeval::["{context}" == "creating-infrastructure-machinesets"] +:infra: +endif::[] + +Vale reports lots of errors, it should also report an attribute that you forgot to unset + +//// +Ignore multi-line comments +:!infra: +//// + +//ignore comments +//:!infra: diff --git a/.vale/fixtures/AsciiDoc/UnsetAttributes/testvalid.adoc b/.vale/fixtures/AsciiDoc/UnsetAttributes/testvalid.adoc new file mode 100644 index 000000000..bf79c8580 --- /dev/null +++ b/.vale/fixtures/AsciiDoc/UnsetAttributes/testvalid.adoc @@ -0,0 +1,19 @@ +:context: creating-infrastructure-machinesets + +ifeval::["{context}" == "creating-infrastructure-machinesets"] +//vale-fixture +:infra: +endif::[] + +Vale reports lots of errors, it should also report an attribute that you forgot to unset + +ifeval::["{context}" == "creating-infrastructure-machinesets"] +//vale-fixture +:!infra: +endif::[] + +//This is really just unsetting a second time, but it should not trip the rule +ifeval::["{context}" == "creating-infrastructure"] +//vale-fixture +:infra!: +endif::[] diff --git a/.vale/styles/AsciiDoc/UnsetAttributes.yml b/.vale/styles/AsciiDoc/UnsetAttributes.yml new file mode 100644 index 000000000..cd1822ca1 --- /dev/null +++ b/.vale/styles/AsciiDoc/UnsetAttributes.yml @@ -0,0 +1,42 @@ +--- +extends: script +level: error +message: "Set attribute has not been unset in the current file." +link: https://docs.asciidoctor.org/asciidoc/latest/attributes/unset-attributes/#unset-a-document-attribute-in-the-header +scope: raw +script: | + text := import("text") + matches := [] + + // trim extra whitespace + scope = text.trim_space(scope) + // add a newline, it might be missing + scope += "\n" + // clean out multi-line comments + scope = text.re_replace("(?s) *(\n////.*?////\n)", scope, "") + + attr_regex := "^:[\\w-]+:$" + unset_attr_pref := "" + unset_attr_suff := "" + + for line in text.split(scope, "\n") { + if text.re_match(attr_regex, line) { + start := text.index(scope, line) + matches = append(matches, {begin: start, end: start + len(line)}) + unset_attr_pref = `^:!` + text.trim_prefix(line, `:`) + unset_attr_suff = `^` + text.trim_suffix(line, `:`) + `!:` + // loop through lines for every attr found + for line in text.split(scope, "\n") { + if text.re_match(unset_attr_pref, line) { + if len(matches) > 0 { + // remove the most recently added match + matches = matches[:len(matches)-1] + } else if text.re_match(unset_attr_suff, line) { + if len(matches) > 0 { + matches = matches[:len(matches)-1] + } + } + } + } + } + } diff --git a/tengo-rule-scripts/UnsetAttributes.tengo b/tengo-rule-scripts/UnsetAttributes.tengo new file mode 100644 index 000000000..d53aa5f02 --- /dev/null +++ b/tengo-rule-scripts/UnsetAttributes.tengo @@ -0,0 +1,51 @@ +/* +Tengo Language +$ tengo UnsetAttributes.tengo +*/ + +fmt := import("fmt") +os := import("os") +text := import("text") + +input := os.args() +scope := os.read_file(input[2]) +matches := [] + +// trim extra whitespace +scope = text.trim_space(scope) +// add a newline, it might be missing +scope += "\n" +// clean out multi-line comments +scope = text.re_replace("(?s) *(\n////.*?////\n)", scope, "") + +attr_regex := "^:[\\w-]+:$" +unset_attr_pref := "" +unset_attr_suff := "" + +for line in text.split(scope, "\n") { + if text.re_match(attr_regex, line) { + start := text.index(scope, line) + matches = append(matches, {begin: start, end: start + len(line)}) + unset_attr_pref = `^:!` + text.trim_prefix(line, `:`) + unset_attr_suff = `^` + text.trim_suffix(line, `:`) + `!:` + // loop through lines for every attr found + for line in text.split(scope, "\n") { + if text.re_match(unset_attr_pref, line) { + if len(matches) > 0 { + // remove the most recently added match + matches = matches[:len(matches)-1] + } else if text.re_match(unset_attr_suff, line) { + if len(matches) > 0 { + matches = matches[:len(matches)-1] + } + } + } + } + } +} + +if len(matches) == 0 { + fmt.println("Attributes are unset properly") +} else { + fmt.println(matches) +}