Repository: terrapower/armi
Pull request #1692 (2024-04-19 23:55:44)

Moving .coveragerc info into pyproject.toml
## What is the change?

I removed the `.coveragerc` file and adding that configuration into the `pyproject.toml`.

## Why is the change being made?

Since we have moved the ARMI project to using `pyproject.toml` for everything else, it makes sense to do it also for this last feature. And it is the community standard these days.

---

## Checklist

- [X] This PR has only [one purpose or idea](https://terrapower.github.io/armi/developer/tooling.html#one-idea-one-pr).
- [X] [Tests](https://terrapower.github.io/armi/developer/tooling.html#test-it) have been added/updated to verify any new/changed code.

<!-- Check the code quality -->

- [X] The code style follows [good practices](https://terrapower.github.io/armi/developer/standards_and_practices.html).
- [X] The commit message(s) follow [good practices](https://terrapower.github.io/armi/developer/tooling.html).

<!-- Check the project-level cruft -->

- [X] The [release notes](https://terrapower.github.io/armi/developer/tooling.html#add-release-notes) have been updated if necessary.
- [X] The [documentation](https://terrapower.github.io/armi/developer/tooling.html#document-it) is still up-to-date in the `doc` folder.
- [X] The dependencies are still up-to-date in `pyproject.toml`.

john-science: > DO NOT MERGE

I want to do some careful by-line testing to make sure all the rules translated correctly to the new format.
opotowsky: > > DO NOT MERGE
> 
> I want to do some careful by-line testing to make sure all the rules translated correctly to the new format.

Feel free to re-request a review if you make big changes after testing. Looks good to me though!
john-science: Okay, the coverage results match, so this PR is safe to merge.

Patch:
diff --git a/.coveragerc b/.coveragerc
deleted file mode 100644
index fd25fbcd..00000000
--- a/.coveragerc
+++ /dev/null
@@ -1,35 +0,0 @@
-# Don't worry about coverage for the grid GUI (for now)
-[run]
-omit =
-    armi/cli/gridGui.py
-    armi/utils/gridEditor.py
-    armi/utils/tests/test_gridGui.py
-    venv/
-source = armi
-# change default .coverage file to something that doesn't have a dot
-# because the Windows file server can't handle dots.
-data_file = coverage_results.cov
-
-[coverage:run]
-parallel = true
-
-[report]
-omit =
-    armi/cli/gridGui.py
-    armi/utils/gridEditor.py
-    */tests/*
-
-exclude_lines =
-    # Don't complain about missing debug-only code:
-    def __repr__
-    if self\.debug
-
-    # Don't complain if tests don't hit defensive assertion code:
-    raise AssertionError
-    raise KeyboardInterrupt
-    raise NotImplementedError
-    except ImportError
-    pass
-
-    # Don't complain if non-runnable code isn't run:
-    if __name__ == .__main__.:
diff --git a/.github/workflows/coverage.yaml b/.github/workflows/coverage.yaml
index ba737fee..b3cd8de0 100644
--- a/.github/workflows/coverage.yaml
+++ b/.github/workflows/coverage.yaml
@@ -30,10 +30,10 @@ jobs:
           pip install -e .[memprof,mpi,test]
       - name: Run Coverage
         run: |
-          coverage run --rcfile=.coveragerc -m pytest -n 4 --cov=armi --cov-config=.coveragerc --cov-report=lcov --ignore=venv armi
-          mpiexec -n 2 --use-hwthread-cpus coverage run --rcfile=.coveragerc -m pytest --cov=armi --cov-config=.coveragerc --cov-report=lcov --cov-append --ignore=venv armi/tests/test_mpiFeatures.py || true
-          mpiexec -n 2 --use-hwthread-cpus coverage run --rcfile=.coveragerc -m pytest --cov=armi --cov-config=.coveragerc --cov-report=lcov --cov-append --ignore=venv armi/tests/test_mpiParameters.py || true
-          coverage combine --rcfile=.coveragerc --keep -a
+          coverage run --rcfile=pyproject.toml -m pytest -n 4 --cov=armi --cov-config=pyproject.toml --cov-report=lcov --ignore=venv armi
+          mpiexec -n 2 --use-hwthread-cpus coverage run --rcfile=pyproject.toml -m pytest --cov=armi --cov-config=pyproject.toml --cov-report=lcov --cov-append --ignore=venv armi/tests/test_mpiFeatures.py || true
+          mpiexec -n 2 --use-hwthread-cpus coverage run --rcfile=pyproject.toml -m pytest --cov=armi --cov-config=pyproject.toml --cov-report=lcov --cov-append --ignore=venv armi/tests/test_mpiParameters.py || true
+          coverage combine --rcfile=pyproject.toml --keep -a
       - name: Publish to coveralls.io
         uses: coverallsapp/github-action@v1.1.2
         with:
diff --git a/armi/cases/case.py b/armi/cases/case.py
index dec8e69b..3cafa4be 100644
--- a/armi/cases/case.py
+++ b/armi/cases/case.py
@@ -30,10 +30,8 @@ import cProfile
 import glob
 import os
 import pathlib
-import platform
 import pstats
 import re
-import shutil
 import sys
 import textwrap
 import time
@@ -62,8 +60,8 @@ from armi.utils.customExceptions import NonexistentSetting
 from armi.utils.directoryChangers import DirectoryChanger
 from armi.utils.directoryChangers import ForcedCreationDirectoryChanger
 
-# change from default .coverage to help with Windows dotfile issues.
-# Must correspond with data_file entry in `coveragerc`!
+# Change from default .coverage to help with Windows dotfile issues.
+# Must correspond with data_file entry in `pyproject.toml`!
 COVERAGE_RESULTS_FILE = "coverage_results.cov"
 
 
@@ -444,6 +442,10 @@ class Case:
         """Helper to provide the coverage configuration file according to the OS. A
         user-supplied file will take precedence, and is not checked for a dot-filename.
 
+        Notes
+        -----
+        ARMI replaced the ".coveragerc" file has been replaced by "pyproject.toml".
+
         Parameters
         ----------
         userCovFile : str
@@ -455,21 +457,14 @@ class Case:
         Returns
         -------
         covFile : str
-            path of coveragerc file
+            path of pyprojec.toml file
         """
         # User-defined file takes precedence.
         if userCovFile:
             return os.path.abspath(userCovFile)
 
         covRcDir = os.path.abspath(context.PROJECT_ROOT)
-        covFile = os.path.join(covRcDir, ".coveragerc")
-        if platform.system() == "Windows":
-            covFileWin = os.path.join(covRcDir, "coveragerc")
-            if makeCopy is True:
-                # Make a copy of the file without the dot in the name
-                shutil.copy(covFile, covFileWin)
-            return covFileWin
-        return covFile
+        return os.path.join(covRcDir, "pyproject.toml")
 
     def _startProfiling(self):
         """Helper to the Case.run(): start the Python profiling,
diff --git a/doc/release/0.3.rst b/doc/release/0.3.rst
index bb58d291..fac43123 100644
--- a/doc/release/0.3.rst
+++ b/doc/release/0.3.rst
@@ -42,6 +42,7 @@ Bug Fixes
 Quality Work
 ------------
 #. We now enforce a maximum line length of 120 characters, using ``ruff``. (`PR#1646 <https://github.com/terrapower/armi/pull/1646>`_)
+#. Move ``.coveragerc`` file information into ``pyproject.toml``. (`PR#1692 <https://github.com/terrapower/armi/pull/1692>`_)
 #. TBD
 
 Changes that Affect Requirements
diff --git a/pyproject.toml b/pyproject.toml
index 7d7de0b0..7adb1802 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -219,6 +219,45 @@ filterwarnings = [
     "ignore: the matrix subclass is not the recommended way:PendingDeprecationWarning",
 ]
 
+[tool.coverage.run]
+exclude_also = [
+    "armi/cli/gridGui.py",
+    "armi/utils/gridEditor.py",
+    "armi/utils/tests/test_gridGui.py",
+    "venv/",
+    ]
+source = ["armi"]
+parallel = true
+# Change default .coverage file to something that doesn't have a dot
+# because some Windows services can't handle dots.
+data_file = "coverage_results.cov"
+
+[tool.coverage.report]
+# Regexes for lines to exclude from consideration
+omit = [
+    "armi/cli/gridGui.py",
+    "armi/utils/gridEditor.py",
+    "*/tests/*",
+    ]
+
+exclude_also = [
+    # Don't complain about missing debug-only code:
+    "def __repr__",
+    "if self\\.debug",
+
+    # Don't complain if tests don't hit defensive assertion code:
+    "raise AssertionError",
+    "raise KeyboardInterrupt",
+    "raise NotImplementedError",
+    "except ImportError",
+    "pass",
+
+    # Don't complain if non-runnable code isn't run:
+    "if __name__ == .__main__.:",
+    ]
+
+ignore_errors = true
+
 
 #######################################################################
 #              DATA FILES TO BE INCLUDED WITH THE PROJECT             #


Test patch:
diff --git a/.github/workflows/unittests.yaml b/.github/workflows/unittests.yaml
index 8679712c..15c0b236 100644
--- a/.github/workflows/unittests.yaml
+++ b/.github/workflows/unittests.yaml
@@ -30,6 +30,6 @@ jobs:
         run: |
           pip install -e .[memprof,mpi,test]
           pytest -n 4 armi
-          mpiexec -n 2 --use-hwthread-cpus coverage run --rcfile=.coveragerc -m pytest --cov=armi --cov-config=.coveragerc --cov-report=lcov --cov-append --ignore=venv armi/tests/test_mpiFeatures.py || true
-          mpiexec -n 2 --use-hwthread-cpus coverage run --rcfile=.coveragerc -m pytest --cov=armi --cov-config=.coveragerc --cov-report=lcov --cov-append --ignore=venv armi/tests/test_mpiParameters.py || true
-          coverage combine --rcfile=.coveragerc --keep -a
+          mpiexec -n 2 --use-hwthread-cpus coverage run --rcfile=pyproject.toml -m pytest --cov=armi --cov-config=pyproject.toml --cov-report=lcov --cov-append --ignore=venv armi/tests/test_mpiFeatures.py || true
+          mpiexec -n 2 --use-hwthread-cpus coverage run --rcfile=pyproject.toml -m pytest --cov=armi --cov-config=pyproject.toml --cov-report=lcov --cov-append --ignore=venv armi/tests/test_mpiParameters.py || true
+          coverage combine --rcfile=pyproject.toml --keep -a
diff --git a/armi/cases/tests/test_cases.py b/armi/cases/tests/test_cases.py
index 0483868f..5d00da5f 100644
--- a/armi/cases/tests/test_cases.py
+++ b/armi/cases/tests/test_cases.py
@@ -139,10 +139,7 @@ class TestArmiCase(unittest.TestCase):
         covRcDir = os.path.abspath(context.PROJECT_ROOT)
         # Don't actually copy the file, just check the file paths match
         covRcFile = case._getCoverageRcFile(userCovFile="", makeCopy=False)
-        if platform.system() == "Windows":
-            self.assertEqual(covRcFile, os.path.join(covRcDir, "coveragerc"))
-        else:
-            self.assertEqual(covRcFile, os.path.join(covRcDir, ".coveragerc"))
+        self.assertEqual(covRcFile, os.path.join(covRcDir, "pyproject.toml"))
 
         userFile = "UserCovRc"
         covRcFile = case._getCoverageRcFile(userCovFile=userFile, makeCopy=False)