diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 5c075ba..d7fd31f 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -25,7 +25,7 @@ jobs: - uses: conda-incubator/setup-miniconda@v2 with: miniconda-version: "latest" - environment-file: conda/dev.yaml + environment-file: conda/release.yaml channels: conda-forge,nodefaults activate-environment: makim use-mamba: true diff --git a/.makim.yaml b/.makim.yaml index 69099f3..be1a277 100644 --- a/.makim.yaml +++ b/.makim.yaml @@ -34,13 +34,14 @@ groups: app: | npx --yes \ -p semantic-release \ + -p conventional-changelog-conventionalcommits \ -p "@semantic-release/commit-analyzer" \ -p "@semantic-release/release-notes-generator" \ -p "@semantic-release/changelog" \ -p "@semantic-release/exec" \ -p "@semantic-release/github" \ -p "@semantic-release/git" \ - -p "@google/semantic-release-replace-plugin" \ + -p "semantic-release-replace-plugin@1.2.7" \ semantic-release targets: diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 598be92..4958a8f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -9,9 +9,9 @@ repos: - repo: local hooks: - - id: blue - name: blue - entry: blue + - id: ruff-format + name: ruff-format + entry: ruff format exclude: | (?x)( docs @@ -21,8 +21,8 @@ repos: types: - python - - id: ruff - name: ruff + - id: ruff-linter + name: ruff-linter entry: ruff check language: system exclude: "docs/" @@ -30,14 +30,6 @@ repos: types: - python - - id: isort - name: isort - entry: isort - language: system - pass_filenames: true - types: - - python - - id: mypy name: mypy entry: mypy @@ -47,7 +39,6 @@ repos: types: - python - - id: bandit name: bandit entry: bandit @@ -59,20 +50,10 @@ repos: - id: vulture name: vulture - entry: vulture + entry: vulture --min-confidence 80 language: system files: "makim/" description: Find unused Python code. pass_filenames: true types: - python - - - id: pydocstyle - name: pydocstyle - entry: pydocstyle - exclude: ^$ - files: "makim/" - language: system - pass_filenames: true - types: - - python diff --git a/.releaserc.json b/.releaserc.json index 14d91bb..799aa19 100644 --- a/.releaserc.json +++ b/.releaserc.json @@ -2,9 +2,12 @@ "branches": ["main"], "tagFormat": "${version}", "plugins": [ - "@semantic-release/commit-analyzer", [ - "@google/semantic-release-replace-plugin", + "@semantic-release/commit-analyzer", { + "preset": "conventionalcommits" + }], + [ + "semantic-release-replace-plugin", { "replacements": [ { diff --git a/conda/dev.yaml b/conda/dev.yaml index cd6d3e4..37f7eb9 100644 --- a/conda/dev.yaml +++ b/conda/dev.yaml @@ -5,4 +5,3 @@ channels: dependencies: - python 3.8.1 # min version supported - poetry >=1.5 - - nodejs # used by semantic-release diff --git a/conda/release.yaml b/conda/release.yaml new file mode 100644 index 0000000..6a92f37 --- /dev/null +++ b/conda/release.yaml @@ -0,0 +1,8 @@ +name: makim +channels: + - nodefaults + - conda-forge +dependencies: + - python >=3.8.1,<3.12 # min version supported + - poetry >=1.5 + - nodejs >=18.17 # used by semantic-release diff --git a/makim/cli.py b/makim/cli.py index e1b441d..5912245 100644 --- a/makim/cli.py +++ b/makim/cli.py @@ -2,6 +2,7 @@ import argparse import os import sys + from pathlib import Path from makim import Makim, __version__ diff --git a/makim/makim.py b/makim/makim.py index a0bc31a..5492b70 100644 --- a/makim/makim.py +++ b/makim/makim.py @@ -11,6 +11,7 @@ import sys import tempfile import warnings + from copy import deepcopy from pathlib import Path from typing import Dict, Optional, Tuple @@ -18,11 +19,16 @@ import dotenv import sh import yaml # type: ignore + from colorama import Fore from jinja2 import Template from makim.errors import MakimError +SCOPE_GLOBAL = 0 +SCOPE_GROUP = 1 +SCOPE_TARGET = 2 + def escape_template_tag(v: str) -> str: """Escape template tag when processing the template config file.""" @@ -150,7 +156,7 @@ def _change_group_data(self, group_name=None): self.group_name = group_name shell_app_default = self.global_data.get('shell', 'xonsh') if self.group_name == 'default' and len(groups) == 1: - group = list(groups)[0] + group = next(iter(groups)) self.group_data = groups[group] shell_app = self.group_data.get('shell', shell_app_default) @@ -174,8 +180,8 @@ def _load_config_data(self): with open(self.makim_file, 'r') as f: # escape template tags content = escape_template_tag(f.read()) - f = io.StringIO(content) - self.global_data = yaml.safe_load(f) + content_io = io.StringIO(content) + self.global_data = yaml.safe_load(content_io) def _load_shell_app(self, shell_app: str = ''): if not shell_app: @@ -219,19 +225,19 @@ def _render_env_inplace( env = deepcopy(dict(os.environ)) variables: dict = {} - if scope_id >= 0: + if scope_id >= SCOPE_GLOBAL: env_user = self.global_data.get('env', {}) env_file = self._load_dotenv(self.global_data) _render_env_inplace(env_user, env_file, variables, env) variables.update(self._load_scoped_vars('global', env=env)) - if scope_id >= 1: + if scope_id >= SCOPE_GROUP: env_user = self.group_data.get('env', {}) env_file = self._load_dotenv(self.group_data) _render_env_inplace(env_user, env_file, variables, env) variables.update(self._load_scoped_vars('group', env=env)) - if scope_id == 2: + if scope_id == SCOPE_TARGET: env_user = self.target_data.get('env', {}) env_file = self._load_dotenv(self.target_data) _render_env_inplace(env_user, env_file, variables, env) @@ -247,21 +253,21 @@ def _load_scoped_vars(self, scope: str, env) -> dict: variables = {} - if scope_id >= 0: + if scope_id >= SCOPE_GLOBAL: variables.update( { k: v.strip() for k, v in self.global_data.get('vars', {}).items() } ) - if scope_id >= 1: + if scope_id >= SCOPE_GROUP: variables.update( { k: v.strip() for k, v in self.group_data.get('vars', {}).items() } ) - if scope_id == 2: + if scope_id == SCOPE_TARGET: variables.update( { k: v.strip() diff --git a/pyproject.toml b/pyproject.toml index 9764bdb..0482e25 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -51,8 +51,6 @@ colorama = ">=0.4.6" [tool.poetry.group.dev.dependencies] containers-sugar = "1.9.0" pytest = ">=7" -blue = ">=0.9.1" -isort = ">=5" pre-commit = ">=3" mypy = ">=1" pytest-cov = ">=3.0.0" @@ -63,10 +61,9 @@ mkdocs-literate-nav = ">=0.4.1" mkdocs-macros-plugin = ">=0.6.3" mkdocs-material = ">=8" mkdocstrings = {version=">=0.19.0", extras=["python"]} -ruff = ">=0.0.278" +ruff = ">=0.1.5" bandit = ">=1.7.5" vulture = ">=2.7" -pydocstyle = ">=6.3.0" compose-go = ">=2.20.2" [build-system] @@ -78,24 +75,40 @@ testpaths = [ "tests", ] -[tool.blue] -line-length = 79 # this is the default - -[tool.isort] -ensure_newline_before_comments = true -line_length = 79 -multi_line_output = 3 -include_trailing_comma = true -skip_glob = ["docs/*", "*.egg-info"] - [tool.mypy] ignore_missing_imports = true + [tool.ruff] line-length = 79 +force-exclude = true +src = ["./makim", "./tests"] +ignore = ["RUF012"] exclude = [ "docs", ] +select = [ + "E", # pycodestyle + "F", # pyflakes + "D", # pydocstyle + "YTT", # flake8-2020 + "PL", # PL + "RUF", # Ruff-specific rules + "I001", # isort +] +# fixable = ["I001"] +fix = true + +[tool.ruff.pydocstyle] +convention = "numpy" + +[tool.ruff.isort] +# Use a single line between direct and from import +lines-between-types = 1 + +[tool.ruff.format] +quote-style = "single" + [tool.bandit] exclude_dirs = ["tests"] diff --git a/tests/test_failure.py b/tests/test_failure.py index 951490e..fc322b3 100644 --- a/tests/test_failure.py +++ b/tests/test_failure.py @@ -1,11 +1,13 @@ """Tests for `makim` package.""" import os import sys + from pathlib import Path import pytest import makim + from makim.errors import MakimError @@ -18,6 +20,7 @@ ], ) def test_failure(target, args, error_code): + """Test makim with expected failures.""" makim_file = Path(__file__).parent / '.makim-unittest.yaml' m = makim.Makim() diff --git a/tests/test_success.py b/tests/test_success.py index 817bae0..e9b02b6 100644 --- a/tests/test_success.py +++ b/tests/test_success.py @@ -21,6 +21,7 @@ ], ) def test_success(target, args): + """Test makim when expects success.""" makim_file = Path(__file__).parent / '.makim-unittest.yaml' m = makim.Makim()