Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Propose already set values when initialized is triggered again #26

Merged
merged 2 commits into from
Mar 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ If you provided all the answers, your project should have been successfully init
To still specify variables, just set them using the arguments discussed in the table above.
And if you are happy with all the defaults, you should be good to do.

!!! note
If you re-initalize a project, `box` will use the already set values as proposed default values.
If you re-initialize in quiet mode and just give one new option, all other options will stay the same.

## Packaging

To package your project, simply run:
Expand Down
10 changes: 8 additions & 2 deletions src/box/config.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Parse the pyproject.toml file

from collections import OrderedDict
from pathlib import Path
from typing import Any, Dict, Union

Expand Down Expand Up @@ -70,15 +71,19 @@ def optional_pyapp_variables(self) -> Dict:
return {}

@property
def possible_app_entries(self) -> Dict:
def possible_app_entries(self) -> OrderedDict:
"""Return [project.gui-scripts] or [project.scripts] entry if available.

If no entry is available, return None. If more than one entry available,
return a list of all entries.

:return: A list of possible entry points or None.
"""
possible_entries = {}
possible_entries = OrderedDict()
try:
possible_entries["current-default"] = {"current": self.app_entry}
except KeyError:
pass
try:
possible_entries["gui-scripts"] = self._project["gui-scripts"]
except KeyError:
Expand All @@ -87,6 +92,7 @@ def possible_app_entries(self) -> Dict:
possible_entries["scripts"] = self._project["scripts"]
except KeyError:
pass
print(possible_entries)
return possible_entries

@property
Expand Down
51 changes: 42 additions & 9 deletions src/box/initialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ def initialize(self):
def _set_app_entry(self):
"""Set the app entry for the project."""
possible_entries = self.pyproj.possible_app_entries

# create a list of possible entries
options = []
sup_keys = possible_entries.keys() # outside keys
Expand Down Expand Up @@ -111,6 +112,12 @@ def query_app_entry(query_txt, opts: List) -> None:

def _set_app_entry_type(self):
"""Set the app entry type for the PyApp packaging. Defaults to `spec`."""
default_entry_type = "spec"
try:
default_entry_type = self.pyproj.app_entry_type
except KeyError:
pass

if self._app_entry_type:
if self._app_entry_type.lower() not in ut.PYAPP_APP_ENTRY_TYPES:
raise click.ClickException(
Expand All @@ -121,12 +128,12 @@ def _set_app_entry_type(self):
entry_type = self._app_entry_type.lower()
else:
if self._quiet:
entry_type = "spec"
entry_type = default_entry_type
else:
entry_type = click.prompt(
"Choose an entry type for the project in PyApp.",
type=click.Choice(ut.PYAPP_APP_ENTRY_TYPES),
default="spec",
default=default_entry_type,
)

pyproject_writer("entry_type", entry_type)
Expand All @@ -135,16 +142,22 @@ def _set_builder(self):
"""Set the builder for the project (defaults to rye)."""
possible_builders = PackageApp().builders

default_builder = "rye"
try:
default_builder = self.pyproj.builder
except KeyError:
pass

if self._builder:
builder = self._builder
else:
if self._quiet:
builder = "rye"
builder = default_builder
else:
builder = click.prompt(
"Choose a builder tool for the project.",
type=click.Choice(possible_builders),
default="rye",
default=default_builder,
)

pyproject_writer("builder", builder)
Expand All @@ -153,23 +166,36 @@ def _set_builder(self):

def _set_optional_deps(self):
"""Set optional dependencies for the project (if any)."""
if (tmp := self.pyproj.optional_dependencies) is not None:
default_optional_deps = tmp
else:
default_optional_deps = ""

if self._optional_deps:
opt_deps = self._optional_deps
else:
if self._quiet:
opt_deps = ""
opt_deps = default_optional_deps
else:
opt_deps = click.prompt(
"Provide any optional dependencies for the project.",
type=str,
default="",
default=default_optional_deps,
)

if opt_deps != "":
pyproject_writer("optional_deps", opt_deps)

def _set_optional_pyapp_variables(self):
"""Set optional environmental variables for PyApp."""
default_opt_vars = ""
try:
tmp = self.pyproj.optional_pyapp_variables
for key, value in tmp.items():
default_opt_vars += f"{key} {value} "
except KeyError:
pass

opt_vars = None
if self._opt_paypp_vars:
opt_vars = self._opt_paypp_vars
Expand All @@ -178,11 +204,13 @@ def _set_optional_pyapp_variables(self):
"Please enter optional PyApp variables to set. "
"Example: `PYAPP_SKIP_INSTALL 1 PYAPP_FULL_ISOLATION 1",
type=str,
default="",
default=default_opt_vars,
)

if opt_vars == "":
opt_vars = None
else:
opt_vars = None if default_opt_vars == "" else default_opt_vars

if opt_vars:
opt_vars = opt_vars.split()
Expand Down Expand Up @@ -215,16 +243,21 @@ def _set_python_version(self):
Ask the user what python version to use. If none is provided (or quiet),
set the default to the latest python version.
"""
if (tmp := self.pyproj.python_version) is not None:
default_py_version = tmp
else:
default_py_version = ut.PYAPP_PYTHON_VERSIONS[-1]

if self._python_version:
py_version = self._python_version
else:
if self._quiet:
py_version = ut.PYAPP_PYTHON_VERSIONS[-1]
py_version = default_py_version
else:
py_version = click.prompt(
"Choose a python version for packaging the project with PyApp.",
type=click.Choice(ut.PYAPP_PYTHON_VERSIONS),
default=ut.PYAPP_PYTHON_VERSIONS[-1],
default=default_py_version,
)

pyproject_writer("python_version", py_version)
40 changes: 40 additions & 0 deletions tests/cli/test_cli_initialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,46 @@ def test_initialize_with_options(rye_project_no_box):
assert pyproj.optional_pyapp_variables == {"PYAPP_FULL_ISOLATION": "1"}


def test_initialize_project_again(rye_project_no_box):
"""Initialization of a previous project sets defaults from previous config."""
builder = "build"
entry_point = "myapp:entry"
entry_type = "module"
optional_deps = "gui"
py_version = "3.8"
pyapp_vars = "PYAPP_FULL_ISOLATION 1"

runner = CliRunner()
runner.invoke(
cli,
[
"init",
"-e",
entry_point,
"-et",
entry_type,
"-py",
py_version,
"-opt",
optional_deps,
"-b",
builder,
"--opt-pyapp-vars",
pyapp_vars,
],
)

# now re-initialize with quiet and assure that the same options are set
runner.invoke(cli, ["init", "-q"])

pyproj = PyProjectParser()
assert pyproj.builder == builder
assert pyproj.python_version == py_version
assert pyproj.optional_dependencies == optional_deps
assert pyproj.app_entry == entry_point
assert pyproj.app_entry_type == entry_type


def test_initialize_project_quiet(rye_project_no_box):
"""Initialize a new project quietly."""
runner = CliRunner()
Expand Down
6 changes: 3 additions & 3 deletions tests/func/test_initialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@
from box.initialization import InitializeProject


def test_app_entry(rye_project):
def test_app_entry(rye_project_no_box):
"""Set the configuration in `pyproject.toml` to rye."""
init = InitializeProject(quiet=True)
init.initialize()

pyproj = PyProjectParser()
assert pyproj.app_entry == f"{rye_project.name}:run"
assert pyproj.app_entry == f"{rye_project_no_box.name}:run"


def test_set_builder(rye_project):
def test_set_builder(rye_project_no_box):
"""Set the configuration in `pyproject.toml` to rye."""
init = InitializeProject(quiet=True)
init.initialize()
Expand Down
Loading