[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
__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
from halfapi.conf import (PROJECT_NAME, HOST, PORT,
PRODUCTION, BASE_DIR, DOMAINS)
from halfapi.db import (
Domain,
APIRouter,
APIRoute,
AclFunction,
Acl)
# builtins
import click
import uvicorn
import os
import sys
import re
import importlib
from pprint import pprint
@ -22,16 +13,31 @@ CONTEXT_SETTINGS={
}
@click.group(invoke_without_command=True, context_settings=CONTEXT_SETTINGS)
@click.option('--version', is_flag=True)
@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:
return run()
@click.option('--host', default=HOST)
@click.option('--port', default=PORT)
@click.option('--host', default=None)
@click.option('--port', default=None)
@cli.command()
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
log_level = 'info' if PRODUCTION else 'debug'
@ -58,18 +64,17 @@ def delete_domain(domain):
@click.option('--domain', default=None)
@click.option('--update', default=False, is_flag=True)
@click.option('--list', default=False, is_flag=True)
@cli.command()
def routes(domain, list, update):
def routes(domain, update):
domains = DOMAINS if domain is None else [domain]
if update:
if not domain:
click.echo('No domain name given, will update all active domains')
for domain in domains:
update_db(domain)
if list:
else:
list_routes(domains)
def list_routes(domains):
for domain in domains:
@ -79,6 +84,27 @@ def list_routes(domains):
print('-', route)
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:
click.echo('Missing domain', err=True)
sys.exit(1)
@ -195,6 +221,32 @@ def update_db(domain=None):
except Exception as e:
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__':
cli()

View File

@ -2,5 +2,3 @@
testpaths = tests halfapi
addopts = --doctest-modules
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')