Skip to content

Commit d58d9e7

Browse files
committed
Merge remote-tracking branch 'upstream/master' into drivendataorg-master
* upstream/master: (24 commits) Add poetry as an env manager (drivendataorg#460) Support pixi as environment manager (drivendataorg#459) Docs: Add guidelines for contributing and requesting tools (drivendataorg#456) Fix terminal animation generation in docs build (drivendataorg#451) Fix failing pipenv installation on Windows GH actions runners (drivendataorg#453) Fix typo in using-the-template.md (drivendataorg#448) Bump to v2.2.0 [skip ci] Update HISTORY.md [skip ci] Add option for tests (drivendataorg#447) Resolve python version to work with compatible operator (drivendataorg#446) Add pyproject.toml as a dependencies file option (drivendataorg#436) Make PyPI badges links to PyPI (drivendataorg#440) Update to version v2.1.0 (drivendataorg#438) Add back isort configuration that was removed in drivendataorg#387 (drivendataorg#439) add badges to readme and docs homepage (drivendataorg#434) Added support for the uv package and project manager (drivendataorg#408) Add ruff as default linting + formatting option (drivendataorg#387) Add PyTest IDs for better readability and filtering (drivendataorg#409) prepare for 2.0.1 release by bumping version in pyproject.toml and updating change log (drivendataorg#422) Fix pre-prompt ccds version error (drivendataorg#426) ...
2 parents f18a1a7 + 0f6b163 commit d58d9e7

38 files changed

+868
-49
lines changed

.github/workflows/release.yml

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
name: release
2+
3+
on:
4+
release:
5+
types:
6+
- published
7+
8+
jobs:
9+
build:
10+
name: Build and publish new release
11+
runs-on: "ubuntu-latest"
12+
13+
steps:
14+
- uses: actions/checkout@v3
15+
16+
- name: Set up Python
17+
uses: actions/setup-python@v4
18+
with:
19+
python-version: "3.10"
20+
21+
- name: Install dependencies
22+
run: |
23+
python -m pip install --upgrade pip
24+
pip install -r dev-requirements.txt
25+
26+
- name: Check that versions match
27+
id: version
28+
run: |
29+
echo "Release tag: [${{ github.event.release.tag_name }}]"
30+
PACKAGE_VERSION=$(python -c "import ccds; print(ccds.__version__)")
31+
echo "Package version: [$PACKAGE_VERSION]"
32+
[ ${{ github.event.release.tag_name }} == "v$PACKAGE_VERSION" ] || { exit 1; }
33+
echo "::set-output name=major_minor_version::v${PACKAGE_VERSION%.*}"
34+
35+
- name: Build package
36+
run: |
37+
make dist
38+
39+
- name: Publish to Test PyPI
40+
uses: pypa/gh-action-pypi-publish@v1.3.0
41+
with:
42+
user: ${{ secrets.PYPI_TEST_USERNAME }}
43+
password: ${{ secrets.PYPI_TEST_PASSWORD }}
44+
repository_url: https://test.pypi.org/legacy/
45+
skip_existing: true
46+
47+
- name: Publish to Production PyPI
48+
uses: pypa/gh-action-pypi-publish@v1.3.0
49+
with:
50+
user: ${{ secrets.PYPI_PROD_USERNAME }}
51+
password: ${{ secrets.PYPI_PROD_PASSWORD }}
52+
skip_existing: false

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,11 @@ ipython_config.py
133133
# https://pdm.fming.dev/#use-with-ide
134134
.pdm.toml
135135

136+
# pixi
137+
# pixi.lock should be committed to version control for reproducibility
138+
# .pixi/ contains the environments and should not be committed
139+
.pixi/
140+
136141
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
137142
__pypackages__/
138143

Makefile

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ create_environment:
2222

2323
## Install Python Dependencies
2424
requirements:
25-
$(PYTHON_INTERPRETER) -m pip install -r dev-requirements.txt
25+
$(PYTHON_INTERPRETER) -m pip install -U -r dev-requirements.txt
2626

2727
# ## Format the code using isort and black
2828
# format:
@@ -34,6 +34,31 @@ requirements:
3434
# isort --check --profile black ccds hooks tests docs/scripts
3535
# black --check ccds hooks tests docs/scripts
3636

37+
clean: clean-build clean-pyc clean-test ## remove all build, test, coverage and Python artifacts
38+
39+
clean-build: ## remove build artifacts
40+
rm -fr build/
41+
rm -fr dist/
42+
rm -fr .eggs/
43+
find . -name '*.egg-info' -exec rm -fr {} +
44+
find . -name '*.egg' -exec rm -f {} +
45+
46+
clean-pyc: ## remove Python file artifacts
47+
find . -name '*.pyc' -exec rm -f {} +
48+
find . -name '*.pyo' -exec rm -f {} +
49+
find . -name '*~' -exec rm -f {} +
50+
find . -name '__pycache__' -exec rm -fr {} +
51+
52+
clean-test: ## remove test and coverage artifacts
53+
rm -fr .tox/
54+
rm -f .coverage
55+
rm -fr htmlcov/
56+
rm -fr .pytest_cache
57+
58+
dist: clean ## builds source and wheel package
59+
python -m build
60+
ls -l dist
61+
3762

3863
### DOCS
3964

@@ -46,7 +71,7 @@ docs-serve:
4671
### TESTS
4772

4873
test: _prep
49-
pytest -vvv --durations=0
74+
pytest -vvv --durations=0 tests
5075

5176
test-fastest: _prep
5277
pytest -vvv -FFF

README.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ for setting up a data science project template that incorporates best practices.
88
To learn more about CCDS's philosophy,
99
visit the [project homepage](https://cookiecutter-data-science.drivendata.org/).
1010

11+
1112
This project also included code from
1213
[cookiecutter-uv](https://github.com/fpgmaas/cookiecutter-uv).
1314

@@ -75,3 +76,37 @@ The directory structure of your new project will look something like this (depen
7576
7677
└── plots.py <- Code to create visualizations
7778
```
79+
80+
## Using unreleased changes
81+
82+
By default, `ccds` will use the _project template_ version that corresponds to the _installed `ccds` package_ version (e.g., if you have installed `ccds` v2.0.1, you'll use the v2.0.1 version of the project template by default). To use a specific version of the project template, use the `-c/--checkout` flag to provide the branch (or tag or commit hash) of the version you'd like to use. For example to use the project template from the `master` branch:
83+
84+
```bash
85+
ccds -c master
86+
```
87+
88+
## Using v1
89+
90+
If you want to use the old v1 project template, you need to have either the cookiecutter-data-science package or cookiecutter package installed. Then, use either command-line program with the `-c v1` option:
91+
92+
```bash
93+
ccds https://github.com/drivendataorg/cookiecutter-data-science -c v1
94+
# or equivalently
95+
cookiecutter https://github.com/drivendataorg/cookiecutter-data-science -c v1
96+
```
97+
98+
## Contributing
99+
100+
We welcome contributions! [See the docs for guidelines](https://cookiecutter-data-science.drivendata.org/contributing/).
101+
102+
### Installing development requirements
103+
104+
```bash
105+
pip install -r dev-requirements.txt
106+
```
107+
108+
### Running the tests
109+
110+
```bash
111+
pytest tests
112+
```

RELEASING.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Information for releases and versioning of ccds
2+
3+
## Background
4+
5+
The release of [ccds v2](https://drivendata.co/blog/ccds-v2) introduced the `ccds` utility and the concept of versioning to cookiecutter data science. Prior to this release, cookiecutter-data-science only provided a project template, which the generic [cookiecutter](https://github.com/cookiecutter/cookiecutter) utility could use to instantiate a project. Branches and forks could be used in the usual way to get different versions of the template.
6+
7+
To give the utility and the template a bit more stability, PR [#336](https://github.com/drivendataorg/cookiecutter-data-science/pull/336) created automated release mechanics for publishing new releases and, by default, pinned the template used by the `ccds` utility to the installed version.
8+
9+
## Issuing a new release
10+
11+
- [ ] Update version in `pyproject.toml` file
12+
- [ ] Ensure `HISTORY.md` is up to date with the changes in this release and add version info and release date
13+
- [ ] Create new release on the GitHub [releases page](https://github.com/drivendataorg/cookiecutter-data-science/releases) with the tag `vMAJOR.MINOR.PATCH` (e.g., `v2.3.0`) and the contents of the relevant `HISTORY.md` section as the release notes.
14+
- [ ] Confirm release action runs successfully and the new release is available on [PyPI](https://pypi.org/project/cookiecutter-data-science/).
15+
16+
`ccds` uses [semantic versioning](https://semver.org/). When issuing a new release, **ensure that your release version tag has the format `vMAJOR.MINOR.PATCH`. The `v` prefix is important because the utility will look for the tag with that name to download by default.

ccds-help.json

Lines changed: 90 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,27 @@
147147
"more_information": "[Docs](https://docs.astral.sh/uv/)"
148148
}
149149
},
150+
{
151+
"choice": "uv",
152+
"help": {
153+
"description": "An extremely fast Python package and project manager, written in Rust.",
154+
"more_information": "[Docs](https://docs.astral.sh/uv/)"
155+
}
156+
},
157+
{
158+
"choice": "pixi",
159+
"help": {
160+
"description": "A fast package manager built on top of the conda ecosystem with lock files for reproducible environments. Supports both pixi.toml and pyproject.toml. Requires pixi to be installed as a system binary (see docs for installation instructions).",
161+
"more_information": "[Docs](https://pixi.sh/)"
162+
}
163+
},
164+
{
165+
"choice": "poetry",
166+
"help": {
167+
"description": "A dependency management and packaging tool for Python with lock files for reproducible environments. Uses pyproject.toml for configuration. Requires poetry to be installed as a system binary.",
168+
"more_information": "[Docs](https://python-poetry.org/docs/)"
169+
}
170+
},
150171
{
151172
"choice": "none",
152173
"help": {
@@ -166,8 +187,15 @@
166187
{
167188
"choice": "requirements.txt",
168189
"help": {
169-
"description": "Most general, least feature-rich format for use with `pip`.",
170-
"more_information": "[pip docs](https://pip.pypa.io/en/stable/reference/requirements-file-format/)"
190+
"description": "Classic format for a list of packages to be installed by `pip`.",
191+
"more_information": "[Docs](https://pip.pypa.io/en/stable/reference/requirements-file-format/)"
192+
}
193+
},
194+
{
195+
"choice": "pyproject.toml",
196+
"help": {
197+
"description": "Modern configuration file for Python projects. Also supported by pixi when using tool.pixi sections.",
198+
"more_information": "[Docs](https://packaging.python.org/en/latest/guides/writing-pyproject-toml/)"
171199
}
172200
},
173201
{
@@ -183,6 +211,13 @@
183211
"description": "Format used by Pipenv",
184212
"more_information": "[Docs](https://pipenv.pypa.io/en/latest/pipfile.html)"
185213
}
214+
},
215+
{
216+
"choice": "pixi.toml",
217+
"help": {
218+
"description": "Configuration file used by pixi for managing dependencies and environments.",
219+
"more_information": "[Docs](https://pixi.sh/latest/reference/pixi_manifest/)"
220+
}
186221
}
187222
]
188223
},
@@ -209,6 +244,59 @@
209244
}
210245
]
211246
},
247+
{
248+
"field": "testing_framework",
249+
"help": {
250+
"description": "Framework used for testing your code.",
251+
"more_information": ""
252+
},
253+
"choices": [
254+
{
255+
"choice": "none",
256+
"help": {
257+
"description": "No testing framework.",
258+
"more_information": ""
259+
}
260+
},
261+
{
262+
"choice": "pytest",
263+
"help": {
264+
"description": "Use the pytest framework for testing.",
265+
"more_information": "[Docs](https://docs.pytest.org/en/latest/)"
266+
}
267+
},
268+
{
269+
"choice": "unittest",
270+
"help": {
271+
"description": "Use Python's built-in testing framework.",
272+
"more_information": "[Docs](https://docs.python.org/3/library/unittest.html)"
273+
}
274+
}
275+
]
276+
},
277+
{
278+
"field": "linting_and_formatting",
279+
"help": {
280+
"description": "How to handle linting and formatting on your code.",
281+
"more_information": ""
282+
},
283+
"choices": [
284+
{
285+
"choice": "ruff",
286+
"help": {
287+
"description": "Use ruff for linting and formatting.",
288+
"more_information": ""
289+
}
290+
},
291+
{
292+
"choice": "flake8+black+isort",
293+
"help": {
294+
"description": "Use flake8 for linting and black+isort for formatting.",
295+
"more_information": ""
296+
}
297+
}
298+
]
299+
},
212300
{
213301
"field": "open_source_license",
214302
"help": {

ccds.json

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,30 @@
1616
"conda",
1717
"pipenv",
1818
"uv",
19+
"pixi",
20+
"poetry",
1921
"none"
2022
],
2123
"dependency_file": [
2224
"requirements.txt",
25+
"pyproject.toml",
2326
"environment.yml",
24-
"Pipfile"
27+
"Pipfile",
28+
"pixi.toml"
2529
],
2630
"pydata_packages": [
2731
"none",
2832
"basic"
2933
],
34+
"testing_framework": [
35+
"none",
36+
"pytest",
37+
"unittest"
38+
],
39+
"linting_and_formatting": [
40+
"ruff",
41+
"flake8+black+isort"
42+
],
3043
"open_source_license": ["No license file", "MIT", "BSD-3-Clause"],
3144
"docs": ["mkdocs", "none"],
3245
"include_code_scaffold": ["Yes", "No"]

ccds/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from importlib.metadata import version
2+
3+
__version__ = version("cookiecutter-data-science")

ccds/__main__.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
from cookiecutter import cli
2424
from cookiecutter import main as api_main # noqa: F401 referenced by tests
2525

26+
from ccds import __version__
27+
2628

2729
def default_ccds_main(f):
2830
"""Set the default for the cookiecutter template argument to the CCDS template."""
@@ -31,6 +33,11 @@ def _main(*args, **kwargs):
3133
f.params[1].default = (
3234
"https://github.com/drivendataorg/cookiecutter-data-science"
3335
)
36+
# Find the "checkout" option in the cookiecutter cli (currently the fifth)
37+
# Per #389, set this to the currently released version by default
38+
param_names = [p.name for p in f.params]
39+
checkout_index = param_names.index("checkout")
40+
f.params[checkout_index].default = f"v{__version__}"
3441
return f(*args, **kwargs)
3542

3643
return _main

0 commit comments

Comments
 (0)