From ebb5393afd44558ccc1887eda493ac527bab099c Mon Sep 17 00:00:00 2001
From: Karel van Klink <karel.vanklink@geant.org>
Date: Wed, 6 Sep 2023 10:20:18 +0200
Subject: [PATCH] Update Vale linting and documentation to be more in line with
 the general GAP documentation

---
 .gitignore                                    |  1 +
 docs/source/glossary.md                       |  3 +++
 docs/vale/.vale.ini                           |  5 +++-
 .../vale/styles/Vocab/geant-jargon/accept.txt |  1 +
 docs/vale/styles/custom/Contractions.yml      | 27 +++++++++++++++++++
 gso/services/infoblox.py                      | 25 ++++++++---------
 gso/services/provisioning_proxy.py            |  6 ++---
 gso/services/subscriptions.py                 |  4 +--
 8 files changed, 54 insertions(+), 18 deletions(-)
 create mode 100644 docs/vale/styles/custom/Contractions.yml

diff --git a/.gitignore b/.gitignore
index e3eaa624..79218323 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,6 +14,7 @@ oss-params.json
 docs/build
 docs/vale/styles/*
 !docs/vale/styles/Vocab/
+!docs/vale/styles/custom/
 
 .idea
 .venv
diff --git a/docs/source/glossary.md b/docs/source/glossary.md
index 57fc3374..7035fa3b 100644
--- a/docs/source/glossary.md
+++ b/docs/source/glossary.md
@@ -5,6 +5,9 @@ BGP
 : Border Gateway Protocol: a path vector routing protocol described in 
 <a href="https://datatracker.ietf.org/doc/html/rfc4271" target="_blank">RFC 4271</a>.
 
+CNAME
+: A type of DNS record that is used as an alias from one hostname to another
+
 CRUD
 : Create, Read, Update, Delete
 
diff --git a/docs/vale/.vale.ini b/docs/vale/.vale.ini
index 2982d4d1..cc1a032a 100644
--- a/docs/vale/.vale.ini
+++ b/docs/vale/.vale.ini
@@ -20,13 +20,16 @@ proselint.Annotations = NO
 ; Replacing a ... with … shouldn't be holding back the entire CI pipeline
 proselint.Typography = warning
 ; Same applies for not using contractions
-Microsoft.Contractions = warning
+Microsoft.Contractions = NO
+custom.Contractions = YES
 
 TokenIgnores = ({term}), (:param \S+:), (:type \S+:)
 
 [*/glossary.md]
 ; Ignore acronyms being undefined in the file that defines all acronyms by definition.
 Microsoft.Acronyms = NO
+Microsoft.Contractions = NO
+custom.Contractions = YES
 Microsoft.Passive = NO
 
 [formats]
diff --git a/docs/vale/styles/Vocab/geant-jargon/accept.txt b/docs/vale/styles/Vocab/geant-jargon/accept.txt
index b4ae8b01..f9dd1b51 100644
--- a/docs/vale/styles/Vocab/geant-jargon/accept.txt
+++ b/docs/vale/styles/Vocab/geant-jargon/accept.txt
@@ -10,3 +10,4 @@ dry_run
 Dark_fiber
 [A|a]ddress
 [I|i]ptrunk
+[A|a]llocate
diff --git a/docs/vale/styles/custom/Contractions.yml b/docs/vale/styles/custom/Contractions.yml
new file mode 100644
index 00000000..9c2b94a5
--- /dev/null
+++ b/docs/vale/styles/custom/Contractions.yml
@@ -0,0 +1,27 @@
+extends: substitution
+message: "Use '%s' instead of '%s'."
+level: suggestion
+ignorecase: true
+swap:
+  aren't: are not
+  can't: cannot
+  couldn't: could not
+  didn't: did not
+  don't: do not
+  doesn't: does not
+  hasn't: has not
+  haven't: have not
+  how's: how is
+  isn't: is not
+  it's: it is
+  shouldn't: should not
+  that's: that is
+  they're: they are
+  wasn't: was not
+  we're: we are
+  we've: we have
+  weren't: were not
+  what's: what is
+  when's: when is
+  where's: where is
+  won't: will not
diff --git a/gso/services/infoblox.py b/gso/services/infoblox.py
index c8775d0e..fca0965c 100644
--- a/gso/services/infoblox.py
+++ b/gso/services/infoblox.py
@@ -20,7 +20,7 @@ class DeletionError(Exception):
 def _setup_connection() -> tuple[connector.Connector, IPAMParams]:
     """Set up a new connection with an Infoblox instance.
 
-    :return: A tuple that contains an Infoblox `Connector` instance, and
+    :return: A tuple that has an Infoblox `Connector` instance, and {term}`IPAM` parameters.
     :rtype: tuple[{class}`infoblox_client.connector.Connector`, IPAMParams]
     """
     oss = load_oss_params().IPAM
@@ -52,7 +52,8 @@ def _allocate_network(
     :type dns_view: str
     :param netmask: The netmask of the desired network. Can be up to 32 for v4 networks, and 128 for v6 networks.
     :type netmask: int
-    :param containers: A list of network containers in which the network should be allocated, given in CIDR notation.
+    :param containers: A list of network containers in which the network should be allocated, given in {term}`CIDR`
+                       notation.
     :type containers: list[str]
     :param comment: Optionally, a comment can be added to the network allocation.
     :type comment: str, optional
@@ -85,8 +86,8 @@ def hostname_available(hostname: str) -> bool:
 def allocate_v4_network(service_type: str, comment: str | None = "") -> ipaddress.IPv4Network:
     """Allocate a new IPv4 network in Infoblox.
 
-    Allocate an IPv4 network for a specific service type. The service type should be defined in the OSS parameters of
-    GSO, from which the containers and netmask will be used.
+    Allocate an IPv4 network for a specific service type. The service type should be defined in the {term}`OSS`
+    parameters of {term}`GSO`, from which the containers and netmask will be used.
 
     :param service_type: The service type for which the network is allocated.
     :type service_type: str
@@ -104,8 +105,8 @@ def allocate_v4_network(service_type: str, comment: str | None = "") -> ipaddres
 def allocate_v6_network(service_type: str, comment: str | None = "") -> ipaddress.IPv6Network:
     """Allocate a new IPv6 network in Infoblox.
 
-    Allocate an IPv6 network for a specific service type. The service type should be defined in the OSS parameters of
-    GSO, from which the containers and netmask will be used.
+    Allocate an IPv6 network for a specific service type. The service type should be defined in the {term}`OSS`
+    parameters of {term}`GSO`, from which the containers and netmask will be used.
 
     :param service_type: The service type for which the network is allocated.
     :type service_type: str
@@ -123,8 +124,8 @@ def allocate_v6_network(service_type: str, comment: str | None = "") -> ipaddres
 def delete_network(ip_network: ipaddress.IPv4Network | ipaddress.IPv6Network) -> None:
     """Delete a network in Infoblox.
 
-    Delete a network that is allocated in Infoblox, by passing the CIDR to be deleted. The CIDR must exactly match an
-    existing entry in Infoblox, otherwise this method raises a {class}`DeletionError`
+    Delete a network that is allocated in Infoblox, by passing the {term}`CIDR` to be deleted. The {term}`CIDR` must
+    exactly match an existing entry in Infoblox, otherwise this method raises a {class}`DeletionError`
 
     :param ip_network: The network that should get deleted.
     :type ip_network: ipaddress.IPv4Network | ipaddress.IPv6Network
@@ -146,12 +147,12 @@ def allocate_host(
     host. Most likely to be a loopback interface. If the hostname is not available in Infoblox (due to a potential
     collision) this method raises an {class}`AllocationError`.
 
-    :param hostname: The FQDN of the new host
+    :param hostname: The {term}`FQDN` of the new host
     :type hostname: str
     :param service_type: The service type from which IP resources should be used.
     :type service_type: str
-    :param cname_aliases: A list of any CNAME aliases that should be associated with this host. Most often this will
-                          be a single loopback address.
+    :param cname_aliases: A list of any {term}`CNAME` aliases that should be associated with this host. Most often this
+                          will be a single loopback address.
     :type cname_aliases: list[str]
     :param comment: Optionally, a comment can be added to the host record in Infoblox.
     :type comment: str, optional
@@ -218,7 +219,7 @@ def delete_host_by_ip(ip_addr: ipaddress.IPv4Address | ipaddress.IPv6Address) ->
 def delete_host_by_fqdn(fqdn: str) -> None:
     """Delete a host from Infoblox.
 
-    Delete a host record in Infoblox, by providing the FQDN that is associated with the record. Raises a
+    Delete a host record in Infoblox, by providing the {term}`FQDN` that is associated with the record. Raises a
     {class}`DeletionError` if no record can be found in Infoblox.
 
     :param fqdn: The FQDN of the host record that should get deleted.
diff --git a/gso/services/provisioning_proxy.py b/gso/services/provisioning_proxy.py
index 1ca12a0b..412902e5 100644
--- a/gso/services/provisioning_proxy.py
+++ b/gso/services/provisioning_proxy.py
@@ -29,7 +29,7 @@ DEFAULT_LABEL = "Provisioning proxy is running. Please come back later for the r
 class CUDOperation(strEnum):
     """Enumerator for different {term}`CRUD` operations that the provisioning proxy supports.
 
-    Read isn't applicable, hence the missing R.
+    Read is not applicable, hence the missing R.
     """
 
     POST = "POST"
@@ -173,7 +173,7 @@ def migrate_ip_trunk(
     :type new_node: {class}`Router`
     :param new_lag_interface: The name of the new aggregated Ethernet interface
     :type new_lag_interface: str
-    :param new_lag_member_interfaces: The new list of interfaces that are part of the LAG
+    :param new_lag_member_interfaces: The new list of interfaces that are part of the {term}`LAG`
     :type new_lag_member_interfaces: list[str]
     :param replace_index: The index of the side that is going to be replaced as part of the existing trunk,
                           can be `0` or `1`.
@@ -213,7 +213,7 @@ def _await_pp_results(subscription: SubscriptionModel, label_text: str = DEFAULT
 
     :param subscription: The current subscription that the provisioning proxy is acting on.
     :type subscription: {class}`orchestrator.domain.SubscriptionModel`
-    :param label_text: A label that's displayed to the operator when the provisioning proxy hasn't returned its
+    :param label_text: A label that's displayed to the operator when the provisioning proxy has not returned its
         results yet. Defaults to `DEFAULT_LABEL`.
     :type label_text: str
     :return: The input that's given by the provisioning proxy, that should contain run results, and a `confirm`
diff --git a/gso/services/subscriptions.py b/gso/services/subscriptions.py
index 9ee2e4df..4986c06a 100644
--- a/gso/services/subscriptions.py
+++ b/gso/services/subscriptions.py
@@ -69,7 +69,7 @@ def get_active_router_subscriptions(fields: list[str]) -> list[Subscription]:
 
 
 def get_product_id_by_name(product_name: ProductType) -> UUID:
-    """Retrieve the UUID of a product by its name.
+    """Retrieve the {term}`UUID` of a product by its name.
 
     Args:
     ----
@@ -77,7 +77,7 @@ def get_product_id_by_name(product_name: ProductType) -> UUID:
 
     Returns:
     -------
-    UUID: The UUID of the product.
+    {term}`UUID`: The {term}`UUID` of the product.
     """
     return ProductTable.query.filter_by(name=product_name).first().product_id
 
-- 
GitLab