Skip to content

Commit 3b64789

Browse files
authored
Merge pull request #2 from pyansys/feat/template
Turn into a cookiecutter template
2 parents 5c4d3d8 + 1fcbbe6 commit 3b64789

38 files changed

+1372
-1
lines changed

.github/dependabot.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: "pip"
4+
directory: "/requirements"
5+
schedule:
6+
interval: "daily"

.github/workflows/ci.yml

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
name: GitHub CI
2+
on:
3+
pull_request:
4+
push:
5+
tags:
6+
- "*"
7+
branches:
8+
- main
9+
10+
jobs:
11+
12+
style:
13+
name: Code style
14+
runs-on: ubuntu-latest
15+
steps:
16+
- uses: actions/checkout@v2
17+
- name: Set up Python
18+
uses: actions/setup-python@v2
19+
with:
20+
python-version: 3.7
21+
- name: Install dependencies
22+
run: |
23+
python -m pip install --upgrade pip tox
24+
- name: Test with tox
25+
run: tox -e style
26+
27+
28+
tests:
29+
name: Test baked project
30+
runs-on: ${{ matrix.os }}
31+
strategy:
32+
matrix:
33+
os: [windows-latest, ubuntu-latest]
34+
python-version: ["3.7", "3.8", "3.9", "3.10"]
35+
build-system: ["flit", "setuptools"]
36+
fail-fast: false
37+
38+
steps:
39+
- uses: actions/checkout@v2
40+
- name: Set up Python ${{ matrix.python-version }}
41+
uses: actions/setup-python@v2
42+
with:
43+
python-version: ${{ matrix.python-version }}
44+
45+
- name: Install dependencies
46+
run: python -m pip install --upgrade pip ${{ matrix.build-system }} tox tox-gh-actions
47+
48+
# Runs only the tox environment specified in tox.ini [gh-actions]
49+
- name: Test with tox-gh-actions
50+
run: tox
51+
52+
# Baked project actions are tested only for Linux-base OS
53+
- name: Install and configure act for Linux-based OS
54+
if: matrix.os == 'ubuntu-latest'
55+
run: |
56+
sudo apt-get install build-essential gcc
57+
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
58+
test -d ~/.linuxbrew && eval "$(~/.linuxbrew/bin/brew shellenv)"
59+
test -d /home/linuxbrew/.linuxbrew && eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"
60+
test -r ~/.bash_profile && echo "eval \"\$($(brew --prefix)/bin/brew shellenv)\"" >> ~/.bash_profile
61+
brew install act
62+
echo "-P ubuntu-latest=ghcr.io/catthehacker/ubuntu:act-latest" >> ~/.actrc
63+
64+
- name: Test flit baked project
65+
if: matrix.os == 'ubuntu-latest' && matrix.build-system == 'flit'
66+
run: |
67+
# Change to baked project directory
68+
cd output/test_bake_project_with_build_s0/cookies/bake00/pyproduct-library
69+
# Initialize it as git repository (pre-commit needs it)
70+
git config --global user.email "[email protected]"
71+
git config --global user.name "Your Name"
72+
git init && git add . && git commit -m "Init Python package"
73+
# TODO: Only filter out errors from tox command
74+
# act -j tests docs > act_output.log || true > act_output.log; grep -c ERROR act_output.log && cat act_output.log
75+
tox
76+
# Check package builds properly
77+
python -m pip install -r requirements/requirements_build.txt
78+
flit build
79+
python -m twine check dist/*
80+
81+
- name: Test poetry baked project
82+
if: matrix.os == 'ubuntu-latest' && matrix.build-system == 'poetry'
83+
run: |
84+
# Change to baked project directory
85+
cd output/test_bake_project_with_build_s1/cookies/bake00/pyproduct-library
86+
# Initialize it as git repository (pre-commit needs it)
87+
git config --global user.email "[email protected]"
88+
git config --global user.name "Your Name"
89+
git init && git add . && git commit -m "Init Python package"
90+
# TODO: Only filter out errors from tox command
91+
# act -j tests docs > act_output.log || true > act_output.log; grep -c ERROR act_output.log && cat act_output.log
92+
tox
93+
# Check package builds properly
94+
poetry run python -m pip install -r requirements/requirements_build.txt
95+
poetry build
96+
poetry run python -m twine check dist/*
97+
98+
- name: Test setuptools baked project
99+
if: matrix.os == 'ubuntu-latest' && matrix.build-system == 'setuptools'
100+
run: |
101+
# Change to baked project directory
102+
cd output/test_bake_project_with_build_s2/cookies/bake00/pyproduct-library
103+
# Initialize it as git repository (pre-commit needs it)
104+
git config --global user.email "[email protected]"
105+
git config --global user.name "Your Name"
106+
git init && git add . && git commit -m "Init Python package"
107+
# TODO: Only filter out errors from tox command
108+
# act -j tests docs > act_output.log || true > act_output.log; grep -c ERROR act_output.log && cat act_output.log
109+
tox
110+
# Check package builds properly
111+
python -m pip install -r requirements/requirements_build.txt
112+
python -m build
113+
python -m twine check dist/*

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,3 +156,6 @@ cython_debug/
156156
#.idea/
157157

158158
# End of https://www.toptal.com/developers/gitignore/api/python
159+
160+
# Ignore baked output cookies from debugging
161+
output/

.pre-commit-config.yaml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
repos:
2+
3+
- repo: https://github.com/psf/black
4+
rev: 22.1.0
5+
hooks:
6+
- id: black
7+
exclude: "^({{cookiecutter.project_name_slug}}/)"
8+
args: ["tests", "hooks"]
9+
10+
- repo: https://github.com/pycqa/isort
11+
rev: 5.10.1
12+
hooks:
13+
- id: isort
14+
args: [
15+
"--profile", "black",
16+
"--force-sort-within-sections",
17+
"--line-length", "100",
18+
"--section-default", "THIRDPARTY", "hooks", "tests"
19+
]
20+
21+
- repo: https://gitlab.com/PyCQA/flake8
22+
rev: 4.0.1
23+
hooks:
24+
- id: flake8
25+
args: ["tests", "hooks"]
26+
exclude: "^({{cookiecutter.project_name_slug}}/)"
27+
28+
- repo: https://github.com/codespell-project/codespell
29+
rev: v2.1.0
30+
hooks:
31+
- id: codespell
32+
33+
- repo: https://github.com/pycqa/pydocstyle
34+
rev: 6.1.1
35+
hooks:
36+
- id: pydocstyle
37+
additional_dependencies: [toml]
38+
args: ["--match-dir='^(hooks)'"]
39+
exclude: "^({{cookiecutter.project_name_slug}}/)|(tests/)"

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2022 ANSYS, Inc. All rights reserved.
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 0 additions & 1 deletion
This file was deleted.

README.rst

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
PyAnsys library as cookiecutter template
2+
========================================
3+
4+
This repository holds a `cookiecutter`_ template for
5+
creating a Python library. The process is fully interactive and the rendered
6+
project is compliant with the `PyAnsys Developer's guide`_.
7+
8+
9+
Requirements
10+
------------
11+
12+
Before creating your library, you will need to install `cookiecutter`_ via:
13+
14+
.. code:: bash
15+
16+
python -m pip install cookiecutter
17+
18+
19+
How to use
20+
----------
21+
22+
Once you have installed `cookiecutter`_, you can create a new Python library by
23+
calling this template using:
24+
25+
.. code:: bash
26+
27+
cookiecutter gh:pyansys/pyansys-template
28+
29+
Previous command will ask you to introduce different data regarding your new
30+
Python project. Some of these are already pre-defined but you can always change
31+
their value:
32+
33+
- **product_name**: the name of Ansys product (i.e. Product).
34+
- **product_name_slug**: product sanitized name (i.e. product).
35+
- **library_name**: the name of the product library (i.e. Library).
36+
- **library_name_slug**: library named sanitized (i.e. library).
37+
- **project_name_slug**: the project's directory name (i.e. pyproduct-library).
38+
- **pkg_name**: the name of the Python package/library (i.e. ansys-product-library).
39+
- **version**: the version of the package/library (i.e. 0.1.dev0).
40+
- **short_description**: a short description of the purpose/goal of the project.
41+
- **repository_url**: link to the repository where the source code will be hosted.
42+
- **requires_python**: choose the minimum required Python version among 3.7, 3.8, 3.9 or 3.10.
43+
- **build_system**: choose the build system among flit, poetry or setuptools.
44+
- **max_linelength**: maximum number of characters per line in the source code (i.e. 100).
45+
46+
47+
How to contribute
48+
-----------------
49+
50+
For developers, the requirements can be installed via:
51+
52+
.. code:: bash
53+
54+
python -m pip install -r requirements/requirements_dev.txt
55+
56+
The coding style checks and unit tests are executed via `tox`_. Simply execute:
57+
58+
.. code:: bash
59+
60+
tox
61+
62+
and all the environments (style and tests) will be checked.
63+
64+
65+
.. LINKS AND REFERENCES
66+
.. _cookiecutter: https://cookiecutter.readthedocs.io/en/latest/
67+
.. _PyAnsys Developer's guide: https://dev.docs.pyansys.com/
68+
.. _tox: https://tox.wiki/

cookiecutter.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"product_name": "product",
3+
"product_name_slug": "{{ cookiecutter.product_name | lower | slugify }}",
4+
"library_name": "library",
5+
"library_name_slug": "{{ cookiecutter.library_name | lower | slugify }}",
6+
"project_name_slug": "py{{ cookiecutter.product_name_slug }}-{{ cookiecutter.library_name_slug }}",
7+
"pkg_name": "ansys-{{ cookiecutter.product_name_slug }}-{{ cookiecutter.library_name_slug }}",
8+
"version": "0.1.dev0",
9+
"short_description": "A Python wrapper for Ansys {{ cookiecutter.product_name }} {{ cookiecutter.library_name }}",
10+
"repository_url": "https://github.com/pyansys/{{ cookiecutter.project_name_slug }}",
11+
"requires_python": ["3.7", "3.8", "3.9", "3.10"],
12+
"build_system": ["flit", "poetry", "setuptools"],
13+
"max_linelength": "100"
14+
}

hooks/post_gen_project.py

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
"""Post-processing script for cleaning the raw rendered project."""
2+
import os
3+
from pathlib import Path
4+
5+
import isort
6+
7+
ALLOWED_BUILD_SYSTEMS = ["flit", "poetry", "setuptools"]
8+
"""A list of all allowed build systems by the template."""
9+
10+
11+
def remove_tool_files(tool_name, basedir):
12+
"""
13+
Remove files matching given glob expression within desired base directory.
14+
15+
Parameters
16+
----------
17+
tool_name: str
18+
Name of the tool used as build system.
19+
basedir: Path
20+
Base directory path.
21+
22+
"""
23+
for filepath in basedir.glob(f"**/*_{tool_name}*"):
24+
filepath.unlink()
25+
26+
27+
def rename_tool_files(tool_name, basedir):
28+
"""Rename tool filenames within desired base directory.
29+
30+
Parameters
31+
----------
32+
tool_name: str
33+
Name of the tool used as build system.
34+
basedir: Path
35+
Base directory path.
36+
37+
"""
38+
for original_filepath in basedir.glob(f"**/*_{tool_name}*"):
39+
new_filename = original_filepath.name.replace(f"_{tool_name}", "")
40+
original_filepath.rename(Path(original_filepath.parent, new_filename))
41+
42+
43+
def main():
44+
"""Entry point of the script."""
45+
# Get baked project location path
46+
project_path = Path(os.getcwd())
47+
48+
# Get the desired build system
49+
build_system = "{{ cookiecutter.build_system }}"
50+
# TODO: warn user if using setup.py
51+
# if build_system == "setuptools":
52+
# raise Warning("Please, consider to update to pyproject.toml.")
53+
54+
# Remove non-desired build system files
55+
for tool in ALLOWED_BUILD_SYSTEMS:
56+
if tool != build_system:
57+
remove_tool_files(tool, project_path)
58+
59+
# Rename any files including tool name suffix
60+
rename_tool_files(build_system, project_path)
61+
62+
# Apply isort with desired config
63+
isort_config = isort.settings.Config(
64+
line_length=100,
65+
profile="black",
66+
)
67+
filepaths_list = [
68+
project_path / "doc/source/conf.py",
69+
]
70+
for filepath in filepaths_list:
71+
isort.api.sort_file(filepath, isort_config)
72+
73+
74+
if __name__ == "__main__":
75+
main()

hooks/pre_gen_project.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
"""Pre-processing script for cleaning the raw rendered project."""
2+
import subprocess
3+
import sys
4+
5+
6+
def install_package(package):
7+
"""
8+
Installs desired package in current Python environment.
9+
10+
Parameters
11+
----------
12+
package: str
13+
Name of the package.
14+
15+
"""
16+
subprocess.check_call(
17+
[sys.executable, "-m", "pip", "install", "--ignore-installed", package]
18+
)
19+
20+
21+
def main():
22+
"""Entry point of the script."""
23+
packages_list = ["isort"]
24+
for package in packages_list:
25+
install_package(package)
26+
27+
28+
if __name__ == "__main__":
29+
main()

0 commit comments

Comments
 (0)