diff options
39 files changed, 870 insertions, 0 deletions
diff --git a/.github/styles/Google/AMPM.yml b/.github/styles/Google/AMPM.yml new file mode 100644 index 00000000..fbdc6e4f --- /dev/null +++ b/.github/styles/Google/AMPM.yml @@ -0,0 +1,9 @@ +extends: existence +message: "Use 'AM' or 'PM' (preceded by a space)." +link: 'https://developers.google.com/style/word-list' +level: error +nonword: true +tokens: + - '\d{1,2}[AP]M' + - '\d{1,2} ?[ap]m' + - '\d{1,2} ?[aApP]\.[mM]\.' diff --git a/.github/styles/Google/Acronyms.yml b/.github/styles/Google/Acronyms.yml new file mode 100644 index 00000000..f41af018 --- /dev/null +++ b/.github/styles/Google/Acronyms.yml @@ -0,0 +1,64 @@ +extends: conditional +message: "Spell out '%s', if it's unfamiliar to the audience." +link: 'https://developers.google.com/style/abbreviations' +level: suggestion +ignorecase: false +# Ensures that the existence of 'first' implies the existence of 'second'. +first: '\b([A-Z]{3,5})\b' +second: '(?:\b[A-Z][a-z]+ )+\(([A-Z]{3,5})\)' +# ... with the exception of these: +exceptions: + - API + - ASP + - CLI + - CPU + - CSS + - CSV + - DEBUG + - DOM + - DPI + - FAQ + - GCC + - GDB + - GET + - GPU + - GTK + - GUI + - HTML + - HTTP + - HTTPS + - IDE + - JAR + - JSON + - JSX + - LESS + - LLDB + - NET + - NOTE + - NVDA + - OSS + - PATH + - PDF + - PHP + - POST + - RAM + - REPL + - RSA + - SCM + - SCSS + - SDK + - SQL + - SSH + - SSL + - SVG + - TBD + - TCP + - TODO + - URI + - URL + - USB + - UTF + - XML + - XSS + - YAML + - ZIP diff --git a/.github/styles/Google/Colons.yml b/.github/styles/Google/Colons.yml new file mode 100644 index 00000000..9a4b4b4a --- /dev/null +++ b/.github/styles/Google/Colons.yml @@ -0,0 +1,7 @@ +extends: existence +message: "'%s' should be in lowercase." +link: 'https://developers.google.com/style/colons' +nonword: true +level: warning +tokens: + - ':\s[A-Z]' diff --git a/.github/styles/Google/Contractions.yml b/.github/styles/Google/Contractions.yml new file mode 100644 index 00000000..905a39f4 --- /dev/null +++ b/.github/styles/Google/Contractions.yml @@ -0,0 +1,28 @@ +extends: substitution +message: "Feel free to use '%s' instead of '%s'." +link: 'https://developers.google.com/style/contractions' +level: suggestion +ignorecase: true +swap: + are not: aren't + cannot: can't + could not: couldn't + did not: didn't + do not: don't + does not: doesn't + has not: hasn't + have not: haven't + how is: how's + is not: isn't + it is: it's + should not: shouldn't + that is: that's + they are: they're + was not: wasn't + we are: we're + we have: we've + were not: weren't + what is: what's + when is: when's + where is: where's + will not: won't diff --git a/.github/styles/Google/DateFormat.yml b/.github/styles/Google/DateFormat.yml new file mode 100644 index 00000000..e9d227fa --- /dev/null +++ b/.github/styles/Google/DateFormat.yml @@ -0,0 +1,9 @@ +extends: existence +message: "Use 'July 31, 2016' format, not '%s'." +link: 'https://developers.google.com/style/dates-times' +ignorecase: true +level: error +nonword: true +tokens: + - '\d{1,2}(?:\.|/)\d{1,2}(?:\.|/)\d{4}' + - '\d{1,2} (?:Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)|May|Jun(?:e)|Jul(?:y)|Aug(?:ust)|Sep(?:tember)?|Oct(?:ober)|Nov(?:ember)?|Dec(?:ember)?) \d{4}' diff --git a/.github/styles/Google/Ellipses.yml b/.github/styles/Google/Ellipses.yml new file mode 100644 index 00000000..436e6177 --- /dev/null +++ b/.github/styles/Google/Ellipses.yml @@ -0,0 +1,7 @@ +extends: existence +message: "In general, don't use an ellipsis." +link: 'https://developers.google.com/style/ellipses' +nonword: true +level: warning +tokens: + - '\.\.\.' diff --git a/.github/styles/Google/EmDash.yml b/.github/styles/Google/EmDash.yml new file mode 100644 index 00000000..c6018db1 --- /dev/null +++ b/.github/styles/Google/EmDash.yml @@ -0,0 +1,8 @@ +extends: existence +message: "Don't put a space before or after an em dash." +link: 'https://developers.google.com/style/dashes' +nonword: true +level: error +tokens: + - '\s—' + - '—\s' diff --git a/.github/styles/Google/EnDash.yml b/.github/styles/Google/EnDash.yml new file mode 100644 index 00000000..194876aa --- /dev/null +++ b/.github/styles/Google/EnDash.yml @@ -0,0 +1,7 @@ +extends: existence +message: "Use an em dash ('—') instead of '–'." +link: 'https://developers.google.com/style/dashes' +nonword: true +level: error +tokens: + - '–' diff --git a/.github/styles/Google/Exclamation.yml b/.github/styles/Google/Exclamation.yml new file mode 100644 index 00000000..c4db380b --- /dev/null +++ b/.github/styles/Google/Exclamation.yml @@ -0,0 +1,7 @@ +extends: existence +message: "Don't use exclamation points in text." +link: 'https://developers.google.com/style/exclamation-points' +nonword: true +level: error +tokens: + - '!' diff --git a/.github/styles/Google/FirstPerson.yml b/.github/styles/Google/FirstPerson.yml new file mode 100644 index 00000000..d2290611 --- /dev/null +++ b/.github/styles/Google/FirstPerson.yml @@ -0,0 +1,11 @@ +extends: existence +message: "Avoid first-person pronouns such as '%s'." +link: 'https://developers.google.com/style/pronouns#personal-pronouns' +ignorecase: true +level: warning +nonword: true +tokens: + - (?:^|\s)I\s + - \bme\b + - \bus\b + - \bours\b diff --git a/.github/styles/Google/Gender.yml b/.github/styles/Google/Gender.yml new file mode 100644 index 00000000..c8486181 --- /dev/null +++ b/.github/styles/Google/Gender.yml @@ -0,0 +1,9 @@ +extends: existence +message: "Don't use '%s' as a gender-neutral pronoun." +link: 'https://developers.google.com/style/pronouns#gender-neutral-pronouns' +level: error +ignorecase: true +tokens: + - he/she + - s/he + - \(s\)he diff --git a/.github/styles/Google/GenderBias.yml b/.github/styles/Google/GenderBias.yml new file mode 100644 index 00000000..261cfb66 --- /dev/null +++ b/.github/styles/Google/GenderBias.yml @@ -0,0 +1,45 @@ +extends: substitution +message: "Consider using '%s' instead of '%s'." +link: 'https://developers.google.com/style/inclusive-documentation' +ignorecase: true +level: error +swap: + (?:alumna|alumnus): graduate + (?:alumnae|alumni): graduates + air(?:m[ae]n|wom[ae]n): pilot(s) + anchor(?:m[ae]n|wom[ae]n): anchor(s) + authoress: author + camera(?:m[ae]n|wom[ae]n): camera operator(s) + chair(?:m[ae]n|wom[ae]n): chair(s) + congress(?:m[ae]n|wom[ae]n): member(s) of congress + door(?:m[ae]|wom[ae]n): concierge(s) + draft(?:m[ae]n|wom[ae]n): drafter(s) + fire(?:m[ae]n|wom[ae]n): firefighter(s) + fisher(?:m[ae]n|wom[ae]n): fisher(s) + fresh(?:m[ae]n|wom[ae]n): first-year student(s) + garbage(?:m[ae]n|wom[ae]n): waste collector(s) + lady lawyer: lawyer + ladylike: courteous + landlord: building manager + mail(?:m[ae]n|wom[ae]n): mail carriers + man and wife: husband and wife + man enough: strong enough + mankind: human kind + manmade: manufactured + manpower: personnel + men and girls: men and women + middle(?:m[ae]n|wom[ae]n): intermediary + news(?:m[ae]n|wom[ae]n): journalist(s) + ombuds(?:man|woman): ombuds + oneupmanship: upstaging + poetess: poet + police(?:m[ae]n|wom[ae]n): police officer(s) + repair(?:m[ae]n|wom[ae]n): technician(s) + sales(?:m[ae]n|wom[ae]n): salesperson or sales people + service(?:m[ae]n|wom[ae]n): soldier(s) + steward(?:ess)?: flight attendant + tribes(?:m[ae]n|wom[ae]n): tribe member(s) + waitress: waiter + woman doctor: doctor + woman scientist[s]?: scientist(s) + work(?:m[ae]n|wom[ae]n): worker(s) diff --git a/.github/styles/Google/HeadingPunctuation.yml b/.github/styles/Google/HeadingPunctuation.yml new file mode 100644 index 00000000..5c39abbf --- /dev/null +++ b/.github/styles/Google/HeadingPunctuation.yml @@ -0,0 +1,8 @@ +extends: existence +message: "Don't put a period at the end of a heading." +link: 'https://developers.google.com/style/capitalization#capitalization-in-titles-and-headings' +nonword: true +level: warning +scope: heading +tokens: + - '[a-z0-9][.](?:\s|$)' diff --git a/.github/styles/Google/Headings.yml b/.github/styles/Google/Headings.yml new file mode 100644 index 00000000..5afb968d --- /dev/null +++ b/.github/styles/Google/Headings.yml @@ -0,0 +1,26 @@ +extends: capitalization +message: "'%s' should use sentence-style capitalization." +link: 'https://developers.google.com/style/capitalization#capitalization-in-titles-and-headings' +level: warning +scope: heading +match: $sentence +exceptions: + - Azure + - CLI + - Code + - Cosmos + - Docker + - Emmet + - I + - Kubernetes + - Linux + - macOS + - Marketplace + - MongoDB + - REPL + - Studio + - TypeScript + - URLs + - Visual + - VS + - Windows diff --git a/.github/styles/Google/Hyphens.yml b/.github/styles/Google/Hyphens.yml new file mode 100644 index 00000000..f9779637 --- /dev/null +++ b/.github/styles/Google/Hyphens.yml @@ -0,0 +1,8 @@ +extends: existence +message: "Don't place a space on either side of a hyphen (unless it's suspended)." +link: 'https://developers.google.com/style/hyphens' +level: warning +nonword: true +tokens: + - '\s-' + - '-\s' diff --git a/.github/styles/Google/Latin.yml b/.github/styles/Google/Latin.yml new file mode 100644 index 00000000..f032b349 --- /dev/null +++ b/.github/styles/Google/Latin.yml @@ -0,0 +1,9 @@ +extends: substitution +message: "Use '%s' instead of '%s'." +link: 'https://developers.google.com/style/abbreviations' +ignorecase: true +level: error +nonword: true +swap: + '\b(?:eg|e\.g\.)[\s,]': for example + '\b(?:ie|i\.e\.)[\s,]': that is diff --git a/.github/styles/Google/LyHyphens.yml b/.github/styles/Google/LyHyphens.yml new file mode 100644 index 00000000..d5b6a942 --- /dev/null +++ b/.github/styles/Google/LyHyphens.yml @@ -0,0 +1,8 @@ +extends: existence +message: "'%s' doesn't need a hyphen." +link: 'https://developers.google.com/style/hyphens' +level: error +ignorecase: false +nonword: true +tokens: + - '\s[^\s-]+ly-' diff --git a/.github/styles/Google/OptionalPlurals.yml b/.github/styles/Google/OptionalPlurals.yml new file mode 100644 index 00000000..7058932f --- /dev/null +++ b/.github/styles/Google/OptionalPlurals.yml @@ -0,0 +1,7 @@ +extends: existence +message: "Don't use plurals in parentheses such as in '%s'." +link: 'https://developers.google.com/style/plurals-parentheses' +level: error +nonword: true +tokens: + - '\b\w+\(s\)' diff --git a/.github/styles/Google/Ordinal.yml b/.github/styles/Google/Ordinal.yml new file mode 100644 index 00000000..8c429e0f --- /dev/null +++ b/.github/styles/Google/Ordinal.yml @@ -0,0 +1,7 @@ +extends: existence +message: "Spell out all ordinal numbers ('%s') in text." +link: 'https://developers.google.com/style/numbers' +level: error +nonword: true +tokens: + - \d+(?:st|th|rd) diff --git a/.github/styles/Google/OxfordComma.yml b/.github/styles/Google/OxfordComma.yml new file mode 100644 index 00000000..98b07113 --- /dev/null +++ b/.github/styles/Google/OxfordComma.yml @@ -0,0 +1,7 @@ +extends: existence +message: "Use the Oxford comma in '%s'." +link: 'https://developers.google.com/style/commas' +scope: sentence +level: warning +tokens: + - '(?:[^,]+,){1,}\s\w+\sand' diff --git a/.github/styles/Google/Parens.yml b/.github/styles/Google/Parens.yml new file mode 100644 index 00000000..3b8711d0 --- /dev/null +++ b/.github/styles/Google/Parens.yml @@ -0,0 +1,7 @@ +extends: existence +message: "Use parentheses judiciously." +link: 'https://developers.google.com/style/parentheses' +nonword: true +level: suggestion +tokens: + - '\(.+\)' diff --git a/.github/styles/Google/Passive.yml b/.github/styles/Google/Passive.yml new file mode 100644 index 00000000..3265890e --- /dev/null +++ b/.github/styles/Google/Passive.yml @@ -0,0 +1,184 @@ +extends: existence +link: 'https://developers.google.com/style/voice' +message: "In general, use active voice instead of passive voice ('%s')." +ignorecase: true +level: suggestion +raw: + - \b(am|are|were|being|is|been|was|be)\b\s* +tokens: + - '[\w]+ed' + - awoken + - beat + - become + - been + - begun + - bent + - beset + - bet + - bid + - bidden + - bitten + - bled + - blown + - born + - bought + - bound + - bred + - broadcast + - broken + - brought + - built + - burnt + - burst + - cast + - caught + - chosen + - clung + - come + - cost + - crept + - cut + - dealt + - dived + - done + - drawn + - dreamt + - driven + - drunk + - dug + - eaten + - fallen + - fed + - felt + - fit + - fled + - flown + - flung + - forbidden + - foregone + - forgiven + - forgotten + - forsaken + - fought + - found + - frozen + - given + - gone + - gotten + - ground + - grown + - heard + - held + - hidden + - hit + - hung + - hurt + - kept + - knelt + - knit + - known + - laid + - lain + - leapt + - learnt + - led + - left + - lent + - let + - lighted + - lost + - made + - meant + - met + - misspelt + - mistaken + - mown + - overcome + - overdone + - overtaken + - overthrown + - paid + - pled + - proven + - put + - quit + - read + - rid + - ridden + - risen + - run + - rung + - said + - sat + - sawn + - seen + - sent + - set + - sewn + - shaken + - shaven + - shed + - shod + - shone + - shorn + - shot + - shown + - shrunk + - shut + - slain + - slept + - slid + - slit + - slung + - smitten + - sold + - sought + - sown + - sped + - spent + - spilt + - spit + - split + - spoken + - spread + - sprung + - spun + - stolen + - stood + - stridden + - striven + - struck + - strung + - stuck + - stung + - stunk + - sung + - sunk + - swept + - swollen + - sworn + - swum + - swung + - taken + - taught + - thought + - thrived + - thrown + - thrust + - told + - torn + - trodden + - understood + - upheld + - upset + - wed + - wept + - withheld + - withstood + - woken + - won + - worn + - wound + - woven + - written + - wrung diff --git a/.github/styles/Google/Periods.yml b/.github/styles/Google/Periods.yml new file mode 100644 index 00000000..d24a6a6c --- /dev/null +++ b/.github/styles/Google/Periods.yml @@ -0,0 +1,7 @@ +extends: existence +message: "Don't use periods with acronyms or initialisms such as '%s'." +link: 'https://developers.google.com/style/abbreviations' +level: error +nonword: true +tokens: + - '\b(?:[A-Z]\.){3,}' diff --git a/.github/styles/Google/Quotes.yml b/.github/styles/Google/Quotes.yml new file mode 100644 index 00000000..3cb6f1ab --- /dev/null +++ b/.github/styles/Google/Quotes.yml @@ -0,0 +1,7 @@ +extends: existence +message: "Commas and periods go inside quotation marks." +link: 'https://developers.google.com/style/quotation-marks' +level: error +nonword: true +tokens: + - '"[^"]+"[.,?]' diff --git a/.github/styles/Google/Ranges.yml b/.github/styles/Google/Ranges.yml new file mode 100644 index 00000000..3ec045e7 --- /dev/null +++ b/.github/styles/Google/Ranges.yml @@ -0,0 +1,7 @@ +extends: existence +message: "Don't add words such as 'from' or 'between' to describe a range of numbers." +link: 'https://developers.google.com/style/hyphens' +nonword: true +level: warning +tokens: + - '(?:from|between)\s\d+\s?-\s?\d+' diff --git a/.github/styles/Google/Semicolons.yml b/.github/styles/Google/Semicolons.yml new file mode 100644 index 00000000..bb8b85b4 --- /dev/null +++ b/.github/styles/Google/Semicolons.yml @@ -0,0 +1,8 @@ +extends: existence +message: "Use semicolons judiciously." +link: 'https://developers.google.com/style/semicolons' +nonword: true +scope: sentence +level: suggestion +tokens: + - ';' diff --git a/.github/styles/Google/Slang.yml b/.github/styles/Google/Slang.yml new file mode 100644 index 00000000..63f4c248 --- /dev/null +++ b/.github/styles/Google/Slang.yml @@ -0,0 +1,11 @@ +extends: existence +message: "Don't use internet slang abbreviations such as '%s'." +link: 'https://developers.google.com/style/abbreviations' +ignorecase: true +level: error +tokens: + - 'tl;dr' + - ymmv + - rtfm + - imo + - fwiw diff --git a/.github/styles/Google/Spacing.yml b/.github/styles/Google/Spacing.yml new file mode 100644 index 00000000..5f209a9f --- /dev/null +++ b/.github/styles/Google/Spacing.yml @@ -0,0 +1,8 @@ +extends: existence +message: "'%s' should have one space." +link: 'https://developers.google.com/style/sentence-spacing' +level: error +nonword: true +tokens: + - '[.?!] {2,}[A-Z]' + - '[.?!][A-Z]' diff --git a/.github/styles/Google/Spelling.yml b/.github/styles/Google/Spelling.yml new file mode 100644 index 00000000..57acb884 --- /dev/null +++ b/.github/styles/Google/Spelling.yml @@ -0,0 +1,8 @@ +extends: existence +message: "In general, use American spelling instead of '%s'." +link: 'https://developers.google.com/style/spelling' +ignorecase: true +level: warning +tokens: + - '(?:\w+)nised?' + - '(?:\w+)logue' diff --git a/.github/styles/Google/Units.yml b/.github/styles/Google/Units.yml new file mode 100644 index 00000000..220de3e9 --- /dev/null +++ b/.github/styles/Google/Units.yml @@ -0,0 +1,7 @@ +extends: existence +message: "Put a nonbreaking space between the number and the unit in '%s'." +link: 'https://developers.google.com/style/units-of-measure' +nonword: true +level: error +tokens: + - \d+(?:GB|TB|MB) diff --git a/.github/styles/Google/Will.yml b/.github/styles/Google/Will.yml new file mode 100644 index 00000000..128a9183 --- /dev/null +++ b/.github/styles/Google/Will.yml @@ -0,0 +1,7 @@ +extends: existence +message: "Avoid using '%s'." +link: 'https://developers.google.com/style/tense' +ignorecase: true +level: warning +tokens: + - will diff --git a/.github/styles/Google/WordList.yml b/.github/styles/Google/WordList.yml new file mode 100644 index 00000000..d5d6bea5 --- /dev/null +++ b/.github/styles/Google/WordList.yml @@ -0,0 +1,79 @@ +extends: substitution +message: "Use %s instead of '%s'." +link: 'https://developers.google.com/style/word-list' +level: warning +ignorecase: false +swap: + '(?:API Console|dev|developer) key': "'API key'" + '(?:cell ?phone|smart ?phone)': "'phone' or 'mobile phone'" + '(?:dev|developer|APIs) console': "'API console'" + '(?:e-mail|Email|E-mail)': "'email'" + '(?:file ?path|path ?name)': "'path'" + '(?:kill|terminate)': "'stop', 'exit', 'cancel', or 'end'" + '(?:OAuth ?2|Oauth)': "'OAuth 2.0'" + '(?:ok|Okay)': "'OK' or 'okay'" + '(?:WiFi|wifi)': "'Wi-Fi'" + '[\.]+apk': "'APK'" + '3\-D': "'3D'" + 'Google (?:I\-O|IO)': "'Google I/O'" + 'tap (?:&|and) hold': "'touch & hold'" + 'un(?:check|select)': "'clear'" + abort: "'stop', 'exit', 'cancel' or 'end'" + above: "'preceding'" + account name: "'username'" + action bar: "'app bar'" + admin: "'administrator'" + Ajax: "'AJAX'" + Android device: "'Android-powered device'" + android: "'Android'" + API explorer: "'APIs Explorer'" + application: "'app'" + approx\.: "'approximately'" + authN: "'authentication'" + authZ: "'authorization'" + autoupdate: "'automatically update'" + cellular data: "'mobile data'" + cellular network: "'mobile network'" + chapter: "'documents', 'pages', 'sections'" + check box: "'checkbox'" + check: "'select'" + CLI: "'command-line tool'" + click on: "'click' or 'click in'" + Cloud: "'Google Cloud Platform' or 'GCP'" + Container Engine: "'Kubernetes Engine'" + content type: "'media type'" + curated roles: "'predefined roles'" + data are: "'data is'" + Developers Console: "'Google API Console' or 'API Console'" + disabled?: "'turn off' or 'off'" + ephemeral IP address: "'ephemeral external IP address'" + fewer data: "'less data'" + file name: "'filename'" + firewalls: "'firewall rules'" + functionality: "'capability' or 'feature'" + Google account: "'Google Account'" + Google accounts: "'Google Accounts'" + Googling: "'search with Google'" + grayed-out: "'unavailable'" + HTTPs: "'HTTPS'" + in order to: "'to'" + ingest: "'import' or 'load'" + k8s: "'Kubernetes'" + long press: "'touch & hold'" + network IP address: "'internal IP address'" + omnibox: "'address bar'" + open-source: "'open source'" + overview screen: "'recents screen'" + regex: "'regular expression'" + SHA1: "'SHA-1' or 'HAS-SHA1'" + sign into: "'sign in to'" + sign-?on: "'single sign-on'" + static IP address: "'static external IP address'" + stylesheet: "'style sheet'" + synch: "'sync'" + tablename: "'table name'" + tablet: "'device'" + touch: "'tap'" + url: "'URL'" + vs\.: "'versus'" + World Wide Web: "'web'" diff --git a/.github/styles/Google/meta.json b/.github/styles/Google/meta.json new file mode 100644 index 00000000..3ae5fb21 --- /dev/null +++ b/.github/styles/Google/meta.json @@ -0,0 +1,16 @@ +{ + "author": "Joseph Kato", + "description": "A Vale-compatible implementation of the Microsoft Writing Style Guide.", + "email": "support@errata.ai", + "lang": "en", + "url": "https://github.com/errata-ai/Google/releases/latest/download/Google.zip", + "feed": "https://github.com/errata-ai/Google/releases.atom", + "issues": "https://github.com/errata-ai/Google/issues/new", + "license": "MIT", + "name": "Google", + "sources": [ + "https://developers.google.com/style/" + ], + "vale_version": ">=1.0.0", + "coverage": 0.0 +} diff --git a/.github/styles/Google/vocab.txt b/.github/styles/Google/vocab.txt new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/.github/styles/Google/vocab.txt diff --git a/.github/styles/VyOS/Terminology.yml b/.github/styles/VyOS/Terminology.yml new file mode 100644 index 00000000..cd0c5089 --- /dev/null +++ b/.github/styles/VyOS/Terminology.yml @@ -0,0 +1,9 @@ +extends: substitution +message: Prefer '%s' over '%s' +ignorecase: false +level: error +swap: + vyos: VyOS + Vyos: VyOS + VYOS: VyOS + Gre: GRE
\ No newline at end of file diff --git a/.github/vyos-linter.py b/.github/vyos-linter.py new file mode 100644 index 00000000..05bb6bbb --- /dev/null +++ b/.github/vyos-linter.py @@ -0,0 +1,162 @@ +import os +import re +import ipaddress +import sys +import ast + +IPV4SEG = r'(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])' +IPV4ADDR = r'(?:(?:' + IPV4SEG + r'\.){3,3}' + IPV4SEG + r')' +IPV6SEG = r'(?:(?:[0-9a-fA-F]){1,4})' +IPV6GROUPS = ( + r'(?:' + IPV6SEG + r':){7,7}' + IPV6SEG, # 1:2:3:4:5:6:7:8 + r'(?:\s' + IPV6SEG + r':){1,7}:', # 1:: 1:2:3:4:5:6:7:: + r'(?:' + IPV6SEG + r':){1,6}:' + IPV6SEG, # 1::8 1:2:3:4:5:6::8 1:2:3:4:5:6::8 + r'(?:' + IPV6SEG + r':){1,5}(?::' + IPV6SEG + r'){1,2}', # 1::7:8 1:2:3:4:5::7:8 1:2:3:4:5::8 + r'(?:' + IPV6SEG + r':){1,4}(?::' + IPV6SEG + r'){1,3}', # 1::6:7:8 1:2:3:4::6:7:8 1:2:3:4::8 + r'(?:' + IPV6SEG + r':){1,3}(?::' + IPV6SEG + r'){1,4}', # 1::5:6:7:8 1:2:3::5:6:7:8 1:2:3::8 + r'(?:' + IPV6SEG + r':){1,2}(?::' + IPV6SEG + r'){1,5}', # 1::4:5:6:7:8 1:2::4:5:6:7:8 1:2::8 + IPV6SEG + r':(?:(?::' + IPV6SEG + r'){1,6})', # 1::3:4:5:6:7:8 1::3:4:5:6:7:8 1::8 + r':(?:(?::' + IPV6SEG + r'){1,7}|:)', # ::2:3:4:5:6:7:8 ::2:3:4:5:6:7:8 ::8 :: + r'fe80:(?::' + IPV6SEG + r'){0,4}%[0-9a-zA-Z]{1,}', # fe80::7:8%eth0 fe80::7:8%1 (link-local IPv6 addresses with zone index) + r'::(?:ffff(?::0{1,4}){0,1}:){0,1}[^\s:]' + IPV4ADDR, # ::255.255.255.255 ::ffff:255.255.255.255 ::ffff:0:255.255.255.255 (IPv4-mapped IPv6 addresses and IPv4-translated addresses) + r'(?:' + IPV6SEG + r':){1,4}:[^\s:]' + IPV4ADDR, # 2001:db8:3:4::192.0.2.33 64:ff9b::192.0.2.33 (IPv4-Embedded IPv6 Address) +) +IPV6ADDR = '|'.join(['(?:{})'.format(g) for g in IPV6GROUPS[::-1]]) # Reverse rows for greedy match + +MAC = r'([0-9A-F]{2}[:-]){5}([0-9A-F]{2})' + +NUMBER = r"([\s']\d+[\s'])" + + +def lint_mac(cnt, line): + mac = re.search(MAC, line, re.I) + if mac is not None: + mac = mac.group() + u_mac = re.search(r'((00)[:-](53)([:-][0-9A-F]{2}){4})', mac, re.I) + m_mac = re.search(r'((90)[:-](10)([:-][0-9A-F]{2}){4})', mac, re.I) + if u_mac is None and m_mac is None: + return (f"Use MAC reserved for Documentation (RFC7042): {mac}", cnt, 'error') + + +def lint_ipv4(cnt, line): + ip = re.search(IPV4ADDR, line, re.I) + if ip is not None: + ip = ipaddress.ip_address(ip.group().strip(' ')) + # https://docs.python.org/3/library/ipaddress.html#ipaddress.IPv4Address.is_private + if ip.is_private is False and ip.is_multicast is False: + return (f"Use IPv4 reserved for Documentation (RFC 5737) or private Space: {ip}", cnt, 'error') + + +def lint_ipv6(cnt, line): + ip = re.search(IPV6ADDR, line, re.I) + if ip is not None: + ip = ipaddress.ip_address(ip.group().strip(' ')) + # https://docs.python.org/3/library/ipaddress.html#ipaddress.IPv4Address.is_private + if ip.is_private is False and ip.is_multicast is False: + return (f"Use IPv6 reserved for Documentation (RFC 3849) or private Space: {ip}", cnt, 'error') + + +def lint_AS(cnt, line): + number = re.search(NUMBER, line, re.I) + if number: + pass + # find a way to detect AS numbers + + +def lint_linelen(cnt, line): + if len(line) > 80: + return (f"Line too long: len={len(line)}", cnt, 'warning') + + +def handle_file(path, file): + errors = [] + path = '/'.join(path) + filepath = f"{path}/{file}" + try: + with open(filepath) as fp: + line = fp.readline() + cnt = 1 + while line: + err_mac = lint_mac(cnt, line.strip()) + err_ip4 = lint_ipv4(cnt, line.strip()) + err_ip6 = lint_ipv6(cnt, line.strip()) + err_len = lint_linelen(cnt, line.strip()) + if err_mac: + errors.append(err_mac) + if err_ip4: + errors.append(err_ip4) + if err_ip6: + errors.append(err_ip6) + if err_len: + errors.append(err_len) + line = fp.readline() + cnt += 1 + finally: + fp.close() + + if len(errors) > 0: + print(f"File: {filepath}") + for error in errors: + print(error) + print('') + return False + +def handle_file_action(filepath): + errors = [] + try: + with open(filepath) as fp: + line = fp.readline() + cnt = 1 + while line: + err_mac = lint_mac(cnt, line.strip()) + err_ip4 = lint_ipv4(cnt, line.strip()) + err_ip6 = lint_ipv6(cnt, line.strip()) + err_len = lint_linelen(cnt, line.strip()) + if err_mac: + errors.append(err_mac) + if err_ip4: + errors.append(err_ip4) + if err_ip6: + errors.append(err_ip6) + if err_len: + errors.append(err_len) + line = fp.readline() + cnt += 1 + finally: + fp.close() + + if len(errors) > 0: + ''' + "::{$type} file={$filename},line={$line},col=$column::{$log}" + ''' + print(f"File: {filepath}") + for error in errors: + print(f"::{error[2]} file={filepath},line={error[1]}::{error[0]}") + print('') + return False + + +def main(): + bool_error = True + print('start') + try: + files = ast.literal_eval(sys.argv[1]) + for file in files: + print(file) + if file[-4:] == ".rst": + if handle_file_action(file) is False: + bool_error = False + except Exception as e: + print(e) + for root, dirs, files in os.walk("../docs"): + path = root.split(os.sep) + for file in files: + if file[-4:] == ".rst": + if handle_file(path, file) is False: + bool_error = False + return bool_error + + +if __name__ == "__main__": + if main() == False: + exit(1) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 00000000..b6797ce0 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,32 @@ +name: Linting +on: + pull_request: + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: File Changes + id: file_changes + uses: trilom/file-changes-action@v1.2.3 + + - name: Vale + uses: errata-ai/vale-action@v1.3.0 + with: + files: '${{ steps.file_changes.outputs.files_modified }}' + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: run python based linter + run: python .github/vyos-linter.py '${{ steps.file_changes.outputs.files_modified }}' + + env: + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} + + diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..d3d92138 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "docs/_include/vyos-1x"] + path = docs/_include/vyos-1x + url = https://github.com/vyos/vyos-1x + branch = current diff --git a/vale.ini b/vale.ini new file mode 100644 index 00000000..b7dde1d8 --- /dev/null +++ b/vale.ini @@ -0,0 +1,16 @@ +StylesPath = .github/styles +MinAlertLevel = suggestion + +SkippedScopes = script, style, pre, figure, img, a, code + + +[*.rst] +BasedOnStyles = VyOS, Google + +Google.DateFormat = YES +vale.GenderBias = NO +vale.Hedging = NO +vale.Redundancy = NO +vale.Repetition = YES +vale.Uncomparables = NO +proselint.GenderBias = NO
\ No newline at end of file |