diff --git a/.github/actions/spelling/README.md b/.github/actions/spelling/README.md new file mode 100644 index 00000000..8dd5e9f8 --- /dev/null +++ b/.github/actions/spelling/README.md @@ -0,0 +1,16 @@ +# check-spelling/check-spelling configuration + +File | Purpose | Format | Info +-|-|-|- +[allow.txt](allow.txt) | Add words to the dictionary | one word per line (only letters and `'`s allowed) | [allow](https://github.com/check-spelling/check-spelling/wiki/Configuration#allow) +[reject.txt](reject.txt) | Remove words from the dictionary (after allow) | grep pattern matching whole dictionary words | [reject](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-reject) +[excludes.txt](excludes.txt) | Files to ignore entirely | perl regular expression | [excludes](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-excludes) +[only.txt](only.txt) | Only check matching files (applied after excludes) | perl regular expression | [only](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-only) +[patterns.txt](patterns.txt) | Patterns to ignore from checked lines | perl regular expression (order matters, first match wins) | [patterns](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-patterns) +[candidate.patterns](candidate.patterns) | Patterns that might be worth adding to [patterns.txt](patterns.txt) | perl regular expression with optional comment block introductions (all matches will be suggested) | [candidates](https://github.com/check-spelling/check-spelling/wiki/Feature:-Suggest-patterns) +[line_forbidden.patterns](line_forbidden.patterns) | Patterns to flag in checked lines | perl regular expression (order matters, first match wins) | [patterns](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-patterns) +[expect.txt](expect.txt) | Expected words that aren't in the dictionary | one word per line (sorted, alphabetically) | [expect](https://github.com/check-spelling/check-spelling/wiki/Configuration#expect) +[advice.md](advice.md) | Supplement for GitHub comment when unrecognized words are found | GitHub Markdown | [advice](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-advice) + +Note: you can replace any of these files with a directory by the same name (minus the suffix) +and then include multiple files inside that directory (with that suffix) to merge multiple files together. diff --git a/.github/actions/spelling/advice.md b/.github/actions/spelling/advice.md new file mode 100644 index 00000000..a32d1090 --- /dev/null +++ b/.github/actions/spelling/advice.md @@ -0,0 +1,31 @@ + +
If the flagged items are :exploding_head: false positives + +If items relate to a ... +* binary file (or some other file you wouldn't want to check at all). + + Please add a file path to the `excludes.txt` file matching the containing file. + + File paths are Perl 5 Regular Expressions - you can [test]( +https://www.regexplanet.com/advanced/perl/) yours before committing to verify it will match your files. + + `^` refers to the file's path from the root of the repository, so `^README\.md$` would exclude [README.md]( +../tree/HEAD/README.md) (on whichever branch you're using). + +* well-formed pattern. + + If you can write a [pattern]( +https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-patterns +) that would match it, + try adding it to the `patterns.txt` file. + + Patterns are Perl 5 Regular Expressions - you can [test]( +https://www.regexplanet.com/advanced/perl/) yours before committing to verify it will match your lines. + + Note that patterns can't match multiline strings. + +
+ + +:steam_locomotive: If you're seeing this message and your PR is from a branch that doesn't have check-spelling, +please merge to your PR's base branch to get the version configured for your repository. diff --git a/.github/actions/spelling/allow.txt b/.github/actions/spelling/allow.txt new file mode 100644 index 00000000..61567618 --- /dev/null +++ b/.github/actions/spelling/allow.txt @@ -0,0 +1,5 @@ +github +https +ssh +ubuntu +workarounds diff --git a/.github/actions/spelling/candidate.patterns b/.github/actions/spelling/candidate.patterns new file mode 100644 index 00000000..53f282b9 --- /dev/null +++ b/.github/actions/spelling/candidate.patterns @@ -0,0 +1,787 @@ +# Repeated letters +\b([A-Za-z])\g{-1}{2,}\b + +# marker to ignore all code on line +^.*/\* #no-spell-check-line \*/.*$ +# marker to ignore all code on line +^.*\bno-spell-check(?:-line|)(?:\s.*|)$ + +# https://cspell.org/configuration/document-settings/ +# cspell inline +^.*\b[Cc][Ss][Pp][Ee][Ll]{2}:\s*[Dd][Ii][Ss][Aa][Bb][Ll][Ee]-[Ll][Ii][Nn][Ee]\b + +# copyright +Copyright (?:\([Cc]\)|)(?:[-\d, ]|and)+(?: [A-Z][a-z]+ [A-Z][a-z]+,?)+ + +# patch hunk comments +^@@ -\d+(?:,\d+|) \+\d+(?:,\d+|) @@ .* +# git index header +index (?:[0-9a-z]{7,40},|)[0-9a-z]{7,40}\.\.[0-9a-z]{7,40} + +# file permissions +['"`\s][-bcdLlpsw](?:[-r][-w][-Ssx]){2}[-r][-w][-SsTtx]\+?['"`\s] + +# css fonts +\bfont(?:-family|):[^;}]+ + +# css url wrappings +\burl\([^)]+\) + +# cid urls +(['"])cid:.*?\g{-1} + +# data url in parens +\(data:(?:[^) ][^)]*?|)(?:[A-Z]{3,}|[A-Z][a-z]{2,}|[a-z]{3,})[^)]*\) +# data url in quotes +([`'"])data:(?:[^ `'"].*?|)(?:[A-Z]{3,}|[A-Z][a-z]{2,}|[a-z]{3,}).*\g{-1} +# data url +\bdata:[-a-zA-Z=;:/0-9+_]*,\S* + +# https/http/file urls +(?:\b(?:https?|ftp|file)://)[-A-Za-z0-9+&@#/*%?=~_|!:,.;]+[-A-Za-z0-9+&@#/*%=~_|] + +# mailto urls +#mailto:[-a-zA-Z=;:/?%&0-9+@._]{3,} + +# magnet urls +magnet:[?=:\w]+ + +# magnet urls +"magnet:[^"]+" + +# obs: +"obs:[^"]*" + +# The `\b` here means a break, it's the fancy way to handle urls, but it makes things harder to read +# In this examples content, I'm using a number of different ways to match things to show various approaches +# asciinema +\basciinema\.org/a/[0-9a-zA-Z]+ + +# asciinema v2 +^\[\d+\.\d+, "[io]", ".*"\]$ + +# apple +\bdeveloper\.apple\.com/[-\w?=/]+ +# Apple music +\bembed\.music\.apple\.com/fr/playlist/usr-share/[-\w.]+ + +# appveyor api +\bci\.appveyor\.com/api/projects/status/[0-9a-z]+ +# appveyor project +\bci\.appveyor\.com/project/(?:[^/\s"]*/){2}builds?/\d+/job/[0-9a-z]+ + +# Amazon + +# Amazon +\bamazon\.com/[-\w]+/(?:dp/[0-9A-Z]+|) +# AWS ARN +arn:aws:[-/:\w]+ +# AWS S3 +\b\w*\.s3[^.]*\.amazonaws\.com/[-\w/&#%_?:=]* +# AWS execute-api +\b[0-9a-z]{10}\.execute-api\.[-0-9a-z]+\.amazonaws\.com\b +# AWS ELB +\b\w+\.[-0-9a-z]+\.elb\.amazonaws\.com\b +# AWS SNS +\bsns\.[-0-9a-z]+.amazonaws\.com/[-\w/&#%_?:=]* +# AWS VPC +vpc-\w+ + +# While you could try to match `http://` and `https://` by using `s?` in `https?://`, sometimes there +# YouTube url +\b(?:(?:www\.|)youtube\.com|youtu.be)/(?:channel/|embed/|user/|playlist\?list=|watch\?v=|v/|)[-a-zA-Z0-9?&=_%]* +# YouTube music +\bmusic\.youtube\.com/youtubei/v1/browse(?:[?&]\w+=[-a-zA-Z0-9?&=_]*) +# YouTube tag +<\s*youtube\s+id=['"][-a-zA-Z0-9?_]*['"] +# YouTube image +\bimg\.youtube\.com/vi/[-a-zA-Z0-9?&=_]* +# Google Accounts +\baccounts.google.com/[-_/?=.:;+%&0-9a-zA-Z]* +# Google Analytics +\bgoogle-analytics\.com/collect.[-0-9a-zA-Z?%=&_.~]* +# Google APIs +\bgoogleapis\.(?:com|dev)/[a-z]+/(?:v\d+/|)[a-z]+/[-@:./?=\w+|&]+ +# Google Artifact Registry +\.pkg\.dev(?:/[-\w]+)+(?::[-\w]+|) +# Google Storage +\b[-a-zA-Z0-9.]*\bstorage\d*\.googleapis\.com(?:/\S*|) +# Google Calendar +\bcalendar\.google\.com/calendar(?:/u/\d+|)/embed\?src=[@./?=\w&%]+ +\w+\@group\.calendar\.google\.com\b +# Google DataStudio +\bdatastudio\.google\.com/(?:(?:c/|)u/\d+/|)(?:embed/|)(?:open|reporting|datasources|s)/[-0-9a-zA-Z]+(?:/page/[-0-9a-zA-Z]+|) +# The leading `/` here is as opposed to the `\b` above +# ... a short way to match `https://` or `http://` since most urls have one of those prefixes +# Google Docs +/docs\.google\.com/[a-z]+/(?:ccc\?key=\w+|(?:u/\d+|d/(?:e/|)[0-9a-zA-Z_-]+/)?(?:edit\?[-\w=#.]*|/\?[\w=&]*|)) +# Google Drive +\bdrive\.google\.com/(?:file/d/|open)[-0-9a-zA-Z_?=]* +# Google Groups +\bgroups\.google\.com(?:/[a-z]+/(?:#!|)[^/\s"]+)* +# Google Maps +\bmaps\.google\.com/maps\?[\w&;=]* +# Google themes +themes\.googleusercontent\.com/static/fonts/[^/\s"]+/v\d+/[^.]+. +# Google CDN +\bclients2\.google(?:usercontent|)\.com[-0-9a-zA-Z/.]* +# Goo.gl +/goo\.gl/[a-zA-Z0-9]+ +# Google Chrome Store +\bchrome\.google\.com/webstore/detail/[-\w]*(?:/\w*|) +# Google Books +\bgoogle\.(?:\w{2,4})/books(?:/\w+)*\?[-\w\d=&#.]* +# Google Fonts +\bfonts\.(?:googleapis|gstatic)\.com/[-/?=:;+&0-9a-zA-Z]* +# Google Forms +\bforms\.gle/\w+ +# Google Scholar +\bscholar\.google\.com/citations\?user=[A-Za-z0-9_]+ +# Google Colab Research Drive +\bcolab\.research\.google\.com/drive/[-0-9a-zA-Z_?=]* +# Google Cloud regions +(?:us|(?:north|south)america|europe|asia|australia|me|africa)-(?:north|south|east|west|central){1,2}\d+ + +# GitHub SHAs (api) +\bapi.github\.com/repos(?:/[^/\s"]+){3}/[0-9a-f]+\b +# GitHub SHAs (markdown) +(?:\[`?[0-9a-f]+`?\]\(https:/|)/(?:www\.|)github\.com(?:/[^/\s"]+){2,}(?:/[^/\s")]+)(?:[0-9a-f]+(?:[-0-9a-zA-Z/#.]*|)\b|) +# GitHub SHAs +\bgithub\.com(?:/[^/\s"]+){2}[@#][0-9a-f]+\b +# GitHub SHA refs +\[([0-9a-f]+)\]\(https://(?:www\.|)github.com/[-\w]+/[-\w]+/commit/\g{-1}[0-9a-f]* +# GitHub wiki +\bgithub\.com/(?:[^/]+/){2}wiki/(?:(?:[^/]+/|)_history|[^/]+(?:/_compare|)/[0-9a-f.]{40,})\b +# githubusercontent +/[-a-z0-9]+\.githubusercontent\.com/[-a-zA-Z0-9?&=_\/.]* +# githubassets +\bgithubassets.com/[0-9a-f]+(?:[-/\w.]+) +# gist github +\bgist\.github\.com/[^/\s"]+/[0-9a-f]+ +# git.io +\bgit\.io/[0-9a-zA-Z]+ +# GitHub JSON +"node_id": "[-a-zA-Z=;:/0-9+_]*" +# Contributor +\[[^\]]+\]\(https://github\.com/[^/\s"]+/?\) +# GHSA +GHSA(?:-[0-9a-z]{4}){3} + +# GitHub actions +\buses:\s+(['"]?)[-\w.]+/[-\w./]+@[-\w.]+\g{-1} + +# GitLab commit +\bgitlab\.[^/\s"]*/\S+/\S+/commit/[0-9a-f]{7,16}#[0-9a-f]{40}\b +# GitLab merge requests +\bgitlab\.[^/\s"]*/\S+/\S+/-/merge_requests/\d+/diffs#[0-9a-f]{40}\b +# GitLab uploads +\bgitlab\.[^/\s"]*/uploads/[-a-zA-Z=;:/0-9+]* +# GitLab commits +\bgitlab\.[^/\s"]*/(?:[^/\s"]+/){2}commits?/[0-9a-f]+\b + +# #includes +^\s*#include\s*(?:<.*?>|".*?") + +# #pragma lib +^\s*#pragma comment\(lib, ".*?"\) + +# binance +accounts\.binance\.com/[a-z/]*oauth/authorize\?[-0-9a-zA-Z&%]* + +# bitbucket diff +\bapi\.bitbucket\.org/\d+\.\d+/repositories/(?:[^/\s"]+/){2}diff(?:stat|)(?:/[^/\s"]+){2}:[0-9a-f]+ +# bitbucket repositories commits +\bapi\.bitbucket\.org/\d+\.\d+/repositories/(?:[^/\s"]+/){2}commits?/[0-9a-f]+ +# bitbucket commits +\bbitbucket\.org/(?:[^/\s"]+/){2}commits?/[0-9a-f]+ + +# bit.ly +\bbit\.ly/\w+ + +# bitrise +\bapp\.bitrise\.io/app/[0-9a-f]*/[\w.?=&]* + +# bootstrapcdn.com +\bbootstrapcdn\.com/[-./\w]+ + +# cdn.cloudflare.com +\bcdnjs\.cloudflare\.com/[./\w]+ + +# circleci +\bcircleci\.com/gh(?:/[^/\s"]+){1,5}.[a-z]+\?[-0-9a-zA-Z=&]+ + +# gitter +\bgitter\.im(?:/[^/\s"]+){2}\?at=[0-9a-f]+ + +# gravatar +\bgravatar\.com/avatar/[0-9a-f]+ + +# ibm +[a-z.]*ibm\.com/[-_#=:%!?~.\\/\d\w]* + +# imgur +\bimgur\.com/[^.]+ + +# Internet Archive +\barchive\.org/web/\d+/(?:[-\w.?,'/\\+&%$#_:]*) + +# discord +/discord(?:app\.com|\.gg)/(?:invite/)?[a-zA-Z0-9]{7,} + +# Disqus +\bdisqus\.com/[-\w/%.()!?&=_]* + +# medium link +\blink\.medium\.com/[a-zA-Z0-9]+ +# medium +\bmedium\.com/@?[^/\s"]+/[-\w]+ + +# microsoft +\b(?:https?://|)(?:(?:(?:blogs|download\.visualstudio|docs|msdn2?|research)\.|)microsoft|blogs\.msdn)\.co(?:m|\.\w\w)/[-_a-zA-Z0-9()=./%]* +# powerbi +\bapp\.powerbi\.com/reportEmbed/[^"' ]* +# vs devops +\bvisualstudio.com(?::443|)/[-\w/?=%&.]* +# microsoft store +\bmicrosoft\.com/store/apps/\w+ + +# mvnrepository.com +\bmvnrepository\.com/[-0-9a-z./]+ + +# now.sh +/[0-9a-z-.]+\.now\.sh\b + +# oracle +\bdocs\.oracle\.com/[-0-9a-zA-Z./_?#&=]* + +# chromatic.com +/\S+.chromatic.com\S*[")] + +# codacy +\bapi\.codacy\.com/project/badge/Grade/[0-9a-f]+ + +# compai +\bcompai\.pub/v1/png/[0-9a-f]+ + +# mailgun api +\.api\.mailgun\.net/v3/domains/[0-9a-z]+\.mailgun.org/messages/[0-9a-zA-Z=@]* +# mailgun +\b[0-9a-z]+.mailgun.org + +# /message-id/ +/message-id/[-\w@./%]+ + +# Reddit +\breddit\.com/r/[/\w_]* + +# requestb.in +\brequestb\.in/[0-9a-z]+ + +# sched +\b[a-z0-9]+\.sched\.com\b + +# Slack url +slack://[a-zA-Z0-9?&=]+ +# Slack +\bslack\.com/[-0-9a-zA-Z/_~?&=.]* +# Slack edge +\bslack-edge\.com/[-a-zA-Z0-9?&=%./]+ +# Slack images +\bslack-imgs\.com/[-a-zA-Z0-9?&=%.]+ + +# shields.io +\bshields\.io/[-\w/%?=&.:+;,]* + +# stackexchange -- https://stackexchange.com/feeds/sites +\b(?:askubuntu|serverfault|stack(?:exchange|overflow)|superuser).com/(?:questions/\w+/[-\w]+|a/) + +# Sentry +[0-9a-f]{32}\@o\d+\.ingest\.sentry\.io\b + +# Twitter markdown +\[@[^[/\]:]*?\]\(https://twitter.com/[^/\s"')]*(?:/status/\d+(?:\?[-_0-9a-zA-Z&=]*|)|)\) +# Twitter hashtag +\btwitter\.com/hashtag/[\w?_=&]* +# Twitter status +\btwitter\.com/[^/\s"')]*(?:/status/\d+(?:\?[-_0-9a-zA-Z&=]*|)|) +# Twitter profile images +\btwimg\.com/profile_images/[_\w./]* +# Twitter media +\btwimg\.com/media/[-_\w./?=]* +# Twitter link shortened +\bt\.co/\w+ + +# facebook +\bfburl\.com/[0-9a-z_]+ +# facebook CDN +\bfbcdn\.net/[\w/.,]* +# facebook watch +\bfb\.watch/[0-9A-Za-z]+ + +# dropbox +\bdropbox\.com/sh?/[^/\s"]+/[-0-9A-Za-z_.%?=&;]+ + +# ipfs protocol +ipfs://[0-9a-zA-Z]{3,} +# ipfs url +/ipfs/[0-9a-zA-Z]{3,} + +# w3 +\bw3\.org/[-0-9a-zA-Z/#.]+ + +# loom +\bloom\.com/embed/[0-9a-f]+ + +# regex101 +\bregex101\.com/r/[^/\s"]+/\d+ + +# figma +\bfigma\.com/file(?:/[0-9a-zA-Z]+/)+ + +# freecodecamp.org +\bfreecodecamp\.org/[-\w/.]+ + +# image.tmdb.org +\bimage\.tmdb\.org/[/\w.]+ + +# mermaid +\bmermaid\.ink/img/[-\w]+|\bmermaid-js\.github\.io/mermaid-live-editor/#/edit/[-\w]+ + +# Wikipedia +\ben\.wikipedia\.org/wiki/[-\w%.#]+ + +# gitweb +[^"\s]+/gitweb/\S+;h=[0-9a-f]+ + +# HyperKitty lists +/archives/list/[^@/]+@[^/\s"]*/message/[^/\s"]*/ + +# lists +/thread\.html/[^"\s]+ + +# list-management +\blist-manage\.com/subscribe(?:[?&](?:u|id)=[0-9a-f]+)+ + +# kubectl.kubernetes.io/last-applied-configuration +"kubectl.kubernetes.io/last-applied-configuration": ".*" + +# pgp +\bgnupg\.net/pks/lookup[?&=0-9a-zA-Z]* + +# Spotify +\bopen\.spotify\.com/embed/playlist/\w+ + +# Mastodon +\bmastodon\.[-a-z.]*/(?:media/|@)[?&=0-9a-zA-Z_]* + +# scastie +\bscastie\.scala-lang\.org/[^/]+/\w+ + +# images.unsplash.com +\bimages\.unsplash\.com/(?:(?:flagged|reserve)/|)[-\w./%?=%&.;]+ + +# pastebin +\bpastebin\.com/[\w/]+ + +# heroku +\b\w+\.heroku\.com/source/archive/\w+ + +# quip +\b\w+\.quip\.com/\w+(?:(?:#|/issues/)\w+)? + +# badgen.net +\bbadgen\.net/badge/[^")\]'\s]+ + +# statuspage.io +\w+\.statuspage\.io\b + +# media.giphy.com +\bmedia\.giphy\.com/media/[^/]+/[\w.?&=]+ + +# tinyurl +\btinyurl\.com/\w+ + +# codepen +\bcodepen\.io/[\w/]+ + +# registry.npmjs.org +\bregistry\.npmjs\.org/(?:@[^/"']+/|)[^/"']+/-/[-\w@.]+ + +# getopts +\bgetopts\s+(?:"[^"]+"|'[^']+') + +# ANSI color codes +(?:\\(?:u00|x)1[Bb]|\\03[1-7]|\x1b|\\u\{1[Bb]\})\[\d+(?:;\d+)*m + +# URL escaped characters +%[0-9A-F][A-F](?=[A-Za-z]) +# lower URL escaped characters +%[0-9a-f][a-f](?=[a-z]{2,}) +# IPv6 +\b(?:[0-9a-fA-F]{0,4}:){3,7}[0-9a-fA-F]{0,4}\b +# c99 hex digits (not the full format, just one I've seen) +0x[0-9a-fA-F](?:\.[0-9a-fA-F]*|)[pP] +# Punycode +\bxn--[-0-9a-z]+ +# sha +sha\d+:[0-9a-f]*?[a-f]{3,}[0-9a-f]* +# sha-... -- uses a fancy capture +(\\?['"]|")[0-9a-f]{40,}\g{-1} +# hex runs +\b(?=(?:[a-fA-F]{0,2}\d)*[a-fA-F]{3})[0-9a-fA-F]{16,}\b +# hex in url queries +=[0-9a-fA-F]*?(?:[A-F]{3,}|[a-f]{3,})[0-9a-fA-F]*?& +# ssh +(?:ssh-\S+|-nistp256) [-a-zA-Z=;:/0-9+]{12,} + +# PGP +\b(?:[0-9A-F]{4} ){9}[0-9A-F]{4}\b +# GPG keys +\b(?:[0-9A-F]{4} ){5}(?: [0-9A-F]{4}){5}\b +# Well known gpg keys +.well-known/openpgpkey/[\w./]+ + +# pki +-----BEGIN.*-----END + +# pki (base64) +LS0tLS1CRUdJT.* + +# C# includes +#^\s*using [^;]+; + +# uuid: +\b[0-9a-fA-F]{8}-(?:[0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}\b +# hex digits including css/html color classes: +(?:[\\0][xX]|\\u\{?|[uU]\+|#x?|%23|&H)[0-9_a-fA-FgGrR]*?[a-fA-FgGrR]{2,}[0-9_a-fA-FgGrR]*(?:[uUlL]{0,3}|[iu]\d+)\b + +# integrity +integrity=(['"])(?:\s*sha\d+-[-a-zA-Z=;:/0-9+]{40,})+\g{-1} + +# https://www.gnu.org/software/groff/manual/groff.html +# man troff content +\\f[BCIPR] +# '/" +\\\([ad]q + +# .desktop mime types +^MimeTypes?=.*$ +# .desktop localized entries +^[A-Z][a-z]+\[[a-z]+\]=.*$ +# Localized .desktop content +Name\[[^\]]+\]=.* + +# IServiceProvider / isAThing +(?:(?:\b|_|(?<=[a-z]))I|(?:\b|_)(?:nsI|isA))(?=(?:[A-Z][a-z]{2,})+(?:[A-Z\d]|\b)) + +# python +#\b(?i)py(?!gments|gmy|lon|ramid|ro|th)(?=[a-z]{2,}) + +# crypt +(['"])\$2[ayb]\$.{56}\g{-1} + +# apache/old crypt +(['"]|)\$+(?:apr|)1\$+.{8}\$+.{22}\g{-1} + +# sha1 hash +\{SHA\}[-a-zA-Z=;:/0-9+]{3,} + +# machine learning (?) +\b(?i)ml(?=[a-z]{2,}) + +# scrypt / argon +\$(?:scrypt|argon\d+[di]*)\$\S+ + +# go.sum +\bh1:\S+ + +# golang print-f-style functions +(?i)(?<=append|comma|debug|equal|err|error|info|log|name|print|skip|scan|trace|true|warn|warning|wrap)f\( + +# imports +^import\s+(?:(?:static|type)\s+|)(?:[\w.]|\{\s*\w*?(?:,\s*(?:\w*|\*))+\s*\})+(?:\s+from (['"]).*?\g{-1}|) + +# scala modules +("[^"]+"\s*%%?\s*){2,3}"[^"]+" + +# container images +image: [-\w./:@]+ + +# Docker images +^\s*(?i)FROM\s+\S+:\S+(?:\s+AS\s+\S+|) + +# `docker images` REPOSITORY TAG IMAGE ID CREATED SIZE +\s*\S+/\S+\s+\S+\s+[0-9a-f]{8,}\s+\d+\s+(?:hour|day|week)s ago\s+[\d.]+[KMGT]B + +# Intel intrinsics +_mm\d*_(?!dd)\w+ + +# Input to GitHub JSON +content: (['"])[-a-zA-Z=;:/0-9+]*=\g{-1} + +# This does not cover multiline strings, if your repository has them, +# you'll want to remove the `(?=.*?")` suffix. +# The `(?=.*?")` suffix should limit the false positives rate +# printf +%(?:(?:(?:hh?|ll?|[jzt])?[diuoxn]|l?[cs]|L?[fega]|p)(?=[a-z]{2,})|(?:X|L?[FEGA])(?=[a-zA-Z]{2,}))(?!%)(?=[_a-zA-Z]+(?!%)\b)(?=.*?['"]) + +# Alternative printf +# %s +%(?:s(?=[a-z]{2,}))(?!%)(?=[_a-zA-Z]+(?!%[^s])\b)(?=.*?['"]) + +# Python string prefix / binary prefix +# Note that there's a high false positive rate, remove the `?=` and search for the regex to see if the matches seem like reasonable strings +(?|m([|!/@#,;']).*?\g{-1}) + +# perl qr regex +(?|\(.*?\)|([|!/@#,;']).*?\g{-1}) + +# perl run +perl(?:\s+-[a-zA-Z]\w*)+ + +# C network byte conversions +#(?:\d|\bh)to(?!ken)(?=[a-z])|to(?=[adhiklpun]\() + +# Go regular expressions +regexp?\.MustCompile\((?:`[^`]*`|".*"|'.*')\) + +# regex choice +\((?:\?:|)[^)|]+\|[^)|][^)]*\) + +# proto +^\s*(\w+)\s\g{-1} = + +# sed regular expressions +sed 's/(?:[^/]*?[a-zA-Z]{3,}[^/]*?/){2} + +# node packages +(["'])@[^/'" ]+/[^/'" ]+\g{-1} + +# go install +go install(?:\s+[a-z]+\.[-@\w/.]+)+ + +# pom.xml +<(?:group|artifact)Id>.*?< + +# jetbrains schema https://youtrack.jetbrains.com/issue/RSRP-489571 +urn:shemas-jetbrains-com + +# Debian changelog severity +[-\w]+ \(.*\) (?:\w+|baseline|unstable|experimental); urgency=(?:low|medium|high|emergency|critical)\b + +# kubernetes pod status lists +# https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase +\w+(?:-\w+)+\s+\d+/\d+\s+(?:Running|Pending|Succeeded|Failed|Unknown)\s+ + +# kubectl - pods in CrashLoopBackOff +\w+-[0-9a-f]+-\w+\s+\d+/\d+\s+CrashLoopBackOff\s+ + +# kubernetes applications +\.apps/[-\w]+ + +# kubernetes object suffix +-[0-9a-f]{10}-\w{5}\s + +# kubernetes crd patterns +^\s*pattern: .*$ + +# posthog secrets +([`'"])phc_[^"',]+\g{-1} + +# xcode + +# xcodeproject scenes +(?:Controller|destination|(?:first|second)Item|ID|id)="\w{3}-\w{2}-\w{3}" + +# xcode api botches +customObjectInstantitationMethod + +# msvc api botches +PrependWithABINamepsace + +# configure flags +.* \| --\w{2,}.*?(?=\w+\s\w+) + +# font awesome classes +\.fa-[-a-z0-9]+ + +# bearer auth +(['"])[Bb]ear[e][r] .{3,}?\g{-1} + +# bearer auth +\b[Bb]ear[e][r]:? [-a-zA-Z=;:/0-9+.]{3,} + +# basic auth +(['"])[Bb]asic [-a-zA-Z=;:/0-9+]{3,}\g{-1} + +# basic auth +: [Bb]asic [-a-zA-Z=;:/0-9+.]{3,} + +# base64 encoded content +([`'"])[-a-zA-Z=;:/0-9+]{3,}=\g{-1} +# base64 encoded content in xml/sgml +>[-a-zA-Z=;:/0-9+]{3,}=?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_]{40,} + +# DNS rr data +(?:\d+\s+){3}(?:[-+/=.\w]{2,}\s*){1,2} + +# encoded-word +=\?[-a-zA-Z0-9"*%]+\?[BQ]\?[^?]{0,75}\?= + +# numerator +\bnumer\b(?=.*denom) + +# Time Zones +\b(?:Africa|Atlantic|America|Antarctica|Arctic|Asia|Australia|Europe|Indian|Pacific)(?:/[-\w]+)+ + +# linux kernel info +^(?:bugs|flags|Features)\s+:.* + +# systemd mode +systemd.*?running in system mode \([-+].*\)$ + +# Lorem +# Update Lorem based on your content (requires `ge` and `w` from https://github.com/jsoref/spelling; and `review` from https://github.com/check-spelling/check-spelling/wiki/Looking-for-items-locally ) +# grep '^[^#].*lorem' .github/actions/spelling/patterns.txt|perl -pne 's/.*i..\?://;s/\).*//' |tr '|' "\n"|sort -f |xargs -n1 ge|perl -pne 's/^[^:]*://'|sort -u|w|sed -e 's/ .*//'|w|review - +# Warning, while `(?i)` is very neat and fancy, if you have some binary files that aren't proper unicode, you might run into: +# ... Operation "substitution (s///)" returns its argument for non-Unicode code point 0x1C19AE (the code point will vary). +# ... You could manually change `(?i)X...` to use `[Xx]...` +# ... or you could add the files to your `excludes` file (a version after 0.0.19 should identify the file path) +#(?:(?:\w|\s|[,.])*\b(?i)(?:amet|consectetur|cursus|dolor|eros|ipsum|lacus|libero|ligula|lorem|magna|neque|nulla|suscipit|tempus)\b(?:\w|\s|[,.])*) + +# Non-English +# Even repositories expecting pure English content can unintentionally have Non-English content... People will occasionally mistakenly enter [homoglyphs](https://en.wikipedia.org/wiki/Homoglyph) which are essentially typos, and using this pattern will mean check-spelling will not complain about them. +# +# If the content to be checked should be written in English and the only Non-English items will be people's names, then you can consider adding this. +# +# Alternatively, if you're using check-spelling v0.0.25+, and you would like to _check_ the Non-English content for spelling errors, you can. For information on how to do so, see: +# https://docs.check-spelling.dev/Feature:-Configurable-word-characters.html#unicode +#[a-zA-Z]*[ÀÁÂÃÄÅÆČÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæčçèéêëìíîïðñòóôõöøùúûüýÿĀāŁłŃńŅņŒœŚśŠšŜŝŸŽžź][a-zA-Z]{3}[a-zA-ZÀÁÂÃÄÅÆČÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæčçèéêëìíîïðñòóôõöøùúûüýÿĀāŁłŃńŅņŒœŚśŠšŜŝŸŽžź]*|[a-zA-Z]{3,}[ÀÁÂÃÄÅÆČÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæčçèéêëìíîïðñòóôõöøùúûüýÿĀāŁłŃńŅņŒœŚśŠšŜŝŸŽžź]|[ÀÁÂÃÄÅÆČÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæčçèéêëìíîïðñòóôõöøùúûüýÿĀāŁłŃńŅņŒœŚśŠšŜŝŸŽžź][a-zA-Z]{3,} + +# highlighted letters +\[[A-Z]\][a-z]+ + +# French +# This corpus only had capital letters, but you probably want lowercase ones as well. +\b[LN]'+[a-z]{2,}\b + +# latex (check-spelling >= 0.0.22) +\\\w{2,}\{ + +# American Mathematical Society (AMS) / Doxygen +TeX/AMS + +# File extensions +\*\.[+\w]+, + +# eslint +"varsIgnorePattern": ".+" + +# nolint +nolint:\s*[\w,]+ + +# Windows short paths +[/\\][^/\\]{5,6}~\d{1,2}(?=[/\\]) + +# Windows Resources with accelerators +\b[A-Z]&[a-z]+\b(?!;) + +# signed off by +(?i)Signed-off-by: .* + +# cygwin paths +/cygdrive/[a-zA-Z]/(?:Program Files(?: \(.*?\)| ?)(?:/[-+.~\\/()\w ]+)*|[-+.~\\/()\w])+ + +# in check-spelling@v0.0.22+, printf markers aren't automatically consumed +# printf markers +(?v# +(?:(?<=[A-Z]{2})V|(?<=[a-z]{2}|[A-Z]{2})v)\d+(?:\b|(?=[a-zA-Z_])) + +# Compiler flags (Unix, Java/Scala) +# Use if you have things like `-Pdocker` and want to treat them as `docker` +(?:^|[\t ,>"'`=(#])-(?:(?:J-|)[DPWXY]|[Llf])(?=[A-Z]{2,}|[A-Z][a-z]|[a-z]{2,}) + +# Compiler flags (Windows / PowerShell) +# This is a subset of the more general compiler flags pattern. +# It avoids matching `-Path` to prevent it from being treated as `ath` +(?:^|[\t ,"'`=(#])-(?:[DPL](?=[A-Z]{2,})|[WXYlf](?=[A-Z]{2,}|[A-Z][a-z]|[a-z]{2,})) + +# Compiler flags (linker) +,-B + +# Library prefix +# e.g., `lib`+`archive`, `lib`+`raw`, `lib`+`unwind` +# (ignores some words that happen to start with `lib`) +(?:\b|_)[Ll]ib(?!era[lt])(?:re(?=office)|era|)(?!ero|erty|rar(?:i(?:an|es)|y))(?=[a-z]) + +# iSCSI iqn (approximate regex) +\biqn\.[0-9]{4}-[0-9]{2}(?:[\.-][a-z][a-z0-9]*)*\b + +# WWNN/WWPN (NAA identifiers) +\b(?:0x)?10[0-9a-f]{14}\b|\b(?:0x|3)?[25][0-9a-f]{15}\b|\b(?:0x|3)?6[0-9a-f]{31}\b + +# curl arguments +\b(?:\\n|)curl(?:\.exe|)(?:\s+-[a-zA-Z]{1,2}\b)*(?:\s+-[a-zA-Z]{3,})(?:\s+-[a-zA-Z]+)* +# set arguments +\b(?:bash|sh|set)(?:\s+[-+][abefimouxE]{1,2})*\s+[-+][abefimouxE]{3,}(?:\s+[-+][abefimouxE]+)* +# tar arguments +\b(?:\\n|)g?tar(?:\.exe|)(?:\s-C \S+|(?:\s+--[-a-zA-Z]+|\s+-[a-zA-Z]+|\s[ABGJMOPRSUWZacdfh-pr-xz]+\b)(?:=[^ ]*|))+ +# tput arguments -- https://man7.org/linux/man-pages/man5/terminfo.5.html -- technically they can be more than 5 chars long... +\btput\s+(?:(?:-[SV]|-T\s*\w+)\s+)*\w{3,5}\b +# macOS temp folders +/var/folders/\w\w/[+\w]+/(?:T|-Caches-)/ +# github runner temp folders +/home/runner/work/_temp/[-_/a-z0-9]+ diff --git a/.github/actions/spelling/excludes.txt b/.github/actions/spelling/excludes.txt new file mode 100644 index 00000000..5475dbed --- /dev/null +++ b/.github/actions/spelling/excludes.txt @@ -0,0 +1,96 @@ +# See https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-excludes +(?:^|/)(?i)COPYRIGHT +(?:^|/)(?i)LICEN[CS]E +(?:^|/)(?i)third[-_]?party/ +(?:^|/)3rdparty/ +(?:^|/)\.keep$ +(?:^|/)generated/ +(?:^|/)go\.sum$ +(?:^|/)jsontestdata\.py$ +(?:^|/)package(?:-lock|)\.json$ +(?:^|/)Pipfile$ +(?:^|/)pyproject.toml +(?:^|/)vendor/ +(?:^|/|\b)requirements(?:-dev|-doc|-test|)\.txt$ +\.a$ +\.ai$ +\.all-contributorsrc$ +\.avi$ +\.bmp$ +\.bz2$ +\.cert?$|\.crt$ +\.class$ +\.coveragerc$ +\.crl$ +\.csr$ +\.dll$ +\.docx?$ +\.drawio$ +\.DS_Store$ +\.eot$ +\.eps$ +\.exe$ +\.gif$ +\.git-blame-ignore-revs$ +\.gitattributes$ +\.gitkeep$ +\.graffle$ +\.gz$ +\.icns$ +\.ico$ +\.ipynb$ +\.jar$ +\.jks$ +\.jpe?g$ +\.key$ +\.lib$ +\.lock$ +\.map$ +\.min\.. +\.mo$ +\.mod$ +\.mp[34]$ +\.o$ +\.ocf$ +\.otf$ +\.p12$ +\.parquet$ +\.pdf$ +\.pem$ +\.pfx$ +\.png$ +\.psd$ +\.pyc$ +\.pylintrc$ +\.qm$ +\.s$ +\.sig$ +\.so$ +\.svgz?$ +\.sys$ +\.tar$ +\.tgz$ +\.tiff?$ +\.ttf$ +\.wav$ +\.webm$ +\.webp$ +\.woff2?$ +\.xcf$ +\.xlsx?$ +\.xpm$ +\.xz$ +\.zip$ +^\.github/actions/spelling/ +^\.github/CODEOWNERS$ +^\Q.github/wordlist.txt\E$ +^\Q.github/workflows/spelling.yml\E$ +^benchmarks/__init__\.py$ +^CODE_OF_CONDUCT\.md$ +^tests/__init__\.py$ +^tests/test_asyncio/__init__\.py$ +^tests/test_graph_utils/__init__\.py$ +^valkey/py\.typed$ +/test_connection_pool\.py$ +/testdata/ +ignore$ diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt new file mode 100644 index 00000000..5e4ef2b4 --- /dev/null +++ b/.github/actions/spelling/expect.txt @@ -0,0 +1,623 @@ +absttl +ACLCAT +aclfile +ACLs +ADDIFNX +addnx +aggregateplan +ahmedsobeh +ahmedszakaria +aia +aiorc +aiovalkey +alertmanager +alertname +ALLSPHINXOPTS +AOF +argvalues +arrappend +arrindex +arrinsert +arrlen +arrpop +arrtrim +aserver +autoclass +autolabeler +automodule +Autosection +autosectionlabel +autouse +avalkey +avgrandom +badssl +barbarbar +bazz +bazzz +bgrewriteaof +bgsave +bitop +bitpos +blmove +blmpop +blpop +bogususer +breakingchange +brpop +brpoplpush +BUCKETSIZE +BUCKETTIMESTAMP +bufflen +bumpepoch +BUSYTIMEFLAG +BYBOX +byfields +bylex +BYRADIUS +byrank +byrevrank +byscore +bysource +bzfp +bzmpop +bzpopmax +bzpopmin +cachetools +cadata +canonname +capath +captest +casesensitive +checkpid +chunklen +ciaoc +ckquorum +clickhouse +clientid +clusterclient +CLUSTERDOWN +cmdname +cmdstat +cmsgpack +cmsincrby +commandmixin +commitish +connstream +consumername +corofunc +countkeysinslot +createconsumer +createrule +crossslot +curvals +cwe +dbsize +dco +Decorrelated +decrby +deff +delconsumer +deleterule +DELIFX +delslots +delslotsrange +deluser +DESTENV +devenv +devhelp +DHE +dic +DICTADD +DICTDEL +DICTDUMP +dirhtml +DIRSTRING +DISMAX +distinctish +distinctishtitle +distincttitle +DOCNORM +DOCSCORE +doctests +doctrees +documentclass +dropindex +echoerr +ENTRIESREAD +evalsha +evictable +exat +excinfo +exconly +EXECABORT +expireat +expiretime +explaincli +extfile +faz +fca +fcall +fieldstrs +filterby +floatreg +flt +flushall +flushconfig +flushslots +flynt +fookey +foomod +foomodule +fromaddr +FROMLONLAT +FROMMEMBER +ftindex +funcname +furo +genindex +genpass +getargspec +getbit +getbuffer +getdel +getex +getkeys +getkeysandflags +GETKEYSINSLOT +getoption +getrange +getredir +getset +grl +Grokzen +groupid +hascontent +haveit +hazmat +hdel +hellobar +hellobarbaz +hellobarbazbar +hexists +hget +hgetall +hhp +hincrby +hincrbyfloat +hkeys +hlen +hmget +hmset +HNSW +hostmetrics +hostnames +hostport +hqx +hrandfield +hscan +hset +hsetnx +hstrlen +htmlhelp +hvals +Hyperlog +HYPERLOGLOG +idef +idletime +ifmodversion +incrby +incrbyfloat +infotype +initbydim +initbyprob +INKEYS +INORDER +insertnx +Instrumentor +intlist +intreg +ipynb +isbn +ISBUSY +ISSUB +jdata +johny +JOINSTR +jset +jsonget +jsonkey +jsonmget +jsons +jsonset +jsonsetexistentialmodifiersshouldsucceed +jtypes +justid +keepttl +keycloak +keyspace +killuser +KInfo +KNN +ktv +kvparams +kvs +kwagrs +kwexpr +kwparams +laddr +lastsave +latexpdf +lbls +lcs +letterpaper +lfu +LIBRARYNAME +libvalkey +lindex +linkcheck +linsert +llen +lmove +lmpop +loadall +loadchunk +loadex +loadfields +lolwut +lorm +lpop +lpos +lpush +lpushx +lrange +lset +Magnocavallo +mailhog +makeinfo +mallocs +MASTERDOWN +maxage +MAXIDLE +MAXITERATIONS +maxmemory +MAXTEXTFIELDS +maxval +mema +memb +memc +memoryviews +mexists +mgetshouldsucceed +minid +minlen +minmatchlen +minval +mkstream +Moby +mockobj +modindex +moduleauthor +movablekeys +mrange +mrevrange +msetnx +msgpack +multikey +multipleoptions +myshardid +nativestr +nbsphinx +nbytes +newobj +newsocket +newtext +newttl +nitpicky +noack +NOAUTH +NOCONTENT +nocreate +nocryptography +nodemap +noeviction +NOFIELDS +NOFREQS +nohl +nojsonfile +nokey +noloop +nomkstream +nooffset +nopass +noq +nostem +NOSTOPWORDS +notakey +notarealkey +NOTREAL +notset +novalues +NSPHINXOPTS +numby +numincrby +numkeys +nummultby +numpat +numreq +numsub +numsubbed +numval +objkeys +objlen +ocsps +odown +ohmytext +oll +omem +onlycluster +onlynoncluster +opensearch +opentelemetry +optin +optval +opvs +otelcol +otlp +pagerefs +pandoc +PAPEROPT +papersize +payloadidx +pdflatex +PEL +pexpire +pexpireat +pexpiretime +pfadd +pfail +pfcount +pfmerge +pmessage +pointsize +popleft +prettytable +PROPERTYKEYS +psetex +psubscribe +psync +pttl +pubsubs +punsubscribe +pxat +pyspelling +pytestmark +qaz +qbuf +qcollectiongenerator +qhc +qhcp +qthelp +quantilerandom +queryindex +racuda +ramen +randomkey +rca +RDB +readexact +Redi +redisearch +REDISGEARS +redisjson +rediss +REFRESHCLUSTER +refvalue +RELATIONSHIPTYPES +rels +reltype +renamenx +replicaof +replicationid +requirepass +resetchannels +resetkeys +resetpass +resetstat +resharding +resourcedetection +resub +retrycount +revrange +revrank +riceratops +rpoplpush +rpush +rpushx +sadd +saveconfig +scandump +scard +scoreidx +sdiff +sdiffstore +sdown +SEARCHSTORE +sectionauthor +sedrik +serializedlength +serie +sessionstart +setbinarykey +setex +setgetdelete +setgetdeleteforget +setid +setinfo +setname +setnx +setrange +setslot +setuser +shardchannels +shardid +shardnumsub +singlehtml +sintercard +sinterstore +sismember +skipif +skipinitial +SKIPINITIALSCAN +skipme +slaveof +slotsrange +slowlog +smarthost +smartypants +smembers +smismember +soba +socktype +Solovyov +someotherkey +sometestfuncname +someval +sourcelink +spaceballs +spellcheck +spfmerge +SPHINXBUILD +spop +spublish +squarespace +srandmember +srem +sscan +sslclient +sslctx +sslsock +sso +ssubscribe +STAGETESTS +stddevrandom +stopword +storedist +stralgo +strappend +strem +subcmd +subv +sug +sugadd +sugdel +sugget +suglen +sugsize +sunion +sunionstore +sunsubscribe +swapdb +SYNADD +syndump +synupdate +tagfield +tagvals +tdigest +telmatosaurus +testc +tfcall +TFCALLASYNC +TFIDF +tfunction +tobytes +tonumber +topkincrby +topklist +trackinginfo +triaging +TRYAGAIN +tsinfo +typehints +ujson +unittests +unixtime +unsub +unwatch +Unwatches +usedby +uvloop +vae +valkey +valkeybloom +valkeycluster +valkeyearch +valkeymod +valkeymodules +valkeypy +venvforinstall +viewcode +vtotal +vulns +waitaof +WAITFORIT +weakrefs +WESTMORELAND +whl +withcode +withcoord +withcount +withcrypto +WITHCURSOR +withdist +withhash +withlabels +withmatchlen +WITHPAYLOADS +WITHSCHEMA +withscore +withsuffixtrie +withvalues +wordlists +WRONGPASS +xack +xadd +xautoclaim +xbdo +xclaim +xdel +xfga +xgroup +xinfo +xlen +xpending +xread +xreadgroup +xrevrange +xtrim +yayakey +ynet +yqq +zadd +zaggregate +zaz +zcard +zcount +zdiff +zdiffstore +zincrby +zinter +zlexcount +zmpop +zmscore +zpages +zpopmax +zpopmin +zrange +zrank +zrem +zrevrange +zrevrank +zscan +zset +zunion +zunionstore diff --git a/.github/actions/spelling/line_forbidden.patterns b/.github/actions/spelling/line_forbidden.patterns new file mode 100644 index 00000000..6af3ad47 --- /dev/null +++ b/.github/actions/spelling/line_forbidden.patterns @@ -0,0 +1,788 @@ +# reject `m_data` as VxWorks defined it and that breaks things if it's used elsewhere +# see [fprime](https://github.com/nasa/fprime/commit/d589f0a25c59ea9a800d851ea84c2f5df02fb529) +# and [Qt](https://github.com/qtproject/qt-solutions/blame/fb7bc42bfcc578ff3fa3b9ca21a41e96eb37c1c7/qtscriptclassic/src/qscriptbuffer_p.h#L46) +#\bm_data\b + +# Were you debugging using a framework with `fit()`? +# If you have a framework that uses `it()` for testing and `fit()` for debugging a specific test, +# you might not want to check in code where you skip all the other tests. +#\bfit\( + +# English does not use a hyphen between adverbs and nouns +# https://twitter.com/nyttypos/status/1894815686192685239 +(?:^|\s)[A-Z]?[a-z]+ly-(?=[a-z]{3,})(?:[.,?!]?\s|$) + +# Smart quotes should match +\s’[^.?!‘’]+’[^.?!‘’]+‘[^.?!‘’]+’|\s‘[^.?!‘’]+’[^.?!‘’]+’[^.?!‘’]+’|\s”[^.?!“”]+”[^.?!“”]+“[^.?!“”]+”|\s“[^.?!“”]+”[^.?!“”]+”[^.?!“”]+” + +# Don't write double negatives +\w+n't not(?=\s) + +# Generally spaces follow instead of preceding `,`s +# It's possible this is some strange CSV dialect, but, even so, you could probably move the space. +\s[a-z]{3,} ,[a-z]{3,}\s + +# Generally words are written with `'s`, not `"s` +[^=|+']\s\w+"s\s + +# Don't miswrite **irreversible binomials** +# https://en.wikipedia.org/wiki/Irreversible_binomial +(?i)\b(?:cheese and macroni|honey and milk|sweet and short|die or do|roll and rock|the bees and the birds|match and mix|tear and wear|clear and loud|death and life|span and spick|vigor and vim|abet and aid|says and deposes|means and ways|dryer and washer|relaxation and rest|famous and rich|loan and savings|come high\s?water or hell|tuck and nip|turf and surf|between a hard place and a rock|dime and five|mouse and cat|tired and sick|pregnant and barefoot|feathered and tarred|feathers and tar|subtraction and addition|liabilities and assets|forth and back|strikes and balls|end to beginning|white and black|small and big|bust or boom|groom and bride|sister and brother|pass and butt|sell and buy|release and catch|effect and cause|state and church|robbers and cops|go and come|going and coming|Indians and cowboys|nights and days|wide and deep|flow and ebb|ice and fire|last and first|ceiling to floor|drink and food|aft and fore|domestic and foreign|backward and forward|foe or friend|back to front|vegetables and fruits|take and give|evil and good|foot and hand|heels over head|Hell and Heaven|there and here|seek and hide|dale and hill|her and him|low and high|valleys and hills|hers and his|thither and hither|yon and hither|cold and hot|wife and husband|out and in|gentlemen and ladies|sea and land|death or life|short and long|found and lost|hate and love|war and love|wife and man|matter over mind|pop and mom|nice or naughty|far and near|tuck and nip|south to north|then and now|later and now|shut and open|under and over|ride and park|starboard and port|cons and pros|pull and push|file and rank|fall and rise|loan and savings|water and soap|finish to start|go and stop|dip and strike|sour and sweet|thin and thick|ring and tip|fro and to|bottom to top|country and town|down and up|downs and ups|downtown and uptown|peace and war|dryer and washer|wane and wax|no and yes|yang and yin|a curse and a blessing|don'ts and dos |farewell and hail|wait and hurry up|difference\s(?:\w+\s+)+day and night|in health and in sickness|from stern to stem|the dead and the quick|a place and a time|generations and ages|comfort and aid|alack and alas|pieces and bits|soul and body|early and bright|mortar and brick|jowl by cheek|tidy and clean|verse and chapter|saucer and cup|cents and dollars|loathing and fear|chips and fish|foremost and first|farewell and hail|fist over hand|shoulders and head|soul and heart|spices and herbs|home and house|thirst and hunger|fork and knife|bounds and leaps|behold and lo|tidy and neat|dime and nickel|cranny and nook|void and null|bolts and nuts|suffering and pain|quiet and peace|ink and pen|choose and pick|simple and plain|proper and prim|rave and rant|shoals and rocks|awe and shock|wonders and signs|bones and skull|crossbones and skull|narrow and strait|narrow and straight|strain and stress|roundabouts and swings|chiggers and ticks|complain and whine|rain and wind|amen and yea|(?:raised|bred) and born|by crook or by hook|(?<=it was a )stormy and dark(?= night)|(?<=this ) age and day|cross the t's and dot the i's|high minded and haughty|best and highest(?= use)|like daughter, like mother|done and over with|(?<=on ) needles and pins|half a dozen of the other, six of one|(?<=up ) personal and close|baggage and bag|beads and baubles|balance and beams|breakfast and bed|braces and belt|bar and bench|bad and big|bosh bash bish|blue and black|beautiful and bold|Baptists and bootleggers|briefs or boxers|butter and bread|boar and bull|carry and cash|cheese and chalk|clans and cliques|control and command|cream and cookies|dumb and deaf|dash and dine|dirty and down|drabs and dribs|drive and drink|disorderly and drunk|furious and fast|famine or feast|forget and fire|fury and fire|fauna and flora|forget and forgive|function and form|foe or friend|frolics and fun|feathers and fur|goblins and ghosts|giggles and grins|home and hearth|haw and hem|holler and hoot|handgrenades and horseshoes|Gentile and Jew|jiving and juking|country and king|caboodle and kit|kin and kith|longitude and latitude|limb and life|learn and live|load and lock|match and mix|mild and meek|number and name|parcel and part|pencil and pen|post to pillar|pans and pots|perish or publish|riches to rags|raving and ranting|write and read|rumble to ready|wrong and right|roll and rock|ready and rough|regulations and rules|secure and safe|sound and safe|shell and shot|shave and shower|symptoms and signs|slide and slip|span and spick|shine and spit|Stripes and Stars|stones and sticks|spice and sugar|that or this|tat for tit|tail and top|turn and toss|treat or trick|tribulations and trials|tested and tried|true and tried|trailer and truck|wear and wash|waiting and watching|wail and weep|wild and wet|hollering and whooping|woolly and wild|wonderful and wise|warlocks and witches|ruin and wrack|the bees and the birds|(?<=between the) deep blue sea and the devil|Dragons & Dungeons|fuck off or fit in|flop-flip|fancy-free and footloose|to hold and to have|least but not last|Lease-Lend|leave ['‘]em and love ['‘]em|leave it or love it|paper and pen(?:cil|)|patter-pitter|relaxation and rest|(?<=without )reason or rhyme|tacky-ticky|take and break|zoom and boom|cox and box|talk and chalk|darts and charts|dip and chips|drive and dive|square and fair|dime and five|jetsam and flotsam|dry and high|fire and hire|split and hit|thither and hither|trot to hot|puff and huff|bustle and hustle|gap and lap|greatest and latest|proud and loud|greet and meet|right makes might|shame and name|dear and near|sods and odds|upwards and onwards|about and out|proud and out|dump and pump|tough and rough|gun and run|clout and shout|bake and shake|surely but slowly|joke and smoke|dash and stash|bitch and stitch|drop and stop|turf and surf|tide and time|gown and town|bake and wake|tear and wear|feed and weed|dealing and wheeling|dine and wine|nay or yea|trouble double|bender fender|dandy-handy|panky-hanky|scarum-harum|skelter helter|piggledy higgledy|quit it and hit|pocus hocus|toity[- ]hoity|potch-hotch|burly-hurly|bitty-itty|bitsy-itsy|votor moter|the highway or my way|pamby-namby|claim it and name it|ever, never|gritty nitty|porgy orgy|mell-pell|baggy saggy|so good, so far|weeny-teeny|blue true|lose it or use it|nilly willy|(?<=the )nays and (?:the |)yeas|beyond and above|graces and airs|muster and alarm|kicking and alive|well and alive|dangerous and armed|oranges and apples|fill and back|forth and back|eggs and bacon|mash and bangers|switch and bait|tackle and bait|pregnant and barefoot|sale and bargain|breakfast and bed|call and beck|whistles and bells|suspenders and belt|bold and big|tall and big|better and bigger|purge and binge|bridle and bit|bobs and bits|pieces and bits|blue and black|tackle and block|guts and blood|gore and blood|weave and bob|arrow and bow|determined and bound|gagged and bound|scrape and bow|bit and brace|water and bread|circuses and bread|roses and bread|serve and brown|spade and bucket|grind and bump|run and bump|large and by|gown and cap|driver and car|mouse and cat|balances and checks|dumplings and chicken|change and chop|sober and clean|dagger and cloak|tie and coat|doughnuts and coffee|go and come|burn and crash|sugar and cream|punishment and crime|saucer and cup|paste and cut|run and cut|burdock and dandelion|night and day|buried and dead|gone and dead|taxes and death|dash and dine|conquer and divide|out and down|cover and duck|dive and duck|every and each|ears and eyes|figures and facts|wide and far|furious and fast|loose and fast|dandy and fine|thumbs and fingers|brimstone and fire|foremost and first|chips and fish|blood and flesh|bone and flesh|ever and forever|center and front|games and fun|bother and fuss|take and give|aspirations and goals|plenty and good|light and goodness|pound and ground|slash and hack|hearty and hale|fast and hard|eggs and ham|nail and hammer|sickle and hammer|tongs and hammer|minds and hearts|now and here|seek and hide|watch and hide|mighty and high|dry and high|tight and high|miss and hit|run and hit|yon and hither|thither and hither|hosed and home|dry and home|eye and hook|loop and hook|buggy and horse|carriage and horse|heavy and hot|high and hot|bothered and hot|puff and huff|when and if|custard and kippers|tell and kiss|kin and kith|fork and knife|screaming and kicking|streams and lakes|order and law|behold and lo|dam and lock|key and lock|feel and look|clear and loud|boy and man|potatoes and meat|women and men|cookies and milk|honey and milk|tenon and mortise|shakers and movers|address and name|faces and names|easy and nice|cranny and nook|crosses and noughts|bolts and nuts|ends and odds|away and off|done and one|about and out|out and over|terminer and oyer|cream and peaches|Qs and Ps|carrots and peas|axe and pick|moan and piss|vinegar and piss|whine and piss|proper and prim|booty and prize|cons and pros|beans and pork|simple and pure|dirty and quick|pinion and rack|ruin and rack|pillage and rape|famous and rich|fall and rise|shine and rise|board and room|tumble and rough|jump and run|pepper and salt|vinegar and salt|sniff and scratch|rescue and search|destroy and seek|tie and shirt|fat and short|sweet and short|stout and short|tell and show|jive and shuck|tired and sick|burn and slash|arrows and slings|fall and slip|steady and slow|grab and smash|mirrors and smoke|ladders and snakes|dance and song|fury and sound|polish and spit|deliver and stand|strain and stress|Drang und Sturm|debonair and suave|tie and suit|rainbows and sunshine|demand and supply|light and sweetness|sandal and sword|chairs and tables|thin and tall|feathers and tar|crumpets and tea|lightning and thunder|ass and tits|fro and to|nail and tooth|go and touch|field and track|error and trial|tribulations and trials|roll and tuck|turn and twist|about and up|coming and up|vigor and vim|see and wait|fuzzy and warm|weft and warp|ward and watch|wane and wax|means and ways|good and well|whine and whinge|roses and wine|phrases and words|no and yes|a leg and an arm|(?<=old )chain and ball|by golly and by guess|bull-and-cock|dried (dry) and cut|(?<=in this )age and day|pony and dog show|(?<=by )starts and fits|grin and bear it|(?<=move ) earth and heaven|quit it and hit it|kisses and hugs|(?<=for all )purposes and intents|make up and kiss|last testament and will|make do and mend|(?<=every ) then and now|for all and once(?=[,.;!?])|jelly and peanut butter|ice cream and pickles|raining dogs and cats|development and research|blues and rhythm|(?<=between a )hard place and a rock|(?<=all's )done and said|(?<=different )sizes and shapes|bones? and skin|(?<=in )spirit and (?:in |)truth|a miss and a swing|(?<=through )thin and thick|O's and X's|a day and a year|nothing or all|worse or better|small or big|white or black|pleasure or business|night or day|alive or dead|die or do|flight or fight|take or give|bad or good|simple or gentle|she or he|tails or heads|her or his|miss or hit|cure or kill|break or make|less or more|never or now|shine or rain|reason or rhyme|wrong or right|swim or sink|later or sooner|more or two|down or up|death or victory|lose or win|no or yes|the egg or (?:the |)chicken|(?<=neither )fowl nor fish|(?<=come )high water or hell|(?<=neither )there nor here|(?<=neither )hair nor hide|(?<=not one )tittle or jot|(?<=neither )money nor love|shut up or put up|leave it or take it|(?<=neither )ornament nor use|gatherer-hunter|cheese corn|Costello and Abbott|Isaac and Abraham|Patroclus and Achilles|Eve and Adam|Anicetus and Alexiares|Cleopatra and Antony|Ant & Dec|Robin and Batman|Clyde and Bonnie|Abel and Cain|Ball and Cannon|Pollux and Castor|Psyche and Cupid|Clack and Click|Pythias and Damon|Goliath and David|Guattari and Deleuze|Jane and Dick|Marguerite and Faust|Swann and Flanders|Saunders and French|Frack and Frick|Laurie and Fry|Sullivan and Gilbert|Aga and Gilgamesh|Gretel and Hansel|Hellman & Friedman|Esau and Jacob|Jill and Jack|Victor and Jack|Vijaya and Jaya|Jekyll & Hyde|Hardy and Laurel|McCartney and Lennon|Loewe and Lerner|Clark and Lewis|Lilo & Stitch|Large and Little|Meslamta-ea and Lugal-irra|Luigi and Mario|Lewis and Martin|Ashley and Mary-Kate Olsen|Sue and Mel|Wise and Morecambe|Mindy and Mork|Eurydice and Orpheus|Horse-Face and Ox-Head|Penn & Teller|Aristotle and Phyllis|Ferb and Phineas|Pinky & The Brain|Galatea and Pygmalion|Ren & Stimpy|Rhett & Link|Morty and Rick|Hart and Rodgers|Hammerstein and Rodgers|Juliet and Romeo|Remus and Romulus|Guildenstern and Rosencrantz|Max and Sam|Delilah and Samson|Simon & Garfunkel|Sonny & Cher|Thelma & Louise|Thompson and Thomson|Tom & Jerry|Isolde and Tristan|Tim & Eric|Adonis and Venus|Vic & Bob|Crick and Watson|Eve and Adam|pears and apples|glass and bottle|Liszt and Brahms|bone and dog|toad and frog|blister and hand|south and north|pork and rabbit|strife and trouble|eight and two|flute and whistle)\b + +# Don't use `requires that` + `to be` +# https://twitter.com/nyttypos/status/1894816551435641027 +\brequires that \w+\b[^.]+to be\b + +# A fully parenthetical sentence’s period goes inside the parentheses, not outside. +# https://twitter.com/nyttypos/status/1898844061873639490 +\([A-Z][a-z]{2,}(?: [a-z]+){3,}\)\.\s + +# Complete sentences shouldn't be in the middle of another sentence as a parenthetical. +(?]|depth|frame|page|project|select)\s[1-9] (?!byte|day|hour|meaning|minute|month|(?:new |)page|people|(?:more |)space|year)[a-z]+ [a-z]+\s + +# Write out numbers at the start of a sentence +# https://www.scribendi.com/academy/articles/when_to_spell_out_numbers_in_writing.en.html#:~:text=Beginning%20a%20Sentence%20with%20a%20Number,may%20be%2e +(?:\b[a-z]{4,}|\s(?:[a-eg-z][a-z]{2}|f[a-hj-z][a-z]|fi[a-fh][a-z]))[:.?!] [1-9] [a-z]{3,} [a-z]+\s\w+ + +# Don't write two numbers in a row +# https://www.scribendi.com/academy/articles/when_to_spell_out_numbers_in_writing.en.html#:~:text=Paired%20Numbers%20%28Two%20Numbers%20in,librarian%20to%20begin%20story%20time%2e +(?:[a-z]{4,}|\s(?!apr|aug|dec|feb|fri|jan|mar|mon|nov|oct|sat|sep|sun|thu|tue|wed)[a-z]{3})\s\d+\s\d+(?!--)[-\s](?:(?!--)[-A-Za-z]){2,}\s + +# This probably indicates Mojibake https://en.wikipedia.org/wiki/Mojibake +# You probably should try to unbake this content +Ã(?:Â[¤¶¥]|[£¢])|à + +# Should be `HH:MM:SS` +\bHH:SS:MM\b + +# Should be `86400` (seconds in a standard day) +\b84600\b(?:.*\bday\b) + +# Should probably be `2006-01-02` (yyyy-mm-dd) +# Assuming that the time is being passed to https://go.dev/src/time/format.go +\b2006-02-01\b + +# Should probably have a trailing `.` +\s([a-z]\.){2,}[a-z]\s + +# Should probably end with `”` +# Likely bad OCR +“.+[^'‘\\\[]+’'(?!['"]) + +# Should probably end with `”` or with only one of `’`/`'` +\s\w+[^'‘\\\[]+’'(?!['"]) + +# Should probably be matching (smart)quotes or backticks (if Markdown) +# Unless the file format is Tex +#(? Don't use `can not` when you mean `cannot`. The only time you're likely to see `can not` written as separate words is when the word `can` happens to precede some other phrase that happens to start with `not`. +# > `Can't` is a contraction of `cannot`, and it's best suited for informal writing. +# > In formal writing and where contractions are frowned upon, use `cannot`. +# > It is possible to write `can not`, but you generally find it only as part of some other construction, such as `not only . . . but also.` +# - if you encounter such a case, add a pattern for that case to patterns.txt. +\b[Cc]an not\b(?! only\b) + +# Should be `chart` +(?i)\bhelm\b.*\bchard\b + +# Should be `counter-intuitive` +\bcounter intuitive\b + +# Do not use `(click) here` links +# For more information, see: +# * https://www.w3.org/QA/Tips/noClickHere +# * https://webaim.org/techniques/hypertext/link_text +# * https://granicus.com/blog/why-click-here-links-are-bad/ +# * https://heyoka.medium.com/dont-use-click-here-f32f445d1021 +(?i)(?:>|\[)(?:(?:click |)here|link|(?:read |)more)(?:> /etc/apt/sources.list.d/something-distro.list +# ```` +\bapt-key add\b + +# Should be `nearby` +\bnear by\b + +# Should probably be a person named `Nick` or the abbreviation `NIC` +\bNic\b + +# Should be `not supposed` +\bsupposed not\b + +# Should be `Once this` or `On this` or even `One that`. Rarely `One, this` +[?!.] One this\b + +# Should probably be `much more` +\bmore much\b + +# Should be `perform its` +\bperform it's\b + +# Should be `PowerPoint` +\bPowerpoint\b + +# Should be `opt-in` +(? below for the` +(?i)\bfind below the\b + +# Should be `then any` unless there's a comparison before the `,` +, than any\b + +# Should be `did not exist` +\bwere not existent\b + +# Should be `nonexistent` +\bnon existing\b + +# Should be `nonexistent` +\b[Nn]o[nt][- ]existent\b + +# Should be `only does` +\bdoes only(?! (?:seem|match))\b + +# Should be `only matches` +\bdoes only match\b + +# Should be `only seems` +\bdoes only seem\b + +# Should be `our` +\bspending out time\b + +# Should be `@brief` / `@details` / `@param` / `@return` / `@retval` +(?:^\s*|(?:\*|//|/*)\s+`)[\\@](?:breif|(?:detail|detials)|(?:params(?!\.)|prama?)|ret(?:uns?)|retvl)\b + +# Should be `more than` or `more, then` +\bmore then\b + +# Should be `Pipeline`/`pipeline` +(?:(?<=\b|[A-Z])p|P)ipeLine(?:\b|(?=[A-Z])) + +# Should be `please do not`/`you do not need` +[Pp]lease do not need + +# Should be `preexisting` +[Pp]re[- ]existing + +# Should be `preempt` +[Pp]re[- ]empt\b + +# Should be `preemptively` +[Pp]re[- ]emptively + +# Should be `prepopulate` +[Pp]re[- ]populate + +# Should be `prerequisite` +[Pp]re[- ]requisite + +# Should be `principal` +[Pp]rinciple(?= [Ee]ngineer) + +# Should be `QuickTime` +\bQuicktime\b + +# Should be `recently changed` or `recent changes` +[Rr]ecent changed + +# Should be `reentrancy` +[Rr]e[- ]entrancy + +# Should be `reentrant` +[Rr]e[- ]entrant + +# Should be `room for` +\brooms for (?!lease|rent|sale) + +# Reword +\b(?i)same as for\b + +# Should be `socioeconomic` +# https://dictionary.cambridge.org/us/dictionary/english/socioeconomic +socio-economic + +# Should be `strong suit` +\b(?:my|his|her|their) strong suite\b + +# Should probably be `temperatures` unless actually talking about thermal drafts (things birds may fly on) +\bthermals\b + +# Should be `there are` or `they are` (or `they're`) +(?i)\btheir are\b + +# Should be `they have` or `have the` or ... +\bthe (?:have(?! nots)|has)\b + +# Should be `too` +(?<=\sit's )to(?= (?:big|large|small|tiny|important)) + +# Should be `too` +(?<=\bway )to(?= many\s) + +# Should be `true` +(?i)(? + +WATCH(?=[a-z]) + +# tolerated irreversible binomials +the low and high cutoff quantiles|longitude and latitude + +# Automatically suggested patterns + +# hit-count: 638 file-count: 54 +# https/http/file urls +(?:\b(?:https?|ftp|file)://)[-A-Za-z0-9+&@#/*%?=~_|!:,.;]+[-A-Za-z0-9+&@#/*%=~_|] + +# hit-count: 303 file-count: 42 +# Python string prefix / binary prefix +# Note that there's a high false positive rate, remove the `?=` and search for the regex to see if the matches seem like reasonable strings +(?v# +(?:(?<=[A-Z]{2})V|(?<=[a-z]{2}|[A-Z]{2})v)\d+(?:\b|(?=[a-zA-Z_])) + +# hit-count: 35 file-count: 4 +# Repeated letters +\b([A-Za-z])\g{-1}{2,}\b + +# hit-count: 17 file-count: 5 +# URL escaped characters +%[0-9A-F][A-F](?=[A-Za-z]) + +# hit-count: 12 file-count: 2 +# container images +image: [-\w./:@]+ + +# hit-count: 7 file-count: 5 +# sha-... -- uses a fancy capture +(\\?['"]|")[0-9a-f]{40,}\g{-1} + +# hit-count: 6 file-count: 6 +# GitHub actions +\buses:\s+(['"]?)[-\w.]+/[-\w./]+@[-\w.]+\g{-1} + +# hit-count: 4 file-count: 1 +# Markdown anchor links +\(#\S*?[a-zA-Z]\S*?\) + +# hit-count: 1 file-count: 1 +# GHSA +GHSA(?:-[0-9a-z]{4}){3} + +# hit-count: 1 file-count: 1 +# Docker images +^\s*(?i)FROM\s+\S+:\S+(?:\s+AS\s+\S+|) + +# Questionably acceptable forms of `in to` +# Personally, I prefer `log into`, but people object +# https://www.tprteaching.com/log-into-log-in-to-login/ +\b(?:(?:[Ll]og(?:g(?=[a-z])|)|[Ss]ign)(?:ed|ing)?) in to\b + +# to opt in +\bto opt in\b + +# pass(ed|ing) in +\bpass(?:ed|ing) in\b + +# acceptable duplicates +# ls directory listings +[-bcdlpsw](?:[-r][-w][-SsTtx]){3}[\.+*]?\s+\d+\s+\S+\s+\S+\s+[.\d]+(?:[KMGT]|)\s+ +# mount +\bmount\s+-t\s+(\w+)\s+\g{-1}\b +# C types and repeated CSS values +\s(auto|await|buffalo|center|div|inherit|long|LONG|none|normal|solid|thin|transparent|very)(?:\s\g{-1})+\s +# C enum and struct +\b(?:enum|struct)\s+(\w+)\s+\g{-1}\b +# go templates +\s(\w+)\s+\g{-1}\s+\`(?:graphql|inject|json|yaml): +# doxygen / javadoc / .net +(?:[\\@](?:brief|defgroup|groupname|link|t?param|return|retval)|(?:public|private|\[Parameter(?:\(.+\)|)\])(?:\s+(?:static|override|readonly|required|virtual))*)(?:\s+\{\w+\}|)\s+(\w+)\s+\g{-1}\s + +# macOS file path +(?:Contents\W+|(?!iOS)/)MacOS\b + +# Python package registry has incorrect spelling for macOS / Mac OS X +"Operating System :: MacOS :: MacOS X" + +# "company" in Germany +\bGmbH\b + +# IntelliJ +\bIntelliJ\b + +# Commit message -- Signed-off-by and friends +^\s*(?:(?:Based-on-patch|Co-authored|Helped|Mentored|Reported|Reviewed|Signed-off)-by|Thanks-to): (?:[^<]*<[^>]*>|[^<]*)\s*$ + +# Autogenerated revert commit message +^This reverts commit [0-9a-f]{40}\.$ + +# ignore long runs of a single character: +\b([A-Za-z])\g{-1}{3,}\b diff --git a/.github/actions/spelling/reject.txt b/.github/actions/spelling/reject.txt new file mode 100644 index 00000000..799b2ec7 --- /dev/null +++ b/.github/actions/spelling/reject.txt @@ -0,0 +1,24 @@ +^attache$ +^bellows?$ +benefitting +occurences? +^dependan.* +^develope$ +^developement$ +^developpe +^Devers?$ +^devex +^devide +^Devinn?[ae] +^devisal +^devisor +^diables?$ +^immediatly$ +^oer$ +Sorce +^[Ss]pae.* +^Teh$ +^untill$ +^untilling$ +^venders?$ +^wether.* diff --git a/.github/workflows/spellcheck.yml b/.github/workflows/spellcheck.yml deleted file mode 100644 index 1517c339..00000000 --- a/.github/workflows/spellcheck.yml +++ /dev/null @@ -1,14 +0,0 @@ -name: spellcheck -on: - pull_request: -jobs: - check-spelling: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v5 - - name: Check Spelling - uses: rojopolis/spellcheck-github-actions@0.52.0 - with: - config_path: .github/spellcheck-settings.yml - task_name: Markdown diff --git a/.github/workflows/spelling.yml b/.github/workflows/spelling.yml new file mode 100644 index 00000000..5d876abf --- /dev/null +++ b/.github/workflows/spelling.yml @@ -0,0 +1,94 @@ +name: Check Spelling + +# SARIF reporting +# +# Access to SARIF reports is generally restricted (by GitHub) to members of the repository. +# +# Requires enabling `security-events: write` +# and configuring the action with `use_sarif: 1` +# +# For information on the feature, see: https://github.com/check-spelling/check-spelling/wiki/Feature:-SARIF-output + +# Minimal workflow structure: +# +# on: +# push: +# ... +# pull_request_target: +# ... +# jobs: +# # you only want the spelling job, all others should be omitted +# spelling: +# # remove `security-events: write` and `use_sarif: 1` +# # remove `experimental_apply_changes_via_bot: 1` +# ... otherwise, adjust the `with:` as you wish + +on: + push: + branches: + - '**' + tags-ignore: + - '**' + pull_request_target: + branches: + - '**' + types: + - 'opened' + - 'reopened' + - 'synchronize' + +permissions: {} + +jobs: + spelling: + name: Check Spelling + permissions: + contents: read + pull-requests: read + actions: read + security-events: write + outputs: + followup: ${{ steps.spelling.outputs.followup }} + runs-on: ubuntu-latest + if: ${{ contains(github.event_name, 'pull_request') || github.event_name == 'push' }} + concurrency: + group: spelling-${{ github.event.pull_request.number || github.ref }} + # note: If you use only_check_changed_files, you do not want cancel-in-progress + cancel-in-progress: true + steps: + - name: check-spelling + id: spelling + uses: check-spelling/check-spelling@v0.0.25 + with: + suppress_push_for_open_pull_request: ${{ github.actor != 'dependabot[bot]' && 1 }} + checkout: true + check_file_names: 1 + post_comment: 0 + use_magic_file: 1 + warnings: bad-regex,binary-file,deprecated-feature,ignored-expect-variant,large-file,limited-references,no-newline-at-eof,noisy-file,non-alpha-in-dictionary,token-is-substring,unexpected-line-ending,whitespace-in-dictionary,minified-file,unsupported-configuration,no-files-to-check,unclosed-block-ignore-begin,unclosed-block-ignore-end + use_sarif: 1 + check_extra_dictionaries: "" + dictionary_source_prefixes: > + { + "asm": "https://raw.githubusercontent.com/check-spelling/assembly-dictionaries/20231110/", + "cspell": "https://raw.githubusercontent.com/check-spelling/cspell-dicts/v20230509/dictionaries/", + "cspell1": "https://raw.githubusercontent.com/check-spelling/cspell-dicts/v20241114/dictionaries/", + "census": "https://raw.githubusercontent.com/check-spelling-sandbox/census/dictionaries-d90e686f89dd241ad61d30f26619e54d73e73c6e/dictionaries/" + } + extra_dictionaries: | + cspell1:software-terms/softwareTerms.txt + cspell1:python/python/python-lib.txt + cspell1:python/python/python.txt + census:census-5.txt + cspell1:python/common/extra.txt + cspell1:fonts/fonts.txt + cspell1:php/php.txt + cspell1:java/java.txt + cspell1:fullstack/fullstack.txt + cspell1:java/java-terms.txt + cspell1:npm/npm.txt + cspell1:r/r.txt + asm:ia64-isa.txt + cspell1:cpp/people.txt + cspell1:golang/go.txt + cspell1:django/django.txt diff --git a/docs/advanced_features.rst b/docs/advanced_features.rst index 4db58460..ab1211fc 100644 --- a/docs/advanced_features.rst +++ b/docs/advanced_features.rst @@ -229,8 +229,8 @@ following keys. - **type**: One of the following: 'subscribe', 'unsubscribe', 'psubscribe', 'punsubscribe', 'message', 'pmessage' -- **channel**: The channel [un]subscribed to or the channel a message - was published to +- **channel**: The channel [un]subscribed to or the channel to which a message + was published - **pattern**: The pattern that matched a published message's channel. Will be None in all cases except for 'pmessage' types. - **data**: The message data. With [un]subscribe messages, this value diff --git a/docs/clustering.rst b/docs/clustering.rst index 19354776..dc12f2bc 100644 --- a/docs/clustering.rst +++ b/docs/clustering.rst @@ -121,10 +121,10 @@ topology and attempt to retry executing the command. >>> rc.bgsave(Valkey.PRIMARIES) You could also pass ClusterNodes directly if you want to execute a -command on a specific node / node group that isn’t addressed by the +command on a specific node / node group that isn't addressed by the nodes flag. However, if the command execution fails due to cluster topology changes, a retry attempt will not be made, since the passed -target node/s may no longer be valid, and the relevant cluster or +target node(s) may no longer be valid, and the relevant cluster or connection error will be returned. .. code:: python diff --git a/docs/examples/redis-stream-example.ipynb b/docs/examples/redis-stream-example.ipynb index 6f7f5a8c..d5e3d49d 100644 --- a/docs/examples/redis-stream-example.ipynb +++ b/docs/examples/redis-stream-example.ipynb @@ -548,7 +548,7 @@ } ], "source": [ - "# check pending status (read messages without a ack)\n", + "# check pending status (read messages without an ack)\n", "def print_pending_info( key_group ):\n", " for s,k in key_group:\n", " pr = r.xpending( name=s, groupname=k )\n", diff --git a/tests/test_asyncio/test_bloom.py b/tests/test_asyncio/test_bloom.py index 04528c1c..259e45dc 100644 --- a/tests/test_asyncio/test_bloom.py +++ b/tests/test_asyncio/test_bloom.py @@ -89,7 +89,7 @@ async def do_verify(): await decoded_r.bf().add("myBloom", x) rv = await decoded_r.bf().exists("myBloom", x) assert rv - rv = await decoded_r.bf().exists("myBloom", f"nonexist_{x}") + rv = await decoded_r.bf().exists("myBloom", f"nonexistent_{x}") res += rv == x assert res < 5 @@ -163,7 +163,7 @@ async def test_bf_card(decoded_r: valkey.Valkey): assert await decoded_r.bf().add("bf1", "item_foo") == 1 assert await decoded_r.bf().card("bf1") == 1 - # Error when key is of a type other than Bloom filtedecoded_r. + # Error when key is of a type other than Bloom filter decoded_r. with pytest.raises(valkey.ResponseError): await decoded_r.set("setKey", "value") await decoded_r.bf().card("setKey") diff --git a/tests/test_asyncio/test_cluster.py b/tests/test_asyncio/test_cluster.py index 01c515a0..789f0eb0 100644 --- a/tests/test_asyncio/test_cluster.py +++ b/tests/test_asyncio/test_cluster.py @@ -2657,7 +2657,7 @@ async def test_blocked_methods(self, r: ValkeyCluster) -> None: ) async def test_empty_stack(self, r: ValkeyCluster) -> None: - """If a pipeline is executed with no commands it should return a empty list.""" + """If a pipeline is executed with no commands it should return an empty list.""" p = r.pipeline() result = await p.execute() assert result == [] diff --git a/tests/test_asyncio/test_search.py b/tests/test_asyncio/test_search.py index 20c9799f..9a4396ac 100644 --- a/tests/test_asyncio/test_search.py +++ b/tests/test_asyncio/test_search.py @@ -53,7 +53,7 @@ async def waitForIndex(env, idx, timeout=None): def getClient(decoded_r: valkey.Valkey): """ - Gets a client client attached to an index name which is ready to be + Gets a client attached to an index name which is ready to be created """ return decoded_r @@ -485,7 +485,7 @@ async def test_example(decoded_r: valkey.Valkey): "doc1", mapping={ "title": "RediSearch", - "body": "RediSearch impements a search engine on top of valkey", + "body": "RediSearch implements a search engine on top of valkey", }, ) @@ -1121,7 +1121,7 @@ async def test_aggregations_groupby(decoded_r: valkey.Valkey): "search", mapping={ "title": "RediSearch", - "body": "RediSearch impements a search engine on top of valkey", + "body": "RediSearch implements a search engine on top of valkey", "parent": "valkey", "random_num": 10, }, diff --git a/tests/test_asyncio/test_timeseries.py b/tests/test_asyncio/test_timeseries.py index 3e917b8e..af7f9296 100644 --- a/tests/test_asyncio/test_timeseries.py +++ b/tests/test_asyncio/test_timeseries.py @@ -67,7 +67,7 @@ async def test_alter(decoded_r: valkey.Valkey): @skip_ifmodversion_lt("1.4.0", "timeseries") -async def test_alter_diplicate_policy(decoded_r: valkey.Valkey): +async def test_alter_duplicate_policy(decoded_r: valkey.Valkey): assert await decoded_r.ts().create(1) info = await decoded_r.ts().info(1) assert_resp_response( diff --git a/tests/test_bloom.py b/tests/test_bloom.py index 93b5c4bd..41bdc849 100644 --- a/tests/test_bloom.py +++ b/tests/test_bloom.py @@ -112,7 +112,7 @@ def do_verify(): client.bf().add("myBloom", x) rv = client.bf().exists("myBloom", x) assert rv - rv = client.bf().exists("myBloom", f"nonexist_{x}") + rv = client.bf().exists("myBloom", f"nonexistent_{x}") res += rv == x assert res < 5 diff --git a/tests/test_cluster.py b/tests/test_cluster.py index 83d6e96c..b4654eae 100644 --- a/tests/test_cluster.py +++ b/tests/test_cluster.py @@ -3268,7 +3268,7 @@ def raise_error(target_node, *args, **kwargs): def test_empty_stack(self, r): """ If pipeline is executed with no commands it should - return a empty list. + return an empty list. """ p = r.pipeline() result = p.execute() diff --git a/tests/test_commands.py b/tests/test_commands.py index dace6ca2..7eef31be 100644 --- a/tests/test_commands.py +++ b/tests/test_commands.py @@ -2623,7 +2623,7 @@ def test_zpopmin(self, r): ) @skip_if_server_version_lt("6.2.0") - def test_zrandemember(self, r): + def test_zrandmember(self, r): r.zadd("a", {"a1": 1, "a2": 2, "a3": 3, "a4": 4, "a5": 5}) assert r.zrandmember("a") is not None assert len(r.zrandmember("a", 2)) == 2 diff --git a/tests/test_search.py b/tests/test_search.py index 7e119058..898aeae1 100644 --- a/tests/test_search.py +++ b/tests/test_search.py @@ -62,7 +62,7 @@ def waitForIndex(env, idx, timeout=None): def getClient(client): """ - Gets a client client attached to an index name which is ready to be + Gets a client attached to an index name which is ready to be created """ return client @@ -459,7 +459,7 @@ def test_example(client): "doc1", mapping={ "title": "RediSearch", - "body": "RediSearch impements a search engine on top of valkey", + "body": "RediSearch implements a search engine on top of valkey", }, ) @@ -1026,7 +1026,7 @@ def test_aggregations_groupby(client): "search", mapping={ "title": "RediSearch", - "body": "RediSearch impements a search engine on top of valkey", + "body": "RediSearch implements a search engine on top of valkey", "parent": "valkey", "random_num": 10, }, diff --git a/tests/test_timeseries.py b/tests/test_timeseries.py index 36322ab3..bb481691 100644 --- a/tests/test_timeseries.py +++ b/tests/test_timeseries.py @@ -69,7 +69,7 @@ def test_alter(client): @skip_ifmodversion_lt("1.4.0", "timeseries") -def test_alter_diplicate_policy(client): +def test_alter_duplicate_policy(client): assert client.ts().create(1) info = client.ts().info(1) assert_resp_response( diff --git a/valkey/_parsers/helpers.py b/valkey/_parsers/helpers.py index 67557044..d0adaf08 100644 --- a/valkey/_parsers/helpers.py +++ b/valkey/_parsers/helpers.py @@ -392,8 +392,8 @@ def parse_slowlog_get(response, **options): def parse_item(item): result = {"id": item[0], "start_time": int(item[1]), "duration": int(item[2])} # Valkey Enterprise injects another entry at index [3], which has - # the complexity info (i.e. the value N in case the command has - # an O(N) complexity) instead of the command. + # the complexity info (i.e. the value N for a command of complexity + # O(N)) instead of the command. if isinstance(item[3], list): result["command"] = space.join(item[3]) result["client_address"] = item[4] diff --git a/valkey/asyncio/connection.py b/valkey/asyncio/connection.py index 5bc3e46c..9f4c06ca 100644 --- a/valkey/asyncio/connection.py +++ b/valkey/asyncio/connection.py @@ -1136,7 +1136,7 @@ async def disconnect(self, inuse_connections: bool = True): Disconnects connections in the pool If ``inuse_connections`` is True, disconnect connections that are - current in use, potentially by other tasks. Otherwise only disconnect + current in use, potentially by other tasks. Otherwise, only disconnect connections that are idle in the pool. """ if inuse_connections: diff --git a/valkey/commands/cluster.py b/valkey/commands/cluster.py index 3f6e5325..3d8bf07c 100644 --- a/valkey/commands/cluster.py +++ b/valkey/commands/cluster.py @@ -225,7 +225,7 @@ def delete(self, *keys: KeyT) -> ResponseT: The keys are first split up into slots and then an DEL command is sent for every slot - Non-existent keys are ignored. + Nonexistent keys are ignored. Returns the number of keys that were deleted. For more information see https://valkey.io/commands/del @@ -240,7 +240,7 @@ def touch(self, *keys: KeyT) -> ResponseT: The keys are first split up into slots and then an TOUCH command is sent for every slot - Non-existent keys are ignored. + Nonexistent keys are ignored. Returns the number of keys that were touched. For more information see https://valkey.io/commands/touch @@ -254,7 +254,7 @@ def unlink(self, *keys: KeyT) -> ResponseT: The keys are first split up into slots and then an TOUCH command is sent for every slot - Non-existent keys are ignored. + Nonexistent keys are ignored. Returns the number of keys that were unlinked. For more information see https://valkey.io/commands/unlink diff --git a/valkey/commands/core.py b/valkey/commands/core.py index 80a71be6..36c8cd9d 100644 --- a/valkey/commands/core.py +++ b/valkey/commands/core.py @@ -2838,7 +2838,7 @@ def lpos( Get position of ``value`` within the list ``name`` If specified, ``rank`` indicates the "rank" of the first element to - return in case there are multiple copies of ``value`` in the list. + return if there are multiple copies of ``value`` in the list. By default, LPOS returns the position of the first occurrence of ``value`` in the list. When ``rank`` 2, LPOS returns the position of the second ``value`` in the list. If ``rank`` is negative, LPOS @@ -2889,7 +2889,7 @@ def sort( ``start`` and ``num`` allow for paging through the sorted data ``by`` allows using an external key to weight and sort the items. - Use an "*" to indicate where in the key the item value is located + Use an "*" to indicate the location of the item value in the key ``get`` allows for returning items from external keys rather than the sorted data itself. Use an "*" to indicate where in the key @@ -2961,7 +2961,7 @@ def sort_ro( ``start`` and ``num`` allow for paging through the sorted data ``by`` allows using an external key to weight and sort the items. - Use an "*" to indicate where in the key the item value is located + Use an "*" to indicate the location of the item value in the key ``get`` allows for returning items from external keys rather than the sorted data itself. Use an "*" to indicate where in the key @@ -3608,7 +3608,7 @@ def xautoclaim( try: if int(count) < 0: - raise DataError("XPENDING count must be a integer >= 0") + raise DataError("XPENDING count must be an integer >= 0") pieces.extend([b"COUNT", count]) except TypeError: pass @@ -3891,14 +3891,14 @@ def xpending_range( # idle try: if int(idle) < 0: - raise DataError("XPENDING idle must be a integer >= 0") + raise DataError("XPENDING idle must be an integer >= 0") pieces.extend(["IDLE", idle]) except TypeError: pass # count try: if int(count) < 0: - raise DataError("XPENDING count must be a integer >= 0") + raise DataError("XPENDING count must be an integer >= 0") pieces.extend([min, max, count]) except TypeError: pass diff --git a/valkey/commands/search/commands.py b/valkey/commands/search/commands.py index 14823d6f..9e389fab 100644 --- a/valkey/commands/search/commands.py +++ b/valkey/commands/search/commands.py @@ -383,7 +383,7 @@ def add_document_hash(self, doc_id, score=1.0, language=None, replace=False): ### Parameters - **doc_id**: the document's id. This has to be an existing HASH key - in Valkey that will hold the fields the index needs. + in Valkey that will hold the fields needed by the index. - **score**: the document ranking, between 0.0 and 1.0 - **replace**: if True, and the document already is in the index, we perform an update and reindex the document @@ -441,7 +441,7 @@ def get(self, *ids): def info(self): """ - Get info an stats about the the current index, including the number of + Get info and stats about the current index, including the number of documents, memory consumption, etc For more information see `FT.INFO `_. @@ -898,7 +898,7 @@ def syndump(self): class AsyncSearchCommands(SearchCommands): async def info(self): """ - Get info an stats about the the current index, including the number of + Get info and stats about the current index, including the number of documents, memory consumption, etc For more information see `FT.INFO `_. diff --git a/valkey/commands/search/indexDefinition.py b/valkey/commands/search/indexDefinition.py index a668e85b..8ace3434 100644 --- a/valkey/commands/search/indexDefinition.py +++ b/valkey/commands/search/indexDefinition.py @@ -9,7 +9,7 @@ class IndexType(Enum): class IndexDefinition: - """IndexDefinition is used to define a index definition for automatic + """IndexDefinition is used to define an index definition for automatic indexing on Hash or Json update.""" def __init__( diff --git a/valkey/commands/search/query.py b/valkey/commands/search/query.py index c2dcccdd..2207b58c 100644 --- a/valkey/commands/search/query.py +++ b/valkey/commands/search/query.py @@ -303,7 +303,7 @@ def sort_by(self, field: str, asc: bool = True) -> "Query": def expander(self, expander: str) -> "Query": """ - Add a expander field to the query. + Add an expander field to the query. - **expander** - the name of the expander """ diff --git a/valkey/commands/timeseries/info.py b/valkey/commands/timeseries/info.py index 91794f6e..f0a85f50 100644 --- a/valkey/commands/timeseries/info.py +++ b/valkey/commands/timeseries/info.py @@ -32,7 +32,7 @@ def __init__(self, args): rules: A list of compaction rules of the time series. sourceKey: - Key name for source time series in case the current series + Key name for source time series if the current series is a target of a rule. chunkCount: Number of Memory Chunks used for the time series. diff --git a/valkey/connection.py b/valkey/connection.py index 699b3e51..5ee5a44c 100644 --- a/valkey/connection.py +++ b/valkey/connection.py @@ -1191,7 +1191,7 @@ def disconnect(self, inuse_connections: bool = True) -> None: Disconnects connections in the pool If ``inuse_connections`` is True, disconnect connections that are - current in use, potentially by other threads. Otherwise only disconnect + current in use, potentially by other threads. Otherwise, only disconnect connections that are idle in the pool. """ self._checkpid() diff --git a/valkey/ocsp.py b/valkey/ocsp.py index 644358b3..509d83b9 100644 --- a/valkey/ocsp.py +++ b/valkey/ocsp.py @@ -47,7 +47,7 @@ def _verify_response(issuer_cert, ocsp_response): def _check_certificate(issuer_cert, ocsp_bytes, validate=True): - """A wrapper the return the validity of a known ocsp certificate""" + """A wrapper to return the validity of a known ocsp certificate""" ocsp_response = ocsp.load_der_ocsp_response(ocsp_bytes)