Metadata-Version: 2.4
Name: check-empty
Version: 2.0.0
Summary: Command-line utility, as well as a hook usable by the Python pre-commit framework, and a GitHub Action, to ensure that selected files are empty.
Keywords: check,command-line,empty,files,github-action,helper,hook,lightweight,pre-commit,prek,tool,utility
Author: Jonathan Dung
Author-email: Jonathan Dung <jonathandung@yahoo.com>
License-Expression: MIT
License-File: AUTHORS.md
License-File: LICENSE
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Natural Language :: English
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: 3.15
Classifier: Programming Language :: Python :: 3.16
Classifier: Programming Language :: Python :: Free Threading :: 3 - Stable
Classifier: Topic :: Utilities
Classifier: Typing :: Typed
Requires-Dist: py7zr==1.1.3 ; extra == '7z'
Requires-Dist: acefile==0.6.14 ; extra == 'ace'
Requires-Dist: check-empty[7z,ace,ar,lzh,rar]==2.0.0 ; extra == 'all'
Requires-Dist: arpy==2.4.0 ; extra == 'ar'
Requires-Dist: lhafile==0.3.1 ; extra == 'lzh'
Requires-Dist: rarfile==4.5 ; extra == 'rar'
Maintainer: Jonathan Dung
Maintainer-email: Jonathan Dung <jonathandung@yahoo.com>
Requires-Python: >=3.10
Provides-Extra: 7z
Provides-Extra: ace
Provides-Extra: all
Provides-Extra: ar
Provides-Extra: lzh
Provides-Extra: rar
Description-Content-Type: text/markdown

# [check-empty](https://pypi.org/p/check-empty)

[![#StandWithPalestine](https://raw.githubusercontent.com/TheBSD/StandWithPalestine/main/badges/StandWithPalestine.svg)](https://github.com/TheBSD/StandWithPalestine/blob/main/docs/README.md)

A simple, dependency-free [pre-commit](https://pre-commit.com) /
[prek](https://prek.j178.dev) hook, CLI, library and
[GitHub Action](https://github.com/marketplace/actions/check-empty-files) conglomerate
written in Python.

Makes sure selected files, even within directories, are empty according to as little
filesystem stat calls as possible, and clears them effectively with minimal I/O if
specified.

## Prerequisites

Supports every Python 3.10 runtime. There are no other requirements.

## Quickstart

If using double-asterisk globbing in the CLI, make sure it is enabled:

```bash
shopt -s globstar
```

similarly for extglob:

```bash
shopt -s extglob
```

Without installation (just trying out the capabilities):

```bash
uvx check-empty -Q src/mylib/py.typed docs/.nojekyll static/.gitkeep some_dir **/*.lock
```

### Installation

```bash
# uv
uv tool install check-empty # bare executable on PATH
uv pip install check-empty # if you want to import check_empty for programmatic usage

pip install check-empty # pip
```

Show the help with:

```bash
check-empty --help # or check-empty -?
```

## Usage

All the snippets below are equivalent, assuming globstar is on.

Run the CLI:

```bash
check-empty -Q src/mylib/py.typed docs/.nojekyll static/.gitkeep some_dir **/*.lock
```

In Python:

```py
from check_empty import check
import glob

a = ['src/mylib/py.typed', 'docs/.nojekyll', 'static/.gitkeep', 'some_dir']
a.extend(glob.iglob('**/*.lock', recursive=True))
# build a list of paths to files or directories by manual globbing
check(a, verbosity=1)
# default verbosity is 2; in the command line, each -Q decreases it by 1 and
# each -V increases it by 1
```

As a pre-commit hook:

```yaml
# .pre-commit-config.yaml
repos:
- repo: https://github.com/jonathandung/check-empty
  rev: v2.0.0 # repository version
  hooks:
    - id: check-empty # the hook
      args: # example list of arguments
        - -Q # flag to decrease output, applicable twice (shorthand for --quiet)
      files: ^src/mylib/py\.typed|docs/\.nojekyll|static/\.gitkeep|some_dir/.*|.*\.lock$
      # paths to files/directories to clear or keep empty as a single regular
      # expression (as per the somewhat restrictive pre-commit config schema),
      # relative to project root
```

equivalent in `prek.toml` format:

```toml
[[repos]]
repo = "https://github.com/jonathandung/check-empty"
rev = "v2.0.0"

[[repos.hooks]]
id = "check-empty"
args = ["-Q"]

[[repos.hooks.files]]
glob = [ # globset reference: https://docs.rs/globset/latest/globset/#syntax
  # this form is only supported by prek; see
  # https://prek.j178.dev/reference/configuration/?h=globs#files
  "src/mylib/py.typed",
  "docs/.nojekyll",
  "static/.gitkeep",
  "some_dir/**", # since directories cannot be passed directly, glob the files within
  "**/*.lock"
]
```

or (TOML 1.1+):

```toml
# using multiline inline tables
[[repos]]
repo = "https://github.com/jonathandung/check-empty"
rev = "v2.0.0"
hooks = [{
  id = "check-empty",
  args = ["-Q"],
  files = {
    glob = [
      "src/mylib/py.typed",
      "docs/.nojekyll",
      "static/.gitkeep",
      "some_dir/**",
      "**/*.lock"
    ]
  },
}]
```

As a GitHub Actions workflow step:

```yaml
steps:
- uses: jonathandung/check-empty@v2.0.0 # the latest version on the GitHub Actions
  # marketplace; this step will fail and subsequent jobs will not run if any file is
  # not empty
  with:
    python-version: '3.14' # run the script on the latest stable Python version
    filenames: |
      src/mylib/py.typed
      docs/.nojekyll
      static/.gitkeep
      some_dir
    globs: '**/*.lock'
    # can also be an array of globs joined into a newline-delimited multiline string,
    # as in filenames
```

Also see the GitHub Action
[manifest](https://github.com/jonathandung/check-empty/blob/main/action.yaml), which
contains the accepted action inputs, action outputs produced and their respective
descriptions.

## Notes

1. If your file name starts with a hyphen, use a command of the form
`check-empty -- -this_is_actually_a_file.txt` to avoid having the filename
misinterpreted as a flag.
2. Forward slashes can be used even on Windows, so there is no need to escape anything.
3. Glob patterns are supported on \*nix only. If on Windows, use a shell like Git Bash.
4. To pass an
[argfile](https://docs.python.org/3/library/argparse.html#fromfile-prefix-chars), use
the `@` prefix, and escape files whose names actually start with `@` using the
double-hyphen syntax.
5. It may be unintuitive that a directory or archive being "empty" means all its files
are empty, but this project explicitly targets files, since version control systems
track files rather than directories.
6. The program can recurse into some archives if specified, but it requires certain
libraries to be installed to do so for certain formats. .7z (corresponding to the `7z`
extra) needs `py7zr`, .rar (the `rar` extra) needs `rarfile`, .lha / .lzh (the `lzh`
extra) needs `lhafile`, .a / .ar / .lib (the `ar` extra) needs `arpy`, .ace (the `ace`
extra) needs `acefile`. These may also slow down the checking significantly for large
directories, since magic numbers must be read for every file and the I/O overhead
accumulates. All the above extras are included in the `all` extra.
7. Keep weird characters in your filenames to a minimum. They may become a problem in
GitHub Actions usage.

## Additional links

- [API and CLI Reference](https://check-empty.readthedocs.io)
- [Releases](https://github.com/jonathandung/check-empty/releases)
- [My page](https://jonathandung.github.io)

## Development

If you wish to contribute to this project, you are more than welcome. Please remember
to read the
[AI use policy](https://github.com/jonathandung/.github/blob/main/AI_USAGE_POLICY.md)
and the
[contributing guide](https://github.com/jonathandung/.github/blob/main/CONTRIBUTING.md).

To build the docs locally (needs Python 3.12+ because of Sphinx), install with the
`docs` [group](https://packaging.python.org/en/latest/specifications/dependency-groups)
using a package manager that supports it (e.g. pip 25.1+ or uv 0.4.27+), preferably
into a virtual environment.

Tests are run with:

```bash
python -m test_check_empty
```

at the project root. `pytest` is not needed.
