<!--
SPDX-FileCopyrightText: Peter Pentchev <roam@ringlet.net>
SPDX-License-Identifier: BSD-2-Clause
-->

# Changelog

All notable changes to the utf8-locale project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [1.1.2] - 2026-08-05

### Fixes

- Rust implementation:
    - include the `tests/data.json` file in the `utf8-locale` crate and
      look for it in the same subdirectory that our `Cargo.toml` file is,
      not higher up; this allows the tests to pass with the packaged crate
    - do not copy the `u8loc.1` file within the source tree, Cargo can
      handle a symlink
    - skip the Python `u8loc` test if there is no `functional.py` file,
      e.g. because it is not yet shipped in the crate
- CI:
    - use `utf8-locale`, not `roundlet`, as the stem for the name of
      the temporary directory

### Additions

- Rust implementation:
    - make sure the tests will work from the directories of the packaged crates, too
- CI:
    - also install `jq` since the `el-build-and-test` tool uses it now

## [1.1.1] - 2026-08-04

### Additions

- Rust implementation:
    - ship a copy of the manual page in the `u8loc` crate

### Fixes

- CI:
    - drop two commented-out lines from the job definition

### Other changes

- Test suite:
    - use ty 0.0.66 with no changes

## [1.1.0] - 2026-08-04

### Semi-incompatible changes

- Python implementation:
    - drop support for Python 3.8, 3.9, and 3.10
- Rust implementation:
    - bump MSRV to 1.88
    - split into two crates: `utf8-locale` for the library and `u8loc` for
      the command-line tool
    - do not expose some nested error types

### Fixes

- Python implementation:
    - bump dependency versions to fix the build with the lowest
      versions of the dependencies (`uv --resolution=lowest`)
- Rust implementation:
    - bump dependency versions to fix the build with the lowest
      versions of the dependencies (`cargo -Zminimal-versions`)
    - assorted fixes suggested by Clippy
- Test suite:
    - make sure the `reuse` virtual envitonment has `charset-normalizer` installed

### Additions

- Python implementation:
    - tentatively mark Python 3.15 as supported
- Rust implementation:
    - add a `u8loc` test that runs the Python functional test against
      the binary executable
    - add two `execline` scripts for building and testing the Rust crates
    - add the `Iterable` trait in preparation for making some of the functions
      even more generic in future versions
    - add the `choose_locale` and `supported_system_locales` functions
- Test suite:
    - use `uvoxen` to generate and run the tests; autogenerate `tox.ini`,
      `uv.lock`, and `python/requirements/docs.txt`
    - add the `ty` test environment for more type checking
- CI:
    - add sourcehut CI definitions for building and testing on Alpine Linux
- Documentation:
    - add `publync` configuration for publishing to the Ringlet website

### Other changes

- Python implementation:
    - switch to PEP 735 dependency groups
    - drop the `hatchling-requirements-txt` dependency
    - keep the `python/requirements/docs.txt` file for ReadTheDocs
    - sprinkle `Final` annotations throughout the codebase
    - use structural pattern matching to simplify some routines
- Rust implementation:
    - bump MSRV to 1.88:
        - use `std::sync::LazyLock` instead of the `once_cell` crate
        - use `expect` with a reason instead of `allow`
        - use Rust edition 2024
    - drop the `thiserror` dependency
    - sync some dependency lower constraints with Debian 13 (trixie)
    - make the `detect_utf8_locale`, `get_utf8_vars`, and `get_utf8_env`
      functions support `Iterable` parameters instead of only array slices
    - move the `Cargo.toml` file to the top-level source directory
    - use workspace package definitions
    - use workspace dependency definitions
    - switch from `license` to `license-file` in the Cargo metadata so that
      the `BSD-2-License` file is included in the crate
    - use the `roundlet` crate's `cli-basic-clap` feature for command-line
      `--help`, `--version`, and `--features` processing
    - use the `roundlet` crate's `test-exe-path` feature in the test suite
- Test suite:
    - use reuse 6.x with no changes
    - use ruff 0.16.1, update some lint overrides
    - use feature-check 2.x and its `Version` objects
    - drop the long-obsolete `tool.black` section from
      the `pyproject.toml` file
    - use pytest 9.x, pass the `--strict` option
    - allow mypy 2.x with no changes
    - drop the Nix testing framework
    - drop the `vetox` testing tool

## [1.0.4] - 2025-01-18

### Fixes

- Point to the Ringlet homepage instead of the GitLab repo as appropriate
- Correct the project name in the "Contact" section of the documentation
- Python implementation:
    - assorted fixes suggested by Ruff
    - bump the required hatchling version to support Python 3.13+ and
      the PEP 639 license specification
- Rust implementation:
    - assorted fixes suggested by Clippy

### Additions

- Python implementation:
    - tentatively declare Python 3.14 as supported
    - uncomment the "Changes" URL in `pyproject.toml`
- Test suite:
    - let `tests/full.sh` honor the `TOX_STAGES` environment variable so
      that an alternative one, e.g. one that uses `uv`, may be used

### Other changes

- Python implementation:
    - switch to a PEP 639 license specification
- Rust implementation:
    - use `//` comments for the SPDX copyright and license tags
    - allow `thiserror` 2.x
    - use `serde_derive` explicitly
    - reorganize the source files, push all Rust-related files into
      the `rust/` subdirectory, and the source files to `rust/src/`
    - switch from `getopts` to `clap` for the `u8loc` tool
- Test suite:
    - use `@docs` as a separate Tox stages tag
    - use reuse 4.x and switch from `.reuse/dep5` to `REUSE.toml`
    - vendor-import vetox 0.2.1
    - Ruff:
        - use Ruff 0.9.2
        - reorganize the Ruff configuration: move some settings to
          the `pyproject.toml` file and the rest to `ruff-base.toml`
        - use concise output even in preview mode
    - Nix:
        - drop Python 3.8 from all the Python tests, it is no longer
          present in nixpkgs/unstable
        - drop Python 3.9 from the Tox test, nixpkgs/unstsable no longer
          support that
        - run the pytest and vetox tests on Python 3.14, too
        - make sure the tests are run with the correct version of Python

## [1.0.3] - 2024-02-28

### Fixes

- Manual page:
    - fix the formatting of the `--features` long option
- Python implementation:
    - fixes suggested by Ruff:
        - sort the `__all__` exported symbols list
        - use a set for tests using the `in` operator
        - add a forgotten `f` prefix to an f-string
        - add some trailing commas in complex function calls

### Additions

- Start some MkDocs-based documentation
- Python implementation:
    - declare Python 3.12 and (tentatively) 3.13 as supported
- Test suite:
    - Nix:
        - add the `python-vetox` expression and the `run-vetox.sh` helper

### Other changes

- C implementation:
    - bump the minimum CMake version to 3.16.0
- Python implementation:
    - switch to the Ruff source code formatter
    - use dataclasses instead of named tuples
    - minor refactoring of the type-checking imports
- Test suite:
    - add the temporary test directories to the `.gitignore` file
    - move the `cleanpy.sh` tool from the `nix/` directory to the `tests/` one
    - `tests/full.sh`:
        - use `tox-stages` instead of `tox-delay` for the Tox-based tests
        - use our `cleanpy.sh` tool to clean more Python-related files
    - Python:
        - run the `ruff`, `reuse`, and `format` tests before the `mypy` and `docs` ones
        - use `tox.minversion`, not `tox.min_version`, to allow Tox 3.x to bootstrap 4.x
        - break some Tox environment requirements into separate files
        - include pytest 8.x in the allowed versions
        - Ruff:
            - use a single `ruff` Tox environment with a pinned Ruff version
            - gather the Ruff configuration files in the common `python/config/ruff/`
              directory
            - test with Ruff 0.2.2 in preview mode, adapt some overrides
    - Rust:
        - add more `clippy` overrides, synced with Rust 1.74
    - Nix:
        - `python-tox`: drop the `tomli` dependency, the `tox` package was fixed
        - only run Tox on Python 3.9 through 3.11
        - use `gitMinimal` instead of `git` for the `reuse` Tox test

## [1.0.1] - 2023-06-29

### Fixes

- Python:
    - do not pass the `python_version` option to mypy
    - correctly annotate a test function that returns a `mock.patch()` object
    - many minor changes suggested by Ruff
- Rust:
    - a couple of minor changes suggested by Clippy

### Additions

- Add a Nix expression to only run the Python unit tests using `pytest`
- Add two shell helpers for running the Nix expressions with several
  versions of Python
- Python:
    - add a Ruff Tox test environment
    - add Tox environment tags for the `tox-stages` tool
    - add a manually-invoked `pyupgrade` Tox test environment

### Other changes

- Convert this changelog to the "Keep a Changelog" format.
- Drop the years from my copyright notices.
- Switch to SPDX copyright and license tags and add a "reuse" Tox environment for
  validating the SPDX tags
- Python:
    - drop Python 3.7 support
    - add the `ruff` and `ruff-all` Tox testing environments, test with Ruff 0.0.275
    - drop the `pep8` and `pylint` Tox testing environments, Ruff does most of that
    - order the Tox environment list a bit more logically
    - adapt the `tox.ini` file format for Tox 4.x
    - use black 23.x and mypy 1.x with no changes
    - use Pytest's own data-driven testing functions instead of the `ddt` library
    - switch to `hatchling` for the PEP 517 build
    - use Ruff's isort implementation
    - move the mypy configuration to the `pyproject.toml` file
    - use `functools.lru_cache()` in the test suite
- Rust:
    - use variables inline in `format!()` strings, declare MSRV 1.58
    - silence clippy's complaints about using blanket restrictions and
      using the question mark operator

## [1.0.0] - 2022-10-30

### Incompatible changes

- Rust:
    - the `get_preferred_languages()` function now accepts a reference to
      the environment variables, since it does not need to modify them
    - mark the public enums and structs as non-exhaustive
    - all functions now return errors instead of exiting the program
    - use our own error type instead of returning `Box<dyn error>`

### New features

- Add a Nix expression for running the Python tests in a clean environment
- Rust:
    - allow hashmaps to be constructed with different hashers
    - keep the `Cargo.lock` file under version control

### Fixes

- C:
    - use `regerror()` more robustly; thanks, John Scott
    - when freeing a list, free the correct pointer
    - add a missed `free()` in an error handling case
    - allow C++ programs to use the `utf8_locale.h` header file
    - do not use reserved identifiers as an include guard
- Python:
    - specify both lower and upper version constraints for the libraries used in
      the test environments
- Rust:
    - actually run the preferred language test with real data, not with
      an empty array

### Other changes

- Python:
    - use pylint 2.14, drop some message overrides
    - type annotations: use the standard `dict`, `list`, etc, types instead of
      the `typing` generics
    - list Python 3.10 and 3.11 as supported versions
    - drop the `flake8` + `hacking` Tox test environment
- Rust:
    - mark some functions as `const`, `inline`, and `must-use`
    - document the errors returned by the library functions
    - use the `thiserror` and `anyhow` libraries for error handling instead of
      the `quick-error` one
    - use the `once_cell` library for initializing static values instead of
      the `lazy_static` one
    - fix many minor issues reported by the `clippy` tool and add
      the `run-clippy` tool to run some stringent checks
    - refactor the internal `build_weights()` function to avoid integer
      arithmetic; when we mean to use the number of items in a hashmap,
      use the number of items in the hashmap
    - explicitly override some of the `clippy` diagnostics

## [0.3.0] - 2022-02-20

### Incompatible changes

- Rust:
    - the individual functions are no longer visible by default in
      the top-level namespace; the new builder interface is preferred

### New features

- Add a new object-oriented interface for the Python and Rust
  implementations: configure a `Utf8Detect` or `LanguagesDetect` object,
  and invoke their `.detect()` method instead of invoking the individual
  functions.
- Add a C implementation: a `libutf8_locale` library and a `u8loc`
  executable built using CMake.
- Add the `tests/full.sh` development helper tool that rebuilds all
  the implementations and runs their respective tests.
- Python:
    - move the languages test data to the `tests/data.json` definitions, too
    - add an object-oriented builder interface
- Rust:
    - add an object-oriented builder interface
    - add the beginnings of a unit test suite using the JSON test definitions

### Fixes

- Fix the functional test's behavior if the u8loc executable does not
  advertise the query-preferred feature.

### Other changes

- Add `*.c`, `*.h`, and `*.1` file definitions to the EditorConfig file.
- Python:
    - drop the `b0` suffix from the `black` tool versioned dependencies;
      the `black` tool is no longer in beta since version 22
- Rust:
    - use the `lazy_static` crate to only compile regular expressions once
    - import struct names directly as a more idiomatic style

## [0.2.0] - 2022-02-01

### New features

- The "C" language is now appended to the end of the list returned by
  the `get_preferred_languages()` function if it is not already there!
- Add the `get_utf8_vars()` function returning an environment-like
  dictionary that only contains the variables that need to be set,
  i.e. `LC_ALL` and `LANGUAGE`.
- Add the `u8loc` command-line tool to the Python implementation.
- Add the `u8loc.1` manual page.
- Add the `tests/functional.py` functional testing tool.
- Add an EditorConfig definitions file.
- Add a Rust implementation.

### Other changes

- Bring the Python build infrastructure somewhat more up to date.
- Require Python 3.7 for dataclasses support.
- Push the Python implementation into a `python/` source subdirectory.

## [0.1.1] - 2021-04-05

### New features

- Add a manifest file for the source distribution.

### Fixes

- Ignore locales with weird names instead of erroring out.
- Ignore the type of a `subprocess.check_output()` mock in the test suite.

## [0.1.0] - 2021-01-04

### Started

- First public release.

[Unreleased]: https://gitlab.com/ppentchev/utf8-locale/-/compare/release%2F1.1.2...main
[1.1.2]: https://gitlab.com/ppentchev/utf8-locale/-/compare/release%2F1.1.1...release%2F1.1.2
[1.1.1]: https://gitlab.com/ppentchev/utf8-locale/-/compare/release%2F1.1.0...release%2F1.1.1
[1.1.0]: https://gitlab.com/ppentchev/utf8-locale/-/compare/release%2F1.0.4...release%2F1.1.0
[1.0.4]: https://gitlab.com/ppentchev/utf8-locale/-/compare/release%2F1.0.3...release%2F1.0.4
[1.0.3]: https://gitlab.com/ppentchev/utf8-locale/-/compare/release%2F1.0.1...release%2F1.0.3
[1.0.1]: https://gitlab.com/ppentchev/utf8-locale/-/compare/release%2F1.0.0...release%2F1.0.1
[1.0.0]: https://gitlab.com/ppentchev/utf8-locale/-/compare/release%2F0.3.0...release%2F1.0.0
[0.3.0]: https://gitlab.com/ppentchev/utf8-locale/-/compare/release%2F0.2.0...release%2F0.3.0
[0.2.0]: https://gitlab.com/ppentchev/utf8-locale/-/compare/release%2F0.1.1...release%2F0.2.0
[0.1.1]: https://gitlab.com/ppentchev/utf8-locale/-/compare/release%2F0.1.0...release%2F0.1.1
[0.1.0]: https://gitlab.com/ppentchev/utf8-locale/-/tags/release%2F0.1.0
