Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Make the project importable as a module #9

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
71 changes: 26 additions & 45 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ You can use the scripts in this repository to analyse another git repository for

Using python 3.7 or greater:

pip install -r requirements.txt
pip install .

There are two scripts for calculating metrics (which may be combined into one soon). To find out how to use them:

python calculate_four_metrics.py --help
python git-metrics.py --help
calculate-four-metrics --help
git-metrics --help

## Throughput metrics: Deployment Lead Time and Deploy Interval

Expand All @@ -37,17 +37,17 @@ Once you have your repository annotated with tags for each deployment, you can u

Use a command like this to produce the raw data for this graph and store it in a csv file:

python git_metrics.py release-lead-time [--tag-pattern=<fn_match>] [--earliest-date=<timestamp>] <path_to_git_repo> > repo_data.csv
git-metrics release-lead-time [--tag-pattern=<fn_match>] [--earliest-date=<timestamp>] <path_to_git_repo> > repo_data.csv


You can then plot this data with this command:

python git_metrics.py plot --release-lead-time <csv_file>
git-metrics plot --release-lead-time <csv_file>

You can also print out average values for both release lead time and release interval like this:

calculate_four_metrics.py lead-time [--deploy-tag-pattern=<fn_match>] [--start-date=<timestamp>] <path_to_git_repo>
calculate_four_metrics.py deploy-interval [--deploy-tag-pattern=<fn_match>] [--start-date=<timestamp>] <path_to_git_repo>
calculate-four-metrics lead-time [--deploy-tag-pattern=<fn_match>] [--start-date=<timestamp>] <path_to_git_repo>
calculate-four-metrics deploy-interval [--deploy-tag-pattern=<fn_match>] [--start-date=<timestamp>] <path_to_git_repo>

For more information about how to install these scripts, see below under 'Installation'

Expand All @@ -66,8 +66,8 @@ If you want to add a patch tag to a commit that has been deployed, and already h

You can also print out average values for both mean time to recover and change failure rate like this:

calculate_four_metrics.py recovery-time [--deploy-tag-pattern=<fn_match>] [--patch-tag-pattern=<fn_match>] [--start-date=<timestamp>] <path_to_git_repo>
calculate_four_metrics.py change-fail-rate [--deploy-tag-pattern=<fn_match>] [--patch-tag-pattern=<fn_match>] [--start-date=<timestamp>] <path_to_git_repo>
calculate-four-metrics recovery-time [--deploy-tag-pattern=<fn_match>] [--patch-tag-pattern=<fn_match>] [--start-date=<timestamp>] <path_to_git_repo>
calculate-four-metrics change-fail-rate [--deploy-tag-pattern=<fn_match>] [--patch-tag-pattern=<fn_match>] [--start-date=<timestamp>] <path_to_git_repo>

## Open branches

Expand All @@ -77,71 +77,52 @@ Open branches gathers information about the age of all commits in a branch that

Use these script commands to produce this kind of graph:

git_metrics.py open-branches [--master-branch=<branch>] <path_to_git_repo> > my_repo.csv
git_metrics.py plot --open-branches my_repo.csv
git-metrics open-branches [--master-branch=<branch>] <path_to_git_repo> > my_repo.csv
git-metrics plot --open-branches my_repo.csv


## Installation

**Requirement:** Python 3.7 or later

To install dependencies:
`pip install -r requirements.txt`
`python pip install .`

for more help run:
`python git_metrics.py --help`

### Python 2 systems

Those OS with Python 2 as default, e.g. Ubuntu 17/16, you need to use pip and python explicitly if you didn't change the default:

Call the script with:

python3 git_metrics.py --help

Install pip3 if not already installed and configure dependencies with pip3, e.g. Ubuntu 16/17:

sudo apt-get install python3-pip
pip3 install -r requirements.txt

On Ubuntu you might also miss the `python3-tk` package if doing plots

sudo apt install python3-tk
`git-metrics --help`

## Usage

Call script with

python3 git_metrics.py --help
git-metrics --help

which will show basic usage information like:

Calculate age of commits in open remote branches

Usage:
git_metrics.py open-branches [--master-branch=<branch>] <path_to_git_repo>
git_metrics.py open-branches [--master-branch=<branch>] --plot <path_to_git_repo>
git_metrics.py release-lead-time [--tag-pattern=<fn_match>] [--earliest-date=<timestamp>] <path_to_git_repo>
git_metrics.py release-lead-time --plot [--tag-pattern=<fn_match>] <path_to_git_repo>
git_metrics.py plot --open-branches <csv_file>
git_metrics.py plot --release-lead-time <csv_file>
git_metrics.py batch --open-branches <path_to_git_repos>...
git_metrics.py batch --release-lead-time [--earliest-date=<timestamp>] <path_to_git_repos>...
git_metrics.py (-h | --help)
git-metrics open-branches [--master-branch=<branch>] <path_to_git_repo>
git-metrics open-branches [--master-branch=<branch>] --plot <path_to_git_repo>
git-metrics release-lead-time [--tag-pattern=<fn_match>] [--earliest-date=<timestamp>] <path_to_git_repo>
git-metrics release-lead-time --plot [--tag-pattern=<fn_match>] <path_to_git_repo>
git-metrics plot --open-branches <csv_file>
git-metrics plot --release-lead-time <csv_file>
git-metrics batch --open-branches <path_to_git_repos>...
git-metrics batch --release-lead-time [--earliest-date=<timestamp>] <path_to_git_repos>...
git-metrics (-h | --help)

Options:
--master-branch=<branch> example: origin/gh-pages


* **`--plot`** parameter will open a GnuPlot plot, and will not will not save your data.
* To _save data_ use without plot and pipe to file for csv format: `git_metrics.py release-lead-time <path_to_git-repo> > my-csv-file.csv`
* Use plot command to plot existing csv files, e.g. `git_metrics.py plot --release-lead-time my-csv-file.csv`
* To _save data_ use without plot and pipe to file for csv format: `git-metrics release-lead-time <path_to_git-repo> > my-csv-file.csv`
* Use plot command to plot existing csv files, e.g. `git-metrics plot --release-lead-time my-csv-file.csv`
* `batch` (undocumented)

## Developer information

Run the self-tests using pytest:

pytest -v


Empty file added git_metrics/__init__.py
Empty file.
20 changes: 10 additions & 10 deletions calculate_four_metrics.py → git_metrics/calculate_four_metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
* Mean time to recover

Usage:
calculate_four_metrics.py lead-time [--deploy-tag-pattern=<fn_match>] [--start-date=<timestamp>] <path_to_git_repo>
calculate_four_metrics.py deploy-interval [--deploy-tag-pattern=<fn_match>] [--start-date=<timestamp>] <path_to_git_repo>
calculate_four_metrics.py change-fail-rate [--deploy-tag-pattern=<fn_match>] [--patch-tag-pattern=<fn_match>] [--start-date=<timestamp>] <path_to_git_repo>
calculate_four_metrics.py recovery-time [--deploy-tag-pattern=<fn_match>] [--patch-tag-pattern=<fn_match>] [--start-date=<timestamp>] <path_to_git_repo>
calculate_four_metrics.py metrics-all [--deploy-tag-pattern=<fn_match>] [--patch-tag-pattern=<fn_match>] [--start-date=<timestamp>] <path_to_git_repo>
calculate_four_metrics.py (-h | --help)
calculate-four-metrics lead-time [--deploy-tag-pattern=<fn_match>] [--start-date=<timestamp>] <path_to_git_repo>
calculate-four-metrics deploy-interval [--deploy-tag-pattern=<fn_match>] [--start-date=<timestamp>] <path_to_git_repo>
calculate-four-metrics change-fail-rate [--deploy-tag-pattern=<fn_match>] [--patch-tag-pattern=<fn_match>] [--start-date=<timestamp>] <path_to_git_repo>
calculate-four-metrics recovery-time [--deploy-tag-pattern=<fn_match>] [--patch-tag-pattern=<fn_match>] [--start-date=<timestamp>] <path_to_git_repo>
calculate-four-metrics metrics-all [--deploy-tag-pattern=<fn_match>] [--patch-tag-pattern=<fn_match>] [--start-date=<timestamp>] <path_to_git_repo>
calculate-four-metrics (-h | --help)

"""
import csv
Expand All @@ -24,10 +24,10 @@

import docopt

from git_metrics_release_lead_time import commit_author_time_tag_author_time_and_from_to_tag_name, \
from .git_metrics_release_lead_time import commit_author_time_tag_author_time_and_from_to_tag_name, \
fetch_tags_and_author_dates, fetch_tags_and_sha
from process import mk_run
from recovery_time import Deployment, find_is_patch, find_outages
from .process import mk_run
from .recovery_time import Deployment, find_is_patch, find_outages


def configure_logging():
Expand Down Expand Up @@ -143,7 +143,7 @@ def calculate_lead_time(path_to_git_repo, pattern, start_date):
log.info("calculating lead time data from deployments %s", deployment_tag_pairs)
lead_time_data = [(tat - cat) for cat, tat, old_tag, tag in deployment_data]
return statistics.mean(lead_time_data) if lead_time_data else "N/A"


def write_four_metrics_csv_file(data):
writer = csv.writer(sys.stdout, delimiter=',', lineterminator='\n')
Expand Down
File renamed without changes.
File renamed without changes.
31 changes: 15 additions & 16 deletions git_metrics.py → git_metrics/git_metrics.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
"""Calculate age of commits in open remote branches

Usage:
git_metrics.py open-branches [--master-branch=<branch>] <path_to_git_repo>
git_metrics.py open-branches [--master-branch=<branch>] --plot <path_to_git_repo>
git_metrics.py release-lead-time [--tag-pattern=<fn_match>] [--earliest-date=<timestamp>] <path_to_git_repo>
git_metrics.py release-lead-time --plot [--tag-pattern=<fn_match>] <path_to_git_repo>
git_metrics.py plot --open-branches <csv_file>
git_metrics.py plot --release-lead-time <csv_file>
git_metrics.py batch --open-branches <path_to_git_repos>...
git_metrics.py batch --release-lead-time [--earliest-date=<timestamp>] <path_to_git_repos>...
git_metrics.py (-h | --help)
git-metrics open-branches [--master-branch=<branch>] <path_to_git_repo>
git-metrics open-branches [--master-branch=<branch>] --plot <path_to_git_repo>
git-metrics release-lead-time [--tag-pattern=<fn_match>] [--earliest-date=<timestamp>] <path_to_git_repo>
git-metrics release-lead-time --plot [--tag-pattern=<fn_match>] <path_to_git_repo>
git-metrics plot --open-branches <csv_file>
git-metrics plot --release-lead-time <csv_file>
git-metrics batch --open-branches <path_to_git_repos>...
git-metrics batch --release-lead-time [--earliest-date=<timestamp>] <path_to_git_repos>...
git-metrics (-h | --help)

Options:
--master-branch=<branch> example: origin/gh-pages
Expand All @@ -23,12 +23,12 @@
import docopt
import sys

from git_metrics_open_branches import plot_open_branches_metrics
from git_metrics_open_branches import get_branches
from git_metrics_open_branches import commit_author_time_and_branch_ref
from git_metrics_release_lead_time import commit_author_time_tag_author_time_and_from_to_tag_name
from git_metrics_release_lead_time import plot_release_lead_time_metrics
from process import mk_run
from .git_metrics_open_branches import plot_open_branches_metrics
from .git_metrics_open_branches import get_branches
from .git_metrics_open_branches import commit_author_time_and_branch_ref
from .git_metrics_release_lead_time import commit_author_time_tag_author_time_and_from_to_tag_name
from .git_metrics_release_lead_time import plot_release_lead_time_metrics
from .process import mk_run


def read_open_branches_csv_file(filename):
Expand Down Expand Up @@ -136,4 +136,3 @@ def assert_master_branch(run, master_branch):

if __name__ == "__main__":
main()

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from data import columns
from custom_git import for_each_ref, log
from .data import columns
from .custom_git import for_each_ref, log


def plot_open_branches_metrics(data):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@

import matplotlib

from data import columns, zip_with_tail
from custom_git import for_each_ref, show
from custom_git import cherry
from process import proc_to_stdout
from .data import columns, zip_with_tail
from .custom_git import for_each_ref, show
from .custom_git import cherry
from .process import proc_to_stdout

TAGS_WITH_AUTHOR_DATE_CMD = for_each_ref(
'refs/tags/**',
Expand Down
File renamed without changes.
File renamed without changes.
4 changes: 2 additions & 2 deletions test_data.py → git_metrics/test_data.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from data import columns
from data import zip_with_tail
from .data import columns
from .data import zip_with_tail


def test_single_column():
Expand Down
4 changes: 2 additions & 2 deletions test_git.py → git_metrics/test_git.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from custom_git import for_each_ref, cherry, show
from custom_git import log
from .custom_git import for_each_ref, cherry, show
from .custom_git import log


def test_for_each_ref_normal():
Expand Down
5 changes: 2 additions & 3 deletions test_integration.py → git_metrics/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import pytest
from git import Repo

from calculate_four_metrics import calculate_lead_time, calculate_deploy_interval, calculate_change_fail_rate, \
from .calculate_four_metrics import calculate_lead_time, calculate_deploy_interval, calculate_change_fail_rate, \
calculate_MTTR


Expand Down Expand Up @@ -52,7 +52,7 @@ def _run_git_cmd(git_repo, command, environment):
"GIT_AUTHOR_NAME": "Integration Test",
"EMAIL": "[email protected]"}
env_variables.update(environment)
subprocess.run(command, cwd=git_repo.working_dir,
subprocess.run(command, cwd=git_repo.working_dir,
env=env_variables)


Expand Down Expand Up @@ -111,4 +111,3 @@ def test_calculate_deploy_interval_no_matching_tags(git_repo_DDDP):
def test_lead_time_multiple_deploys(git_repo_DDDP):
mean_lead_time = calculate_lead_time(git_repo_DDDP.working_dir, "FOO*", 1548321540)
assert mean_lead_time == "N/A"

2 changes: 1 addition & 1 deletion test_process.py → git_metrics/test_process.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import os
from subprocess import Popen, PIPE

from process import proc_to_stdout
from .process import proc_to_stdout


def test_proc_to_pocess():
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from recovery_time import find_outages, split_sequence, Deployment, find_is_patch
from .recovery_time import find_outages, split_sequence, Deployment, find_is_patch

deployment_zero = Deployment(False, 0)
deployment_two = Deployment(False, 2)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from collections import namedtuple
from contextlib import contextmanager

from git_metrics_release_lead_time import parse_tags_with_date
from git_metrics_release_lead_time import tags_with_author_date
from git_metrics_release_lead_time import fetch_tags_and_sha
import git_metrics_release_lead_time
from .git_metrics_release_lead_time import parse_tags_with_date
from .git_metrics_release_lead_time import tags_with_author_date
from .git_metrics_release_lead_time import fetch_tags_and_sha
from . import git_metrics_release_lead_time


def test_parse_tags_with_author_date():
Expand Down
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"
6 changes: 0 additions & 6 deletions requirements.txt

This file was deleted.

21 changes: 21 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from setuptools import setup, find_packages

setup(
name='git_metrics',
version='0.1.0',
packages=find_packages(),
install_requires=[
"docopt >= 0.6.2",
"GitPython >= 3.1.14",
"matplotlib >= 3.3.4",
"pandas >= 1.2.3",
"pytest >= 6.2.2",
"requests >= 2.25.1",
],
entry_points={
'console_scripts': [
'calculate-four-metrics = git_metrics.calculate_four_metrics:main',
'git-metrics = git_metrics.git_metrics:main',
],
},
)