Skip to content

Commit

Permalink
Propose already set values when initialized is triggered again (#26)
Browse files Browse the repository at this point in the history
* Propose already set values when initialized is triggered again

* update docs
  • Loading branch information
trappitsch authored Mar 22, 2024
1 parent c95decb commit 68f4513
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 14 deletions.
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

0 comments on commit 68f4513

Please sign in to comment.