Skip to content

Commit

Permalink
Merge pull request #11 from robertopreste/issue_9
Browse files Browse the repository at this point in the history
Add --repo option
  • Loading branch information
robertopreste committed Dec 19, 2019
2 parents c2ac2d1 + 6f3afa7 commit 94579c5
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 48 deletions.
6 changes: 6 additions & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,9 @@ History

* Add ``--branch`` option to check for specific branch;
* Update documentation.

0.4.0 (2019-12-12)
==================

* Add ``--repo`` option to check for a specific repository;
* Update repository.
9 changes: 8 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,13 @@ If you want to monitor one specific branch of your repositories (suppose you hav
$ quickci status --branch dev

If the ``--branch`` option is not provided, the build status of the ``master`` branch will be retrieved by default.

If you want to check one specific repository, you can provide the ``--repo <reponame>`` option::

$ quickci status --repo my_repo

It is obviously possible to combine the ``--repo`` and ``--branch`` options to check a given branch of a specific repository.

It is also possible to check a specific service using subcommands of ``quickci status``::

$ quickci status travis
Expand All @@ -89,7 +96,7 @@ It is also possible to check a specific service using subcommands of ``quickci s
$ quickci status buddy
$ quickci status drone

These subcommands also accept the ``--branch`` option.
These subcommands also accept the ``--branch`` and ``--repo`` options.
If the token for a specific service is not listed in ``~/.config/quickci/tokens.json``, it is possible to provide it using the ``--token <service_token>`` option::

$ quickci status travis --token <TravisCI token>
Expand Down
13 changes: 10 additions & 3 deletions docs/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@ If you want to monitor one specific branch of your repositories (suppose you hav
$ quickci status --branch dev

If the ``--branch`` option is not provided, the build status of the ``master`` branch will be retrieved by default.

If you want to check one specific repository, you can provide the ``--repo <reponame>`` option::

$ quickci status --repo my_repo

It is obviously possible to combine the ``--repo`` and ``--branch`` options to check a given branch of a specific repository.

It is also possible to check a specific service using subcommands of ``quickci status``::

$ quickci status travis
Expand All @@ -46,11 +53,11 @@ It is also possible to check a specific service using subcommands of ``quickci s
$ quickci status buddy
$ quickci status drone

These subcommands also accept the ``--branch`` option::
These subcommands also accept the ``--branch`` and ``--repo`` options::

$ quickci status travis --branch master
$ quickci status circle --branch feature1
$ quickci status drone --branch new_feature
$ quickci status circle --branch feature1 --repo my_repo
$ quickci status drone --branch new_feature --repo my_other_repo

If you have not set up a config file, you can still retrieve information from CI services providing their authentication token right into the command::

Expand Down
90 changes: 67 additions & 23 deletions quickci/classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import json
import os
import requests
from typing import List, Tuple, Dict, Any
from typing import List, Tuple, Dict, Any, Optional


class _CIService:
Expand All @@ -23,14 +23,20 @@ class _CIService:
_token: Authentication token.
_url: Base url for API requests.
_branch: Branch to check (default: master).
_repo: Repository to check (default: None).
_found: Whether the given branch has at least one build
(default: False).
"""

def __init__(self, token: str, url: str, branch: str):
def __init__(self,
token: str,
url: str,
branch: str,
repo: Optional[str]):
self._token = token
self._url = url
self._branch = branch
self._repo = repo
self._found = False

@property
Expand Down Expand Up @@ -66,9 +72,12 @@ async def aget(host: str,
class TravisCI(_CIService):
"""Class used to get and manipulate data from the TravisCI platform."""

def __init__(self, token: str = "replace_me", branch: str = "master"):
def __init__(self,
token: str = "replace_me",
branch: str = "master",
repo: Optional[str] = None):
url = "https://api.travis-ci.com"
super().__init__(token, url, branch)
super().__init__(token, url, branch, repo)

@property
def headers(self) -> Dict[str, str]:
Expand Down Expand Up @@ -132,7 +141,10 @@ def status(self):
return
projs = self.projects()
loop = asyncio.get_event_loop()
tasks = [self.astatus(el) for el in projs]
if self._repo:
tasks = [self.astatus(el) for el in projs if el[0] == self._repo]
else:
tasks = [self.astatus(el) for el in projs]
loop.run_until_complete(asyncio.gather(*tasks))
if self._found is False:
click.secho("\tNo build found.", fg="magenta")
Expand All @@ -142,9 +154,12 @@ def status(self):
class CircleCI(_CIService):
"""Class used to get and manipulate data from the CircleCI platform."""

def __init__(self, token: str = "replace_me", branch: str = "master"):
def __init__(self,
token: str = "replace_me",
branch: str = "master",
repo: Optional[str] = None):
url = "https://circleci.com/api/v1.1"
super().__init__(token, url, branch)
super().__init__(token, url, branch, repo)

@property
def headers(self) -> Dict[str, str]:
Expand Down Expand Up @@ -191,8 +206,12 @@ def status(self):
projs = self.projects()
loop = asyncio.get_event_loop()
executor = ThreadPoolExecutor()
tasks = [loop.run_in_executor(executor, self.astatus, repo)
for repo in projs]
if self._repo:
tasks = [loop.run_in_executor(executor, self.astatus, repo)
for repo in projs if repo.get("reponame") == self._repo]
else:
tasks = [loop.run_in_executor(executor, self.astatus, repo)
for repo in projs]
asyncio.gather(*tasks)
if self._found is False:
click.secho("\tNo build found.", fg="magenta")
Expand All @@ -202,9 +221,12 @@ def status(self):
class AppVeyor(_CIService):
"""Class used to get and manipulate data from the AppVeyor platform."""

def __init__(self, token: str = "replace_me", branch: str = "master"):
def __init__(self,
token: str = "replace_me",
branch: str = "master",
repo: Optional[str] = None):
url = "https://ci.appveyor.com/api"
super().__init__(token, url, branch)
super().__init__(token, url, branch, repo)

@property
def headers(self) -> Dict[str, str]:
Expand Down Expand Up @@ -253,9 +275,17 @@ def status(self):
"directly using `--token`.", fg="red")
return
projs = self.projects()
account = projs[0].get("accountName")
try:
account = projs[0].get("accountName")
except IndexError: # no projects in AppVeyor
click.secho("\tNo projects found.", fg="magenta")
return
loop = asyncio.get_event_loop()
tasks = [self.astatus(el.get("slug"), account) for el in projs]
if self._repo:
tasks = [self.astatus(el.get("slug"), account)
for el in projs if el.get("slug") == self._repo]
else:
tasks = [self.astatus(el.get("slug"), account) for el in projs]
loop.run_until_complete(asyncio.gather(*tasks))
if self._found is False:
click.secho("\tNo build found.", fg="magenta")
Expand All @@ -265,9 +295,12 @@ def status(self):
class Buddy(_CIService):
"""Class used to get and manipulate data from the Buddy platform."""

def __init__(self, token: str = "replace_me", branch: str = "master"):
def __init__(self,
token: str = "replace_me",
branch: str = "master",
repo: Optional[str] = None):
url = "https://api.buddy.works"
super().__init__(token, url, branch)
super().__init__(token, url, branch, repo)

@property
def headers(self) -> Dict[str, str]:
Expand Down Expand Up @@ -342,7 +375,11 @@ def status(self):
return
projs = self.projects()
loop = asyncio.get_event_loop()
tasks = [self.astatus(repo) for repo in projs]
if self._repo:
tasks = [self.astatus(repo)
for repo in projs if repo == self._repo]
else:
tasks = [self.astatus(repo) for repo in projs]
loop.run_until_complete(asyncio.gather(*tasks))
if self._found is False:
click.secho("\tNo build found.", fg="magenta")
Expand All @@ -352,9 +389,12 @@ def status(self):
class DroneCI(_CIService):
"""Class used to get and manipulate data from the Drone CI platform."""

def __init__(self, token: str = "replace_me", branch: str = "master"):
def __init__(self,
token: str = "replace_me",
branch: str = "master",
repo: Optional[str] = None):
url = "https://cloud.drone.io/api"
super().__init__(token, url, branch)
super().__init__(token, url, branch, repo)

@property
def headers(self) -> Dict[str, str]:
Expand Down Expand Up @@ -415,7 +455,11 @@ def status(self):
return
projs = self.projects()
loop = asyncio.get_event_loop()
tasks = [self.astatus(repo) for repo in projs]
if self._repo:
tasks = [self.astatus(repo)
for repo in projs if repo == self._repo]
else:
tasks = [self.astatus(repo) for repo in projs]
loop.run_until_complete(asyncio.gather(*tasks))
if self._found is False:
click.secho("\tNo build found.", fg="magenta")
Expand Down Expand Up @@ -493,10 +537,10 @@ class Config:

DEFAULT_CONFIG = """
{
"TRAVISCI_TOKEN": "replace_me",
"CIRCLECI_TOKEN": "replace_me",
"APPVEYOR_TOKEN": "replace_me",
"BUDDY_TOKEN": "replace_me",
"TRAVISCI_TOKEN": "replace_me",
"CIRCLECI_TOKEN": "replace_me",
"APPVEYOR_TOKEN": "replace_me",
"BUDDY_TOKEN": "replace_me",
"DRONE_TOKEN": "replace_me"
}
"""
Expand Down
48 changes: 27 additions & 21 deletions quickci/commands/status.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,30 @@

@click.group(invoke_without_command=True)
@click.option("--branch", "-b", help="Branch to check", default="master")
@click.option("--repo", "-r", help="Repo to check", default=None)
@click.pass_context
def status(ctx, branch):
def status(ctx, branch, repo):
"""Return the status of the given branch of each project in each CI."""
ctx.obj = Config()

if ctx.invoked_subcommand is None:
ctx.invoke(travis, branch=branch)
ctx.invoke(circle, branch=branch)
ctx.invoke(appveyor, branch=branch)
ctx.invoke(buddy, branch=branch)
ctx.invoke(drone, branch=branch)
ctx.invoke(travis, branch=branch, repo=repo)
ctx.invoke(circle, branch=branch, repo=repo)
ctx.invoke(appveyor, branch=branch, repo=repo)
ctx.invoke(buddy, branch=branch, repo=repo)
ctx.invoke(drone, branch=branch, repo=repo)
pass


@status.command(short_help="Show status of Travis CI projects.")
@click.option("--token", "-t", help="Travis CI auth token", default=None)
@click.option("--branch", "-b", help="Branch to check", default="master")
@click.option("--repo", "-r", help="Repo to check", default=None)
@click.pass_obj
def travis(obj, token, branch):
def travis(obj, token, branch, repo):
"""Return the status of the given branch of each project in Travis CI."""
ci = TravisCI(token=token, branch=branch) \
if token else TravisCI(token=obj["travis"], branch=branch)
ci = TravisCI(token=token, branch=branch, repo=repo) \
if token else TravisCI(token=obj["travis"], branch=branch, repo=repo)
click.secho(f"Travis CI ({branch} branch)", bold=True, fg="blue")
ci.status()
return 0
Expand All @@ -37,11 +39,12 @@ def travis(obj, token, branch):
@status.command(short_help="Show status of CircleCI projects.")
@click.option("--token", "-t", help="CircleCI auth token", default=None)
@click.option("--branch", "-b", help="Branch to check", default="master")
@click.option("--repo", "-r", help="Repo to check", default=None)
@click.pass_obj
def circle(obj, token, branch):
def circle(obj, token, branch, repo):
"""Return the status of the given branch of each project in CircleCI."""
ci = CircleCI(token=token, branch=branch) \
if token else CircleCI(token=obj["circle"], branch=branch)
ci = CircleCI(token=token, branch=branch, repo=repo) \
if token else CircleCI(token=obj["circle"], branch=branch, repo=repo)
click.secho(f"CircleCI ({branch} branch)", bold=True, fg="blue")
ci.status()
return 0
Expand All @@ -50,11 +53,12 @@ def circle(obj, token, branch):
@status.command(short_help="Show status of AppVeyor projects.")
@click.option("--token", "-t", help="AppVeyor auth token", default=None)
@click.option("--branch", "-b", help="Branch to check", default="master")
@click.option("--repo", "-r", help="Repo to check", default=None)
@click.pass_obj
def appveyor(obj, token, branch):
def appveyor(obj, token, branch, repo):
"""Return the status of the given branch of each project in AppVeyor."""
ci = AppVeyor(token=token, branch=branch) \
if token else AppVeyor(token=obj["appveyor"], branch=branch)
ci = AppVeyor(token=token, branch=branch, repo=repo) \
if token else AppVeyor(token=obj["appveyor"], branch=branch, repo=repo)
click.secho(f"AppVeyor ({branch} branch)", bold=True, fg="blue")
ci.status()
return 0
Expand All @@ -63,11 +67,12 @@ def appveyor(obj, token, branch):
@status.command(short_help="Show status of Buddy projects.")
@click.option("--token", "-t", help="Buddy auth token", default=None)
@click.option("--branch", "-b", help="Branch to check", default="master")
@click.option("--repo", "-r", help="Repo to check", default=None)
@click.pass_obj
def buddy(obj, token, branch):
def buddy(obj, token, branch, repo):
"""Return the status of the given branch of each project in Buddy."""
ci = Buddy(token=token, branch=branch) \
if token else Buddy(token=obj["buddy"], branch=branch)
ci = Buddy(token=token, branch=branch, repo=repo) \
if token else Buddy(token=obj["buddy"], branch=branch, repo=repo)
click.secho(f"Buddy ({branch} branch)", bold=True, fg="blue")
ci.status()
return 0
Expand All @@ -76,11 +81,12 @@ def buddy(obj, token, branch):
@status.command(short_help="Show status of Drone CI projects.")
@click.option("--token", "-t", help="Drone CI auth token", default=None)
@click.option("--branch", "-b", help="Branch to check", default="master")
@click.option("--repo", "-r", help="Repo to check", default=None)
@click.pass_obj
def drone(obj, token, branch):
def drone(obj, token, branch, repo):
"""Return the status of the given branch of each project in Drone CI."""
ci = DroneCI(token=token, branch=branch) \
if token else DroneCI(token=obj["drone"], branch=branch)
ci = DroneCI(token=token, branch=branch, repo=repo) \
if token else DroneCI(token=obj["drone"], branch=branch, repo=repo)
click.secho(f"Drone CI ({branch} branch)", bold=True, fg="blue")
ci.status()
return 0

0 comments on commit 94579c5

Please sign in to comment.