Skip to content

Commit

Permalink
Added pybamm-cookiecutter CLI (#36)
Browse files Browse the repository at this point in the history
## Additions
+ Added a basic `cli` with an optional `--path` argument defining the
path generated project should reside within.
+ Added basic documentation for `cli` usage in `cli.py` and `README.md`.

## Removals
- Removed `models`, `entry points`, and `parameter sets` from the
project as they are now populated in the template.
- Removed the `project-tests` from `noxfile` and updated workflow to
only test the template.
- Removed the entry points from `pyproject.toml` and `pybamm` as a
dependency in the project.

## Usage 
To test this, check out this branch and inside the repository and do a
local `pipx` installation on your machine.
```bash 
git clone https://github.com/santacodes/pybamm-cookiecutter -b cli
cd pybamm-cookiecutter/
pipx install . 
```
After installation, the `CLI` will be available systemwide and can be
accessed using the `pybamm-cookiecutter` command.
For help references add the `-h` or `--help` flag, e.g.
`pybamm-cookiecutter --help` which would prompt with all the available
arguments.

Sub-task #26

---------

Co-authored-by: Agriya Khetarpal <74401230+agriyakhetarpal@users.noreply.github.com>
  • Loading branch information
santacodes and agriyakhetarpal authored Aug 15, 2024
1 parent 1c21cce commit b127ab7
Show file tree
Hide file tree
Showing 46 changed files with 182 additions and 1,079 deletions.
54 changes: 45 additions & 9 deletions .github/workflows/test_on_push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,14 @@ jobs:
- name: Install nox
run: uv pip install nox[uv]

- name: Set up Git
run: |
git config --global user.name "pybamm user"
git config --global user.email "pybammuser@pybamm.org"
- name: Test template generation
run: nox -s template-tests

- name: Test project
run: nox -s project-tests

- name: Run coverage tests
if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.12'
run: nox -s coverage
Expand Down Expand Up @@ -98,7 +100,6 @@ jobs:
- name: Check if the documentation can be built
run: nox -s docs


generated_project_tests:
needs: [template_test]
runs-on: ${{ matrix.os }}
Expand All @@ -121,12 +122,39 @@ jobs:
with:
python-version: ${{ matrix.python-version }}

- name: Set up uv
uses: yezz123/setup-uv@v4
with:
uv-venv: ".venv"

- name: Install copier and jinja2_time
run: python -m pip install copier jinja2_time
run: uv pip install copier jinja2-time

- name: Generate project
run: |
copier copy . ../pybamm-${{ matrix.backend }}-${{ matrix.vcs }} --data project_name=pybamm-${{ matrix.backend }}-${{ matrix.vcs }} --data project_slug=pybamm_${{ matrix.backend }}_${{ matrix.vcs }} --data backend=${{ matrix.backend }} --data vcs=${{ matrix.vcs }} --trust --defaults
copier copy . ../ --data project_name=pybamm-${{ matrix.backend }}-${{ matrix.vcs }} --data project_slug=pybamm_${{ matrix.backend }}_${{ matrix.vcs }} --data backend=${{ matrix.backend }} --data vcs=${{ matrix.vcs }} --trust --defaults
- name: Install nox
uses: wntrblm/nox@2024.04.15

- name: Test the generated project
working-directory: ../pybamm-${{ matrix.backend }}-${{ matrix.vcs }}
run: nox -s generated-project-tests

run_generated_project_doctests:
needs: [template_test]
runs-on: ubuntu-latest
name: Generated Project Doctests (ubuntu-latest / Python 3.12)

steps:
- name: Check out pybamm-cookiecutter repository
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: 3.12

- name: Set up uv
uses: yezz123/setup-uv@v4
Expand All @@ -136,6 +164,14 @@ jobs:
- name: Install nox
uses: wntrblm/nox@2024.04.15

- name: Test the generated project
working-directory: ../pybamm-${{ matrix.backend }}-${{ matrix.vcs }}
run: nox -s generated-project-tests
- name: Install copier and jinja2_time and generate a template with default values
run: |
uv pip install copier jinja2-time
copier copy . . --trust --defaults
- name: Check if the documentation can be built
working-directory: ./pybamm-example-project
run: |
git add .
git commit -am "initial commit"
nox -s docs
7 changes: 0 additions & 7 deletions LICENSES-bundled.txt

This file was deleted.

26 changes: 22 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,24 +26,42 @@
<!-- SPHINX-START -->
[![Powered by NumFOCUS](https://img.shields.io/badge/powered%20by-NumFOCUS-orange.svg?style=flat&colorA=E1523D&colorB=007D8A)](http://numfocus.org)
[![Copier](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/copier-org/copier/master/img/badge/badge-grayscale-inverted-border-red.json)](https://github.com/copier-org/copier)
[![Test template and generated project](https://github.com/pybamm-team/pybamm-cookie/actions/workflows/test_on_push.yml/badge.svg)](https://github.com/pybamm-team/pybamm-cookie/actions/workflows/test_on_push.yml)

This repository contains a `copier` template for battery modeling projects using PyBaMM, released under the [BSD-3-Clause license](https://github.com/pybamm-team/pybamm-cookiecutter/blob/main/LICENSE). Currently under active development.

## 📄 Using `pybamm-cookiecutter`

### Generating projects with `pybamm-cookiecutter` manually using copier
### Generating projects with `pybamm-cookiecutter`

This template is not on PyPI yet, so it cannot be installed through `pip` until the first release. Meanwhile, it can be used by cloning this repository and using `copier` to generate a project with this template.
#### Manually using copier

Install `copier` and `jinja2_time` extension using `pip`.
```bash
pip install copier jinja2-time
```
Generate a project from the `pybamm-cookiecutter` template.
**Note:** This requires an internet connection. You could manually clone the git repository and run the copy command, or just execute the copy command with the URL to the git repository.

```bash
copier copy https://github.com/pybamm-team/pybamm-cookiecutter.git name_of_your_project/ --trust
copier copy https://github.com/pybamm-team/pybamm-cookiecutter.git . --trust
# this will generate the project in the current working directory
copier copy https://github.com/pybamm-team/pybamm-cookiecutter.git path_to_copy_to/ --trust
# this will generate the project in the specified path
```
#### Using pipx (recommended)

You can generate a project by executing the `pipx run` command which doesn't need any package installations.
```bash
pipx run pybamm-cookiecutter --path /path_to_copy_to
```

Or if you wish to install the `pybamm-cookiecutter` package and then generate a project, you could do so with the help of following commands.
```bash
pipx install pybamm-cookiecutter # or pip install pybamm-cookiecutter
```
Navigate into the directory you want your project directory to reside in, or use `--path` argument to explicitly mention the path where you want your project to be generated.
```bash
pybamm-cookiecutter --path /path_to_copy_to
```

Copier will prompt you with various configurations and you may choose the ones that suit your use case.
Expand Down
50 changes: 0 additions & 50 deletions cookiecutter.json

This file was deleted.

12 changes: 9 additions & 3 deletions copier.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,13 @@ _jinja_extensions:

_subdirectory: template

_exclude:
- copier.yml

_tasks:
- git init -b {{branch}}
- git config user.name "{{full_name}}"
- git config user.email "{{email}}"
- command: git init -b {{branch}}
working_directory: "{{project_name}}"
- command: git config user.name {{full_name}}
working_directory: "{{project_name}}"
- command: git config user.email {{email}}
working_directory: "{{project_name}}"
5 changes: 0 additions & 5 deletions noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,6 @@ def run_template_generation(session):
"""Run tests for the template generation."""
install_and_run_tests(session, "tests/template_tests")

@nox.session(name="project-tests")
def run_project_tests(session):
"""Run the tests for testing project units"""
install_and_run_tests(session, "tests/project_tests")

@nox.session(name="coverage")
def run_coverage(session):
"""Run the coverage tests and generate an XML report."""
Expand Down
20 changes: 12 additions & 8 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ build-backend = "hatchling.build"
name = "pybamm-cookiecutter"
authors = [
{ name = "Agriya Khetarpal", email = "agriyakhetarpal@outlook.com" },
{ name = "Santhosh Sundaram", email = "santhoshsundaram9650@gmail.com" },
]
maintainers = [
{ name = "PyBaMM Team", email = "pybamm@pybamm.org" },
Expand All @@ -30,7 +31,7 @@ classifiers = [
"Typing :: Typed",
]
dynamic = ["version"]
dependencies = ["pybamm", "copier", "jinja2-time"]
dependencies = ["copier", "jinja2-time", "colorama"]

[project.optional-dependencies]
dev = [
Expand All @@ -55,26 +56,29 @@ docs = [
"sphinx-gallery",
]

[project.scripts]
pybamm-cookiecutter = "pybamm_cookiecutter.cli:pybamm_cookiecutter_cli"

[project.entry-points."pipx.run"]
pybamm-cookiecutter = "pybamm_cookiecutter.cli:pybamm_cookiecutter_cli"

[project.urls]
Homepage = "https://github.com/pybamm-team/pybamm-cookiecutter"
"Bug Tracker" = "https://github.com/pybamm-team/pybamm-cookiecutter/issues"
Discussions = "https://github.com/pybamm-team/pybamm-cookiecutter/discussions"
Changelog = "https://github.com/pybamm-team/pybamm-cookiecutter/releases"

[project.entry-points."parameter_sets"]
Chen2020 = "pybamm_cookiecutter.parameters.input.Chen2020:get_parameter_values"

[project.entry-points."models"]
SPM = "pybamm_cookiecutter.models.input.SPM:SPM"
BasicReservoir = "pybamm_cookiecutter.models.input.BasicReservoir:BasicReservoir"

[tool.hatch]
version.source = "vcs"
build.hooks.vcs.version-file = "src/pybamm_cookiecutter/_version.py"
envs.default.dependencies = [
"pybamm",
]

[tool.hatch.build.targets.wheel]
only-include = ["src/pybamm_cookiecutter", "/template", "copier.yml", "LICENSE", "LICENSES-bundled.txt"]
sources = ["src"]

[tool.mypy]
packages = [
"src/pybamm_cookiecutter",
Expand Down
11 changes: 3 additions & 8 deletions src/pybamm_cookiecutter/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,10 @@
"""
from __future__ import annotations

import pybamm

from ._version import version as __version__
from .entry_point import Model, parameter_sets, models
from pybamm_cookiecutter.cli import pybamm_cookiecutter_cli
from pybamm_cookiecutter._version import __version__

__all__ : list[str] = [
"__version__",
"pybamm",
"parameter_sets",
"Model",
"models",
"pybamm_cookiecutter_cli",
]
4 changes: 4 additions & 0 deletions src/pybamm_cookiecutter/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
if __name__ == "__main__":
from pybamm_cookiecutter.cli import pybamm_cookiecutter_cli

pybamm_cookiecutter_cli()
60 changes: 60 additions & 0 deletions src/pybamm_cookiecutter/cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import copier
import argparse
from pathlib import Path
from colorama import Fore
import os

project_root = Path(__file__).resolve().parent.parent
TEMPLATE = str(project_root)

def pybamm_cookiecutter_cli():
"""
Command Line Interface (CLI) for generating PyBaMM based projects using copier.
Parameters
----------
--path: pathlib.Path
Examples
-------
$ pybamm-cookiecutter
Generates a project in the current working directory of the terminal.
$ pybamm-cookiecutter --path /myproject
Generates a project in the `myproject` directory.
"""
try:
parser = argparse.ArgumentParser(description = "A copier template generator for PyBaMM based projects")
parser.add_argument(
"--path", type = str,
required = False,
default = os.getcwd(),
help = "The destination path for project generation. The default is the current working directory"
)

from pybamm_cookiecutter import __version__ as version
parser.add_argument(
'--version',
action='version',
version=f'PyBaMM Cookiecutter CLI Version - {version}'
)

parser.add_argument(
"--defaults",
action="store_true",
help="Whether to use default options for generating the template"
)
args = parser.parse_args()
destination_path = Path(args.path)

with copier.Worker(src_path = TEMPLATE, dst_path = destination_path, unsafe = True, defaults = args.defaults) as worker:
worker.run_copy()

except KeyboardInterrupt:
print(Fore.RED + "Execution stopped by the user" + Fore.RESET)
except Exception as error:
print(Fore.RED + "Error caused by an exception: " + Fore.RESET, error)
print(Fore.CYAN + "If you are unsure what the error is, feel free to open an issue at" + Fore.YELLOW +" - https://github.com/pybamm-team/pybamm-cookiecutter/issues" + Fore.RESET)

if __name__ == '__main__':

pybamm_cookiecutter_cli()
Loading

0 comments on commit b127ab7

Please sign in to comment.