[cli] Added init-project command and cli tests
This commit is contained in:
parent
527d5c2e93
commit
4d02cf4acd
|
@ -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())
|
||||||
|
|
|
@ -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,18 +64,17 @@ 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)
|
||||||
|
|
||||||
|
|
||||||
def list_routes(domains):
|
def list_routes(domains):
|
||||||
for domain in domains:
|
for domain in 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()
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
|
@ -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
|
|
@ -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')
|
Loading…
Reference in New Issue