From f3cc96b738cbbee116b89d257c621a1cc096f931 Mon Sep 17 00:00:00 2001 From: Rahul Mahajan Date: Thu, 6 Jul 2023 23:36:54 -0400 Subject: [PATCH 01/10] run through isort --- .pycodestyle | 2 +- docs/conf.py | 1 + setup.py | 1 + src/wxflow/__init__.py | 26 ++++++++++++++------------ src/wxflow/configuration.py | 2 +- src/wxflow/executable.py | 2 +- src/wxflow/factory.py | 1 - src/wxflow/fsutils.py | 4 ++-- src/wxflow/jinja.py | 8 +++++--- src/wxflow/logger.py | 4 ++-- src/wxflow/schema.py | 3 +-- src/wxflow/template.py | 4 ++-- src/wxflow/timetools.py | 3 +-- src/wxflow/yaml_file.py | 10 ++++++---- tests/test_configuration.py | 3 ++- tests/test_executable.py | 3 ++- tests/test_file_utils.py | 1 + tests/test_jinja.py | 3 ++- tests/test_logger.py | 3 +-- tests/test_schema.py | 6 ++++-- tests/test_template.py | 3 ++- tests/test_timetools.py | 1 + tests/test_yaml_file.py | 7 +++++-- 23 files changed, 58 insertions(+), 43 deletions(-) diff --git a/.pycodestyle b/.pycodestyle index f5a2f03..af7b2b6 100644 --- a/.pycodestyle +++ b/.pycodestyle @@ -2,4 +2,4 @@ count = False max-line-length = 160 statistics = True -exclude = .git,.github +exclude = .git,.github,venv,.vscode diff --git a/docs/conf.py b/docs/conf.py index 0e5786a..858cd91 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -8,6 +8,7 @@ import os import sys + sys.path.insert(0, os.path.abspath('.')) project = 'wxflow' diff --git a/setup.py b/setup.py index e748ce0..ef1deea 100644 --- a/setup.py +++ b/setup.py @@ -1,4 +1,5 @@ ''' Standard file for building the package with Distutils. ''' import setuptools + setuptools.setup() diff --git a/src/wxflow/__init__.py b/src/wxflow/__init__.py index eccefa5..692ba92 100644 --- a/src/wxflow/__init__.py +++ b/src/wxflow/__init__.py @@ -1,18 +1,20 @@ import os -from .yaml_file import YAMLFile, parse_yaml, parse_yamltmpl, parse_j2yaml, save_as_yaml, dump_as_yaml, vanilla_yaml -from .timetools import * -from .template import TemplateConstants, Template -from .task import Task -from .logger import Logger, logit -from .jinja import Jinja -from .fsutils import mkdir, mkdir_p, rmdir, chdir, rm_p, cp -from .file_utils import FileHandler -from .factory import Factory -from .executable import Executable, which, CommandNotFoundError -from .exceptions import WorkflowException, msg_except_handle -from .configuration import Configuration, cast_strdict_as_dtypedict, cast_as_dtype from .attrdict import AttrDict +from .configuration import (Configuration, cast_as_dtype, + cast_strdict_as_dtypedict) +from .exceptions import WorkflowException, msg_except_handle +from .executable import CommandNotFoundError, Executable, which +from .factory import Factory +from .file_utils import FileHandler +from .fsutils import chdir, cp, mkdir, mkdir_p, rm_p, rmdir +from .jinja import Jinja +from .logger import Logger, logit +from .task import Task +from .template import Template, TemplateConstants +from .timetools import * +from .yaml_file import (YAMLFile, dump_as_yaml, parse_j2yaml, parse_yaml, + parse_yamltmpl, save_as_yaml, vanilla_yaml) __docformat__ = "restructuredtext" __version__ = "0.1.0" diff --git a/src/wxflow/configuration.py b/src/wxflow/configuration.py index 9b460ab..77cf009 100644 --- a/src/wxflow/configuration.py +++ b/src/wxflow/configuration.py @@ -4,7 +4,7 @@ import subprocess from pathlib import Path from pprint import pprint -from typing import Union, List, Dict, Any +from typing import Any, Dict, List, Union from .attrdict import AttrDict from .timetools import to_datetime diff --git a/src/wxflow/executable.py b/src/wxflow/executable.py index 0e6e51e..b2e2388 100644 --- a/src/wxflow/executable.py +++ b/src/wxflow/executable.py @@ -2,7 +2,7 @@ import shlex import subprocess import sys -from typing import Any, Optional, Union, List +from typing import Any, List, Optional, Union __all__ = ["Executable", "which", "CommandNotFoundError"] diff --git a/src/wxflow/factory.py b/src/wxflow/factory.py index bde5246..2ee6207 100644 --- a/src/wxflow/factory.py +++ b/src/wxflow/factory.py @@ -1,6 +1,5 @@ import sys - __all__ = ['Factory'] diff --git a/src/wxflow/fsutils.py b/src/wxflow/fsutils.py index 23331a9..c266642 100644 --- a/src/wxflow/fsutils.py +++ b/src/wxflow/fsutils.py @@ -1,7 +1,7 @@ -import os +import contextlib import errno +import os import shutil -import contextlib __all__ = ['mkdir', 'mkdir_p', 'rmdir', 'chdir', 'rm_p', 'cp'] diff --git a/src/wxflow/jinja.py b/src/wxflow/jinja.py index 2f30367..f8dc39f 100644 --- a/src/wxflow/jinja.py +++ b/src/wxflow/jinja.py @@ -1,12 +1,14 @@ import io import os import sys -import jinja2 -from markupsafe import Markup from pathlib import Path from typing import Dict -from .timetools import strftime, to_YMDH, to_YMD, to_fv3time, to_isotime, to_julian +import jinja2 +from markupsafe import Markup + +from .timetools import (strftime, to_fv3time, to_isotime, to_julian, to_YMD, + to_YMDH) __all__ = ['Jinja'] diff --git a/src/wxflow/logger.py b/src/wxflow/logger.py index b12aef8..3dc7ce7 100644 --- a/src/wxflow/logger.py +++ b/src/wxflow/logger.py @@ -2,12 +2,12 @@ Logger """ +import logging import os import sys from functools import wraps from pathlib import Path -from typing import Union, List -import logging +from typing import List, Union __all__ = ['Logger', 'logit'] diff --git a/src/wxflow/schema.py b/src/wxflow/schema.py index 2a46c62..fbb1263 100644 --- a/src/wxflow/schema.py +++ b/src/wxflow/schema.py @@ -4,9 +4,8 @@ import inspect import re - -from typing import Dict from pydoc import locate +from typing import Dict try: from contextlib import ExitStack diff --git a/src/wxflow/template.py b/src/wxflow/template.py index 8532305..ad623c2 100644 --- a/src/wxflow/template.py +++ b/src/wxflow/template.py @@ -1,6 +1,6 @@ -import re -import os import copy +import os +import re from collections import namedtuple from collections.abc import Sequence diff --git a/src/wxflow/timetools.py b/src/wxflow/timetools.py index cd43b55..e46dfb9 100644 --- a/src/wxflow/timetools.py +++ b/src/wxflow/timetools.py @@ -1,6 +1,5 @@ -import re import datetime - +import re __all__ = ["to_datetime", "to_timedelta", "datetime_to_YMDH", "datetime_to_YMD", "datetime_to_JDAY", diff --git a/src/wxflow/yaml_file.py b/src/wxflow/yaml_file.py index 521a3c0..bb601a3 100644 --- a/src/wxflow/yaml_file.py +++ b/src/wxflow/yaml_file.py @@ -1,12 +1,14 @@ +import datetime +import json import os import re -import json -import yaml -import datetime from typing import Any, Dict + +import yaml + from .attrdict import AttrDict -from .template import TemplateConstants, Template from .jinja import Jinja +from .template import Template, TemplateConstants __all__ = ['YAMLFile', 'parse_yaml', 'parse_yamltmpl', 'parse_j2yaml', 'save_as_yaml', 'dump_as_yaml', 'vanilla_yaml'] diff --git a/tests/test_configuration.py b/tests/test_configuration.py index 8f13251..7926f09 100644 --- a/tests/test_configuration.py +++ b/tests/test_configuration.py @@ -1,7 +1,8 @@ import os -import pytest from datetime import datetime +import pytest + from wxflow.configuration import Configuration, cast_as_dtype file0 = """#!/bin/bash diff --git a/tests/test_executable.py b/tests/test_executable.py index 7fd3c08..2f19587 100644 --- a/tests/test_executable.py +++ b/tests/test_executable.py @@ -1,8 +1,9 @@ import os from pathlib import Path + import pytest -from wxflow.executable import Executable, which, CommandNotFoundError +from wxflow.executable import CommandNotFoundError, Executable, which script = """#!/bin/bash echo ${USER} diff --git a/tests/test_file_utils.py b/tests/test_file_utils.py index f01b4c2..08b305e 100644 --- a/tests/test_file_utils.py +++ b/tests/test_file_utils.py @@ -1,4 +1,5 @@ import os + from wxflow.file_utils import FileHandler diff --git a/tests/test_jinja.py b/tests/test_jinja.py index b2c5bd0..bfc23f3 100644 --- a/tests/test_jinja.py +++ b/tests/test_jinja.py @@ -1,6 +1,7 @@ +from datetime import datetime + import pytest -from datetime import datetime from wxflow.jinja import Jinja from wxflow.timetools import to_isotime diff --git a/tests/test_logger.py b/tests/test_logger.py index 86bbfe5..d231e65 100644 --- a/tests/test_logger.py +++ b/tests/test_logger.py @@ -1,5 +1,4 @@ -from wxflow.logger import Logger -from wxflow.logger import logit +from wxflow.logger import Logger, logit level = 'debug' number_of_log_msgs = 5 diff --git a/tests/test_schema.py b/tests/test_schema.py index 32612c7..ab74034 100644 --- a/tests/test_schema.py +++ b/tests/test_schema.py @@ -6,11 +6,13 @@ """ import os + import pytest + from wxflow import schema -from wxflow.yaml_file import parse_yaml -from wxflow.schema import SchemaError from wxflow.configuration import cast_strdict_as_dtypedict +from wxflow.schema import SchemaError +from wxflow.yaml_file import parse_yaml # Define the path to the YAML-formatted file containing the schema diff --git a/tests/test_template.py b/tests/test_template.py index c582c23..8e3c795 100644 --- a/tests/test_template.py +++ b/tests/test_template.py @@ -1,5 +1,6 @@ import os -from wxflow.template import TemplateConstants, Template + +from wxflow.template import Template, TemplateConstants def test_substitute_string_from_dict(): diff --git a/tests/test_timetools.py b/tests/test_timetools.py index 185d7e4..d114a19 100644 --- a/tests/test_timetools.py +++ b/tests/test_timetools.py @@ -1,4 +1,5 @@ from datetime import datetime, timedelta + from wxflow.timetools import * current_date = datetime.now() diff --git a/tests/test_yaml_file.py b/tests/test_yaml_file.py index 5d0a3fd..83350c4 100644 --- a/tests/test_yaml_file.py +++ b/tests/test_yaml_file.py @@ -1,7 +1,10 @@ import os -import pytest from datetime import datetime -from wxflow.yaml_file import YAMLFile, parse_yamltmpl, parse_j2yaml, save_as_yaml, dump_as_yaml + +import pytest + +from wxflow.yaml_file import (YAMLFile, dump_as_yaml, parse_j2yaml, + parse_yamltmpl, save_as_yaml) host_yaml = """ host: From 1f85a909b41da5c8a074d6dc9f44096451094287 Mon Sep 17 00:00:00 2001 From: Rahul Mahajan Date: Thu, 6 Jul 2023 23:55:16 -0400 Subject: [PATCH 02/10] add codecoverage --- .coveragerc | 41 ++++++++++++++++++++++++++++++++++ .github/workflows/pytests.yaml | 3 +++ setup.cfg | 3 +++ 3 files changed, 47 insertions(+) create mode 100644 .coveragerc diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 0000000..678397c --- /dev/null +++ b/.coveragerc @@ -0,0 +1,41 @@ +# .coveragerc to control code coverage tool +# https://coverage.readthedocs.io/en/latest/config.html + +[run] +# Path where source is stored +source = wxflow/ + +# Omit some source code patterns when computing code coverage +omit = + setup.py + +# whether to measure branch coverage in addition to statement coverage. +# https://coverage.readthedocs.io/en/latest/branch.html#branch +branch = True + +[report] +# number of digits after the decimal point to display for reported coverage percentages +precision = 2 + +# when running a summary report in terminal, show missing lines +# show_missing = True + +# don’t report files that are 100% covered. This helps you focus on files that need attention. +# skip_covered = True + +# don’t report files that have no executable code (such as __init__.py files) +skip_empty = True + +[html] +# where to write the HTML report files +directory = htmlcov + +# title of HTML page +title = Leaspy - Code coverage report + +# To view the dynamic context (cf. above) in HTML report +show_contexts = True + +[xml] +# where to write the XML report +output = coverage.xml diff --git a/.github/workflows/pytests.yaml b/.github/workflows/pytests.yaml index f1facb5..10c24c8 100644 --- a/.github/workflows/pytests.yaml +++ b/.github/workflows/pytests.yaml @@ -31,3 +31,6 @@ jobs: run: | cd $GITHUB_WORKSPACE pytest -v + + - name: "Upload coverage to Codecov" + uses: codecov/codecov-action@v1 diff --git a/setup.cfg b/setup.cfg index 0a09c95..fc253f0 100644 --- a/setup.cfg +++ b/setup.cfg @@ -62,3 +62,6 @@ verbose = 2 no-skip-report = true quiet-stdout = true run-coverage = true + +[tool:pytest] +addopts = --cov=./ From a69a6758f54998d10faa6e63810f07a526fa9985 Mon Sep 17 00:00:00 2001 From: Rahul Mahajan Date: Fri, 7 Jul 2023 00:09:19 -0400 Subject: [PATCH 03/10] add badge from codecov --- README.md | 1 + docs/index.rst | 3 +++ 2 files changed, 4 insertions(+) diff --git a/README.md b/README.md index 1b98103..6f1e38e 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ [![pynorms](https://github.com/NOAA-EMC/wxflow/actions/workflows/pynorms.yaml/badge.svg)](https://github.com/NOAA-EMC/wxflow/actions/workflows/pynorms.yaml) [![pytests](https://github.com/NOAA-EMC/wxflow/actions/workflows/pytests.yaml/badge.svg)](https://github.com/NOAA-EMC/wxflow/actions/workflows/pytests.yaml) [![Documentation Status](https://readthedocs.org/projects/wxflow/badge/?version=latest)](https://wxflow.readthedocs.io/en/latest/?badge=latest) +[![codecov](https://codecov.io/gh/noaa-emc/wxflow/branch/develop/graph/badge.svg?token=JWTPE8Z7MH)](https://codecov.io/gh/noaa-emc/wxflow) # Tools for Weather Workflows diff --git a/docs/index.rst b/docs/index.rst index e826706..6c76d60 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -15,6 +15,9 @@ wxflow .. image:: https://readthedocs.org/projects/wxflow/badge/?version=latest :target: https://wxflow.readthedocs.io/en/latest/?badge=latest :alt: Documentation Status +.. image:: https://codecov.io/gh/noaa-emc/wxflow/branch/develop/graph/badge.svg?token=JWTPE8Z7MH + :target: https://codecov.io/gh/noaa-emc/wxflow + :alt: Codecov A Python library of common tools used in weather workflows. From 1bcfb5a383ac44244a4f55468679f9a67bd8f9a4 Mon Sep 17 00:00:00 2001 From: Rahul Mahajan Date: Fri, 7 Jul 2023 00:21:04 -0400 Subject: [PATCH 04/10] more comprehensive coverage reports --- .coveragerc | 3 --- setup.cfg | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/.coveragerc b/.coveragerc index 678397c..419cb65 100644 --- a/.coveragerc +++ b/.coveragerc @@ -30,9 +30,6 @@ skip_empty = True # where to write the HTML report files directory = htmlcov -# title of HTML page -title = Leaspy - Code coverage report - # To view the dynamic context (cf. above) in HTML report show_contexts = True diff --git a/setup.cfg b/setup.cfg index fc253f0..62b08b5 100644 --- a/setup.cfg +++ b/setup.cfg @@ -64,4 +64,4 @@ quiet-stdout = true run-coverage = true [tool:pytest] -addopts = --cov=./ +addopts = --cov=wxflow --cov-report=term-missing --cov-report=xml --cov-report=html From 8a5b6d1c67110db4b8773cab43b2309367eb2ca2 Mon Sep 17 00:00:00 2001 From: Rahul Mahajan Date: Mon, 10 Jul 2023 12:19:56 -0400 Subject: [PATCH 05/10] more docs --- .flake8 | 6 +++ docs/conf.py | 118 ++++++++++++++++++++++++++++++++++++++---- docs/contributing.rst | 117 +++++++++++++++++++++++++++++++++++++++++ docs/index.rst | 71 +++++++++++++++---------- docs/maintaining.rst | 42 +++++++++++++++ docs/yaml_file.rst | 2 +- setup.cfg | 5 ++ setup.py | 2 +- 8 files changed, 322 insertions(+), 41 deletions(-) create mode 100644 .flake8 create mode 100644 docs/contributing.rst create mode 100644 docs/maintaining.rst diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000..35bff9e --- /dev/null +++ b/.flake8 @@ -0,0 +1,6 @@ +[flake8] +exclude = .git,.github,venv,__pycache__,docs/conf.py,old,build,dist +max-line-length = 160 +per-file-ignores = + # imported but unused + __init__.py: F401 diff --git a/docs/conf.py b/docs/conf.py index 858cd91..f9b237c 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -8,12 +8,24 @@ import os import sys +import datetime +from typing import Any, Dict +import wxflow -sys.path.insert(0, os.path.abspath('.')) +sys.path.insert(0, os.path.abspath(".")) -project = 'wxflow' -copyright = '2023, NOAA/NWS/NCEP/EMC' -author = 'NOAA/NWS/NCEP/EMC' +current_year = datetime.datetime.now().year + +# General information about the project. +project = "wxflow" +copyright = "2023-{}, NOAA/NWS/NCEP/EMC".format(current_year) +author = "NOAA/NWS/NCEP/EMC" +version = wxflow.__version__ +release = wxflow.__version__ + +# The language for content autogenerated by Sphinx. Refer to documentation for +# a list of supported languages. +language = "en" # -- General configuration --------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration @@ -21,18 +33,102 @@ extensions = [ "sphinx.ext.napoleon", "sphinx.ext.autodoc", - "sphinx.ext.viewcode" + "sphinx.ext.extlinks", + "sphinx.ext.viewcode", + "sphinx.ext.doctest", + "sphinx.ext.intersphinx", + "sphinx.ext.todo", + "sphinx_copybutton", ] -templates_path = ['_templates'] -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] +# -- Options for extlinks ---------------------------------------------------- +# + +extlinks = { + "pypi": ("https://pypi.org/project/%s/", "%s"), +} + +# -- Options for intersphinx ------------------------------------------------- +# + +intersphinx_mapping = {"python": ("https://docs.python.org/3/", None)} + +# -- Options for TODOs ------------------------------------------------------- +# + +todo_include_todos = True + +napoleon_google_docstring = False +napoleon_use_param = False +napoleon_use_ivar = True + +templates_path = ["_templates"] + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] + +# The suffix of source filenames. +source_suffix = ".rst" + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = "sphinx" +pygments_dark_style = "monokai" + +# A list of ignored prefixes for module index sorting. +# modindex_common_prefix = [] + +# The encoding of source files. +source_encoding = "utf-8" + +# The master toctree document. +master_doc = "index" # -- Options for HTML output ------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output -html_theme = 'sphinx_rtd_theme' -html_theme_path = ["_themes", ] -html_static_path = ['_static'] +# on_rtd is whether we are on readthedocs.org +on_rtd = os.environ.get("READTHEDOCS", None) == "True" + +try: + import furo + + html_theme = "furo" + html_theme_options: Dict[str, Any] = { + "navigation_with_keys": True, + "source_repository": "https://github.com/NOAA-EMC/wxflow", + "source_branch": "develop", + "source_directory": "docs/", + "footer_icons": [ + { + "name": "GitHub", + "url": "https://github.com/NOAA-EMc/wxflow", + "html": """ + + + + """, + "class": "", + }, + ], + } +except ImportError: + html_theme = "default" + +show_cloud_banner = True + +html_theme_path = [ + "_themes", +] +html_static_path = ["_static"] + +html_context = { + "display_github": True, + "github_user": "NOAA-EMC", + "github_repo": "wxflow", + "github_version": version, + "conf_py_path": "/docs/", +} # Show documentation from class as well as __init__ docstring -autoclass_content = 'both' +autoclass_content = "both" diff --git a/docs/contributing.rst b/docs/contributing.rst new file mode 100644 index 0000000..44bbf14 --- /dev/null +++ b/docs/contributing.rst @@ -0,0 +1,117 @@ +Contributing +============ + +We love contributions here in ``wxflow``! If you're looking for something to work on then check out our +`issue tracker `_ for open issues. + +If you want to make a contribution to ``wxflow`` then please raise a +`Pull Request `_ on GitHub. + +To help speed up the review process please ensure the following: + +- The PR addresses an open issue. +- All tests are passing locally with ``pytest``. +- The project passes linting with ``black`` and ``flake8``. +- If adding a new feature you also add documentation. + +Developing +---------- + +To check out a local copy of the project you can `fork the project on GitHub `_ +and then clone it locally. + +.. code-block:: bash + + $ git clone https://github.com/yourusername/wxflow + $ cd wxflow + +This project uses ``black`` to format code and ``flake8`` for linting. We also support ``pre-commit`` to ensure +these have been run. To configure your local environment please install these development dependencies and set up +the commit hooks. + +.. code-block:: bash + + $ pip install black flake8 pre-commit + $ pre-commit install + +You can check that things are working correctly by calling pre-commit directly. + +.. code-block:: bash + + $ pre-commit run --all-files + black......................................Passed + flake8.....................................Passed + +These checks will be run automatically when you make a commit. + +Testing +------- + +This project uses ``pytest`` to run tests and also to test docstring examples. + +Install the test dependencies. + +.. code-block:: bash + + $ pip install .dev + +Run the tests. + +.. code-block:: bash + + $ pytest + === 3 passed in 0.13 seconds === + +If you are working on a new feature please add tests to ensure the feature works as expected. If you are working on +a bug fix then please add a test to ensure there is no regression. + +Tests are stored in ``wxflow/tests`` and follow the pytest format. + +.. code-block:: python + + from datetime import datetime + from wxflow import to_datetime + + def test_to_datetime(): + assert to_datetime('20220314') == datetime(2022, 3, 14) + +Making a Pull Request +--------------------- + +Once you've made your changes and are ready to make a Pull Request please ensure tests and linting pass locally before pushing to GitHub. +When making your Pull Request please include a short description of the changes, but more importantly why they are important. Perhaps by +writing a before and after paragraph with user examples. + +Also consider how your title look when it appears in a changelog. Does it full describe the change to an outside user? For example +``Add support for checking supported datetime`` is a much better title than ``Fixes #56``. + +.. code-block:: markdown + + # Add support for validating a string can be transformed into a datetime object + + Closes #56 + + **Changes** + + This PR allows the inspection of strings to check if it can be transformed into a datetime object. + + **Before** + + If a user passed a random string to `is_supported_datetime` it would return `False`. + + ```python + >>> from wxflow import is_supported_datetime + >>> is_supported_datetime('2012 Jun 15, 12:23') + False + ``` + + **After** + + If a user passes a valid, supported datetime string, it will return true + + + ```python + >>> from wxflow import is_supported_datetime + >>> is_supported_datetime('20120615T1223z') + True + ``` diff --git a/docs/index.rst b/docs/index.rst index 6c76d60..f2e66b2 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -4,32 +4,24 @@ wxflow ====== .. image:: https://img.shields.io/pypi/wxflow - :target: https://pypi.org/project/wxflow/ - :alt: PyPI + :target: https://pypi.org/project/wxflow/ + :alt: PyPI .. image:: https://github.com/NOAA-EMC/wxflow/workflows/pynorms/badge.svg - :target: https://github.com/NOAA-EMC/wxflow/actions/workflows/pynorms.yaml - :alt: pynorms + :target: https://github.com/NOAA-EMC/wxflow/actions/workflows/pynorms.yaml + :alt: pynorms .. image:: https://github.com/NOAA-EMC/wxflow/workflows/pytests/badge.svg - :target: https://github.com/NOAA-EMC/wxflow/actions/workflows/pytests.yaml - :alt: pytests + :target: https://github.com/NOAA-EMC/wxflow/actions/workflows/pytests.yaml + :alt: pytests .. image:: https://readthedocs.org/projects/wxflow/badge/?version=latest :target: https://wxflow.readthedocs.io/en/latest/?badge=latest :alt: Documentation Status .. image:: https://codecov.io/gh/noaa-emc/wxflow/branch/develop/graph/badge.svg?token=JWTPE8Z7MH - :target: https://codecov.io/gh/noaa-emc/wxflow - :alt: Codecov + :target: https://codecov.io/gh/noaa-emc/wxflow + :alt: Codecov -A Python library of common tools used in weather workflows. - -Installation ------------- - -.. code-block:: bash - - pip install wxflow - -Description ------------ +******** +Overview +******** wxflow is a Python library of common tools used in weather workflows. It is designed to be used in NWP applications such as GFS, GEFS, and RRFS workflows. Some of the tools @@ -44,18 +36,41 @@ included in wxflow are: - **task**: A task tool that allows for the use of a YAML file to configure tasks. +Installation +------------ + +.. code-block:: bash -.. toctree:: - :maxdepth: 2 - :caption: Contents: + pip install wxflow - API Reference +Disclaimer +---------- +The United States Department of Commerce (DOC) GitHub project code is provided +on an "as is" basis and the user assumes responsibility for its use. DOC has +relinquished control of the information and no longer has responsibility to +protect the integrity, confidentiality, or availability of the information. Any +claims against the Department of Commerce stemming from the use of its GitHub +project will be governed by all applicable Federal law. Any reference to +specific commercial products, processes, or services by service mark, +trademark, manufacturer, or otherwise, does not constitute or imply their +endorsement, recommendation or favoring by the Department of Commerce. The +Department of Commerce seal and logo, or the seal and logo of a DOC bureau, +shall not be used in any manner to imply endorsement of any commercial product +or activity by DOC or the United States Government. -Indices and tables -================== +.. toctree:: + :hidden: + :maxdepth: 2 + + Contributing + Maintaining + +.. toctree:: + :caption: Development + :hidden: + :maxdepth: 2 -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` + API Reference + Function index diff --git a/docs/maintaining.rst b/docs/maintaining.rst new file mode 100644 index 0000000..e2890c3 --- /dev/null +++ b/docs/maintaining.rst @@ -0,0 +1,42 @@ +Maintaining +=========== + +Reviewing Pull Requests +----------------------- + +This project generally accepts any Pull Request which improves the project. + +Any small issues which fix typos or improve documentation can be merged straight in. + +Any bug fix or enhancement PRs should reference an open issue which describes the problem. This gives +us and other users the opportunity to discuss the change before anyone invests time in implementing it. + +Typically we have a "yes and" policy when it comes to reviewing where we generally accept whatever is contributed even +if it's not quite right. If you have a small amount of feedback during review, such as the user forgot to run ``black`` or +you want to reword something in a docstring it's preferable to just push extra commits to the PR, or just merge +and raise a follow up PR to tweak things. + +For larger design or implementation feedback then feel free to push this back on to the contributor. + + +Releasing +--------- + +We follow `Semantic Versioning `_ and releases are published automatically when a tag is pushed to GitHub. +Ensure that the `__version__` in `src/wxflow/__init__.py `_ is updated to the updated version before tagging. + +.. code-block:: bash + + # Set next version number + export RELEASE=x.x.x + + # Edit src/wxflow/__init__.py + __version__ = $RELEASE + + # Create tags + git add src/wxflow/__init__.py + git commit -m "Release $RELEASE" + git tag -a $RELEASE -m "Version $RELEASE" + + # Push + git push upstream --tags diff --git a/docs/yaml_file.rst b/docs/yaml_file.rst index b0196e1..d891118 100644 --- a/docs/yaml_file.rst +++ b/docs/yaml_file.rst @@ -1,4 +1,4 @@ -.. currentmodule:: wxflow +.. module:: wxflow .. autoclass:: YAMLFile :members: save, dump, as_dict diff --git a/setup.cfg b/setup.cfg index 62b08b5..e3f4294 100644 --- a/setup.cfg +++ b/setup.cfg @@ -65,3 +65,8 @@ run-coverage = true [tool:pytest] addopts = --cov=wxflow --cov-report=term-missing --cov-report=xml --cov-report=html + +[tool:flake8] +exclude = .git,.github,venv,__pycache__,docs/conf.py,old,build,dist +max-line-length = 160 +per-file-ignores = __init__.py: F401 diff --git a/setup.py b/setup.py index ef1deea..d2a8222 100644 --- a/setup.py +++ b/setup.py @@ -1,4 +1,4 @@ -''' Standard file for building the package with Distutils. ''' +""" Standard file for building the package with Distutils. """ import setuptools From f2132c4d45fc04a18a7d71091d91df1a16850006 Mon Sep 17 00:00:00 2001 From: Rahul Mahajan Date: Mon, 10 Jul 2023 12:42:53 -0400 Subject: [PATCH 06/10] / --- .pycodestyle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pycodestyle b/.pycodestyle index af7b2b6..4e9ad7e 100644 --- a/.pycodestyle +++ b/.pycodestyle @@ -2,4 +2,4 @@ count = False max-line-length = 160 statistics = True -exclude = .git,.github,venv,.vscode +exclude = .git,.github,venv,.vscode,docs/conf.py From 53c8ecf139f8e210f55ebcb3c32510335a6ea9ee Mon Sep 17 00:00:00 2001 From: Rahul Mahajan Date: Mon, 10 Jul 2023 12:56:23 -0400 Subject: [PATCH 07/10] enable pre-commit hooks. not for the faint hearted --- .pre-commit-config.yaml | 16 ++++++++++++++++ docs/conf.py | 3 ++- docs/contributing.rst | 4 ++-- 3 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 .pre-commit-config.yaml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..33ecd63 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,16 @@ +repos: + - repo: https://github.com/pycqa/isort + rev: 5.12.0 + hooks: + - id: isort + name: isort (python) + - repo: https://github.com/psf/black + rev: 23.3.0 + hooks: + - id: black + language_version: python3 + - repo: https://github.com/pycqa/flake8 + rev: 6.0.0 + hooks: + - id: flake8 + language_version: python3 diff --git a/docs/conf.py b/docs/conf.py index f9b237c..b67881c 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -6,10 +6,11 @@ # -- Project information ----------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information +import datetime import os import sys -import datetime from typing import Any, Dict + import wxflow sys.path.insert(0, os.path.abspath(".")) diff --git a/docs/contributing.rst b/docs/contributing.rst index 44bbf14..2a1ac32 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -25,13 +25,13 @@ and then clone it locally. $ git clone https://github.com/yourusername/wxflow $ cd wxflow -This project uses ``black`` to format code and ``flake8`` for linting. We also support ``pre-commit`` to ensure +This project uses ``isort`` to sort Python import definitions alphabetically, ``black`` to format code and ``flake8`` for linting. We also support ``pre-commit`` to ensure these have been run. To configure your local environment please install these development dependencies and set up the commit hooks. .. code-block:: bash - $ pip install black flake8 pre-commit + $ pip install isort black flake8 pre-commit $ pre-commit install You can check that things are working correctly by calling pre-commit directly. From bb3677e020d3a52de4fa13be5aa4a33bd526a6de Mon Sep 17 00:00:00 2001 From: Rahul Mahajan Date: Mon, 10 Jul 2023 13:01:44 -0400 Subject: [PATCH 08/10] add isort and update extras deps --- docs/contributing.rst | 3 ++- setup.cfg | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/contributing.rst b/docs/contributing.rst index 2a1ac32..b07422f 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -39,10 +39,11 @@ You can check that things are working correctly by calling pre-commit directly. .. code-block:: bash $ pre-commit run --all-files + isort......................................Passed black......................................Passed flake8.....................................Passed -These checks will be run automatically when you make a commit. +These checks will be run automatically when you make a commit (if ``pre-commit`` has been installed). Testing ------- diff --git a/setup.cfg b/setup.cfg index e3f4294..12c6778 100644 --- a/setup.cfg +++ b/setup.cfg @@ -44,7 +44,7 @@ install_requires = PyYAML>=6.0 Jinja2>=3.1.2 tests_require = - pytest + pytest, pytest-cov, isort, black, flake8 [options.packages.find] where=src @@ -53,7 +53,7 @@ where=src * = *.txt, *.md [options.extras_require] -dev = pytest>=7; pytest-cov>=3 +dev = pytest>=7; pytest-cov>=3, isort>=5, black>=21, flake8>=4, pre-commit>=2, tox>=3 docs = sphinx>=4; sphinx-autobuild; sphinx_rtd_theme>=0.5 [green] From 778d6d99a40f7d7b4846257e452f5e99e2a689b5 Mon Sep 17 00:00:00 2001 From: Rahul Mahajan Date: Mon, 10 Jul 2023 13:07:32 -0400 Subject: [PATCH 09/10] fix typo in setup.cfg --- setup.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index 12c6778..cdae91a 100644 --- a/setup.cfg +++ b/setup.cfg @@ -53,7 +53,7 @@ where=src * = *.txt, *.md [options.extras_require] -dev = pytest>=7; pytest-cov>=3, isort>=5, black>=21, flake8>=4, pre-commit>=2, tox>=3 +dev = pytest>=7; pytest-cov>=3; isort>=5; black>=21; flake8>=4; pre-commit>=2; tox>=3 docs = sphinx>=4; sphinx-autobuild; sphinx_rtd_theme>=0.5 [green] From d757260c3bfd27467a8c60505876b73bc84c55cf Mon Sep 17 00:00:00 2001 From: Rahul Mahajan Date: Mon, 10 Jul 2023 13:14:14 -0400 Subject: [PATCH 10/10] update requirements --- docs/requirements.txt | 4 +++- setup.cfg | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index cb5dbf6..c7df203 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,3 +1,5 @@ sphinx +furo +sphinx_rtd_theme sphinx-autobuild -sphinx-rtd-theme +sphinx-copybutton diff --git a/setup.cfg b/setup.cfg index cdae91a..280cb8b 100644 --- a/setup.cfg +++ b/setup.cfg @@ -54,7 +54,7 @@ where=src [options.extras_require] dev = pytest>=7; pytest-cov>=3; isort>=5; black>=21; flake8>=4; pre-commit>=2; tox>=3 -docs = sphinx>=4; sphinx-autobuild; sphinx_rtd_theme>=0.5 +docs = sphinx>=4; sphinx-autobuild; sphinx_rtd_theme>=0.5; furo>=2023.03.23; sphinx-copybutton [green] file-pattern = test_*.py