Skip to content

Commit

Permalink
Implement GH issues threshold config (closes #10)
Browse files Browse the repository at this point in the history
  • Loading branch information
textbook committed Jul 6, 2016
1 parent 8542651 commit ff455bd
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 19 deletions.
11 changes: 10 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,12 @@ The following service definitions include the configuration options:
* ``api_token`` (required),
* ``account`` (required - the name of the account the project is in, e.g.
``"textbook"``)
* ``repo`` (required
* ``repo`` (required - the name of the project repository within that account,
e.g. ``"flash"``)
* ``neutral_threshold`` (the maximum half life to show as a neutral state,
in days, defaults to 30)
* ``ok_threshold`` (the maximum half life to show as an OK state, in days,
defaults to 7)

* ``ghe_issues`` - for issues and PRs in project repositories on
`GitHub Enterprise`_ installations
Expand All @@ -72,6 +77,10 @@ The following service definitions include the configuration options:
``"textbook"``)
* ``repo`` (required - the name of the project repository within that account,
e.g. ``"flash"``)
* ``neutral_threshold`` (the maximum half life to show as a neutral state,
in days, defaults to 30)
* ``ok_threshold`` (the maximum half life to show as an OK state, in days,
defaults to 7)

* ``github`` - for project repositories on `GitHub`_

Expand Down
2 changes: 1 addition & 1 deletion flash_services/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from .travis import TravisOS, TravisPro

__author__ = 'Jonathan Sharpe'
__version__ = '0.3.4'
__version__ = '0.3.5'

blueprint = Blueprint(
'services',
Expand Down
23 changes: 23 additions & 0 deletions flash_services/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,3 +158,26 @@ def url_builder(self, endpoint, *, root=None, params=None, url_params=None):
root = self.root
return super().url_builder(endpoint=endpoint, root=root, params=params,
url_params=url_params)


class ThresholdMixin:
"""Mix-in class for defining health thresholds.
Attributes:
NEUTRAL_THRESHOLD: The threshold beyond which the service is
considered to be in an error state.
OK_THRESHOLD: The threshold beyond which the service is
considered to be in a neutral state.
"""

NEUTRAL_THRESHOLD = None
OK_THRESHOLD = None

def __init__(self, **kwargs):
super().__init__(**kwargs)
self.ok_threshold = int(kwargs.get('ok_threshold', self.OK_THRESHOLD))
self.neutral_threshold = int(kwargs.get(
'neutral_threshold',
self.NEUTRAL_THRESHOLD
))
8 changes: 4 additions & 4 deletions flash_services/coveralls.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@
import requests

from .auth import Unauthenticated
from .core import Service
from .core import Service, ThresholdMixin
from .utils import occurred, remove_tags

logger = logging.getLogger(__name__)


class Coveralls(Unauthenticated, Service):
class Coveralls(Unauthenticated, ThresholdMixin, Service):
"""Show the current status of a Coveralls repository.
Arguments:
Expand All @@ -33,6 +33,8 @@ class Coveralls(Unauthenticated, Service):
"""

FRIENDLY_NAME = 'Coveralls'
NEUTRAL_THRESHOLD = 50
OK_THRESHOLD = 80
REQUIRED = {'vcs_name', 'account', 'repo'}
ROOT = 'https://coveralls.io'
TEMPLATE = 'coveralls-section'
Expand All @@ -42,8 +44,6 @@ def __init__(self, *, vcs_name, account, repo, **kwargs):
self.account = account
self.repo = repo
self.vcs_name = vcs_name
self.ok_threshold = kwargs.get('ok_threshold', 80)
self.neutral_threshold = kwargs.get('neutral_threshold', 50)

@property
def repo_name(self):
Expand Down
20 changes: 10 additions & 10 deletions flash_services/github.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import requests

from .auth import UrlParamMixin
from .core import CustomRootMixin, VersionControlService
from .core import CustomRootMixin, ThresholdMixin, VersionControlService
from .utils import naturaldelta, occurred, safe_parse


Expand Down Expand Up @@ -115,10 +115,12 @@ def format_commit(cls, commit):
))


class GitHubIssues(GitHub):
class GitHubIssues(ThresholdMixin, GitHub):
"""Show the current status of GitHub issues and pull requests."""

FRIENDLY_NAME = 'GitHub Issues'
NEUTRAL_THRESHOLD = 30
OK_THRESHOLD = 7
TEMPLATE = 'gh-issues-section'

def __init__(self, *, api_token, account, repo, **kwargs):
Expand All @@ -142,18 +144,17 @@ def update(self):
logger.error('failed to update GitHub issue data')
return {}

@classmethod
def format_data(cls, name, data):
def format_data(self, name, data):
counts = defaultdict(int)
for issue in data:
if issue.get('pull_request') is not None:
counts['{}-pull-requests'.format(issue['state'])] += 1
else:
counts['{}-issues'.format(issue['state'])] += 1
half_life = cls.half_life(data)
half_life = self.half_life(data)
return dict(
halflife=naturaldelta(half_life),
health=cls.health_summary(half_life),
health=self.health_summary(half_life),
issues=counts,
name=name,
)
Expand All @@ -180,8 +181,7 @@ def half_life(issues):
size = len(lives)
return lives[((size + (size % 2)) // 2) - 1]

@staticmethod
def health_summary(half_life):
def health_summary(self, half_life):
"""Calculate the health of the service.
Args:
Expand All @@ -195,9 +195,9 @@ def health_summary(half_life):
"""
if half_life is None:
return 'neutral'
if half_life < timedelta(weeks=1):
if half_life <= timedelta(days=self.ok_threshold):
return 'ok'
elif half_life < timedelta(days=30):
elif half_life <= timedelta(days=self.neutral_threshold):
return 'neutral'
return 'error'

Expand Down
2 changes: 1 addition & 1 deletion flash_services/templates/partials/gh-issues-section.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<span class="closed-pull-requests"></span>
</div>
<div class="pane-item">
<span class="item-title">Half life: </span>
<span class="item-title">&lambda;: </span>
<span class="half-life"></span>
</div>
</section>
16 changes: 14 additions & 2 deletions tests/test_github_issues_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,5 +130,17 @@ def test_update_failure(get, error, service):
),
),
])
def test_format_data(input_, expected):
assert GitHubIssues.format_data(*input_) == expected
def test_format_data(input_, expected, service):
assert service.format_data(*input_) == expected


def test_adjust_threshold():
service = GitHubIssues(ok_threshold=1, account='', repo='', api_token='')
assert service.ok_threshold == 1
assert service.neutral_threshold == 30
issues = [
{'state': 'closed', 'created_at': '2010/10/12', 'closed_at': '2010/10/15'},
]
assert service.format_data('', issues).get('health') == 'neutral'
service.neutral_threshold = 2
assert service.format_data('', issues).get('health') == 'error'

0 comments on commit ff455bd

Please sign in to comment.