Просмотр исходного кода

refactor: use click for new-app prompts

version-14
Ankush Menat 3 лет назад
committed by Ankush Menat
Родитель
Сommit
53f54c3761
2 измененных файлов: 34 добавлений и 36 удалений
  1. +5
    -4
      frappe/tests/test_boilerplate.py
  2. +29
    -32
      frappe/utils/boilerplate.py

+ 5
- 4
frappe/tests/test_boilerplate.py Просмотреть файл

@@ -4,6 +4,7 @@ import glob
import os
import shutil
import unittest
from io import StringIO
from unittest.mock import patch

import frappe
@@ -80,20 +81,20 @@ class TestBoilerPlate(unittest.TestCase):
user_inputs.extend(value)
else:
user_inputs.append(value)
return user_inputs
return StringIO("\n".join(user_inputs))

def test_simple_input_to_boilerplate(self):
with patch("builtins.input", side_effect=self.get_user_input_stream(self.default_user_input)):
with patch("sys.stdin", self.get_user_input_stream(self.default_user_input)):
hooks = _get_inputs(self.default_hooks.app_name)
self.assertDictEqual(hooks, self.default_hooks)

def test_invalid_inputs(self):
invalid_inputs = copy.deepcopy(self.default_user_input).update(
invalid_inputs = copy.copy(self.default_user_input).update(
{
"title": ["1nvalid Title", "valid title"],
}
)
with patch("builtins.input", side_effect=self.get_user_input_stream(invalid_inputs)):
with patch("sys.stdin", self.get_user_input_stream(invalid_inputs)):
hooks = _get_inputs(self.default_hooks.app_name)
self.assertEqual(hooks.app_title, "valid title")



+ 29
- 32
frappe/utils/boilerplate.py Просмотреть файл

@@ -4,6 +4,7 @@
import os
import re

import click
import git

import frappe
@@ -29,47 +30,43 @@ def _get_inputs(app_name):
hooks.app_name = app_name
app_title = hooks.app_name.replace("_", " ").title()

NEW_APP_CONFIG = {
"app_title": {"prompt": "App Title (default: {0})".format(app_title)},
new_app_config = {
"app_title": {
"prompt": "App Title".format(app_title),
"default": app_title,
"validator": is_valid_title,
},
"app_description": {"prompt": "App Description"},
"app_publisher": {"prompt": "App Publisher"},
"app_email": {"prompt": "App Email"},
"app_icon": {"prompt": "App Icon (default 'octicon octicon-file-directory')"},
"app_color": {"prompt": "App Color (default 'grey')"},
"app_license": {"prompt": "App License (default 'MIT')"},
"app_icon": {"prompt": "App Icon", "default": "octicon octicon-file-directory"},
"app_color": {"prompt": "App Color", "default": "grey"},
"app_license": {"prompt": "App License", "default": "MIT"},
}

for property, config in NEW_APP_CONFIG.items():
hook_val = None
while not hook_val:
hook_val = cstr(input(config["prompt"] + ": "))

if not hook_val:
defaults = {
"app_title": app_title,
"app_icon": "octicon octicon-file-directory",
"app_color": "grey",
"app_license": "MIT",
}
if property in defaults:
hook_val = defaults[property]

if property == "app_name" and hook_val.lower().replace(" ", "_") != hook_val:
print("App Name must be all lowercase and without spaces")
hook_val = ""
elif property == "app_title" and not re.match(
r"^(?![\W])[^\d_\s][\w -]+$", hook_val, re.UNICODE
):
print(
"App Title should start with a letter and it can only consist of letters, numbers, spaces and underscores"
)
hook_val = ""

hooks[property] = hook_val
for property, config in new_app_config.items():
value = None
while value is None:
value = click.prompt(
config["prompt"], default=config.get("default"), type=config.get("type", str)
)
if validator_function := config.get("validator"):
if not validator_function(value):
value = None
hooks[property] = value

return hooks


def is_valid_title(title) -> bool:
if not re.match(r"^(?![\W])[^\d_\s][\w -]+$", title, re.UNICODE):
print(
"App Title should start with a letter and it can only consist of letters, numbers, spaces and underscores"
)
return False
return True


def _create_app_boilerplate(dest, hooks, no_git=False):
frappe.create_folder(
os.path.join(dest, hooks.app_name, hooks.app_name, frappe.scrub(hooks.app_title)), with_init=True


Загрузка…
Отмена
Сохранить