Skip to content

Commit

Permalink
feat: Add initial mechanism for conditional question (#291)
Browse files Browse the repository at this point in the history
  • Loading branch information
xmnlab authored May 27, 2024
1 parent 1bc2dbc commit 3591c9e
Show file tree
Hide file tree
Showing 4 changed files with 315 additions and 11 deletions.
2 changes: 1 addition & 1 deletion src/scicookie/profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def __init__(self, profile_name: str):

if profile_name not in self.profiles_available:
SciCookieLogs.raise_error(
"The given profiles is not available.",
f"The given profile ({profile_name}) is not available.",
SciCookieErrorType.SCICOOKIE_INVALID_PARAMETER,
)

Expand Down
15 changes: 10 additions & 5 deletions src/scicookie/ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,17 @@ def _create_question(
def check_dependencies_satisfied(
question: dict[str, Any], answers: dict[str, str]
) -> bool:
"""
Check if dependencies are satisfied.
"""Check if dependencies are satisfied."""
if "depends_on" not in question:
return True

Note: Not implemented yet.
"""
return True
depends_satisfied = True
for dep_key, dep_value in question.get("depends_on", {}).items():
if answers[dep_key] != dep_value:
depends_satisfied = False
break

return depends_satisfied


def sanitize_package_slug(package_slug: str) -> str:
Expand Down
242 changes: 242 additions & 0 deletions tests/profiles/test-depends-on.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,242 @@
author_full_name:
message: Type the author's name
help: https://osl-incubator.github.io/scicookie/guide/#information-about-the-project
type: text
default: Roronoa Zoro
visible: true

author_email:
message: Type the author's email
help: https://osl-incubator.github.io/scicookie/guide/#information-about-the-project
type: text
default: [email protected]
visible: true

project_name:
message: Type the project's title
help: https://osl-incubator.github.io/scicookie/guide/#information-about-the-project
type: text
default: OSL Python package
visible: true

project_short_description:
message: Type a short description about the project
help: https://osl-incubator.github.io/scicookie/guide/#information-about-the-project
type: text
default: This Project aims to ...
visible: true

project_slug:
message: Type the code name for your project (e.g. the repository name)
help: https://osl-incubator.github.io/scicookie/guide/#information-about-the-project
type: text
default: "myprojectslug"
visible: true

package_slug:
message: Type the code name for your package (the name used to import your package)
help: https://osl-incubator.github.io/scicookie/guide/#information-about-the-project
type: text
default: "mypackageslug"
visible: true

project_version:
message: Type the project version
help: https://osl-incubator.github.io/scicookie/guide/#information-about-the-project
type: text
default: 0.1.0
visible: true
depends_on:
package_slug: mypackageslug

project_url:
message: Type the project URL
help: https://osl-incubator.github.io/scicookie/guide/#information-about-the-project
type: text
default: "myproject.com"
visible: true
depends_on:
project_version: 1.0.0

project_license:
message: Select one option for the project license
help: https://osl-incubator.github.io/scicookie/guide/#information-about-the-project
type: single-choice
default: BSD 3 Clause
# first choice is the default for the UI
choices:
- BSD 3 Clause
- MIT
- ISC license
- Apache Software License 2.0
- GNU General Public License v3
- Other
visible: true

project_layout:
message: Select one option for the project layout
help: "For more information, check:\n https://osl-incubator.github.io/scicookie/guide/#project-layout"
type: single-choice
default: src
# first choice is the default for the UI
choices:
- src
- flat
visible: true

build_system:
message: Select one option for the build system
help: "For more information, check:\n https://osl-incubator.github.io/scicookie/guide/#build-system"
type: single-choice
default: poetry
# first choice is the default for the UI
choices:
- poetry
- flit
- mesonpy
- setuptools
- pdm
- hatch
- maturin
- scikit-build-core
- pybind11
visible: true

command_line_interface:
message: Select one option for Command Line Interface (CLI)
help: "For more information, check:\n https://osl-incubator.github.io/scicookie/guide/#command-line-interfaces-clis"
type: single-choice
default: None
# first choice is the default for the UI
choices:
- None
- Click
- Argparse
visible: true

documentation_engine:
message: Select one option for the Documentation Engine
help: "For more information, check:\n https://osl-incubator.github.io/scicookie/guide/#documentation-engine"
type: single-choice
default: mkdocs
# first choice is the default for the UI
choices:
- mkdocs
- sphinx
- jupyter-book
- quarto
visible: true

documentation_url:
message: Type the documentation URL
help: The URL for the documentation page.
type: text
default: "docs.myproject.com"
visible: true

use_tools:
message: Select all the initial tools you want to add to your project
help: "For more information, check:\n https://osl-incubator.github.io/scicookie/guide/#project-tools"
type: multiple-choices
choices:
- bandit
- black
- conda
- coverage
- flake8
- hypothesis
- isort
- make
- makim
- mccabe
- mypy
- pre-commit
- prettier
- pydocstyle
- pytest
- ruff
- shellcheck
- vulture
visible: true

use_containers:
message: Select one option for the container technology for this project
help: "For more information, check:\n https://osl-incubator.github.io/scicookie/guide/#integration-with-devops-tools"
type: single-choice
default: None
# first choice is the default for the UI
choices:
- None
- Docker
- Podman
visible: true

# doc_template:
# message: Select the template for the Documentation Engine
# help: ""
# default: Material

code_of_conduct:
message: Select one option for the Code of Conduct
help: "For more information, check:\n https://osl-incubator.github.io/scicookie/guide/#code-of-conduct"
type: single-choice
default: None
# first choice is the default for the UI
choices:
- None
- contributor-covenant
- citizen-code-of-conduct
- numfocus-adapted-coc
- python-adapted-coc
visible: true

governance_document:
message: Select one option for a governance document template
help: "For more information, check:\n https://osl-incubator.github.io/scicookie/guide/#governance-document"
type: single-choice
default: None
# first choice is the default for the UI
choices:
- None
- numpy-governance
- sciml-governance
visible: true

roadmap_document:
message: Select one option for a Roadmap document template
help: "For more information, check:\n https://osl-incubator.github.io/scicookie/guide/#roadmap-document"
type: single-choice
default: None
# first choice is the default for the UI
choices:
- None
- pytorch-ignite-roadmap
visible: true

git_username:
message: Type the GIT username
help: https://osl-incubator.github.io/scicookie/guide/#control-version
type: "text"
default: ""
visible: true

git_https_origin:
message: Type the GIT HTTPS origin URL
help: https://osl-incubator.github.io/scicookie/guide/#control-version
type: "text"
default: ""
visible: true

git_https_upstream:
message: Type the GIT HTTPS upstream URL
help: https://osl-incubator.github.io/scicookie/guide/#control-version
type: "text"
default: ""
visible: true

git_main_branch:
message: Type the GIT main branch
help: https://osl-incubator.github.io/scicookie/guide/#control-version
type: "text"
default: main
visible: true
67 changes: 62 additions & 5 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,20 @@ def tmp_dir() -> str:


@pytest.mark.skipif(not sys.platform.startswith("linux"), reason="Linux only")
class TestMain:
class BaseCLITestProfile:
"""Tests for test-main.yaml."""

profile_path: str
profile_path: str = ""
profile_filename: str = ""

@classmethod
def setup_class(cls):
"""Configure initial settings for the class."""
test_dir = Path(__file__).parent
src_dir = test_dir.parent / "src" / "scicookie"

profile_src_path = test_dir / "profiles" / "test-main.yaml"
cls.profile_path = src_dir / "profiles" / "test-main.yaml"
profile_src_path = test_dir / "profiles" / cls.profile_filename
cls.profile_path = src_dir / "profiles" / cls.profile_filename

shutil.copy(profile_src_path, cls.profile_path)

Expand All @@ -52,9 +53,16 @@ def teardown_class(cls):
"""Cleanup after test."""
cls.profile_path.unlink()


@pytest.mark.skipif(not sys.platform.startswith("linux"), reason="Linux only")
class TestMain(BaseCLITestProfile):
"""Tests for test-main.yaml."""

profile_filename: str = "test-main.yaml"

def test_cli(self, tmp_dir: str) -> None:
"""Test with test-main.yaml."""
all_questions = get_all_questions("test-main.yaml")
all_questions = get_all_questions(self.profile_filename)

child = pexpect.spawn(
"scicookie --profile test-main",
Expand All @@ -76,3 +84,52 @@ def test_cli(self, tmp_dir: str) -> None:
child.expect(pexpect.EOF)
output = child.before
assert "Traceback" not in output, output


@pytest.mark.skipif(not sys.platform.startswith("linux"), reason="Linux only")
class TestDependsOn(BaseCLITestProfile):
"""Tests for test-main.yaml."""

profile_filename: str = "test-depends-on.yaml"

def test_cli(self, tmp_dir: str) -> None:
"""Test with test-main.yaml."""
all_questions = get_all_questions(self.profile_filename)

child = pexpect.spawn(
"scicookie --profile test-depends-on",
cwd=tmp_dir,
encoding="utf-8",
timeout=10,
)

answers = {}

for key, value in all_questions.items():
depends_on = value.get("depends_on", {})
depends_on_satisfied = True

for dep_key, dep_val in depends_on.items():
if answers.get(dep_key, "") != dep_val:
depends_on_satisfied = False
break

if not depends_on_satisfied:
continue

prompt = value.get("message")

if not prompt:
continue

# Escape special characters and allow any whitespace after
regex_prompt = re.escape(prompt) + r"\s*"
# Use regex for matching the prompt
child.expect(regex_prompt, timeout=10)
response = value.get("default", "")
answers[key] = response
child.sendline(response)

child.expect(pexpect.EOF)
output = child.before
assert "Traceback" not in output, output

0 comments on commit 3591c9e

Please sign in to comment.