diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..faa3394 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +RULES.md linguist-generated=true \ No newline at end of file diff --git a/.github/workflows/update-rules.yml b/.github/workflows/update-rules.yml new file mode 100644 index 0000000..4442f74 --- /dev/null +++ b/.github/workflows/update-rules.yml @@ -0,0 +1,39 @@ +name: Update Rules Page + +on: + pull_request: + branches: [main] + paths: + - 'styles/**' + - '.github/workflows/update-rules.yml' + +jobs: + generate_markdown: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: 3.x + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install pyyaml + + - name: Run script to generate Markdown + run: python scripts/update-rules-page.py + + - name: Commit and push changes + run: | + git config --local user.email "action@github.com" + git config --local user.name "GitHub Action" + git add -f RULES.md + TIMESTAMP=$(date -u +"%Y-%m-%d") + git commit -m "Update RULES.md - $TIMESTAMP." || echo "No changes to commit." + git config pull.rebase true + git pull origin ${{ github.head_ref }} + git push origin HEAD:${{ github.head_ref }} diff --git a/.gitignore b/.gitignore index 1461f1b..4c138c0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ Docshtml.zip Docsmd.zip +.DS_Store +/RULES.md \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8b0473d..ae81cc9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -16,7 +16,7 @@ Are you interested in contributing your team's product-specific terminology and 1. Create a folder such as `[Product Name]-Names` and add it to the [`Styles/Datadog` folder][4]. 2. Update the [CODEOWNERS file][5] with your team's GitHub handle. -3. Update the `StylesPath` to point to the approriate directory in your team repository's [`.vale.ini` file][6]. +3. Update the `StylesPath` to point to the appropriate directory in your team repository's [`.vale.ini` file][6]. In order to ease and speed up our review, here are some items you can check for when submitting your pull request: diff --git a/RULES.md b/RULES.md new file mode 100644 index 0000000..6669c73 --- /dev/null +++ b/RULES.md @@ -0,0 +1,848 @@ +# Vale Rules Overview + +This page provides a comprehensive list of the Vale linter rules used in Datadog documentation. + +Last Updated: 2024-03-20 + +## Table of Contents +- [Vocab](#vocab) +- [CWS-Descriptions](#cws-descriptions) +- [SIEM-Names](#siem-names) +- [Datadog](#datadog) +- [CWS-Names](#cws-names) + +## Vocab + + +## CWS-Descriptions + +### Refer to the 'Datadog %s' instead of the 'Datadog %s' + +**Level:** *error* + +**Swap:** +- `agent` -> `Agent` + +**Ignore Case:** False + + +## SIEM-Names + +### Rule names should use sentence case + +**Level:** *error* + +
+Exceptions: + +- `1Password` +- `Advanced Protection` +- `Autoscaling Group` +- `Amazon EC2 Instance` +- `Amazon S3` +- `API calls` +- `Auth0 Attack Protection` +- `Auth0 Breached Password Detection` +- `Auth0 Brute Force Protection` +- `Auth0 Guardian MFA` +- `Auth0 Suspicious IP Throttling` +- `AWS Cloudtrail GetCallerIdentity` +- `AWS DescribeInstances` +- `AWS IAM User created with AdministratorAccess policy attached` +- `AWS ConsoleLogin` +- `AWS Console login without MFA` +- `AWS GuardDuty` +- `AWS IAM Roles Anywhere` +- `AWS Kinesis Firehose` +- `AWS Lambda` +- `AWS Network Gateway` +- `AWS Secrets Manager` +- `AWS Systems Manager` +- `AWS Verified Access` +- `AWS VPC Flow Log` +- `Azure Active Directory` +- `Azure AD Identity Protection` +- `Azure AD Privileged Identity Management` +- `CloudTrail` +- `Cloudflare` +- `Cloudflare CASB Finding` +- `Cloudflare L7 DDOS` +- `Crowdstrike Alerts` +- `Enterprise Organization` +- `GitHub` +- `GitHub Advanced Security` +- `GitHub Dependabot` +- `GitHub Personal Access Token` +- `GitHub Secret Scanning` +- `Google App Engine` +- `Google Cloud` +- `Google Cloud IAM Role updated` +- `Google Cloud Storage` +- `Google Cloud Storage Bucket` +- `Google Compute` +- `Google Compute Engine` +- `Google Drive` +- `Google Security Command Center` +- `Google Workspace` +- `IdP configuration changed` +- `Impossible Travel Auth0` +- `IoC` +- `Jamf Protect` +- `Microsoft 365 Application Impersonation` +- `Microsoft 365 Default or Anonymous` +- `Microsoft 365 E-Discovery` +- `Microsoft 365 Exchange` +- `Microsoft 365 Full Access` +- `Microsoft 365 Inbound Connector` +- `Microsoft 365 OneDrive` +- `Microsoft 365 Security and Compliance` +- `Microsoft 365 SendAs` +- `Microsoft Defender for Cloud` +- `Microsoft Intune Enterprise MDM` +- `Microsoft Teams` +- `Okta` +- `Okta Identity Provider` +- `Palo Alto Networks Firewall` +- `RDS Snapshot` +- `Scout Suite` +- `Sqreen` +- `Tor` +- `TruffleHog` +- `Zendesk Automatic Redaction` +
+ + +## Datadog + +### Use inclusive language + +**Level:** *error* + +[Link](https://github.com/DataDog/documentation/blob/master/CONTRIBUTING.md#inclusive-language) + +**Swap:** +- `black ?list` -> `disallow list|exclude list` +- `master` -> `primary` +- `slave` -> `secondary` +- `white ?list` -> `allow list|include list` + +**Ignore Case:** True + +### Avoid vague text in links like '%s' unless you can pair it with more descriptive text + +**Level:** *warning* + +[Link](https://github.com/DataDog/documentation/blob/master/CONTRIBUTING.md#links) + +**Swap:** +- `\[here\]\(.*?\)` -> `here` +- `\s*here\s*` -> `here` +- `\[this\]\(.*?\)` -> `this` +- `\s*this\s*` -> `this` +- `\[page\]\(.*?\)` -> `page` +- `\s*page\s*` -> `page` +- `\[this page\]\(.*?\)` -> `this page` +- `\s*this page\s*` -> `this page` + +**Ignore Case:** True + +### Use '%s' instead of '%s' + +**Level:** *warning* + +[Link](https://github.com/DataDog/documentation/blob/master/CONTRIBUTING.md#words-and-phrases) + +**Swap:** +- `a number of` -> `few|several|many` +- `acknowledgement` -> `acknowledgment` +- `App Analytics` -> `Tracing without Limits™` +- `auto(?:\s|-)complete` -> `autocomplete` +- `auto(?:\s|-)completion` -> `autocompletion` +- `Availability Zone` -> `availability zone` +- `Availability Zones` -> `availability zones` +- `back(?:\s|-)end` -> `backend` +- `back(?:\s|-)ends` -> `backends` +- `bear in mind` -> `keep in mind` +- `boolean` -> `Boolean` +- `booleans` -> `Booleans` +- `cheat sheet` -> `cheatsheet` +- `command line interface` -> `command-line interface` +- `Create a new` -> `Create a|Create an` +- `culprit` -> `cause` +- `data are` -> `data is` +- `data(?:\s|-)point` -> `datapoint` +- `data(?:\s|-)points` -> `datapoints` +- `data(?:\s|-)set` -> `dataset` +- `data(?:\s|-)sets` -> `datasets` +- `data-?center` -> `data center` +- `data-?centers` -> `data centers` +- `Datadog (?:app|application)` -> `Datadog|Datadog site` +- `Datadog product` -> `Datadog|Datadog service` +- `data-?source` -> `data source` +- `data-?sources` -> `data sources` +- `default (?:dash|screen)board` -> `out-of-the-box dashboard` +- `default (?:dash|screen)boards` -> `out-of-the-box dashboards` +- `(?:Dev/?ops|dev/?ops|Dev/Ops)` -> `DevOps|DevSecOps` +- `drill (?:down|into)` -> `examine|investigate|analyze` +- `drilling (?:down|into)` -> `examining|investigating|analyzing` +- `Distributed Tracing` -> `distributed tracing` +- `(?:easy|easily)` -> `` +- `e-?book` -> `eBook` +- `e-?books` -> `eBooks` +- `e-mail` -> `email` +- `e-mailing` -> `emailing` +- `e-mails` -> `emails` +- `end(?:\s|-)point` -> `endpoint` +- `end(?:\s|-)points` -> `endpoints` +- `event (?:stream|streem)` -> `Event Stream` +- `flame-?graph` -> `flame graph` +- `flame-?graphs` -> `flame graphs` +- `figure out` -> `determine` +- `figuring out` -> `determining` +- `file(?:\s|-)name` -> `filename` +- `file(?:\s|-)names` -> `filenames` +- `filesystem` -> `file system` +- `filesystems` -> `file systems` +- `fine\s?-?tune` -> `customize|optimize|refine` +- `for the most part` -> `generally|usually` +- `front(?:\s|-)end` -> `frontend` +- `health-?check` -> `heath check` +- `health-?checks` -> `heath checks` +- `(?:heat-?map|Heat Map)` -> `heat map` +- `(?:heat-?maps|Heat Maps)` -> `heat maps` +- `(?:host-?map|Host Map)` -> `host map` +- `(?:host-?maps|Host Maps)` -> `host maps` +- `hone in` -> `home in` +- `hones in` -> `homes in` +- `honing in` -> `homing in` +- `highly` -> `` +- `hit` -> `click|select` +- `in order to` -> `to` +- `in sync` -> `in-sync` +- `In sync` -> `In-sync` +- `indices` -> `indexes` +- `indexation` -> `indexing` +- `infrastructures` -> `infrastructure` +- `install command` -> `installation command` +- `Internet` -> `internet` +- `(?:i/?-?o|I-?O)` -> `I/O` +- `(?:i/?ops|I/OPS)` -> `IOPS` +- `just` -> `` +- `keep in mind` -> `consider` +- `left up to` -> `determined by` +- `let's assume` -> `assuming|for example, if` +- `load-?balancing` -> `load balancing` +- `machine-?learning` -> `machine learning` +- `micro(?:\s|-)service` -> `microservice` +- `micro(?:\s|-)services` -> `microservices` +- `multi-?alert` -> `multi alert` +- `multicloud` -> `multi-cloud` +- `multiline` -> `multi-line` +- `Note that` -> `**Note**:` +- `(?:obvious|obviously|Obviously)` -> `` +- `off-line` -> `offline` +- `on the fly` -> `real-time|in real time` +- `Once` -> `After` +- `open-?source` -> `open source` +- `page view` -> `pageview` +- `page views` -> `pageviews` +- `play a hand` -> `influence` +- `please` -> `` +- `pre-connect` -> `preconnect` +- `quick|quickly` -> `` +- `screen(?:\s|-)board` -> `screenboard` +- `simple|simply` -> `` +- `single pane of glass` -> `single view|single place|single page` +- `slice and dice` -> `filter and group` +- `stand for` -> `represent|mean` +- `Synthetics` -> `Synthetic Monitoring` +- `reenable` -> `re-enable` +- `run(?:\s|-)time` -> `runtime` +- `refer to|visit` -> `see|read|follow` +- `time board` -> `timeboard` +- `time(?:\s|-)series` -> `timeseries` +- `time-?frame` -> `time frame` +- `time-?frames` -> `time frames` +- `top-?list` -> `top list` +- `trade(?:\s|-)off` -> `trade-off` +- `Trace Search and Analytics` -> `Tracing without Limits™` +- `turnkey` -> `ready to use` +- `under the hood` -> `` +- `utilize` -> `use` +- `very` -> `` +- `via` -> `with|through` +- `visit` -> `see|read` +- `webserver` -> `web server` +- `web site` -> `website` +- `X-axis` -> `x-axis` +- `Y-axis` -> `y-axis` +- `(?:github|Github)` -> `GitHub` +- `(?:kubernetes|k8s|K8s|K8S)` -> `Kubernetes` +- `(?:Mapreduce|mapreduce|Map reduce|Map Reduce)` -> `MapReduce` +- `memcached` -> `Memcached` +- `(?:nginx|Nginx)` -> `NGINX` +- `(?:node.js|nodeJS|NodeJS|node.JS|Node.JS)` -> `Node.js` +- `(?:pagerduty|pager duty|Pagerduty|Pager duty)` -> `PagerDuty` +- `prometheus` -> `Prometheus` +- `(?:sql|Sql)` -> `SQL` +- `(?:statsd|statsD|Statsd)` -> `StatsD` +- `(?:unix|Unix)` -> `UNIX` + +**Ignore Case:** False + +### Do not use Latin abbreviations + +**Level:** *warning* + +[Link](https://github.com/DataDog/documentation/blob/master/CONTRIBUTING.md#abbreviations) + +**Swap:** +- `\b(?:eg|e\.g\.|eg\.)[\s,]` -> `for example` +- `\b(?:ie|i\.e\.|ie\.)[\s,]` -> `that is` + +**Ignore Case:** True + +### '%s' should use sentence-style capitalization + +**Level:** *warning* + +[Link](https://github.com/DataDog/documentation/blob/master/CONTRIBUTING.md#headers) + +
+Exceptions: + +- `ACLs` +- `ActiveMQ XML Integration` +- `Agent` +- `Agentless` +- `Agents` +- `Airflow` +- `Amazon` +- `Amazon Web Services` +- `APCu` +- `APIs` +- `APM` +- `Application Performance Monitoring` +- `APM & Continuous Profiler` +- `App Analytics` +- `App Service` +- `AppVeyor` +- `Application Security Management` +- `Application Vulnerability Management` +- `AuthN` +- `Autodiscovery` +- `AWS Step Functions` +- `AWS Systems Manager` +- `Azure` +- `Azure App Service` +- `Azure App Service Plan` +- `Azure Blob Storage` +- `Azure Event Hub` +- `Audit Trail` +- `BitBucket` +- `BuildKite` +- `Browser Monitoring` +- `CakePHP` +- `Cassandra Nodetool` +- `Cassandra Nodetool Integration` +- `CentOS` +- `Chef` +- `CircleCI` +- `CI/CD` +- `CI Visibility` +- `Clipboard` +- `Cloud Cost Management` +- `Cloud Pub Sub` +- `Cloud Security Management` +- `Cloud Security Posture Management` +- `Cloud SIEM` +- `Cloud Workload Security` +- `CloudFormation` +- `CloudSQL` +- `CloudTrail` +- `CloudWatch` +- `Cluster Agent` +- `Continuous Profiler` +- `Continuous Testing` +- `DaemonSet` +- `Data Collected` +- `Database Monitoring` +- `Datadog` +- `DatadogMetric` +- `Datadog Agent Manager` +- `Datadog for Government` +- `Datadog Forwarder` +- `Datadog Lambda Extension` +- `Datadog Operator` +- `Datadog Plugin` +- `Datadog Watchdog` +- `DatadogHook` +- `Debian` +- `Detection Rules` +- `Docker` +- `Docker Compose` +- `Docker Swarm` +- `Dockerfile` +- `DogStatsD` +- `Envoy` +- `Fargate` +- `FastCGI` +- `Firehose Nozzle` +- `FireLens` +- `Fluent Bit` +- `Fluentd` +- `FreeBSD` +- `FreeSwitch` +- `Further Reading` +- `GeoIP` +- `Git` +- `GitHub` +- `GitHub Actions` +- `GitLab` +- `GitLab Runner Integration` +- `Google` +- `Google Analytics` +- `Google Cloud` +- `Google Cloud Functions` +- `GraphQL` +- `Gunicorn` +- `HAProxy` +- `HBase RegionServer Integration` +- `HDFS DataNode Integration` +- `HDFS NameNode Integration` +- `Helm` +- `Heroku` +- `HipChat` +- `HostPort` +- `I` +- `IdP` +- `IDs` +- `iLert` +- `Incident Management` +- `Infrastructure Monitoring` +- `Ingress Controller` +- `Internet Information Services` +- `IoT` +- `IPs` +- `Java` +- `JavaScript` +- `JBoss` +- `Jenkins` +- `JFrog` +- `JFrog Artifactory` +- `Jira` +- `JMXFetch` +- `Journald` +- `Kafka` +- `Kafka Consumer Integration` +- `Kubernetes` +- `Kubernetes Engine` +- `Kubernetes Pod` +- `Kubernetes Service` +- `Lambda` +- `Lambda Layer` +- `Lambda@Edge` +- `LaunchDarkly` +- `Linux` +- `Live Analytics` +- `Live Search` +- `Live Tail` +- `Log Explorer` +- `Log Management` +- `Log Rehydration` +- `Logback` +- `macOS` +- `Marketplace` +- `MarkLogic` +- `Meraki` +- `Mesos Slave Integration` +- `Metrics Explorer` +- `Metrics without Limits` +- `Mobile Monitoring` +- `MongoDB` +- `MsTest` +- `MySQL` +- `Network Address Translation` +- `Network Device Monitoring` +- `Network Performance Monitoring` +- `New Relic` +- `NGINX Plus` +- `NixOS` +- `Node` +- `Notebook` +- `Notebook List` +- `npm` +- `NXLog` +- `Observability Pipelines` +- `OkHttp` +- `OneLogin` +- `OPcache` +- `OpenLDAP` +- `OpenMetrics` +- `OpenShift` +- `OpenStack` +- `openSUSE` +- `OpenTelemetry` +- `OpenTracing` +- `OpenVPN` +- `OpsGenie` +- `OpsWorks` +- `Oracle Instant Client` +- `Phusion Passenger` +- `Pipeline Visibility` +- `Pivotal Platform` +- `Postgres` +- `PostgreSQL` +- `PowerDNS` +- `Prometheus` +- `Prometheus Alertmanager` +- `Puppet` +- `Python` +- `RabbitMQ` +- `Rails` +- `Rancher` +- `Real User Monitoring` +- `Red Hat` +- `Redis` +- `ReplicaSet` +- `RocketPants` +- `Roku Monitoring` +- `Root Cause Analysis` +- `Route53` +- `RSpec` +- `Ruby` +- `RUM` +- `RumMonitor` +- `SafeNet` +- `SaltStack` +- `Security Monitoring` +- `Security Signal` +- `Security Signals` +- `SELinux` +- `Sensitive Data Scanner` +- `Serverless APM` +- `Serverless Framework` +- `Serverless Monitoring` +- `Serverless Workload Monitoring` +- `Service Checks` +- `Session Replay` +- `Siri` +- `Slack` +- `SLIs` +- `SLOs` +- `socat` +- `Social Security` +- `SQL Server` +- `SQLDelight` +- `SQLite` +- `Stackdriver` +- `StackPulse` +- `StackStorm` +- `StatsD` +- `Sumo Logic` +- `Swift` +- `Synthetic Monitoring` +- `Syslog` +- `sysOID` +- `System Core` +- `System Swap` +- `Teamcity` +- `Terraform` +- `Testing Visibility` +- `TokuMX` +- `Tracing Without Limits` +- `Trello` +- `Twilio` +- `TypeScript` +- `Ubuntu` +- `Unified Service Tagging` +- `Unix` +- `Unix Domain Socket` +- `URLs` +- `User Datagram Protocol` +- `USM` +- `Universal Service Monitoring` +- `Varnish` +- `Vector` +- `Vertica` +- `VMWare` +- `vSphere` +- `Watchdog` +- `Watchdog Insights` +- `Webhook` +- `WildFly` +- `Windows` +- `Xray` +- `ZooKeeper` +
+ +### Missing ™ on phrase '%s' + +**Level:** *error* + +[Link](https://www.datadoghq.com) + +**Tokens:** +- `(? +Exceptions: + +- `(?:A|a)dvertise` +- `(?:A|a)dvise` +- `(?:A|a)ppraise` +- `(?:A|a)pprise` +- `(?:A|a)rise` +- `(?:C|c)hastise` +- `(?:C|c)ircumcise` +- `(?:C|c)lockwise` +- `(?:C|c)omprise` +- `(?:C|c)ompromise` +- `(?:C|c)oncise` +- `(?:C|c)ounterclockwise` +- `(?:D|d)emise` +- `(?:D|d)espise` +- `(?:D|d)evise` +- `(?:D|d)isguise` +- `(?:E|e)nterprise` +- `(?:E|e)xcise` +- `(?:E|e)xercise` +- `(?:E|e)xpertise` +- `(?:F|f)ranchise` +- `(?:I|i)mprecise` +- `(?:I|i)mprovise` +- `(?:I|i)ncise` +- `(?:L|l)ikewise` +- `(?:M|m)erchandise` +- `(?:N|n)oise` +- `(?:O|o)therwise` +- `(?:P|p)aradise` +- `(?:P|p)oise` +- `(?:P|p)raise` +- `(?:P|p)recise` +- `(?:P|p)remise` +- `(?:P|p)romise` +- `(?:R|r)evise` +- `(?:R|r)ise` +- `(?:S|s)upervise` +- `(?:S|s)urmise` +- `(?:S|s)urprise` +- `(?:T|t)elevise` +- `(?:W|w)ise` +- `(?:d|D)etours?` +- `(?:c|C)ontours?` +- `(?:g|G)lamour` +- `(?:o|O)utpour` +- `(?:s|S)cours?` +- `(?:t|T)roubadours?` +- `(?:p|P)ompadour` + + +**Ignore Case:** True + +### Avoid first-person pronouns such as '%s' + +**Level:** *warning* + +[Link](https://github.com/DataDog/documentation/blob/master/CONTRIBUTING.md#pronouns) + +**Tokens:** +- `(?<=^|\s)I(?=\s)` +- `(?<=^|\s)I,(?=\s)` +- `\bI'm\b` +- `(?<=\s)[Mm]e\b` +- `(?<=\s)[Mm]y\b` +- `(?<=\s)[Mm]ine\b` +- `(?<=\s)[Ww]e\b` +- `we'(?:ve|re)` +- `(?<=\s)[Uu]s\b` +- `(?<=\s)[Oo]ur\b` +- `\blet's\b` + +### Avoid en dashes ('–'). For hyphenated words, use a hyphen ('-'). +For parenthesis, use an em dash ('—') + +**Level:** *error* + +[Link](https://github.com/DataDog/documentation/blob/master/CONTRIBUTING.md#dashes) + +**Tokens:** +- `–` + +### Use %s (the former, to refer to Datadog's mechanism for applying integration configurations to containers; the latter, to refer to automatic discovery IN GENERAL) instead of '%s' + +**Level:** *warning* + +[Link](https://github.com/DataDog/documentation/blob/master/CONTRIBUTING.md#words-and-phrases) + +**Swap:** +- `{'(?:autodiscovery|auto-discovery|Auto-discovery)': 'Autodiscovery|automatic detection'}` +- `{'(?:autodiscover|auto-discover|Auto-discover)': 'Autodiscover|automatically detect'}` +- `{'(?:autodiscovered|auto-discovered|Auto-discovered)': 'Autodiscovered|automatically detected'}` + +**Ignore Case:** False + +### Use gender-neutral pronouns + +**Level:** *error* + +[Link](https://github.com/DataDog/documentation/blob/master/CONTRIBUTING.md#gender) + +**Tokens:** +- `he/she` +- `s/he` +- `\(s\)he` +- `\bhe\b` +- `\bhim\b` +- `\bhis\b` +- `\bshe\b` +- `\bher\b` + +**Ignore Case:** True + +### Use only one space between words and sentences (not two) + +**Level:** *error* + +[Link](https://github.com/DataDog/documentation/blob/master/CONTRIBUTING.md#spaces) + +**Tokens:** +- `[\w.?!,\(\)\-":] {2,}[\w.?!,\(\)\-":]` + +### Use straight quotes instead of smart quotes + +**Level:** *error* + +**Tokens:** +- `“` +- `”` +- `‘` +- `’` + +### Format times as 'HOUR:MINUTE a.m.' or HOUR:MINUTE p.m.' instead of '%s' + +**Level:** *warning* + +[Link](https://datadoghq.atlassian.net/wiki/spaces/WRIT/pages/2732523547/Style+guide#%s) + +**Tokens:** +- `(1[012]|[1-9]):[0-5][0-9] (A\.M\.|P\.M\.)` +- `(1[012]|[1-9]):[0-5][0-9] (?i)(a\.m[^\.]|p\.m[^\.])` +- `(1[012]|[1-9]):[0-5][0-9][ ]?(?i)(am|pm)` + +### Use the Oxford comma in '%s' + +**Level:** *suggestion* + +[Link](https://github.com/DataDog/documentation/blob/master/CONTRIBUTING.md#commas) + +**Tokens:** +- `(?:[^,]+,){1,}\s\w+\s(?:and|or)` + +### Don't put a space before or after a dash + +**Level:** *warning* + +[Link](https://github.com/DataDog/documentation/blob/master/CONTRIBUTING.md#dashes) + +**Tokens:** +- `\s[—–]\s` + +### Try to keep your sentence length to 25 words or fewer + +**Level:** *suggestion* + +**Ignore Case:** False + + +## CWS-Names + +### Rule names should not start with '%s' + +**Level:** *error* + +**Tokens:** +- `A` +- `An` +- `The` + +**Ignore Case:** False + +### Rule names should avoid weak works like '%s' + +**Level:** *error* + +[Link](https://developers.google.com/tech-writing/one/clear-sentences) + +**Tokens:** +- `was` +- `were` +- `is` +- `are` + +**Ignore Case:** True + +### Rule names should use sentence case + +**Level:** *error* + +
+Exceptions: + +- `OverlayFS` +- `DNS` +- `TXT` +- `Kubernetes` +
+ +### New Value rules should use '%s' instead of '%s' + +**Level:** *error* + +**Swap:** +- `unrecognized` -> `unfamiliar` +- `unusual` -> `unfamiliar` +- `new` -> `unfamiliar` + +**Ignore Case:** True + +### Rule names should not be longer than 10 words + +**Level:** *error* + +**Ignore Case:** False + diff --git a/scripts/update-rules-page.py b/scripts/update-rules-page.py new file mode 100644 index 0000000..85956ec --- /dev/null +++ b/scripts/update-rules-page.py @@ -0,0 +1,78 @@ +import os +import yaml +from datetime import datetime + +def generate_rule_markdown(rule_data): + + ## Use description field if it exists; if not, use message field + description = rule_data.get('description', rule_data['message'].rstrip('.')) + markdown = f"### {description}\n\n" + markdown += f"**Level:** *{rule_data['level']}*\n\n" + + if 'link' in rule_data: + markdown += f"[Link]({rule_data['link']})\n\n" + + for field in ['tokens']: + if field in rule_data: + markdown += f"**{field.capitalize()}:**\n" + for item in rule_data[field]: + markdown += f"- `{item}`\n" + markdown += "\n" + + if 'exceptions' in rule_data: + markdown += "
\nExceptions:\n\n" + for exception in rule_data['exceptions']: + markdown += f"- `{exception}`\n" + markdown += "
\n\n" + + if 'swap' in rule_data: + markdown += "**Swap:**\n" + if isinstance(rule_data['swap'], dict): + for key, value in rule_data['swap'].items(): + markdown += f"- `{key}` -> `{value}`\n" + elif isinstance(rule_data['swap'], list): + for item in rule_data['swap']: + markdown += f"- `{item}`\n" + markdown += "\n" + + if 'ignorecase' in rule_data: + markdown += f"**Ignore Case:** {rule_data['ignorecase']}\n\n" + + return markdown + +def process_subfolder(subfolder_path): + markdown_content = "" + for root, _, files in os.walk(subfolder_path): + for file in files: + if file.endswith('.yml'): + with open(os.path.join(root, file), 'r') as f: + rule_data = yaml.safe_load(f) + markdown_content += generate_rule_markdown(rule_data) + return markdown_content + +def generate_table_of_contents(style_folders): + toc = "## Table of Contents\n" + for folder in style_folders: + toc += f"- [{folder}](#{folder.lower()})\n" + return toc + +def main(): + styles_folder = 'styles' + style_folders = [folder for folder in os.listdir(styles_folder) + if os.path.isdir(os.path.join(styles_folder, folder))] + + markdown_content = "# Vale Rules Overview\n\n" + markdown_content += "This page provides a comprehensive list of the Vale linter rules used in Datadog documentation.\n\n" + markdown_content += f"Last Updated: {datetime.now().strftime('%Y-%m-%d')}\n\n" + markdown_content += generate_table_of_contents(style_folders) + + for style_folder in style_folders: + subfolder_path = os.path.join(styles_folder, style_folder) + markdown_content += f"\n## {style_folder}\n\n" + markdown_content += process_subfolder(subfolder_path) + + with open('RULES.md', 'w') as file: + file.write(markdown_content) + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/styles/Datadog/abbreviations.yml b/styles/Datadog/abbreviations.yml index bcd2163..356d424 100644 --- a/styles/Datadog/abbreviations.yml +++ b/styles/Datadog/abbreviations.yml @@ -1,4 +1,5 @@ extends: substitution +description: Do not use Latin abbreviations message: "Use '%s' instead of abbreviations like '%s'." link: "https://github.com/DataDog/documentation/blob/master/CONTRIBUTING.md#abbreviations" ignorecase: true diff --git a/styles/Datadog/americanspelling.yml b/styles/Datadog/americanspelling.yml index 415b8e6..9618399 100644 --- a/styles/Datadog/americanspelling.yml +++ b/styles/Datadog/americanspelling.yml @@ -1,4 +1,5 @@ extends: existence +description: Use American spelling message: "In general, use American spelling instead of '%s'." link: 'https://github.com/DataDog/documentation/blob/master/CONTRIBUTING.md' ignorecase: true diff --git a/styles/Datadog/gender.yml b/styles/Datadog/gender.yml index b2b19b7..cc0a570 100644 --- a/styles/Datadog/gender.yml +++ b/styles/Datadog/gender.yml @@ -1,4 +1,5 @@ extends: existence +description: Use gender-neutral pronouns message: "Use a gender-neutral pronoun instead of '%s'." link: "https://github.com/DataDog/documentation/blob/master/CONTRIBUTING.md#gender" level: error diff --git a/styles/Datadog/inclusive.yml b/styles/Datadog/inclusive.yml index bc1a9df..8a815f0 100644 --- a/styles/Datadog/inclusive.yml +++ b/styles/Datadog/inclusive.yml @@ -1,4 +1,5 @@ extends: substitution +description: Use inclusive language message: "Use '%s' instead of '%s'." link: "https://github.com/DataDog/documentation/blob/master/CONTRIBUTING.md#inclusive-language" ignorecase: true