From 0329d5226a23f9f2027bafbc26ecbb6e07b2b800 Mon Sep 17 00:00:00 2001 From: Oussama Makhlouk Date: Wed, 10 Jun 2026 02:29:30 +0100 Subject: [PATCH] issue #85: Split and expand project documentation --- CONTRIBUTING.md | 69 +++++++++++ README.md | 271 ++++++++++++++++---------------------------- docs/development.md | 95 ++++++++++++++++ docs/gitignore.md | 82 ++++++++++++++ docs/icons.md | 52 +++++++++ docs/json-output.md | 131 +++++++++++++++++++++ docs/usage.md | 171 ++++++++++++++++++++++++++++ 7 files changed, 697 insertions(+), 174 deletions(-) create mode 100644 CONTRIBUTING.md create mode 100644 docs/development.md create mode 100644 docs/gitignore.md create mode 100644 docs/icons.md create mode 100644 docs/json-output.md create mode 100644 docs/usage.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..781d2ff --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,69 @@ +# Contributing + +Thanks for your interest in contributing to `treels`. + +## Getting started + +```bash +git clone https://github.com/OussamaM1/treels.git +cd treels +go test ./... +``` + +## Development workflow + +Before opening a pull request, run: + +```bash +go test ./... +go vet ./... +golangci-lint run +``` + +If you do not have `golangci-lint` installed, CI will still run it on the pull request. + +## Contribution guidelines + +- Keep changes focused and easy to review. +- Add or update tests for behavior changes. +- Update documentation for user-facing changes. +- Prefer existing project patterns before adding new abstractions. +- Avoid introducing new dependencies unless they are clearly justified. + +## Adding or changing CLI behavior + +For a new flag or output behavior, update: + +- `cmd/flag.go` +- `module/types.go` +- relevant implementation under `service/` +- tests under `cmd/` and/or `service/` +- `README.md` +- relevant files under `docs/` + +## Documentation style + +- Prefer examples using `--no-icons` unless documenting icon behavior. +- Keep README concise and link to detailed docs. +- Document flag interactions when behavior may be surprising. +- Be explicit about limitations, especially for `.gitignore` and JSON output. + +## Reporting bugs + +When reporting a bug, include: + +- operating system +- `treels --version` +- command used +- expected output +- actual output +- small reproduction directory structure, if possible + +## Feature requests + +Good feature requests explain: + +- the problem or workflow +- proposed CLI usage +- expected output +- any interaction with existing flags diff --git a/README.md b/README.md index 1a8e2dc..7d66b2a 100644 --- a/README.md +++ b/README.md @@ -4,101 +4,33 @@ [![codecov](https://codecov.io/gh/OussamaM1/treels/branch/main/graph/badge.svg)](https://codecov.io/gh/OussamaM1/treels) `treels` is a Go CLI that blends the quick scan of `ls` with the structure of `tree`. -Use it to inspect a directory as a compact grid, expand it as a tree, hide project noise with -`.gitignore`, and keep large repositories readable with depth limits. +Use it to inspect directories as a compact grid, expand them as a tree, hide project noise with +`.gitignore`, show detailed metadata, and keep large repositories readable with depth limits.

- treels picture + treels preview

+## Quick start + ```bash -treels # compact ls-style view -treels -t # tree view -treels -t --depth 2 # tree view, limited to two levels -treels -t --gitignore # tree view, excluding .gitignore matches -treels -t --dirs-only # show directory structure only -treels --json # machine-readable output -treels --long # detailed listing with mode, size, and date -treels --no-summary # hide the final count line +treels # compact ls-style view +treels --tree # recursive tree view +treels --tree --depth 2 # tree view limited to two levels +treels --tree --gitignore # exclude root .gitignore matches +treels --tree --dirs-only # show directory structure only +treels --long --readable # detailed listing with readable sizes +treels --json # machine-readable output +treels --no-icons # fallback for terminals without Nerd Fonts ``` > [!NOTE] > File and folder icons look best with a Nerd Font installed. If your terminal does not support > Nerd Font glyphs, use `--no-icons`. -## Preview - -Compact directory listing: - -```text -$ treels --no-icons file-icons-example -. -Dockerfile Main.kt Program.cs -app.conf app.lock app.log -app.rb app.swift backup.zip -c-file.c class-java-file.class component.vue -config.xml cpp-file.cpp document.pdf -index.html index.php java-file.java -javascript-file.js json-file.json logo.png -main.tf package.json plb-file.plb -pls-file.pls python-file.py react-component.jsx -react-typescript.tsx rust-file.rs script.sh -song.mp3 sql-file.sql styles.css -typescript-file.ts video.mp4 yaml-file.yml - -0 directories, 36 files -``` - -Tree view with a depth limit: - -```text -$ treels -t --depth 1 --gitignore --no-icons -. -├── LICENSE -├── README.md -├── cmd -├── example -├── file-icons-example -├── go.mod -├── go.sum -├── main.go -├── module -├── service -└── utils - -6 directories, 5 files -``` - -Focused tree view for one directory: - -```text -$ treels -t --depth 2 --no-icons service -. -├── gitignore.go -├── service.go -├── service_test.go -└── util.go - -0 directories, 4 files -``` - -## Features - -- Compact grid output for fast directory scans. -- Recursive tree output with familiar branch characters. -- Optional Nerd Font icons and file-type colors. -- `--gitignore` support to skip generated files, dependencies, logs, and build output. -- `--depth N` to keep tree output readable in large repositories. -- `--dirs-only` to inspect folder structure without file-level noise. -- `--json` for scripts and automation. -- `--long` detailed listing with permissions, size, and modification date. -- `--readable` file sizes. -- `--all` support for hidden files. -- `--no-icons` fallback for terminals without icon fonts. - ## Installation -Install with Go: +### With Go ```bash go install github.com/oussamaM1/treels@latest @@ -116,131 +48,122 @@ The binary is usually placed in: $(go env GOPATH)/bin ``` -## Usage +### From source ```bash -treels [flags] [path] -``` - -If no path is provided, `treels` lists the current directory. - -## Examples - -List the current directory: - -```bash -treels +git clone https://github.com/OussamaM1/treels.git +cd treels +go build . +./treels --version ``` -Include hidden files: +## Features -```bash -treels --all -``` +| Feature | Flag | +| --- | --- | +| Compact grid listing | default | +| Recursive tree view | `-t`, `--tree` | +| Depth limit | `--depth N` | +| Detailed metadata | `-l`, `--long` | +| Human-readable sizes | `-r`, `--readable` | +| JSON output | `--json` | +| Hidden files | `-a`, `--all` | +| Directory-only view | `--dirs-only` | +| Respect root `.gitignore` | `--gitignore` | +| Disable icons | `--no-icons` | +| Hide text summary | `--no-summary` | +| Version output | `-v`, `--version` | -Show a tree: +## Usage ```bash -treels --tree +treels [flags] [path] ``` -Limit tree depth: - -```bash -treels --tree --depth 2 -``` +If no path is provided, `treels` lists the current directory. -Respect `.gitignore` rules: +For detailed usage examples and flag interactions, see [docs/usage.md](docs/usage.md). -```bash -treels --tree --gitignore -``` +## Preview -Show directories only: +Examples below use `--no-icons` so output is readable in any terminal. -```bash -treels --tree --dirs-only -``` +### Compact directory listing -Output JSON: +```text +$ treels --no-icons file-icons-example +. +Dockerfile Main.kt Program.cs +app.conf app.lock app.log +app.rb app.swift backup.zip +c-file.c class-java-file.class component.vue +config.xml cpp-file.cpp document.pdf +index.html index.php java-file.java +javascript-file.js json-file.json logo.png +main.tf package.json plb-file.plb +pls-file.pls python-file.py react-component.jsx +react-typescript.tsx rust-file.rs script.sh +song.mp3 sql-file.sql styles.css +typescript-file.ts video.mp4 yaml-file.yml -```bash -treels --json -treels --tree --json --depth 2 +0 directories, 36 files ``` -Show detailed metadata: +### Tree view with a depth limit -```bash -treels --long -treels --tree --long -``` - -Show readable sizes: +```text +$ treels --tree --depth 1 --gitignore --no-icons +. +├── LICENSE +├── README.md +├── cmd +├── docs +├── example +├── file-icons-example +├── go.mod +├── go.sum +├── main.go +├── module +├── service +└── utils -```bash -treels --readable +7 directories, 5 files ``` -Disable icons: +### Detailed listing -```bash -treels --no-icons -``` - -Hide the final summary: +```text +$ treels --long --readable --no-icons service +. +-rw-r--r-- 3.8 KB 2026-06-10 gitignore.go +-rw-r--r-- 4.0 KB 2026-06-10 json.go +-rw-r--r-- 7.1 KB 2026-06-10 service.go +-rw-r--r-- 35.0 KB 2026-06-10 service_test.go +-rw-r--r-- 18.0 KB 2026-06-10 util.go -```bash -treels --no-summary +0 directories, 5 files ``` -## Flags - -| Flag | Description | -| --- | --- | -| `-a`, `--all` | List hidden files and directories. | -| `-t`, `--tree` | Show recursive tree view. | -| `--dirs-only` | Show only directories. | -| `--depth N` | Limit tree recursion depth. | -| `--gitignore` | Respect `.gitignore` rules from the target directory. | -| `--json` | Output machine-readable JSON. | -| `-l`, `--long` | Show detailed file metadata. | -| `--no-icons` | Disable file and folder icons. | -| `--no-summary` | Hide the final file and directory count. | -| `-r`, `--readable` | Show human-readable file and directory sizes. | -| `-v`, `--version` | Print the current version. | -| `-h`, `--help` | Show help. | +## Documentation -## Fonts - -Icons require a Nerd Font-compatible terminal. Recommended setup: - -1. Install a Nerd Font, such as FiraCode Nerd Font. -2. Select that font in your terminal profile. -3. Run `treels` normally. - -If icons render as empty boxes or odd symbols, use: - -```bash -treels --no-icons -``` +- [Usage guide](docs/usage.md) +- [JSON output](docs/json-output.md) +- [Gitignore support](docs/gitignore.md) +- [Icons and fonts](docs/icons.md) +- [Development guide](docs/development.md) +- [Contributing](CONTRIBUTING.md) ## Development -Run tests: - ```bash go test ./... -``` - -Run lint: - -```bash +go vet ./... golangci-lint run +go build . ``` -Build locally: +See [docs/development.md](docs/development.md) for more details. -```bash -go build . -``` +## License + +This project is licensed under the terms in [LICENSE](LICENSE). diff --git a/docs/development.md b/docs/development.md new file mode 100644 index 0000000..044ddab --- /dev/null +++ b/docs/development.md @@ -0,0 +1,95 @@ +# Development guide + +This guide covers local development commands for `treels`. + +## Requirements + +- Go `1.25.0` or compatible +- Optional: `golangci-lint` for local linting + +## Setup + +```bash +git clone https://github.com/OussamaM1/treels.git +cd treels +go mod download +``` + +## Run locally + +```bash +go run . +go run . --tree --depth 2 --no-icons +go run . --long --readable +``` + +## Build + +```bash +go build . +./treels --version +``` + +## Test + +```bash +go test ./... +``` + +With coverage: + +```bash +go test ./... -coverprofile=coverage.out +go tool cover -func=coverage.out +``` + +## Vet and lint + +```bash +go vet ./... +golangci-lint run +``` + +The repository includes `.golangci.yml` with these enabled linters: + +- `errcheck` +- `revive` +- `govet` +- `staticcheck` + +## CI + +GitHub Actions run: + +- `go mod tidy` +- `go mod verify` +- `go vet ./...` +- `go build -v ./...` +- `go test -v ./... -coverprofile=coverage.out` +- `golangci-lint` + +Workflow files live in `.github/workflows/`. + +## Project structure + +```text +cmd/ CLI command and flag definitions +module/ shared flag/options types, icons, colors, extension constants +service/ traversal, rendering, JSON output, gitignore matching +utils/ validation helpers +docs/ documentation +``` + +## Adding a new flag + +When adding a user-facing flag, update: + +1. `module/types.go` +2. `cmd/flag.go` +3. relevant service code +4. tests in `cmd/` and/or `service/` +5. `README.md` and relevant `docs/*.md` + +## Testing documentation examples + +Documentation examples should prefer `--no-icons` for stable text rendering unless the example is specifically about icons. diff --git a/docs/gitignore.md b/docs/gitignore.md new file mode 100644 index 0000000..c0491a0 --- /dev/null +++ b/docs/gitignore.md @@ -0,0 +1,82 @@ +# Gitignore support + +Use `--gitignore` to hide entries matched by `.gitignore` rules from the target directory. + +```bash +treels --tree --gitignore +treels --json --gitignore +treels --tree --gitignore --dirs-only +``` + +## Current behavior + +`treels` reads `.gitignore` from the directory being listed. + +```bash +treels --gitignore path/to/project +``` + +In this example, rules are read from: + +```text +path/to/project/.gitignore +``` + +If that file does not exist, `--gitignore` behaves like normal listing. + +## Supported rule features + +The matcher supports common `.gitignore` pattern features: + +| Feature | Example | +| --- | --- | +| Comments | `# generated files` | +| Escaped comments | `\#literal-file` | +| Negation | `!keep.log` | +| Anchored rules | `/dist` | +| Directory-only rules | `build/` | +| File globs | `*.log` | +| Slash-separated globs | `logs/*.txt` | +| `**` wildcard | `logs/**/*.tmp` | + +## Examples + +Given this `.gitignore`: + +```gitignore +*.log +dist/ +!important.log +``` + +This command: + +```bash +treels --gitignore --no-icons +``` + +Will: + +- hide files ending in `.log` +- hide the `dist` directory +- keep `important.log` + +## Interaction with other flags + +| Combination | Behavior | +| --- | --- | +| `--gitignore --tree` | Ignored directories are not recursively traversed. | +| `--gitignore --dirs-only` | Ignored directories are omitted; files are already omitted by `--dirs-only`. | +| `--gitignore --all` | Hidden files may be shown, but ignored hidden files are still omitted. | +| `--gitignore --json` | JSON entries and summary counts reflect filtered output. | + +## Limitations + +`treels` does not currently aim for full Git parity. Important limitations: + +- Nested `.gitignore` files are not loaded. +- Global Git excludes are not loaded. +- `.git/info/exclude` is not loaded. +- Rules are interpreted relative to the target directory only. + +These limitations are good candidates for future improvement. diff --git a/docs/icons.md b/docs/icons.md new file mode 100644 index 0000000..3e87339 --- /dev/null +++ b/docs/icons.md @@ -0,0 +1,52 @@ +# Icons and fonts + +`treels` uses Nerd Font icons by default to make file types easier to scan. + +## Requirements + +Icons require a terminal font that includes Nerd Font glyphs. + +Recommended fonts: + +- FiraCode Nerd Font +- JetBrainsMono Nerd Font +- Hack Nerd Font +- MesloLGS Nerd Font + +After installing a Nerd Font, select it in your terminal profile. + +## Disable icons + +If icons render as empty boxes, question marks, or strange symbols, disable them: + +```bash +treels --no-icons +``` + +This is also useful for: + +- CI logs +- plain text snapshots +- terminals without glyph support +- documentation examples + +## Colors + +`treels` applies ANSI colors to icons and directory names in text output. + +JSON output never includes icons or ANSI color codes. + +## File type support + +Icons are selected using filename and extension mappings. Examples include: + +| Type | Examples | +| --- | --- | +| Go | `.go`, `.mod`, `.sum` | +| Web | `.html`, `.css`, `.js`, `.ts`, `.jsx`, `.tsx`, `.vue` | +| Data | `.json`, `.yml`, `.yaml`, `.xml`, `.sql` | +| Media | `.png`, `.jpg`, `.mp4`, `.mp3` | +| Archives | `.zip`, `.tar`, `.gz`, `.rar`, `.7z` | +| Project files | `README.md`, `LICENSE`, `Dockerfile`, `package.json`, `Cargo.toml` | + +Unknown files use the default file icon. Unknown directories use the default folder icon. diff --git a/docs/json-output.md b/docs/json-output.md new file mode 100644 index 0000000..41b319f --- /dev/null +++ b/docs/json-output.md @@ -0,0 +1,131 @@ +# JSON output + +Use `--json` when `treels` output needs to be consumed by scripts or other tools. + +```bash +treels --json [path] +treels --tree --json --depth 2 [path] +``` + +JSON output is pretty-printed and always includes a `summary` object. + +## Flat JSON example + +```bash +treels --json service +``` + +```json +{ + "root": "service", + "tree": false, + "entries": [ + { + "name": "gitignore.go", + "path": "service/gitignore.go", + "type": "file", + "size": 3946 + }, + { + "name": "json.go", + "path": "service/json.go", + "type": "file", + "size": 3822 + } + ], + "summary": { + "directories": 0, + "files": 2 + } +} +``` + +## Tree JSON example + +```bash +treels --tree --json --depth 2 cmd +``` + +```json +{ + "root": "cmd", + "tree": true, + "entries": [ + { + "name": "flag.go", + "path": "cmd/flag.go", + "type": "file", + "size": 1174 + }, + { + "name": "root.go", + "path": "cmd/root.go", + "type": "file", + "size": 1404 + } + ], + "summary": { + "directories": 0, + "files": 2 + } +} +``` + +Directories in tree mode may include `children`: + +```json +{ + "name": "cmd", + "path": "./cmd", + "type": "directory", + "size": 128, + "children": [ + { + "name": "root.go", + "path": "cmd/root.go", + "type": "file", + "size": 1404 + } + ] +} +``` + +## Schema + +| Field | Type | Description | +| --- | --- | --- | +| `root` | string | Directory that was listed. | +| `tree` | boolean | Whether recursive tree mode was enabled. | +| `entries` | array | Visible entries after filtering. | +| `entries[].name` | string | Entry name. | +| `entries[].path` | string | Entry path joined with the listed parent path. | +| `entries[].type` | string | Either `file` or `directory`. | +| `entries[].size` | number | Size in bytes from the filesystem. | +| `entries[].children` | array | Child entries for directories in tree JSON mode. Omitted when empty. | +| `summary.directories` | number | Count of visible directories after filtering and depth limits. | +| `summary.files` | number | Count of visible files after filtering and depth limits. | + +## Flag behavior + +Most filtering flags affect JSON output: + +| Flag | Effect on JSON | +| --- | --- | +| `--tree` | Enables recursive JSON and directory `children`. | +| `--depth N` | Limits recursive JSON depth when combined with `--tree`. | +| `--all` | Includes hidden entries. | +| `--dirs-only` | Omits file entries. | +| `--gitignore` | Omits entries matched by the target directory's `.gitignore`. | + +Text formatting flags do not affect JSON output: + +| Flag | JSON effect | +| --- | --- | +| `--long` | No effect. | +| `--readable` | No effect; sizes remain raw bytes. | +| `--no-icons` | No effect. | +| `--no-summary` | No effect; JSON always includes `summary`. | + +## Stability notes + +The JSON format is intended for automation. Avoid relying on text output when writing scripts; use `--json` instead. diff --git a/docs/usage.md b/docs/usage.md new file mode 100644 index 0000000..6d1cc6a --- /dev/null +++ b/docs/usage.md @@ -0,0 +1,171 @@ +# Usage guide + +`treels` lists one directory at a time. If no path is provided, it lists the current working directory. + +```bash +treels [flags] [path] +``` + +Examples in this guide use `--no-icons` when showing text output so the examples render correctly without a Nerd Font. + +## Output modes + +### Compact mode + +Compact mode is the default. It lists the direct children of the target directory in a terminal-width-aware grid. + +```bash +treels --no-icons +``` + +```text +. +LICENSE README.md cmd docs go.mod +main.go module service utils + +6 directories, 4 files +``` + +### Tree mode + +Use `--tree` / `-t` for recursive tree output. + +```bash +treels --tree --no-icons +``` + +```text +. +├── LICENSE +├── README.md +├── cmd +│ ├── flag.go +│ ├── root.go +│ └── root_test.go +└── main.go + +1 directories, 4 files +``` + +### Long mode + +Use `--long` / `-l` to show file metadata. + +```bash +treels --long --no-icons +``` + +```text +. +-rw-r--r-- 1.1 KB 2026-06-10 README.md +drwxr-xr-x 4.0 KB 2026-06-10 cmd +-rw-r--r-- 123 B 2026-06-10 main.go + +1 directories, 2 files +``` + +Long mode columns are: + +| Column | Description | +| --- | --- | +| mode | File mode / permissions, such as `-rw-r--r--` or `drwxr-xr-x`. | +| size | Size in bytes by default, or human-readable with `--readable`. | +| date | Modification date in `YYYY-MM-DD` format. | +| name | Entry name, including icons unless `--no-icons` is used. | + +Long mode also works with tree output: + +```bash +treels --tree --long --readable --no-icons +``` + +### JSON mode + +Use `--json` for machine-readable output. + +```bash +treels --json +``` + +See [json-output.md](json-output.md) for the JSON schema and examples. + +## Common workflows + +### Quickly scan the current directory + +```bash +treels +``` + +### Include hidden files + +```bash +treels --all +``` + +### Inspect a project tree without generated files + +```bash +treels --tree --depth 2 --gitignore +``` + +### Show only folder structure + +```bash +treels --tree --dirs-only +``` + +### Show detailed metadata with readable sizes + +```bash +treels --long --readable +``` + +### Disable icons for plain terminals or logs + +```bash +treels --no-icons +``` + +### Use from scripts + +```bash +treels --json +``` + +## Flags + +| Flag | Description | +| --- | --- | +| `-a`, `--all` | List hidden files and directories. | +| `-t`, `--tree` | Show recursive tree view. | +| `--dirs-only` | Show only directories. | +| `--depth N` | Limit tree recursion depth. | +| `--gitignore` | Respect `.gitignore` rules from the target directory. | +| `--json` | Output machine-readable JSON. | +| `-l`, `--long` | Show detailed file metadata. | +| `--no-icons` | Disable file and folder icons. | +| `--no-summary` | Hide the final text summary. | +| `-r`, `--readable` | Show human-readable file and directory sizes. | +| `-v`, `--version` | Print the current version. | +| `-h`, `--help` | Show help. | + +## Flag interactions + +| Combination | Behavior | +| --- | --- | +| `--tree --depth N` | Recurses up to `N` levels. `--depth 0` shows only the root line and summary. | +| `--tree --dirs-only` | Recursively shows directories while omitting files. | +| `--long --readable` | Shows human-readable sizes in the long metadata column. | +| `--tree --long` | Shows tree branches plus metadata for each entry. | +| `--json --tree` | Emits recursive JSON with `children` arrays for directories. | +| `--json --long` | JSON output is unchanged; `--long` only affects text output. | +| `--gitignore --all` | Hidden files are included only if they are not ignored by `.gitignore`. | +| `--json --no-summary` | No effect; JSON always includes the `summary` object. | + +## Exit codes + +| Code | Meaning | +| --- | --- | +| `0` | Command completed successfully. | +| `1` | Invalid arguments, invalid directory, or runtime error. |