Skip to content

Commit

Permalink
Adding pre-commit-ci (#35)
Browse files Browse the repository at this point in the history
* Adding pre-commit-ci config

* bump CI -- pre-commit-ci enabled

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* update black version

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* pre-commit-ci happy with builtin type constructor use

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
ijpulidos and pre-commit-ci[bot] authored Mar 11, 2024
1 parent 2e300ed commit 7594295
Show file tree
Hide file tree
Showing 25 changed files with 2,301 additions and 1,333 deletions.
22 changes: 22 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
ci:
autoupdate_schedule: "quarterly"
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
- id: check-yaml
- id: debug-statements
- id: trailing-whitespace
- id: check-builtin-literals
- id: check-executables-have-shebangs
- id: check-json
- repo: https://github.com/psf/black
rev: 24.2.0
hooks:
- id: black
- repo: https://github.com/asottile/pyupgrade
rev: 'v3.15.0'
hooks:
- id: pyupgrade
args:
- --py39-plus
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@ Copyright (c) 2023, ChoderaLab
#### Acknowledgements
[Choderalab -- Perses](https://github.com/choderalab/perses)
[Open Free energy Consortium](https://openfree.energy/)
Project based on the
Project based on the
[Computational Molecular Science Python Cookiecutter](https://github.com/molssi/cookiecutter-cms) version 1.1.
16 changes: 8 additions & 8 deletions devtools/README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# Development, testing, and deployment tools

This directory contains a collection of tools for running Continuous Integration (CI) tests,
This directory contains a collection of tools for running Continuous Integration (CI) tests,
conda installation, and other development tools not directly related to the coding process.


## Manifest

### Continuous Integration

You should test your code, but do not feel compelled to use these specific programs. You also may not need Unix and
You should test your code, but do not feel compelled to use these specific programs. You also may not need Unix and
Windows testing if you only plan to deploy on specific platforms. These are just to help you get started.

### Conda Environment:
Expand All @@ -17,7 +17,7 @@ This directory contains the files to setup the Conda environment for testing pur

* `conda-envs`: directory containing the YAML file(s) which fully describe Conda Environments, their dependencies, and those dependency provenance's
* `test_env.yaml`: Simple test environment file with base dependencies. Channels are not specified here and therefore respect global Conda configuration

### Additional Scripts:

This directory contains OS agnostic helper scripts which don't fall in any of the previous categories
Expand All @@ -40,17 +40,17 @@ This directory contains OS agnostic helper scripts which don't fall in any of th
- [ ] Make sure there is an/are issue(s) opened for your specific update
- [ ] Create the PR, referencing the issue
- [ ] Debug the PR as needed until tests pass
- [ ] Tag the final, debugged version
- [ ] Tag the final, debugged version
* `git tag -a X.Y.Z [latest pushed commit] && git push --follow-tags`
- [ ] Get the PR merged in

## Versioneer Auto-version
[Versioneer](https://github.com/warner/python-versioneer) will automatically infer what version
is installed by looking at the `git` tags and how many commits ahead this version is. The format follows
[Versioneer](https://github.com/warner/python-versioneer) will automatically infer what version
is installed by looking at the `git` tags and how many commits ahead this version is. The format follows
[PEP 440](https://www.python.org/dev/peps/pep-0440/) and has the regular expression of:
```regexp
\d+.\d+.\d+(?\+\d+-[a-z0-9]+)
```
If the version of this commit is the same as a `git` tag, the installed version is the same as the tag,
e.g. `feflow-0.1.2`, otherwise it will be appended with `+X` where `X` is the number of commits
If the version of this commit is the same as a `git` tag, the installed version is the same as the tag,
e.g. `feflow-0.1.2`, otherwise it will be appended with `+X` where `X` is the number of commits
ahead from the last tag, and then `-YYYYYY` where the `Y`'s are replaced with the `git` commit hash.
83 changes: 53 additions & 30 deletions devtools/scripts/create_conda_env.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
import subprocess as sp
from tempfile import TemporaryDirectory
from contextlib import contextmanager

# YAML imports
try:
import yaml # PyYAML

loader = yaml.safe_load
except ImportError:
try:
Expand All @@ -17,19 +19,30 @@
try:
# Load Ruamel YAML from the base conda environment
from importlib import util as import_util
CONDA_BIN = os.path.dirname(os.environ['CONDA_EXE'])
ruamel_yaml_path = glob.glob(os.path.join(CONDA_BIN, '..',
'lib', 'python*.*', 'site-packages',
'ruamel_yaml', '__init__.py'))[0]

CONDA_BIN = os.path.dirname(os.environ["CONDA_EXE"])
ruamel_yaml_path = glob.glob(
os.path.join(
CONDA_BIN,
"..",
"lib",
"python*.*",
"site-packages",
"ruamel_yaml",
"__init__.py",
)
)[0]
# Based on importlib example, but only needs to load_module since its the whole package, not just
# a module
spec = import_util.spec_from_file_location('ruamel_yaml', ruamel_yaml_path)
spec = import_util.spec_from_file_location("ruamel_yaml", ruamel_yaml_path)
yaml = spec.loader.load_module()
except (KeyError, ImportError, IndexError):
raise ImportError("No YAML parser could be found in this or the conda environment. "
"Could not find PyYAML or Ruamel YAML in the current environment, "
"AND could not find Ruamel YAML in the base conda environment through CONDA_EXE path. "
"Environment not created!")
raise ImportError(
"No YAML parser could be found in this or the conda environment. "
"Could not find PyYAML or Ruamel YAML in the current environment, "
"AND could not find Ruamel YAML in the base conda environment through CONDA_EXE path. "
"Environment not created!"
)
loader = yaml.YAML(typ="safe").load # typ="safe" avoids odd typing on output


Expand All @@ -46,50 +59,60 @@ def temp_cd():


# Args
parser = argparse.ArgumentParser(description='Creates a conda environment from file for a given Python version.')
parser.add_argument('-n', '--name', type=str,
help='The name of the created Python environment')
parser.add_argument('-p', '--python', type=str,
help='The version of the created Python environment')
parser.add_argument('conda_file',
help='The file for the created Python environment')
parser = argparse.ArgumentParser(
description="Creates a conda environment from file for a given Python version."
)
parser.add_argument(
"-n", "--name", type=str, help="The name of the created Python environment"
)
parser.add_argument(
"-p", "--python", type=str, help="The version of the created Python environment"
)
parser.add_argument("conda_file", help="The file for the created Python environment")

args = parser.parse_args()

# Open the base file
with open(args.conda_file, "r") as handle:
with open(args.conda_file) as handle:
yaml_script = loader(handle.read())

python_replacement_string = "python {}*".format(args.python)
python_replacement_string = f"python {args.python}*"

try:
for dep_index, dep_value in enumerate(yaml_script['dependencies']):
if re.match('python([ ><=*]+[0-9.*]*)?$', dep_value): # Match explicitly 'python' and its formats
yaml_script['dependencies'].pop(dep_index)
for dep_index, dep_value in enumerate(yaml_script["dependencies"]):
if re.match(
"python([ ><=*]+[0-9.*]*)?$", dep_value
): # Match explicitly 'python' and its formats
yaml_script["dependencies"].pop(dep_index)
break # Making the assumption there is only one Python entry, also avoids need to enumerate in reverse
except (KeyError, TypeError):
# Case of no dependencies key, or dependencies: None
yaml_script['dependencies'] = []
yaml_script["dependencies"] = []
finally:
# Ensure the python version is added in. Even if the code does not need it, we assume the env does
yaml_script['dependencies'].insert(0, python_replacement_string)
yaml_script["dependencies"].insert(0, python_replacement_string)

# Figure out conda path
if "CONDA_EXE" in os.environ:
conda_path = os.environ["CONDA_EXE"]
else:
conda_path = shutil.which("conda")
if conda_path is None:
raise RuntimeError("Could not find a conda binary in CONDA_EXE variable or in executable search path")
raise RuntimeError(
"Could not find a conda binary in CONDA_EXE variable or in executable search path"
)

print("CONDA ENV NAME {}".format(args.name))
print("PYTHON VERSION {}".format(args.python))
print("CONDA FILE NAME {}".format(args.conda_file))
print("CONDA PATH {}".format(conda_path))
print(f"CONDA ENV NAME {args.name}")
print(f"PYTHON VERSION {args.python}")
print(f"CONDA FILE NAME {args.conda_file}")
print(f"CONDA PATH {conda_path}")

# Write to a temp directory which will always be cleaned up
with temp_cd():
temp_file_name = "temp_script.yaml"
with open(temp_file_name, 'w') as f:
with open(temp_file_name, "w") as f:
f.write(yaml.dump(yaml_script))
sp.call("{} env create -n {} -f {}".format(conda_path, args.name, temp_file_name), shell=True)
sp.call(
f"{conda_path} env create -n {args.name} -f {temp_file_name}",
shell=True,
)
4 changes: 2 additions & 2 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ To compile the docs, first ensure that Sphinx and the ReadTheDocs theme are inst


```bash
conda install sphinx sphinx_rtd_theme
conda install sphinx sphinx_rtd_theme
```


Expand All @@ -14,7 +14,7 @@ Once installed, you can use the `Makefile` in this directory to compile static H
make html
```

The compiled docs will be in the `_build` directory and can be viewed by opening `index.html` (which may itself
The compiled docs will be in the `_build` directory and can be viewed by opening `index.html` (which may itself
be inside a directory called `html/` depending on what version of Sphinx is installed).


Expand Down
4 changes: 2 additions & 2 deletions docs/_static/README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# Static Doc Directory

Add any paths that contain custom static files (such as style sheets) here,
relative to the `conf.py` file's directory.
relative to the `conf.py` file's directory.
They are copied after the builtin static files,
so a file named "default.css" will overwrite the builtin "default.css".

The path to this folder is set in the Sphinx `conf.py` file in the line:
The path to this folder is set in the Sphinx `conf.py` file in the line:
```python
templates_path = ['_static']
```
Expand Down
4 changes: 2 additions & 2 deletions docs/_templates/README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# Templates Doc Directory

Add any paths that contain templates here, relative to
Add any paths that contain templates here, relative to
the `conf.py` file's directory.
They are copied after the builtin template files,
so a file named "page.html" will overwrite the builtin "page.html".

The path to this folder is set in the Sphinx `conf.py` file in the line:
The path to this folder is set in the Sphinx `conf.py` file in the line:
```python
html_static_path = ['_templates']
```
Expand Down
Loading

0 comments on commit 7594295

Please sign in to comment.