From d6a0fbe0ccd09e8f83aebe8c94edf1ab4e2ab195 Mon Sep 17 00:00:00 2001 From: haliphax Date: Wed, 8 Nov 2023 15:18:56 -0600 Subject: [PATCH] pre-commit hooks --- .github/workflows/codeql-analysis.yml | 58 +++++------ .gitignore | 1 + .nvmrc | 1 + .pre-commit-config.yaml | 36 +++++++ .prettierignore | 1 + aethersprite/__init__.py | 1 - aethersprite/authz.py | 2 +- aethersprite/common.py | 4 - aethersprite/emotes.py | 4 +- aethersprite/extensions/base/alias.py | 6 +- aethersprite/extensions/base/greet.py | 1 - aethersprite/extensions/base/only.py | 4 +- aethersprite/extensions/base/poll.py | 3 - aethersprite/extensions/base/roles.py | 5 +- aethersprite/extensions/base/settings.py | 4 +- aethersprite/extensions/base/wipe.py | 1 - aethersprite/extensions/base/yeet.py | 7 +- aethersprite/webapp/__init__.py | 1 - package-lock.json | 119 +++++++++++++++++++++++ package.json | 12 +++ pyproject.toml | 1 + requirements/dev.in | 3 + requirements/dev.txt | 41 ++++++++ 23 files changed, 259 insertions(+), 57 deletions(-) create mode 100644 .nvmrc create mode 100644 .pre-commit-config.yaml create mode 100644 .prettierignore create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 requirements/dev.in create mode 100644 requirements/dev.txt diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 12fcb1f..47ecc11 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -13,12 +13,12 @@ name: "CodeQL" on: push: - branches: [ main ] + branches: [main] pull_request: # The branches below must be a subset of the branches above - branches: [ main ] + branches: [main] schedule: - - cron: '24 4 * * 5' + - cron: "24 4 * * 5" jobs: analyze: @@ -32,40 +32,40 @@ jobs: strategy: fail-fast: false matrix: - language: [ 'python' ] + language: ["python"] # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] # Learn more: # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed steps: - - name: Checkout repository - uses: actions/checkout@v2 + - name: Checkout repository + uses: actions/checkout@v2 - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v1 - with: - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - # queries: ./path/to/local/query, your-org/your-repo/queries@main + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main - # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v1 + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v1 - # ℹī¸ Command-line programs to run using the OS shell. - # 📚 https://git.io/JvXDl + # ℹī¸ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl - # ✏ī¸ If the Autobuild fails above, remove it and uncomment the following three lines - # and modify them (or add more) to build your code if your project - # uses a compiled language + # ✏ī¸ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language - #- run: | - # make bootstrap - # make release + #- run: | + # make bootstrap + # make release - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 diff --git a/.gitignore b/.gitignore index f303d29..19dd280 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ /config.toml /data/ /html/ +node_modules/ diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..a77793e --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +lts/hydrogen diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..c631eb1 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,36 @@ +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.0.0 + hooks: + # blocks files larger than 500 KB + - id: check-added-large-files + + # blocks files with leftover merge conflict markers + - id: check-merge-conflict + + - id: no-commit-to-branch + name: Block commits to main branch + + - repo: local + hooks: + - id: ruff + name: Lint files with ruff + args: [check, --target-version, py311, --fix, --show-fixes] + entry: ruff + language: system + types: [python] + + - id: black + name: Format files with black + args: [-t, py311] + entry: black + language: system + types: [python] + + - id: prettier + name: Format files with prettier + args: [prettier, -l, -u, -w] + entry: npx + exclude: \.py$ + language: system + types: [text] diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..d8b83df --- /dev/null +++ b/.prettierignore @@ -0,0 +1 @@ +package-lock.json diff --git a/aethersprite/__init__.py b/aethersprite/__init__.py index 130f88f..5633b21 100644 --- a/aethersprite/__init__.py +++ b/aethersprite/__init__.py @@ -1,7 +1,6 @@ """Aethersprite Discord bot/framework""" # stdlib -from asyncio import new_event_loop from importlib import import_module import logging from os import environ diff --git a/aethersprite/authz.py b/aethersprite/authz.py index 2673414..1b3c320 100644 --- a/aethersprite/authz.py +++ b/aethersprite/authz.py @@ -2,7 +2,7 @@ # stdlib from os import environ -from typing import Sequence, Union +from typing import Sequence # 3rd party from discord import DMChannel, Member, Role diff --git a/aethersprite/common.py b/aethersprite/common.py index a46dc6a..2fad1e0 100644 --- a/aethersprite/common.py +++ b/aethersprite/common.py @@ -4,15 +4,11 @@ from typing import Any # 3rd party -from discord.ext.commands import Context # stdlib from collections import namedtuple -from datetime import datetime, timezone -from functools import wraps from math import ceil, floor import re -from typing import Callable, Tuple # constants MINUTE = 60 diff --git a/aethersprite/emotes.py b/aethersprite/emotes.py index 3175009..09624c3 100644 --- a/aethersprite/emotes.py +++ b/aethersprite/emotes.py @@ -2,9 +2,9 @@ BUTTON_SUFFIX = "\ufe0f\u20e3" CHECK_MARK = "\u2705" -POLICE_OFFICER = '\U0001F46E' +POLICE_OFFICER = "\U0001F46E" PROHIBITED = "\U0001f6ab" SHADE_BLOCK = "\u2591" SOLID_BLOCK = "\u2588" -THUMBS_DOWN = '\U0001F44E' +THUMBS_DOWN = "\U0001F44E" WASTEBASKET = "\U0001f5d1" diff --git a/aethersprite/extensions/base/alias.py b/aethersprite/extensions/base/alias.py index 16d3498..4a4cbc7 100644 --- a/aethersprite/extensions/base/alias.py +++ b/aethersprite/extensions/base/alias.py @@ -56,21 +56,21 @@ async def add(self, ctx: Context, alias: str, command: str): als = aliases[guild] if alias in als: - await ctx.send(f":newspaper: Already exists.") + await ctx.send(":newspaper: Already exists.") return cmd = bot.get_command(command) if cmd is None: - await ctx.send(f":scream: No such command!") + await ctx.send(":scream: No such command!") return als[alias] = command aliases[guild] = als log.info(f"{ctx.author} added alias {alias} for {command}") - await ctx.send(f":sunglasses: Done.") + await ctx.send(":sunglasses: Done.") @command(name="alias.remove") async def remove(self, ctx: Context, alias: str): diff --git a/aethersprite/extensions/base/greet.py b/aethersprite/extensions/base/greet.py index 83b1ba2..3af14fd 100644 --- a/aethersprite/extensions/base/greet.py +++ b/aethersprite/extensions/base/greet.py @@ -10,7 +10,6 @@ # 3rd party from discord import Member -from discord.channel import TextChannel from discord.ext.commands import Bot # filters diff --git a/aethersprite/extensions/base/only.py b/aethersprite/extensions/base/only.py index 42f132f..1b161ec 100644 --- a/aethersprite/extensions/base/only.py +++ b/aethersprite/extensions/base/only.py @@ -63,7 +63,7 @@ async def add( ourchan = ours[chan_id] if command in ourchan: - await ctx.send(f":newspaper: Already done.") + await ctx.send(":newspaper: Already done.") return @@ -71,7 +71,7 @@ async def add( ours[chan_id] = ourchan onlies[guild] = ours log.info(f"{ctx.author} added {command} to {channel} whitelist") - await ctx.send(f":shield: Done.") + await ctx.send(":shield: Done.") @command(name="only.remove") async def remove( diff --git a/aethersprite/extensions/base/poll.py b/aethersprite/extensions/base/poll.py index a663c4e..8d435ba 100644 --- a/aethersprite/extensions/base/poll.py +++ b/aethersprite/extensions/base/poll.py @@ -7,11 +7,8 @@ # 3rd party from discord import Color, Embed, Message, Member -from discord.abc import GuildChannel -from discord.channel import TextChannel from discord.ext.commands import check, command, Context from discord.ext.commands.bot import Bot -from discord.guild import Guild from discord.raw_models import RawReactionActionEvent from sqlitedict import SqliteDict diff --git a/aethersprite/extensions/base/roles.py b/aethersprite/extensions/base/roles.py index d2a81d1..79e898a 100644 --- a/aethersprite/extensions/base/roles.py +++ b/aethersprite/extensions/base/roles.py @@ -3,10 +3,9 @@ # stdlib import asyncio as aio from datetime import datetime, timedelta -from typing import Optional # 3rd party -from discord import Color, Embed, Guild, Member, Message, TextChannel +from discord import Color, Embed, Message from discord.errors import NotFound from discord.ext.commands import Bot, check, command, Context from discord.raw_models import RawReactionActionEvent @@ -76,7 +75,7 @@ async def _get_message( ): roles_: list[str] = settings["roles.catalog"].get(ctx)[:10] # type: ignore embed = Embed( - title=f":billed_cap: Available roles", + title=":billed_cap: Available roles", description="Use post reactions to manage role membership", color=Color.purple(), ) diff --git a/aethersprite/extensions/base/settings.py b/aethersprite/extensions/base/settings.py index a25714d..3dd22b2 100644 --- a/aethersprite/extensions/base/settings.py +++ b/aethersprite/extensions/base/settings.py @@ -105,12 +105,12 @@ async def set( return if settings[name].set(ctx, value, channel=channel.id): - await ctx.send(f":thumbsup: Value updated.") + await ctx.send(":thumbsup: Value updated.") log.info( f"{ctx.author} updated setting {name}: {value} in {channel}" ) else: - await ctx.send(f":thumbsdown: Error updating value.") + await ctx.send(":thumbsdown: Error updating value.") log.warn( f"{ctx.author} failed to update setting {name}: {value} " f"in {channel}" diff --git a/aethersprite/extensions/base/wipe.py b/aethersprite/extensions/base/wipe.py index af4dc31..baea07a 100644 --- a/aethersprite/extensions/base/wipe.py +++ b/aethersprite/extensions/base/wipe.py @@ -9,7 +9,6 @@ # than x days old on a schedule # typing -from typing import Optional # 3rd party from discord.ext.commands import Bot, check, command, Context diff --git a/aethersprite/extensions/base/yeet.py b/aethersprite/extensions/base/yeet.py index 79df61e..8e6130f 100644 --- a/aethersprite/extensions/base/yeet.py +++ b/aethersprite/extensions/base/yeet.py @@ -1,7 +1,6 @@ """Yeet cog""" # stdlib -import typing # 3rd party from discord import DMChannel, TextChannel @@ -53,13 +52,13 @@ async def add( key = f"{server_key}#{channel.id}" guild = str(ctx.guild.id) - if not ctx.guild.id in yeets: + if ctx.guild.id not in yeets: yeets[guild] = set([]) ys = yeets[guild] if (key in ys and not server) or (server_key in ys and server): - await ctx.send(f":newspaper: Already done.") + await ctx.send(":newspaper: Already done.") return @@ -75,7 +74,7 @@ async def add( log.info( f"{ctx.author} yeeted {server_key if server else key} in {ctx.channel}" ) - await ctx.send(f":boom: Yeet!") + await ctx.send(":boom: Yeet!") @command(name="unyeet") async def remove( diff --git a/aethersprite/webapp/__init__.py b/aethersprite/webapp/__init__.py index 6e6dc06..a6ce2a7 100644 --- a/aethersprite/webapp/__init__.py +++ b/aethersprite/webapp/__init__.py @@ -2,7 +2,6 @@ # stdlib from importlib import import_module -from inspect import ismodule # 3rd party from flask import Flask diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..8770005 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,119 @@ +{ + "name": "aethersprite", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "devDependencies": { + "prettier": "^3.0.3", + "prettier-plugin-toml": "^1.0.0" + } + }, + "node_modules/@chevrotain/cst-dts-gen": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/cst-dts-gen/-/cst-dts-gen-11.0.3.tgz", + "integrity": "sha512-BvIKpRLeS/8UbfxXxgC33xOumsacaeCKAjAeLyOn7Pcp95HiRbrpl14S+9vaZLolnbssPIUuiUd8IvgkRyt6NQ==", + "dev": true, + "dependencies": { + "@chevrotain/gast": "11.0.3", + "@chevrotain/types": "11.0.3", + "lodash-es": "4.17.21" + } + }, + "node_modules/@chevrotain/gast": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/gast/-/gast-11.0.3.tgz", + "integrity": "sha512-+qNfcoNk70PyS/uxmj3li5NiECO+2YKZZQMbmjTqRI3Qchu8Hig/Q9vgkHpI3alNjr7M+a2St5pw5w5F6NL5/Q==", + "dev": true, + "dependencies": { + "@chevrotain/types": "11.0.3", + "lodash-es": "4.17.21" + } + }, + "node_modules/@chevrotain/regexp-to-ast": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/regexp-to-ast/-/regexp-to-ast-11.0.3.tgz", + "integrity": "sha512-1fMHaBZxLFvWI067AVbGJav1eRY7N8DDvYCTwGBiE/ytKBgP8azTdgyrKyWZ9Mfh09eHWb5PgTSO8wi7U824RA==", + "dev": true + }, + "node_modules/@chevrotain/types": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/types/-/types-11.0.3.tgz", + "integrity": "sha512-gsiM3G8b58kZC2HaWR50gu6Y1440cHiJ+i3JUvcp/35JchYejb2+5MVeJK0iKThYpAa/P2PYFV4hoi44HD+aHQ==", + "dev": true + }, + "node_modules/@chevrotain/utils": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/utils/-/utils-11.0.3.tgz", + "integrity": "sha512-YslZMgtJUyuMbZ+aKvfF3x1f5liK4mWNxghFRv7jqRR9C3R3fAOGTTKvxXDa2Y1s9zSbcpuO0cAxDYsc9SrXoQ==", + "dev": true + }, + "node_modules/@toml-tools/lexer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@toml-tools/lexer/-/lexer-1.0.0.tgz", + "integrity": "sha512-rVoOC9FibF2CICwCBWQnYcjAEOmLCJExer178K2AsY0Nk9FjJNVoVJuR5UAtuq42BZOajvH+ainf6Gj2GpCnXQ==", + "dev": true, + "dependencies": { + "chevrotain": "^11.0.1" + } + }, + "node_modules/@toml-tools/parser": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@toml-tools/parser/-/parser-1.0.0.tgz", + "integrity": "sha512-j8cd3A3ccLHppGoWI69urbiVJslrpwI6sZ61ySDUPxM/FTkQWRx/JkkF8aipnl0Ds0feWXyjyvmWzn70mIohYg==", + "dev": true, + "dependencies": { + "@toml-tools/lexer": "^1.0.0", + "chevrotain": "^11.0.1" + } + }, + "node_modules/chevrotain": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-11.0.3.tgz", + "integrity": "sha512-ci2iJH6LeIkvP9eJW6gpueU8cnZhv85ELY8w8WiFtNjMHA5ad6pQLaJo9mEly/9qUyCpvqX8/POVUTf18/HFdw==", + "dev": true, + "dependencies": { + "@chevrotain/cst-dts-gen": "11.0.3", + "@chevrotain/gast": "11.0.3", + "@chevrotain/regexp-to-ast": "11.0.3", + "@chevrotain/types": "11.0.3", + "@chevrotain/utils": "11.0.3", + "lodash-es": "4.17.21" + } + }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", + "dev": true + }, + "node_modules/prettier": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.3.tgz", + "integrity": "sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==", + "dev": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-plugin-toml": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-plugin-toml/-/prettier-plugin-toml-1.0.0.tgz", + "integrity": "sha512-YMn4Fqy/ANHommZh61s5qqtpfcgPB00Ty890bFPr73B0HAy77zgyH89SvAK+NyPPx3AdM56a4Yo66LH9GPnuZw==", + "dev": true, + "dependencies": { + "@toml-tools/lexer": "^1.0.0", + "@toml-tools/parser": "^1.0.0" + }, + "peerDependencies": { + "prettier": "^3.0.0" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..adc73bf --- /dev/null +++ b/package.json @@ -0,0 +1,12 @@ +{ + "devDependencies": { + "prettier": "^3.0.3", + "prettier-plugin-toml": "^1.0.0" + }, + "prettier": { + "plugins": [ + "prettier", + "prettier-plugin-toml" + ] + } +} diff --git a/pyproject.toml b/pyproject.toml index fb4eee4..4f91421 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,6 +15,7 @@ packages = ["aethersprite"] dependencies = { file = "requirements/requirements.txt" } [tool.setuptools.dynamic.optional-dependencies] +dev = { file = "requirements/dev.txt" } docs = { file = "requirements/docs.txt" } [tool.black] diff --git a/requirements/dev.in b/requirements/dev.in new file mode 100644 index 0000000..316163d --- /dev/null +++ b/requirements/dev.in @@ -0,0 +1,3 @@ +black +pre-commit +ruff diff --git a/requirements/dev.txt b/requirements/dev.txt new file mode 100644 index 0000000..0d55e5b --- /dev/null +++ b/requirements/dev.txt @@ -0,0 +1,41 @@ +# +# This file is autogenerated by pip-compile with Python 3.11 +# by the following command: +# +# pip-compile dev.in +# +black==23.11.0 + # via -r dev.in +cfgv==3.4.0 + # via pre-commit +click==8.1.7 + # via black +distlib==0.3.7 + # via virtualenv +filelock==3.13.1 + # via virtualenv +identify==2.5.31 + # via pre-commit +mypy-extensions==1.0.0 + # via black +nodeenv==1.8.0 + # via pre-commit +packaging==23.2 + # via black +pathspec==0.11.2 + # via black +platformdirs==3.11.0 + # via + # black + # virtualenv +pre-commit==3.5.0 + # via -r dev.in +pyyaml==6.0.1 + # via pre-commit +ruff==0.1.4 + # via -r dev.in +virtualenv==20.24.6 + # via pre-commit + +# The following packages are considered to be unsafe in a requirements file: +# setuptools