[cli] Added init-project command and cli tests

This commit is contained in:
Maxime Alves LIRMM@home 2020-07-29 21:03:00 +02:00
parent 527d5c2e93
commit 4d02cf4acd
6 changed files with 173 additions and 21 deletions

View File

View File

@ -1,3 +1,8 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
__version__ = '0.1.0' __version__ = '0.1.0'
print(f'HalfAPI version:{__version__}')
def version():
return f'HalfAPI version:{__version__}'
if __name__ == '__main__':
print(version())

View File

@ -1,19 +1,10 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from halfapi.conf import (PROJECT_NAME, HOST, PORT,
PRODUCTION, BASE_DIR, DOMAINS)
from halfapi.db import (
Domain,
APIRouter,
APIRoute,
AclFunction,
Acl)
# builtins # builtins
import click import click
import uvicorn import uvicorn
import os import os
import sys import sys
import re
import importlib import importlib
from pprint import pprint from pprint import pprint
@ -22,16 +13,31 @@ CONTEXT_SETTINGS={
} }
@click.group(invoke_without_command=True, context_settings=CONTEXT_SETTINGS) @click.group(invoke_without_command=True, context_settings=CONTEXT_SETTINGS)
@click.option('--version', is_flag=True)
@click.pass_context @click.pass_context
def cli(ctx): def cli(ctx, version):
if version:
import halfapi
return click.echo(halfapi.version())
if ctx.invoked_subcommand is None: if ctx.invoked_subcommand is None:
return run() return run()
@click.option('--host', default=None)
@click.option('--host', default=HOST) @click.option('--port', default=None)
@click.option('--port', default=PORT)
@cli.command() @cli.command()
def run(host, port): def run(host, port):
from halfapi.conf import (PROJECT_NAME, HOST, PORT,
PRODUCTION, BASE_DIR)
if not host:
host = HOST
if not port:
port = PORT
port = int(port)
debug = reload = not PRODUCTION debug = reload = not PRODUCTION
log_level = 'info' if PRODUCTION else 'debug' log_level = 'info' if PRODUCTION else 'debug'
@ -58,16 +64,15 @@ def delete_domain(domain):
@click.option('--domain', default=None) @click.option('--domain', default=None)
@click.option('--update', default=False, is_flag=True) @click.option('--update', default=False, is_flag=True)
@click.option('--list', default=False, is_flag=True)
@cli.command() @cli.command()
def routes(domain, list, update): def routes(domain, update):
domains = DOMAINS if domain is None else [domain] domains = DOMAINS if domain is None else [domain]
if update: if update:
if not domain: if not domain:
click.echo('No domain name given, will update all active domains') click.echo('No domain name given, will update all active domains')
for domain in domains: for domain in domains:
update_db(domain) update_db(domain)
if list: else:
list_routes(domains) list_routes(domains)
@ -79,6 +84,27 @@ def list_routes(domains):
print('-', route) print('-', route)
def update_db(domain=None): def update_db(domain=None):
from halfapi.db import (
Domain,
APIRouter,
APIRoute,
AclFunction,
Acl)
global Domain, APIRouter, APIRoute, AclFunction, Acl
if domain is None:
from halfapi.conf import DOMAINS
click.echo('No domain name given, will update all active domains')
for domain in DOMAINS:
dbupdate_fct(domain)
sys.exit(0)
return dbupdate_fct(domain)
def dbupdate_fct(domain=None):
if domain is None: if domain is None:
click.echo('Missing domain', err=True) click.echo('Missing domain', err=True)
sys.exit(1) sys.exit(1)
@ -195,6 +221,32 @@ def update_db(domain=None):
except Exception as e: except Exception as e:
click.echo(e, err=True) click.echo(e, err=True)
@click.argument('project')
@click.option('--repo', default=None)
@cli.command()
def init_project(project, repo):
import pygit2
if not re.match('^[a-z0-9_]+$', project, re.I):
click.echo('Project name must match "^[a-z0-9_]+$", retry.', err=True)
sys.exit(1)
if os.path.exists(project):
click.echo(f'A file named {project} already exists, abort.', err=True)
sys.exit(1)
if repo is not None:
click.echo(f'Clone URL {repo} in directory {project}')
pygit2.clone_repository(
url=repo,
path=project
)
else:
click.echo(f'Initialize project repository in directory {project}')
pygit2.init_repository(project)
if __name__ == '__main__': if __name__ == '__main__':
cli() cli()

View File

@ -2,5 +2,3 @@
testpaths = tests halfapi testpaths = tests halfapi
addopts = --doctest-modules addopts = --doctest-modules
doctest_optionflags = ELLIPSIS doctest_optionflags = ELLIPSIS
env =
DEBUG=TRUE

46
tests/test_cli.py Normal file
View File

@ -0,0 +1,46 @@
#!/usr/bin/env python3
import os
import pytest
from click.testing import CliRunner
from halfapi.cli import cli
@pytest.fixture
def runner():
return CliRunner()
def test_cli(runner):
# Wrong command
with runner.isolated_filesystem():
r = runner.invoke(cli, ['foobar'])
assert r.exit_code == 2
# Test existing commands
with runner.isolated_filesystem():
r = runner.invoke(cli, ['--help'])
assert r.exit_code == 0
with runner.isolated_filesystem():
r = runner.invoke(cli, ['--version'])
assert r.exit_code == 0
with runner.isolated_filesystem():
r = runner.invoke(cli, ['dbupdate', '--help'])
assert r.exit_code == 0
with runner.isolated_filesystem():
r = runner.invoke(cli, ['init-project', '--help'])
assert r.exit_code == 0
with runner.isolated_filesystem():
r = runner.invoke(cli, ['run', '--help'])
assert r.exit_code == 0
with runner.isolated_filesystem():
r = runner.invoke(cli, ['domain', '--help'])
assert r.exit_code == 0
with runner.isolated_filesystem():
r = runner.invoke(cli, ['routes', '--help'])
assert r.exit_code == 0

View File

@ -0,0 +1,51 @@
#!/usr/bin/env python3
import os
import pytest
from click.testing import CliRunner
from halfapi.cli import cli
@pytest.fixture
def runner():
return CliRunner()
def test_init_project(runner):
# Missing argument (project)
r = runner.invoke(cli, ['init-project'])
assert r.exit_code == 2
with runner.isolated_filesystem():
# Fail : Wrong project name
r = runner.invoke(cli, ['init-project', 'test*-project'])
assert r.exit_code == 1
with runner.isolated_filesystem():
# Fail : Already existing folder
os.mkdir('testproject')
r = runner.invoke(cli, ['init-project', 'testproject'])
assert r.exit_code == 1
with runner.isolated_filesystem():
# Fail : Already existing nod
os.mknod('testproject')
r = runner.invoke(cli, ['init-project', 'testproject'])
assert r.exit_code == 1
with runner.isolated_filesystem():
# Success : New repo
r = runner.invoke(cli, ['init-project', 'testproject'])
assert r.exit_code == 0
assert os.path.isdir('testproject')
assert os.path.isdir('testproject/.git')
with runner.isolated_filesystem():
# Success : Cloned repo
import pygit2
pygit2.init_repository('testproject.git', bare=True)
assert os.path.isdir('testproject.git')
r = runner.invoke(cli, ['init-project', 'testproject', '--repo', './testproject.git'])
assert r.exit_code == 0
assert os.path.isdir('testproject')
assert os.path.isdir('testproject/.git')