Skip to content

Commit

Permalink
PD-72 add packing dependency (#20)
Browse files Browse the repository at this point in the history
* add packing and remove wps dev
* add pyproject.toml from the template and not uv
* refactor placeholder names, cleanup unit tests
* update docs
  • Loading branch information
igor-sb authored Sep 3, 2024
1 parent 9835df7 commit 7af8196
Show file tree
Hide file tree
Showing 13 changed files with 185 additions and 449 deletions.
26 changes: 25 additions & 1 deletion docs/source/custom_templates.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ folder to the new project and also do the following:

- If *README.md* contains placeholder string *{{git_account_name}}*, it will
be replaced by git username.

- If there is *pyproject.toml* file, it will replace *{{placeholder_name}}* with
project name and *{{python_version}}* with a Python version from the CLI
argument.

Template directory can contain anything. However, for Bluprint configs to work,
it needs a folder to store yaml configs (default: *conf*) and another folder to
Expand All @@ -20,7 +24,27 @@ store data in the project to which relative paths in *data.yaml* point to
By default *bluprint_conf* function *load_config_yaml()* looks for
*conf/config.yaml* and *load_data_yaml()* looks for *conf/data.yaml* in the
project folder. You can use different names and override these defaults when
calling *bluprint_conf* functions, for example:
calling *bluprint_conf* functions, for example this template folder::

my_custom_template
├── configs
│ ├── my_main_config.yaml
│ └── my_data_config.yaml
├── my_data
│ └── ...
├── {{placeholder_name}}
│ └── my_code.py
├── README.md
└── pyproject.toml

can be used to create a new project:

.. code:: bash
bluprint create my_project --template-dir /path/to/my_custom_template
which can then be used:

.. code:: python
Expand Down
6 changes: 4 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "bluprint"
version = "0.3.0"
version = "0.3.1"
description = ""
authors = [
{name = "igor-sb"},
Expand All @@ -11,6 +11,7 @@ requires-python = "==3.11.*"
dependencies = [
"fire>=0.5.0",
"bluprint-conf>=0.1.0",
"packaging>=24.1",
]
classifiers = [
"Programming Language :: Python :: 3.11",
Expand All @@ -27,7 +28,6 @@ dev-dependencies = [
"pytest>=7.4.3",
"pytest-mock>=3.12.0",
"autopep8>=2.0.4",
"wemake-python-styleguide>=0.18.0",
"unify>=0.5",
"isort>=5.12.0",
"pre-commit>=3.5.0",
Expand Down Expand Up @@ -130,6 +130,7 @@ ignore = [
# "**/errors.py" = ["WPS202"]

[tool.mypy]
exclude = 'src/bluprint/template/*'
[[tool.mypy.overrides]]
module = [
"pandas.*",
Expand All @@ -138,3 +139,4 @@ module = [
"bluprint_conf.*",
]
ignore_missing_imports = true

30 changes: 23 additions & 7 deletions src/bluprint/create/py_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@
from bluprint.create.errors import LowPythonVersionError, PythonVersionError
from bluprint.project import copy_template
from bluprint.template import (
Placeholder,
activate_data_conf_proj_dirs,
default_template_dir,
replace_git_account_name_in_readme,
replace_placeholder_name_in_file,
replace_placeholder_in_file,
)

MIN_PYTHON_VERSION = '3.11'
Expand All @@ -36,6 +38,7 @@ def create_python_project(
template_dir=template_dir,
keep_r_files=keep_r_files,
omit_examples=omit_examples,
overwrite=True,
)


Expand Down Expand Up @@ -65,13 +68,22 @@ def initialize_python_project(
keep_r_files=keep_r_files,
overwrite=overwrite,
)
Path.rename(
Path(project_dir) / 'placeholder_name',
Path(project_dir) / project_name,
if (Path(project_dir) / Placeholder.project_name).exists():
Path.rename(
Path(project_dir) / Placeholder.project_name,
Path(project_dir) / project_name,
)
if not (Path(template_dir) / 'pyproject.toml').exists():
activate_data_conf_proj_dirs(Path(project_dir) / 'pyproject.toml')
replace_placeholder_in_file(
Path(project_dir) / 'pyproject.toml',
placeholder=Placeholder.project_name,
replacement=project_name,
)
replace_placeholder_name_in_file(
replace_placeholder_in_file(
Path(project_dir) / 'pyproject.toml',
project_name,
placeholder=Placeholder.python_version,
replacement=python_version,
)
if not omit_examples:
readme_file = Path(project_dir) / 'README.md'
Expand All @@ -82,7 +94,11 @@ def initialize_python_project(
]
for example_file in example_files_with_placeholder:
if example_file.exists():
replace_placeholder_name_in_file(example_file, project_name)
replace_placeholder_in_file(
example_file,
placeholder=Placeholder.project_name,
replacement=project_name,
)
if readme_file.exists():
replace_git_account_name_in_readme(readme_file)
uv_add(['bluprint_conf'], project_dir)
Expand Down
3 changes: 2 additions & 1 deletion src/bluprint/create/r_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from bluprint.binary import rcmd, renv_create_snapshot, renv_init, renv_install
from bluprint.colors import progress_log
from bluprint.create.errors import RpackageMissingError
from bluprint.template import Placeholder


@progress_log('creating R project', print_ok=False)
Expand All @@ -28,7 +29,7 @@ def initialize_r_project(
renv_install(r_packages, project_dir)
renv_create_snapshot(project_dir)
Path.rename(
Path(project_dir) / 'placeholder_name.Rproj',
Path(project_dir) / f'{Placeholder.project_name}.Rproj',
Path(project_dir) / f'{project_name}.Rproj',
)

Expand Down
23 changes: 18 additions & 5 deletions src/bluprint/template.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@
from bluprint.create.errors import GitError


class Placeholder(object):
project_name = '{{placeholder_name}}'
python_version = '{{python_version}}'


def example_files(project_name: str = 'placeholder_name') -> tuple[Path, ...]:
return (
Path('notebooks') / 'example_jupyternb.ipynb',
Expand All @@ -25,20 +30,20 @@ def example_files(project_name: str = 'placeholder_name') -> tuple[Path, ...]:

def r_files() -> tuple[Path, ...]:
return (
Path('placeholder_name.Rproj'),
Path(f'{Placeholder.project_name}.Rproj'),
Path('notebooks') / 'example_rmarkdown.Rmd',
)


def replace_placeholder_name_in_file(
def replace_placeholder_in_file(
filename: str | Path,
project_name: str,
placeholder='{{placeholder_name}}',
placeholder: str,
replacement: str,
) -> None:
file_lines = []
with Path(filename).open('r') as in_file:
for line in in_file:
file_lines.append(line.replace(placeholder, project_name))
file_lines.append(line.replace(placeholder, replacement))
with Path(filename).open('w') as out_file:
for line in file_lines:
out_file.write(line)
Expand Down Expand Up @@ -70,3 +75,11 @@ def default_template_dir() -> str:
template_dir = str(files('bluprint') / 'template')
styled_print(f'using template: {template_dir}')
return template_dir


def activate_data_conf_proj_dirs(pyproject_toml: str | Path) -> None:
with Path(pyproject_toml).open('a') as pyproject_toml_file:
pyproject_toml_file.write('[tool.setuptools]\n')
pyproject_toml_file.write(
f'packages = ["conf", "data", "{Placeholder.project_name}"]',
)
21 changes: 14 additions & 7 deletions tests/create/test_create_py.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@

from bluprint import cli
from bluprint.create.errors import LowPythonVersionError
from bluprint.template import default_template_dir, example_files
from bluprint.template import Placeholder, default_template_dir, example_files


def test_create_py_project(find_files_in_dir, tmp_path):
template_dir = default_template_dir()
project_name = 'placeholder_name'
project_name = 'test_project'
cli.Bluprint().create(
project_name=project_name,
parent_dir=tmp_path,
Expand All @@ -23,14 +23,17 @@ def test_create_py_project(find_files_in_dir, tmp_path):
for file_path in find_files_in_dir(project_dir)
}
template_files = {
file_path.relative_to(template_dir)
Path(
str(file_path.relative_to(template_dir))
.replace(Placeholder.project_name, project_name)
)
for file_path in find_files_in_dir(template_dir)
}
template_files.update([
Path('pyproject.toml'),
Path('uv.lock'),
])
template_files.remove(Path(f'{project_name}.Rproj')) # Python-only test
template_files.remove(Path(f'{project_name}.Rproj'))
template_files.remove(Path('notebooks/example_rmarkdown.Rmd'))

venv_dir = project_dir / '.venv'
Expand All @@ -47,7 +50,7 @@ def test_low_python_version():

def test_create_py_project_without_examples(find_files_in_dir, tmp_path):
template_dir = default_template_dir()
project_name = 'placeholder_name'
project_name = 'test_project'
cli.Bluprint().create(
project_name=project_name,
parent_dir=tmp_path,
Expand All @@ -60,7 +63,10 @@ def test_create_py_project_without_examples(find_files_in_dir, tmp_path):
}
project_example_files = example_files(project_name)
template_files = {
file_path.relative_to(template_dir)
Path(
str(file_path.relative_to(template_dir))
.replace(Placeholder.project_name, project_name)
)
for file_path in find_files_in_dir(template_dir)
if file_path.relative_to(template_dir) not in project_example_files
}
Expand All @@ -69,7 +75,7 @@ def test_create_py_project_without_examples(find_files_in_dir, tmp_path):
Path('uv.lock'),
])

template_files.remove(Path('placeholder_name.Rproj')) # Python-only test
template_files.remove(Path(f'{project_name}.Rproj')) # Python-only test

venv_dir = project_dir / '.venv'
assert project_files == template_files
Expand Down Expand Up @@ -119,3 +125,4 @@ def test_create_py_project_custom_template(find_files_in_dir, tmp_path):
assert (project_dir / 'readme.md').read_text().strip() == 'read me!'
assert (project_dir / 'placeholder_name' / 'test.py').read_text() \
== 'print("hello!")'
assert (project_dir / 'pyproject.toml').exists()
9 changes: 6 additions & 3 deletions tests/create/test_create_r.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
from bluprint import cli
from bluprint.create.errors import RpackageMissingError
from bluprint.create.r_project import check_if_r_package_is_installed
from bluprint.template import default_template_dir
from bluprint.template import Placeholder, default_template_dir


def test_create_pyr_project(find_files_in_dir, tmp_path):
template_dir = default_template_dir()
project_name = 'placeholder_name'
project_name = 'test_project'
cli.Bluprint().create(
project_name=project_name,
parent_dir=tmp_path,
Expand All @@ -23,7 +23,10 @@ def test_create_pyr_project(find_files_in_dir, tmp_path):
for file_path in find_files_in_dir(tmp_path / project_name)
}
template_files = {
file_path.relative_to(template_dir)
Path(
str(file_path.relative_to(template_dir))
.replace(Placeholder.project_name, project_name)
)
for file_path in find_files_in_dir(template_dir)
}
template_files.update([
Expand Down
23 changes: 16 additions & 7 deletions tests/init/test_init_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@

from bluprint import cli
from bluprint.errors import ProjectExistsError
from bluprint.template import default_template_dir, example_files
from bluprint.template import Placeholder, default_template_dir, example_files


def test_init_py_project(find_files_in_dir, tmp_path):
template_dir = default_template_dir()
project_name = 'placeholder_name'
project_name = 'test_project'
project_dir = tmp_path / project_name
project_dir.mkdir()
cli.Bluprint().init(
Expand All @@ -23,7 +23,10 @@ def test_init_py_project(find_files_in_dir, tmp_path):
for file_path in find_files_in_dir(project_dir)
}
template_files = {
file_path.relative_to(template_dir)
Path(
str(file_path.relative_to(template_dir))
.replace(Placeholder.project_name, project_name)
)
for file_path in find_files_in_dir(template_dir)
}
template_files.update([
Expand All @@ -41,7 +44,7 @@ def test_init_py_project(find_files_in_dir, tmp_path):

def test_init_pyr_project(find_files_in_dir, tmp_path):
template_dir = default_template_dir()
project_name = 'placeholder_name'
project_name = 'test_project'
project_dir = tmp_path / project_name
project_dir.mkdir()
cli.Bluprint().init(
Expand All @@ -54,7 +57,10 @@ def test_init_pyr_project(find_files_in_dir, tmp_path):
for file_path in find_files_in_dir(tmp_path / project_name)
}
template_files = {
file_path.relative_to(template_dir)
Path(
str(file_path.relative_to(template_dir))
.replace(Placeholder.project_name, project_name)
)
for file_path in find_files_in_dir(template_dir)
}
template_files.update([
Expand Down Expand Up @@ -83,7 +89,7 @@ def test_init_existing_with_pyproject_toml(tmp_path):


def test_init_existing_without_examples_with_yamls(find_files_in_dir, tmp_path):
project_name = 'placeholder_name'
project_name = 'test_project'
project_dir = tmp_path / project_name
project_dir.mkdir()
(project_dir / 'data').mkdir()
Expand All @@ -101,7 +107,10 @@ def test_init_existing_without_examples_with_yamls(find_files_in_dir, tmp_path):
template_dir = default_template_dir()
project_example_files = example_files(project_name)
template_files = {
file_path.relative_to(template_dir)
Path(
str(file_path.relative_to(template_dir))
.replace(Placeholder.project_name, project_name)
)
for file_path in find_files_in_dir(template_dir)
if file_path.relative_to(template_dir) not in project_example_files
}
Expand Down
Loading

0 comments on commit 7af8196

Please sign in to comment.