Skip to content
Merged
1 change: 1 addition & 0 deletions changes/2115.misc.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The methods used for handling questions in the new project wizard have been refactored into a common utility.
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ Source = "https://github.com/beeware/briefcase"
briefcase = "briefcase.__main__:main"

[project.entry-points."briefcase.bootstraps"]
None = "briefcase.bootstraps.empty:EmptyBootstrap"
Toga = "briefcase.bootstraps.toga:TogaGuiBootstrap"
Console = "briefcase.bootstraps.console:ConsoleBootstrap"
PySide6 = "briefcase.bootstraps.pyside6:PySide6GuiBootstrap"
Expand Down
2 changes: 1 addition & 1 deletion src/briefcase/bootstraps/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ def pyproject_extra_content(self) -> str | None:
"""Additional TOML to add to the bottom of pyproject.toml."""

def post_generate(self, base_path: Path) -> None:
"""Code to run after the template has been generated.
"""Runs after the template has been generated.

This can be used to produce any additional files that the base
template doesn't provide.
Expand Down
79 changes: 40 additions & 39 deletions src/briefcase/commands/convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from packaging.utils import canonicalize_name

from ..config import is_valid_app_name
from .new import NewCommand, parse_project_overrides, titlecase
from .new import NewCommand, parse_project_overrides

if sys.version_info >= (3, 11): # pragma: no-cover-if-lt-py311
import tomllib
Expand Down Expand Up @@ -119,7 +119,7 @@ def input_app_name(self, override_value: str | None) -> str:
and override_value is None
):
app_name = canonicalize_name(self.pep621_data["name"])
self.prompt_divider(title="App name")
self.input.divider(title="App name")
self.input.prompt()
self.input.prompt(
f"Using value from PEP621 formatted pyproject.toml {app_name!r}"
Expand All @@ -134,9 +134,9 @@ def input_app_name(self, override_value: str | None) -> str:
f"app name of '{default}', but you can use another name if you want."
)

return self.input_text(
return self.input.text_question(
intro=intro,
variable="app name",
description="App name",
default=default,
validator=self.validate_app_name,
override_value=override_value,
Expand All @@ -147,8 +147,8 @@ def input_formal_name(self, app_name: str, override_value: str | None) -> str:

:returns: The source directory
"""
default = titlecase(" ".join(re.split("[-_]", app_name)))
return self.input_text(
default = (" ".join(re.split("[-_]", app_name))).title()
return self.input.text_question(
intro=(
"We need a formal name for your application. This is the name that "
"will be displayed to humans whenever the name of the application is "
Expand All @@ -158,7 +158,7 @@ def input_formal_name(self, app_name: str, override_value: str | None) -> str:
f"Based on the app name, we suggest a formal name of '{default}', but "
"you can use another name if you want."
),
variable="formal name",
description="Formal name",
default=default,
override_value=override_value,
)
Expand Down Expand Up @@ -215,9 +215,9 @@ def input_source_dir(
:returns: The source directory
"""
default, intro = self.get_source_dir_hint(app_name, module_name)
return self.input_text(
return self.input.text_question(
intro=intro,
variable="source directory",
description="Source directory",
default=default,
validator=partial(self.validate_source_dir, module_name),
override_value=override_value,
Expand Down Expand Up @@ -250,9 +250,9 @@ def input_test_source_dir(self, module_name, override_value) -> str:
else:
default = "tests"

return self.input_text(
return self.input.text_question(
intro=intro,
variable="test source directory",
description="Test source directory",
default=default,
validator=partial(self.validate_test_source_dir, module_name),
override_value=override_value,
Expand All @@ -270,16 +270,16 @@ def input_description(self, override_value: str | None) -> str:
if "description" in self.pep621_data and override_value is None:
description = self.pep621_data["description"]

self.prompt_divider(title="Description")
self.input.divider(title="Description")
self.input.prompt()
self.input.prompt(
f"Using value from PEP621 formatted pyproject.toml {description!r}"
)
return description

return self.input_text(
return self.input.text_question(
intro="Now, we need a one line description for your application.",
variable="description",
description="Description",
default="My first application",
override_value=override_value,
)
Expand All @@ -293,34 +293,34 @@ def input_url(self, app_name, override_value: str | None) -> str:

if not options or override_value:
default = self.make_project_url("com.example", app_name)
return self.input_text(
return self.input.text_question(
intro=(
"What website URL do you want to use for this application? Based "
f"on your existing 'pyproject.toml', this might be {default}"
),
variable="application URL",
description="Application URL",
default=default,
validator=validate_url,
override_value=override_value,
)

options.append("Other")
url = self.select_option(
url = self.input.selection_question(
intro=(
"What website URL do you want to use for this application? The "
"following URLs are defined in your existing 'pyproject.toml'; "
"select 'Other' to provide a different URL."
),
variable="application URL",
description="Application URL",
default=None,
options=options,
override_value=override_value,
)

if url == "Other":
url = self.input_text(
url = self.input.text_question(
intro="What website URL do you want to use for the application?",
variable="application URL",
description="Application URL",
default=self.make_project_url("com.example", app_name),
validator=validate_url,
)
Expand All @@ -337,10 +337,10 @@ def input_app_type(self, override_value: str | None) -> bool:
"console": "Console",
}
return (
self.select_option(
self.input.selection_question(
intro="Is this a GUI application or a console application?",
variable="interface style",
default=None,
description="Interface style",
default="gui",
options=options,
override_value=override_value.lower() if override_value else None,
)
Expand All @@ -349,7 +349,7 @@ def input_app_type(self, override_value: str | None) -> bool:

def input_bundle(self, url, app_name, override_value: str | None) -> str:
default = ".".join(reversed(urlparse(url).netloc.split(".")))
return self.input_text(
return self.input.text_question(
intro=(
"Now we need a bundle identifier for your application.\n"
"\n"
Expand All @@ -364,7 +364,7 @@ def input_bundle(self, url, app_name, override_value: str | None) -> str:
"application's machine readable name to form a complete application "
f"identifier ('{default}.{app_name}')."
),
variable="bundle identifier",
description="Bundle identifier",
default=default,
validator=self.validate_bundle,
override_value=override_value,
Expand All @@ -388,9 +388,9 @@ def input_author(self, override_value: str | None) -> str:
]

if not options or override_value is not None:
return self.input_text(
return self.input.text_question(
intro=intro,
variable="author",
description="Author",
default="Jane Developer",
override_value=override_value,
)
Expand All @@ -401,26 +401,27 @@ def input_author(self, override_value: str | None) -> str:

options.append("Other")

# We want to use the input_text-function if override_value is provided or if the selected author is "Other"
# However, since we don't want the select_option prompt if an override value is provided, we need to
# initialise the author variable here.
author = self.select_option(
# We want to use text_question if override_value is provided or if the selected
# author is "Other". However, since we don't want the selection_question prompt
# if an override value is provided, we need to initialise the author variable
# here.
author = self.input.selection_question(
intro=(
intro
+ "\n\n"
+ "We found these author names in the PEP621 formatted "
+ "'pyproject.toml'. Who do you want to be credited as the author of "
+ "this application?"
),
variable="Author",
description="Author",
options=options,
default=None,
override_value=None,
)
if author == "Other":
author = self.input_text(
author = self.input.text_question(
intro="Who do you want to be credited as the author of this application?",
variable="author",
description="Author",
default="Jane Developer",
override_value=None,
)
Expand All @@ -447,9 +448,9 @@ def input_email(self, author: str, bundle: str, override_value: str | None) -> s
f"we believe it could be '{default}'."
)

author_email = self.input_text(
author_email = self.input.text_question(
intro=intro,
variable="author's email",
description="Author's email",
default=default,
validator=self.validate_email,
override_value=override_value,
Expand Down Expand Up @@ -551,9 +552,9 @@ def input_license(self, override_value: str | None) -> str:
"Other",
]

return self.select_option(
return self.input.selection_question(
intro=intro,
variable="Project License",
description="Project license",
options=options,
default=default,
override_value=override_value,
Expand Down Expand Up @@ -715,7 +716,7 @@ def convert_app(
bootstrap = EmptyBootstrap(self.logger, self.input, context)
context.update(self.build_gui_context(bootstrap, project_overrides))

self.prompt_divider() # close the prompting section of output
self.input.divider() # close the prompting section of output

self.warn_unused_overrides(project_overrides)

Expand Down
2 changes: 1 addition & 1 deletion src/briefcase/commands/create.py
Original file line number Diff line number Diff line change
Expand Up @@ -910,7 +910,7 @@ def create_app(self, app: AppConfig, test_mode: bool = False, **options):
bundle_path = self.bundle_path(app)
if bundle_path.exists():
self.logger.info()
confirm = self.input.boolean_input(
confirm = self.input.boolean(
f"Application {app.app_name!r} already exists; overwrite", default=False
)
if not confirm:
Expand Down
Loading
Loading