Skip to main content

CLI tool to scan and convert source files to UTF-8 with BOM.

Project description

CUTF

cutf is a CLI tool that scans source files, detects legacy encodings, and converts them to UTF-8 with BOM.

It can also report replacement characters () introduced by decoding issues. It can optionally fix those replacement characters interactively through Ollama while preserving the original file encoding.

Features

  • Scan one file or an entire directory tree.
  • Filter files by extension.
  • Detect source encoding with chardet.
  • Convert files to UTF-8 with BOM through iconv.
  • Interactively repair replacement characters through Ollama without changing file encoding.
  • Optional backup copy of original files.
  • Detailed report for converted, skipped, and problematic files.

Requirements

  • Python 3.10+
  • uv (only for local development)
  • iconv available in your system PATH when you use conversion mode
  • Ollama available when you use --fix-wrong-with-ai

Install iconv

  • macOS: usually preinstalled (iconv --version)
  • Linux: install from system package manager (for example libc-bin / glibc tools)
  • Windows: download and install GNU iconv for Windows (GnuWin32) and make sure iconv.exe is in PATH

Installation

Option A – Install from PyPI (recommended)

No need to clone the repository. Just run:

pip install cutf

or with uv:

uv tool install cutf

Then use it directly:

cutf --path ./src --all --extensions .py .txt

Option B – Clone and run locally

1) Clone the repository

git clone https://github.com/<your-org>/cutf.git
cd cutf

2) Create environment and install dependencies with uv

uv sync --all-groups

3) Run cutf

uv run cutf --path ./src --all --extensions .py .txt

Usage

usage: cutf --path PATH [--checks] [--convert] [--copyOld]
            [--fix-wrong-with-ai] [--ai-ollama-url AI_OLLAMA_URL]
            [--printMissingCharString] [--printAllSkippedFile]
            [--all] [--verbose] [--only-relevant]
            [--extensions EXT [EXT ...]]

Main options

  • --path: file or directory to process.
  • --checks: run missing-character checks.
  • --convert: convert non-UTF files to UTF-8 with BOM.
  • --fix-wrong-with-ai: interactively replace through Ollama while preserving the file encoding.
  • --ai-ollama-url: override the Ollama base URL used by AI fix mode.
  • --all: enable both --checks and --convert.
  • --extensions: list of extensions to scan (required), for example .cpp .h .cs .ini.
  • --copyOld: copy original file before conversion into temp folder.
  • --printMissingCharString: print the line content for each missing-character finding.
  • --printAllSkippedFile: print every skipped file instead of only the count.
  • --only-relevant: hide less relevant missing-character entries.
  • --verbose: print extra execution logs.

AI Fix Mode

--fix-wrong-with-ai is a dedicated mode. It cannot be combined with --checks, --convert, or --all.

When enabled, cutf:

  • scans every matching file for
  • asks Ollama for a single-character replacement proposal
  • shows the wrong line and the proposed corrected line
  • lets you choose whether to apply, retry, or skip
  • writes the accepted fix back without changing the original encoding or BOM

Ollama URL resolution order:

  • --ai-ollama-url
  • .env file next to the executable, using OLLAMA_URL=...
  • OLLAMA_URL from the process environment
  • current-user environment on Windows when available

Default model: qwen2.5:1.5b-instruct

Typical Commands

Run checks only:

uv run cutf --path ./project --checks --extensions .py .js .ts

Run conversion + checks:

uv run cutf --path ./project --all --extensions .cpp .h --copyOld

Process one file:

uv run cutf --path ./src/main.cpp --all --extensions .cpp

Run interactive AI fixing:

OLLAMA_URL=http://localhost:11434 uv run cutf --path ./src --fix-wrong-with-ai --extensions .cpp .py

Override the Ollama URL explicitly:

uv run cutf --path ./src --fix-wrong-with-ai --ai-ollama-url http://localhost:11434 --extensions .cpp

Development

Run tests:

uv run pytest

Run linter:

uv run ruff check .

Format code:

uv run ruff format .

FAQ

Why does CUTF require --extensions?

It prevents accidental processing of unrelated files and keeps scans predictable.

Why UTF-8 with BOM?

Some tools and Windows-oriented workflows require BOM for UTF-8 detection.

What happens if iconv is missing?

CUTF stops before processing and prints an error only for conversion mode. AI fix mode does not require iconv.

Where are original files copied when --copyOld is enabled?

They are copied to <system-temp>/SrcChE.

Does CUTF modify UTF-8 files?

Only when conversion is requested and the file is detected as non-UTF. Otherwise files are skipped.

Does AI fix mode change the file encoding?

No. Accepted changes are written back using the original encoding and BOM.

License

This project is distributed under the license in LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cutf-0.0.10.tar.gz (76.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cutf-0.0.10-py3-none-any.whl (23.5 kB view details)

Uploaded Python 3

File details

Details for the file cutf-0.0.10.tar.gz.

File metadata

  • Download URL: cutf-0.0.10.tar.gz
  • Upload date:
  • Size: 76.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.15 {"installer":{"name":"uv","version":"0.11.15","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for cutf-0.0.10.tar.gz
Algorithm Hash digest
SHA256 f34350f3644c06b668997e9cbdd23a7896c09f85c66e50efaf5f7a98b1f38ed8
MD5 f713abd942125043271cc6bc4a04ea56
BLAKE2b-256 74190fe89cfc25c3fb9315f522856b11ff5aba57a26e9aa96bc9a0847e5d748b

See more details on using hashes here.

File details

Details for the file cutf-0.0.10-py3-none-any.whl.

File metadata

  • Download URL: cutf-0.0.10-py3-none-any.whl
  • Upload date:
  • Size: 23.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.15 {"installer":{"name":"uv","version":"0.11.15","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for cutf-0.0.10-py3-none-any.whl
Algorithm Hash digest
SHA256 1b043473ca49d5d4e5d7087becca8f316a43112e5c26fb6dfdb54205c74638d3
MD5 a816a31102b074f679a2ce1310545aa5
BLAKE2b-256 56b8fd4fc0739df0d2485b03be1c71fc8fd1234987c59be7441a4347a4a27e7b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page