Skip to content

Commit

Permalink
allow using xrlint-config.* instead of xrlint_config.*
Browse files Browse the repository at this point in the history
  • Loading branch information
forman committed Feb 21, 2025
1 parent 79f497e commit dc1a95d
Show file tree
Hide file tree
Showing 9 changed files with 79 additions and 43 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# xrlint
/xrlint-config.*
/xrlint_config.*
/notebooks/xrlint-config.*
/notebooks/xrlint_config.*

# Logs
Expand Down
6 changes: 6 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

## Version 0.5.1 (in development)

- XRLint now also loads default configuration from files named
`xrlint-config.yaml` and `xrlint-config.json`. (#60)

- The command `xrlint --init` now writes `xrlint-config.yaml`
instead of `xrlint_config.yaml`.

- Enhanced documentation by a new page that compiles
the code examples in the `examples` folder.

Expand Down
47 changes: 30 additions & 17 deletions docs/cli.md
Original file line number Diff line number Diff line change
@@ -1,32 +1,44 @@
# Command Line Interface

After installation, the `xrlint` command can be used from the terminal.
The following are the command's options and arguments:
The following are the command's usage help including a short description
of its options and arguments:

```
Usage: xrlint [OPTIONS] [FILES]...
Validate the given dataset FILES.
Reads configuration from './xrlint_config.*' if such file exists and unless
'--no_config_lookup' is set or '--config' is provided. It then validates
each dataset in FILES against the configuration. The default dataset patters
are '**/*.zarr' and '**/.nc'. FILES may comprise also directories or URLs.
The supported URL protocols are the ones supported by xarray. Using remote
protocols may require installing additional packages such as S3Fs
(https://s3fs.readthedocs.io/) for the 's3' protocol.
When executed, XRLint does the following three things:
If a directory is provided that not matched by any file pattern, it will be
traversed recursively. The validation result is dumped to standard output if
not otherwise stated by '--output-file'. The output format is 'simple' by
default. Other inbuilt formats are 'json' and 'html' which you can specify
using the '--format' option.
(1) Unless options '--no-config-lookup' or '--config' are used it searches
for a default configuration file in the current working directory. Default
configuration files are determined by their filename, namely
'xrlint_config.py' or 'xrlint-config.<format>', where <format> refers to the
filename extensions 'json', 'yaml', and 'yml'. A Python configuration file
('*.py'), is expected to provide XRLInt configuration from a function
'export_config()', which may include custom plugins and rules.
(2) It then validates each dataset in FILES against the configuration. The
default dataset patters are '**/*.zarr' and '**/.nc'. FILES may comprise
also directories or URLs. The supported URL protocols are the ones supported
by xarray. Using remote protocols may require installing additional packages
such as S3Fs (https://s3fs.readthedocs.io/) for the 's3' protocol. If a
directory is provided that not matched by any file pattern, it will be
traversed recursively.
(3) The validation result is dumped to standard output if not otherwise
stated by '--output-file'. The output format is 'simple' by default. Other
inbuilt formats are 'json' and 'html' which you can specify using the '--
format' option.
Please refer to the documentation (https://bcdev.github.io/xrlint/) for more
information.
Options:
--no-config-lookup Disable use of default configuration from
xrlint_config.*
-c, --config FILE Use this configuration, overriding xrlint_config.*
config options if present
--no-config-lookup Disable use of default configuration files
-c, --config FILE Use this configuration instead of looking for a
default configuration file
--print-config FILE Print the configuration for the given file
--plugin MODULE Specify plugins. MODULE is the name of Python module
that defines an 'export_plugin()' function.
Expand All @@ -40,4 +52,5 @@ Options:
--init Write initial configuration file and exit.
--version Show the version and exit.
--help Show this message and exit.
```
8 changes: 4 additions & 4 deletions docs/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ Many parts have been copied and adjusted as it applies in many similar ways to X

The XRLint configuration file may be named any of the following:

* `xrlint_config.yaml`
* `xrlint_config.json`
* `xrlint_config.py`
* YAML format: `xrlint-config.yaml` (or use extension `.yml`)
* JSON format: `xrlint-config.json`
* Python module: `xrlint_config.py` (note the underscore)

It should be placed in the root directory of your project and export
an array of [configuration objects](#configuration-objects) or
Expand Down Expand Up @@ -40,7 +40,7 @@ Same using JSON:
]
```

And as Python script:
And as Python module:

```python
def export_config():
Expand Down
2 changes: 1 addition & 1 deletion docs/start.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Initializing a new project with
xrlint --init
```

writes a configuration file `xrlint_config.yaml`
writes a configuration file `xrlint-config.yaml`
into the current working directory:

```yaml
Expand Down
2 changes: 1 addition & 1 deletion notebooks/xrlint-linter.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -1924,7 +1924,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.13.1"
"version": "3.12.8"
}
},
"nbformat": 4,
Expand Down
4 changes: 3 additions & 1 deletion tests/cli/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,10 @@ def test_color_no_color(self):
def test_files_with_invalid_config(self):
with text_file(DEFAULT_CONFIG_FILE_YAML, self.invalid_config_yaml):
result = self.xrlint("--no-color", *self.files)
# noinspection SpellCheckingInspection
self.assertEqual(
"Error: xrlint_config.yaml: configuration 'recommentet' not found\n",
f"Error: {DEFAULT_CONFIG_FILE_YAML}:"
" configuration 'recommentet' not found\n",
result.output,
)
self.assertEqual(1, result.exit_code)
Expand Down
20 changes: 13 additions & 7 deletions xrlint/cli/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,24 @@

from typing import Final

DEFAULT_CONFIG_BASENAME: Final = "xrlint_config"

DEFAULT_CONFIG_FILE_YAML: Final = f"{DEFAULT_CONFIG_BASENAME}.yaml"
DEFAULT_CONFIG_FILE_JSON: Final = f"{DEFAULT_CONFIG_BASENAME}.json"
DEFAULT_CONFIG_FILE_PY: Final = f"{DEFAULT_CONFIG_BASENAME}.py"
_MODULE_BASENAME: Final = "xrlint_config"
_REGULAR_BASENAME: Final = "xrlint-config"


DEFAULT_CONFIG_FILES: Final = [
DEFAULT_CONFIG_FILE_YAML,
DEFAULT_CONFIG_FILE_JSON,
DEFAULT_CONFIG_FILE_PY,
# Added in 0.5.1:
f"{_REGULAR_BASENAME}.yaml",
f"{_REGULAR_BASENAME}.yml",
f"{_REGULAR_BASENAME}.json",
# Until 0.5.0:
f"{_MODULE_BASENAME}.yaml",
f"{_MODULE_BASENAME}.yml",
f"{_MODULE_BASENAME}.json",
f"{_MODULE_BASENAME}.py",
]

DEFAULT_CONFIG_FILE_YAML: Final = f"{_REGULAR_BASENAME}.yaml"
DEFAULT_OUTPUT_FORMAT: Final = "simple"
DEFAULT_MAX_WARNINGS: Final = 5

Expand Down
31 changes: 19 additions & 12 deletions xrlint/cli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
# Warning: do not import heavy stuff here, it can
# slow down commands like "xrlint --help" otherwise.
from xrlint.cli.constants import (
DEFAULT_CONFIG_BASENAME,
DEFAULT_MAX_WARNINGS,
DEFAULT_OUTPUT_FORMAT,
)
Expand All @@ -20,17 +19,14 @@
@click.option(
"--no-config-lookup",
"no_config_lookup",
help=f"Disable use of default configuration from {DEFAULT_CONFIG_BASENAME}.*",
help="Disable use of default configuration files",
is_flag=True,
)
@click.option(
"--config",
"-c",
"config_path",
help=(
f"Use this configuration, overriding {DEFAULT_CONFIG_BASENAME}.*"
f" config options if present"
),
help="Use this configuration instead of looking for a default configuration file",
metavar="FILE",
)
@click.option(
Expand Down Expand Up @@ -115,22 +111,33 @@ def main(
):
"""Validate the given dataset FILES.
Reads configuration from './xrlint_config.*' if such file
exists and unless '--no-config-lookup' is set or '--config' is
provided.
It then validates each dataset in FILES against the configuration.
When executed, XRLint does the following three things:
(1) Unless options '--no-config-lookup' or '--config' are used
it searches for a default configuration file in the current working
directory. Default configuration files are determined by their
filename, namely 'xrlint_config.py' or 'xrlint-config.<format>',
where <format> refers to the filename extensions
'json', 'yaml', and 'yml'. A Python configuration file ('*.py'),
is expected to provide XRLInt configuration from a function
'export_config()', which may include custom plugins and rules.
(2) It then validates each dataset in FILES against the configuration.
The default dataset patters are '**/*.zarr' and '**/.nc'.
FILES may comprise also directories or URLs. The supported URL
protocols are the ones supported by xarray. Using remote
protocols may require installing additional packages such as
S3Fs (https://s3fs.readthedocs.io/) for the 's3' protocol.
If a directory is provided that not matched by any file pattern,
it will be traversed recursively.
The validation result is dumped to standard output if not otherwise
(3) The validation result is dumped to standard output if not otherwise
stated by '--output-file'. The output format is 'simple' by default.
Other inbuilt formats are 'json' and 'html' which you can specify
using the '--format' option.
Please refer to the documentation (https://bcdev.github.io/xrlint/)
for more information.
"""
from xrlint.cli.engine import XRLint

Expand Down

0 comments on commit dc1a95d

Please sign in to comment.