mirror of
https://github.com/godotengine/issue-stats.git
synced 2026-01-04 18:10:12 +03:00
Set up mypy, Flake8, isort and pre-commit hooks
This commit is contained in:
9
.editorconfig
Normal file
9
.editorconfig
Normal file
@@ -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
|
||||||
3
.flake8
Normal file
3
.flake8
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
[flake8]
|
||||||
|
# Black is used for formatting, ignore Flake8's line length limits.
|
||||||
|
extend-ignore = E501
|
||||||
42
.pre-commit-config.yaml
Normal file
42
.pre-commit-config.yaml
Normal file
@@ -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
|
||||||
@@ -65,7 +65,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getChartColor(label) {
|
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()`).
|
// Function that sums all values in an array (use with `reduce()`).
|
||||||
|
|||||||
31
main.py
31
main.py
@@ -1,23 +1,26 @@
|
|||||||
#!/usr/bin/env python3
|
#!/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 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:
|
def main() -> None:
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
|
|
||||||
transport = AIOHTTPTransport(
|
transport: Final = AIOHTTPTransport(
|
||||||
url="https://api.github.com/graphql",
|
url="https://api.github.com/graphql",
|
||||||
headers={
|
headers={
|
||||||
"Authorization": f"Bearer {os.getenv('GODOT_ISSUES_STATS_GITHUB_TOKEN')}"
|
"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
|
cursor = None
|
||||||
# Get the 30×100 = 3,000 last issues.
|
# Get the 30×100 = 3,000 last issues.
|
||||||
# TODO: Retry requests a few times if they fail.
|
# TODO: Retry requests a few times if they fail.
|
||||||
@@ -52,13 +55,13 @@ def main() -> None:
|
|||||||
cursor = result["repository"]["issues"]["edges"][0]["cursor"]
|
cursor = result["repository"]["issues"]["edges"][0]["cursor"]
|
||||||
|
|
||||||
# Array of dictionaries with user and system information string.
|
# 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).
|
# 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 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,
|
# A single user may increment multiple counters in the same category,
|
||||||
# as they may report issues with different hardware or operating systems.
|
# as they may report issues with different hardware or operating systems.
|
||||||
statistics = {
|
statistics: Dict[str, Any] = {
|
||||||
"os": {
|
"os": {
|
||||||
"windows": {
|
"windows": {
|
||||||
"11": set(),
|
"11": set(),
|
||||||
@@ -153,7 +156,6 @@ def main() -> None:
|
|||||||
# Number of physical CPU cores.
|
# Number of physical CPU cores.
|
||||||
# On CPUs with hybrid topologies (such as 12th generation Intel and newer),
|
# On CPUs with hybrid topologies (such as 12th generation Intel and newer),
|
||||||
# this is the sum of P-cores and E-cores.
|
# this is the sum of P-cores and E-cores.
|
||||||
"1": set(),
|
|
||||||
"2": set(),
|
"2": set(),
|
||||||
"3": set(),
|
"3": set(),
|
||||||
"4": set(),
|
"4": set(),
|
||||||
@@ -310,7 +312,7 @@ def main() -> None:
|
|||||||
# Handle deleted ("ghost") users.
|
# Handle deleted ("ghost") users.
|
||||||
user = (
|
user = (
|
||||||
node["node"]["author"]["login"]
|
node["node"]["author"]["login"]
|
||||||
if node["node"]["author"] != None
|
if node["node"]["author"] is not None
|
||||||
else "ghost"
|
else "ghost"
|
||||||
)
|
)
|
||||||
# Fix CRLF line endings causing issues with detection,
|
# Fix CRLF line endings causing issues with detection,
|
||||||
@@ -2945,13 +2947,14 @@ def main() -> None:
|
|||||||
):
|
):
|
||||||
statistics["gpu"]["intel"]["unknown"].add(user)
|
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:
|
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
|
# 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).
|
# match each metric (and not who exactly).
|
||||||
def set_default(obj):
|
def set_default(obj: object) -> int:
|
||||||
if isinstance(obj, set):
|
if isinstance(obj, set):
|
||||||
return len(obj)
|
return len(obj)
|
||||||
raise TypeError
|
raise TypeError
|
||||||
|
|||||||
16
mypy.ini
Normal file
16
mypy.ini
Normal file
@@ -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
|
||||||
3
requirements.txt
Normal file
3
requirements.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
gql[all]==3.4.1
|
||||||
|
python-dotenv==1.0.0
|
||||||
|
typing_extensions==4.7.0
|
||||||
Reference in New Issue
Block a user