diff --git a/.travis.yml b/.travis.yml index bcdfc72..1349da0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,6 @@ before_script: - pip install -Iv "codeclimate-test-reporter<4.4" script: - - python setup.py test - py.test --cov=deploybot test/ after_success: diff --git a/bitbucket-pipelines.yml b/bitbucket-pipelines.yml index a16d926..0ab9ffa 100644 --- a/bitbucket-pipelines.yml +++ b/bitbucket-pipelines.yml @@ -5,4 +5,4 @@ pipelines: - step: script: - pip install -r requirements.txt - - python setup.py test + - py.test --cov=deploybot test/ diff --git a/cli.py b/cli.py deleted file mode 100755 index 4562fea..0000000 --- a/cli.py +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -from cli.cli import main - -if __name__ == '__main__': - main() diff --git a/cli/__init__.py b/cli/__init__.py index 3a6e075..fe94c03 100644 --- a/cli/__init__.py +++ b/cli/__init__.py @@ -1,60 +1,4 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -from deploybot.client import Client -from deploybot.deploy import Deploy -from deploybot.user import User -from deploybot.repository import Repository -from deploybot.environment import Environment -from deploybot.server import Server -from .help import Help - import json -import tableprint -import copy -import os -import sys - - -def run(command): - account = os.environ.get('DEPLOYBOT_ACCOUNT') - token = os.environ.get('DEPLOYBOT_TOKEN') - client = Client(account, token) - - if command == "repository": - client = Repository(client) - elif command == "user": - client = User(client) - elif command == "environment": - client = Environment(client) - elif command == "deploy": - client = Deploy(client) - elif command == "server": - client = Server(client) - elif command == "help": - client = Help() - else: - raise IndexError("Command not found") - - return client - - -def headers(command): - if command == "repository": - headers = ('ID', 'Title', 'Name') - elif command == "user": - headers = ('ID', 'Name', 'Email', 'Admin') - elif command == "environment": - headers = ('ID', 'Repository ID', 'Environment Name', 'Branch', 'Automatic', 'Current') - elif command == "deploy": - headers = ('ID', 'Repository ID', 'Environment ID', 'State', 'Version') - elif command == "server": - headers = ('ID', 'Environment ID', 'Name', 'Protocol') - elif command == "help": - headers = ('Command', 'Description', 'Parameters') - else: - raise IndexError("Header not found") - - return headers def body(command, cmd, item): @@ -149,7 +93,7 @@ def body(command, cmd, item): else: raise IndexError("Body not found") - return body + return list(map(lambda x: unicode(x), body)) def response(cmd, param, result): @@ -166,35 +110,4 @@ def response(cmd, param, result): data.append(body(cmd, param, item)) - return data - - -def main(out=sys.stdout): - column_width = os.environ.get('COLUMN_WIDTH', 32) - style = os.environ.get('COLUMN_STYLE', 'fancy_grid') - - try: - arg1 = sys.argv[1] - args = copy.copy(sys.argv) - - args.pop(0) - args.pop(0) - - if arg1 == 'help': - cmd = 'list' - else: - cmd = args.pop(0) - - result = getattr(run(arg1), cmd)(*args) - header = headers(arg1) - data = response(arg1, cmd, result) - except Exception as e: - header = ('Error', 'Code') - data = [ - ( - str(e), - "try %s help" % sys.argv[0], - ) - ] - - tableprint.table(data, headers=header, width=int(column_width), style=style, out=out) + return data \ No newline at end of file diff --git a/cli/cli.py b/cli/cli.py new file mode 100644 index 0000000..6aaeaba --- /dev/null +++ b/cli/cli.py @@ -0,0 +1,17 @@ +import click +from .user import user +from .server import server +from .environment import environment +from .repository import repository +from .deploy import deploy + + +@click.group() +def cli(): + pass + +cli.add_command(user) +cli.add_command(server) +cli.add_command(environment) +cli.add_command(repository) +cli.add_command(deploy) diff --git a/cli/config.py b/cli/config.py new file mode 100644 index 0000000..a117beb --- /dev/null +++ b/cli/config.py @@ -0,0 +1,12 @@ +import os +from deploybot.client import Client + + +class Config(object): + + def __init__(self): + self.account = os.environ.get('DEPLOYBOT_ACCOUNT') + self.token = os.environ.get('DEPLOYBOT_TOKEN') + self.width = os.environ.get('COLUMN_WIDTH', 32) + self.style = os.environ.get('COLUMN_STYLE', 'fancy_grid') + self.client = Client(self.account, self.token) \ No newline at end of file diff --git a/cli/deploy.py b/cli/deploy.py new file mode 100644 index 0000000..ee25a1f --- /dev/null +++ b/cli/deploy.py @@ -0,0 +1,55 @@ +from deploybot.deploy import Deploy +from .config import Config +from . import response +from io import StringIO +import click +import tableprint + +output = StringIO() +pass_config = click.make_pass_decorator(Config, ensure=True) +header = ('ID', 'Repository ID', 'Environment ID', 'State', 'Version') + + +@click.group('deploy', short_help='Deploy commands') +def deploy(): + pass + + +@deploy.command('list') +@click.argument('repository', type=int) +@click.argument('environment', type=int) +@pass_config +def deploy_list(config, repository, environment): + """List deploys""" + client = Deploy(config.client) + result = client.list(repository, environment) + data = response('deploy', 'list', result) + + tableprint.table(data, headers=header, width=int(config.width), style=config.style, out=output) + click.echo(output.getvalue()) + + +@deploy.command('get') +@click.argument('id', type=int) +@pass_config +def deploy_get(config, id): + """Get info from deploy""" + client = Deploy(config.client) + result = client.get(id) + data = response('deploy', 'get', result) + + tableprint.table(data, headers=header, width=int(config.width), style=config.style, out=output) + click.echo(output.getvalue()) + + +@deploy.command('trigger') +@click.argument('id', type=int) +@pass_config +def deploy_get(config, id): + """Trigger a specific deploy""" + client = Deploy(config.client) + result = client.get(id) + data = response('deploy', 'trigger', result) + + tableprint.table(data, headers=header, width=int(config.width), style=config.style, out=output) + click.echo(output.getvalue()) diff --git a/cli/environment.py b/cli/environment.py new file mode 100644 index 0000000..5ea17de --- /dev/null +++ b/cli/environment.py @@ -0,0 +1,41 @@ +from deploybot.environment import Environment +from .config import Config +from . import response +from io import StringIO +import click +import tableprint + +output = StringIO() +pass_config = click.make_pass_decorator(Config, ensure=True) +header = ('ID', 'Repository ID', 'Environment Name', 'Branch', 'Automatic', 'Current') + + +@click.group('environment', short_help='Environment commands') +def environment(): + pass + + +@environment.command('list') +@click.argument('repository', type=int, required=False) +@pass_config +def environment_list(config, repository=None): + """List environments""" + client = Environment(config.client) + result = client.list(repository) + data = response('environment', 'list', result) + + tableprint.table(data, headers=header, width=int(config.width), style=config.style, out=output) + click.echo(output.getvalue()) + + +@environment.command('get') +@click.argument('id', type=int) +@pass_config +def environment_get(config, id): + """Get info from environment""" + client = Environment(config.client) + result = client.get(id) + data = response('environment', 'get', result) + + tableprint.table(data, headers=header, width=int(config.width), style=config.style, out=output) + click.echo(output.getvalue()) diff --git a/cli/help.py b/cli/help.py deleted file mode 100644 index d84723a..0000000 --- a/cli/help.py +++ /dev/null @@ -1,80 +0,0 @@ -# -*- coding: utf-8 -*- -from json import dumps - -""" -Help Class -""" - - -class Help(object): - """ - List help - :return string - """ - def list(self): - content = { - 'meta': { - 'total': 7 - }, - 'entries': [ - { - 'command': 'user list', - 'description': 'list users', - 'params': '' - }, - { - 'command': 'user get', - 'description': 'get user', - 'params': '[user_id]' - }, - { - 'command': 'deploy list', - 'description': 'list deployments', - 'params': '[repository_id] [environment_id]' - }, - { - 'command': 'deploy get', - 'description': 'get deploy', - 'params': '[deploy_id]' - }, - { - 'command': 'deploy trigger', - 'description': 'trigger deploy', - 'params': '[deploy_id]' - }, - { - 'command': 'environment list', - 'description': 'list environments', - 'params': '[repository_id]' - }, - { - 'command': 'environment get', - 'description': 'get environment', - 'params': '[enviroment_id]' - }, - { - 'command': 'repository list', - 'description': 'list repositories', - 'params': '' - }, - { - 'command': 'repository get', - 'description': 'get repository', - 'params': '' - }, - { - 'command': 'server list', - 'description': 'list servers', - 'params': '[repository_id] [environment_id]' - }, - { - 'command': 'server get', - 'description': 'get server', - 'params': '[server_id]' - } - ] - } - - result = dumps(content) - - return result diff --git a/cli/repository.py b/cli/repository.py new file mode 100644 index 0000000..9685fc5 --- /dev/null +++ b/cli/repository.py @@ -0,0 +1,40 @@ +from deploybot.repository import Repository +from .config import Config +from . import response +from io import StringIO +import click +import tableprint + +output = StringIO() +pass_config = click.make_pass_decorator(Config, ensure=True) +header = ('ID', 'Title', 'Name') + + +@click.group('repository', short_help='Repository commands') +def repository(): + pass + + +@repository.command('list') +@pass_config +def repository_list(config): + """List repositorys""" + client = Repository(config.client) + result = client.list() + data = response('repository', 'list', result) + + tableprint.table(data, headers=header, width=int(config.width), style=config.style, out=output) + click.echo(output.getvalue()) + + +@repository.command('get') +@click.argument('id', type=int) +@pass_config +def repository_get(config, id): + """Get info from repository""" + client = Repository(config.client) + result = client.get(id) + data = response('repository', 'get', result) + + tableprint.table(data, headers=header, width=int(config.width), style=config.style, out=output) + click.echo(output.getvalue()) diff --git a/cli/server.py b/cli/server.py new file mode 100644 index 0000000..8d4d753 --- /dev/null +++ b/cli/server.py @@ -0,0 +1,40 @@ +from deploybot.server import Server +from .config import Config +from . import response +from io import StringIO +import click +import tableprint + +output = StringIO() +pass_config = click.make_pass_decorator(Config, ensure=True) +header = ('ID', 'Environment ID', 'Name', 'Protocol') + + +@click.group('server', short_help='Server commands') +def server(): + pass + + +@server.command('list') +@pass_config +def server_list(config): + """List servers""" + client = Server(config.client) + result = client.list() + data = response('server', 'list', result) + + tableprint.table(data, headers=header, width=int(config.width), style=config.style, out=output) + click.echo(output.getvalue()) + + +@server.command('get') +@click.argument('id', type=int) +@pass_config +def server_get(config, id): + """Get info from server""" + client = Server(config.client) + result = client.get(id) + data = response('server', 'get', result) + + tableprint.table(data, headers=header, width=int(config.width), style=config.style, out=output) + click.echo(output.getvalue()) diff --git a/cli/user.py b/cli/user.py new file mode 100644 index 0000000..a032844 --- /dev/null +++ b/cli/user.py @@ -0,0 +1,40 @@ +from deploybot.user import User +from .config import Config +from . import response +from io import StringIO +import click +import tableprint + +output = StringIO() +pass_config = click.make_pass_decorator(Config, ensure=True) +header = ('ID', 'Name', 'Email', 'Admin') + + +@click.group('user', short_help='User account commands') +def user(): + pass + + +@user.command('list') +@pass_config +def user_list(config): + """List all users from account""" + client = User(config.client) + result = client.list() + data = response('user', 'list', result) + + tableprint.table(data, headers=header, width=int(config.width), style=config.style, out=output) + click.echo(output.getvalue()) + + +@user.command('get') +@click.argument('id') +@pass_config +def user_get(config, id): + """Get info from user""" + client = User(config.client) + result = client.get(id) + data = response('user', 'get', result) + + tableprint.table(data, headers=header, width=int(config.width), style=config.style, out=output) + click.echo(output.getvalue()) diff --git a/setup.py b/setup.py index 757f947..6a68a0c 100755 --- a/setup.py +++ b/setup.py @@ -1,11 +1,10 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- from setuptools import setup, find_packages setup( name="deploybot-cli", test_suite='test', - version='0.2.9', + version='0.3.0', description=u"Deploybot API Client", long_description=u"Deploybot terminal tool", classifiers=[], @@ -16,16 +15,16 @@ license='GPL', include_package_data=True, zip_safe=False, - packages=find_packages(), + packages=find_packages(exclude=['test']), install_requires=[ - 'python_http_client', 'tableprint', 'deploybot-sdk', + 'python_http_client', 'tableprint', 'deploybot-sdk', 'click' ], extras_require={ 'test': ['pytest', 'pytest-cov', 'mock', 'unittest-data-provider'], }, entry_points={ 'console_scripts': [ - 'deploybot = cli:main' + 'deploybot = cli.cli:cli' ] } ) diff --git a/test/cli_test.py b/test/cli_test.py index 5b4a423..badc832 100644 --- a/test/cli_test.py +++ b/test/cli_test.py @@ -1,14 +1,6 @@ -# -*- coding: utf-8 -*- from unittest import TestCase from unittest_data_provider import data_provider -from deploybot.deploy import Deploy -from deploybot.user import User -from deploybot.repository import Repository -from deploybot.environment import Environment -from deploybot.server import Server -from cli.help import Help - -import cli +from cli import body, response import mock import sys import json @@ -18,65 +10,9 @@ class TestCli(TestCase): - # Bootstrap def setUp(self): TestCase.setUp(self) - def test_run_raises_index_error_with_unknown_command(self): - self.assertRaises(IndexError, cli.run, ["default"]) - - def test_run_raises_type_error_without_command(self): - self.assertRaises(TypeError, cli.run) - - def test_run_return_class_with_valid_command(self): - self.assertIsInstance(cli.run("help"), object) - - commands = lambda: ( - ( - ("help", Help), - ("repository", Repository), - ("user", User), - ("environment", Environment), - ("deploy", Deploy), - ("server", Server), - ) - ) - - @data_provider(commands) - def test_run_return_class_with_valid_command(self, command="", instance=object): - result = cli.run(command) - - self.assertIsInstance(result, instance) - - def test_headers_raises_index_error_with_unknown_command(self): - self.assertRaises(IndexError, cli.headers, ["default"]) - - def test_headers_raises_type_error_without_command(self): - self.assertRaises(TypeError, cli.headers) - - commands = lambda: ( - ( - ("help", 3), - ("repository", 3), - ("user", 4), - ("environment", 6), - ("deploy", 5), - ("server", 4), - ) - ) - - @data_provider(commands) - def test_headers_return_return_with_valid_command(self, command="", size=0): - result = cli.headers(command) - - self.assertEquals(len(result), size) - - def test_body_raises_index_error_with_unknown_command(self): - self.assertRaises(IndexError, cli.body, *["default", "default", {}]) - - def test_body_raises_type_error_parameters(self): - self.assertRaises(TypeError, cli.body) - commands = lambda: ( ( ("help", "list", {'command': True, 'description': True, 'params': True}), @@ -105,7 +41,7 @@ def test_body_raises_type_error_parameters(self): @data_provider(commands) def test_body_return_class_with_valid_command(self, command="", parameter="", result={}): - self.assertIsInstance(cli.body(command, parameter, result), list) + self.assertIsInstance(body(command, parameter, result), list) def test_response_with_list_param(self): json_content = { @@ -130,7 +66,7 @@ def test_response_with_list_param(self): json_result = json.dumps(json_content) - self.assertNotEquals("", cli.response("user", "list", json_result)) + self.assertNotEquals("", response("user", "list", json_result)) def test_response_with_valid_get_parameter_return_valid(self): json_content = { @@ -147,22 +83,4 @@ def test_response_with_valid_get_parameter_return_valid(self): json_result = json.dumps(json_content) - self.assertNotEquals("", cli.response("user", "get", json_result)) - - def test_main(self): - sys.argv = [ - __file__, - 'help' - ] - result = cli.main(sys.stdout) - - self.assertNotEquals("", result) - - def test_main_without(self): - sys.argv = [ - __file__, - 'user' - ] - result = cli.main(sys.stdout) - - self.assertNotEquals("", result) + self.assertNotEquals("", response("user", "get", json_result)) diff --git a/test/config_test.py b/test/config_test.py new file mode 100644 index 0000000..24bce17 --- /dev/null +++ b/test/config_test.py @@ -0,0 +1,18 @@ +from unittest import TestCase +from cli.config import Config + +import os + + +class TestConfig(TestCase): + def setUp(self): + TestCase.setUp(self) + + def test_config_contains_default_attributes(self): + config = Config() + + self.assertEquals(config.width, 32) + self.assertEquals(config.style, 'fancy_grid') + self.assertIsInstance(config.client, object) + self.assertEquals(config.account, os.environ.get('DEPLOYBOT_ACCOUNT')) + self.assertEquals(config.token, os.environ.get('DEPLOYBOT_TOKEN')) diff --git a/test/deploy_test.py b/test/deploy_test.py new file mode 100644 index 0000000..1ff3813 --- /dev/null +++ b/test/deploy_test.py @@ -0,0 +1,30 @@ +from unittest import TestCase +from click.testing import CliRunner +from cli.deploy import deploy + + +class TestDeploy(TestCase): + def setUp(self): + TestCase.setUp(self) + + def test_deploy_list(self): + runner = CliRunner() + result = runner.invoke(deploy, ['list', '77289', '92033']) + + assert result.exit_code == 0 + assert result.output != "" + + def test_deploy_get(self): + runner = CliRunner() + result = runner.invoke(deploy, ['get', '7929622']) + + assert result.exit_code == 0 + assert result.output != "" + + def test_deploy_trigger(self): + self.skipTest('dont do this') + runner = CliRunner() + result = runner.invoke(deploy, ['trigger', '91944']) + + assert result.exit_code == 0 + assert result.output != "" diff --git a/test/environment_test.py b/test/environment_test.py new file mode 100644 index 0000000..65bdf0b --- /dev/null +++ b/test/environment_test.py @@ -0,0 +1,29 @@ +from unittest import TestCase +from click.testing import CliRunner +from cli.environment import environment + + +class TestEnvironment(TestCase): + def setUp(self): + TestCase.setUp(self) + + def test_environment_list_without_repository(self): + runner = CliRunner() + result = runner.invoke(environment, ['list']) + + assert result.exit_code == -1 + assert result.output == "" + + def test_environment_list_with_repository(self): + runner = CliRunner() + result = runner.invoke(environment, ['list', '106090']) + + assert result.exit_code == 0 + assert result.output != "" + + def test_environment_get(self): + runner = CliRunner() + result = runner.invoke(environment, ['get', '106090']) + + assert result.exit_code == 0 + assert result.output != "" diff --git a/test/help_test.py b/test/help_test.py deleted file mode 100644 index b6a3112..0000000 --- a/test/help_test.py +++ /dev/null @@ -1,15 +0,0 @@ -# -*- coding: utf-8 -*- -from unittest import TestCase -from cli.help import Help - - -class TestHelper(TestCase): - # Bootstrap - def setUp(self): - TestCase.setUp(self) - - self.help = Help() - - # test repositories list - def test_list_must_be_return_json(self): - self.assertNotEquals("", self.help.list()) \ No newline at end of file diff --git a/test/repository_test.py b/test/repository_test.py new file mode 100644 index 0000000..e4b1816 --- /dev/null +++ b/test/repository_test.py @@ -0,0 +1,22 @@ +from unittest import TestCase +from click.testing import CliRunner +from cli.repository import repository + + +class TestRepository(TestCase): + def setUp(self): + TestCase.setUp(self) + + def test_repository_list(self): + runner = CliRunner() + result = runner.invoke(repository, ['list']) + + assert result.exit_code == 0 + assert result.output != "" + + def test_repository_get(self): + runner = CliRunner() + result = runner.invoke(repository, ['get', '109294']) + + assert result.exit_code == 0 + assert result.output != "" diff --git a/test/server_test.py b/test/server_test.py new file mode 100644 index 0000000..c667fd3 --- /dev/null +++ b/test/server_test.py @@ -0,0 +1,22 @@ +from unittest import TestCase +from click.testing import CliRunner +from cli.server import server + + +class TestServer(TestCase): + def setUp(self): + TestCase.setUp(self) + + def test_server_list(self): + runner = CliRunner() + result = runner.invoke(server, ['list']) + + assert result.exit_code == 0 + assert result.output != "" + + def test_server_get(self): + runner = CliRunner() + result = runner.invoke(server, ['get', '125815']) + + assert result.exit_code == 0 + assert result.output != "" diff --git a/test/user_test.py b/test/user_test.py new file mode 100644 index 0000000..bceccb9 --- /dev/null +++ b/test/user_test.py @@ -0,0 +1,22 @@ +from unittest import TestCase +from click.testing import CliRunner +from cli.user import user + + +class TestUser(TestCase): + def setUp(self): + TestCase.setUp(self) + + def test_user_list(self): + runner = CliRunner() + result = runner.invoke(user, ['list']) + + assert result.exit_code == 0 + assert result.output != "" + + def test_user_get(self): + runner = CliRunner() + result = runner.invoke(user, ['get', '46964']) + + assert result.exit_code == 0 + assert result.output != ""