mirror of
https://github.com/eza-community/eza
synced 2024-09-16 06:31:27 +00:00
5cc7bdfc3f
This was horrible. Signed-off-by: Christina Sørensen <christina@cafkafk.com>
252 lines
11 KiB
Markdown
252 lines
11 KiB
Markdown
<div align="center">
|
||
|
||
# eza
|
||
|
||
eza is a modern, maintained replacement for ls, built on [exa](https://github.com/ogham/exa).
|
||
|
||
**README Sections:** [Options](#options) — [Installation](#installation) — [Development](#development)
|
||
|
||
[![Built with Nix](https://img.shields.io/badge/Built_With-Nix-5277C3.svg?logo=nixos&labelColor=73C3D5)](https://nixos.org)
|
||
[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg)](code_of_conduct.md)
|
||
|
||
[![Unit tests](https://github.com/cafkafk/eza/actions/workflows/unit-tests.yml/badge.svg)](https://github.com/cafkafk/eza/actions/workflows/unit-tests.yml)
|
||
![Crates.io](https://img.shields.io/crates/v/eza?link=https%3A%2F%2Fcrates.io%2Fcrates%2Feza)
|
||
![Crates.io](https://img.shields.io/crates/l/eza?link=https%3A%2F%2Fgithub.com%2Fcafkafk%2Feza%2Fblob%2Fmain%2FLICENCE)
|
||
|
||
</div>
|
||
|
||
![Screenshots of eza](screenshots.png)
|
||
|
||
---
|
||
|
||
**eza** is a modern, maintained replacement for the venerable file-listing command-line program `ls` that ships with Unix and Linux operating systems, giving it more features and better defaults.
|
||
It uses colours to distinguish file types and metadata.
|
||
It knows about symlinks, extended attributes, and Git.
|
||
And it’s **small**, **fast**, and just **one single binary**.
|
||
|
||
By deliberately making some decisions differently, eza attempts to be a more featureful, more user-friendly version of `ls`.
|
||
|
||
|
||
---
|
||
|
||
**eza** features not in exa (non-exhaustive):
|
||
|
||
- Fixes [“The Grid Bug”](https://github.com/cafkafk/eza/issues/66#issuecomment-1656758327) introduced in exa 2021.
|
||
- Hyperlink support.
|
||
- Selinux context output.
|
||
- Git repo status output.
|
||
- Human readable relative dates.
|
||
- Several security fixes (see [dependabot](https://github.com/cafkafk/eza/security/dependabot?q=is%3Aclosed))
|
||
- Many smaller bug fixes/changes!
|
||
|
||
---
|
||
|
||
<a id="try-it">
|
||
<h1>Try it!</h1>
|
||
</a>
|
||
|
||
### Nix ❄️
|
||
|
||
If you already have Nix setup with flake support, you can try out eza with the `nix run` command:
|
||
|
||
nix run github:cafkafk/eza
|
||
|
||
Nix will build eza and run it.
|
||
|
||
If you want to pass arguments this way, use e.g. `nix run github:cafkafk/eza -- -ol`.
|
||
|
||
<a id="installation">
|
||
<h1>Installation</h1>
|
||
</a>
|
||
|
||
eza is available for macOS and Linux.
|
||
|
||
### Cargo (crates.io)
|
||
|
||
![Crates.io](https://img.shields.io/crates/v/eza?link=https%3A%2F%2Fcrates.io%2Fcrates%2Feza)
|
||
|
||
If you already have a Rust environment set up, you can use the `cargo install` command:
|
||
|
||
cargo install eza
|
||
|
||
Cargo will build the `eza` binary and place it in `$HOME/.local/share/cargo/bin/eza`.
|
||
|
||
### Cargo (git)
|
||
|
||
If you already have a Rust environment set up, you can use the `cargo install` command in your local clone of the repo:
|
||
|
||
git clone https://github.com/cafkafk/eza.git
|
||
cd eza
|
||
cargo install --path .
|
||
|
||
Cargo will build the `eza` binary and place it in `$HOME/.cargo`.
|
||
|
||
---
|
||
Click sections to expand.
|
||
|
||
<a id="options">
|
||
<details>
|
||
<summary> Command-line options </summary>
|
||
|
||
<h1>Command-line options</h1>
|
||
</a>
|
||
|
||
eza’s options are almost, but not quite, entirely unlike `ls`’s.
|
||
|
||
### Display options
|
||
|
||
- **-1**, **--oneline**: display one entry per line
|
||
- **-G**, **--grid**: display entries as a grid (default)
|
||
- **-l**, **--long**: display extended details and attributes
|
||
- **-R**, **--recurse**: recurse into directories
|
||
- **-T**, **--tree**: recurse into directories as a tree
|
||
- **-x**, **--across**: sort the grid across, rather than downwards
|
||
- **-F**, **--classify**: display type indicator by file names
|
||
- **--colo[u]r**: when to use terminal colours
|
||
- **--colo[u]r-scale**: highlight levels of file sizes distinctly
|
||
- **--icons**: display icons
|
||
- **--no-icons**: don't display icons (always overrides --icons)
|
||
- **--hyperlink**: display entries as hyperlinks
|
||
|
||
### Filtering options
|
||
|
||
- **-a**, **--all**: show hidden and 'dot' files
|
||
- **-d**, **--list-dirs**: list directories like regular files
|
||
- **-L**, **--level=(depth)**: limit the depth of recursion
|
||
- **-r**, **--reverse**: reverse the sort order
|
||
- **-s**, **--sort=(field)**: which field to sort by
|
||
- **--group-directories-first**: list directories before other files
|
||
- **-D**, **--only-dirs**: list only directories
|
||
- **--git-ignore**: ignore files mentioned in `.gitignore`
|
||
- **-I**, **--ignore-glob=(globs)**: glob patterns (pipe-separated) of files to ignore
|
||
|
||
Pass the `--all` option twice to also show the `.` and `..` directories.
|
||
|
||
### Long view options
|
||
|
||
These options are available when running with `--long` (`-l`):
|
||
|
||
- **-b**, **--binary**: list file sizes with binary prefixes
|
||
- **-B**, **--bytes**: list file sizes in bytes, without any prefixes
|
||
- **-g**, **--group**: list each file’s group
|
||
- **-h**, **--header**: add a header row to each column
|
||
- **-H**, **--links**: list each file’s number of hard links
|
||
- **-i**, **--inode**: list each file’s inode number
|
||
- **-m**, **--modified**: use the modified timestamp field
|
||
- **-S**, **--blocks**: list each file’s number of file system blocks
|
||
- **-t**, **--time=(field)**: which timestamp field to use
|
||
- **-u**, **--accessed**: use the accessed timestamp field
|
||
- **-U**, **--created**: use the created timestamp field
|
||
- **-X**, **--dereference**: dereference symlinks for file information
|
||
- **-Z**, **--context**: list each file’s security context
|
||
- **-@**, **--extended**: list each file’s extended attributes and sizes
|
||
- **--changed**: use the changed timestamp field
|
||
- **--git**: list each file’s Git status, if tracked or ignored
|
||
- **--time-style**: how to format timestamps
|
||
- **--no-permissions**: suppress the permissions field
|
||
- **-o**, **--octal-permissions**: list each file's permission in octal format
|
||
- **--no-filesize**: suppress the filesize field
|
||
- **--no-user**: suppress the user field
|
||
- **--no-time**: suppress the time field
|
||
|
||
Some of the options accept parameters:
|
||
|
||
- Valid **--color** options are **always**, **automatic**, and **never**.
|
||
- Valid sort fields are **accessed**, **changed**, **created**, **extension**, **Extension**, **inode**, **modified**, **name**, **Name**, **size**, **type**, and **none**. Fields starting with a capital letter sort uppercase before lowercase. The modified field has the aliases **date**, **time**, and **newest**, while its reverse has the aliases **age** and **oldest**.
|
||
- Valid time fields are **modified**, **changed**, **accessed**, and **created**.
|
||
- Valid time styles are **default**, **iso**, **long-iso**, **full-iso**, and **relative**.
|
||
|
||
</details>
|
||
|
||
<a id="development">
|
||
<details>
|
||
<summary> Development </summary>
|
||
<h1>Development
|
||
|
||
<a href="https://blog.rust-lang.org/2022/08/11/Rust-1.63.0.html">
|
||
<img src="https://img.shields.io/badge/rustc-1.63.0+-lightgray.svg" alt="Rust 1.63.0+" />
|
||
</a>
|
||
|
||
<a href="https://github.com/cafkafk/eza/blob/master/LICENCE">
|
||
<img src="https://img.shields.io/badge/licence-MIT-green" alt="MIT Licence" />
|
||
</a>
|
||
</h1></a>
|
||
|
||
eza is written in [Rust](https://www.rust-lang.org/).
|
||
You will need rustc version 1.56.1 or higher.
|
||
The recommended way to install Rust for development is from the [official download page](https://www.rust-lang.org/tools/install), using rustup.
|
||
|
||
Once Rust is installed, you can compile eza with Cargo:
|
||
|
||
cargo build
|
||
cargo test
|
||
|
||
- The [just](https://github.com/casey/just) command runner can be used to run some helpful development commands, in a manner similar to `make`.
|
||
Run `just --list` to get an overview of what’s available.
|
||
|
||
- If you are compiling a copy for yourself, be sure to run `cargo build --release` or `just build-release` to benefit from release-mode optimisations.
|
||
Copy the resulting binary, which will be in the `target/release` directory, into a folder in your `$PATH`.
|
||
`/usr/local/bin` is usually a good choice.
|
||
|
||
- To compile and install the manual pages, you will need [pandoc](https://pandoc.org/).
|
||
The `just man` command will compile the Markdown into manual pages, which it will place in the `target/man` directory.
|
||
To use them, copy them into a directory that `man` will read.
|
||
`/usr/local/share/man` is usually a good choice.
|
||
|
||
- eza depends on [libgit2](https://github.com/rust-lang/git2-rs) for certain features.
|
||
If you’re unable to compile libgit2, you can opt out of Git support by running `cargo build --no-default-features`.
|
||
|
||
- If you intend to compile for musl, you will need to use the flag `vendored-openssl` if you want to get the Git feature working.
|
||
The full command is `cargo build --release --target=x86_64-unknown-linux-musl --features vendored-openssl,git`.
|
||
|
||
### Developing on Nix (experimental) ❄️
|
||
|
||
If you have a working Nix installation with flake support, you can use nix to manage your dev environment.
|
||
|
||
nix develop
|
||
|
||
The Nix Flake has a few features:
|
||
- Run `nix flake check` to run `treefmt` on the repo.
|
||
- Run `nix build` and manually test `./results/bin/eza -- <arguments>` for easy debugging.
|
||
- Run `nix build .#test` to run `cargo test` via the flake.
|
||
- Run `nix build .#clippy` to lint with clippy (still work in progress).
|
||
|
||
|
||
### Testing with Vagrant
|
||
|
||
eza uses [Vagrant][] to configure virtual machines for testing.
|
||
|
||
Programs such as eza that are basically interfaces to the system are [notoriously difficult to test][testing].
|
||
Although the internal components have unit tests, it’s impossible to do a complete end-to-end test without mandating the current user’s name, the time zone, the locale, and directory structure to test.
|
||
(And yes, these tests are worth doing. I have missed an edge case on many an occasion.)
|
||
|
||
The initial attempt to solve the problem was just to create a directory of “awkward” test cases, run eza on it, and make sure it produced the correct output.
|
||
But even this output would change if, say, the user’s locale formats dates in a different way.
|
||
These can be mocked inside the code, but at the cost of making that code more complicated to read and understand.
|
||
|
||
An alternative solution is to fake *everything*: create a virtual machine with a known state and run the tests on *that*.
|
||
This is what Vagrant does.
|
||
Although it takes a while to download and set up, it gives everyone the same development environment to test for any obvious regressions.
|
||
|
||
[Vagrant]: https://www.vagrantup.com/
|
||
[testing]: https://eev.ee/blog/2016/08/22/testing-for-people-who-hate-testing/#troublesome-cases
|
||
|
||
First, initialise the VM:
|
||
|
||
host$ vagrant up
|
||
|
||
The first command downloads the virtual machine image, and then runs our provisioning script, which installs Rust and eza’s build-time dependencies, configures the environment, and generates some awkward files and folders to use as test cases.
|
||
Once this is done, you can SSH in, and build and test:
|
||
|
||
host$ vagrant ssh
|
||
vm$ cd /vagrant
|
||
vm$ cargo build
|
||
vm$ ./xtests/run
|
||
All the tests passed!
|
||
|
||
Of course, the drawback of having a standard development environment is that you stop noticing bugs that occur outside of it.
|
||
For this reason, Vagrant isn’t a *necessary* development step — it’s there if you’d like to use it, but eza still gets used and tested on other platforms.
|
||
It can still be built and compiled on any target triple that it supports, VM or no VM, with `cargo build` and `cargo test`.
|
||
|
||
</details>
|