Skip to content

Commit

Permalink
fix: use only one default config file not to confuse the user
Browse files Browse the repository at this point in the history
  • Loading branch information
Tomas Peterka committed Feb 6, 2024
1 parent e039862 commit cf9f3ff
Show file tree
Hide file tree
Showing 12 changed files with 92 additions and 49 deletions.
4 changes: 2 additions & 2 deletions .pre-commit-hooks.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
- id: gira
name: gira
entry: gira-precommit
language: system
entry: gira
language: python
stages: [prepare-commit-msg]
47 changes: 36 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,45 +1,70 @@
# Gira

Gira gathers JIRA tickets from commit messages of your updated dependencies when you
change them in one of: `pyproject.toml`, `poetry.lock`, `west.yaml`, and `pubspec.yaml`.
It is especially usefull in "prepare-commit-msg" stage of [pre-commit](https://pre-commit.com)
Gira reacts on changes in your dependency files and bring you JIRA tickets mentioned in commits between current and updated version of the dependencies. Supported files are:

//Disclaimer: works the best if your dependencies follow [semantic release](https://semantic-release.gitbook.io/semantic-release/) (have tags in `v{X.Y.*}` format)//
- pyproject.toml
- poetry.lock
- west.yaml
- pubspec.yaml

It is especially usefull in [pre-commit](https://pre-commit.com).

___Pssst__: works the best if your dependencies follow [semantic release](https://semantic-release.gitbook.io/semantic-release/) thus have tags in `vX.Y.*` format.


## Usage

```bash
gira [-r revision] [--format="commit|detail|markdown"]
gira [-r revision] [-c config] [--format="commit|detail|markdown"]
```

Revision can be tag/branch or a commit. Gira will check dependency files for changes between
the current version and the revision version.
Revision can be tag, branch, or a commit. By default `gira` check for staged/unstaged changes and if no are found then it diffs to the previous commit. This is the way to tell `gira` to diff to a different tag (for example).

Format is useful if you generate into a commit message (only ticket names (e.g. JIRA-1234))
or you want a user readable "detailed" print or the same but markdown formatted.
Format can be short or detailed. Detailed formats will try to reach to your JIRA server for the details. The short (default) version is useful as suffix to
commit messages. The markdown version is intended for changelogs.

```bash
$ gira [--format=commit]
internal-dependency1 <versionB> => <versionB>: JIRA-123, JIRA-567
other-followed-lib <versionB> => <versionB>: JIRA-876, JIRA-543
```

Config file is by default _.gira.yaml_ but can be pretty much any YAML or pyproject.toml. See section bellow.

## Pre-commit

Add to your .pre-commit-config.yaml

```yaml
- repo: https://github.com/dronetag/gira
rev: v1.0.0
hooks:
- id: gira
# if you use other config than .gira.yaml then
# args: ["-c", "your-config.yaml"]
```

## Configuration

Gira is configured either by pyproject.toml or standalone .gira.yaml or actually any other
YAML file that you specify with `-c` and has "gira.observe" and optionally "gira.jira" keys.

### Observed Dependencies

Observed dependencies are in form of NAME=git-url where NAME must be the same as specified
in your dependency file (e.g. pyproject.toml or a YAML).
Observed dependencies are in form of NAME=git-url where NAME must be the same as specified in your dependency/lock file.

```toml
[tool.gira.observe]
internal-lib1 = "github.com/company/internal-lib1"
other-dependency = "bitbucket.com/company/other-dependency"
```
or
```yaml
gira:
observe:
internal-lib1: "github.com/company/internal-lib1"
other-dependency: "bitbucket.com/company/other-dependency"
```
### Submodules
Expand Down
17 changes: 5 additions & 12 deletions gira/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,7 @@
from . import logger
from .jira import Jira

DEFAULT_CONFIG_PATHS = (
".gira.yaml",
"pyproject.toml",
"west.yml",
"west.yaml",
)
DEFAULT_CONFIG = Path(".gira.yaml")


class Config:
Expand All @@ -36,19 +31,17 @@ def from_file(path: Optional[Path]) -> Config:
if path and path.exists():
return _parse_file(path)

for path_str in DEFAULT_CONFIG_PATHS:
if Path(path_str).exists():
logger.debug(f"Loading configuration from {path_str}")
return _parse_file(Path(path_str))
if DEFAULT_CONFIG.exists():
return _parse_file(DEFAULT_CONFIG)

raise FileNotFoundError("No configuration file found")


def _parse_file(path: Path) -> Config:
if path.name == "pyproject.toml":
return _pytoml(path)
if path.name == ".gira.yaml":
return _conf(path)
if path.name == "pyproject.toml":
return _pytoml(path)
if path.name.startswith("west"):
return _west(path)
if path.name.endswith(".yaml"):
Expand Down
2 changes: 1 addition & 1 deletion gira/formatter.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@


def get_formatter(name: str, stream: TextIO):
if name == "commit":
if name in ("commit", "short"):
return CommitFormatter(stream)
if name in ("detail", "detailed"):
return DetailFormatter(stream)
Expand Down
11 changes: 8 additions & 3 deletions gira/repo.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ class Repo:
bare: bool
repo: pygit2.Repository
_submodules: Optional[dict[Path, str]]
_diff_cached: bool
MESSAGE_LIMIT = 250

def __init__(self, path: Path, ref: Optional[str] = "", bare: bool = False):
self.path = path
self.repo = pygit2.Repository(str(path), pygit2.GIT_REPOSITORY_OPEN_BARE if bare else 0)
self.bare = bare
self._diff_cached = False
try:
self.ref = self._check_ref(ref)
except KeyError as e:
Expand Down Expand Up @@ -52,7 +54,7 @@ def changed_files(self) -> list[Path]:
def submodule_change(self, submodule_path: Path) -> tuple[str, str]:
"""Return list of lines added and removed in the diff"""
try:
diffs = self.repo.diff(self.ref, context_lines=0)
diffs = self.repo.diff(self.ref, context_lines=0, cached=self._diff_cached)
except KeyError:
raise RuntimeError(f"Revision {self.ref} does not exist")

Expand Down Expand Up @@ -95,8 +97,11 @@ def _check_ref(self, ref: Optional[str]):
return "refs/tags/" + ref
except KeyError:
return "refs/heads/" + ref
if self.repo and len(self.repo.diff("HEAD")) == 0:
return "HEAD^"
if self.repo and len(self.repo.diff("HEAD")) > 0:
return "HEAD"
if self.repo and len(self.repo.diff("HEAD", cached=True)) > 0:
self._diff_cached = True
return "HEAD"
return "HEAD"

def messages(self, a: str, b: Optional[str] = None):
Expand Down
2 changes: 2 additions & 0 deletions tests/local-template/.gira.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
observed:
dep1: "file:///${GIRA_TEST_ROOT}/remote/dep1/.git"
2 changes: 1 addition & 1 deletion tests/local-template/poetry/poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions tests/local-template/poetry/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ classifiers = [

[tool.poetry.dependencies]
python = "^3.8"
dep1 = "1.0.0"
dep1-poetry = "1.0.0"
wheel = "*"
pytest = {version="*", optional=true}

[tool.poetry.extras]
dev = ["wheel", "pytest"]

[tool.gira.observe]
dep1 = "file://${GIRA_TEST_ROOT}/remote/dep1/.git"
dep1-poetry = "file://${GIRA_TEST_ROOT}/remote/dep1/.git"
4 changes: 2 additions & 2 deletions tests/local-template/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ environment:

dependencies:
analyzer: ^5.13.0
dep1:
dep1-pubspec:
git:
url: file:///${GIRA_TEST_ROOT}/remote/dep1/.git
ref: v1.0.0
non-internal-dep2: ^0.9.3+5

gira:
observe:
dep1: "file:///${GIRA_TEST_ROOT}/remote/dep1/.git"
dep1-pubspec: "file:///${GIRA_TEST_ROOT}/remote/dep1/.git"
4 changes: 2 additions & 2 deletions tests/local-template/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ dependencies = [
"tomli; python_version < '3.11'",
"pyyaml",
"jira",
"dep1==1.0.0",
"dep1-pytoml==1.0.0",
]

[tool.gira.observe]
dep1 = "file://${GIRA_TEST_ROOT}/remote/dep1/.git"
dep1-pytoml = "file://${GIRA_TEST_ROOT}/remote/dep1/.git"
4 changes: 2 additions & 2 deletions tests/local-template/west.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ manifest:
remote: local

projects:
- name: dep1
- name: dep1-west
repo-path: libs/dep1
revision: v1.0.0
import: true

gira:
observe:
dep1: "file://${GIRA_TEST_ROOT}/remote/dep1/.git"
dep1-west: "file://${GIRA_TEST_ROOT}/remote/dep1/.git"
40 changes: 29 additions & 11 deletions tests/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,61 +16,79 @@ envsubst < local-template/poetry/poetry.lock > local/poetry/poetry.lock
envsubst < local-template/pyproject.toml > local/pyproject.toml
envsubst < local-template/pubspec.yaml > local/pubspec.yaml
envsubst < local-template/west.yaml > local/west.yaml
envsubst < local-template/.gira.yaml > local/.gira.yaml


pushd local
git init
git init 2> /dev/null
git add .
git commit -m "Initial commit"
git commit -m "Initial commit" 2> /dev/null

# run on no changes in dependencies
echo "-- Test no changes" > README.md
gira
git reset README.md
rm README.md

#############################################
## run tests
echo "Test poetry/poetry.lock"
echo "-- Test poetry/poetry.lock"
git reset --hard
rm -rf .gira_cache output.txt
sed -i 's/1.0.0/1.1.0/g' poetry/poetry.lock
gira > output.txt
gira -c poetry/pyproject.toml | tee output.txt
grep dep1-poetry output.txt
grep "1.0.0" output.txt
grep "1.1.0" output.txt
grep OCD-1234 output.txt
grep -v OCD-567 output.txt


echo "Test poetry/pyproject.toml"
echo "-- Test poetry/pyproject.toml"
git reset --hard
rm -rf .gira_cache output.txt
sed -i 's/1.0.0/1.1.1/g' poetry/pyproject.toml
gira -c poetry/pyproject.toml > output.txt
grep dep1-poetry output.txt
grep "1.0.0" output.txt
grep "1.1.1" output.txt
grep OCD-1234 output.txt
grep OCD-567 output.txt


echo "Test pyproject.toml"
echo "-- Test pyproject.toml"
git reset --hard
rm -rf .gira_cache output.txt
sed -i 's/1.0.0/1.1.0/g' pyproject.toml
gira > output.txt
gira -c pyproject.toml > output.txt
grep dep1-pytoml output.txt
grep "1.0.0" output.txt
grep "1.1.0" output.txt
grep OCD-1234 output.txt
grep -v OCD-567 output.txt


echo "Test pubspec.yaml"
echo "-- Test pubspec.yaml"
git reset --hard
rm -rf .gira_cache output.txt
sed -i 's/1.0.0/1.1.1/g' pubspec.yaml
gira -c pubspec.yaml > output.txt
grep dep1-pubspec output.txt
grep OCD-1234 output.txt
grep OCD-567 output.txt


echo "Test pubspec.yaml"
echo "-- Test pubspec.yaml"
git reset --hard
rm -rf .gira_cache output.txt
sed -i 's/1.0.0/1.1.0/g' west.yaml
gira -c west.yaml > output.txt
grep dep1-west output.txt
grep OCD-1234 output.txt
grep -v OCD-567 output.txt

echo "Test moving from 1.0.0 to 1.1.0 and then to 1.1.1"

echo "-- Test moving from 1.0.0 to 1.1.0 and then to 1.1.1"
git reset --hard
rm -rf .gira_cache output.txt
sed -i 's/1.0.0/1.1.0/g' west.yaml
Expand All @@ -84,7 +102,7 @@ grep OCD-1234 output.txt
grep OCD-567 output.txt


echo "Test pre-commit"
echo "-- Test pre-commit"
git reset --hard
rm -rf .gira_cache output.txt
sed -i 's/1.0.0/1.1.1/g' west.yaml
Expand Down

0 comments on commit cf9f3ff

Please sign in to comment.