codecov[bot]: # [Codecov](https://codecov.io/gh/repobee/repobee/pull/535?src=pr&el=h1) Report
> Merging [#535](https://codecov.io/gh/repobee/repobee/pull/535?src=pr&el=desc) into [master](https://codecov.io/gh/repobee/repobee/commit/03c8971cb3a6ab9276d99af987bcd6139026a373&el=desc) will **decrease** coverage by `3.74%`.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/repobee/repobee/pull/535/graphs/tree.svg?width=650&height=150&src=pr&token=5vOKgkphZe)](https://codecov.io/gh/repobee/repobee/pull/535?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master     #535      +/-   ##
==========================================
- Coverage   91.92%   88.18%   -3.75%     
==========================================
  Files          47       47              
  Lines        2478     2463      -15     
  Branches      407      405       -2     
==========================================
- Hits         2278     2172     -106     
- Misses        154      241      +87     
- Partials       46       50       +4     
```


| [Impacted Files](https://codecov.io/gh/repobee/repobee/pull/535?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [src/\_repobee/config.py](https://codecov.io/gh/repobee/repobee/pull/535/diff?src=pr&el=tree#diff-c3JjL19yZXBvYmVlL2NvbmZpZy5weQ==) | `100.00% <100.00%> (ø)` | |
| [src/\_repobee/constants.py](https://codecov.io/gh/repobee/repobee/pull/535/diff?src=pr&el=tree#diff-c3JjL19yZXBvYmVlL2NvbnN0YW50cy5weQ==) | `100.00% <100.00%> (ø)` | |
| [src/\_repobee/ext/defaults/configwizard.py](https://codecov.io/gh/repobee/repobee/pull/535/diff?src=pr&el=tree#diff-c3JjL19yZXBvYmVlL2V4dC9kZWZhdWx0cy9jb25maWd3aXphcmQucHk=) | `97.29% <100.00%> (ø)` | |
| [src/\_repobee/ext/gitlab.py](https://codecov.io/gh/repobee/repobee/pull/535/diff?src=pr&el=tree#diff-c3JjL19yZXBvYmVlL2V4dC9naXRsYWIucHk=) | `63.86% <0.00%> (-28.56%)` | :arrow_down: |
| [src/\_repobee/cli/parsing.py](https://codecov.io/gh/repobee/repobee/pull/535/diff?src=pr&el=tree#diff-c3JjL19yZXBvYmVlL2NsaS9wYXJzaW5nLnB5) | `86.57% <0.00%> (-5.37%)` | :arrow_down: |
| [src/\_repobee/git.py](https://codecov.io/gh/repobee/repobee/pull/535/diff?src=pr&el=tree#diff-c3JjL19yZXBvYmVlL2dpdC5weQ==) | `96.62% <0.00%> (-3.38%)` | :arrow_down: |
| [src/\_repobee/command/repos.py](https://codecov.io/gh/repobee/repobee/pull/535/diff?src=pr&el=tree#diff-c3JjL19yZXBvYmVlL2NvbW1hbmQvcmVwb3MucHk=) | `91.80% <0.00%> (-3.28%)` | :arrow_down: |
| [src/repobee\_plug/cli/\_corecommand.py](https://codecov.io/gh/repobee/repobee/pull/535/diff?src=pr&el=tree#diff-c3JjL3JlcG9iZWVfcGx1Zy9jbGkvX2NvcmVjb21tYW5kLnB5) | `92.30% <0.00%> (-0.20%)` | :arrow_down: |
| [src/\_repobee/ext/defaults/github.py](https://codecov.io/gh/repobee/repobee/pull/535/diff?src=pr&el=tree#diff-c3JjL19yZXBvYmVlL2V4dC9kZWZhdWx0cy9naXRodWIucHk=) | `90.29% <0.00%> (-0.11%)` | :arrow_down: |
| [src/repobee\_plug/\_pluginmeta.py](https://codecov.io/gh/repobee/repobee/pull/535/diff?src=pr&el=tree#diff-c3JjL3JlcG9iZWVfcGx1Zy9fcGx1Z2lubWV0YS5weQ==) | `97.93% <0.00%> (-0.05%)` | :arrow_down: |
| ... and [4 more](https://codecov.io/gh/repobee/repobee/pull/535/diff?src=pr&el=tree-more) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/repobee/repobee/pull/535?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/repobee/repobee/pull/535?src=pr&el=footer). Last update [03c8971...9ccaac4](https://codecov.io/gh/repobee/repobee/pull/535?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

diff --git a/docs/configuration.rst b/docs/configuration.rst
index 5d0393f..679b3e8 100644
--- a/docs/configuration.rst
+++ b/docs/configuration.rst
@@ -38,7 +38,7 @@ consequence, a single organization).
 
 .. code-block:: bash
 
-    [DEFAULTS]
+    [repobee]
     base_url = https://some-api-v3-url
     user = YOUR_USERNAME
     org_name = ORGANIZATION_NAME
@@ -48,7 +48,7 @@ consequence, a single organization).
 
 .. important::
 
-    If the configuration file exists, it *must* contain the ``[DEFAULTS]``
+    If the configuration file exists, it *must* contain the ``[repobee]``
     header. This is to minimize the risk of misconfiguration by novice users.
 
 **To find out where to place the configuration file (and what to name it)**,
@@ -65,6 +65,6 @@ details.
 .. note::
 
     You can run ``repobee verify-settings`` to verify the basic configuration.
-    This will check the most important settings configurable in ``DEFAULTS``.
+    This will check the most important settings configurable in ``repobee``.
 
 .. _`GitHub access token docs`: https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/
diff --git a/docs/getting_started.rst b/docs/getting_started.rst
index 268d9d6..9e51b19 100644
--- a/docs/getting_started.rst
+++ b/docs/getting_started.rst
@@ -76,7 +76,7 @@ has defaults for at least the following:
 .. code-block:: bash
    :caption: config.ini
 
-   [DEFAULTS]
+   [repobee]
    base_url = https://some-enterprise-host/api/v3
    user = slarse
    org_name = repobee-demo
@@ -113,7 +113,7 @@ that you got everything correctly.
     [INFO] Found valid config file at /home/slarse/.config/repobee/config.ini
     [INFO]
     ----------------BEGIN CONFIG FILE-----------------
-    [DEFAULTS]
+    [repobee]
     base_url = https://some-enterprise-host/api/v3
     user = slarse
     org_name = repobee-demo
diff --git a/docs/plugins.rst b/docs/plugins.rst
index 2155e44..550a3a0 100644
--- a/docs/plugins.rst
+++ b/docs/plugins.rst
@@ -105,7 +105,7 @@ example of using the builtins_ ``javac`` and ``pylint``.
 
 .. code-block:: bash
 
-    [DEFAULTS]
+    [repobee]
     plugins = javac, pylint
 
 Like with all other configuration values, they are only used if no command line
@@ -198,7 +198,7 @@ the ``[javac]`` section. Example:
 
 .. code-block:: bash
 
-    [DEFAULTS]
+    [repobee]
     plugins = javac
 
     [javac]
@@ -231,7 +231,7 @@ define some defaults:
 
 .. code-block:: bash
 
-    [DEFAULTS]
+    [repobee]
     plugins = junit4
 
     [junit4]
@@ -241,10 +241,10 @@ define some defaults:
 
 .. important::
 
-    If the configuration file exists, it *must* contain the ``[DEFAULTS]``
+    If the configuration file exists, it *must* contain the ``[repobee]``
     header, even if you don't put anything in that section. This is to minimize
     the risk of subtle misconfiguration errors by novice users. If you only
-    want to configure plugins, just add the ``[DEFAULTS]`` header by itself,
+    want to configure plugins, just add the ``[repobee]`` header by itself,
     without options, to meet this requirement.
 
 .. _repobee-junit4: https://github.com/repobee/repobee-junit4
diff --git a/requirements/app.txt b/requirements/app.txt
index 661e660..4c4b556 100644
--- a/requirements/app.txt
+++ b/requirements/app.txt
@@ -2,5 +2,5 @@ appdirs
 daiquiri
 pygithub
 colored
-python-gitlab==1.15.0
+python-gitlab==2.4.0
 pluggy==0.13.1
diff --git a/setup.py b/setup.py
index 7a9a005..91494ce 100644
--- a/setup.py
+++ b/setup.py
@@ -43,7 +43,7 @@ required = [
     "daiquiri",
     "pygithub",
     "colored",
-    "python-gitlab==1.15.0",
+    "python-gitlab==2.4.0",
     "pluggy>=0.13.1",
 ]
 
diff --git a/src/_repobee/config.py b/src/_repobee/config.py
index b3f8eb9..22d02f7 100644
--- a/src/_repobee/config.py
+++ b/src/_repobee/config.py
@@ -81,7 +81,7 @@ def get_plugin_names(config_file: Union[str, pathlib.Path]) -> List[str]:
         return []
     config = _read_config(config_file)
     plugin_string = config.get(
-        constants.DEFAULTS_SECTION_HDR, "plugins", fallback=""
+        constants.CORE_SECTION_HDR, "plugins", fallback=""
     )
     return [name.strip() for name in plugin_string.split(",") if name]
 
@@ -132,7 +132,7 @@ def _read_defaults(config_file: pathlib.Path) -> dict:
     token = os.getenv(constants.TOKEN_ENV)
     if not config_file.is_file():
         return {} if not token else dict(token=token)
-    defaults = dict(_read_config(config_file)[constants.DEFAULTS_SECTION_HDR])
+    defaults = dict(_read_config(config_file)[constants.CORE_SECTION_HDR])
     if token:
         if defaults.get("token"):
             LOGGER.warning(
@@ -150,10 +150,10 @@ def _read_config(config_file: pathlib.Path) -> configparser.ConfigParser:
     except configparser.MissingSectionHeaderError:
         pass  # handled by the next check
 
-    if constants.DEFAULTS_SECTION_HDR not in config_parser:
+    if constants.CORE_SECTION_HDR not in config_parser:
         raise exception.FileError(
             "config file at '{!s}' does not contain the required "
-            "[DEFAULTS] header".format(config_file)
+            "[repobee] header".format(config_file)
         )
 
     return config_parser
diff --git a/src/_repobee/constants.py b/src/_repobee/constants.py
index daf0e59..79ee656 100644
--- a/src/_repobee/constants.py
+++ b/src/_repobee/constants.py
@@ -22,7 +22,7 @@ LOG_DIR = pathlib.Path(
         appname=_repobee._external_package_name, appauthor=_repobee.__author__
     )
 )
-DEFAULTS_SECTION_HDR = "DEFAULTS"
+CORE_SECTION_HDR = "repobee"
 DEFAULT_CONFIG_FILE = CONFIG_DIR / "config.ini"
 assert DEFAULT_CONFIG_FILE.is_absolute()
 
diff --git a/src/_repobee/ext/defaults/configwizard.py b/src/_repobee/ext/defaults/configwizard.py
index eaab7d8..99db987 100644
--- a/src/_repobee/ext/defaults/configwizard.py
+++ b/src/_repobee/ext/defaults/configwizard.py
@@ -56,8 +56,8 @@ def callback(args: argparse.Namespace, api: plug.API) -> None:
     os.makedirs(
         str(constants.DEFAULT_CONFIG_FILE.parent), mode=0o700, exist_ok=True
     )
-    if constants.DEFAULTS_SECTION_HDR not in parser:
-        parser.add_section(constants.DEFAULTS_SECTION_HDR)
+    if constants.CORE_SECTION_HDR not in parser:
+        parser.add_section(constants.CORE_SECTION_HDR)
 
     LOGGER.info("Welcome to the configuration wizard!")
     LOGGER.info("Type defaults for the options when prompted.")
@@ -69,11 +69,11 @@ def callback(args: argparse.Namespace, api: plug.API) -> None:
     LOGGER.info("Current defaults are shown in brackets [].")
     for option in constants.ORDERED_CONFIGURABLE_ARGS:
         prompt = "Enter default for '{}': [{}] ".format(
-            option, parser[constants.DEFAULTS_SECTION_HDR].get(option, "")
+            option, parser[constants.CORE_SECTION_HDR].get(option, "")
         )
         default = input(prompt)
         if default:
-            parser[constants.DEFAULTS_SECTION_HDR][option] = default
+            parser[constants.CORE_SECTION_HDR][option] = default
 
     with open(
         str(constants.DEFAULT_CONFIG_FILE),

Change the default section header to `repobee` instead of `DEFAULTS`
It makes more sense, and is less easy to confuse with `DEFAULT`, which has a special meaning.
diff --git a/tests/integration_tests/README.md b/tests/integration_tests/README.md
index 9ae85dc..d9c1c84 100644
--- a/tests/integration_tests/README.md
+++ b/tests/integration_tests/README.md
@@ -83,7 +83,7 @@ connect to the GitLab instance at `https://gitlab.integrationtest.local`.
 Replace `<TOKEN>` with [this token](token).
 
 ```
-[DEFAULTS]
+[repobee]
 base_url = https://gitlab.integrationtest.local
 token = <TOKEN>
 org_name = repobee-testing
diff --git a/tests/unit_tests/repobee/conftest.py b/tests/unit_tests/repobee/conftest.py
index 32a81c5..896d0be 100644
--- a/tests/unit_tests/repobee/conftest.py
+++ b/tests/unit_tests/repobee/conftest.py
@@ -164,7 +164,7 @@ _config_master_org = "master_org_name = {}".format(constants.MASTER_ORG_NAME)
 def config_missing_option(request, empty_config_mock, students_file):
     missing_option = request.param
 
-    config_contents = ["[DEFAULTS]"]
+    config_contents = ["[repobee]"]
     if not missing_option == "--bu":
         config_contents.append(_config_base)
     if not missing_option == "-o":
@@ -186,7 +186,7 @@ def config_mock(empty_config_mock, students_file):
     """Fixture with a pre-filled config file."""
     config_contents = os.linesep.join(
         [
-            "[DEFAULTS]",
+            "[repobee]",
             "base_url = {}".format(constants.BASE_URL),
             "user = {}".format(constants.USER),
             "org_name = {}".format(constants.ORG_NAME),
diff --git a/tests/unit_tests/repobee/plugin_tests/test_configwizard.py b/tests/unit_tests/repobee/plugin_tests/test_configwizard.py
index 07ec73a..a452941 100644
--- a/tests/unit_tests/repobee/plugin_tests/test_configwizard.py
+++ b/tests/unit_tests/repobee/plugin_tests/test_configwizard.py
@@ -53,9 +53,7 @@ def test_enters_values_if_config_file_exists_and_user_enters_yes(
     confparser.read(str(config_mock))
 
     for key, value in defaults_options.items():
-        assert (
-            confparser[_repobee.constants.DEFAULTS_SECTION_HDR][key] == value
-        )
+        assert confparser[_repobee.constants.CORE_SECTION_HDR][key] == value
 
 
 def test_enters_values_without_continue_prompt_if_no_config_exists(
@@ -73,9 +71,7 @@ def test_enters_values_without_continue_prompt_if_no_config_exists(
     confparser.read(str(config_mock))
 
     for key, value in defaults_options.items():
-        assert (
-            confparser[_repobee.constants.DEFAULTS_SECTION_HDR][key] == value
-        )
+        assert confparser[_repobee.constants.CORE_SECTION_HDR][key] == value
 
 
 def test_skips_empty_values(empty_config_mock, defaults_options):
@@ -99,13 +95,9 @@ def test_skips_empty_values(empty_config_mock, defaults_options):
     confparser = configparser.ConfigParser()
     confparser.read(str(empty_config_mock))
 
-    assert (
-        empty_option not in confparser[_repobee.constants.DEFAULTS_SECTION_HDR]
-    )
+    assert empty_option not in confparser[_repobee.constants.CORE_SECTION_HDR]
     for key, value in defaults_options.items():
-        assert (
-            confparser[_repobee.constants.DEFAULTS_SECTION_HDR][key] == value
-        )
+        assert confparser[_repobee.constants.CORE_SECTION_HDR][key] == value
 
 
 def test_retains_values_that_are_not_specified(config_mock, defaults_options):
@@ -137,7 +129,7 @@ def test_retains_values_that_are_not_specified(config_mock, defaults_options):
     empty_option = list(defaults_options.keys())[3]
     defaults_options[empty_option] = ""
     expected_retained_default = confparser[
-        _repobee.constants.DEFAULTS_SECTION_HDR
+        _repobee.constants.CORE_SECTION_HDR
     ][empty_option]
 
     # act
@@ -152,11 +144,11 @@ def test_retains_values_that_are_not_specified(config_mock, defaults_options):
     parser.read(str(config_mock))
 
     assert (
-        parser[_repobee.constants.DEFAULTS_SECTION_HDR][empty_option]
+        parser[_repobee.constants.CORE_SECTION_HDR][empty_option]
         == expected_retained_default
     )
     for option, value in defaults_options.items():
-        assert parser[_repobee.constants.DEFAULTS_SECTION_HDR][option] == value
+        assert parser[_repobee.constants.CORE_SECTION_HDR][option] == value
     for option, value in plugin_options.items():
         assert parser[plugin_section][option] == value
 
diff --git a/tests/unit_tests/repobee/test_config.py b/tests/unit_tests/repobee/test_config.py
index 7e88fa5..55b0230 100644
--- a/tests/unit_tests/repobee/test_config.py
+++ b/tests/unit_tests/repobee/test_config.py
@@ -30,7 +30,7 @@ class TestGetConfiguredDefaults:
     def test_get_configured_defaults_empty_file(self, empty_config_mock):
         with pytest.raises(exception.FileError) as exc_info:
             config.get_configured_defaults(str(empty_config_mock))
-        assert "does not contain the required [DEFAULTS] header" in str(
+        assert "does not contain the required [repobee] header" in str(
             exc_info.value
         )
 
@@ -61,7 +61,7 @@ class TestGetConfiguredDefaults:
         invalid_key = "not_valid_key"
         config_contents = os.linesep.join(
             [
-                "[{}]".format(_repobee.constants.DEFAULTS_SECTION_HDR),
+                "[{}]".format(_repobee.constants.CORE_SECTION_HDR),
                 "base_url = {}".format(BASE_URL),
                 "user = {}".format(USER),
                 "org_name = {}".format(ORG_NAME),
@@ -98,7 +98,7 @@ class TestGetConfiguredDefaults:
         with pytest.raises(exception.FileError) as exc_info:
             config.get_configured_defaults(str(empty_config_mock))
 
-        assert "does not contain the required [DEFAULTS] header" in str(
+        assert "does not contain the required [repobee] header" in str(
             exc_info.value
         )
 
@@ -126,7 +126,7 @@ class TestGetPluginNames:
     ):
         contents = os.linesep.join(
             [
-                "[{}]".format(_repobee.constants.DEFAULTS_SECTION_HDR),
+                "[{}]".format(_repobee.constants.CORE_SECTION_HDR),
                 "plugins = " + plugins_string,
             ]
         )
@@ -177,7 +177,7 @@ class TestCheckConfigIntegrity:
         empty_config_mock.write(
             os.linesep.join(
                 [
-                    "[{}]".format(_repobee.constants.DEFAULTS_SECTION_HDR),
+                    "[{}]".format(_repobee.constants.CORE_SECTION_HDR),
                     "user = someone",
                     "option = value",
                 ]
@@ -198,7 +198,7 @@ class TestCheckConfigIntegrity:
         empty_config_mock.write(
             os.linesep.join(
                 [
-                    "[{}]".format(_repobee.constants.DEFAULTS_SECTION_HDR),
+                    "[{}]".format(_repobee.constants.CORE_SECTION_HDR),
                     "user = someone",
                     "base_url",
                     "org_name = cool",
diff --git a/tests/unit_tests/repobee/test_main.py b/tests/unit_tests/repobee/test_main.py
index 9c707d9..941c749 100644
--- a/tests/unit_tests/repobee/test_main.py
+++ b/tests/unit_tests/repobee/test_main.py
@@ -406,7 +406,7 @@ def test_non_zero_exit_status_on_exception(
 
 def test_show_config_custom_config():
     config_text = """
-[DEFAULTS]
+[repobee]
 user = some-unlikely-user
 """.strip()
     with tempfile.NamedTemporaryFile() as tmpfile, patch(
diff --git a/tests/unit_tests/repobee_plug/test_pluginmeta.py b/tests/unit_tests/repobee_plug/test_pluginmeta.py
index 2e09683..5753dc9 100644
--- a/tests/unit_tests/repobee_plug/test_pluginmeta.py
+++ b/tests/unit_tests/repobee_plug/test_pluginmeta.py
@@ -436,7 +436,7 @@ class TestDeclarativeCommandExtension:
     @pytest.fixture
     def config_file(self, tmpdir):
         config_file = pathlib.Path(str(tmpdir)) / "config.ini"
-        config_file.write_text("[DEFAULTS]")
+        config_file.write_text("[repobee]")
         return config_file
 
     def test_add_required_option_to_config_show(

pip install -e .[TEST]
parse_log_pytest
requirements.txt
pytest>=4.0.0 pytest-cov>=2.6.1 pytest-mock codecov bandit flake8 black pytest
3.8
requirements/app.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
appdirs==1.4.4
bandit==1.7.10
black==24.8.0
certifi==2025.1.31
cffi==1.17.1
charset-normalizer==3.4.1
click==8.1.8
codecov==2.1.13
colored==1.4.4
coverage==7.6.1
cryptography==44.0.2
daiquiri==3.2.5.1
Deprecated==1.2.18
exceptiongroup==1.2.2
flake8==7.1.2
idna==3.10
iniconfig==2.1.0
markdown-it-py==3.0.0
mccabe==0.7.0
mdurl==0.1.2
mypy-extensions==1.0.0
packaging==24.2
pathspec==0.12.1
pbr==6.1.1
platformdirs==4.3.6
pluggy==1.5.0
pycodestyle==2.12.1
pycparser==2.22
pyflakes==3.2.0
PyGithub==2.6.1
Pygments==2.19.1
PyJWT==2.9.0
PyNaCl==1.5.0
pytest==8.3.5
pytest-cov==5.0.0
pytest-mock==3.14.0
python-gitlab==1.15.0
python-json-logger==3.3.0
PyYAML==6.0.2
-e git+https://github.com/repobee/repobee.git@03c8971cb3a6ab9276d99af987bcd6139026a373#egg=repobee
requests==2.32.3
rich==14.0.0
six==1.17.0
stevedore==5.3.0
tomli==2.2.1
typing_extensions==4.13.0
urllib3==2.2.3
wrapt==1.17.2

name: repobee
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=24.2=py38h06a4308_0
  - python=3.8.20=he870216_0
  - readline=8.2=h5eee18b_0
  - setuptools=75.1.0=py38h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.44.0=py38h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - appdirs==1.4.4
      - bandit==1.7.10
      - black==24.8.0
      - certifi==2025.1.31
      - cffi==1.17.1
      - charset-normalizer==3.4.1
      - click==8.1.8
      - codecov==2.1.13
      - colored==1.4.4
      - coverage==7.6.1
      - cryptography==44.0.2
      - daiquiri==3.2.5.1
      - deprecated==1.2.18
      - exceptiongroup==1.2.2
      - flake8==7.1.2
      - idna==3.10
      - iniconfig==2.1.0
      - markdown-it-py==3.0.0
      - mccabe==0.7.0
      - mdurl==0.1.2
      - mypy-extensions==1.0.0
      - packaging==24.2
      - pathspec==0.12.1
      - pbr==6.1.1
      - platformdirs==4.3.6
      - pluggy==1.5.0
      - pycodestyle==2.12.1
      - pycparser==2.22
      - pyflakes==3.2.0
      - pygithub==2.6.1
      - pygments==2.19.1
      - pyjwt==2.9.0
      - pynacl==1.5.0
      - pytest==8.3.5
      - pytest-cov==5.0.0
      - pytest-mock==3.14.0
      - python-gitlab==1.15.0
      - python-json-logger==3.3.0
      - pyyaml==6.0.2
      - repobee==3.0.0a3
      - requests==2.32.3
      - rich==14.0.0
      - six==1.17.0
      - stevedore==5.3.0
      - tomli==2.2.1
      - typing-extensions==4.13.0
      - urllib3==2.2.3
      - wrapt==1.17.2
prefix: /opt/conda/envs/repobee

tests/unit_tests/repobee/plugin_tests/test_configwizard.py::test_enters_values_if_config_file_exists_and_user_enters_yes tests/unit_tests/repobee/plugin_tests/test_configwizard.py::test_enters_values_without_continue_prompt_if_no_config_exists tests/unit_tests/repobee/plugin_tests/test_configwizard.py::test_skips_empty_values tests/unit_tests/repobee/plugin_tests/test_configwizard.py::test_retains_values_that_are_not_specified tests/unit_tests/repobee/test_config.py::TestGetConfiguredDefaults::test_get_configured_defaults_empty_file tests/unit_tests/repobee/test_config.py::TestGetConfiguredDefaults::test_get_configured_defaults_reads_full_config tests/unit_tests/repobee/test_config.py::TestGetConfiguredDefaults::test_token_in_env_variable_overrides_configuration_file tests/unit_tests/repobee/test_config.py::TestGetConfiguredDefaults::test_get_configured_defaults_raises_on_invalid_keys tests/unit_tests/repobee/test_config.py::TestGetConfiguredDefaults::test_get_configured_defaults_raises_on_missing_header tests/unit_tests/repobee/test_config.py::TestGetPluginNames::test_with_full_config tests/unit_tests/repobee/test_config.py::TestGetPluginNames::test_with_only_plugins[javac,pylint-expected_plugins0] tests/unit_tests/repobee/test_config.py::TestGetPluginNames::test_with_only_plugins[javac, tests/unit_tests/repobee/test_config.py::TestGetPluginNames::test_with_only_plugins[javac-expected_plugins2] tests/unit_tests/repobee/test_config.py::TestGetPluginNames::test_with_only_plugins[-expected_plugins3] tests/unit_tests/repobee/test_config.py::TestExecuteConfigHooks::test_with_config_file tests/unit_tests/repobee/test_config.py::TestCheckConfigIntegrity::test_with_well_formed_config tests/unit_tests/repobee/test_config.py::TestCheckConfigIntegrity::test_with_invalid_defaults_key_raises tests/unit_tests/repobee/test_config.py::TestCheckConfigIntegrity::test_with_valid_but_malformed_default_args_raises tests/unit_tests/repobee/test_main.py::test_no_plugins_with_configured_plugins tests/unit_tests/repobee/test_main.py::test_configured_plugins_are_loaded tests/unit_tests/repobee/test_main.py::test_show_config_custom_config tests/unit_tests/repobee_plug/test_pluginmeta.py::TestDeclarativeCommandExtension::test_add_required_option_to_config_show
tests/unit_tests/repobee/plugin_tests/test_configwizard.py::test_exits_when_config_file_exists_and_user_enters_no tests/unit_tests/repobee/plugin_tests/test_configwizard.py::test_creates_directory tests/unit_tests/repobee/test_config.py::TestGetConfiguredDefaults::test_get_configured_defaults_no_config_file tests/unit_tests/repobee/test_config.py::TestExecuteConfigHooks::test_with_no_config_file tests/unit_tests/repobee/test_config.py::TestCheckConfigIntegrity::test_with_well_formed_plugin_options tests/unit_tests/repobee/test_config.py::TestCheckConfigIntegrity::test_with_no_config_file_raises tests/unit_tests/repobee/test_main.py::test_happy_path tests/unit_tests/repobee/test_main.py::test_exit_status_1_on_exception_in_parsing tests/unit_tests/repobee/test_main.py::test_exit_status_1_on_exception_in_handling_parsed_args tests/unit_tests/repobee/test_main.py::test_plugins_args tests/unit_tests/repobee/test_main.py::test_no_plugins_arg tests/unit_tests/repobee/test_main.py::test_dist_plugins_are_loaded_when_dist_install tests/unit_tests/repobee/test_main.py::test_plugin_with_subparser_name tests/unit_tests/repobee/test_main.py::test_plug_arg_incompatible_with_no_plugins tests/unit_tests/repobee/test_main.py::test_invalid_plug_options tests/unit_tests/repobee/test_main.py::test_does_not_raise_on_exception_in_dispatch tests/unit_tests/repobee/test_main.py::test_logs_traceback_on_exception_in_dispatch_if_traceback tests/unit_tests/repobee/test_main.py::test_show_all_opts_correctly_separated tests/unit_tests/repobee/test_main.py::test_non_zero_exit_status_on_exception tests/unit_tests/repobee/test_main.py::TestRun::test_operates_in_current_workdir_by_default tests/unit_tests/repobee/test_main.py::TestRun::test_operates_in_specified_workdir tests/unit_tests/repobee_plug/test_pluginmeta.py::TestPluginInheritance::test_raises_on_non_hook_public_method tests/unit_tests/repobee_plug/test_pluginmeta.py::TestPluginInheritance::test_happy_path tests/unit_tests/repobee_plug/test_pluginmeta.py::TestPluginInheritance::test_with_private_methods tests/unit_tests/repobee_plug/test_pluginmeta.py::TestDeclarativeExtensionCommand::test_default_settings tests/unit_tests/repobee_plug/test_pluginmeta.py::TestDeclarativeExtensionCommand::test_generated_parser tests/unit_tests/repobee_plug/test_pluginmeta.py::TestDeclarativeExtensionCommand::test_configuration tests/unit_tests/repobee_plug/test_pluginmeta.py::TestDeclarativeExtensionCommand::test_raises_when_non_configurable_value_is_configured tests/unit_tests/repobee_plug/test_pluginmeta.py::TestDeclarativeExtensionCommand::test_override_opt_names tests/unit_tests/repobee_plug/test_pluginmeta.py::TestDeclarativeExtensionCommand::test_positional_arguments tests/unit_tests/repobee_plug/test_pluginmeta.py::TestDeclarativeExtensionCommand::test_mutex_group_arguments_are_mutually_exclusive tests/unit_tests/repobee_plug/test_pluginmeta.py::TestDeclarativeExtensionCommand::test_positionals_not_allowed_in_mutex_group tests/unit_tests/repobee_plug/test_pluginmeta.py::TestDeclarativeExtensionCommand::test_mutex_group_allows_one_argument tests/unit_tests/repobee_plug/test_pluginmeta.py::TestDeclarativeExtensionCommand::test_create_new_category tests/unit_tests/repobee_plug/test_pluginmeta.py::TestDeclarativeExtensionCommand::test_add_two_actions_to_new_category tests/unit_tests/repobee_plug/test_pluginmeta.py::TestDeclarativeExtensionCommand::test_raises_when_both_action_and_category_given tests/unit_tests/repobee_plug/test_pluginmeta.py::TestDeclarativeExtensionCommand::test_parsed_args_are_added_to_self tests/unit_tests/repobee_plug/test_pluginmeta.py::TestDeclarativeCommandExtension::test_raises_when_command_and_command_extension_are_subclassed_together tests/unit_tests/repobee_plug/test_pluginmeta.py::TestDeclarativeCommandExtension::test_requires_settings tests/unit_tests/repobee_plug/test_pluginmeta.py::TestDeclarativeCommandExtension::test_requires_non_empty_actions_list
src/_repobee/config.py setup.py src/_repobee/ext/defaults/configwizard.py docs/getting_started.rst docs/plugins.rst requirements/app.txt src/_repobee/constants.py docs/configuration.rst
src/_repobee/config.py setup.py src/_repobee/ext/defaults/configwizard.py docs/getting_started.rst docs/plugins.rst requirements/app.txt src/_repobee/constants.py docs/configuration.rst