aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGlandos <bugs-github@antipoul.fr>2021-06-06 14:30:52 +0200
committerGlandos <bugs-github@antipoul.fr>2021-06-06 15:13:21 +0200
commit74e222f1a1cbfc2fac102fefc1115e9d0a6586dc (patch)
tree86566065de2804457e698c9d32b5b2ee99d3d49e
parenteff871e83c5a82d17f48d148257e6ac95c8470d3 (diff)
downloadihatemoney-mirror-74e222f1a1cbfc2fac102fefc1115e9d0a6586dc.zip
ihatemoney-mirror-74e222f1a1cbfc2fac102fefc1115e9d0a6586dc.tar.gz
ihatemoney-mirror-74e222f1a1cbfc2fac102fefc1115e9d0a6586dc.tar.bz2
remove usage of Flask-Script
Use flask.cli instead with compatibility layer for existing commands, such as "runserver".
-rw-r--r--Makefile2
-rw-r--r--docs/installation.rst2
-rwxr-xr-xihatemoney/manage.py135
-rw-r--r--ihatemoney/tests/main_test.py28
-rw-r--r--setup.cfg7
5 files changed, 81 insertions, 93 deletions
diff --git a/Makefile b/Makefile
index 30de0dd..2e8c18f 100644
--- a/Makefile
+++ b/Makefile
@@ -38,7 +38,7 @@ update: remove-install-stamp install ## Update the dependencies
.PHONY: serve
serve: install ## Run the ihatemoney server
@echo 'Running ihatemoney on http://localhost:5000'
- $(PYTHON) -m ihatemoney.manage runserver
+ $(PYTHON) -m ihatemoney.manage run
.PHONY: test
test: install-dev ## Run the tests
diff --git a/docs/installation.rst b/docs/installation.rst
index 82ac12f..a366cbe 100644
--- a/docs/installation.rst
+++ b/docs/installation.rst
@@ -61,7 +61,7 @@ Test it
Once installed, you can start a test server::
- ihatemoney runserver
+ ihatemoney run
And point your browser at `http://localhost:5000 <http://localhost:5000>`_.
diff --git a/ihatemoney/manage.py b/ihatemoney/manage.py
index eb1e24c..805a07f 100755
--- a/ihatemoney/manage.py
+++ b/ihatemoney/manage.py
@@ -5,8 +5,8 @@ import os
import random
import sys
-from flask_migrate import Migrate, MigrateCommand
-from flask_script import Command, Manager, Option
+import click
+from flask.cli import FlaskGroup
from werkzeug.security import generate_password_hash
from ihatemoney.models import Project, db
@@ -14,31 +14,48 @@ from ihatemoney.run import create_app
from ihatemoney.utils import create_jinja_env
-class GeneratePasswordHash(Command):
+@click.group(cls=FlaskGroup, create_app=create_app)
+def cli():
+ """IHateMoney Management script"""
- """Get password from user and hash it without printing it in clear text."""
- def run(self):
- password = getpass.getpass(prompt="Password: ")
- print(generate_password_hash(password))
-
-
-class GenerateConfig(Command):
- def get_options(self):
- return [
- Option(
- "config_file",
- choices=[
- "ihatemoney.cfg",
- "apache-vhost.conf",
- "gunicorn.conf.py",
- "supervisord.conf",
- "nginx.conf",
- ],
- )
+@cli.command(
+ context_settings={"ignore_unknown_options": True, "allow_extra_args": True}
+)
+@click.pass_context
+def runserver(ctx):
+ """Deprecated, use the "run" command instead"""
+ click.secho(
+ '"runserver" is deprecated, please use the standard "run" flask command',
+ fg="red",
+ )
+ run = cli.get_command(ctx, "run")
+ ctx.forward(run)
+
+
+@click.command(name="generate_password_hash")
+def password_hash():
+ """Get password from user and hash it without printing it in clear text."""
+ password = getpass.getpass(prompt="Password: ")
+ print(generate_password_hash(password))
+
+
+@click.command()
+@click.argument(
+ "config_file",
+ type=click.Choice(
+ [
+ "ihatemoney.cfg",
+ "apache-vhost.conf",
+ "gunicorn.conf.py",
+ "supervisord.conf",
+ "nginx.conf",
]
+ ),
+)
+def generate_config(config_file):
+ """Generate front-end server configuration"""
- @staticmethod
def gen_secret_key():
return "".join(
[
@@ -49,59 +66,33 @@ class GenerateConfig(Command):
]
)
- def run(self, config_file):
- env = create_jinja_env("conf-templates", strict_rendering=True)
- template = env.get_template(f"{config_file}.j2")
+ env = create_jinja_env("conf-templates", strict_rendering=True)
+ template = env.get_template(f"{config_file}.j2")
- bin_path = os.path.dirname(sys.executable)
- pkg_path = os.path.abspath(os.path.dirname(__file__))
+ bin_path = os.path.dirname(sys.executable)
+ pkg_path = os.path.abspath(os.path.dirname(__file__))
- print(
- template.render(
- pkg_path=pkg_path,
- bin_path=bin_path,
- sys_prefix=sys.prefix,
- secret_key=self.gen_secret_key(),
- )
+ print(
+ template.render(
+ pkg_path=pkg_path,
+ bin_path=bin_path,
+ sys_prefix=sys.prefix,
+ secret_key=gen_secret_key(),
)
-
-
-class DeleteProject(Command):
- def run(self, project_name):
- demo_project = Project.query.get(project_name)
- db.session.delete(demo_project)
+ )
+
+
+@cli.command()
+@click.argument("project_name")
+def delete_project(project_name):
+ """Delete a project"""
+ project = Project.query.get(project_name)
+ if project is None:
+ click.secho(f'Project "{project_name}" not found', fg="red")
+ else:
+ db.session.delete(project)
db.session.commit()
-def main():
- QUIET_COMMANDS = ("generate_password_hash", "generate-config")
-
- exception = None
- backup_stderr = sys.stderr
- # Hack to divert stderr for commands generating content to stdout
- # to avoid confusing the user
- if len(sys.argv) > 1 and sys.argv[1] in QUIET_COMMANDS:
- sys.stderr = open(os.devnull, "w")
-
- try:
- app = create_app()
- Migrate(app, db)
- except Exception as e:
- exception = e
-
- # Restore stderr
- sys.stderr = backup_stderr
-
- if exception:
- raise exception
-
- manager = Manager(app)
- manager.add_command("db", MigrateCommand)
- manager.add_command("generate_password_hash", GeneratePasswordHash)
- manager.add_command("generate-config", GenerateConfig)
- manager.add_command("delete-project", DeleteProject)
- manager.run()
-
-
if __name__ == "__main__":
- main()
+ cli()
diff --git a/ihatemoney/tests/main_test.py b/ihatemoney/tests/main_test.py
index 06dbfac..f052ee0 100644
--- a/ihatemoney/tests/main_test.py
+++ b/ihatemoney/tests/main_test.py
@@ -1,4 +1,3 @@
-import io
import os
import smtplib
import socket
@@ -9,7 +8,7 @@ from sqlalchemy import orm
from ihatemoney import models
from ihatemoney.currency_convertor import CurrencyConverter
-from ihatemoney.manage import DeleteProject, GenerateConfig, GeneratePasswordHash
+from ihatemoney.manage import delete_project, generate_config, password_hash
from ihatemoney.run import load_configuration
from ihatemoney.tests.common.ihatemoney_testcase import BaseTestCase, IhatemoneyTestCase
@@ -82,28 +81,23 @@ class CommandTestCase(BaseTestCase):
- raise no exception
- produce something non-empty
"""
- cmd = GenerateConfig()
- for config_file in cmd.get_options()[0].kwargs["choices"]:
- with patch("sys.stdout", new=io.StringIO()) as stdout:
- cmd.run(config_file)
- print(stdout.getvalue())
- self.assertNotEqual(len(stdout.getvalue().strip()), 0)
+ runner = self.app.test_cli_runner()
+ for config_file in generate_config.params[0].type.choices:
+ result = runner.invoke(generate_config, config_file)
+ self.assertNotEqual(len(result.output.strip()), 0)
def test_generate_password_hash(self):
- cmd = GeneratePasswordHash()
- with patch("sys.stdout", new=io.StringIO()) as stdout, patch(
- "getpass.getpass", new=lambda prompt: "secret"
- ): # NOQA
- cmd.run()
- print(stdout.getvalue())
- self.assertEqual(len(stdout.getvalue().strip()), 189)
+ runner = self.app.test_cli_runner()
+ with patch("getpass.getpass", new=lambda prompt: "secret"):
+ result = runner.invoke(password_hash)
+ self.assertEqual(len(result.output.strip()), 94)
def test_demo_project_deletion(self):
self.create_project("demo")
self.assertEquals(models.Project.query.get("demo").name, "demo")
- cmd = DeleteProject()
- cmd.run("demo")
+ runner = self.app.test_cli_runner()
+ runner.invoke(delete_project, "demo")
self.assertEqual(len(models.Project.query.all()), 0)
diff --git a/setup.cfg b/setup.cfg
index 8446f90..044defe 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -32,7 +32,6 @@ install_requires =
Flask-Mail~=0.9
Flask-Migrate>=2.5.3,<3 # Not following semantic versioning (e.g. https://github.com/miguelgrinberg/flask-migrate/commit/1af28ba273de6c88544623b8dc02dd539340294b)
Flask-RESTful~=0.3
- Flask-Script~=2.0
Flask-SQLAlchemy~=2.4
Flask-WTF~=0.14,>=0.14.3 # See b76da172652da94c1f9c4b2fdd965375da8a2c3f
WTForms~=2.2.1,<2.3 # See #567
@@ -58,8 +57,12 @@ doc =
docutils==0.17.1
[options.entry_points]
+flask.commands =
+ generate_password_hash = ihatemoney.manage:password_hash
+ generate-config = ihatemoney.manage:generate_config
+
console_scripts =
- ihatemoney = ihatemoney.manage:main
+ ihatemoney = ihatemoney.manage:cli
paste.app_factory =
main = ihatemoney.run:main