diff --git a/.expeditor/buildkite/verify.sh b/.expeditor/buildkite/verify.sh
index f2a3a3092..796901753 100755
--- a/.expeditor/buildkite/verify.sh
+++ b/.expeditor/buildkite/verify.sh
@@ -8,7 +8,8 @@ ruby -v
bundle --version
echo "--- bundle install"
-bundle install --jobs=7 --retry=3 --without tools maintenance deploy
+bundle config set --local without tools maintenance deploy
+bundle install --jobs=7 --retry=3
bundle update
echo "+++ bundle exec rake lint"
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b37f3562a..31a0ed007 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,10 +1,35 @@
# Changelog
-
+
+## [v1.68.5](https://github.com/inspec/inspec-azure/tree/v1.68.5) (2021-09-14)
+
+#### Merged Pull Requests
+- Add vale linter [#444](https://github.com/inspec/inspec-azure/pull/444) ([IanMadd](https://github.com/IanMadd))
+
+
+## [v1.68.4](https://github.com/inspec/inspec-azure/tree/v1.68.4) (2021-09-14)
+
+#### Merged Pull Requests
+- Fix YAML frontmatter lines in resource docs pages [#479](https://github.com/inspec/inspec-azure/pull/479) ([IanMadd](https://github.com/IanMadd))
+
+## [v1.68.3](https://github.com/inspec/inspec-azure/tree/v1.68.3) (2021-09-14)
+
+#### Merged Pull Requests
+- F/linked service [#430](https://github.com/inspec/inspec-azure/pull/430) ([sa-progress](https://github.com/sa-progress))
+
+## [v1.68.2](https://github.com/inspec/inspec-azure/tree/v1.68.2) (2021-09-14)
+
+#### Merged Pull Requests
+- Update rubocop requirement from ~> 1.20.0 to ~> 1.21.0 [#478](https://github.com/inspec/inspec-azure/pull/478) ([dependabot[bot]](https://github.com/dependabot[bot]))
+
+## [v1.68.1](https://github.com/inspec/inspec-azure/tree/v1.68.1) (2021-09-02)
+
+#### Merged Pull Requests
+- skip nested nil values in array [#449](https://github.com/inspec/inspec-azure/pull/449) ([sathish-progress](https://github.com/sathish-progress))
+
## [v1.68.0](https://github.com/inspec/inspec-azure/tree/v1.68.0) (2021-08-31)
#### Merged Pull Requests
- Support azure synapse notebooks [#422](https://github.com/inspec/inspec-azure/pull/422) ([sathish-progress](https://github.com/sathish-progress))
-
## [v1.67.0](https://github.com/inspec/inspec-azure/tree/v1.67.0) (2021-08-31)
diff --git a/Gemfile b/Gemfile
index 2850c3854..1510dff78 100644
--- a/Gemfile
+++ b/Gemfile
@@ -14,5 +14,5 @@ end
group :development, :test do
gem 'minitest'
- gem 'rubocop', '~> 1.20.0'
+ gem 'rubocop', '~> 1.21.0'
end
diff --git a/README.md b/README.md
index 2ec217598..bd6d4cb5c 100644
--- a/README.md
+++ b/README.md
@@ -128,6 +128,10 @@ The following is a list of static resources.
- [azure_container_registries](docs/resources/azure_container_registries.md)
- [azure_container_registry](docs/resources/azure_container_registry.md)
- [azure_cosmosdb_database_account](docs/resources/azure_cosmosdb_database_account.md)
+- [azure_data_factories](docs/resources/azure_data_factories.md)
+- [azure_data_factory](docs/resources/azure_data_factory.md)
+- [azure_data_factory_linked_service](docs/resources/azure_data_factory_linked_service.md)
+- [azure_data_factory_linked_services](docs/resources/azure_data_factory_linked_services.md)
- [azure_db_migration_service](docs/resources/azure_db_migration_service.md)
- [azure_db_migration_services](docs/resources/azure_db_migration_services.md)
- [azure_ddos_protection_resource](docs/resources/azure_ddos_protection_resource.md)
@@ -421,7 +425,7 @@ They can be defined as environment variables or resource parameters (has priorit
If you'd like to contribute to this project please see [Contributing Rules](CONTRIBUTING.md).
-For a detailed walk-through of resource creation, see the [Resource Creation Guide](docs/resource_creation_guide.md).
+For a detailed walk-through of resource creation, see the [Resource Creation Guide](dev-docs/resource_creation_guide.md).
### Developing a Static Resource
diff --git a/VERSION b/VERSION
index 21807ece4..5f09f1823 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.68.0
\ No newline at end of file
+1.68.5
\ No newline at end of file
diff --git a/docs/resource_creation_guide.md b/dev-docs/resource_creation_guide.md
similarity index 100%
rename from docs/resource_creation_guide.md
rename to dev-docs/resource_creation_guide.md
diff --git a/docs/.vale.ini b/docs/.vale.ini
new file mode 100644
index 000000000..b292dedef
--- /dev/null
+++ b/docs/.vale.ini
@@ -0,0 +1,17 @@
+# Vale configuration file.
+#
+# For more information, see https://errata-ai.gitbook.io/vale/getting-started/configuration.
+
+StylesPath = tools/vale
+MinAlertLevel = suggestion
+
+[*.md]
+BasedOnStyles = Microsoft, write-good, chef
+
+Microsoft.Contractions = NO
+Microsoft.Headings = NO
+Microsoft.GeneralURL = NO
+Microsoft.RangeFormat = NO
+
+# Ignore SVG markup
+TokenIgnores = (\*\*\{\w*\}\*\*)
\ No newline at end of file
diff --git a/docs/resources/azure_data_factory_linked_service.md b/docs/resources/azure_data_factory_linked_service.md
new file mode 100644
index 000000000..d83e71843
--- /dev/null
+++ b/docs/resources/azure_data_factory_linked_service.md
@@ -0,0 +1,84 @@
+---
+title: About the azure_data_factory_linked_service Resource
+platform: azure
+---
+
+# azure_data_factory_linked_service
+
+Use the `azure_data_factory_linked_service` InSpec audit resource to test the properties of an Azure Linked service.
+
+## Azure REST API Version, Endpoint, and HTTP Client Parameters
+
+This resource interacts with API versions supported by the resource provider. The `api_version` is defined as a resource parameter.
+If not provided, the latest version is used. For more information, refer to [`azure_generic_resource`](azure_generic_resource.md).
+
+Unless defined, `azure_cloud` global endpoint and default values for the HTTP client is used. For more information, refer to the resource pack [README](../../README.md). For API related info : [`Azure Linked Services Docs`](https://docs.microsoft.com/en-us/rest/api/datafactory/linked-services/get).
+
+## Availability
+
+### Installation
+
+This resource is available in the [InSpec Azure resource pack](https://github.com/inspec/inspec-azure). For an example, `inspec.yml` file and how to set up your Azure credentials, refer to resource pack [README](../../README.md#Service-Principal).
+
+## Syntax
+
+`resource_group`, `linked_service_name`, and `factory_name` are required parameters.
+
+```ruby
+describe azure_data_factory_linked_service(resource_group: `RESOURCE_GROUP`, factory_name: `FACTORY_NAME`, linked_service_name: `LINKED_SERVICE_NAME`) do
+end
+```
+
+## Parameters
+
+| Name | Description |
+|--------------------------------|-----------------------------------------------------------------------------------|
+| resource_group | Azure resource group that the targeted resource resides in. |
+| factory_name | The factory name. |
+| linked_service_name | The name of the linked service. |
+
+All the parameter sets are required for a valid query:
+
+- `resource_group` , `factory_name`, and `linked_service_name`.
+
+## Properties
+
+| Name | Description |
+|--------------------------------|----------------------------------------------------------------------------------|
+| name | Name of the Azure resource to test. |
+| type | The resource type. |
+| linked_service_type | The linked services type. |
+| type_properties | The properties of linked service type. |
+| properties | The properties of the resource. |
+
+## Examples
+
+### Test that a Linked Service exists
+
+```ruby
+describe azure_data_factory_linked_service(resource_group: `RESOURCE_GROUP`, factory_name: `FACTORY_NAME`, linked_service_name: `LINKED_SERVICE_NAME`) do
+ it { should exist }
+end
+```
+
+### Test that a linked service does not exist
+
+```ruby
+describe azure_data_factory_linked_service(resource_group: `RESOURCE_GROUP`, factory_name: `FACTORY_NAME`, linked_service_name: 'should not exit') do
+ it { should_not exist }
+end
+```
+
+### Test properties of a linked service
+
+```ruby
+describe azure_data_factory_linked_service(resource_group: `RESOURCE_GROUP`, name: 'FACTORY_NAME') do
+ its('name') { should eq linked_service_name1 }
+ its('type') { should eq 'Microsoft.DataFactory/factories/linkedservices' }
+ its('linked_service_type') { should eq 'MYSQL' }
+end
+```
+
+## Azure Permissions
+
+Your [Service Principal](https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-create-service-principal-portal) must be set up with a `contributor` role on the subscription you wish to test.
diff --git a/docs/resources/azure_data_factory_linked_services.md b/docs/resources/azure_data_factory_linked_services.md
new file mode 100644
index 000000000..51319171c
--- /dev/null
+++ b/docs/resources/azure_data_factory_linked_services.md
@@ -0,0 +1,86 @@
+---
+title: About the azure_data_factory_linked_service Resource
+platform: azure
+---
+
+# azure_data_factory_linked_service
+
+Use the `azure_data_factory_linked_service` InSpec audit resource to test the properties related to linked services for a resource group or the entire subscription.
+
+## Azure REST API Version, Endpoint, and HTTP Client Parameters
+
+This resource interacts with API versions supported by the resource provider. The `api_version` is defined as a resource parameter. If not provided, the latest version is used. For more information, refer to [`azure_generic_resource`](azure_generic_resource.md).
+
+Unless defined, `azure_cloud` global endpoint and default values for the HTTP client is used. For more information, refer to the resource pack [README](../../README.md). For information on API, refer [`Azure Linked Services Docs`](https://docs.microsoft.com/en-us/rest/api/datafactory/linked-services/list-by-factory).
+
+## Availability
+
+### Installation
+
+This resource is available in the [InSpec Azure resource pack](https://github.com/inspec/inspec-azure). For an example, `inspec.yml` file and how to set up your Azure credentials, refer to resource pack [README](../../README.md#Service-Principal).
+
+## Syntax
+
+An `azure_data_factory_linked_service` resource block returns all Azure Linked Services, either within a Resource Group (if provided), or within an entire Subscription.
+
+```ruby
+describe (resource_group: `RESOURCE_GROUP`, factory_name: 'FACTORY_NAME') do
+ #...
+end
+```
+
+`resource_group` and `factory_name` are required parameters.
+
+## Parameters
+
+| Name | Description |
+|--------------------------------|-----------------------------------------------------------------------------------|
+| resource_group | Azure resource group that the targeted resource resides in. |
+| factory_name | Azure factory name for which linked services are retrived. |
+
+## Properties
+
+| Property | Description | Filter Criteria* |
+|-----------------|---------------------------------------------------------|-----------------------|
+| names | A list of the unique resource names. | `name` |
+| ids | A list of Linked Services IDs. | `id` |
+| properties | A list of properties for the resource | `properties` |
+| provisioning_states | The linked services provisioning state. | `provisioning_state` |
+| linked_service_types | The type of linked service resource. | `linked_service_type` |
+| type_properties | The linked service type of properties. | `type_properties` |
+
+* For information on how to use filter criteria on plural resources, refer to [FilterTable usage](https://github.com/inspec/inspec/blob/master/dev-docs/filtertable-usage.md).
+
+## Examples
+
+### Test if any linked services exist in the resource group
+
+```ruby
+describe azure_data_factory_linked_service(resource_group: `RESOURCE_GROUP`, factory_name: 'FACTORY_NAME') do
+ it { should exist }
+ its('names') { should include "factory_name" }
+end
+```
+
+### Test that there aren't any Linked Services in a resource group
+
+```ruby
+# Should not exist if no Linked Services are in the resource group
+describe azure_data_factory_linked_service(resource_group: `RESOURCE_GROUP`, factory_name: 'FACTORY_NAME') do
+ it { should_not exist }
+end
+```
+
+### Filter Linked Services in a resource group by properties
+
+```ruby
+describe azure_data_factory_linked_service(resource_group: `RESOURCE_GROUP`, factory_name: 'FACTORY_NAME') do
+ its('names') { should include linked_service_name1 }
+ its('types') { should include 'Microsoft.DataFactory/factories/linkedservices' }
+ its('linked_service_types') { should include('MySql') }
+end
+```
+
+## Azure Permissions
+
+Your [Service Principal](https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-create-service-principal-portal) must be set up with a `contributor` role on the subscription you wish to test.
diff --git a/docs/resources/azure_ddos_protection_resource.md b/docs/resources/azure_ddos_protection_resource.md
index e4d888035..2a21ceec1 100644
--- a/docs/resources/azure_ddos_protection_resource.md
+++ b/docs/resources/azure_ddos_protection_resource.md
@@ -1,7 +1,7 @@
---
title: About the azure_ddos_protection_resource Resource
platform: azure
- ---
+---
# azure_ddos_protection_resource
diff --git a/docs/resources/azure_ddos_protection_resources.md b/docs/resources/azure_ddos_protection_resources.md
index e31802eb5..9a4aeff2c 100644
--- a/docs/resources/azure_ddos_protection_resources.md
+++ b/docs/resources/azure_ddos_protection_resources.md
@@ -1,7 +1,7 @@
---
title: About the azure_ddos_protection_resources Resource
platform: azure
- ---
+---
# azure_ddos_protection_resources
diff --git a/docs/resources/azure_dns_zones_resource.md b/docs/resources/azure_dns_zones_resource.md
index fb16996d5..b117b400d 100644
--- a/docs/resources/azure_dns_zones_resource.md
+++ b/docs/resources/azure_dns_zones_resource.md
@@ -1,7 +1,7 @@
---
title: About the azure_dns_zones_resource Resource
platform: azure
- ---
+---
# azure_dns_zones_resource
diff --git a/docs/resources/azure_dns_zones_resources.md b/docs/resources/azure_dns_zones_resources.md
index 078664b57..44e0842d2 100644
--- a/docs/resources/azure_dns_zones_resources.md
+++ b/docs/resources/azure_dns_zones_resources.md
@@ -1,7 +1,7 @@
---
title: About the azure_dns_zones_resources Resource
platform: azure
- ---
+---
# azure_dns_zones_resources
diff --git a/docs/resources/azure_migrate_assessment_project.md b/docs/resources/azure_migrate_assessment_project.md
new file mode 100644
index 000000000..626df35ed
--- /dev/null
+++ b/docs/resources/azure_migrate_assessment_project.md
@@ -0,0 +1,102 @@
+---
+title: About the azure_migrate_assessment_project Resource
+platform: azure
+---
+
+# azure_migrate_assessment_project
+
+Use the `azure_migrate_assessment_project` InSpec audit resource to test the properties related to an Azure Migrate assessment project.
+
+## Azure REST API Version, Endpoint, and HTTP Client Parameters
+
+This resource interacts with API versions supported by the resource provider. The `api_version` is defined as a resource parameter.
+If not provided, the latest version is used. For more information, refer to [`azure_generic_resource`](azure_generic_resource.md).
+
+Unless defined, `azure_cloud` global endpoint and default values for the HTTP client is used. For more information, refer to the resource pack [README](../../README.md).
+
+## Availability
+
+### Installation
+
+This resource is available in the [InSpec Azure resource pack](https://github.com/inspec/inspec-azure). For an example, `inspec.yml` file and how to set up your Azure credentials, refer to resource pack [README](../../README.md#Service-Principal).
+
+## Syntax
+
+`name` and `resource_group` are required parameters.
+
+```ruby
+describe azure_migrate_assessment_project(resource_group: 'RESOURCE_GROUP', name: 'ASSESSMENT_PROJECT_NAME') do
+ it { should exist }
+ its('name') { should cmp 'ASSESSMENT_PROJECT_NAME' }
+ its('type') { should cmp 'Microsoft.Migrate/assessmentprojects' }
+end
+```
+
+```ruby
+describe azure_migrate_assessment_project(resource_group: 'RESOURCE_GROUP', name: 'ASSESSMENT_PROJECT_NAME') do
+ it { should exist }
+end
+```
+
+## Parameters
+
+| Name | Description |
+|----------------|----------------------------------------------------------------------------------|
+| name | Name of the Azure Migrate assessment Project to test. |
+| resource_group | Azure resource group that the targeted project resides in. |
+
+The parameter set should be provided for a valid query:
+
+- `resource_group` and `name`.
+
+## Properties
+
+| Property | Description |
+|-------------------------------|------------------------------------------------------------------|
+| id | Path reference to the project. |
+| name | Name of the project. |
+| type | Type of the object. |
+| eTag | For optimistic concurrency control. |
+| properties | Properties of the project. |
+| location | Azure location in which project is created. |
+| properties.assessmentSolutionId | Assessment solution ARM id tracked by `Microsoft.Migrate/migrateProjects`.|
+| properties.customerStorageAccountArmId| The ARM ID of the storage account used for interactions when public access is disabled.|
+| properties.privateEndpointConnections | The list of private endpoint connections to the project. |
+| properties.numberOfMachines | Number of machines in the project. |
+| tags | Tags provided by Azure Tagging service. |
+
+For properties applicable to all resources, such as `type`, `name`, `id`, and `properties`, refer to the [`azure_generic_resource`](azure_generic_resource.md#properties).
+
+Refer to the [Azure documentation](https://docs.microsoft.com/en-us/rest/api/migrate/assessment/projects/get) for other properties available. Access any attribute in the response by separating the key names with a period (`.`).
+
+## Examples
+
+### Test that the migrate assessment project has a minimum scaling factor
+
+```ruby
+describe azure_migrate_assessment_project(resource_group: 'RESOURCE_GROUP', name: 'ASSESSMENT_PROJECT_NAME') do
+ its('properties.numberOfGroups') { should eq 2 }
+end
+```
+
+## Matchers
+
+This InSpec audit resource has the following special matchers. For a full list of available matchers, please visit our [Universal Matchers page](/inspec/matchers/).
+
+### exists
+
+```ruby
+# If a Migrate Assessment Project is found, it will exist
+describe azure_migrate_assessment_project(resource_group: 'RESOURCE_GROUP', name: 'ASSESSMENT_PROJECT_NAME') do
+ it { should exist }
+end
+
+# if Migrate Assessment Project is not found, it will not exist
+describe azure_migrate_assessment_project(resource_group: 'RESOURCE_GROUP', name: 'ASSESSMENT_PROJECT_NAME') do
+ it { should_not exist }
+end
+```
+
+## Azure Permissions
+
+Your [Service Principal](https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-create-service-principal-portal) must be set up with a `contributor` role on the subscription you wish to test.
diff --git a/docs/resources/azure_policy_assignments.md b/docs/resources/azure_policy_assignments.md
index 3e3d8550d..41ec7526e 100644
--- a/docs/resources/azure_policy_assignments.md
+++ b/docs/resources/azure_policy_assignments.md
@@ -3,7 +3,7 @@ title: About the azure_policy_assignments Resource
platform: azure
---
-## azure_policy_assignments
+# azure_policy_assignments
Use the `azure_policy_assignments` InSpec resource to examine assignments of Azure policy to resources and resource groups.
diff --git a/docs/resources/azure_virtual_wan.md b/docs/resources/azure_virtual_wan.md
index b2b2d238f..a67f7c667 100644
--- a/docs/resources/azure_virtual_wan.md
+++ b/docs/resources/azure_virtual_wan.md
@@ -3,7 +3,7 @@ title: About the azure_virtual_wan Resource
platform: azure
---
-## azure_virtual_wan
+# azure_virtual_wan
Use the `azure_virtual_wan` InSpec audit resource to test the properties related to a Azure Virtual WAN in a given resource group.
diff --git a/docs/tools/vale/Microsoft/AMPM.yml b/docs/tools/vale/Microsoft/AMPM.yml
new file mode 100644
index 000000000..8b9fed162
--- /dev/null
+++ b/docs/tools/vale/Microsoft/AMPM.yml
@@ -0,0 +1,9 @@
+extends: existence
+message: Use 'AM' or 'PM' (preceded by a space).
+link: https://docs.microsoft.com/en-us/style-guide/a-z-word-list-term-collections/term-collections/date-time-terms
+level: error
+nonword: true
+tokens:
+ - '\d{1,2}[AP]M'
+ - '\d{1,2} ?[ap]m'
+ - '\d{1,2} ?[aApP]\.[mM]\.'
diff --git a/docs/tools/vale/Microsoft/Accessibility.yml b/docs/tools/vale/Microsoft/Accessibility.yml
new file mode 100644
index 000000000..05bf92739
--- /dev/null
+++ b/docs/tools/vale/Microsoft/Accessibility.yml
@@ -0,0 +1,25 @@
+extends: existence
+message: "Don't use language (such as '%s') that defines people by their disability."
+link: https://docs.microsoft.com/en-us/style-guide/a-z-word-list-term-collections/term-collections/accessibility-terms
+level: suggestion
+ignorecase: true
+tokens:
+ - a victim of
+ - able-bodied
+ - affected by
+ - an epileptic
+ - crippled
+ - disabled
+ - dumb
+ - handicapped
+ - handicaps
+ - healthy
+ - lame
+ - maimed
+ - missing a limb
+ - mute
+ - normal
+ - sight-impaired
+ - stricken with
+ - suffers from
+ - vision-impaired
diff --git a/docs/tools/vale/Microsoft/Acronyms.yml b/docs/tools/vale/Microsoft/Acronyms.yml
new file mode 100644
index 000000000..308ff7c0e
--- /dev/null
+++ b/docs/tools/vale/Microsoft/Acronyms.yml
@@ -0,0 +1,64 @@
+extends: conditional
+message: "'%s' has no definition."
+link: https://docs.microsoft.com/en-us/style-guide/acronyms
+level: suggestion
+ignorecase: false
+# Ensures that the existence of 'first' implies the existence of 'second'.
+first: '\b([A-Z]{3,5})\b'
+second: '(?:\b[A-Z][a-z]+ )+\(([A-Z]{3,5})\)'
+# ... with the exception of these:
+exceptions:
+ - API
+ - ASP
+ - CLI
+ - CPU
+ - CSS
+ - CSV
+ - DEBUG
+ - DOM
+ - DPI
+ - FAQ
+ - GCC
+ - GDB
+ - GET
+ - GPU
+ - GTK
+ - GUI
+ - HTML
+ - HTTP
+ - HTTPS
+ - IDE
+ - JAR
+ - JSON
+ - JSX
+ - LESS
+ - LLDB
+ - NET
+ - NOTE
+ - NVDA
+ - OSS
+ - PATH
+ - PDF
+ - PHP
+ - POST
+ - RAM
+ - REPL
+ - RSA
+ - SCM
+ - SCSS
+ - SDK
+ - SQL
+ - SSH
+ - SSL
+ - SVG
+ - TBD
+ - TCP
+ - TODO
+ - URI
+ - URL
+ - USB
+ - UTF
+ - XML
+ - XSS
+ - YAML
+ - ZIP
diff --git a/docs/tools/vale/Microsoft/Adverbs.yml b/docs/tools/vale/Microsoft/Adverbs.yml
new file mode 100644
index 000000000..07d98d83e
--- /dev/null
+++ b/docs/tools/vale/Microsoft/Adverbs.yml
@@ -0,0 +1,270 @@
+extends: existence
+message: "Consider removing '%s'."
+link: https://docs.microsoft.com/en-us/style-guide/word-choice/use-simple-words-concise-sentences
+ignorecase: true
+level: warning
+action:
+ name: remove
+tokens:
+ - abnormally
+ - absentmindedly
+ - accidentally
+ - adventurously
+ - anxiously
+ - arrogantly
+ - awkwardly
+ - bashfully
+ - beautifully
+ - bitterly
+ - bleakly
+ - blindly
+ - blissfully
+ - boastfully
+ - boldly
+ - bravely
+ - briefly
+ - brightly
+ - briskly
+ - broadly
+ - busily
+ - calmly
+ - carefully
+ - carelessly
+ - cautiously
+ - cheerfully
+ - cleverly
+ - closely
+ - coaxingly
+ - colorfully
+ - continually
+ - coolly
+ - courageously
+ - crossly
+ - cruelly
+ - curiously
+ - daintily
+ - dearly
+ - deceivingly
+ - deeply
+ - defiantly
+ - deliberately
+ - delightfully
+ - diligently
+ - dimly
+ - doubtfully
+ - dreamily
+ - easily
+ - elegantly
+ - energetically
+ - enormously
+ - enthusiastically
+ - excitedly
+ - extremely
+ - fairly
+ - faithfully
+ - famously
+ - ferociously
+ - fervently
+ - fiercely
+ - fondly
+ - foolishly
+ - fortunately
+ - frankly
+ - frantically
+ - freely
+ - frenetically
+ - frightfully
+ - furiously
+ - generally
+ - generously
+ - gently
+ - gladly
+ - gleefully
+ - gracefully
+ - gratefully
+ - greatly
+ - greedily
+ - happily
+ - hastily
+ - healthily
+ - heavily
+ - helplessly
+ - honestly
+ - hopelessly
+ - hungrily
+ - innocently
+ - inquisitively
+ - intensely
+ - intently
+ - interestingly
+ - inwardly
+ - irritably
+ - jaggedly
+ - jealously
+ - jovially
+ - joyfully
+ - joyously
+ - jubilantly
+ - judgmentally
+ - justly
+ - keenly
+ - kiddingly
+ - kindheartedly
+ - knavishly
+ - knowingly
+ - knowledgeably
+ - lazily
+ - lightly
+ - limply
+ - lively
+ - loftily
+ - longingly
+ - loosely
+ - loudly
+ - lovingly
+ - loyally
+ - madly
+ - majestically
+ - meaningfully
+ - mechanically
+ - merrily
+ - miserably
+ - mockingly
+ - mortally
+ - mysteriously
+ - naturally
+ - nearly
+ - neatly
+ - nervously
+ - nicely
+ - noisily
+ - obediently
+ - obnoxiously
+ - oddly
+ - offensively
+ - optimistically
+ - overconfidently
+ - painfully
+ - partially
+ - patiently
+ - perfectly
+ - playfully
+ - politely
+ - poorly
+ - positively
+ - potentially
+ - powerfully
+ - promptly
+ - properly
+ - punctually
+ - quaintly
+ - queasily
+ - queerly
+ - questionably
+ - quickly
+ - quietly
+ - quirkily
+ - quizzically
+ - randomly
+ - rapidly
+ - rarely
+ - readily
+ - really
+ - reassuringly
+ - recklessly
+ - regularly
+ - reluctantly
+ - repeatedly
+ - reproachfully
+ - restfully
+ - righteously
+ - rightfully
+ - rigidly
+ - roughly
+ - rudely
+ - safely
+ - scarcely
+ - scarily
+ - searchingly
+ - sedately
+ - seemingly
+ - selfishly
+ - separately
+ - seriously
+ - shakily
+ - sharply
+ - sheepishly
+ - shrilly
+ - shyly
+ - silently
+ - sleepily
+ - slowly
+ - smoothly
+ - softly
+ - solemnly
+ - solidly
+ - speedily
+ - stealthily
+ - sternly
+ - strictly
+ - suddenly
+ - supposedly
+ - surprisingly
+ - suspiciously
+ - sweetly
+ - swiftly
+ - sympathetically
+ - tenderly
+ - tensely
+ - terribly
+ - thankfully
+ - thoroughly
+ - thoughtfully
+ - tightly
+ - tremendously
+ - triumphantly
+ - truthfully
+ - ultimately
+ - unabashedly
+ - unaccountably
+ - unbearably
+ - unethically
+ - unexpectedly
+ - unfortunately
+ - unimpressively
+ - unnaturally
+ - unnecessarily
+ - urgently
+ - usefully
+ - uselessly
+ - utterly
+ - vacantly
+ - vaguely
+ - vainly
+ - valiantly
+ - vastly
+ - verbally
+ - very
+ - viciously
+ - victoriously
+ - violently
+ - vivaciously
+ - voluntarily
+ - warmly
+ - weakly
+ - wearily
+ - wetly
+ - wholly
+ - wildly
+ - willfully
+ - wisely
+ - woefully
+ - wonderfully
+ - worriedly
+ - yawningly
+ - yearningly
+ - yieldingly
+ - youthfully
+ - zealously
+ - zestfully
+ - zestily
diff --git a/docs/tools/vale/Microsoft/Auto.yml b/docs/tools/vale/Microsoft/Auto.yml
new file mode 100644
index 000000000..4da439353
--- /dev/null
+++ b/docs/tools/vale/Microsoft/Auto.yml
@@ -0,0 +1,11 @@
+extends: existence
+message: "In general, don't hyphenate '%s'."
+link: https://docs.microsoft.com/en-us/style-guide/a-z-word-list-term-collections/a/auto
+ignorecase: true
+level: error
+action:
+ name: convert
+ params:
+ - simple
+tokens:
+ - 'auto-\w+'
diff --git a/docs/tools/vale/Microsoft/Avoid.yml b/docs/tools/vale/Microsoft/Avoid.yml
new file mode 100644
index 000000000..fdb974278
--- /dev/null
+++ b/docs/tools/vale/Microsoft/Avoid.yml
@@ -0,0 +1,14 @@
+extends: existence
+message: "Don't use '%s'."
+# See the A-Z word list
+link: https://docs.microsoft.com/en-us/style-guide
+ignorecase: true
+level: error
+tokens:
+ - abortion
+ - and so on
+ - app(?:lication)s? (?:developer|program)
+ - app(?:lication)? file
+ - backbone
+ - backend
+ - contiguous selection
diff --git a/docs/tools/vale/Microsoft/ComplexWords.yml b/docs/tools/vale/Microsoft/ComplexWords.yml
new file mode 100644
index 000000000..65b7a3472
--- /dev/null
+++ b/docs/tools/vale/Microsoft/ComplexWords.yml
@@ -0,0 +1,120 @@
+extends: substitution
+message: "Consider using '%s' instead of '%s'."
+link: https://docs.microsoft.com/en-us/style-guide/word-choice/use-simple-words-concise-sentences
+ignorecase: true
+level: suggestion
+action:
+ name: replace
+swap:
+ "approximate(?:ly)?": about
+ abundance: plenty
+ accelerate: speed up
+ accentuate: stress
+ accompany: go with
+ accomplish: carry out|do
+ accorded: given
+ accordingly: so
+ accrue: add
+ accurate: right|exact
+ acquiesce: agree
+ acquire: get|buy
+ additional: more|extra
+ address: discuss
+ addressees: you
+ adjacent to: next to
+ adjustment: change
+ admissible: allowed
+ advantageous: helpful
+ advise: tell
+ aggregate: total
+ aircraft: plane
+ alleviate: ease
+ allocate: assign|divide
+ alternatively: or
+ alternatives: choices|options
+ ameliorate: improve
+ amend: change
+ anticipate: expect
+ apparent: clear|plain
+ ascertain: discover|find out
+ assistance: help
+ attain: meet
+ attempt: try
+ authorize: allow
+ belated: late
+ bestow: give
+ cease: stop|end
+ collaborate: work together
+ commence: begin
+ compensate: pay
+ component: part
+ comprise: form|include
+ concept: idea
+ concerning: about
+ confer: give|award
+ consequently: so
+ consolidate: merge
+ constitutes: forms
+ contains: has
+ convene: meet
+ demonstrate: show|prove
+ depart: leave
+ designate: choose
+ desire: want|wish
+ determine: decide|find
+ detrimental: bad|harmful
+ disclose: share|tell
+ discontinue: stop
+ disseminate: send|give
+ eliminate: end
+ elucidate: explain
+ employ: use
+ enclosed: inside|included
+ encounter: meet
+ endeavor: try
+ enumerate: count
+ equitable: fair
+ equivalent: equal
+ exclusively: only
+ expedite: hurry
+ facilitate: ease
+ females: women
+ finalize: complete|finish
+ frequently: often
+ identical: same
+ incorrect: wrong
+ indication: sign
+ initiate: start|begin
+ itemized: listed
+ jeopardize: risk
+ liaise: work with|partner with
+ maintain: keep|support
+ methodology: method
+ modify: change
+ monitor: check|watch
+ multiple: many
+ necessitate: cause
+ notify: tell
+ numerous: many
+ objective: aim|goal
+ obligate: bind|compel
+ optimum: best|most
+ permit: let
+ portion: part
+ possess: own
+ previous: earlier
+ previously: before
+ prioritize: rank
+ procure: buy
+ provide: give|offer
+ purchase: buy
+ relocate: move
+ solicit: request
+ state-of-the-art: latest
+ subsequent: later|next
+ substantial: large
+ sufficient: enough
+ terminate: end
+ transmit: send
+ utilization: use
+ utilize: use
diff --git a/docs/tools/vale/Microsoft/Contractions.yml b/docs/tools/vale/Microsoft/Contractions.yml
new file mode 100644
index 000000000..fffd2d9c9
--- /dev/null
+++ b/docs/tools/vale/Microsoft/Contractions.yml
@@ -0,0 +1,30 @@
+extends: substitution
+message: "Use '%s' instead of '%s'."
+link: https://docs.microsoft.com/en-us/style-guide/word-choice/use-contractions
+level: error
+ignorecase: true
+action:
+ name: replace
+swap:
+ are not: aren't
+ cannot: can't
+ could not: couldn't
+ did not: didn't
+ do not: don't
+ does not: doesn't
+ has not: hasn't
+ have not: haven't
+ how is: how's
+ is not: isn't
+ it is: it's
+ should not: shouldn't
+ that is: that's
+ they are: they're
+ was not: wasn't
+ we are: we're
+ we have: we've
+ were not: weren't
+ what is: what's
+ when is: when's
+ where is: where's
+ will not: won't
diff --git a/docs/tools/vale/Microsoft/Dashes.yml b/docs/tools/vale/Microsoft/Dashes.yml
new file mode 100644
index 000000000..2894cf722
--- /dev/null
+++ b/docs/tools/vale/Microsoft/Dashes.yml
@@ -0,0 +1,13 @@
+extends: existence
+message: "Remove the spaces around '%s'."
+link: https://docs.microsoft.com/en-us/style-guide/punctuation/dashes-hyphens/emes
+ignorecase: true
+nonword: true
+level: error
+action:
+ name: edit
+ params:
+ - remove
+ - ' '
+tokens:
+ - '[—–]\s|\s[—–]'
diff --git a/docs/tools/vale/Microsoft/DateFormat.yml b/docs/tools/vale/Microsoft/DateFormat.yml
new file mode 100644
index 000000000..196531394
--- /dev/null
+++ b/docs/tools/vale/Microsoft/DateFormat.yml
@@ -0,0 +1,8 @@
+extends: existence
+message: Use 'July 31, 2016' format, not '%s'.
+link: https://docs.microsoft.com/en-us/style-guide/a-z-word-list-term-collections/term-collections/date-time-terms
+ignorecase: true
+level: error
+nonword: true
+tokens:
+ - '\d{1,2} (?:Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)|May|Jun(?:e)|Jul(?:y)|Aug(?:ust)|Sep(?:tember)?|Oct(?:ober)|Nov(?:ember)?|Dec(?:ember)?) \d{4}'
diff --git a/docs/tools/vale/Microsoft/DateNumbers.yml b/docs/tools/vale/Microsoft/DateNumbers.yml
new file mode 100644
index 000000000..14d46747c
--- /dev/null
+++ b/docs/tools/vale/Microsoft/DateNumbers.yml
@@ -0,0 +1,40 @@
+extends: existence
+message: "Don't use ordinal numbers for dates."
+link: https://docs.microsoft.com/en-us/style-guide/numbers#numbers-in-dates
+level: error
+nonword: true
+ignorecase: true
+raw:
+ - \b(?:Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)|May|Jun(?:e)|Jul(?:y)|Aug(?:ust)|Sep(?:tember)?|Oct(?:ober)|Nov(?:ember)?|Dec(?:ember)?)\b\s*
+tokens:
+ - first
+ - second
+ - third
+ - fourth
+ - fifth
+ - sixth
+ - seventh
+ - eighth
+ - ninth
+ - tenth
+ - eleventh
+ - twelfth
+ - thirteenth
+ - fourteenth
+ - fifteenth
+ - sixteenth
+ - seventeenth
+ - eighteenth
+ - nineteenth
+ - twentieth
+ - twenty-first
+ - twenty-second
+ - twenty-third
+ - twenty-fourth
+ - twenty-fifth
+ - twenty-sixth
+ - twenty-seventh
+ - twenty-eighth
+ - twenty-ninth
+ - thirtieth
+ - thirty-first
diff --git a/docs/tools/vale/Microsoft/DateOrder.yml b/docs/tools/vale/Microsoft/DateOrder.yml
new file mode 100644
index 000000000..12d69ba51
--- /dev/null
+++ b/docs/tools/vale/Microsoft/DateOrder.yml
@@ -0,0 +1,8 @@
+extends: existence
+message: "Always spell out the name of the month."
+link: https://docs.microsoft.com/en-us/style-guide/numbers#numbers-in-dates
+ignorecase: true
+level: error
+nonword: true
+tokens:
+ - '\b\d{1,2}/\d{1,2}/(?:\d{4}|\d{2})\b'
diff --git a/docs/tools/vale/Microsoft/Ellipses.yml b/docs/tools/vale/Microsoft/Ellipses.yml
new file mode 100644
index 000000000..320457a8b
--- /dev/null
+++ b/docs/tools/vale/Microsoft/Ellipses.yml
@@ -0,0 +1,9 @@
+extends: existence
+message: "In general, don't use an ellipsis."
+link: https://docs.microsoft.com/en-us/style-guide/punctuation/ellipses
+nonword: true
+level: warning
+action:
+ name: remove
+tokens:
+ - '\.\.\.'
diff --git a/docs/tools/vale/Microsoft/FirstPerson.yml b/docs/tools/vale/Microsoft/FirstPerson.yml
new file mode 100644
index 000000000..34dcbb8bb
--- /dev/null
+++ b/docs/tools/vale/Microsoft/FirstPerson.yml
@@ -0,0 +1,13 @@
+extends: existence
+message: "Use first person (such as '%s') sparingly."
+link: https://docs.microsoft.com/en-us/style-guide/grammar/person
+ignorecase: true
+level: warning
+nonword: true
+tokens:
+ - (?:^|\s)I\s
+ - (?:^|\s)I,\s
+ - \bI'm\b
+ - \bme\b
+ - \bmy\b
+ - \bmine\b
diff --git a/docs/tools/vale/Microsoft/Foreign.yml b/docs/tools/vale/Microsoft/Foreign.yml
new file mode 100644
index 000000000..d37835a5d
--- /dev/null
+++ b/docs/tools/vale/Microsoft/Foreign.yml
@@ -0,0 +1,12 @@
+extends: substitution
+message: "Use '%s' instead of '%s'."
+link: https://docs.microsoft.com/en-us/style-guide/word-choice/use-us-spelling-avoid-non-english-words
+ignorecase: true
+level: error
+nonword: true
+action:
+ name: replace
+swap:
+ '\b(?:eg|e\.g\.)[\s,]': for example
+ '\b(?:ie|i\.e\.)[\s,]': that is
+
diff --git a/docs/tools/vale/Microsoft/Gender.yml b/docs/tools/vale/Microsoft/Gender.yml
new file mode 100644
index 000000000..47c080247
--- /dev/null
+++ b/docs/tools/vale/Microsoft/Gender.yml
@@ -0,0 +1,8 @@
+extends: existence
+message: "Don't use '%s'."
+link: https://github.com/MicrosoftDocs/microsoft-style-guide/blob/master/styleguide/grammar/nouns-pronouns.md#pronouns-and-gender
+level: error
+ignorecase: true
+tokens:
+ - he/she
+ - s/he
diff --git a/docs/tools/vale/Microsoft/GenderBias.yml b/docs/tools/vale/Microsoft/GenderBias.yml
new file mode 100644
index 000000000..3d873aa31
--- /dev/null
+++ b/docs/tools/vale/Microsoft/GenderBias.yml
@@ -0,0 +1,44 @@
+extends: substitution
+message: "Consider using '%s' instead of '%s'."
+ignorecase: true
+level: error
+swap:
+ (?:alumna|alumnus): graduate
+ (?:alumnae|alumni): graduates
+ air(?:m[ae]n|wom[ae]n): pilot(s)
+ anchor(?:m[ae]n|wom[ae]n): anchor(s)
+ authoress: author
+ camera(?:m[ae]n|wom[ae]n): camera operator(s)
+ chair(?:m[ae]n|wom[ae]n): chair(s)
+ congress(?:m[ae]n|wom[ae]n): member(s) of congress
+ door(?:m[ae]|wom[ae]n): concierge(s)
+ draft(?:m[ae]n|wom[ae]n): drafter(s)
+ fire(?:m[ae]n|wom[ae]n): firefighter(s)
+ fisher(?:m[ae]n|wom[ae]n): fisher(s)
+ fresh(?:m[ae]n|wom[ae]n): first-year student(s)
+ garbage(?:m[ae]n|wom[ae]n): waste collector(s)
+ lady lawyer: lawyer
+ ladylike: courteous
+ landlord: building manager
+ mail(?:m[ae]n|wom[ae]n): mail carriers
+ man and wife: husband and wife
+ man enough: strong enough
+ mankind: human kind
+ manmade: manufactured
+ manpower: personnel
+ men and girls: men and women
+ middle(?:m[ae]n|wom[ae]n): intermediary
+ news(?:m[ae]n|wom[ae]n): journalist(s)
+ ombuds(?:man|woman): ombuds
+ oneupmanship: upstaging
+ poetess: poet
+ police(?:m[ae]n|wom[ae]n): police officer(s)
+ repair(?:m[ae]n|wom[ae]n): technician(s)
+ sales(?:m[ae]n|wom[ae]n): salesperson or sales people
+ service(?:m[ae]n|wom[ae]n): soldier(s)
+ steward(?:ess)?: flight attendant
+ tribes(?:m[ae]n|wom[ae]n): tribe member(s)
+ waitress: waiter
+ woman doctor: doctor
+ woman scientist[s]?: scientist(s)
+ work(?:m[ae]n|wom[ae]n): worker(s)
diff --git a/docs/tools/vale/Microsoft/GeneralURL.yml b/docs/tools/vale/Microsoft/GeneralURL.yml
new file mode 100644
index 000000000..dcef503d9
--- /dev/null
+++ b/docs/tools/vale/Microsoft/GeneralURL.yml
@@ -0,0 +1,11 @@
+extends: existence
+message: "For a general audience, use 'address' rather than 'URL'."
+link: https://docs.microsoft.com/en-us/style-guide/urls-web-addresses
+level: warning
+action:
+ name: replace
+ params:
+ - URL
+ - address
+tokens:
+ - URL
diff --git a/docs/tools/vale/Microsoft/HeadingAcronyms.yml b/docs/tools/vale/Microsoft/HeadingAcronyms.yml
new file mode 100644
index 000000000..9dc3b6c2d
--- /dev/null
+++ b/docs/tools/vale/Microsoft/HeadingAcronyms.yml
@@ -0,0 +1,7 @@
+extends: existence
+message: "Avoid using acronyms in a title or heading."
+link: https://docs.microsoft.com/en-us/style-guide/acronyms#be-careful-with-acronyms-in-titles-and-headings
+level: warning
+scope: heading
+tokens:
+ - '[A-Z]{2,4}'
diff --git a/docs/tools/vale/Microsoft/HeadingColons.yml b/docs/tools/vale/Microsoft/HeadingColons.yml
new file mode 100644
index 000000000..7013c3914
--- /dev/null
+++ b/docs/tools/vale/Microsoft/HeadingColons.yml
@@ -0,0 +1,8 @@
+extends: existence
+message: "Capitalize '%s'."
+link: https://docs.microsoft.com/en-us/style-guide/punctuation/colons
+nonword: true
+level: error
+scope: heading
+tokens:
+ - ':\s[a-z]'
diff --git a/docs/tools/vale/Microsoft/HeadingPunctuation.yml b/docs/tools/vale/Microsoft/HeadingPunctuation.yml
new file mode 100644
index 000000000..af04b02eb
--- /dev/null
+++ b/docs/tools/vale/Microsoft/HeadingPunctuation.yml
@@ -0,0 +1,13 @@
+extends: existence
+message: "Don't use end punctuation in headings."
+link: https://docs.microsoft.com/en-us/style-guide/punctuation/periods
+nonword: true
+level: warning
+scope: heading
+action:
+ name: edit
+ params:
+ - remove
+ - '.?!'
+tokens:
+ - '[a-z][.?!](?:\s|$)'
diff --git a/docs/tools/vale/Microsoft/Headings.yml b/docs/tools/vale/Microsoft/Headings.yml
new file mode 100644
index 000000000..63624edc1
--- /dev/null
+++ b/docs/tools/vale/Microsoft/Headings.yml
@@ -0,0 +1,28 @@
+extends: capitalization
+message: "'%s' should use sentence-style capitalization."
+link: https://docs.microsoft.com/en-us/style-guide/capitalization
+level: suggestion
+scope: heading
+match: $sentence
+indicators:
+ - ':'
+exceptions:
+ - Azure
+ - CLI
+ - Code
+ - Cosmos
+ - Docker
+ - Emmet
+ - I
+ - Kubernetes
+ - Linux
+ - macOS
+ - Marketplace
+ - MongoDB
+ - REPL
+ - Studio
+ - TypeScript
+ - URLs
+ - Visual
+ - VS
+ - Windows
diff --git a/docs/tools/vale/Microsoft/Hyphens.yml b/docs/tools/vale/Microsoft/Hyphens.yml
new file mode 100644
index 000000000..90bbb5def
--- /dev/null
+++ b/docs/tools/vale/Microsoft/Hyphens.yml
@@ -0,0 +1,14 @@
+extends: existence
+message: "'%s' doesn't need a hyphen."
+link: https://docs.microsoft.com/en-us/style-guide/punctuation/dashes-hyphens/hyphens
+level: warning
+ignorecase: false
+nonword: true
+action:
+ name: edit
+ params:
+ - replace
+ - '-'
+ - ' '
+tokens:
+ - '\s[^\s-]+ly-'
diff --git a/docs/tools/vale/Microsoft/Negative.yml b/docs/tools/vale/Microsoft/Negative.yml
new file mode 100644
index 000000000..d6ff2f224
--- /dev/null
+++ b/docs/tools/vale/Microsoft/Negative.yml
@@ -0,0 +1,13 @@
+extends: existence
+message: "Form a negative number with an en dash, not a hyphen."
+link: https://docs.microsoft.com/en-us/style-guide/numbers
+nonword: true
+level: error
+action:
+ name: edit
+ params:
+ - replace
+ - '-'
+ - '–'
+tokens:
+ - '\s-\d+\s'
diff --git a/docs/tools/vale/Microsoft/Ordinal.yml b/docs/tools/vale/Microsoft/Ordinal.yml
new file mode 100644
index 000000000..e3483e380
--- /dev/null
+++ b/docs/tools/vale/Microsoft/Ordinal.yml
@@ -0,0 +1,13 @@
+extends: existence
+message: "Don't add -ly to an ordinal number."
+link: https://docs.microsoft.com/en-us/style-guide/numbers
+level: error
+action:
+ name: edit
+ params:
+ - trim
+ - ly
+tokens:
+ - firstly
+ - secondly
+ - thirdly
diff --git a/docs/tools/vale/Microsoft/OxfordComma.yml b/docs/tools/vale/Microsoft/OxfordComma.yml
new file mode 100644
index 000000000..493b55c3c
--- /dev/null
+++ b/docs/tools/vale/Microsoft/OxfordComma.yml
@@ -0,0 +1,8 @@
+extends: existence
+message: "Use the Oxford comma in '%s'."
+link: https://docs.microsoft.com/en-us/style-guide/punctuation/commas
+scope: sentence
+level: suggestion
+nonword: true
+tokens:
+ - '(?:[^\s,]+,){1,} \w+ (?:and|or) \w+[.?!]'
diff --git a/docs/tools/vale/Microsoft/Passive.yml b/docs/tools/vale/Microsoft/Passive.yml
new file mode 100644
index 000000000..102d377ca
--- /dev/null
+++ b/docs/tools/vale/Microsoft/Passive.yml
@@ -0,0 +1,183 @@
+extends: existence
+message: "'%s' looks like passive voice."
+ignorecase: true
+level: suggestion
+raw:
+ - \b(am|are|were|being|is|been|was|be)\b\s*
+tokens:
+ - '[\w]+ed'
+ - awoken
+ - beat
+ - become
+ - been
+ - begun
+ - bent
+ - beset
+ - bet
+ - bid
+ - bidden
+ - bitten
+ - bled
+ - blown
+ - born
+ - bought
+ - bound
+ - bred
+ - broadcast
+ - broken
+ - brought
+ - built
+ - burnt
+ - burst
+ - cast
+ - caught
+ - chosen
+ - clung
+ - come
+ - cost
+ - crept
+ - cut
+ - dealt
+ - dived
+ - done
+ - drawn
+ - dreamt
+ - driven
+ - drunk
+ - dug
+ - eaten
+ - fallen
+ - fed
+ - felt
+ - fit
+ - fled
+ - flown
+ - flung
+ - forbidden
+ - foregone
+ - forgiven
+ - forgotten
+ - forsaken
+ - fought
+ - found
+ - frozen
+ - given
+ - gone
+ - gotten
+ - ground
+ - grown
+ - heard
+ - held
+ - hidden
+ - hit
+ - hung
+ - hurt
+ - kept
+ - knelt
+ - knit
+ - known
+ - laid
+ - lain
+ - leapt
+ - learnt
+ - led
+ - left
+ - lent
+ - let
+ - lighted
+ - lost
+ - made
+ - meant
+ - met
+ - misspelt
+ - mistaken
+ - mown
+ - overcome
+ - overdone
+ - overtaken
+ - overthrown
+ - paid
+ - pled
+ - proven
+ - put
+ - quit
+ - read
+ - rid
+ - ridden
+ - risen
+ - run
+ - rung
+ - said
+ - sat
+ - sawn
+ - seen
+ - sent
+ - set
+ - sewn
+ - shaken
+ - shaven
+ - shed
+ - shod
+ - shone
+ - shorn
+ - shot
+ - shown
+ - shrunk
+ - shut
+ - slain
+ - slept
+ - slid
+ - slit
+ - slung
+ - smitten
+ - sold
+ - sought
+ - sown
+ - sped
+ - spent
+ - spilt
+ - spit
+ - split
+ - spoken
+ - spread
+ - sprung
+ - spun
+ - stolen
+ - stood
+ - stridden
+ - striven
+ - struck
+ - strung
+ - stuck
+ - stung
+ - stunk
+ - sung
+ - sunk
+ - swept
+ - swollen
+ - sworn
+ - swum
+ - swung
+ - taken
+ - taught
+ - thought
+ - thrived
+ - thrown
+ - thrust
+ - told
+ - torn
+ - trodden
+ - understood
+ - upheld
+ - upset
+ - wed
+ - wept
+ - withheld
+ - withstood
+ - woken
+ - won
+ - worn
+ - wound
+ - woven
+ - written
+ - wrung
diff --git a/docs/tools/vale/Microsoft/Percentages.yml b/docs/tools/vale/Microsoft/Percentages.yml
new file mode 100644
index 000000000..b68a7363f
--- /dev/null
+++ b/docs/tools/vale/Microsoft/Percentages.yml
@@ -0,0 +1,7 @@
+extends: existence
+message: "Use a numeral plus the units."
+link: https://docs.microsoft.com/en-us/style-guide/numbers
+nonword: true
+level: error
+tokens:
+ - '\b[a-zA-z]+\spercent\b'
diff --git a/docs/tools/vale/Microsoft/Quotes.yml b/docs/tools/vale/Microsoft/Quotes.yml
new file mode 100644
index 000000000..38f497606
--- /dev/null
+++ b/docs/tools/vale/Microsoft/Quotes.yml
@@ -0,0 +1,7 @@
+extends: existence
+message: 'Punctuation should be inside the quotes.'
+link: https://docs.microsoft.com/en-us/style-guide/punctuation/quotation-marks
+level: error
+nonword: true
+tokens:
+ - '["“][^"”“]+["”][.,]'
diff --git a/docs/tools/vale/Microsoft/RangeFormat.yml b/docs/tools/vale/Microsoft/RangeFormat.yml
new file mode 100644
index 000000000..f1d736e9d
--- /dev/null
+++ b/docs/tools/vale/Microsoft/RangeFormat.yml
@@ -0,0 +1,13 @@
+extends: existence
+message: "Use an en dash in a range of numbers."
+link: https://docs.microsoft.com/en-us/style-guide/numbers
+nonword: true
+level: error
+action:
+ name: edit
+ params:
+ - replace
+ - '-'
+ - '–'
+tokens:
+ - '\b\d+\s?[-]\s?\d+\b'
diff --git a/docs/tools/vale/Microsoft/RangeTime.yml b/docs/tools/vale/Microsoft/RangeTime.yml
new file mode 100644
index 000000000..cdd4b3346
--- /dev/null
+++ b/docs/tools/vale/Microsoft/RangeTime.yml
@@ -0,0 +1,13 @@
+extends: existence
+message: "Use 'to' instead of a dash in '%s'."
+link: https://docs.microsoft.com/en-us/style-guide/numbers
+nonword: true
+level: error
+action:
+ name: edit
+ params:
+ - replace
+ - '[-–]'
+ - 'to'
+tokens:
+ - '\b(?:AM|PM)\s?[-–]\s?.+(?:AM|PM)\b'
diff --git a/docs/tools/vale/Microsoft/Ranges.yml b/docs/tools/vale/Microsoft/Ranges.yml
new file mode 100644
index 000000000..67d9702b0
--- /dev/null
+++ b/docs/tools/vale/Microsoft/Ranges.yml
@@ -0,0 +1,7 @@
+extends: existence
+message: "In most cases, use 'from' or 'through' to describe a range of numbers."
+link: 'https://docs.microsoft.com/en-us/style-guide/numbers'
+nonword: true
+level: warning
+tokens:
+ - '\b\d+\s?[-–]\s?\d+\b'
diff --git a/docs/tools/vale/Microsoft/Semicolon.yml b/docs/tools/vale/Microsoft/Semicolon.yml
new file mode 100644
index 000000000..4d905467d
--- /dev/null
+++ b/docs/tools/vale/Microsoft/Semicolon.yml
@@ -0,0 +1,8 @@
+extends: existence
+message: "Try to simplify this sentence."
+link: https://docs.microsoft.com/en-us/style-guide/punctuation/semicolons
+nonword: true
+scope: sentence
+level: suggestion
+tokens:
+ - ';'
diff --git a/docs/tools/vale/Microsoft/SentenceLength.yml b/docs/tools/vale/Microsoft/SentenceLength.yml
new file mode 100644
index 000000000..f248cf051
--- /dev/null
+++ b/docs/tools/vale/Microsoft/SentenceLength.yml
@@ -0,0 +1,7 @@
+extends: occurrence
+message: "Try to keep sentences short (< 30 words)."
+scope: sentence
+level: suggestion
+max: 30
+token: \b(\w+)\b
+
diff --git a/docs/tools/vale/Microsoft/Spacing.yml b/docs/tools/vale/Microsoft/Spacing.yml
new file mode 100644
index 000000000..bbd10e51d
--- /dev/null
+++ b/docs/tools/vale/Microsoft/Spacing.yml
@@ -0,0 +1,8 @@
+extends: existence
+message: "'%s' should have one space."
+link: https://docs.microsoft.com/en-us/style-guide/punctuation/periods
+level: error
+nonword: true
+tokens:
+ - '[a-z][.?!] {2,}[A-Z]'
+ - '[a-z][.?!][A-Z]'
diff --git a/docs/tools/vale/Microsoft/Suspended.yml b/docs/tools/vale/Microsoft/Suspended.yml
new file mode 100644
index 000000000..7282e9c9c
--- /dev/null
+++ b/docs/tools/vale/Microsoft/Suspended.yml
@@ -0,0 +1,7 @@
+extends: existence
+message: "Don't use '%s' unless space is limited."
+link: https://docs.microsoft.com/en-us/style-guide/punctuation/dashes-hyphens/hyphens
+ignorecase: true
+level: warning
+tokens:
+ - '\w+- and \w+-'
diff --git a/docs/tools/vale/Microsoft/Terms.yml b/docs/tools/vale/Microsoft/Terms.yml
new file mode 100644
index 000000000..e41ff74b7
--- /dev/null
+++ b/docs/tools/vale/Microsoft/Terms.yml
@@ -0,0 +1,43 @@
+extends: substitution
+message: "Prefer '%s' over '%s'."
+level: warning
+ignorecase: true
+action:
+ name: replace
+swap:
+ '(?:agent|virtual assistant|intelligent personal assistant)': personal digital assistant
+ '(?:drive C:|drive C>|C: drive)': drive C
+ '(?:internet bot|web robot)s?': bot(s)
+ '(?:microsoft cloud|the cloud)': cloud
+ '(?:mobile|smart) ?phone': phone
+ '24/7': every day
+ 'audio(?:-| )book': audiobook
+ 'back(?:-| )light': backlight
+ 'chat ?bots?': chatbot(s)
+ adaptor: adapter
+ administrate: administer
+ afterwards: afterward
+ alphabetic: alphabetical
+ alphanumerical: alphanumeric
+ anti-aliasing: antialiasing
+ anti-malware: antimalware
+ anti-spyware: antispyware
+ anti-virus: antivirus
+ appendixes: appendices
+ artificial intelligence: artificial intelligence
+ assembler: assembly language
+ bpp: bpp
+ bps: bps
+ caap: CaaP
+ conversation-as-a-platform: conversation as a platform
+ eb: EB
+ gb: GB
+ gbps: Gbps
+ kb: KB
+ keypress: keystroke
+ mb: MB
+ pb: PB
+ tb: TB
+ zb: ZB
+ viz: namely
+ ergo: therefore
diff --git a/docs/tools/vale/Microsoft/URLFormat.yml b/docs/tools/vale/Microsoft/URLFormat.yml
new file mode 100644
index 000000000..82e702f98
--- /dev/null
+++ b/docs/tools/vale/Microsoft/URLFormat.yml
@@ -0,0 +1,10 @@
+extends: substitution
+message: "Use '%s' instead of '%s'."
+ignorecase: true
+level: error
+action:
+ name: replace
+swap:
+ URL for: URL of
+ an URL: a URL
+
diff --git a/docs/tools/vale/Microsoft/Units.yml b/docs/tools/vale/Microsoft/Units.yml
new file mode 100644
index 000000000..f062418ee
--- /dev/null
+++ b/docs/tools/vale/Microsoft/Units.yml
@@ -0,0 +1,16 @@
+extends: existence
+message: "Don't spell out the number in '%s'."
+link: https://docs.microsoft.com/en-us/style-guide/a-z-word-list-term-collections/term-collections/units-of-measure-terms
+level: error
+raw:
+ - '[a-zA-Z]+\s'
+tokens:
+ - '(?:centi|milli)?meters'
+ - '(?:kilo)?grams'
+ - '(?:kilo)?meters'
+ - '(?:mega)?pixels'
+ - cm
+ - inches
+ - lb
+ - miles
+ - pounds
diff --git a/docs/tools/vale/Microsoft/Vocab.yml b/docs/tools/vale/Microsoft/Vocab.yml
new file mode 100644
index 000000000..eebe97b15
--- /dev/null
+++ b/docs/tools/vale/Microsoft/Vocab.yml
@@ -0,0 +1,25 @@
+extends: existence
+message: "Verify your use of '%s' with the A-Z word list."
+link: 'https://docs.microsoft.com/en-us/style-guide'
+level: suggestion
+ignorecase: true
+tokens:
+ - above
+ - accessible
+ - actionable
+ - against
+ - alarm
+ - alert
+ - alias
+ - allows?
+ - and/or
+ - as well as
+ - assure
+ - author
+ - avg
+ - beta
+ - ensure
+ - he
+ - insure
+ - sample
+ - she
diff --git a/docs/tools/vale/Microsoft/We.yml b/docs/tools/vale/Microsoft/We.yml
new file mode 100644
index 000000000..97c901c1b
--- /dev/null
+++ b/docs/tools/vale/Microsoft/We.yml
@@ -0,0 +1,11 @@
+extends: existence
+message: "Try to avoid using first-person plural like '%s'."
+link: https://docs.microsoft.com/en-us/style-guide/grammar/person#avoid-first-person-plural
+level: warning
+ignorecase: true
+tokens:
+ - we
+ - we'(?:ve|re)
+ - ours?
+ - us
+ - let's
diff --git a/docs/tools/vale/Microsoft/Wordiness.yml b/docs/tools/vale/Microsoft/Wordiness.yml
new file mode 100644
index 000000000..22a4c932c
--- /dev/null
+++ b/docs/tools/vale/Microsoft/Wordiness.yml
@@ -0,0 +1,122 @@
+extends: substitution
+message: "Consider using '%s' instead of '%s'."
+link: https://docs.microsoft.com/en-us/style-guide/word-choice/use-simple-words-concise-sentences
+ignorecase: true
+level: warning
+action:
+ name: replace
+swap:
+ (?:give|gave) rise to: lead to
+ (?:previous|prior) to: before
+ a (?:large)? majority of: most
+ a (?:large)? number of: many
+ a myriad of: myriad
+ adversely impact: hurt
+ all across: across
+ all of a sudden: suddenly
+ all of these: these
+ all of: all
+ all-time record: record
+ almost all: most
+ almost never: seldom
+ along the lines of: similar to
+ an adequate number of: enough
+ an appreciable number of: many
+ an estimated: about
+ any and all: all
+ are in agreement: agree
+ as a matter of fact: in fact
+ as a means of: to
+ as a result of: because of
+ as of yet: yet
+ as per: per
+ at a later date: later
+ at all times: always
+ at the present time: now
+ at this point in time: at this point
+ based in large part on: based on
+ based on the fact that: because
+ basic necessity: necessity
+ because of the fact that: because
+ came to a realization: realized
+ came to an abrupt end: ended abruptly
+ carry out an evaluation of: evaluate
+ close down: close
+ closed down: closed
+ complete stranger: stranger
+ completely separate: separate
+ concerning the matter of: regarding
+ conduct a review of: review
+ conduct an investigation: investigate
+ conduct experiments: experiment
+ continue on: continue
+ despite the fact that: although
+ disappear from sight: disappear
+ drag and drop: drag
+ drag-and-drop: drag
+ doomed to fail: doomed
+ due to the fact that: because
+ during the period of: during
+ during the time that: while
+ emergency situation: emergency
+ except when: unless
+ excessive number: too many
+ extend an invitation: invite
+ fall down: fall
+ fell down: fell
+ for the duration of: during
+ gather together: gather
+ has the ability to: can
+ has the capacity to: can
+ has the opportunity to: could
+ hold a meeting: meet
+ if this is not the case: if not
+ in a careful manner: carefully
+ in a thoughtful manner: thoughtfully
+ in a timely manner: timely
+ in an effort to: to
+ in between: between
+ in lieu of: instead of
+ in many cases: often
+ in most cases: usually
+ in order to: to
+ in some cases: sometimes
+ in spite of the fact that: although
+ in spite of: despite
+ in the (?:very)? near future: soon
+ in the event that: if
+ in the neighborhood of: roughly
+ in the vicinity of: close to
+ it would appear that: apparently
+ lift up: lift
+ made reference to: referred to
+ make reference to: refer to
+ mix together: mix
+ none at all: none
+ not in a position to: unable
+ not possible: impossible
+ of major importance: important
+ perform an assessment of: assess
+ pertaining to: about
+ place an order: order
+ plays a key role in: is essential to
+ present time: now
+ readily apparent: apparent
+ some of the: some
+ span across: span
+ subsequent to: after
+ successfully complete: complete
+ sufficient number (?:of)?: enough
+ take action: act
+ take into account: consider
+ the question as to whether: whether
+ there is no doubt but that: doubtless
+ this day and age: this age
+ this is a subject that: this subject
+ time (?:frame|period): time
+ under the provisions of: under
+ until such time as: until
+ used for fuel purposes: used for fuel
+ whether or not: whether
+ with regard to: regarding
+ with the exception of: except for
diff --git a/docs/tools/vale/Microsoft/meta.json b/docs/tools/vale/Microsoft/meta.json
new file mode 100644
index 000000000..297719bbb
--- /dev/null
+++ b/docs/tools/vale/Microsoft/meta.json
@@ -0,0 +1,4 @@
+{
+ "feed": "https://github.com/errata-ai/Microsoft/releases.atom",
+ "vale_version": ">=1.0.0"
+}
diff --git a/docs/tools/vale/Vocab/tech-blogging/accept.txt b/docs/tools/vale/Vocab/tech-blogging/accept.txt
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/tools/vale/Vocab/tech-blogging/reject.txt b/docs/tools/vale/Vocab/tech-blogging/reject.txt
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/tools/vale/chef/OxfordComma.yml b/docs/tools/vale/chef/OxfordComma.yml
new file mode 100644
index 000000000..8780c6b53
--- /dev/null
+++ b/docs/tools/vale/chef/OxfordComma.yml
@@ -0,0 +1,7 @@
+extends: existence
+message: 'Use the Oxford comma in a list of three or more items.'
+link: 'https://contribute.jquery.org/style-guide/prose/#grammar'
+scope: sentence
+level: warning
+tokens:
+ - '(?:[^,]+,){1,}\s\w+\sand'
diff --git a/docs/tools/vale/chef/acronyms.yml b/docs/tools/vale/chef/acronyms.yml
new file mode 100644
index 000000000..dc97459da
--- /dev/null
+++ b/docs/tools/vale/chef/acronyms.yml
@@ -0,0 +1,20 @@
+extends: conditional
+message: "'%s' has no definition."
+link: https://docs.microsoft.com/en-us/style-guide/acronyms
+level: suggestion
+ignorecase: false
+# Ensures that the existence of 'first' implies the existence of 'second'.
+first: '\b([A-Z]{3,5})\b'
+second: '(?:\b[A-Z][a-z]+ )+\(([A-Z]{3,5})\)'
+# ... with the exception of these:
+exceptions:
+ - REST
+ - API
+ - CMDB
+ - URL
+ - FQDN
+ - CPU
+ - https
+ - JSON
+ - VPN
+ - HTTP
diff --git a/docs/tools/vale/chef/capitalize.yml b/docs/tools/vale/chef/capitalize.yml
new file mode 100644
index 000000000..5d72e3ffd
--- /dev/null
+++ b/docs/tools/vale/chef/capitalize.yml
@@ -0,0 +1,11 @@
+extends: substitution
+message: "Use '%s' instead of '%s'"
+level: error
+ignorecase: false
+swap:
+ 'Microsoft Windows': Windows
+ 'windows': Windows
+ 'linux': Linux
+ 'postgreSQL' : PostgreSQL
+ 'postgresql' : PostgreSQL
+
diff --git a/docs/tools/vale/chef/chef_automate.yml b/docs/tools/vale/chef/chef_automate.yml
new file mode 100644
index 000000000..13279d15d
--- /dev/null
+++ b/docs/tools/vale/chef/chef_automate.yml
@@ -0,0 +1,6 @@
+extends: substitution
+message: "Use '%s' instead of '%s'"
+level: error
+ignorecase: false
+swap:
+ '(?:[^\s]*) ?Automate': Chef Automate
diff --git a/docs/tools/vale/chef/chef_desktop.yml b/docs/tools/vale/chef/chef_desktop.yml
new file mode 100644
index 000000000..0c289692b
--- /dev/null
+++ b/docs/tools/vale/chef/chef_desktop.yml
@@ -0,0 +1,7 @@
+extends: substitution
+message: "Use '%s' instead of '%s'"
+level: error
+ignorecase: true
+swap:
+ # '(?[^\s]*(Windows|macOS))? Desktop': Chef Desktop
+ 'chefdesktop': Chef Desktop
diff --git a/docs/tools/vale/chef/chef_habitat.yml b/docs/tools/vale/chef/chef_habitat.yml
new file mode 100644
index 000000000..75a6db468
--- /dev/null
+++ b/docs/tools/vale/chef/chef_habitat.yml
@@ -0,0 +1,6 @@
+extends: substitution
+message: "Use Use '%s' instead of 'Habitat'."
+level: error
+swap:
+ '(?:[^\s]* ){0,1}Habitat': Chef Habitat
+
diff --git a/docs/tools/vale/chef/chef_infra_client.yml b/docs/tools/vale/chef/chef_infra_client.yml
new file mode 100644
index 000000000..6fc86418e
--- /dev/null
+++ b/docs/tools/vale/chef/chef_infra_client.yml
@@ -0,0 +1,7 @@
+extends: substitution
+message: "Use '%s' instead of '%s'"
+level: error
+ignorecase: true
+swap:
+ 'chef client': Chef Infra Client
+ 'chef-client': Chef Infra Client
diff --git a/docs/tools/vale/chef/chef_infra_server.yml b/docs/tools/vale/chef/chef_infra_server.yml
new file mode 100644
index 000000000..36b189ca9
--- /dev/null
+++ b/docs/tools/vale/chef/chef_infra_server.yml
@@ -0,0 +1,7 @@
+extends: substitution
+message: "Use '%s' instead of '%s'"
+level: error
+ignorecase: true
+swap:
+ 'Chef Server': Chef Infra Server
+
diff --git a/docs/tools/vale/chef/chef_inspec.yml b/docs/tools/vale/chef/chef_inspec.yml
new file mode 100644
index 000000000..5a34ae5ac
--- /dev/null
+++ b/docs/tools/vale/chef/chef_inspec.yml
@@ -0,0 +1,6 @@
+extends: substitution
+message: "Use '%s' instead of '%s'"
+level: error
+ignorecase: true
+swap:
+ '(?:[^\s]*) ?InSpec': Chef InSpec
diff --git a/docs/tools/vale/chef/habitat_builder.yml b/docs/tools/vale/chef/habitat_builder.yml
new file mode 100644
index 000000000..3f24a8654
--- /dev/null
+++ b/docs/tools/vale/chef/habitat_builder.yml
@@ -0,0 +1,6 @@
+extends: substitution
+message: "Use Use '%s' instead of 'Builder'."
+level: error
+swap:
+ '(?:[^\s]* ){0,2}Builder': Chef Habitat Builder
+
diff --git a/docs/tools/vale/chef/habitat_depot.yml b/docs/tools/vale/chef/habitat_depot.yml
new file mode 100644
index 000000000..bd3591916
--- /dev/null
+++ b/docs/tools/vale/chef/habitat_depot.yml
@@ -0,0 +1,6 @@
+extends: substitution
+message: "Use Use '%s' instead of 'Depot'."
+level: error
+swap:
+ 'Depot': Chef Habitat Artifact storage
+
diff --git a/docs/tools/vale/chef/habitat_studio.yml b/docs/tools/vale/chef/habitat_studio.yml
new file mode 100644
index 000000000..7f4320ede
--- /dev/null
+++ b/docs/tools/vale/chef/habitat_studio.yml
@@ -0,0 +1,6 @@
+extends: substitution
+message: "Use Use '%s' instead of 'Studio'."
+level: error
+swap:
+ '(?:[^\s]* ){0,2}Studio': Chef Habitat Studio
+
diff --git a/docs/tools/vale/chef/habitat_supervisor.yml b/docs/tools/vale/chef/habitat_supervisor.yml
new file mode 100644
index 000000000..b6b45af65
--- /dev/null
+++ b/docs/tools/vale/chef/habitat_supervisor.yml
@@ -0,0 +1,6 @@
+extends: substitution
+message: "Use Use '%s' instead of 'Supervisor'."
+level: error
+swap:
+ '(?:[^\s]* ){0,2}Supervisor': Chef Habitat Supervisor
+
diff --git a/docs/tools/vale/chef/policyfile.yml b/docs/tools/vale/chef/policyfile.yml
new file mode 100644
index 000000000..50cb2d396
--- /dev/null
+++ b/docs/tools/vale/chef/policyfile.yml
@@ -0,0 +1,6 @@
+extends: substitution
+message: "Use '%s' instead of '%s'"
+level: error
+ignorecase: true
+swap:
+ 'policy file': Policyfile
diff --git a/docs/tools/vale/chef/rule-form.txt b/docs/tools/vale/chef/rule-form.txt
new file mode 100644
index 000000000..9fc757dfa
--- /dev/null
+++ b/docs/tools/vale/chef/rule-form.txt
@@ -0,0 +1,33 @@
+# All rules should define the following header keys:
+#
+# `extends` indicates the extension point being used (see below for information
+# on the possible values).
+extends: existence
+# `message` is shown to the user when the rule is broken.
+#
+# Many extension points accept format specifiers (%s), which are replaced by
+# extracted values. See the exention-specific sections below for more details.
+message: "Consider removing '%s'"
+# `level` assigns the rule's severity.
+#
+# The accepted values are suggestion, warning, and error.
+level: warning
+# `scope` specifies where this rule should apply -- e.g., headings, sentences, etc.
+#
+# See the Markup section for more information on scoping.
+scope: heading
+# `code` determines whether or not the content of code spans -- e.g., `foo` for
+# Markdown -- is ignored.
+code: false
+# `link` gives the source for this rule.
+link: 'https://errata.ai/'
+
+# Example Style
+extends: existence
+message: Consider removing '%s'
+level: warning
+code: false
+ignorecase: true
+tokens:
+ - appears to be
+ - arguably
diff --git a/docs/tools/vale/vale.tmpl b/docs/tools/vale/vale.tmpl
new file mode 100644
index 000000000..36dfbd6b7
--- /dev/null
+++ b/docs/tools/vale/vale.tmpl
@@ -0,0 +1,51 @@
+{{- /* Modify Vale's output https://docs.errata.ai/vale/cli#--output */ -}}
+
+{{- /* Keep track of our various counts */ -}}
+
+{{- $e := 0 -}}
+{{- $w := 0 -}}
+{{- $s := 0 -}}
+{{- $f := 0 -}}
+
+{{- /* Range over the linted files */ -}}
+
+{{- range .Files}}
+
+{{- $f = add1 $f -}}
+{{- $path := .Path | underline -}}
+
+{{- /* Range over the file's alerts */ -}}
+
+{{- range .Alerts -}}
+
+{{- $error := "" -}}
+{{- if eq .Severity "error" -}}
+ {{- $error = .Severity | red -}}
+ {{- $e = add1 $e -}}
+{{- else if eq .Severity "warning" -}}
+ {{- $error = .Severity | yellow -}}
+ {{- $w = add1 $w -}}
+{{- else -}}
+ {{- $error = .Severity | blue -}}
+ {{- $s = add1 $s -}}
+{{- end}}
+
+{{- /* Variables setup */ -}}
+
+{{- $path = $path -}}
+{{- $loc := printf "Line %d, position %d" .Line (index .Span 0) -}}
+{{- $check := printf "%s" .Check -}}
+{{- $message := printf "%s" .Message -}}
+{{- $link := printf "%s" .Link -}}
+
+{{- /* Output */ -}}
+
+{{ $path }}:
+ {{ $loc }} (rule {{ $check }})
+ {{ $error }}: {{ $message }}
+ More information: {{ $link }}
+
+{{end -}}
+{{end -}}
+
+{{- $e}} {{"errors" | red}}, {{$w}} {{"warnings" | yellow}}, and {{$s}} {{"suggestions" | blue}} found in {{$f}} {{$f | int | plural "file" "files"}}.
diff --git a/docs/tools/vale/vale/Annotations.yml b/docs/tools/vale/vale/Annotations.yml
new file mode 100755
index 000000000..a249c7463
--- /dev/null
+++ b/docs/tools/vale/vale/Annotations.yml
@@ -0,0 +1,9 @@
+message: "'%s' left in text"
+extends: existence
+ignorecase: false
+level: suggestion
+tokens:
+ - XXX
+ - FIXME
+ - TODO
+ - NOTE
diff --git a/docs/tools/vale/vale/Editorializing.yml b/docs/tools/vale/vale/Editorializing.yml
new file mode 100755
index 000000000..848036c25
--- /dev/null
+++ b/docs/tools/vale/vale/Editorializing.yml
@@ -0,0 +1,44 @@
+extends: existence
+message: "Consider removing '%s'"
+ignorecase: true
+level: warning
+tokens:
+ - actually
+ - aptly
+ - are a number
+ - basically
+ - clearly
+ - completely
+ - essentially
+ - exceedingly
+ - excellent
+ - extremely
+ - fairly
+ - fortunately
+ - huge
+ - interestingly
+ - is a number
+ - it is important to realize
+ - it should be noted that
+ - largely
+ - mostly
+ - notably
+ - note that
+ - obviously
+ - of course
+ - quite
+ - relatively
+ - remarkably
+ - several
+ - significantly
+ - substantially
+ - surprisingly
+ - tiny
+ - totally
+ - tragically
+ - unfortunately
+ - untimely
+ - various
+ - vast
+ - very
+ - without a doubt
diff --git a/docs/tools/vale/vale/Hedging.yml b/docs/tools/vale/vale/Hedging.yml
new file mode 100755
index 000000000..815551924
--- /dev/null
+++ b/docs/tools/vale/vale/Hedging.yml
@@ -0,0 +1,28 @@
+extends: existence
+message: "Consider removing '%s'"
+ignorecase: true
+level: warning
+tokens:
+ - appear to be
+ - arguably
+ - as far as I know
+ - could
+ - from my point of view
+ - hopefully
+ - I believe
+ - I doubt
+ - I think
+ - in general
+ - In my opinion
+ - likely
+ - might
+ - more or less
+ - perhaps
+ - possibly
+ - presumably
+ - probably
+ - seem(s)?
+ - somewhat
+ - to my knowledge
+ - unlikely
+ - usually
diff --git a/docs/tools/vale/vale/Litotes.yml b/docs/tools/vale/vale/Litotes.yml
new file mode 100755
index 000000000..adeee352e
--- /dev/null
+++ b/docs/tools/vale/vale/Litotes.yml
@@ -0,0 +1,28 @@
+extends: substitution
+message: Consider using '%s' instead of '%s'
+ignorecase: true
+level: warning
+swap:
+ no minor: major
+ no ordinary: extraordinary
+ no(?:t)? small: large
+ not (?:a)? bad: good
+ not accept(?:ed)?: rejected
+ not allow(?:ed)?: prevented
+ not certain: uncertain
+ not consider(?:ed)?: ignored
+ not fail: passed
+ not have: lack(s)
+ not many: few
+ not old enough: too young
+ not remember: forgot
+ not succeed: failed
+ not the brightest: dumb
+ not the same: different
+ not unaware: aware
+ not unclean: clean
+ not unfamiliar: familiar
+ not unlike: like
+ not unpleasant: pleasant
+ not useless: useful
+ not wrong: right
diff --git a/docs/tools/vale/vale/Redundancy.yml b/docs/tools/vale/vale/Redundancy.yml
new file mode 100755
index 000000000..3a79dc1e7
--- /dev/null
+++ b/docs/tools/vale/vale/Redundancy.yml
@@ -0,0 +1,67 @@
+extends: existence
+message: "'%s' is redundant"
+ignorecase: true
+level: error
+tokens:
+ - (?:added|extra) bonus
+ - (?:advance|prior) notice
+ - (?:gather|assemble|attach|blend|mix|combine|collaborate|connect|cooperate) together
+ - (?:terrible|horrible) tragedy
+ - \d{1,2} ?a\.?m\.? in the morning
+ - \d{1,2} ?p\.?m\.? at night
+ - \d{1,2} ?p\.?m\.? in the afternoon
+ - \d{1,2} ?p\.?m\.? in the evening
+ - ABM missile
+ - ABM missiles
+ - ABS braking system
+ - absolutely (?:necessary|essential)
+ - ACT test
+ - already existing
+ - armed gunman
+ - artificial prosthesis
+ - ATM machine
+ - bald-headed
+ - brief (?:moment|summary)
+ - CD disc
+ - cease and desist
+ - circle around
+ - close proximity
+ - closed fist
+ - completely (?:destroyed|eliminate|engulfed|filled|surround)
+ - could possibly
+ - CPI Index
+ - current trend(s)?
+ - end result
+ - enter in
+ - erode away
+ - false pretense
+ - final result
+ - free gift
+ - GPS system
+ - GUI interface
+ - HIV virus
+ - inner feelings
+ - ISBN number
+ - join together
+ - LCD display
+ - local resident(s)?
+ - natural instinct
+ - new invention
+ - null and void
+ - past history
+ - PDF format
+ - PIN number
+ - please RSVP
+ - RAM memory
+ - RAS syndrome
+ - RIP in peace
+ - safe haven
+ - SALT talks
+ - SAT test
+ - shout loudly
+ - surrounded on all sides
+ - undergraduate student
+ - unexpected surprise
+ - unintended mistake
+ - UPC code(s)?
+ - violent explosion
diff --git a/docs/tools/vale/vale/Uncomparables.yml b/docs/tools/vale/vale/Uncomparables.yml
new file mode 100755
index 000000000..5bba006a1
--- /dev/null
+++ b/docs/tools/vale/vale/Uncomparables.yml
@@ -0,0 +1,44 @@
+extends: existence
+message: "'%s' is not comparable"
+ignorecase: true
+level: error
+raw:
+ - \b(?:absolutely|most|more|less|least|very|quite|largely|extremely|increasingly|kind of|mildy|hardly|greatly|sort of)\b\s*
+tokens:
+ - absolute
+ - adequate
+ - complete
+ - correct
+ - certain
+ - devoid
+ - entire
+ - 'false'
+ - fatal
+ - favorite
+ - final
+ - ideal
+ - impossible
+ - inevitable
+ - infinite
+ - irrevocable
+ - main
+ - manifest
+ - only
+ - paramount
+ - perfect
+ - perpetual
+ - possible
+ - preferable
+ - principal
+ - singular
+ - stationary
+ - sufficient
+ - 'true'
+ - unanimous
+ - unavoidable
+ - unbroken
+ - uniform
+ - unique
+ - universal
+ - void
+ - whole
diff --git a/docs/tools/vale/write-good/Cliches.yml b/docs/tools/vale/write-good/Cliches.yml
new file mode 100644
index 000000000..c95314387
--- /dev/null
+++ b/docs/tools/vale/write-good/Cliches.yml
@@ -0,0 +1,702 @@
+extends: existence
+message: "Try to avoid using clichés like '%s'."
+ignorecase: true
+level: warning
+tokens:
+ - a chip off the old block
+ - a clean slate
+ - a dark and stormy night
+ - a far cry
+ - a fine kettle of fish
+ - a loose cannon
+ - a penny saved is a penny earned
+ - a tough row to hoe
+ - a word to the wise
+ - ace in the hole
+ - acid test
+ - add insult to injury
+ - against all odds
+ - air your dirty laundry
+ - all fun and games
+ - all in a day's work
+ - all talk, no action
+ - all thumbs
+ - all your eggs in one basket
+ - all's fair in love and war
+ - all's well that ends well
+ - almighty dollar
+ - American as apple pie
+ - an axe to grind
+ - another day, another dollar
+ - armed to the teeth
+ - as luck would have it
+ - as old as time
+ - as the crow flies
+ - at loose ends
+ - at my wits end
+ - avoid like the plague
+ - babe in the woods
+ - back against the wall
+ - back in the saddle
+ - back to square one
+ - back to the drawing board
+ - bad to the bone
+ - badge of honor
+ - bald faced liar
+ - ballpark figure
+ - banging your head against a brick wall
+ - baptism by fire
+ - barking up the wrong tree
+ - bat out of hell
+ - be all and end all
+ - beat a dead horse
+ - beat around the bush
+ - been there, done that
+ - beggars can't be choosers
+ - behind the eight ball
+ - bend over backwards
+ - benefit of the doubt
+ - bent out of shape
+ - best thing since sliced bread
+ - bet your bottom dollar
+ - better half
+ - better late than never
+ - better mousetrap
+ - better safe than sorry
+ - between a rock and a hard place
+ - beyond the pale
+ - bide your time
+ - big as life
+ - big cheese
+ - big fish in a small pond
+ - big man on campus
+ - bigger they are the harder they fall
+ - bird in the hand
+ - bird's eye view
+ - birds and the bees
+ - birds of a feather flock together
+ - bit the hand that feeds you
+ - bite the bullet
+ - bite the dust
+ - bitten off more than he can chew
+ - black as coal
+ - black as pitch
+ - black as the ace of spades
+ - blast from the past
+ - bleeding heart
+ - blessing in disguise
+ - blind ambition
+ - blind as a bat
+ - blind leading the blind
+ - blood is thicker than water
+ - blood sweat and tears
+ - blow off steam
+ - blow your own horn
+ - blushing bride
+ - boils down to
+ - bolt from the blue
+ - bone to pick
+ - bored stiff
+ - bored to tears
+ - bottomless pit
+ - boys will be boys
+ - bright and early
+ - brings home the bacon
+ - broad across the beam
+ - broken record
+ - brought back to reality
+ - bull by the horns
+ - bull in a china shop
+ - burn the midnight oil
+ - burning question
+ - burning the candle at both ends
+ - burst your bubble
+ - bury the hatchet
+ - busy as a bee
+ - by hook or by crook
+ - call a spade a spade
+ - called onto the carpet
+ - calm before the storm
+ - can of worms
+ - can't cut the mustard
+ - can't hold a candle to
+ - case of mistaken identity
+ - cat got your tongue
+ - cat's meow
+ - caught in the crossfire
+ - caught red-handed
+ - checkered past
+ - chomping at the bit
+ - cleanliness is next to godliness
+ - clear as a bell
+ - clear as mud
+ - close to the vest
+ - cock and bull story
+ - cold shoulder
+ - come hell or high water
+ - cool as a cucumber
+ - cool, calm, and collected
+ - cost a king's ransom
+ - count your blessings
+ - crack of dawn
+ - crash course
+ - creature comforts
+ - cross that bridge when you come to it
+ - crushing blow
+ - cry like a baby
+ - cry me a river
+ - cry over spilt milk
+ - crystal clear
+ - curiosity killed the cat
+ - cut and dried
+ - cut through the red tape
+ - cut to the chase
+ - cute as a bugs ear
+ - cute as a button
+ - cute as a puppy
+ - cuts to the quick
+ - dark before the dawn
+ - day in, day out
+ - dead as a doornail
+ - devil is in the details
+ - dime a dozen
+ - divide and conquer
+ - dog and pony show
+ - dog days
+ - dog eat dog
+ - dog tired
+ - don't burn your bridges
+ - don't count your chickens
+ - don't look a gift horse in the mouth
+ - don't rock the boat
+ - don't step on anyone's toes
+ - don't take any wooden nickels
+ - down and out
+ - down at the heels
+ - down in the dumps
+ - down the hatch
+ - down to earth
+ - draw the line
+ - dressed to kill
+ - dressed to the nines
+ - drives me up the wall
+ - dull as dishwater
+ - dyed in the wool
+ - eagle eye
+ - ear to the ground
+ - early bird catches the worm
+ - easier said than done
+ - easy as pie
+ - eat your heart out
+ - eat your words
+ - eleventh hour
+ - even the playing field
+ - every dog has its day
+ - every fiber of my being
+ - everything but the kitchen sink
+ - eye for an eye
+ - face the music
+ - facts of life
+ - fair weather friend
+ - fall by the wayside
+ - fan the flames
+ - feast or famine
+ - feather your nest
+ - feathered friends
+ - few and far between
+ - fifteen minutes of fame
+ - filthy vermin
+ - fine kettle of fish
+ - fish out of water
+ - fishing for a compliment
+ - fit as a fiddle
+ - fit the bill
+ - fit to be tied
+ - flash in the pan
+ - flat as a pancake
+ - flip your lid
+ - flog a dead horse
+ - fly by night
+ - fly the coop
+ - follow your heart
+ - for all intents and purposes
+ - for the birds
+ - for what it's worth
+ - force of nature
+ - force to be reckoned with
+ - forgive and forget
+ - fox in the henhouse
+ - free and easy
+ - free as a bird
+ - fresh as a daisy
+ - full steam ahead
+ - fun in the sun
+ - garbage in, garbage out
+ - gentle as a lamb
+ - get a kick out of
+ - get a leg up
+ - get down and dirty
+ - get the lead out
+ - get to the bottom of
+ - get your feet wet
+ - gets my goat
+ - gilding the lily
+ - give and take
+ - go against the grain
+ - go at it tooth and nail
+ - go for broke
+ - go him one better
+ - go the extra mile
+ - go with the flow
+ - goes without saying
+ - good as gold
+ - good deed for the day
+ - good things come to those who wait
+ - good time was had by all
+ - good times were had by all
+ - greased lightning
+ - greek to me
+ - green thumb
+ - green-eyed monster
+ - grist for the mill
+ - growing like a weed
+ - hair of the dog
+ - hand to mouth
+ - happy as a clam
+ - happy as a lark
+ - hasn't a clue
+ - have a nice day
+ - have high hopes
+ - have the last laugh
+ - haven't got a row to hoe
+ - head honcho
+ - head over heels
+ - hear a pin drop
+ - heard it through the grapevine
+ - heart's content
+ - heavy as lead
+ - hem and haw
+ - high and dry
+ - high and mighty
+ - high as a kite
+ - hit paydirt
+ - hold your head up high
+ - hold your horses
+ - hold your own
+ - hold your tongue
+ - honest as the day is long
+ - horns of a dilemma
+ - horse of a different color
+ - hot under the collar
+ - hour of need
+ - I beg to differ
+ - icing on the cake
+ - if the shoe fits
+ - if the shoe were on the other foot
+ - in a jam
+ - in a jiffy
+ - in a nutshell
+ - in a pig's eye
+ - in a pinch
+ - in a word
+ - in hot water
+ - in the gutter
+ - in the nick of time
+ - in the thick of it
+ - in your dreams
+ - it ain't over till the fat lady sings
+ - it goes without saying
+ - it takes all kinds
+ - it takes one to know one
+ - it's a small world
+ - it's only a matter of time
+ - ivory tower
+ - Jack of all trades
+ - jockey for position
+ - jog your memory
+ - joined at the hip
+ - judge a book by its cover
+ - jump down your throat
+ - jump in with both feet
+ - jump on the bandwagon
+ - jump the gun
+ - jump to conclusions
+ - just a hop, skip, and a jump
+ - just the ticket
+ - justice is blind
+ - keep a stiff upper lip
+ - keep an eye on
+ - keep it simple, stupid
+ - keep the home fires burning
+ - keep up with the Joneses
+ - keep your chin up
+ - keep your fingers crossed
+ - kick the bucket
+ - kick up your heels
+ - kick your feet up
+ - kid in a candy store
+ - kill two birds with one stone
+ - kiss of death
+ - knock it out of the park
+ - knock on wood
+ - knock your socks off
+ - know him from Adam
+ - know the ropes
+ - know the score
+ - knuckle down
+ - knuckle sandwich
+ - knuckle under
+ - labor of love
+ - ladder of success
+ - land on your feet
+ - lap of luxury
+ - last but not least
+ - last hurrah
+ - last-ditch effort
+ - law of the jungle
+ - law of the land
+ - lay down the law
+ - leaps and bounds
+ - let sleeping dogs lie
+ - let the cat out of the bag
+ - let the good times roll
+ - let your hair down
+ - let's talk turkey
+ - letter perfect
+ - lick your wounds
+ - lies like a rug
+ - life's a bitch
+ - life's a grind
+ - light at the end of the tunnel
+ - lighter than a feather
+ - lighter than air
+ - like clockwork
+ - like father like son
+ - like taking candy from a baby
+ - like there's no tomorrow
+ - lion's share
+ - live and learn
+ - live and let live
+ - long and short of it
+ - long lost love
+ - look before you leap
+ - look down your nose
+ - look what the cat dragged in
+ - looking a gift horse in the mouth
+ - looks like death warmed over
+ - loose cannon
+ - lose your head
+ - lose your temper
+ - loud as a horn
+ - lounge lizard
+ - loved and lost
+ - low man on the totem pole
+ - luck of the draw
+ - luck of the Irish
+ - make hay while the sun shines
+ - make money hand over fist
+ - make my day
+ - make the best of a bad situation
+ - make the best of it
+ - make your blood boil
+ - man of few words
+ - man's best friend
+ - mark my words
+ - meaningful dialogue
+ - missed the boat on that one
+ - moment in the sun
+ - moment of glory
+ - moment of truth
+ - money to burn
+ - more power to you
+ - more than one way to skin a cat
+ - movers and shakers
+ - moving experience
+ - naked as a jaybird
+ - naked truth
+ - neat as a pin
+ - needle in a haystack
+ - needless to say
+ - neither here nor there
+ - never look back
+ - never say never
+ - nip and tuck
+ - nip it in the bud
+ - no guts, no glory
+ - no love lost
+ - no pain, no gain
+ - no skin off my back
+ - no stone unturned
+ - no time like the present
+ - no use crying over spilled milk
+ - nose to the grindstone
+ - not a hope in hell
+ - not a minute's peace
+ - not in my backyard
+ - not playing with a full deck
+ - not the end of the world
+ - not written in stone
+ - nothing to sneeze at
+ - nothing ventured nothing gained
+ - now we're cooking
+ - off the top of my head
+ - off the wagon
+ - off the wall
+ - old hat
+ - older and wiser
+ - older than dirt
+ - older than Methuselah
+ - on a roll
+ - on cloud nine
+ - on pins and needles
+ - on the bandwagon
+ - on the money
+ - on the nose
+ - on the rocks
+ - on the spot
+ - on the tip of my tongue
+ - on the wagon
+ - on thin ice
+ - once bitten, twice shy
+ - one bad apple doesn't spoil the bushel
+ - one born every minute
+ - one brick short
+ - one foot in the grave
+ - one in a million
+ - one red cent
+ - only game in town
+ - open a can of worms
+ - open and shut case
+ - open the flood gates
+ - opportunity doesn't knock twice
+ - out of pocket
+ - out of sight, out of mind
+ - out of the frying pan into the fire
+ - out of the woods
+ - out on a limb
+ - over a barrel
+ - over the hump
+ - pain and suffering
+ - pain in the
+ - panic button
+ - par for the course
+ - part and parcel
+ - party pooper
+ - pass the buck
+ - patience is a virtue
+ - pay through the nose
+ - penny pincher
+ - perfect storm
+ - pig in a poke
+ - pile it on
+ - pillar of the community
+ - pin your hopes on
+ - pitter patter of little feet
+ - plain as day
+ - plain as the nose on your face
+ - play by the rules
+ - play your cards right
+ - playing the field
+ - playing with fire
+ - pleased as punch
+ - plenty of fish in the sea
+ - point with pride
+ - poor as a church mouse
+ - pot calling the kettle black
+ - pretty as a picture
+ - pull a fast one
+ - pull your punches
+ - pulling your leg
+ - pure as the driven snow
+ - put it in a nutshell
+ - put one over on you
+ - put the cart before the horse
+ - put the pedal to the metal
+ - put your best foot forward
+ - put your foot down
+ - quick as a bunny
+ - quick as a lick
+ - quick as a wink
+ - quick as lightning
+ - quiet as a dormouse
+ - rags to riches
+ - raining buckets
+ - raining cats and dogs
+ - rank and file
+ - rat race
+ - reap what you sow
+ - red as a beet
+ - red herring
+ - reinvent the wheel
+ - rich and famous
+ - rings a bell
+ - ripe old age
+ - ripped me off
+ - rise and shine
+ - road to hell is paved with good intentions
+ - rob Peter to pay Paul
+ - roll over in the grave
+ - rub the wrong way
+ - ruled the roost
+ - running in circles
+ - sad but true
+ - sadder but wiser
+ - salt of the earth
+ - scared stiff
+ - scared to death
+ - sealed with a kiss
+ - second to none
+ - see eye to eye
+ - seen the light
+ - seize the day
+ - set the record straight
+ - set the world on fire
+ - set your teeth on edge
+ - sharp as a tack
+ - shoot for the moon
+ - shoot the breeze
+ - shot in the dark
+ - shoulder to the wheel
+ - sick as a dog
+ - sigh of relief
+ - signed, sealed, and delivered
+ - sink or swim
+ - six of one, half a dozen of another
+ - skating on thin ice
+ - slept like a log
+ - slinging mud
+ - slippery as an eel
+ - slow as molasses
+ - smart as a whip
+ - smooth as a baby's bottom
+ - sneaking suspicion
+ - snug as a bug in a rug
+ - sow wild oats
+ - spare the rod, spoil the child
+ - speak of the devil
+ - spilled the beans
+ - spinning your wheels
+ - spitting image of
+ - spoke with relish
+ - spread like wildfire
+ - spring to life
+ - squeaky wheel gets the grease
+ - stands out like a sore thumb
+ - start from scratch
+ - stick in the mud
+ - still waters run deep
+ - stitch in time
+ - stop and smell the roses
+ - straight as an arrow
+ - straw that broke the camel's back
+ - strong as an ox
+ - stubborn as a mule
+ - stuff that dreams are made of
+ - stuffed shirt
+ - sweating blood
+ - sweating bullets
+ - take a load off
+ - take one for the team
+ - take the bait
+ - take the bull by the horns
+ - take the plunge
+ - takes one to know one
+ - takes two to tango
+ - the more the merrier
+ - the real deal
+ - the real McCoy
+ - the red carpet treatment
+ - the same old story
+ - there is no accounting for taste
+ - thick as a brick
+ - thick as thieves
+ - thin as a rail
+ - think outside of the box
+ - third time's the charm
+ - this day and age
+ - this hurts me worse than it hurts you
+ - this point in time
+ - three sheets to the wind
+ - through thick and thin
+ - throw in the towel
+ - tie one on
+ - tighter than a drum
+ - time and time again
+ - time is of the essence
+ - tip of the iceberg
+ - tired but happy
+ - to coin a phrase
+ - to each his own
+ - to make a long story short
+ - to the best of my knowledge
+ - toe the line
+ - tongue in cheek
+ - too good to be true
+ - too hot to handle
+ - too numerous to mention
+ - touch with a ten foot pole
+ - tough as nails
+ - trial and error
+ - trials and tribulations
+ - tried and true
+ - trip down memory lane
+ - twist of fate
+ - two cents worth
+ - two peas in a pod
+ - ugly as sin
+ - under the counter
+ - under the gun
+ - under the same roof
+ - under the weather
+ - until the cows come home
+ - unvarnished truth
+ - up the creek
+ - uphill battle
+ - upper crust
+ - upset the applecart
+ - vain attempt
+ - vain effort
+ - vanquish the enemy
+ - vested interest
+ - waiting for the other shoe to drop
+ - wakeup call
+ - warm welcome
+ - watch your p's and q's
+ - watch your tongue
+ - watching the clock
+ - water under the bridge
+ - weather the storm
+ - weed them out
+ - week of Sundays
+ - went belly up
+ - wet behind the ears
+ - what goes around comes around
+ - what you see is what you get
+ - when it rains, it pours
+ - when push comes to shove
+ - when the cat's away
+ - when the going gets tough, the tough get going
+ - white as a sheet
+ - whole ball of wax
+ - whole hog
+ - whole nine yards
+ - wild goose chase
+ - will wonders never cease?
+ - wisdom of the ages
+ - wise as an owl
+ - wolf at the door
+ - words fail me
+ - work like a dog
+ - world weary
+ - worst nightmare
+ - worth its weight in gold
+ - wrong side of the bed
+ - yanking your chain
+ - yappy as a dog
+ - years young
+ - you are what you eat
+ - you can run but you can't hide
+ - you only live once
+ - you're the boss
+ - young and foolish
+ - young and vibrant
diff --git a/docs/tools/vale/write-good/E-Prime.yml b/docs/tools/vale/write-good/E-Prime.yml
new file mode 100644
index 000000000..074a102b2
--- /dev/null
+++ b/docs/tools/vale/write-good/E-Prime.yml
@@ -0,0 +1,32 @@
+extends: existence
+message: "Try to avoid using '%s'."
+ignorecase: true
+level: suggestion
+tokens:
+ - am
+ - are
+ - aren't
+ - be
+ - been
+ - being
+ - he's
+ - here's
+ - here's
+ - how's
+ - i'm
+ - is
+ - isn't
+ - it's
+ - she's
+ - that's
+ - there's
+ - they're
+ - was
+ - wasn't
+ - we're
+ - were
+ - weren't
+ - what's
+ - where's
+ - who's
+ - you're
diff --git a/docs/tools/vale/write-good/Illusions.yml b/docs/tools/vale/write-good/Illusions.yml
new file mode 100644
index 000000000..b4f132185
--- /dev/null
+++ b/docs/tools/vale/write-good/Illusions.yml
@@ -0,0 +1,11 @@
+extends: repetition
+message: "'%s' is repeated!"
+level: warning
+alpha: true
+action:
+ name: edit
+ params:
+ - truncate
+ - " "
+tokens:
+ - '[^\s]+'
diff --git a/docs/tools/vale/write-good/Passive.yml b/docs/tools/vale/write-good/Passive.yml
new file mode 100644
index 000000000..f472cb904
--- /dev/null
+++ b/docs/tools/vale/write-good/Passive.yml
@@ -0,0 +1,183 @@
+extends: existence
+message: "'%s' may be passive voice. Use active voice if you can."
+ignorecase: true
+level: warning
+raw:
+ - \b(am|are|were|being|is|been|was|be)\b\s*
+tokens:
+ - '[\w]+ed'
+ - awoken
+ - beat
+ - become
+ - been
+ - begun
+ - bent
+ - beset
+ - bet
+ - bid
+ - bidden
+ - bitten
+ - bled
+ - blown
+ - born
+ - bought
+ - bound
+ - bred
+ - broadcast
+ - broken
+ - brought
+ - built
+ - burnt
+ - burst
+ - cast
+ - caught
+ - chosen
+ - clung
+ - come
+ - cost
+ - crept
+ - cut
+ - dealt
+ - dived
+ - done
+ - drawn
+ - dreamt
+ - driven
+ - drunk
+ - dug
+ - eaten
+ - fallen
+ - fed
+ - felt
+ - fit
+ - fled
+ - flown
+ - flung
+ - forbidden
+ - foregone
+ - forgiven
+ - forgotten
+ - forsaken
+ - fought
+ - found
+ - frozen
+ - given
+ - gone
+ - gotten
+ - ground
+ - grown
+ - heard
+ - held
+ - hidden
+ - hit
+ - hung
+ - hurt
+ - kept
+ - knelt
+ - knit
+ - known
+ - laid
+ - lain
+ - leapt
+ - learnt
+ - led
+ - left
+ - lent
+ - let
+ - lighted
+ - lost
+ - made
+ - meant
+ - met
+ - misspelt
+ - mistaken
+ - mown
+ - overcome
+ - overdone
+ - overtaken
+ - overthrown
+ - paid
+ - pled
+ - proven
+ - put
+ - quit
+ - read
+ - rid
+ - ridden
+ - risen
+ - run
+ - rung
+ - said
+ - sat
+ - sawn
+ - seen
+ - sent
+ - set
+ - sewn
+ - shaken
+ - shaven
+ - shed
+ - shod
+ - shone
+ - shorn
+ - shot
+ - shown
+ - shrunk
+ - shut
+ - slain
+ - slept
+ - slid
+ - slit
+ - slung
+ - smitten
+ - sold
+ - sought
+ - sown
+ - sped
+ - spent
+ - spilt
+ - spit
+ - split
+ - spoken
+ - spread
+ - sprung
+ - spun
+ - stolen
+ - stood
+ - stridden
+ - striven
+ - struck
+ - strung
+ - stuck
+ - stung
+ - stunk
+ - sung
+ - sunk
+ - swept
+ - swollen
+ - sworn
+ - swum
+ - swung
+ - taken
+ - taught
+ - thought
+ - thrived
+ - thrown
+ - thrust
+ - told
+ - torn
+ - trodden
+ - understood
+ - upheld
+ - upset
+ - wed
+ - wept
+ - withheld
+ - withstood
+ - woken
+ - won
+ - worn
+ - wound
+ - woven
+ - written
+ - wrung
diff --git a/docs/tools/vale/write-good/README.md b/docs/tools/vale/write-good/README.md
new file mode 100644
index 000000000..3edcc9b37
--- /dev/null
+++ b/docs/tools/vale/write-good/README.md
@@ -0,0 +1,27 @@
+Based on [write-good](https://github.com/btford/write-good).
+
+> Naive linter for English prose for developers who can't write good and wanna learn to do other stuff good too.
+
+```
+The MIT License (MIT)
+
+Copyright (c) 2014 Brian Ford
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+```
diff --git a/docs/tools/vale/write-good/So.yml b/docs/tools/vale/write-good/So.yml
new file mode 100644
index 000000000..e57f099dc
--- /dev/null
+++ b/docs/tools/vale/write-good/So.yml
@@ -0,0 +1,5 @@
+extends: existence
+message: "Don't start a sentence with '%s'."
+level: error
+raw:
+ - '(?:[;-]\s)so[\s,]|\bSo[\s,]'
diff --git a/docs/tools/vale/write-good/ThereIs.yml b/docs/tools/vale/write-good/ThereIs.yml
new file mode 100644
index 000000000..8b82e8f6c
--- /dev/null
+++ b/docs/tools/vale/write-good/ThereIs.yml
@@ -0,0 +1,6 @@
+extends: existence
+message: "Don't start a sentence with '%s'."
+ignorecase: false
+level: error
+raw:
+ - '(?:[;-]\s)There\s(is|are)|\bThere\s(is|are)\b'
diff --git a/docs/tools/vale/write-good/TooWordy.yml b/docs/tools/vale/write-good/TooWordy.yml
new file mode 100644
index 000000000..275701b19
--- /dev/null
+++ b/docs/tools/vale/write-good/TooWordy.yml
@@ -0,0 +1,221 @@
+extends: existence
+message: "'%s' is too wordy."
+ignorecase: true
+level: warning
+tokens:
+ - a number of
+ - abundance
+ - accede to
+ - accelerate
+ - accentuate
+ - accompany
+ - accomplish
+ - accorded
+ - accrue
+ - acquiesce
+ - acquire
+ - additional
+ - adjacent to
+ - adjustment
+ - admissible
+ - advantageous
+ - adversely impact
+ - advise
+ - aforementioned
+ - aggregate
+ - aircraft
+ - all of
+ - all things considered
+ - alleviate
+ - allocate
+ - along the lines of
+ - already existing
+ - alternatively
+ - amazing
+ - ameliorate
+ - anticipate
+ - apparent
+ - appreciable
+ - as a matter of fact
+ - as a means of
+ - as far as I'm concerned
+ - as of yet
+ - as to
+ - as yet
+ - ascertain
+ - assistance
+ - at the present time
+ - at this time
+ - attain
+ - attributable to
+ - authorize
+ - because of the fact that
+ - belated
+ - benefit from
+ - bestow
+ - by means of
+ - by virtue of
+ - by virtue of the fact that
+ - cease
+ - close proximity
+ - commence
+ - comply with
+ - concerning
+ - consequently
+ - consolidate
+ - constitutes
+ - demonstrate
+ - depart
+ - designate
+ - discontinue
+ - due to the fact that
+ - each and every
+ - economical
+ - eliminate
+ - elucidate
+ - employ
+ - endeavor
+ - enumerate
+ - equitable
+ - equivalent
+ - evaluate
+ - evidenced
+ - exclusively
+ - expedite
+ - expend
+ - expiration
+ - facilitate
+ - factual evidence
+ - feasible
+ - finalize
+ - first and foremost
+ - for all intents and purposes
+ - for the most part
+ - for the purpose of
+ - forfeit
+ - formulate
+ - have a tendency to
+ - honest truth
+ - however
+ - if and when
+ - impacted
+ - implement
+ - in a manner of speaking
+ - in a timely manner
+ - in a very real sense
+ - in accordance with
+ - in addition
+ - in all likelihood
+ - in an effort to
+ - in between
+ - in excess of
+ - in lieu of
+ - in light of the fact that
+ - in many cases
+ - in my opinion
+ - in order to
+ - in regard to
+ - in some instances
+ - in terms of
+ - in the case of
+ - in the event that
+ - in the final analysis
+ - in the nature of
+ - in the near future
+ - in the process of
+ - inception
+ - incumbent upon
+ - indicate
+ - indication
+ - initiate
+ - irregardless
+ - is applicable to
+ - is authorized to
+ - is responsible for
+ - it is
+ - it is essential
+ - it seems that
+ - it was
+ - magnitude
+ - maximum
+ - methodology
+ - minimize
+ - minimum
+ - modify
+ - monitor
+ - multiple
+ - necessitate
+ - nevertheless
+ - not certain
+ - not many
+ - not often
+ - not unless
+ - not unlike
+ - notwithstanding
+ - null and void
+ - numerous
+ - objective
+ - obligate
+ - obtain
+ - on the contrary
+ - on the other hand
+ - one particular
+ - optimum
+ - overall
+ - owing to the fact that
+ - participate
+ - particulars
+ - pass away
+ - pertaining to
+ - point in time
+ - portion
+ - possess
+ - preclude
+ - previously
+ - prior to
+ - prioritize
+ - procure
+ - proficiency
+ - provided that
+ - purchase
+ - put simply
+ - readily apparent
+ - refer back
+ - regarding
+ - relocate
+ - remainder
+ - remuneration
+ - requirement
+ - reside
+ - residence
+ - retain
+ - satisfy
+ - shall
+ - should you wish
+ - similar to
+ - solicit
+ - span across
+ - strategize
+ - subsequent
+ - substantial
+ - successfully complete
+ - sufficient
+ - terminate
+ - the month of
+ - the point I am trying to make
+ - therefore
+ - time period
+ - took advantage of
+ - transmit
+ - transpire
+ - type of
+ - until such time as
+ - utilization
+ - utilize
+ - validate
+ - various different
+ - what I mean to say is
+ - whether or not
+ - with respect to
+ - with the exception of
+ - witnessed
diff --git a/docs/tools/vale/write-good/Weasel.yml b/docs/tools/vale/write-good/Weasel.yml
new file mode 100644
index 000000000..e29391444
--- /dev/null
+++ b/docs/tools/vale/write-good/Weasel.yml
@@ -0,0 +1,207 @@
+extends: existence
+message: "'%s' is a weasel word!"
+ignorecase: true
+level: warning
+tokens:
+ - absolutely
+ - accidentally
+ - additionally
+ - allegedly
+ - alternatively
+ - angrily
+ - anxiously
+ - approximately
+ - awkwardly
+ - badly
+ - barely
+ - beautifully
+ - blindly
+ - boldly
+ - bravely
+ - brightly
+ - briskly
+ - bristly
+ - bubbly
+ - busily
+ - calmly
+ - carefully
+ - carelessly
+ - cautiously
+ - cheerfully
+ - clearly
+ - closely
+ - coldly
+ - completely
+ - consequently
+ - correctly
+ - courageously
+ - crinkly
+ - cruelly
+ - crumbly
+ - cuddly
+ - currently
+ - daily
+ - daringly
+ - deadly
+ - definitely
+ - deliberately
+ - doubtfully
+ - dumbly
+ - eagerly
+ - early
+ - easily
+ - elegantly
+ - enormously
+ - enthusiastically
+ - equally
+ - especially
+ - eventually
+ - exactly
+ - exceedingly
+ - exclusively
+ - extremely
+ - fairly
+ - faithfully
+ - fatally
+ - fiercely
+ - finally
+ - fondly
+ - few
+ - foolishly
+ - fortunately
+ - frankly
+ - frantically
+ - generously
+ - gently
+ - giggly
+ - gladly
+ - gracefully
+ - greedily
+ - happily
+ - hardly
+ - hastily
+ - healthily
+ - heartily
+ - helpfully
+ - honestly
+ - hourly
+ - hungrily
+ - hurriedly
+ - immediately
+ - impatiently
+ - inadequately
+ - ingeniously
+ - innocently
+ - inquisitively
+ - interestingly
+ - irritably
+ - jiggly
+ - joyously
+ - justly
+ - kindly
+ - largely
+ - lately
+ - lazily
+ - likely
+ - literally
+ - lonely
+ - loosely
+ - loudly
+ - loudly
+ - luckily
+ - madly
+ - many
+ - mentally
+ - mildly
+ - monthly
+ - mortally
+ - mostly
+ - mysteriously
+ - neatly
+ - nervously
+ - nightly
+ - noisily
+ - normally
+ - obediently
+ - occasionally
+ - only
+ - openly
+ - painfully
+ - particularly
+ - patiently
+ - perfectly
+ - politely
+ - poorly
+ - powerfully
+ - presumably
+ - previously
+ - promptly
+ - punctually
+ - quarterly
+ - quickly
+ - quietly
+ - rapidly
+ - rarely
+ - really
+ - recently
+ - recklessly
+ - regularly
+ - remarkably
+ - relatively
+ - reluctantly
+ - repeatedly
+ - rightfully
+ - roughly
+ - rudely
+ - sadly
+ - safely
+ - selfishly
+ - sensibly
+ - seriously
+ - sharply
+ - shortly
+ - shyly
+ - significantly
+ - silently
+ - simply
+ - sleepily
+ - slowly
+ - smartly
+ - smelly
+ - smoothly
+ - softly
+ - solemnly
+ - sparkly
+ - speedily
+ - stealthily
+ - sternly
+ - stupidly
+ - substantially
+ - successfully
+ - suddenly
+ - surprisingly
+ - suspiciously
+ - swiftly
+ - tenderly
+ - tensely
+ - thoughtfully
+ - tightly
+ - timely
+ - truthfully
+ - unexpectedly
+ - unfortunately
+ - usually
+ - very
+ - victoriously
+ - violently
+ - vivaciously
+ - warmly
+ - waverly
+ - weakly
+ - wearily
+ - weekly
+ - wildly
+ - wisely
+ - worldly
+ - wrinkly
+ - yearly
diff --git a/docs/tools/vale/write-good/meta.json b/docs/tools/vale/write-good/meta.json
new file mode 100644
index 000000000..a115d2886
--- /dev/null
+++ b/docs/tools/vale/write-good/meta.json
@@ -0,0 +1,4 @@
+{
+ "feed": "https://github.com/errata-ai/write-good/releases.atom",
+ "vale_version": ">=1.0.0"
+}
diff --git a/inspec.yml b/inspec.yml
index 04fc195d6..650934a35 100644
--- a/inspec.yml
+++ b/inspec.yml
@@ -5,7 +5,7 @@ copyright: Chef Software, Inc.
copyright_email: support@chef.io
license: Apache-2.0
summary: This resource pack provides compliance resources for Azure.
-version: 1.68.0
+version: 1.68.5
inspec_version: '>= 4.18.39'
supports:
- platform: azure
diff --git a/libraries/azure_backend.rb b/libraries/azure_backend.rb
index d187ae954..ff947d6f8 100644
--- a/libraries/azure_backend.rb
+++ b/libraries/azure_backend.rb
@@ -622,6 +622,8 @@ def create_method(object, name, value)
else
probes = []
value.each do |value_item|
+ next if value_item.nil?
+
probes << AzureResourceProbe.new(value_item)
end
end
diff --git a/libraries/azure_data_factory_linked_service.rb b/libraries/azure_data_factory_linked_service.rb
new file mode 100644
index 000000000..848226ca2
--- /dev/null
+++ b/libraries/azure_data_factory_linked_service.rb
@@ -0,0 +1,39 @@
+require 'azure_generic_resource'
+
+class AzureDataFactoryLinkedService < AzureGenericResource
+ name 'azure_data_factory_linked_service'
+ desc 'Checking azure data factory linked service'
+ example <<-EXAMPLE
+ describe azure_data_factory_linked_service(resource_group: resource_group, factory_name: factory_name, linked_service_name: linked_service_name) do
+ it { should exist }
+ end
+ EXAMPLE
+
+ def initialize(opts = {})
+ # Options should be Hash type. Otherwise Ruby will raise an error when we try to access the keys.
+ raise ArgumentError, 'Parameters must be provided in an Hash object.' unless opts.is_a?(Hash)
+ #
+ # Azure REST API endpoint URL format for the resource:
+ # GET https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/
+ # providers/Microsoft.DataFactory/factories/{factoryName}/linkedservices/{linkedServiceName}?api-version=2018-06-01
+ #
+ opts[:resource_provider] = specific_resource_constraint('Microsoft.DataFactory/factories', opts)
+ opts[:required_parameters] = %i(factory_name)
+ opts[:resource_path] = [opts[:factory_name], 'linkedservices'].join('/')
+ opts[:resource_identifiers] = %i(linked_service_name)
+ # static_resource parameter must be true for setting the resource_provider in the backend.
+ super(opts, true)
+ end
+
+ def to_s
+ super(AzureDataFactoryLinkedService)
+ end
+
+ def linked_service_type
+ properties.type if exists?
+ end
+
+ def type_properties
+ properties.typeProperties if exists?
+ end
+end
diff --git a/libraries/azure_data_factory_linked_services.rb b/libraries/azure_data_factory_linked_services.rb
new file mode 100644
index 000000000..5323ff53b
--- /dev/null
+++ b/libraries/azure_data_factory_linked_services.rb
@@ -0,0 +1,75 @@
+require 'azure_generic_resources'
+
+class AzureDataFactoryLinkedServices < AzureGenericResources
+ name 'azure_data_factory_linked_services'
+ desc 'List azure linked services'
+ example <<-EXAMPLE
+ describe azure_data_factory_linked_services(resource_group: 'example', factory_name: 'fn') do
+ it { should exist }
+ end
+ EXAMPLE
+
+ def initialize(opts = {})
+ # Options should be Hash type. Otherwise Ruby will raise an error when we try to access the keys.
+ raise ArgumentError, 'Parameters must be provided in an Hash object.' unless opts.is_a?(Hash)
+ # Azure REST API endpoint URL format for the resource:
+ # GET https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/
+ # providers/Microsoft.DataFactory/factories/{factoryName}/linkedservices?api-version=2018-06-01
+ #
+ opts[:resource_provider] = specific_resource_constraint('Microsoft.DataFactory/factories', opts)
+ opts[:required_parameters] = %i(factory_name)
+ opts[:resource_path] = [opts[:factory_name], 'linkedservices'].join('/')
+ # static_resource parameter must be true for setting the resource_provider in the backend.
+ super(opts, true)
+ # Check if the resource is failed.
+ # It is recommended to check that after every usage of superclass methods or API calls.
+ return if failed_resource?
+
+ # Define the column and field names for FilterTable.
+ # - column: It is defined as an instance method, callable on the resource, and present `field` values in a list.
+ # - field: It has to be identical with the `key` names in @table items that will be presented in the FilterTable.
+ # @see https://github.com/inspec/inspec/blob/master/docs/dev/filtertable-usage.md
+
+ table_schema = [
+ { column: :names, field: :name },
+ { column: :types, field: :type },
+ { column: :ids, field: :id },
+ { column: :etags, field: :etag },
+ { column: :type_properties, field: :type_properties },
+ { column: :linked_service_types, field: :linked_service_type },
+ { column: :properties, field: :properties },
+ ]
+
+ # FilterTable is populated at the very end due to being an expensive operation.
+ AzureGenericResources.populate_filter_table(:table, table_schema)
+ end
+
+ def to_s
+ super(AzureDataFactoryLinkedServices)
+ end
+
+ private
+
+ # Populate the @table with the resource attributes.
+ # @table has been declared in the super class as an empty array.
+ # Each item in the @table
+ # - should be a Hash object
+ # - should have the exact key names defined in the @table_schema as `field`.
+ def populate_table
+ # If @resources empty than @table should stay as an empty array as declared in superclass.
+ # This will ensure constructing resource and passing `should_not exist` test.
+ return [] if @resources.empty?
+
+ @resources.each do |resource|
+ @table << {
+ id: resource[:id],
+ name: resource[:name],
+ type: resource[:type],
+ etag: resource[:etag],
+ type_properties: resource[:properties][:typeProperties],
+ linked_service_type: resource[:properties][:type],
+ properties: resource[:properties],
+ }
+ end
+ end
+end
diff --git a/terraform/azure.tf b/terraform/azure.tf
index 009afec51..0f03d20a2 100644
--- a/terraform/azure.tf
+++ b/terraform/azure.tf
@@ -1372,6 +1372,13 @@ resource "azurerm_data_factory" "adf" {
resource_group_name = azurerm_resource_group.rg.name
}
+resource "azurerm_data_factory_linked_service_mysql" "dflsmsql" {
+ name = "dflsm-sql"
+ resource_group_name = azurerm_resource_group.rg.name
+ data_factory_name = azurerm_data_factory.adf.name
+ connection_string = "Server=test;Port=3306;Database=test;User=test;SSLMode=1;UseSystemTrustStore=0;Password=test"
+}
+
// the resource itself is not yet available in tf because of this open issue
// https://github.com/terraform-providers/terraform-provider-azurerm/issues/9197
//resource "azurerm_policy_exemption" "inspec_compliance_policy_exemption" {
diff --git a/terraform/outputs.tf b/terraform/outputs.tf
index ba3f32b26..d06ed0dea 100644
--- a/terraform/outputs.tf
+++ b/terraform/outputs.tf
@@ -480,6 +480,10 @@ output "sample_directory_object" {
value = var.sample_directory_object
}
+output "linked_service_name" {
+ value = azurerm_data_factory_linked_service_mysql.dflsmsql.name
+}
+
output "inspec_redis_cache_name" {
description = "The name of the redis cache created for cloud packs"
value = azurerm_redis_cache.inspec_compliance_redis_cache.name
diff --git a/test/integration/verify/controls/azure_data_factory_linked_service.rb b/test/integration/verify/controls/azure_data_factory_linked_service.rb
new file mode 100644
index 000000000..3d992cf8c
--- /dev/null
+++ b/test/integration/verify/controls/azure_data_factory_linked_service.rb
@@ -0,0 +1,24 @@
+resource_group1 = input('resource_group', value: nil)
+factory_name1 = input('df_name', value: nil)
+linked_service_name1 = input('linked_service_name', value: nil)
+
+control 'azure_data_factory_linked_service' do
+
+ describe azure_data_factory_linked_service(resource_group: resource_group1,
+ factory_name: factory_name1, linked_service_name: linked_service_name1) do
+ it { should exist }
+ its('name') { should eq linked_service_name1 }
+ its('type') { should eq 'Microsoft.DataFactory/factories/linkedservices' }
+ its('linked_service_type') { should eq 'MySql' }
+ end
+
+ describe azure_data_factory_linked_service(resource_group: resource_group1,
+ factory_name: 'fake', linked_service_name: linked_service_name1) do
+ it { should_not exist }
+ end
+
+ describe azure_data_factory_linked_service(resource_group: resource_group1,
+ factory_name: factory_name1, linked_service_name: 'should_not_exist') do
+ it { should_not exist }
+ end
+end
diff --git a/test/integration/verify/controls/azure_data_factory_linked_services.rb b/test/integration/verify/controls/azure_data_factory_linked_services.rb
new file mode 100644
index 000000000..5c1be513f
--- /dev/null
+++ b/test/integration/verify/controls/azure_data_factory_linked_services.rb
@@ -0,0 +1,12 @@
+resource_group = input('resource_group', value: nil)
+factory_name = input('df_name', value: nil)
+linked_service_name1 = input('linked_service_name', value: nil)
+
+control 'azure_data_factory_linked_services' do
+ describe azure_data_factory_linked_services(resource_group: resource_group, factory_name: factory_name) do
+ it { should exist }
+ its('names') { should include linked_service_name1 }
+ its('types') { should include 'Microsoft.DataFactory/factories/linkedservices' }
+ its('linked_service_types') { should include('MySql') }
+ end
+end
diff --git a/test/unit/resources/azure_data_factory_linked_service_test.rb b/test/unit/resources/azure_data_factory_linked_service_test.rb
new file mode 100644
index 000000000..72c222790
--- /dev/null
+++ b/test/unit/resources/azure_data_factory_linked_service_test.rb
@@ -0,0 +1,17 @@
+require_relative 'helper'
+require 'azure_data_factory_linked_service'
+
+class AzureDataFactoryLinkedServiceTestConstructorTest < Minitest::Test
+ def test_empty_param_not_ok
+ assert_raises(ArgumentError) { AzureDataFactoryLinkedService.new }
+ end
+
+ # resource_provider should not be allowed.
+ def test_resource_provider_not_ok
+ assert_raises(ArgumentError) { AzureDataFactoryLinkedService.new(resource_provider: 'some_type') }
+ end
+
+ def test_resource_group
+ assert_raises(ArgumentError) { AzureDataFactoryLinkedService.new(name: 'my-name') }
+ end
+end
diff --git a/test/unit/resources/azure_data_factory_linked_services_test.rb b/test/unit/resources/azure_data_factory_linked_services_test.rb
new file mode 100644
index 000000000..a8092e468
--- /dev/null
+++ b/test/unit/resources/azure_data_factory_linked_services_test.rb
@@ -0,0 +1,25 @@
+require_relative 'helper'
+require 'azure_data_factory_linked_services'
+
+class AzureDataFactoryLinkedServicesTestConstructorTest < Minitest::Test
+ # resource_type should not be allowed.
+ def test_resource_type_not_ok
+ assert_raises(ArgumentError) { AzureDataFactoryLinkedServices.new(resource_provider: 'some_type') }
+ end
+
+ def tag_value_not_ok
+ assert_raises(ArgumentError) { AzureDataFactoryLinkedServices.new(tag_value: 'some_tag_value') }
+ end
+
+ def tag_name_not_ok
+ assert_raises(ArgumentError) { AzureDataFactoryLinkedServices.new(tag_name: 'some_tag_name') }
+ end
+
+ def test_resource_id_not_ok
+ assert_raises(ArgumentError) { AzureDataFactoryLinkedServices.new(resource_id: 'some_id') }
+ end
+
+ def test_name_not_ok
+ assert_raises(ArgumentError) { AzureDataFactoryLinkedServices.new(name: 'some_name') }
+ end
+end