Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/docs_branch_update.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
docs_rebuild:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: set up development environment
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 0
- run: python3 -m pip install --upgrade build && python3 -m build
Expand Down
12 changes: 6 additions & 6 deletions .github/workflows/pull_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python 3.12
- uses: actions/checkout@v4
- name: Set up Python 3.13
uses: actions/setup-python@v3
with:
python-version: '3.12'
python-version: '3.13'
- name: Install linters
run: |
python -m pip install --upgrade pip
Expand All @@ -26,12 +26,12 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
py: ['3.10', '3.11', '3.12']
py: ['3.10', '3.11', '3.12', '3.13']
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v3
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.py }}
- name: Configure SSH
Expand Down
12 changes: 6 additions & 6 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
repos:
- repo: https://github.com/psf/black
rev: 24.4.2
rev: 25.1.0
hooks:
- id: black
- repo: https://github.com/pycqa/isort
rev: 5.13.2
rev: 6.0.1
hooks:
- id: isort
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.10.0
rev: v1.17.0
hooks:
- id: mypy
additional_dependencies: [types-paramiko]
- repo: https://github.com/nbQA-dev/nbQA
rev: 1.8.5
rev: 1.9.1
hooks:
- id: nbqa-isort
- id: nbqa-mypy
args: [--ignore-missing-imports]
- repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks
rev: v2.13.0
rev: v2.15.0
hooks:
- id: pretty-format-ini
args: [--autofix]
files: ^.*\.(cfg|CFG|ini|INI)$
- id: pretty-format-yaml
args: [--autofix]
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
rev: v5.0.0
hooks:
- id: check-json
- id: pretty-format-json
Expand Down
6 changes: 3 additions & 3 deletions enderchest/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import re
import subprocess
import sys
from typing import Callable, Dict
from collections.abc import Callable


def get_keywords():
Expand Down Expand Up @@ -54,8 +54,8 @@ class NotThisMethod(Exception):
"""Exception raised if a method is not valid for the current scenario."""


LONG_VERSION_PY: Dict[str, str] = {}
HANDLERS: Dict[str, Dict[str, Callable]] = {}
LONG_VERSION_PY: dict[str, str] = {}
HANDLERS: dict[str, dict[str, Callable]] = {}


def register_vcs_handler(vcs, method): # decorator
Expand Down
7 changes: 4 additions & 3 deletions enderchest/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
import os
import sys
from argparse import ArgumentParser, RawTextHelpFormatter
from collections.abc import Iterable, Sequence
from pathlib import Path
from typing import Any, Iterable, Protocol, Sequence
from typing import Any, Protocol

from . import craft, gather, inventory, loggers, place, remote, uninstall
from ._version import get_versions
Expand Down Expand Up @@ -793,11 +794,11 @@ def parse_args(argv: Sequence[str]) -> tuple[Action, Path, int, dict[str, Any]]:

log_level = loggers.verbosity_to_log_level(verbosity)

MINECRAFT_ROOT = os.getenv("MINECRAFT_ROOT")
env_root = os.getenv("MINECRAFT_ROOT")

return (
actions[aliases[command]],
Path(root_arg or root_flag or MINECRAFT_ROOT or os.getcwd()),
Path(root_arg or root_flag or env_root or os.getcwd()),
log_level,
action_kwargs,
)
Expand Down
3 changes: 2 additions & 1 deletion enderchest/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@

import ast
import datetime as dt
from collections.abc import Iterable, Mapping, Sequence
from configparser import ConfigParser, ParsingError
from io import StringIO
from pathlib import Path
from typing import Any, Iterable, Mapping, Sequence
from typing import Any

from ._version import get_versions

Expand Down
50 changes: 25 additions & 25 deletions enderchest/craft.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import logging
import re
from collections import Counter
from collections.abc import Callable, Iterable, Sequence
from pathlib import Path
from typing import Callable, Iterable, Sequence
from urllib.parse import ParseResult

from pathvalidate import is_valid_filename
Expand Down Expand Up @@ -70,7 +70,7 @@ def craft_ender_chest(
passing in, say "/"
"""
if not minecraft_root.exists():
CRAFT_LOGGER.error(f"The directory {minecraft_root} does not exist")
CRAFT_LOGGER.error("The directory %s does not exist", minecraft_root)
CRAFT_LOGGER.error("Aborting")
return
if (
Expand All @@ -89,12 +89,13 @@ def craft_ender_chest(
try:
fs.ender_chest_config(minecraft_root, check_exists=True)
exist_message = (
f"There is already an EnderChest installed to {minecraft_root}"
"There is already an EnderChest installed to %s",
minecraft_root,
)
if overwrite:
CRAFT_LOGGER.warning(exist_message)
CRAFT_LOGGER.warning(*exist_message)
else:
CRAFT_LOGGER.error(exist_message)
CRAFT_LOGGER.error(*exist_message)
CRAFT_LOGGER.error("Aborting")
return
except FileNotFoundError:
Expand All @@ -116,7 +117,7 @@ def craft_ender_chest(
ender_chest.register_remote(remote, alias)
except (RuntimeError, ValueError) as fetch_fail:
CRAFT_LOGGER.error(
f"Could not fetch remotes from {copy_from}:\n {fetch_fail}"
"Could not fetch remotes from %s:\n %s", copy_from, fetch_fail
)
CRAFT_LOGGER.error("Aborting.")
return
Expand Down Expand Up @@ -182,7 +183,7 @@ def craft_shulker_box(
to ensure that they are valid or actively in use
"""
if not is_valid_filename(name):
CRAFT_LOGGER.error(f"{name} is not a valid name: must be usable as a filename")
CRAFT_LOGGER.error("%s is not a valid name: must be usable as a filename", name)
return

try:
Expand All @@ -205,13 +206,14 @@ def craft_shulker_box(
config_path = fs.shulker_box_config(minecraft_root, name)
if config_path.exists():
exist_message = (
f"There is already a shulker box named {name}"
f" in {fs.ender_chest_folder(minecraft_root)}"
"There is already a shulker box named %s in %s",
name,
fs.ender_chest_folder(minecraft_root),
)
if overwrite:
CRAFT_LOGGER.warning(exist_message)
CRAFT_LOGGER.warning(*exist_message)
else:
CRAFT_LOGGER.error(exist_message)
CRAFT_LOGGER.error(*exist_message)
CRAFT_LOGGER.error("Aborting")
return
match_criteria: list[tuple[str, tuple[str, ...]]] = []
Expand Down Expand Up @@ -252,14 +254,14 @@ def specify_ender_chest_from_prompt(minecraft_root: Path) -> EnderChest:
try:
root = fs.ender_chest_folder(minecraft_root)
CRAFT_LOGGER.info(
f"This will overwrite the EnderChest configuration at {root}."
"This will overwrite the EnderChest configuration at %s.", root
)
if not confirm(default=False):
message = f"Aborting: {fs.ender_chest_config(minecraft_root)} exists."
raise FileExistsError(message)
except FileNotFoundError:
# good! Then we don't already have an EnderChest here
CRAFT_LOGGER.debug(f"{minecraft_root} does not already contain an EnderChest")
CRAFT_LOGGER.debug("%s does not already contain an EnderChest", minecraft_root)

instances: list[InstanceSpec] = []

Expand Down Expand Up @@ -322,7 +324,7 @@ def specify_ender_chest_from_prompt(minecraft_root: Path) -> EnderChest:
remotes.extend(fetch_remotes_from_a_remote_ender_chest(remote_uri))
except Exception as fetch_fail:
CRAFT_LOGGER.error(
f"Could not fetch remotes from {remote_uri}\n {fetch_fail}"
"Could not fetch remotes from %s\n %s", remote_uri, fetch_fail
)
if not confirm(default=True):
continue
Expand Down Expand Up @@ -383,7 +385,7 @@ def specify_ender_chest_from_prompt(minecraft_root: Path) -> EnderChest:
)
if name in (alias for _, alias in remotes):
CRAFT_LOGGER.error(
f"The name {name} is already in use. Choose a different name."
"The name %s is already in use. Choose a different name.", name
)
continue
break
Expand Down Expand Up @@ -425,7 +427,7 @@ def specify_shulker_box_from_prompt(minecraft_root: Path, name: str) -> ShulkerB
f"A file named {name} already exists in your EnderChest folder."
)
CRAFT_LOGGER.warning(
f"There is already a folder named {name} in your EnderChest folder."
"There is already a folder named %s in your EnderChest folder.", name
)
if not confirm(default=False):
raise FileExistsError(
Expand Down Expand Up @@ -850,8 +852,7 @@ def _prompt_for_instance_numbers(
if selections == "":
if exclude:
return shulker_box
else:
selections = "*"
selections = "*"

if re.search("[^0-9-,* ]", selections): # check for invalid characters
CRAFT_LOGGER.error("Invalid selection.\n")
Expand All @@ -869,7 +870,7 @@ def _prompt_for_instance_numbers(
# luckily we don't need to worry about negative numbers
index = int(value) - 1
if index < 0 or index >= len(instances):
CRAFT_LOGGER.error(f"Invalid selection: {entry} is out of range\n")
CRAFT_LOGGER.error("Invalid selection: %s is out of range\n", entry)
return _prompt_for_instance_numbers(
shulker_box, instance_loader(), instance_loader, exclude=exclude
)
Expand All @@ -878,21 +879,21 @@ def _prompt_for_instance_numbers(
bounds = tuple(int(bound) for bound in match.groups())
if bounds[0] > bounds[1]:
CRAFT_LOGGER.error(
f"Invalid selection: {entry} is not a valid range\n"
"Invalid selection: %s is not a valid range\n", entry
)
return _prompt_for_instance_numbers(
shulker_box, instance_loader(), instance_loader, exclude=exclude
)
if max(bounds) > len(instances) or min(bounds) < 1:
CRAFT_LOGGER.error(f"Invalid selection: {entry} is out of range\n")
CRAFT_LOGGER.error("Invalid selection: %s is out of range\n", entry)
return _prompt_for_instance_numbers(
shulker_box, instance_loader(), instance_loader, exclude=exclude
)
selected_instances.update(
instance.name for instance in instances[bounds[0] - 1 : bounds[1]]
)
case _:
CRAFT_LOGGER.error(f"Invalid selection.\n")
CRAFT_LOGGER.error("Invalid selection.\n")
return _prompt_for_instance_numbers(
shulker_box, instance_loader(), instance_loader, exclude=exclude
)
Expand All @@ -904,9 +905,8 @@ def _prompt_for_instance_numbers(
return shulker_box

CRAFT_LOGGER.info(
"You selected to {} the instances:\n%s".format(
"explicitly exclude" if exclude else "include"
),
"You selected to %s the instances:\n%s",
"explicitly exclude" if exclude else "include",
"\n".join([f" - {name}" for name in choices]),
)
if not confirm(default=True):
Expand Down
15 changes: 8 additions & 7 deletions enderchest/enderchest.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
"""Specification and configuration of an EnderChest"""

from collections.abc import Iterable
from dataclasses import dataclass
from pathlib import Path
from socket import gethostname
from typing import Any, Iterable
from typing import Any
from urllib.parse import ParseResult, urlparse

from . import config as cfg
Expand Down Expand Up @@ -227,7 +228,7 @@ def register_instance(self, instance: i.InstanceSpec) -> i.InstanceSpec:
counter += 1
name = f"{instance.name}.{counter}"

GATHER_LOGGER.debug(f"Registering instance {name} at {instance.root}")
GATHER_LOGGER.debug("Registering instance %s at %s", name, instance.root)
self._instances.append(instance._replace(name=name))
return self._instances[-1]

Expand Down Expand Up @@ -319,13 +320,13 @@ def from_cfg(cls, config_file: Path) -> "EnderChest":
offer_to_update_symlink_allowlist = config[section].getboolean(
"offer-to-update-symlink-allowlist", True
)
if "do-not-sync" in config[section].keys():
if "do-not-sync" in config[section]:
do_not_sync = cfg.parse_ini_list(
config[section]["do-not-sync"] or ""
)
for setting in folder_defaults.keys():
for setting in folder_defaults:
setting_key = setting.replace("_", "-")
if setting_key in config[section].keys():
if setting_key in config[section]:
folder_defaults[setting] = cfg.parse_ini_list(
config[section][setting_key] or ""
)
Expand Down Expand Up @@ -388,7 +389,7 @@ def from_cfg(cls, config_file: Path) -> "EnderChest":
)
ender_chest.do_not_sync.insert(0, chest_cfg_exclusion)
requires_rewrite = True
for setting in folder_defaults.keys():
for setting in folder_defaults:
if folder_defaults[setting] is None:
folder_defaults[setting] = dict(_DEFAULTS)[setting] # type: ignore
# requires_rewrite = True # though I'm considering it
Expand Down Expand Up @@ -480,4 +481,4 @@ def create_ender_chest(minecraft_root: Path, ender_chest: EnderChest) -> None:

config_path = fs.ender_chest_config(minecraft_root, check_exists=False)
ender_chest.write_to_cfg(config_path)
CRAFT_LOGGER.info(f"EnderChest configuration written to {config_path}")
CRAFT_LOGGER.info("EnderChest configuration written to %s", config_path)
Loading
Loading