dycw-actions 0.3.2__py3-none-any.whl → 0.7.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. actions/__init__.py +1 -1
  2. actions/action_dicts/constants.py +8 -0
  3. actions/action_dicts/lib.py +186 -0
  4. actions/clean_dir/cli.py +21 -0
  5. actions/clean_dir/constants.py +7 -0
  6. actions/clean_dir/lib.py +59 -0
  7. actions/clean_dir/settings.py +18 -0
  8. actions/cli.py +95 -6
  9. actions/constants.py +10 -0
  10. actions/pre_commit/click.py +15 -0
  11. actions/pre_commit/conformalize_repo/__init__.py +1 -0
  12. actions/pre_commit/conformalize_repo/cli.py +64 -0
  13. actions/pre_commit/conformalize_repo/configs/gitignore +244 -0
  14. actions/pre_commit/conformalize_repo/constants.py +78 -0
  15. actions/pre_commit/conformalize_repo/lib.py +1293 -0
  16. actions/pre_commit/conformalize_repo/settings.py +119 -0
  17. actions/pre_commit/constants.py +8 -0
  18. actions/pre_commit/format_requirements/__init__.py +1 -0
  19. actions/pre_commit/format_requirements/cli.py +24 -0
  20. actions/pre_commit/format_requirements/constants.py +7 -0
  21. actions/pre_commit/format_requirements/lib.py +52 -0
  22. actions/pre_commit/replace_sequence_strs/__init__.py +1 -0
  23. actions/pre_commit/replace_sequence_strs/cli.py +24 -0
  24. actions/pre_commit/replace_sequence_strs/constants.py +7 -0
  25. actions/pre_commit/replace_sequence_strs/lib.py +73 -0
  26. actions/pre_commit/touch_empty_py/__init__.py +1 -0
  27. actions/pre_commit/touch_empty_py/cli.py +24 -0
  28. actions/pre_commit/touch_empty_py/constants.py +7 -0
  29. actions/pre_commit/touch_empty_py/lib.py +54 -0
  30. actions/pre_commit/touch_py_typed/__init__.py +1 -0
  31. actions/pre_commit/touch_py_typed/cli.py +24 -0
  32. actions/pre_commit/touch_py_typed/constants.py +7 -0
  33. actions/pre_commit/touch_py_typed/lib.py +64 -0
  34. actions/pre_commit/update_requirements/__init__.py +1 -0
  35. actions/pre_commit/update_requirements/classes.py +117 -0
  36. actions/pre_commit/update_requirements/cli.py +24 -0
  37. actions/pre_commit/update_requirements/constants.py +7 -0
  38. actions/pre_commit/update_requirements/lib.py +128 -0
  39. actions/pre_commit/utilities.py +386 -0
  40. actions/publish_package/__init__.py +1 -0
  41. actions/publish_package/cli.py +27 -0
  42. actions/publish_package/constants.py +7 -0
  43. actions/{publish → publish_package}/lib.py +18 -17
  44. actions/{publish → publish_package}/settings.py +7 -7
  45. actions/py.typed +0 -0
  46. actions/random_sleep/__init__.py +1 -0
  47. actions/random_sleep/cli.py +26 -0
  48. actions/random_sleep/constants.py +7 -0
  49. actions/{sleep → random_sleep}/lib.py +14 -13
  50. actions/{sleep → random_sleep}/settings.py +3 -3
  51. actions/run_hooks/__init__.py +1 -0
  52. actions/run_hooks/cli.py +21 -0
  53. actions/run_hooks/constants.py +7 -0
  54. actions/run_hooks/lib.py +97 -0
  55. actions/run_hooks/settings.py +24 -0
  56. actions/setup_cronjob/__init__.py +1 -0
  57. actions/setup_cronjob/cli.py +31 -0
  58. actions/setup_cronjob/configs/cron.tmpl +3 -0
  59. actions/setup_cronjob/configs/logrotate.tmpl +10 -0
  60. actions/setup_cronjob/constants.py +12 -0
  61. actions/setup_cronjob/lib.py +120 -0
  62. actions/setup_cronjob/settings.py +27 -0
  63. actions/tag_commit/__init__.py +1 -0
  64. actions/tag_commit/cli.py +27 -0
  65. actions/tag_commit/constants.py +7 -0
  66. actions/tag_commit/lib.py +63 -0
  67. actions/{tag → tag_commit}/settings.py +3 -3
  68. actions/types.py +14 -1
  69. actions/utilities.py +131 -17
  70. dycw_actions-0.7.1.dist-info/METADATA +22 -0
  71. dycw_actions-0.7.1.dist-info/RECORD +77 -0
  72. {dycw_actions-0.3.2.dist-info → dycw_actions-0.7.1.dist-info}/WHEEL +1 -1
  73. actions/publish/cli.py +0 -43
  74. actions/settings.py +0 -18
  75. actions/sleep/cli.py +0 -39
  76. actions/tag/cli.py +0 -43
  77. actions/tag/lib.py +0 -62
  78. dycw_actions-0.3.2.dist-info/METADATA +0 -14
  79. dycw_actions-0.3.2.dist-info/RECORD +0 -22
  80. /actions/{publish → action_dicts}/__init__.py +0 -0
  81. /actions/{sleep → clean_dir}/__init__.py +0 -0
  82. /actions/{tag → pre_commit}/__init__.py +0 -0
  83. {dycw_actions-0.3.2.dist-info → dycw_actions-0.7.1.dist-info}/entry_points.txt +0 -0
@@ -4,29 +4,30 @@ from math import ceil, floor
4
4
  from random import choice
5
5
  from time import sleep
6
6
 
7
+ from utilities.text import strip_and_dedent
7
8
  from utilities.whenever import get_now
8
9
  from whenever import TimeDelta, ZonedDateTime
9
10
 
10
11
  from actions import __version__
11
12
  from actions.logging import LOGGER
12
- from actions.sleep.settings import SLEEP_SETTINGS
13
+ from actions.random_sleep.settings import SETTINGS
13
14
 
14
15
 
15
16
  def random_sleep(
16
17
  *,
17
- min_: int = SLEEP_SETTINGS.min,
18
- max_: int = SLEEP_SETTINGS.max,
19
- step: int = SLEEP_SETTINGS.step,
20
- log_freq: int = SLEEP_SETTINGS.log_freq,
18
+ min_: int = SETTINGS.min,
19
+ max_: int = SETTINGS.max,
20
+ step: int = SETTINGS.step,
21
+ log_freq: int = SETTINGS.log_freq,
21
22
  ) -> None:
22
23
  LOGGER.info(
23
- """\
24
- Running %r (version %s) with settings:
25
- - min_ = %s
26
- - max_ = %s
27
- - step = %s
28
- - log_freq = %s
29
- """,
24
+ strip_and_dedent("""
25
+ Running '%s' (version %s) with settings:
26
+ - min_ = %s
27
+ - max_ = %s
28
+ - step = %s
29
+ - log_freq = %s
30
+ """),
30
31
  random_sleep.__name__,
31
32
  __version__,
32
33
  min_,
@@ -49,7 +50,7 @@ def _intermediate(
49
50
  end: ZonedDateTime,
50
51
  /,
51
52
  *,
52
- log_freq: int = SLEEP_SETTINGS.log_freq,
53
+ log_freq: int = SETTINGS.log_freq,
53
54
  ) -> None:
54
55
  elapsed = TimeDelta(seconds=floor((now - start).in_seconds()))
55
56
  remaining = TimeDelta(seconds=ceil((end - now).in_seconds()))
@@ -6,14 +6,14 @@ from actions.utilities import LOADER
6
6
 
7
7
 
8
8
  @settings
9
- class SleepSettings:
9
+ class Settings:
10
10
  min: int = option(default=0, help="Minimum duration, in seconds")
11
11
  max: int = option(default=3600, help="Maximum duration, in seconds")
12
12
  step: int = option(default=1, help="Step duration, in seconds")
13
13
  log_freq: int = option(default=60, help="Log frequency, in seconds")
14
14
 
15
15
 
16
- SLEEP_SETTINGS = load_settings(SleepSettings, [LOADER])
16
+ SETTINGS = load_settings(Settings, [LOADER])
17
17
 
18
18
 
19
- __all__ = ["SLEEP_SETTINGS", "SleepSettings"]
19
+ __all__ = ["SETTINGS", "Settings"]
@@ -0,0 +1 @@
1
+ from __future__ import annotations
@@ -0,0 +1,21 @@
1
+ from __future__ import annotations
2
+
3
+ from typed_settings import click_options
4
+ from utilities.logging import basic_config
5
+ from utilities.os import is_pytest
6
+
7
+ from actions.logging import LOGGER
8
+ from actions.run_hooks.lib import run_hooks
9
+ from actions.run_hooks.settings import Settings
10
+ from actions.utilities import LOADER
11
+
12
+
13
+ @click_options(Settings, [LOADER], show_envvars_in_help=True)
14
+ def run_hooks_sub_cmd(settings: Settings, /) -> None:
15
+ if is_pytest():
16
+ return
17
+ basic_config(obj=LOGGER)
18
+ run_hooks(repos=settings.repos, hooks=settings.hooks, sleep=settings.sleep)
19
+
20
+
21
+ __all__ = ["run_hooks_sub_cmd"]
@@ -0,0 +1,7 @@
1
+ from __future__ import annotations
2
+
3
+ RUN_HOOKS_DOCSTRING = "Run 'pre-commit' hooks"
4
+ RUN_HOOKS_SUB_CMD = "run-hooks"
5
+
6
+
7
+ __all__ = ["RUN_HOOKS_DOCSTRING", "RUN_HOOKS_SUB_CMD"]
@@ -0,0 +1,97 @@
1
+ from __future__ import annotations
2
+
3
+ import time
4
+ from pathlib import Path
5
+ from re import search
6
+ from subprocess import CalledProcessError
7
+ from typing import TYPE_CHECKING, Any
8
+
9
+ from utilities.functions import ensure_class, ensure_str
10
+ from utilities.text import strip_and_dedent
11
+ from whenever import TimeDelta
12
+ from yaml import safe_load
13
+
14
+ from actions import __version__
15
+ from actions.logging import LOGGER
16
+ from actions.run_hooks.settings import SETTINGS
17
+ from actions.utilities import logged_run
18
+
19
+ if TYPE_CHECKING:
20
+ from collections.abc import Iterator
21
+
22
+
23
+ def run_hooks(
24
+ *,
25
+ repos: list[str] | None = SETTINGS.repos,
26
+ hooks: list[str] | None = SETTINGS.hooks,
27
+ sleep: int = SETTINGS.sleep,
28
+ ) -> None:
29
+ LOGGER.info(
30
+ strip_and_dedent("""
31
+ Running '%s' (version %s) with settings:
32
+ - repos = %s
33
+ - hooks = %s
34
+ - sleep = %d
35
+ """),
36
+ run_hooks.__name__,
37
+ __version__,
38
+ repos,
39
+ hooks,
40
+ sleep,
41
+ )
42
+ results = {
43
+ hook: _run_hook(hook, sleep=sleep)
44
+ for hook in _yield_hooks(repos=repos, hooks=hooks)
45
+ }
46
+ failed = {hook: result for hook, result in results.items() if not result}
47
+ if len(failed) >= 1:
48
+ msg = f"Failed hook(s): {', '.join(failed)}"
49
+ raise RuntimeError(msg)
50
+
51
+
52
+ def _yield_hooks(
53
+ *,
54
+ repos: list[str] | None = SETTINGS.repos,
55
+ hooks: list[str] | None = SETTINGS.hooks,
56
+ ) -> Iterator[str]:
57
+ dict_ = safe_load(Path(".pre-commit-config.yaml").read_text())
58
+ repos_list = ensure_class(dict_["repos"], list)
59
+ results: set[str] = set()
60
+ for repo in (ensure_class(r, dict) for r in repos_list):
61
+ url = repo["repo"]
62
+ if (repos is not None) and any(search(repo_i, url) for repo_i in repos):
63
+ results.update(_yield_repo_hooks(repo))
64
+ elif hooks is not None:
65
+ for hook in _yield_repo_hooks(repo):
66
+ if any(search(hook_i, hook) for hook_i in hooks):
67
+ results.add(hook)
68
+ yield from sorted(results)
69
+
70
+
71
+ def _yield_repo_hooks(repo: dict[str, Any], /) -> Iterator[str]:
72
+ hooks = ensure_class(repo["hooks"], list)
73
+ for hook in (ensure_class(r, dict) for r in hooks):
74
+ yield ensure_str(hook["id"])
75
+
76
+
77
+ def _run_hook(hook: str, /, *, sleep: int = SETTINGS.sleep) -> bool:
78
+ LOGGER.info("Running '%s'...", hook)
79
+ try:
80
+ logged_run("pre-commit", "run", "--verbose", "--all-files", hook, print=True)
81
+ except CalledProcessError:
82
+ is_success = False
83
+ else:
84
+ is_success = True
85
+ delta = TimeDelta(seconds=sleep)
86
+ LOGGER.info(
87
+ "Hook '%s' %s; sleeping for %s...",
88
+ hook,
89
+ "succeeded" if is_success else "failed",
90
+ delta,
91
+ )
92
+ time.sleep(sleep)
93
+ LOGGER.info("Finished sleeping for %s", delta)
94
+ return is_success
95
+
96
+
97
+ __all__ = ["run_hooks"]
@@ -0,0 +1,24 @@
1
+ from __future__ import annotations
2
+
3
+ from typed_settings import load_settings, option, settings
4
+
5
+ from actions.utilities import LOADER, convert_list_strs
6
+
7
+
8
+ @settings
9
+ class Settings:
10
+ repos: list[str] | None = option(
11
+ default=None,
12
+ converter=convert_list_strs,
13
+ help="The repos whose hooks are to be run",
14
+ )
15
+ hooks: list[str] | None = option(
16
+ default=None, converter=convert_list_strs, help="The hooks to be run"
17
+ )
18
+ sleep: int = option(default=1, help="Sleep in between runs")
19
+
20
+
21
+ SETTINGS = load_settings(Settings, [LOADER])
22
+
23
+
24
+ __all__ = ["SETTINGS", "Settings"]
@@ -0,0 +1 @@
1
+ from __future__ import annotations
@@ -0,0 +1,31 @@
1
+ from __future__ import annotations
2
+
3
+ from typed_settings import click_options
4
+ from utilities.logging import basic_config
5
+ from utilities.os import is_pytest
6
+
7
+ from actions.logging import LOGGER
8
+ from actions.setup_cronjob.lib import setup_cronjob
9
+ from actions.setup_cronjob.settings import Settings
10
+ from actions.utilities import LOADER
11
+
12
+
13
+ @click_options(Settings, [LOADER], show_envvars_in_help=True)
14
+ def setup_cronjob_sub_cmd(settings: Settings, /) -> None:
15
+ if is_pytest():
16
+ return
17
+ basic_config(obj=LOGGER)
18
+ setup_cronjob(
19
+ name=settings.name,
20
+ prepend_path=settings.prepend_path,
21
+ schedule=settings.schedule,
22
+ user=settings.user,
23
+ timeout=settings.timeout,
24
+ kill_after=settings.kill_after,
25
+ command=settings.command,
26
+ args=settings.args,
27
+ logs_keep=settings.logs_keep,
28
+ )
29
+
30
+
31
+ __all__ = ["setup_cronjob_sub_cmd"]
@@ -0,0 +1,3 @@
1
+ PATH=${PREPEND_PATH}/usr/local/bin:/usr/bin:/bin
2
+
3
+ ${SCHEDULE} ${USER} (echo "[$$(date '+\%Y-\%m-\%d \%H:\%M:\%S') | $$$$] Starting '${NAME}'..."; flock --nonblock --verbose /tmp/cron-${NAME}.lock timeout --kill-after=${KILL_AFTER}s --verbose ${TIMEOUT}s ${COMMAND}${SPACE}${ARGS}; echo "[$$(date '+\%Y-\%m-\%d \%H:\%M:\%S') | $$$$] Finished '${NAME}' with exit code $$?") 2>&1 | sudo tee -a /var/log/${NAME}.log
@@ -0,0 +1,10 @@
1
+ /var/log/${NAME}.log {
2
+ compress
3
+ daily
4
+ dateext
5
+ dateformat -%Y-%m-%d
6
+ delaycompress
7
+ missingok
8
+ notifempty
9
+ rotate ${ROTATE}
10
+ }
@@ -0,0 +1,12 @@
1
+ from __future__ import annotations
2
+
3
+ from actions.constants import PATH_ACTIONS
4
+
5
+ PATH_CONFIGS = PATH_ACTIONS / "setup_cronjob/configs"
6
+
7
+
8
+ SETUP_CRONJOB_SUB_CMD = "setup-cronjob"
9
+ SETUP_CRONJOB_DOCSTRING = "Setup a cronjob"
10
+
11
+
12
+ __all__ = ["PATH_CONFIGS", "SETUP_CRONJOB_DOCSTRING", "SETUP_CRONJOB_SUB_CMD"]
@@ -0,0 +1,120 @@
1
+ from __future__ import annotations
2
+
3
+ from string import Template
4
+ from typing import TYPE_CHECKING
5
+
6
+ from utilities.platform import SYSTEM
7
+ from utilities.subprocess import chmod, chown, tee
8
+ from utilities.text import strip_and_dedent
9
+
10
+ from actions import __version__
11
+ from actions.logging import LOGGER
12
+ from actions.setup_cronjob.constants import PATH_CONFIGS
13
+ from actions.setup_cronjob.settings import SETTINGS
14
+
15
+ if TYPE_CHECKING:
16
+ from collections.abc import Sequence
17
+
18
+ from utilities.types import PathLike
19
+
20
+
21
+ def setup_cronjob(
22
+ *,
23
+ name: str = SETTINGS.name,
24
+ prepend_path: Sequence[PathLike] | None = SETTINGS.prepend_path,
25
+ schedule: str = SETTINGS.schedule,
26
+ user: str = SETTINGS.user,
27
+ timeout: int = SETTINGS.timeout,
28
+ kill_after: int = SETTINGS.kill_after,
29
+ command: PathLike = SETTINGS.command,
30
+ args: list[str] | None = SETTINGS.args,
31
+ logs_keep: int = SETTINGS.logs_keep,
32
+ ) -> None:
33
+ """Set up a cronjob & logrotate."""
34
+ LOGGER.info(
35
+ strip_and_dedent("""
36
+ Running '%s' (version %s) with settings:
37
+ - name = %s
38
+ - prepend_path = %s
39
+ - schedule = %s
40
+ - user = %s
41
+ - timeout = %d
42
+ - kill_after = %d
43
+ - command = %s
44
+ - args = %s
45
+ - logs_keep = %d
46
+ """),
47
+ setup_cronjob.__name__,
48
+ __version__,
49
+ name,
50
+ prepend_path,
51
+ schedule,
52
+ user,
53
+ timeout,
54
+ kill_after,
55
+ command,
56
+ args,
57
+ logs_keep,
58
+ )
59
+ if SYSTEM != "linux":
60
+ msg = f"System must be 'linux'; got {SYSTEM!r}"
61
+ raise TypeError(msg)
62
+ _tee_and_perms(
63
+ f"/etc/cron.d/{name}",
64
+ _get_crontab(
65
+ prepend_path=prepend_path,
66
+ schedule=schedule,
67
+ user=user,
68
+ name=name,
69
+ timeout=timeout,
70
+ kill_after=kill_after,
71
+ command=command,
72
+ args=args,
73
+ ),
74
+ )
75
+ _tee_and_perms(
76
+ f"/etc/logrotate.d/{name}", _get_logrotate(name=name, logs_keep=logs_keep)
77
+ )
78
+
79
+
80
+ def _get_crontab(
81
+ *,
82
+ prepend_path: Sequence[PathLike] | None = SETTINGS.prepend_path,
83
+ schedule: str = SETTINGS.schedule,
84
+ user: str = SETTINGS.user,
85
+ name: str = SETTINGS.name,
86
+ timeout: int = SETTINGS.timeout,
87
+ kill_after: int = SETTINGS.kill_after,
88
+ command: PathLike | None = SETTINGS.command,
89
+ args: list[str] | None = SETTINGS.args,
90
+ ) -> str:
91
+ return Template((PATH_CONFIGS / "cron.tmpl").read_text()).substitute(
92
+ PREPEND_PATH=""
93
+ if prepend_path is None
94
+ else "".join(f"{p}:" for p in prepend_path),
95
+ SCHEDULE=schedule,
96
+ USER=user,
97
+ NAME=name,
98
+ TIMEOUT=timeout,
99
+ KILL_AFTER=kill_after,
100
+ COMMAND=command,
101
+ SPACE=" " if (args is not None) and (len(args) >= 1) else "",
102
+ ARGS="" if args is None else " ".join(args),
103
+ )
104
+
105
+
106
+ def _get_logrotate(
107
+ *, name: str = SETTINGS.name, logs_keep: int = SETTINGS.logs_keep
108
+ ) -> str:
109
+ return Template((PATH_CONFIGS / "logrotate.tmpl").read_text()).substitute(
110
+ NAME=name, ROTATE=logs_keep
111
+ )
112
+
113
+
114
+ def _tee_and_perms(path: PathLike, text: str, /) -> None:
115
+ tee(path, text, sudo=True)
116
+ chown(path, sudo=True, user="root", group="root")
117
+ chmod(path, "u=rw,g=r,o=r", sudo=True)
118
+
119
+
120
+ __all__ = ["setup_cronjob"]
@@ -0,0 +1,27 @@
1
+ from __future__ import annotations
2
+
3
+ from typed_settings import load_settings, option, settings
4
+ from utilities.getpass import USER
5
+
6
+ from actions.utilities import LOADER
7
+
8
+
9
+ @settings
10
+ class Settings:
11
+ name: str = option(default="name", help="Cron job name")
12
+ prepend_path: list[str] | None = option(default=None, help="Paths to prepend")
13
+ schedule: str = option(default="* * * * *", help="Cron job schedule")
14
+ user: str = option(default=USER, help="Cron job user")
15
+ timeout: int = option(default=60, help="Seconds until timing-out the cron job")
16
+ kill_after: int = option(
17
+ default=10, help="Seconds until killing the cron job (after timeout)"
18
+ )
19
+ command: str = option(default="true", help="Command or executable script")
20
+ args: list[str] | None = option(default=None, help="Command arguments")
21
+ logs_keep: int = option(default=7, help="Number of logs to keep")
22
+
23
+
24
+ SETTINGS = load_settings(Settings, [LOADER])
25
+
26
+
27
+ __all__ = ["LOADER", "SETTINGS", "Settings"]
@@ -0,0 +1 @@
1
+ from __future__ import annotations
@@ -0,0 +1,27 @@
1
+ from __future__ import annotations
2
+
3
+ from typed_settings import click_options
4
+ from utilities.logging import basic_config
5
+ from utilities.os import is_pytest
6
+
7
+ from actions.logging import LOGGER
8
+ from actions.tag_commit.lib import tag_commit
9
+ from actions.tag_commit.settings import Settings
10
+ from actions.utilities import LOADER
11
+
12
+
13
+ @click_options(Settings, [LOADER], show_envvars_in_help=True)
14
+ def tag_commit_sub_cmd(settings: Settings, /) -> None:
15
+ if is_pytest():
16
+ return
17
+ basic_config(obj=LOGGER)
18
+ tag_commit(
19
+ user_name=settings.user_name,
20
+ user_email=settings.user_email,
21
+ major_minor=settings.major_minor,
22
+ major=settings.major,
23
+ latest=settings.latest,
24
+ )
25
+
26
+
27
+ __all__ = ["tag_commit_sub_cmd"]
@@ -0,0 +1,7 @@
1
+ from __future__ import annotations
2
+
3
+ TAG_COMMIT_DOCSTRING = "Tag the latest commit"
4
+ TAG_COMMIT_SUB_CMD = "tag-commit"
5
+
6
+
7
+ __all__ = ["TAG_COMMIT_DOCSTRING", "TAG_COMMIT_SUB_CMD"]
@@ -0,0 +1,63 @@
1
+ from __future__ import annotations
2
+
3
+ from contextlib import suppress
4
+ from subprocess import CalledProcessError
5
+
6
+ from utilities.text import strip_and_dedent
7
+ from utilities.version import parse_version
8
+
9
+ from actions import __version__
10
+ from actions.logging import LOGGER
11
+ from actions.tag_commit.settings import SETTINGS
12
+ from actions.utilities import logged_run
13
+
14
+
15
+ def tag_commit(
16
+ *,
17
+ user_name: str = SETTINGS.user_name,
18
+ user_email: str = SETTINGS.user_email,
19
+ major_minor: bool = SETTINGS.major_minor,
20
+ major: bool = SETTINGS.major,
21
+ latest: bool = SETTINGS.latest,
22
+ ) -> None:
23
+ LOGGER.info(
24
+ strip_and_dedent("""
25
+ Running '%s' (version %s) with settings:
26
+ - user_name = %s
27
+ - user_email = %s
28
+ - major_minor = %s
29
+ - major = %s
30
+ - latest = %s
31
+ """),
32
+ tag_commit.__name__,
33
+ __version__,
34
+ user_name,
35
+ user_email,
36
+ major_minor,
37
+ major,
38
+ latest,
39
+ )
40
+ logged_run("git", "config", "--global", "user.name", user_name)
41
+ logged_run("git", "config", "--global", "user.email", user_email)
42
+ version = parse_version(
43
+ logged_run("bump-my-version", "show", "current_version", return_=True)
44
+ )
45
+ _tag(str(version))
46
+ if major_minor:
47
+ _tag(f"{version.major}.{version.minor}")
48
+ if major:
49
+ _tag(str(version.major))
50
+ if latest:
51
+ _tag("latest")
52
+
53
+
54
+ def _tag(version: str, /) -> None:
55
+ with suppress(CalledProcessError):
56
+ logged_run("git", "tag", "--delete", version)
57
+ with suppress(CalledProcessError):
58
+ logged_run("git", "push", "--delete", "origin", version)
59
+ logged_run("git", "tag", "-a", version, "HEAD", "-m", version)
60
+ logged_run("git", "push", "--tags", "--force", "--set-upstream", "origin")
61
+
62
+
63
+ __all__ = ["tag_commit"]
@@ -6,7 +6,7 @@ from actions.utilities import LOADER
6
6
 
7
7
 
8
8
  @settings
9
- class TagSettings:
9
+ class Settings:
10
10
  user_name: str = option(default="github-actions-bot", help="'git' user name")
11
11
  user_email: str = option(default="noreply@github.com", help="'git' user email")
12
12
  major_minor: bool = option(default=False, help="Add the 'major.minor' tag")
@@ -14,7 +14,7 @@ class TagSettings:
14
14
  latest: bool = option(default=False, help="Add the 'latest' tag")
15
15
 
16
16
 
17
- TAG_SETTINGS = load_settings(TagSettings, [LOADER])
17
+ SETTINGS = load_settings(Settings, [LOADER])
18
18
 
19
19
 
20
- __all__ = ["TAG_SETTINGS", "TagSettings"]
20
+ __all__ = ["SETTINGS", "Settings"]
actions/types.py CHANGED
@@ -1,8 +1,21 @@
1
1
  from __future__ import annotations
2
2
 
3
+ from collections.abc import Callable
4
+ from typing import TYPE_CHECKING, Any
5
+
6
+ from tomlkit.items import Array, Table
3
7
  from typed_settings import Secret
8
+ from utilities.packaging import Requirement
9
+
10
+ if TYPE_CHECKING:
11
+ from tomlkit.container import Container
12
+
4
13
 
14
+ type FuncRequirement = Callable[[Requirement], Requirement]
15
+ type HasAppend = Array | list[Any]
16
+ type HasSetDefault = Container | StrDict | Table
5
17
  type SecretLike = str | Secret[str]
18
+ type StrDict = dict[str, Any]
6
19
 
7
20
 
8
- __all__ = ["SecretLike"]
21
+ __all__ = ["FuncRequirement", "HasAppend", "HasSetDefault", "SecretLike", "StrDict"]