Skip to content

Commit

Permalink
Major update to CI workflows and dependencies (#287)
Browse files Browse the repository at this point in the history
* Remove py3.6 support, run codebase through flynt, update dependencies

* Use group.dev.dependencies instead of dev-dependencies

* Remove py3.7 support, it's EOL since 06/2023

* Install dev dependencies during CI

* Reorder workflow

* Update all the dev dependencies

* Update more dependencies, try to install dev multiple times

* Add macos-latest to CI
  • Loading branch information
gaby authored Jul 18, 2023
1 parent 07f6c5d commit cf33a11
Show file tree
Hide file tree
Showing 42 changed files with 1,192 additions and 1,211 deletions.
14 changes: 8 additions & 6 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
python-version: ["3.6", "3.7", "3.8", "3.9", "3.10", "3.11"]
os: [ubuntu-latest, windows-latest, macos-latest]
python-version: ["3.8", "3.9", "3.10", "3.11"]
fail-fast: false
steps:
- name: Checkout repo
Expand All @@ -28,12 +28,14 @@ jobs:
with:
python-version: '${{ matrix.python-version }}'

- name: Install dependencies
- name: Setup Environment
run: |
python3 -m pip install --upgrade pip setuptools
python3 -m pip install poetry
python3 -m pip install --upgrade pip setuptools poetry
poetry run python -m pip install -U pip setuptools
poetry install -E textract
- name: Install dependencies
run: |
poetry install --with dev -E textract || poetry install --with dev -E textract || echo "No dev group"
- name: Version info
run: |
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -116,3 +116,6 @@ venv.bak/

# End of https://www.gitignore.io/api/visualstudiocode
.idea

# ruff
**/.ruff_cache/
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ Some highlights include:

organize works on macOS, Windows and Linux.

Only python 3.6+ is needed.
Only python 3.8+ is needed.
Install it via your package manager or from [python.org](https://python.org).

Installation is done via pip. Note that the package name is `organize-tool`:
Expand Down
8 changes: 3 additions & 5 deletions organize/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
LOG_PATH = log_fs.getsyspath("organize.log")

# configure logging
LOGGING_CONFIG = """
LOGGING_CONFIG = f"""
version: 1
disable_existing_loggers: false
formatters:
Expand All @@ -23,7 +23,7 @@
file:
class: logging.handlers.TimedRotatingFileHandler
level: DEBUG
filename: {filename}
filename: {str(LOG_PATH)}
formatter: simple
when: midnight
backupCount: 30
Expand All @@ -32,7 +32,5 @@
handlers: [file]
exifread:
level: INFO
""".format(
filename=str(LOG_PATH)
)
"""
logging.config.dictConfig(yaml.safe_load(LOGGING_CONFIG))
10 changes: 5 additions & 5 deletions organize/actions/_conflict_resolution.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ def next_free_name(
counter = start
prev_candidate = ""
if not extension.startswith("."):
extension = ".%s" % extension
wanted = "%s%s" % (name, extension)
extension = f".{extension}"
wanted = f"{name}{extension}"
if not fs.exists(wanted):
return wanted
while True:
Expand Down Expand Up @@ -90,7 +90,7 @@ def resolve_overwrite_conflict(
return None

elif conflict_mode == "overwrite":
print("Overwrite %s." % safe_description(dst_fs, dst_path))
print(f"Overwrite {safe_description(dst_fs, dst_path)}.")
if not simulate:
if dst_fs.isdir(dst_path):
dst_fs.removedir(dst_path)
Expand All @@ -116,15 +116,15 @@ def resolve_overwrite_conflict(
extension=ext,
template=rename_template,
)
print('Renaming existing to: "%s"' % name)
print(f'Renaming existing to: "{name}"')
if not simulate:
if dst_fs.isdir(dst_path):
move_dir(dst_fs, dst_path, dst_fs, name)
elif dst_fs.isfile(dst_path):
move_file(dst_fs, dst_path, dst_fs, name)
return dst_path

raise ValueError("Unknown conflict_mode %s" % conflict_mode)
raise ValueError(f"Unknown conflict_mode {conflict_mode}")


def dst_from_options(src_path, dest, filesystem, args: dict):
Expand Down
4 changes: 2 additions & 2 deletions organize/actions/action.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class Action:
schema_support_instance_without_args = False

class Meta:
default_filesystem = "." # type: Union[FS, str]
default_filesystem = "." # type: Union[FS, str]

@classmethod
def get_name(cls):
Expand Down Expand Up @@ -70,7 +70,7 @@ def __str__(self) -> str:
return self.__class__.__name__

def __repr__(self) -> str:
return "<%s>" % str(self)
return f"<{str(self)}>"

def __eq__(self, other) -> bool:
return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
2 changes: 1 addition & 1 deletion organize/actions/confirm.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,4 @@ def pipeline(self, args: dict, simulate: bool):
raise StopIteration("Aborted")

def __str__(self) -> str:
return 'Confirm(msg="%s")' % self.msg
return f'Confirm(msg="{self.msg}")'
8 changes: 4 additions & 4 deletions organize/actions/copy.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@

from organize.utils import SimulationFS, Template, safe_description

from .action import Action
from ._conflict_resolution import CONFLICT_OPTIONS, check_conflict, dst_from_options
from .action import Action


class Copy(Action):
Expand Down Expand Up @@ -61,7 +61,7 @@ def __init__(
) -> None:
if on_conflict not in CONFLICT_OPTIONS:
raise ValueError(
"on_conflict must be one of %s" % ", ".join(CONFLICT_OPTIONS)
f"on_conflict must be one of {', '.join(CONFLICT_OPTIONS)}"
)

self.dest = Template.from_string(dest)
Expand Down Expand Up @@ -108,7 +108,7 @@ def pipeline(self, args: dict, simulate: bool):
dst_fs = SimulationFS(dst_fs)

if not skip:
self.print("Copy to %s" % safe_description(dst_fs, dst_path))
self.print(f"Copy to {safe_description(dst_fs, dst_path)}")
if not simulate:
dst_fs.makedirs(dirname(dst_path), recreate=True)
copy_action(src_fs, src_path, dst_fs, dst_path)
Expand All @@ -120,4 +120,4 @@ def pipeline(self, args: dict, simulate: bool):
}

def __str__(self) -> str:
return "Copy(dest=%s, conflict_mode=%s)" % (self.dest, self.conflict_mode)
return f"Copy(dest={self.dest}, conflict_mode={self.conflict_mode})"
2 changes: 1 addition & 1 deletion organize/actions/delete.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def pipeline(self, args: dict, simulate: bool):
fs = args["fs"] # type: FS
fs_path = args["fs_path"] # type: str
desc = safe_description(fs=fs, path=fs_path)
self.print('Deleting "%s"' % desc)
self.print(f'Deleting "{desc}"')
if not simulate:
logger.info("Deleting %s.", desc)
if fs.isdir(fs_path):
Expand Down
4 changes: 2 additions & 2 deletions organize/actions/echo.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def __init__(self, msg):

def pipeline(self, args: dict, simulate: bool) -> None:
full_msg = self.msg.render(**args)
self.print("%s" % full_msg)
self.print(f"{full_msg}")

def __str__(self) -> str:
return 'Echo(msg="%s")' % self.msg
return f'Echo(msg="{self.msg}")'
6 changes: 3 additions & 3 deletions organize/actions/macos_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@ def pipeline(self, args: dict, simulate: bool):

if color not in COLORS:
raise ValueError(
"color %s is unknown. (Available: %s)" % (color, " / ".join(COLORS))
f"color {color} is unknown. (Available: {' / '.join(COLORS)})"
)

self.print('Adding tag: "%s" (color: %s)' % (name, color))
self.print(f'Adding tag: "{name}" (color: {color})')
if not simulate:
_tag = macos_tags.Tag(
name=name,
Expand All @@ -74,4 +74,4 @@ def _parse_tag(self, s):
return result["name"], result["color"].lower()

def __str__(self) -> str:
return "MacOSTags(tags=%s)" % self.tags
return f"MacOSTags(tags={self.tags})"
8 changes: 4 additions & 4 deletions organize/actions/move.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@

from organize.utils import SimulationFS, Template, safe_description

from .action import Action
from ._conflict_resolution import CONFLICT_OPTIONS, check_conflict, dst_from_options
from .action import Action


# this is taken from my PR
Expand Down Expand Up @@ -140,7 +140,7 @@ def __init__(
) -> None:
if on_conflict not in CONFLICT_OPTIONS:
raise ValueError(
"on_conflict must be one of %s" % ", ".join(CONFLICT_OPTIONS)
f"on_conflict must be one of {', '.join(CONFLICT_OPTIONS)}"
)

self.dest = Template.from_string(dest)
Expand Down Expand Up @@ -186,7 +186,7 @@ def pipeline(self, args: dict, simulate: bool):
dst_fs = SimulationFS(dst_fs)

if not skip:
self.print("Move to %s" % safe_description(dst_fs, dst_path))
self.print(f"Move to {safe_description(dst_fs, dst_path)}")
if not simulate:
dst_fs.makedirs(dirname(dst_path), recreate=True)
move_action(src_fs, src_path, dst_fs, dst_path)
Expand All @@ -198,4 +198,4 @@ def pipeline(self, args: dict, simulate: bool):
}

def __str__(self) -> str:
return "Move(dest=%s, conflict_mode=%s)" % (self.dest, self.conflict_mode)
return f"Move(dest={self.dest}, conflict_mode={self.conflict_mode})"
15 changes: 8 additions & 7 deletions organize/actions/rename.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,12 @@

from organize.utils import Template, safe_description

from ._conflict_resolution import (
CONFLICT_OPTIONS,
check_conflict,
resolve_overwrite_conflict,
)
from .action import Action
from ._conflict_resolution import CONFLICT_OPTIONS, check_conflict, resolve_overwrite_conflict

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -53,7 +57,7 @@ def __init__(
) -> None:
if on_conflict not in CONFLICT_OPTIONS:
raise ValueError(
"on_conflict must be one of %s" % ", ".join(CONFLICT_OPTIONS)
f"on_conflict must be one of {', '.join(CONFLICT_OPTIONS)}"
)

self.new_name = Template.from_string(name)
Expand Down Expand Up @@ -95,7 +99,7 @@ def pipeline(self, args: dict, simulate: bool):
)

if not skip:
self.print("Rename to %s" % safe_description(fs, dst_path))
self.print(f"Rename to {safe_description(fs, dst_path)}")
if not simulate:
move_action(fs, src_path, fs, dst_path)

Expand All @@ -106,7 +110,4 @@ def pipeline(self, args: dict, simulate: bool):
}

def __str__(self) -> str:
return "Rename(new_name=%s, conflict_mode=%s)" % (
self.new_name,
self.conflict_mode,
)
return f"Rename(new_name={self.new_name}, conflict_mode={self.conflict_mode})"
6 changes: 3 additions & 3 deletions organize/actions/shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def pipeline(self, args: dict, simulate: bool):

if not simulate or self.run_in_simulation:
# we use call instead of run to be compatible with python < 3.5
self.print("$ %s" % full_cmd)
self.print(f"$ {full_cmd}")
logger.info('Executing command "%s" in shell.', full_cmd)
try:
call = subprocess.run(
Expand All @@ -88,7 +88,7 @@ def pipeline(self, args: dict, simulate: bool):
}
}
else:
self.print("** not run in simulation ** $ %s" % full_cmd)
self.print(f"** not run in simulation ** $ {full_cmd}")
return {
self.get_name(): {
"output": self.simulation_output.render(**args),
Expand All @@ -97,4 +97,4 @@ def pipeline(self, args: dict, simulate: bool):
}

def __str__(self) -> str:
return 'Shell(cmd="%s")' % self.cmd
return f'Shell(cmd="{self.cmd}")'
2 changes: 1 addition & 1 deletion organize/actions/symlink.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def pipeline(self, args: dict, simulate: bool):
if dest.endswith("/"):
dest = path.join(dest, path.basename(fs_path))

self.print("Creating symlink: %s" % dest)
self.print(f"Creating symlink: {dest}")
if not simulate:
os.makedirs(os.path.dirname(dest), exist_ok=True)
os.symlink(fs.getsyspath(fs_path), dest)
2 changes: 1 addition & 1 deletion organize/actions/trash.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def get_schema(cls):
def trash(self, path: str, simulate: bool):
from send2trash import send2trash

self.print('Trash "%s"' % path)
self.print(f'Trash "{path}"')
if not simulate:
logger.info("Moving file %s into trash.", path)
send2trash(path)
Expand Down
2 changes: 1 addition & 1 deletion organize/actions/write.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ def __init__(
self._is_first_write = True

if self.mode not in MODES:
raise ValueError("mode must be one of %s" % ", ".join(MODES))
raise ValueError(f"mode must be one of {', '.join(MODES)}")

def pipeline(self, args: dict, simulate: bool):
text = self.text.render(args)
Expand Down
7 changes: 4 additions & 3 deletions organize/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ def execute(
skip_tags: Optional[Tuple[str]] = None,
):
from schema import SchemaError

from . import core

config_path, config_text = read_config(config)
Expand Down Expand Up @@ -235,7 +236,7 @@ def edit(config: Optional[str], editor):
if is_syspath:
click.edit(filename=confpath, editor=editor)
else:
click.echo("Not a local config path: %s" % confpath)
click.echo(f"Not a local config path: {confpath}")


@cli.command()
Expand All @@ -253,7 +254,7 @@ def check(config: str, debug):

try:
config_path, config_str = read_config(config)
print("Checking: %s" % config_path)
print(f"Checking: {config_path}")

if debug:
out.rule("Raw", align="left")
Expand Down Expand Up @@ -327,7 +328,7 @@ def reveal(config: Optional[str], path: bool):
raise ValueError("not a local path")
webbrowser.open(dir_url)
except Exception as e:
click.echo("Cannot reveal this config (%s)" % e)
click.echo(f"Cannot reveal this config ({e})")
click.echo(confpath)


Expand Down
Loading

0 comments on commit cf33a11

Please sign in to comment.