From be9acfddc452940892c90a4a5b7e7e0d19dca3d9 Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Fri, 30 Jun 2023 12:05:18 +0200 Subject: [PATCH] Set up mypy, Flake8, isort and pre-commit hooks --- .editorconfig | 9 +++++++++ .flake8 | 3 +++ .pre-commit-config.yaml | 42 +++++++++++++++++++++++++++++++++++++++++ index.html | 2 +- main.py | 31 ++++++++++++++++-------------- mypy.ini | 16 ++++++++++++++++ requirements.txt | 3 +++ 7 files changed, 91 insertions(+), 15 deletions(-) create mode 100644 .editorconfig create mode 100644 .flake8 create mode 100644 .pre-commit-config.yaml create mode 100644 mypy.ini create mode 100644 requirements.txt diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..9c61627 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,9 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_style = space +indent_size = 4 +insert_final_newline = true +trim_trailing_whitespace = true diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000..bd34cfa --- /dev/null +++ b/.flake8 @@ -0,0 +1,3 @@ +[flake8] +# Black is used for formatting, ignore Flake8's line length limits. +extend-ignore = E501 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..e3313af --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,42 @@ +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.4.0 + hooks: + # Generic hooks, relevant for any language. + - id: forbid-new-submodules + - id: fix-byte-order-marker + - id: end-of-file-fixer + - id: trailing-whitespace + - id: mixed-line-ending + args: + - --fix=lf + - id: detect-private-key + - id: check-added-large-files + - id: check-merge-conflict + - id: check-vcs-permalinks + - id: check-json + - id: check-toml + - id: check-xml + - id: check-yaml + - id: check-executables-have-shebangs + - id: check-shebang-scripts-are-executable + - id: check-case-conflict + - id: check-symlinks + + # Python-specific hooks. + - id: requirements-txt-fixer + + - repo: https://github.com/PyCQA/isort + rev: 5.12.0 + hooks: + - id: isort + + - repo: https://github.com/psf/black + rev: 23.3.0 + hooks: + - id: black + + - repo: https://github.com/PyCQA/flake8 + rev: 6.0.0 + hooks: + - id: flake8 diff --git a/index.html b/index.html index 3b4ae6f..fea0718 100644 --- a/index.html +++ b/index.html @@ -65,7 +65,7 @@ } function getChartColor(label) { - return chartColors[label] ?? '#'+(0x1000000+(Math.random())*0xffffff).toString(16).substr(1,6); + return chartColors[label] ?? '#' + (0x1000000 + (Math.random()) * 0xffffff).toString(16).substr(1, 6); } // Function that sums all values in an array (use with `reduce()`). diff --git a/main.py b/main.py index 35f939e..7a58d45 100755 --- a/main.py +++ b/main.py @@ -1,23 +1,26 @@ #!/usr/bin/env python3 -from gql import gql, Client -from gql.transport.aiohttp import AIOHTTPTransport -from dotenv import load_dotenv -import os import json +import os +from typing import Any, Dict + +from dotenv import load_dotenv +from gql import Client, gql +from gql.transport.aiohttp import AIOHTTPTransport +from typing_extensions import Final def main() -> None: load_dotenv() - transport = AIOHTTPTransport( + transport: Final = AIOHTTPTransport( url="https://api.github.com/graphql", headers={ "Authorization": f"Bearer {os.getenv('GODOT_ISSUES_STATS_GITHUB_TOKEN')}" }, ) - client = Client(transport=transport, fetch_schema_from_transport=True) + client: Final = Client(transport=transport, fetch_schema_from_transport=True) - results = [] + results: Final = [] cursor = None # Get the 30×100 = 3,000 last issues. # TODO: Retry requests a few times if they fail. @@ -52,13 +55,13 @@ def main() -> None: cursor = result["repository"]["issues"]["edges"][0]["cursor"] # Array of dictionaries with user and system information string. - user_system_infos = [] + user_system_infos: Final = [] # Counters for all statistics (values are a set of usernames). # A set is used, so that each user may only increment a given counter once. # A single user may increment multiple counters in the same category, # as they may report issues with different hardware or operating systems. - statistics = { + statistics: Dict[str, Any] = { "os": { "windows": { "11": set(), @@ -153,7 +156,6 @@ def main() -> None: # Number of physical CPU cores. # On CPUs with hybrid topologies (such as 12th generation Intel and newer), # this is the sum of P-cores and E-cores. - "1": set(), "2": set(), "3": set(), "4": set(), @@ -310,7 +312,7 @@ def main() -> None: # Handle deleted ("ghost") users. user = ( node["node"]["author"]["login"] - if node["node"]["author"] != None + if node["node"]["author"] is not None else "ghost" ) # Fix CRLF line endings causing issues with detection, @@ -2945,13 +2947,14 @@ def main() -> None: ): statistics["gpu"]["intel"]["unknown"].add(user) - print(f"Number of scannable reports: {len(user_system_infos)}") + statistics["num_reports"] = len(user_system_infos) + print(f"Number of scannable reports: {statistics['num_reports']}") - output_path = "statistics.json" + output_path: Final = "statistics.json" with open(output_path, "w") as out_file: # Serialize Python sets as their length as an integer, since we only need to know how many users # match each metric (and not who exactly). - def set_default(obj): + def set_default(obj: object) -> int: if isinstance(obj, set): return len(obj) raise TypeError diff --git a/mypy.ini b/mypy.ini new file mode 100644 index 0000000..dda6f10 --- /dev/null +++ b/mypy.ini @@ -0,0 +1,16 @@ +[mypy] +strict = True +disallow_any_unimported = True +disallow_any_decorated = True +warn_unreachable = True +pretty = True +show_column_numbers = True + +[mypy-gql] +ignore_missing_imports = True + +[mypy-dotenv] +ignore_missing_imports = True + +[mypy-gql.transport.aiohttp] +ignore_missing_imports = True diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..40e809a --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +gql[all]==3.4.1 +python-dotenv==1.0.0 +typing_extensions==4.7.0