From 690b742474eef5326686da42b2f6c83b7c453015 Mon Sep 17 00:00:00 2001 From: Tom Vo Date: Tue, 30 Jan 2024 15:19:38 -0800 Subject: [PATCH 01/11] Add initial updates to contributing guide --- CONTRIBUTING.rst | 490 +++++++++++++++++--------------------------- docs/_static/ci.png | Bin 0 -> 90346 bytes 2 files changed, 185 insertions(+), 305 deletions(-) create mode 100644 docs/_static/ci.png diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 1d79514d..47648d60 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -1,330 +1,249 @@ .. highlight:: shell -============ -Contributing -============ - -Contributions are welcome and greatly appreciated! Every little bit helps, and credit will always be given. - -Types of Contributions ----------------------- - -xCDAT includes issue templates based on the contribution type: https://github.com/xCDAT/xcdat/issues/new/choose. -Note, new contributions must be made under the Apache-2.0 with LLVM exception license. +.. note:: -Bug Report -~~~~~~~~~~ + Large portions of this document came from or are inspired by the `Xarray Contributing + Guide `_. -Look through the `GitHub Issues`_ for bugs to fix. Any unassigned issues tagged with "Type: Bug" is open for implementation. +============ +Overview +============ -Feature Request -~~~~~~~~~~~~~~~ +xCDAT is a community-driven open source project and we welcome everyone who would like to +contribute! Feel free to open a `GitHub Issue`_ or start a `GitHub Discussion`_ for bug +reports, bug fixes, documentation improvements, enhancement suggestions, and other ideas. -Look through the `GitHub Issues`_ for feature suggestions. Any unassigned issues tagged with "Type: Enhancement" is open for implementation. +We encourage discussion on any xCDAT related topic in the `GitHub Discussion`_ forum. +You can also subscribe to our `mailing list`_ for news and announcements related to xCDAT, +such as software version releases or future roadmap plans. -If you are proposing a feature: +Please note that xCDAT has a `Code of Conduct`_. By participating in the xCDAT +community, you agree to abide by its rules. -* Explain in detail how it would work. -* Keep the scope as narrow as possible, to make it easier to implement. -* Remember that this is a open-source project, and that contributions are welcome :) +.. _GitHub Issue: https://github.com/xCDAT/xcdat/issues +.. _GitHub Discussion: https://github.com/xCDAT/xcdat/discussions +.. _Code of Conduct: CODE-OF-CONDUCT.rst +.. _mailing list: https://groups.google.com/g/xcdat -Features must meet the following criteria before they are considered for implementation: +Where to start? +=============== -1. Feature is not implemented by ``xarray`` -2. Feature is not implemented in another actively developed xarray-based package +If you are brand new to xCDAT or open-source development, we recommend going +through the `GitHub Issues`_ page to find issues that interest you. If you are +interested in opening a GitHub issue, you can use the templates `here `_ - * For example, `cf_xarray`_ already handles interpretation of `CF convention`_ attributes on xarray objects +Some issues are particularly suited for new contributors by the label +`Documentation `_ and +`good first issue `_ where +you could start out. These are well documented issues, that do not require a deep +understanding of the internals of xCDAT. Once you've found an interesting issue, you can +return here to get your development environment setup. -3. Feature is not limited to specific use cases (e.g., data quality issues) -4. Feature is generally reusable -5. Feature is relatively simple and lightweight to implement and use +**New contributions must be made under the Apache-2.0 with LLVM exception license.** -Documentation Update -~~~~~~~~~~~~~~~~~~~~ +Documentation Updates +~~~~~~~~~~~~~~~~~~~~~ -Help improve xCDAT's documentation, whether that be the Sphinx documentation or the API docstrings. +Contributing to the `documentation `_ is an +excellent way to help xCDAT. You don't need to be an expert in xCDAT to help with +documentation! -Community Discussion -~~~~~~~~~~~~~~~~~~~~ +Bug Reports and enhancement requests +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Bug reports are an important part of making xCDAT more stable. Having a complete bug +report will allow others to reproduce the bug and provide insight into fixing. -Take a look at the `GitHub Discussions`_ page to get involved, share ideas, or ask questions. +Trying out the bug-producing code on the ``main`` branch is often a worthwhile exercise +to confirm that the bug still exists. It is also worth searching existing bug reports and +pull requests to see if the issue has already been reported and/or fixed. -.. _cf_xarray: https://cf-xarray.readthedocs.io/en/latest/index.html -.. _CF convention: http://cfconventions.org/ .. _GitHub Issues: https://github.com/xCDAT/xcdat/issues -.. _GitHub Discussions: https://github.com/xCDAT/xcdat/discussions - -Version Control ---------------- - -The repository uses branch-based (core team) and fork-based (external collaborators) -Git workflows with tagged software releases. - -.. figure:: _static/git-flow.svg - :alt: Git Flow Diagram - -Guidelines -~~~~~~~~~~ - -1. ``main`` must always be deployable -2. All changes are made through support branches -3. Rebase with the latest ``main`` to avoid/resolve conflicts -4. Make sure pre-commit quality assurance checks pass when committing (enforced in CI/CD build) -5. Open a pull request early for discussion -6. Once the CI/CD build passes and pull request is approved, squash and rebase your commits -7. Merge pull request into ``main`` and delete the branch - -Things to Avoid -~~~~~~~~~~~~~~~ - -1. Don't merge in broken or commented out code -2. Don't commit directly to ``main`` - - * There are branch-protection rules for ``main`` - -3. Don't merge with conflicts. Instead, handle conflicts upon rebasing - -Source: https://gist.github.com/jbenet/ee6c9ac48068889b0912 - -Pre-commit -~~~~~~~~~~ -The repository uses the pre-commit package to manage pre-commit hooks. -These hooks help with quality assurance standards by identifying simple issues -at the commit level before submitting code reviews. - -.. figure:: _static/pre-commit-flow.svg - :alt: Pre-commit Flow Diagram - - pre-commit Flow - - -Get Started ------------- - -Ready to contribute? Here's how to set up xCDAT for local development. - -VS Code, the editor of choice -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -We recommend using VS Code as your IDE because it is open-source and has great Python development support. - -Get VS Code here: https://code.visualstudio.com - -VS Code Setup -^^^^^^^^^^^^^ -xCDAT includes a VS Code workspace file (``.vscode/xcdat.code-setting``). This file automatically configures your IDE with the quality assurance tools, code line-length rulers, and more. - -Make sure to follow the :ref:`Local Development` section below. - -Recommended VS Code Extensions -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - * `Python `_ - * `Pylance `_ - * `Python Docstring Generator `_ - * `Python Type Hint `_ - * `Better Comments `_ - * `Jupyter `_ - * `Visual Studio Intellicode `_ - - -.. _Local Development: -Local Development -~~~~~~~~~~~~~~~~~ +Version control, Git, and GitHub +================================ -1. Download and install Conda +The code is hosted on `GitHub `_. To +contribute you will need to sign up for a `free GitHub account +`_. We use `Git `_ for +version control to allow many people to work together on the project. - Linux - :: +Some great resources for learning Git: - $ wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh - $ bash ./Miniconda3-latest-Linux-x86_64.sh - Do you wish the installer to initialize Miniconda3 by running conda init? [yes|no] yes +* the `GitHub help pages `_. +* the `NumPy's documentation `_. +* Matthew Brett's `Pydagogue `_. +Getting started with Git +------------------------ - MacOS - :: - - $ wget https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-x86_64.sh - $ bash ./Miniconda3-latest-MacOSX-x86_64.sh - Do you wish the installer to initialize Miniconda3 by running conda init? [yes|no] yes - -2. Fork the ``xcdat`` repo on GitHub. - - - If you are a maintainer, you can clone and branch directly from the root repository here: https://github.com/xCDAT/xcdat - -3. Clone your fork locally:: - - $ git clone git@github.com:your_name_here/xcdat.git - -4. Open ``.vscode/xcdat.code-settings`` in VS Code +`GitHub has instructions for setting up Git `__ including installing git, +setting up your SSH key, and configuring git. All these steps need to be completed before +you can work seamlessly between your local repository and GitHub. +.. note:: -5. Create and activate Conda development environment:: + The following instructions assume you want to learn how to interact with github via the git command-line utility, + but contributors who are new to git may find it easier to use other tools instead such as + `Github Desktop `_. - $ cd xcdat - $ conda env create -f conda-env/dev.yml - $ conda activate xcdat_dev +Creating a development environment +================================== -6. Set VS Code Python interpretor to ``xcdat_dev`` +Before starting any development, you'll need to create an isolated xCDAT +development environment: -7. Install pre-commit:: +- Install either `Anaconda `_ or `miniconda + `_ +- Make sure your conda is up to date (``conda update conda``) +- Make sure that you have forked and cloned the repository +- ``cd`` to the *xcdat* source directory - $ pre-commit install - pre-commit installed at .git/hooks/pre-commit +Now we are going through a two-step process: -8. Create a branch for local development and make changes:: + 1. Install the build dependencies + 2. Build and install `xcdat` - $ git checkout -b + .. code-block:: bash + # Create and activate the conda/mamba development environment + >>> mamba env create -f conda-env/dev.yml + >>> mamba activate xcdat_dev -9. `` During or after making changes, check for formatting or linting issues using pre-commit:: + # Build and install xcdat + >>> make install # or python -m pip install . - # Step 9 performs this automatically on staged files in a commit - $ pre-commit run --all-files +At this point you should be able to import ``xcdat`` from your locally built version: - Trim Trailing Whitespace.................................................Passed - Fix End of Files.........................................................Passed - Check Yaml...............................................................Passed - black....................................................................Passed - isort....................................................................Passed - flake8...................................................................Passed - mypy.....................................................................Passed +.. code-block:: sh -10. Generate code coverage report and check unit tests pass:: + $ python # start an interpreter + >>> import xcdat + >>> xcdat.__version__ + '0.6.1' - $ make test # Automatically opens HTML report in your browser - $ pytest # Does not automatically open HTML report in your browser +This will create the new environment, and not touch any of your existing environments, +nor any existing Python installation. - ================================= test session starts ================================= - platform darwin -- Python 3.8.8, pytest-6.2.2, py-1.10.0, pluggy-0.13.1 - rootdir: , configfile: setup.cfg - plugins: anyio-2.2.0, cov-2.11.1 - collected 3 items +To view your environments:: - tests/test_dataset.py .. - tests/test_xcdat.py . + conda info -e - ---------- coverage: platform darwin, python 3.8.8-final-0 ----------- - Name Stmts Miss Cover - --------------------------------------- - xcdat/__init__.py 3 0 100% - xcdat/dataset.py 18 0 100% - xcdat/xcdat.py 0 0 100% - --------------------------------------- - TOTAL 21 0 100% - Coverage HTML written to dir tests_coverage_reports/htmlcov - Coverage XML written to file tests_coverage_reports/coverage.xml +To return to your root environment:: - - The Coverage HTML report is much more detailed (e.g., exact lines of tested/untested code) + conda deactivate -11. Commit your changes:: +See the full `conda docs here `__. - $ git add . - $ git commit -m +Install pre-commit hooks +------------------------ - Trim Trailing Whitespace.................................................Passed - Fix End of Files.........................................................Passed - Check Yaml...............................................................Passed - black....................................................................Passed - isort....................................................................Passed - flake8...................................................................Passed - mypy.....................................................................Passed +We highly recommend that you setup `pre-commit `_ hooks to automatically +run all the above tools every time you make a git commit. To install the hooks -12. Make sure pre-commit QA checks pass. Otherwise, fix any caught issues. +.. code-block:: bash + >>> python -m pip install pre-commit + >>> pre-commit install - - Most of the tools fix issues automatically so you just need to re-stage the files. - - flake8 and mypy issues must be fixed automatically. +This can be done by running: -13. Push changes:: +.. code-block:: bash + >>> pre-commit run - $ git push origin +from the root of the ``xcdat`` repository. You can skip the pre-commit checks with +``git commit --no-verify``. -14. Submit a pull request through the GitHub website. +Note, these hooks are also executed in the GitHub CI/CD build workflow and must +pass before pull requests can be merged. +Contributing to the code base +============================= -Pull Request Guidelines ------------------------ +.. contents:: Code Base: + :local: -Before you submit a pull request, check that it meets these guidelines: +Pull Request (PR) +----------------- -1. The pull request should include tests for new or modified code. -2. Link issues to pull requests. -3. If the pull request adds functionality, the docs should be updated. Put - your new functionality into a function with a docstring, and add the - feature to the list in README.rst. -4. Squash and rebase commits for a clean and navigable Git history. +When you open a `pull request `_ on GitHub, +there a template with a checklist available to use. -When you open a pull request on GitHub, there is a template available for use. +Here's a simple checklist for PRs: +- **Properly comment and document your code.** API docstrings are formatted using the +`numpy style guide `_ +- **Test that the documentation builds correctly** by typing ``make doc`` in the root of the ``xcdat`` directory. This is not strictly necessary, but this may be easier than waiting for CI to catch a mistake. See `"Contributing to the documentation" `_. +- **Test your code**. + - Write new tests if needed. + - Test the code using `Pytest `_. Running all tests (type ``make test`` or ``pytest`` in the root directory) takes a while, so feel free to only run the tests you think are needed based on your PR (example: ``pytest xarray/tests/test_dataarray.py``). CI will catch any failing tests. -Style Guide ------------ +- **Properly format your code** and verify that it passes the formatting guidelines set by `Black `_ and `flake8`_. You can use `pre-commit `_ to run these automatically on each commit. -xCDAT integrates the Black code formatter for code styling. If you want to learn more, please read about it `here `__. + - Run ``pre-commit run --all-files`` in the root directory. This may modify some files. Confirm and commit any formatting changes. -xCDAT also leverages `Python Type Annotations `_ to help the project scale. -`mypy `_ performs optional static type checking through pre-commit. +- **Push your code** and `create a PR on GitHub `_. +- **Use a helpful title for your pull request** by summarizing the main contributions rather than using the latest commit message. If the PR addresses an `issue `_, please `reference it `_. -Testing -------- +Code Formatting +~~~~~~~~~~~~~~~ -Testing your local changes are important to ensure long-term maintainability and extensibility of the project. -Since xCDAT is an open source library, we aim to avoid as many bugs as possible from reaching the end-user. +xCDAT uses several tools to ensure a consistent code format throughout the project: -To get started, here are guides on how to write tests using pytest: +- `Black `_ for standardized + code formatting, +- `Flake8 `_ for code linting +- `isort `_ for standardized order of imports +- `mypy `_ for static type checking on `type hints + `_. -- https://docs.pytest.org/en/latest/ -- https://docs.python-guide.org/writing/tests/#py-test +We highly recommend that you setup `pre-commit hooks `_ +to automatically run all the above tools every time you make a git commit. This +can be done by running:: -In most cases, if a function is hard to test, it is usually a symptom of being too complex (high cyclomatic-complexity). + pre-commit install -DOs for Testing -~~~~~~~~~~~~~~~ +from the root of the ``xcdat`` repository. You can skip the pre-commit checks +with ``git commit --no-verify``. -* *DO* write tests for new or refactored code -* *DO* try to follow test-driven-development -* *DO* use the Coverage reports to see lines of code that need to be tested -* *DO* focus on simplistic, small, reusable modules for unit testing -* *DO* cover as many edge cases as possible when testing +Testing With Continuous Integration +----------------------------------- -DON'Ts for Testing -~~~~~~~~~~~~~~~~~~ +The xCDAT `build workflow `_ +runs the test suite automatically via the +`GitHub Actions `__, +continuous integration service, once your pull request is submitted. -* *DON'T* push or merge untested code -* *DON'T* introduce tests that fail or produce warnings +A pull-request will be considered for merging when you have an all 'green' build. If any +tests are failing, then you will get a red 'X', where you can click through to see the +individual failed tests. This is an example of a green build. -Documenting Code ----------------- +.. image:: _static/ci.png -If you are using VS code, the `Python Docstring Generator `_ extension can be used to auto-generate a docstring snippet once a function/class has been written. -If you want the extension to generate docstrings in Sphinx format, you must set the ``"autoDocstring.docstringFormat": "sphinx"`` setting, under File > Preferences > Settings. +.. note:: -Note that it is best to write the docstrings once you have fully defined the function/class, as then the extension will generate the full docstring. -If you make any changes to the code once a docstring is generated, you will have to manually go and update the affected docstrings. + Each time you push to your PR branch, a new run of the tests will be + triggered on the CI. If they haven't already finished, tests for any older + commits on the same branch will be automatically cancelled. -More info on docstrings here: https://sphinx-rtd-tutorial.readthedocs.io/en/latest/docstrings.html +Writing tests +~~~~~~~~~~~~~ -DOs for Documenting Code -~~~~~~~~~~~~~~~~~~~~~~~~ +All tests should go into the ``tests`` subdirectory of the specific package. +This folder contains many current examples of tests, and we suggest looking to these for +inspiration. -* *DO* explain **why** something is done, its purpose, and its goal. The code shows **how** it is done, so commenting on this can be redundant. -* *DO* explain ambiguity or complexities to avoid confusion -* *DO* embrace documentation as an integral part of the overall development process -* *DO* treat documenting as code and follow principles such as *Don't Repeat Yourself* and *Easier to Change* +The ``xarray.testing`` module has many special ``assert`` functions that +make it easier to make statements about whether DataArray or Dataset objects are +equivalent. The easiest way to verify that your code is correct is to +explicitly construct the result you expect, then compare the actual result to +the expected correct result:: -DON'Ts for Documenting Code -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + def test_constructor_from_0d(): + expected = Dataset({None: ([], 0)})[None] + actual = DataArray(0) + assert_identical(expected, actual) -* *DON'T* write comments as a crutch for poor code -* *DON'T* comment *every* function, data structure, type declaration Developer Tips --------------- - -* flake8 will warn you if the cyclomatic complexity of a function is too high. - - * https://github.com/PyCQA/mccabe - +============== Helpful Commands ---------------- @@ -332,63 +251,24 @@ Helpful Commands .. note:: Run ``make help`` in the root of the project for a list of useful commands -To run a subset of tests:: - -$ pytest tests.test_xcdat - -FAQs ----- - -.. _Why squash and rebase?: - -Why squash and rebase commits? -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Before you merge a support branch back into ``main``, the branch is typically squashed down to a single buildable commit, and then rebased on top of the main repo's ``main`` branch. - -Why? - -* Ensures build passes from the commit -* Cleans up Git history for easy navigation -* Makes collaboration and review process more efficient -* Makes handling conflicts from rebasing simple since you only have to deal with conflicted commits +xCDAT and Visual Studio Code +---------------------------- -How do I squash and rebase commits? -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +We recommend using `VS Code `_ as your code editor because +it is open-source and has great Python development support. -* Use GitHub's Squash and Merge feature in the pull request +xCDAT includes a +`VS Code Workspace file `_, which conveniently configures VS Code for quality assurance tools, code line-length rulers, and more. +Just open ``.vscode/xcdat-workspace.code-settings`` using VS Code. - * You still need to rebase on the latest ``main`` if ``main`` is ahead of your branch. +Some recommended extensions include: -* Manually squash and rebase - - 1. `` Sync your fork of ``main`` (aka ``origin``) with the root ``main`` (aka ``upstream``) :: - - git checkout main - git rebase upstream/main - git push -f origin main - - 2. Get the SHA of the commit OR number of commits to rebase to :: - - git checkout - git log --graph --decorate --pretty=oneline --abbrev-commit - - 3. Squash commits:: - - git rebase -i [SHA] - - # OR - - git rebase -i HEAD~[NUMBER OF COMMITS] - - 4. Rebase branch onto ``main`` :: - - git rebase main - git push -f origin - - 5. Make sure your squashed commit messages are refined - - 6. Force push to remote branch :: - - git push -f origin + * `Python `_ + * `Pylance `_ + * `Python Docstring Generator `_ + * `Python Type Hint `_ + * `Better Comments `_ + * `Jupyter `_ + * `Visual Studio Intellicode `_ + * `autoDocstring `_ diff --git a/docs/_static/ci.png b/docs/_static/ci.png new file mode 100644 index 0000000000000000000000000000000000000000..ad29c37611f58655bcddb03938f662047ddfb0c6 GIT binary patch literal 90346 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�Ol{3m*3ys%`_Ag`e7)>eVl!j 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 literal 0 HcmV?d00001 From ef596aed0d9d08faf108ebe78464280e23806652 Mon Sep 17 00:00:00 2001 From: Tom Vo Date: Wed, 31 Jan 2024 14:52:29 -0800 Subject: [PATCH 02/11] Clean up links --- CONTRIBUTING.rst | 257 ++++++++++++++++++++++++++++++----------------- 1 file changed, 164 insertions(+), 93 deletions(-) diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 47648d60..ac15f3e4 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -10,8 +10,8 @@ Overview ============ xCDAT is a community-driven open source project and we welcome everyone who would like to -contribute! Feel free to open a `GitHub Issue`_ or start a `GitHub Discussion`_ for bug -reports, bug fixes, documentation improvements, enhancement suggestions, and other ideas. +contribute! Feel free to open a `GitHub Issue`_ for bug reports, bug fixes, +documentation improvements, enhancement suggestions, and other ideas. We encourage discussion on any xCDAT related topic in the `GitHub Discussion`_ forum. You can also subscribe to our `mailing list`_ for news and announcements related to xCDAT, @@ -20,21 +20,16 @@ such as software version releases or future roadmap plans. Please note that xCDAT has a `Code of Conduct`_. By participating in the xCDAT community, you agree to abide by its rules. -.. _GitHub Issue: https://github.com/xCDAT/xcdat/issues -.. _GitHub Discussion: https://github.com/xCDAT/xcdat/discussions -.. _Code of Conduct: CODE-OF-CONDUCT.rst -.. _mailing list: https://groups.google.com/g/xcdat - Where to start? -=============== +--------------- If you are brand new to xCDAT or open-source development, we recommend going through the `GitHub Issues`_ page to find issues that interest you. If you are -interested in opening a GitHub issue, you can use the templates `here `_ +interested in opening a GitHub Issue, you can use these `templates`_. Some issues are particularly suited for new contributors by the label -`Documentation `_ and -`good first issue `_ where +`type: docs `_ and +`good-first-issue `_ where you could start out. These are well documented issues, that do not require a deep understanding of the internals of xCDAT. Once you've found an interesting issue, you can return here to get your development environment setup. @@ -44,12 +39,14 @@ return here to get your development environment setup. Documentation Updates ~~~~~~~~~~~~~~~~~~~~~ -Contributing to the `documentation `_ is an -excellent way to help xCDAT. You don't need to be an expert in xCDAT to help with -documentation! +Contributing to the `documentation`_ is an excellent way to help xCDAT. Anything from +fixing typos to improving sentence structure or API docstrings/examples can go a long +way in making xCDAT more user-friendly. -Bug Reports and enhancement requests -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +To open a documentation update request, please use the `documentation update template`_. + +Bug reports +~~~~~~~~~~~ Bug reports are an important part of making xCDAT more stable. Having a complete bug report will allow others to reproduce the bug and provide insight into fixing. @@ -57,26 +54,46 @@ Trying out the bug-producing code on the ``main`` branch is often a worthwhile e to confirm that the bug still exists. It is also worth searching existing bug reports and pull requests to see if the issue has already been reported and/or fixed. -.. _GitHub Issues: https://github.com/xCDAT/xcdat/issues +To open a new bug report, please use this issue `bug report template`_. + +Enhancement requests +~~~~~~~~~~~~~~~~~~~~ +Enhancements are a great way to improve xCDAT's capabilities for the broader scientific +community. + +If you are proposing an enhancement: + +* Explain in detail how it would work +* Make sure it fits in the domain of geospatial climate science +* Keep the scope as narrow as possible, to make it easier to implement +* Generally reusable among the community (not model or data-specific) +* Remember that this is a open-source project, and that contributions are welcome :) + +To open a new enhancement request, please use this issue `enhancement request template`_. + +All other inquiries +~~~~~~~~~~~~~~~~~~~~ + +We welcome comments, questions, or feedback! Please share your thoughts on the +`GitHub Discussions`_ forum! Version control, Git, and GitHub -================================ +-------------------------------- -The code is hosted on `GitHub `_. To -contribute you will need to sign up for a `free GitHub account -`_. We use `Git `_ for -version control to allow many people to work together on the project. +The code is hosted on `GitHub`_. To contribute you will need to sign up for a +`free GitHub account`_. We use `Git`_ for version control to allow many people to work +together on the project. Some great resources for learning Git: -* the `GitHub help pages `_. -* the `NumPy's documentation `_. -* Matthew Brett's `Pydagogue `_. +* the `GitHub help pages`_. +* the `NumPy's documentation`_. +* Matthew Brett's `Pydagogue`_. Getting started with Git ------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~ -`GitHub has instructions for setting up Git `__ including installing git, +`GitHub has instructions for setting up Git`_ including installing git, setting up your SSH key, and configuring git. All these steps need to be completed before you can work seamlessly between your local repository and GitHub. @@ -84,68 +101,108 @@ you can work seamlessly between your local repository and GitHub. The following instructions assume you want to learn how to interact with github via the git command-line utility, but contributors who are new to git may find it easier to use other tools instead such as - `Github Desktop `_. + `GitHub Desktop`_. + +.. Links + +.. _GitHub has instructions for setting up Git: https://help.github.com/set-up-git-redirect +.. _templates: https://github.com/xCDAT/xcdat/issues/new/choose +.. _documentation: https://xcdat.readthedocs.io/en/latest/ +.. _GitHub Issues: https://github.com/xCDAT/xcdat/issues +.. _documentation update template: https://github.com/xCDAT/xcdat/issues/new?assignees=&labels=Type%3A+Documentation&projects=&template=documentation.yml&title=%5BDoc%5D%3A+ +.. _bug report template: https://github.com/xCDAT/xcdat/issues/new?assignees=&labels=Type%3A+Bug&projects=&template=bug_report.yml&title=%5BBug%5D%3A+ +.. _enhancement request template: https://github.com/xCDAT/xcdat/issues/new?assignees=&labels=Type%3A+Enhancement&projects=&template=feature_request.yml&title=%5BFeature%5D%3A+ +.. _GitHub Issue: https://github.com/xCDAT/xcdat/issues +.. _GitHub Issues: https://github.com/xCDAT/xcdat/issues +.. _GitHub Discussion: https://github.com/xCDAT/xcdat/discussions +.. _GitHub Discussions: https://github.com/xCDAT/xcdat/discussions +.. _Code of Conduct: CODE-OF-CONDUCT.rst +.. _mailing list: https://groups.google.com/g/xcdat +.. _GitHub: https://www.github.com/xCDAT/xcdat +.. _free GitHub account: https://github.com/signup/free +.. _Git: http://git-scm.com/ +.. _GitHub help pages: https://help.github.com/ +.. _NumPy's documentation: https://numpy.org/doc/stable/dev/index.html +.. _Pydagogue: https://matthew-brett.github.io/pydagogue/ +.. _GitHub Desktop: https://desktop.github.com/ Creating a development environment -================================== +---------------------------------- Before starting any development, you'll need to create an isolated xCDAT development environment: -- Install either `Anaconda `_ or `miniconda - `_ +- We recommend installing `Miniforge`_ to use ``mamba``. If you prefer, you can install + `Anaconda`_ or `Miniconda`_ to use ``conda`` instead. - Make sure your conda is up to date (``conda update conda``) -- Make sure that you have forked and cloned the repository -- ``cd`` to the *xcdat* source directory +- Make sure that you have forked and cloned the `repository`_. If you are in the xCDAT + organization, forking is not needed since you will have direct read access to the repo. +- ``cd`` to the ``xcdat`` source directory Now we are going through a two-step process: - 1. Install the build dependencies - 2. Build and install `xcdat` +1. Install the build dependencies .. code-block:: bash - # Create and activate the conda/mamba development environment + >>> mamba env create -f conda-env/dev.yml >>> mamba activate xcdat_dev - - # Build and install xcdat + >>> >>> make install # or python -m pip install . -At this point you should be able to import ``xcdat`` from your locally built version: +2. Build and install ``xcdat`` + + At this point you should be able to import ``xcdat`` from your locally built version: + + .. code-block:: bash + + $ python # start an interpreter + >>> import xcdat + >>> xcdat.__version__ + '0.6.1' + + This will create the new environment, and not touch any of your existing environments, + nor any existing Python installation. + +To view your environments: -.. code-block:: sh + .. code-block:: bash - $ python # start an interpreter - >>> import xcdat - >>> xcdat.__version__ - '0.6.1' + conda info -e -This will create the new environment, and not touch any of your existing environments, -nor any existing Python installation. +To return to your root environment: -To view your environments:: + .. code-block:: bash - conda info -e + conda deactivate -To return to your root environment:: +See the full `conda docs here`_. - conda deactivate +.. _Miniforge: https://github.com/conda-forge/miniforge +.. _Anaconda: https://www.anaconda.com/download +.. _Miniconda: https://docs.conda.io/projects/miniconda/en/latest/ +.. _repository: https://github.com/xCDAT/xcdat +.. _conda docs here: http://conda.pydata.org/docs -See the full `conda docs here `__. +.. _installing pre-commit hooks: Install pre-commit hooks ------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~ -We highly recommend that you setup `pre-commit `_ hooks to automatically -run all the above tools every time you make a git commit. To install the hooks +We highly recommend that you setup `pre-commit`_ hooks to automatically run all +the tools listed in the :ref:`code-formatting` section every time you make a git commit. + +To install the hooks .. code-block:: bash + >>> python -m pip install pre-commit >>> pre-commit install This can be done by running: .. code-block:: bash + >>> pre-commit run from the root of the ``xcdat`` repository. You can skip the pre-commit checks with @@ -155,60 +212,65 @@ Note, these hooks are also executed in the GitHub CI/CD build workflow and must pass before pull requests can be merged. Contributing to the code base -============================= +----------------------------- -.. contents:: Code Base: +.. contents:: :local: Pull Request (PR) ------------------ +~~~~~~~~~~~~~~~~~ -When you open a `pull request `_ on GitHub, -there a template with a checklist available to use. +When you open a `pull request`_ on GitHub, there a template with a checklist available to use. Here's a simple checklist for PRs: - **Properly comment and document your code.** API docstrings are formatted using the -`numpy style guide `_ -- **Test that the documentation builds correctly** by typing ``make doc`` in the root of the ``xcdat`` directory. This is not strictly necessary, but this may be easier than waiting for CI to catch a mistake. See `"Contributing to the documentation" `_. +`NumPy style guide`_ +- **Test that the documentation builds correctly** by typing ``make docs`` in the root of the ``xcdat`` directory. This is not strictly necessary, but this may be easier than waiting for CI to catch a mistake. - **Test your code**. - Write new tests if needed. - - Test the code using `Pytest `_. Running all tests (type ``make test`` or ``pytest`` in the root directory) takes a while, so feel free to only run the tests you think are needed based on your PR (example: ``pytest xarray/tests/test_dataarray.py``). CI will catch any failing tests. + - Test the code using `Pytest`_. Running all tests (type ``make test`` or ``pytest`` in the root directory) takes a while, so feel free to only run the tests you think are needed based on your PR (example: ``pytest xarray/tests/test_dataarray.py``). CI will catch any failing tests. -- **Properly format your code** and verify that it passes the formatting guidelines set by `Black `_ and `flake8`_. You can use `pre-commit `_ to run these automatically on each commit. +- **Properly format your code** and verify that it passes the formatting guidelines set by `Black`_ and `Flake8`_. You can use `pre-commit`_ to run these automatically on each commit. - Run ``pre-commit run --all-files`` in the root directory. This may modify some files. Confirm and commit any formatting changes. -- **Push your code** and `create a PR on GitHub `_. -- **Use a helpful title for your pull request** by summarizing the main contributions rather than using the latest commit message. If the PR addresses an `issue `_, please `reference it `_. +- **Push your code** and `create a PR on GitHub`_. +- **Use a helpful title for your pull request** by summarizing the main contributions rather than using the latest commit message. If the PR addresses a `GitHub Issue`_, please `reference it`_. + +.. _code-formatting: Code Formatting ~~~~~~~~~~~~~~~ xCDAT uses several tools to ensure a consistent code format throughout the project: -- `Black `_ for standardized - code formatting, -- `Flake8 `_ for code linting -- `isort `_ for standardized order of imports -- `mypy `_ for static type checking on `type hints - `_. - -We highly recommend that you setup `pre-commit hooks `_ -to automatically run all the above tools every time you make a git commit. This -can be done by running:: - - pre-commit install - -from the root of the ``xcdat`` repository. You can skip the pre-commit checks -with ``git commit --no-verify``. +- `Black`_ for standardized code formatting +- `Flake8`_ for code linting +- `isort`_ for standardized order of imports +- `mypy`_ for static type checking on `type hints`_ + +We highly recommend that you setup `pre-commit hooks`_ to automatically run all the +above tools every time you make a git commit. Check out the :ref:`installing pre-commit +hooks` section above for instructions. + +.. _pull request: https://github.com/xCDAT/xcdat/compare +.. _create a PR on GitHub: https://help.github.com/en/articles/creating-a-pull-request +.. _reference it: https://help.github.com/en/articles/autolinked-references-and-urls +.. _NumPy style guide: https://numpydoc.readthedocs.io/en/latest/format.html +.. _pre-commit: https://pre-commit.com/ +.. _pre-commit hooks: https://pre-commit.com/ +.. _Pytest: http://doc.pytest.org/en/latest/ +.. _Black: https://black.readthedocs.io/en/stable/ +.. _Flake8: https://flake8.pycqa.org/en/latest/ +.. _isort: https://pycqa.github.io/isort/ +.. _mypy: http://mypy-lang.org/ +.. _type hints: https://docs.python.org/3/library/typing.html Testing With Continuous Integration ------------------------------------ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The xCDAT `build workflow `_ -runs the test suite automatically via the -`GitHub Actions `__, +The xCDAT `build workflow`_ runs the test suite automatically via the `GitHub Actions`_, continuous integration service, once your pull request is submitted. A pull-request will be considered for merging when you have an all 'green' build. If any @@ -223,6 +285,9 @@ individual failed tests. This is an example of a green build. triggered on the CI. If they haven't already finished, tests for any older commits on the same branch will be automatically cancelled. +.. _build workflow: https://github.com/xCDAT/xcdat/actions/workflows/build_workflow.yml +.. _GitHub Actions: https://docs.github.com/en/free-pro-team@latest/actions + Writing tests ~~~~~~~~~~~~~ @@ -243,24 +308,27 @@ the expected correct result:: Developer Tips -============== +-------------- Helpful Commands ----------------- +~~~~~~~~~~~~~~~~ .. note:: - Run ``make help`` in the root of the project for a list of useful commands + * Run ``make help`` in the root of the project for a list of useful commands + * Run ``make install`` to install a local build of xCDAT into your mamba/conda environment + * Run ``make clean`` to delete all build, test, coverage and Python artifacts xCDAT and Visual Studio Code ----------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -We recommend using `VS Code `_ as your code editor because -it is open-source and has great Python development support. +We recommend using `VS Code`_ as your code editor because it is open-source and has +great Python development support. -xCDAT includes a -`VS Code Workspace file `_, which conveniently configures VS Code for quality assurance tools, code line-length rulers, and more. -Just open ``.vscode/xcdat-workspace.code-settings`` using VS Code. +xCDAT includes a `VS Code Workspace file`_, which conveniently configures VS Code for +quality assurance tools, code line-length rulers, and more. You just need to open this +file using VS Code, create your development environment, and select the appropriate +Python interpreter for the workspace (from the dev environment). Some recommended extensions include: @@ -272,3 +340,6 @@ Some recommended extensions include: * `Jupyter `_ * `Visual Studio Intellicode `_ * `autoDocstring `_ + +.. _VS Code: https://code.visualstudio.com +.. _VS Code Workspace file: https://github.com/xCDAT/xcdat/blob/main/.vscode/xcdat.code-workspace From aff46b1d6a94de05873a149897f6f228dff92012 Mon Sep 17 00:00:00 2001 From: Tom Vo Date: Wed, 31 Jan 2024 14:55:41 -0800 Subject: [PATCH 03/11] Fix ref link title --- CONTRIBUTING.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index ac15f3e4..e061a159 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -184,7 +184,7 @@ See the full `conda docs here`_. .. _repository: https://github.com/xCDAT/xcdat .. _conda docs here: http://conda.pydata.org/docs -.. _installing pre-commit hooks: +.. _install pre-commit hooks: Install pre-commit hooks ~~~~~~~~~~~~~~~~~~~~~~~~ @@ -251,7 +251,7 @@ xCDAT uses several tools to ensure a consistent code format throughout the proje - `mypy`_ for static type checking on `type hints`_ We highly recommend that you setup `pre-commit hooks`_ to automatically run all the -above tools every time you make a git commit. Check out the :ref:`installing pre-commit +above tools every time you make a git commit. Check out the :ref:`install pre-commit hooks` section above for instructions. .. _pull request: https://github.com/xCDAT/xcdat/compare From 9996b5d9a19ad033cdbc579f1ea74882ebd16fa7 Mon Sep 17 00:00:00 2001 From: Tom Vo Date: Wed, 31 Jan 2024 14:58:01 -0800 Subject: [PATCH 04/11] Update titles --- CONTRIBUTING.rst | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index e061a159..f58a8415 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -36,7 +36,7 @@ return here to get your development environment setup. **New contributions must be made under the Apache-2.0 with LLVM exception license.** -Documentation Updates +Documentation updates ~~~~~~~~~~~~~~~~~~~~~ Contributing to the `documentation`_ is an excellent way to help xCDAT. Anything from @@ -103,8 +103,6 @@ you can work seamlessly between your local repository and GitHub. but contributors who are new to git may find it easier to use other tools instead such as `GitHub Desktop`_. -.. Links - .. _GitHub has instructions for setting up Git: https://help.github.com/set-up-git-redirect .. _templates: https://github.com/xCDAT/xcdat/issues/new/choose .. _documentation: https://xcdat.readthedocs.io/en/latest/ @@ -217,7 +215,7 @@ Contributing to the code base .. contents:: :local: -Pull Request (PR) +Pull request (PR) ~~~~~~~~~~~~~~~~~ When you open a `pull request`_ on GitHub, there a template with a checklist available to use. @@ -240,7 +238,7 @@ Here's a simple checklist for PRs: .. _code-formatting: -Code Formatting +Code formatting ~~~~~~~~~~~~~~~ xCDAT uses several tools to ensure a consistent code format throughout the project: @@ -267,7 +265,7 @@ hooks` section above for instructions. .. _mypy: http://mypy-lang.org/ .. _type hints: https://docs.python.org/3/library/typing.html -Testing With Continuous Integration +Testing with continuous integration ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The xCDAT `build workflow`_ runs the test suite automatically via the `GitHub Actions`_, @@ -307,10 +305,10 @@ the expected correct result:: assert_identical(expected, actual) -Developer Tips +Developer tips -------------- -Helpful Commands +Helpful commands ~~~~~~~~~~~~~~~~ .. note:: From 07ddee8a3ecd238940eb48eb095b3beb45f7962c Mon Sep 17 00:00:00 2001 From: Tom Vo Date: Wed, 31 Jan 2024 15:31:04 -0800 Subject: [PATCH 05/11] Fix bullet points --- CONTRIBUTING.rst | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index f58a8415..be1bfb90 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -86,9 +86,9 @@ together on the project. Some great resources for learning Git: -* the `GitHub help pages`_. -* the `NumPy's documentation`_. -* Matthew Brett's `Pydagogue`_. +* the `GitHub help pages`_ +* the `NumPy's documentation`_ +* Matthew Brett's `Pydagogue`_ Getting started with Git ~~~~~~~~~~~~~~~~~~~~~~~~ @@ -131,10 +131,10 @@ Before starting any development, you'll need to create an isolated xCDAT development environment: - We recommend installing `Miniforge`_ to use ``mamba``. If you prefer, you can install - `Anaconda`_ or `Miniconda`_ to use ``conda`` instead. + `Anaconda`_ or `Miniconda`_ to use ``conda`` instead - Make sure your conda is up to date (``conda update conda``) - Make sure that you have forked and cloned the `repository`_. If you are in the xCDAT - organization, forking is not needed since you will have direct read access to the repo. + organization, forking is not needed since you will have direct read access to the repo - ``cd`` to the ``xcdat`` source directory Now we are going through a two-step process: @@ -221,15 +221,17 @@ Pull request (PR) When you open a `pull request`_ on GitHub, there a template with a checklist available to use. Here's a simple checklist for PRs: + - **Properly comment and document your code.** API docstrings are formatted using the -`NumPy style guide`_ + `NumPy style guide`_ - **Test that the documentation builds correctly** by typing ``make docs`` in the root of the ``xcdat`` directory. This is not strictly necessary, but this may be easier than waiting for CI to catch a mistake. - **Test your code**. - Write new tests if needed. - Test the code using `Pytest`_. Running all tests (type ``make test`` or ``pytest`` in the root directory) takes a while, so feel free to only run the tests you think are needed based on your PR (example: ``pytest xarray/tests/test_dataarray.py``). CI will catch any failing tests. -- **Properly format your code** and verify that it passes the formatting guidelines set by `Black`_ and `Flake8`_. You can use `pre-commit`_ to run these automatically on each commit. +- **Properly format your code** and verify that it passes the formatting guidelines set by `Black`_ and `Flake8`_. + You can use `pre-commit`_ to run these automatically on each commit. - Run ``pre-commit run --all-files`` in the root directory. This may modify some files. Confirm and commit any formatting changes. From bf02a93c97e7ecda535c862af091c474fb1c8313 Mon Sep 17 00:00:00 2001 From: tomvothecoder Date: Tue, 2 Apr 2024 12:10:13 -0700 Subject: [PATCH 06/11] Add repo setup instructions --- .gitignore | 6 ++---- CONTRIBUTING.rst | 26 +++++++++++++++++++++++--- docs/_static/github-fork-button.png | Bin 0 -> 24772 bytes 3 files changed, 25 insertions(+), 7 deletions(-) create mode 100644 docs/_static/github-fork-button.png diff --git a/.gitignore b/.gitignore index f2b99889..8b6882f0 100644 --- a/.gitignore +++ b/.gitignore @@ -117,7 +117,5 @@ conda-build/ # Ad-hoc QA qa/ -# Sphinx generated .txt files -notebook-examples.txt -team-panel.txt -demos.txt \ No newline at end of file +# Custom Sphinx generated .txt files. +docs/*.txt diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index be1bfb90..88dc51f0 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -97,11 +97,31 @@ Getting started with Git setting up your SSH key, and configuring git. All these steps need to be completed before you can work seamlessly between your local repository and GitHub. +Set up the Repo +~~~~~~~~~~~~~~~ + .. note:: - The following instructions assume you want to learn how to interact with github via the git command-line utility, - but contributors who are new to git may find it easier to use other tools instead such as - `GitHub Desktop`_. + The following instructions assume you want to learn how to interact with GitHub via + the git command-line utility, but contributors who are new to git may find it easier + to use other tools instead such as `GitHub Desktop`_. + +Once you have Git setup, you have two options for working with the ``xcdat`` repository: +(1) Clone the main repo, (2) Fork the main repo and clone your fork. + +1. Clone the main repo + + - If you are a regular xCDAT contributor and have direct write access to the main repo, you can + clone the main repo running ``git clone https://github.com/xCDAT/xcdat.git``. + +2. Fork the main repo and clone your fork + + - If you are not a regular xCDAT contributor and don't have write access to the main + repo, you will need to fork the main repo then clone your fork. + - Head over to the `GitHub`_ repo page, click the fork button, and click + "Create a new fork" (shown below). + - .. image:: _static/github-fork-button.png + - Then clone your fork by running ``git clone https://github.com//xcdat.git`` .. _GitHub has instructions for setting up Git: https://help.github.com/set-up-git-redirect .. _templates: https://github.com/xCDAT/xcdat/issues/new/choose diff --git a/docs/_static/github-fork-button.png b/docs/_static/github-fork-button.png new file mode 100644 index 0000000000000000000000000000000000000000..98698793c0a4279533827b9e945c1b1d34f4f79d GIT binary patch literal 24772 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 literal 0 HcmV?d00001 From a88da42b5bea411614b6ee85494735d90ccc0d7b Mon Sep 17 00:00:00 2001 From: tomvothecoder Date: Tue, 2 Apr 2024 12:13:29 -0700 Subject: [PATCH 07/11] Add Steve suggestion to replace mamba with conda --- CONTRIBUTING.rst | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 88dc51f0..f79dcac2 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -150,8 +150,7 @@ Creating a development environment Before starting any development, you'll need to create an isolated xCDAT development environment: -- We recommend installing `Miniforge`_ to use ``mamba``. If you prefer, you can install - `Anaconda`_ or `Miniconda`_ to use ``conda`` instead +- We recommend installing `Anaconda`_ or `Miniconda`_ - Make sure your conda is up to date (``conda update conda``) - Make sure that you have forked and cloned the `repository`_. If you are in the xCDAT organization, forking is not needed since you will have direct read access to the repo @@ -163,8 +162,8 @@ Now we are going through a two-step process: .. code-block:: bash - >>> mamba env create -f conda-env/dev.yml - >>> mamba activate xcdat_dev + >>> conda env create -f conda-env/dev.yml + >>> conda activate xcdat_dev >>> >>> make install # or python -m pip install . @@ -248,7 +247,7 @@ Here's a simple checklist for PRs: - **Test your code**. - Write new tests if needed. - - Test the code using `Pytest`_. Running all tests (type ``make test`` or ``pytest`` in the root directory) takes a while, so feel free to only run the tests you think are needed based on your PR (example: ``pytest xarray/tests/test_dataarray.py``). CI will catch any failing tests. + - Test the code using `Pytest`_. Running all tests (type ``make test`` or ``pytest`` in the root directory) takes a while, so feel free to only run the tests you think are needed based on your PR (example: ``pytest tests/test_dataset.py``). CI will catch any failing tests. - **Properly format your code** and verify that it passes the formatting guidelines set by `Black`_ and `Flake8`_. You can use `pre-commit`_ to run these automatically on each commit. @@ -335,7 +334,7 @@ Helpful commands .. note:: * Run ``make help`` in the root of the project for a list of useful commands - * Run ``make install`` to install a local build of xCDAT into your mamba/conda environment + * Run ``make install`` to install a local build of xCDAT into your conda environment * Run ``make clean`` to delete all build, test, coverage and Python artifacts From 9ac118987c915b52264953dc3b3ce5c1497edefe Mon Sep 17 00:00:00 2001 From: tomvothecoder Date: Tue, 2 Apr 2024 12:59:47 -0700 Subject: [PATCH 08/11] Replace mamba with conda in installation guide --- CONTRIBUTING.rst | 1 - docs/getting-started-guide/installation.rst | 95 +++++++++++++-------- xcdat/dataset.py | 1 - 3 files changed, 58 insertions(+), 39 deletions(-) diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index f79dcac2..1e35de92 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -337,7 +337,6 @@ Helpful commands * Run ``make install`` to install a local build of xCDAT into your conda environment * Run ``make clean`` to delete all build, test, coverage and Python artifacts - xCDAT and Visual Studio Code ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/getting-started-guide/installation.rst b/docs/getting-started-guide/installation.rst index a78df825..a51d4df2 100644 --- a/docs/getting-started-guide/installation.rst +++ b/docs/getting-started-guide/installation.rst @@ -7,64 +7,83 @@ Installation Prerequisites ------------- -1. Familiarity with ``xarray``, since this package is an extension of it +1. Familiarity with ``xarray`` - - We highly recommend visiting the `xarray tutorial`_ and `xarray documentation`_ - pages if you aren't familiar with ``xarray``. + We highly recommend visiting the `xarray tutorial`_ and `xarray documentation`_ + pages if you aren't familiar with ``xarray``. -2. xCDAT is distributed through the `conda-forge`_ channel of Anaconda. We recommend - using Mamba (via `Miniforge`_), a drop-in replacement of Conda that is faster and more - reliable than Conda. Miniforge ships with ``conda-forge`` set as the prioritized channel. - Mamba also uses the same commands and configurations as Conda, and you can swap - commands between both tools. +2. xCDAT is distributed through conda, which is available through Anaconda and Miniconda. - Follow these steps to install Miniforge (Mac OS & Linux): + We recommend following the `Quick command line install`_ steps in the Anaconda docs + to install Miniconda. Those steps are also provided below for convenience. .. code-block:: bash - curl -L -O "https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-$(uname)-$(uname -m).sh" - bash Miniforge3-$(uname)-$(uname -m).sh + >>> # Linux + >>> mkdir -p ~/miniconda3 + >>> curl https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-arm64.sh -o ~/miniconda3/miniconda.sh + >>> bash ~/miniconda3/miniconda.sh -b -u -p ~/miniconda3 + >>> rm -rf ~/miniconda3/miniconda.sh - Then follow the instructions for installation. We recommend you type ``yes`` in - response to ``"Do you wish the installer to initialize Miniforge by running conda init?"`` - to add ``conda`` and ``mamba`` to your path. Note that this will modify your shell - profile (e.g., ``~/.bashrc``). + .. code-block:: bash + + >>> # MacOS + >>> mkdir -p ~/miniconda3 + >>> wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O ~/miniconda3/miniconda.sh + >>> bash ~/miniconda3/miniconda.sh -b -u -p ~/miniconda3 + >>> rm -rf ~/miniconda3/miniconda.sh + + Then follow the instructions for installation. To have conda added to + your path you will need to type ``yes`` in response to ``"Do you wish the + installer to initialize Miniconda3 by running conda init?"`` (we recommend + that you do this). Note that this will modify your shell profile (e.g., + ``~/.bashrc``) to add ``conda`` to your path. + + .. note:: + After installation completes you may need to type ``bash`` to + restart your shell (if you use bash). Alternatively, you can log out and + log back in. + +3. Add the ``conda-forge`` channel. + + xCDAT is hosted on the `conda-forge`_ channel, which is the standard channel for + most scientific Python packages. + + .. code-block:: bash - *Note: After installation completes you may need to type ``bash`` to - restart your shell (if you use bash). Alternatively, you can log out and - log back in.* + >>> conda config --add channels conda-forge + >>> conda config --set channel_priority strict .. _xarray tutorial: https://tutorial.xarray.dev/intro.html .. _xarray documentation: https://docs.xarray.dev/en/stable/getting-started-guide/index.html +.. _Quick command line install: https://docs.anaconda.com/free/miniconda/#quick-command-line-install .. _conda-forge: https://anaconda.org/conda-forge/xcdat -.. _Miniforge: https://github.com/conda-forge/miniforge Instructions ------------ -1. Create a Mamba environment from scratch with ``xcdat`` (`mamba create`_) +1. Create a Conda environment from scratch with ``xcdat`` (`conda create`_) - We recommend using the Mamba environment creation procedure to install ``xcdat``. - The advantage with following this approach is that Mamba will attempt to resolve - dependencies (e.g. ``python >= 3.8``) for compatibility. + We recommend using the Conda environment creation procedure to install ``xcdat``. + The advantage with following this approach is that Conda will attempt to resolve + dependencies (e.g. ``python >= 3.9``) for compatibility. - To create an ``xcdat`` Mamba environment, - run: + To create an ``xcdat`` Conda environment, run: .. code-block:: bash - >>> mamba create -n -c conda-forge xcdat - >>> mamba activate + >>> conda create -n -c conda-forge xcdat + >>> conda activate -2. Install ``xcdat`` in an existing Mamba environment (`mamba install`_) +2. Install ``xcdat`` in an existing Conda environment (`conda install`_) - You can also install ``xcdat`` in an existing Mamba environment, granted that Mamba + You can also install ``xcdat`` in an existing Conda environment, granted that Conda is able to resolve the compatible dependencies. .. code-block:: bash - >>> mamba activate - >>> mamba install -c conda-forge xcdat + >>> conda activate + >>> conda install -c conda-forge xcdat 3. [Optional] Some packages that are commonly used with ``xcdat`` can be installed either in step 1 or step 2 above: @@ -72,10 +91,11 @@ Instructions - ``jupyterlab``: a web-based interactive development environment for notebooks, code, and data. This package also includes ``ipykernel``. - ``matplotlib``: a library for creating visualizations in Python. + - ``nc-time-axis`` is an optional dependency required for ``matplotlib`` to plot ``cftime`` coordinates - ``cartopy``: an add-on package for ``matplotlib`` and specialized for geospatial data processing. -.. _mamba create: https://mamba.readthedocs.io/en/latest/user_guide/mamba.html#quickstart -.. _mamba install: https://mamba.readthedocs.io/en/latest/user_guide/mamba.html#quickstart +.. _conda create: https://docs.conda.io/projects/conda/en/latest/commands/create.html +.. _conda install: https://docs.conda.io/projects/conda/en/latest/commands/install.html Updating -------- @@ -85,15 +105,16 @@ latest stable version of ``xcdat`` for the latest features and bug fixes. .. code-block:: bash - >>> mamba activate - >>> mamba update xcdat + >>> conda activate + >>> conda update xcdat To update to a specific version of ``xcdat``: .. code-block:: bash - >>> mamba activate - >>> mamba update xcdat= + >>> conda activate + >>> conda update xcdat= + >>> # Example: conda update xcdat=0.6.1 Jupyter Users set ``ESMFMKFILE`` env variable --------------------------------------------- diff --git a/xcdat/dataset.py b/xcdat/dataset.py index 45774b48..32522bd6 100644 --- a/xcdat/dataset.py +++ b/xcdat/dataset.py @@ -225,7 +225,6 @@ def open_mfdataset( ---------- .. [2] https://docs.xarray.dev/en/stable/generated/xarray.combine_nested.html .. [3] https://xarray.pydata.org/en/stable/generated/xarray.open_mfdataset.html - .. [4] https://cdms.readthedocs.io/en/latest/manual/cdms_6.html """ if isinstance(paths, str) or isinstance(paths, pathlib.Path): if os.path.isdir(paths): From 589be4487c065306847752ff944e71e04ed59417 Mon Sep 17 00:00:00 2001 From: Tom Vo Date: Wed, 5 Jun 2024 15:16:10 -0700 Subject: [PATCH 09/11] Update repo to repository --- CONTRIBUTING.rst | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 1e35de92..057eec8f 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -107,18 +107,18 @@ Set up the Repo to use other tools instead such as `GitHub Desktop`_. Once you have Git setup, you have two options for working with the ``xcdat`` repository: -(1) Clone the main repo, (2) Fork the main repo and clone your fork. +(1) Clone the main repository, (2) Fork the main repository and clone your fork. -1. Clone the main repo +1. Clone the main repository - - If you are a regular xCDAT contributor and have direct write access to the main repo, you can - clone the main repo running ``git clone https://github.com/xCDAT/xcdat.git``. + - If you are a regular xCDAT contributor and have direct write access to the main repository, you can + clone the main repository running ``git clone https://github.com/xCDAT/xcdat.git``. -2. Fork the main repo and clone your fork +2. Fork the main repository and clone your fork - If you are not a regular xCDAT contributor and don't have write access to the main - repo, you will need to fork the main repo then clone your fork. - - Head over to the `GitHub`_ repo page, click the fork button, and click + repository, you will need to fork the main repository then clone your fork. + - Head over to the `GitHub`_ repository page, click the fork button, and click "Create a new fork" (shown below). - .. image:: _static/github-fork-button.png - Then clone your fork by running ``git clone https://github.com//xcdat.git`` @@ -153,7 +153,7 @@ development environment: - We recommend installing `Anaconda`_ or `Miniconda`_ - Make sure your conda is up to date (``conda update conda``) - Make sure that you have forked and cloned the `repository`_. If you are in the xCDAT - organization, forking is not needed since you will have direct read access to the repo + organization, forking is not needed since you will have direct read access to the repository - ``cd`` to the ``xcdat`` source directory Now we are going through a two-step process: @@ -178,8 +178,8 @@ Now we are going through a two-step process: >>> xcdat.__version__ '0.6.1' - This will create the new environment, and not touch any of your existing environments, - nor any existing Python installation. + This will create the new environment, and not touch any of your existing environments, + nor any existing Python installation. To view your environments: From 7c25b7c639c177ce6bcbf38bf8a5dc4e7bd177c1 Mon Sep 17 00:00:00 2001 From: Tom Vo Date: Wed, 5 Jun 2024 15:19:22 -0700 Subject: [PATCH 10/11] Update instructions on dev env --- CONTRIBUTING.rst | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 057eec8f..43bb1302 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -156,7 +156,8 @@ development environment: organization, forking is not needed since you will have direct read access to the repository - ``cd`` to the ``xcdat`` source directory -Now we are going through a two-step process: +Now we are going through a two-step process. This will create the new environment, and +not touch any of your existing environments, nor any existing Python installation. 1. Install the build dependencies @@ -178,8 +179,6 @@ Now we are going through a two-step process: >>> xcdat.__version__ '0.6.1' - This will create the new environment, and not touch any of your existing environments, - nor any existing Python installation. To view your environments: From 57a9a00f21c8776fd6e7058bf244c37c5a8b5900 Mon Sep 17 00:00:00 2001 From: Tom Vo Date: Wed, 5 Jun 2024 15:23:36 -0700 Subject: [PATCH 11/11] Fix instructions for dev env --- CONTRIBUTING.rst | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 43bb1302..3605d505 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -159,7 +159,7 @@ development environment: Now we are going through a two-step process. This will create the new environment, and not touch any of your existing environments, nor any existing Python installation. -1. Install the build dependencies +1. Install the build dependencies and install the local build of ``xcdat``. .. code-block:: bash @@ -168,9 +168,7 @@ not touch any of your existing environments, nor any existing Python installatio >>> >>> make install # or python -m pip install . -2. Build and install ``xcdat`` - - At this point you should be able to import ``xcdat`` from your locally built version: +2. At this point you should be able to import ``xcdat`` from your locally built version: .. code-block:: bash