Skip to content

feat: add GNU ls compatibility mode#116

Merged
seapagan merged 6 commits intomainfrom
feat/gnu-compat-bootstrap
Apr 5, 2026
Merged

feat: add GNU ls compatibility mode#116
seapagan merged 6 commits intomainfrom
feat/gnu-compat-bootstrap

Conversation

@seapagan
Copy link
Copy Markdown
Owner

@seapagan seapagan commented Apr 5, 2026

Summary

Add a bootstrap GNU compatibility mode without changing native lsplus behavior.

This introduces startup mode selection from LSP_COMPAT_MODE or compat_mode in config, reserves the conflicting GNU short flags in gnu mode, and keeps the current lsplus-specific behavior in native mode.

What changed

  • add compatibility mode selection with env-over-config precedence
  • build the CLI with the clap builder API so shared options stay in one parser path
  • reserve -D, -I, -N, and -Z for GNU semantics in gnu mode and reject them until implemented
  • expose GNU-mode names where supported, including --group-directories-first and --indicator-style=slash
  • keep GNU mode on standard clap help output, with -p and --indicator-style=slash as separate entry points to the same behavior
  • add and update tests for mode selection, parser behavior, help output, and integration coverage
  • document the new compatibility mode in the README and mdBook docs

Why

This gives lsp a functional GNU-compatible CLI surface for aliasing or scripting, without breaking the existing native command set. It also establishes the parser structure needed to implement the remaining GNU behaviors incrementally.

Summary by CodeRabbit

  • New Features

    • Introduced Compatibility Mode with two CLI surfaces: native (default) and GNU-style; enable via config or LSP_COMPAT_MODE (env wins)
    • GNU-mode maps certain flags (e.g., -p → indicator-style=slash) and reserves conflicting short flags to error until implemented
  • Documentation

    • Added comprehensive docs and examples for Compatibility Mode, config, environment override, and alias guidance
  • Tests

    • Added unit and integration tests covering startup config precedence, invalid-mode errors, and GNU vs native CLI behaviours

seapagan added 3 commits April 5, 2026 16:09
Signed-off-by: Grant Ramsay <seapagan@gmail.com>
Signed-off-by: Grant Ramsay <seapagan@gmail.com>
Signed-off-by: Grant Ramsay <seapagan@gmail.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 5, 2026

Warning

Rate limit exceeded

@seapagan has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 11 minutes and 1 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 11 minutes and 1 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f8720614-27f9-46a1-b9db-9bf82a73e2b7

📥 Commits

Reviewing files that changed from the base of the PR and between 05fd376 and 3c2988e.

📒 Files selected for processing (5)
  • src/app.rs
  • src/cli.rs
  • src/lib.rs
  • src/settings.rs
  • src/structs.rs
📝 Walkthrough

Walkthrough

The PR adds a compatibility mode selecting either native or GNU ls CLI surfaces. Startup loads a StartupConfig (params + compat_mode), the environment LSP_COMPAT_MODE overrides config, and GNU mode currently changes CLI/help output only; conflicting short flags (-D, -I, -N, -Z) are reserved and error in GNU mode.

Changes

Cohort / File(s) Summary
Documentation
README.md, docs/src/config.md, docs/src/usage.md, TODO.md
Added Compatibility Mode docs, environment/config precedence, example TOML, mappings for GNU equivalents, notes about reserved/conflicting short flags, and TODOs for indicator modes.
CLI Parsing Refactor
src/cli.rs
Replaced clap::Parser derive with manual clap::Command/Arg builder. Added CompatMode enum and mode-aware command construction/parsing (parse_from_mode, Flags::parse_from, Flags::try_parse_from, flags_from_matches). GNU mode alters option names/behaviour (adds --indicator-style, maps -p to indicator-style=slash, rejects certain native short flags).
Config and Settings
src/settings.rs, src/structs.rs
Introduced StartupConfig including compat_mode, load_startup_config/load_startup_config_from, ParsedConfig for TOML, and COMPAT_MODE_ENV_VAR. Added #[serde(default)] to Params to allow partial config deserialisation.
Application Entry Points
src/main.rs, src/app.rs
main now loads startup config and calls cli::parse_from_mode; added pub fn run_with_flags_and_config(args, config) and made run_with_flags delegate to it. Startup config load failures now print an error and exit.
Unit Tests
tests/crate/cli.rs, tests/crate/settings.rs
Added tests for mode-dependent CLI parsing and help output; added settings tests for config vs env precedence, valid/invalid compat values, and startup config behaviour.
Integration Tests
tests/integration.rs
Updated native-mode assertions to set LSP_COMPAT_MODE=native explicitly; added GNU-mode integration tests verifying flag rejection/acceptance, help output, and config/env precedence.

Sequence Diagram(s)

sequenceDiagram
    participant Main as main()
    participant Config as settings::load_startup_config()
    participant Env as Environment
    participant File as Config File
    participant CLI as cli::parse_from_mode()
    participant App as app::run_with_flags_and_config()
    
    Main->>Config: load_startup_config()
    Config->>Env: check LSP_COMPAT_MODE
    alt Env var present
        Env-->>Config: compat_mode value
    else Env var absent
        Config->>File: read config.toml
        File-->>Config: compat_mode field
        alt Config compat_mode exists
            Config->>Config: use from config
        else Config compat_mode missing
            Config->>Config: default Native
        end
    end
    Config-->>Main: StartupConfig{params, compat_mode}
    Main->>CLI: parse_from_mode(compat_mode)
    CLI-->>Main: Flags (mode-aware)
    Main->>App: run_with_flags_and_config(flags, params)
    App->>App: merge flags + params
    App-->>Main: Result
Loading

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly Related PRs

Suggested labels

testing

Poem

🐰 Hops! A mode for GNU and native cheer,

Configs whisper, env shouts loud and clear;
Flags now choose their dance by startup call,
Native stays, GNU waits to claim them all. 🌿

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 58.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: add GNU ls compatibility mode' accurately and concisely describes the primary change in the changeset.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/gnu-compat-bootstrap

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@seapagan seapagan changed the title feat: add GNU compatibility mode feat: add GNU ls compatibility mode Apr 5, 2026
@seapagan seapagan changed the title feat: add GNU ls compatibility mode feat: add GNU ls compatibility mode Apr 5, 2026
@seapagan seapagan self-assigned this Apr 5, 2026
@seapagan seapagan added the enhancement New feature or request label Apr 5, 2026
@codacy-production
Copy link
Copy Markdown

codacy-production bot commented Apr 5, 2026

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 81 complexity · 42 duplication

Metric Results
Complexity 81
Duplication 42

View in Codacy

TIP This summary will be updated as you push new changes. Give us feedback

@seapagan seapagan marked this pull request as ready for review April 5, 2026 15:39
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (3)
docs/src/usage.md (1)

114-114: Consider adding a note clarifying the mode context.

Line 114 references -D in native mode context, but with the new compatibility mode documentation above, users might be confused since -D is reserved in GNU mode. Consider adding a brief clarification.

📝 Suggested clarification
-If you add the '-D' option to the command, directories will be sorted first:
+If you add the '-D' option to the command (native mode only; use
+`--group-directories-first` in gnu mode), directories will be sorted first:
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/src/usage.md` at line 114, Add a brief clarification next to the '-D'
example stating that the '-D' option (directories sorted first) applies only in
native mode and is reserved/unavailable in GNU (compatibility) mode; reference
the new compatibility/GNU mode section so readers aren’t confused about
mode-specific option behavior and consider a one-line example or parenthetical
note indicating how to enable native mode if needed.
docs/src/config.md (1)

126-126: Consider using "native" in the example config.

The example configuration sets compat_mode = "gnu", which may surprise users copying the example verbatim. Since native is the default and most users will start there, consider showing "native" or omitting this line (relying on the default) and adding a comment about switching to "gnu" when needed.

📝 Suggested alternative
-compat_mode = "gnu"
+# compat_mode = "native"  # or "gnu" for GNU ls compatibility
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/src/config.md` at line 126, Update the example config to avoid
surprising users by either setting compat_mode to "native" or removing the
compat_mode line and adding a short comment; specifically modify the example
line that currently reads compat_mode = "gnu" so it shows compat_mode = "native"
(or omit it) and include a one-line note that users can switch to "gnu" if they
need GNU compatibility—refer to the compat_mode configuration key in the docs to
locate the example to change.
tests/integration.rs (1)

702-723: Add explicit rejection tests for the -I and -Z reserved flags in GNU compatibility mode.

The test at lines 702-723 verifies all four reserved flags (-D, -I, -N, -Z) are omitted from help output, but explicit rejection tests exist only for -D (line 622) and -N (line 642). For consistency and complete coverage, add tests that verify -I and -Z are rejected when used in GNU mode, similar to the existing tests for -D and -N.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/integration.rs` around lines 702 - 723, Add two tests mirroring the
existing reserved-flag checks for -D and -N: create test_gnu_mode_rejects_I and
test_gnu_mode_rejects_Z that run Command::cargo_bin("lsp") with
env("LSP_COMPAT_MODE","gnu") and pass "-I" and "-Z" respectively, assert the
command exits non-success and stderr contains the expected reserved-flag
rejection message (same pattern used in the existing tests for -D and -N),
placing them alongside the other integration tests in tests/integration.rs.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@docs/src/config.md`:
- Line 126: Update the example config to avoid surprising users by either
setting compat_mode to "native" or removing the compat_mode line and adding a
short comment; specifically modify the example line that currently reads
compat_mode = "gnu" so it shows compat_mode = "native" (or omit it) and include
a one-line note that users can switch to "gnu" if they need GNU
compatibility—refer to the compat_mode configuration key in the docs to locate
the example to change.

In `@docs/src/usage.md`:
- Line 114: Add a brief clarification next to the '-D' example stating that the
'-D' option (directories sorted first) applies only in native mode and is
reserved/unavailable in GNU (compatibility) mode; reference the new
compatibility/GNU mode section so readers aren’t confused about mode-specific
option behavior and consider a one-line example or parenthetical note indicating
how to enable native mode if needed.

In `@tests/integration.rs`:
- Around line 702-723: Add two tests mirroring the existing reserved-flag checks
for -D and -N: create test_gnu_mode_rejects_I and test_gnu_mode_rejects_Z that
run Command::cargo_bin("lsp") with env("LSP_COMPAT_MODE","gnu") and pass "-I"
and "-Z" respectively, assert the command exits non-success and stderr contains
the expected reserved-flag rejection message (same pattern used in the existing
tests for -D and -N), placing them alongside the other integration tests in
tests/integration.rs.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 08aef5c4-4c83-4904-ad01-1f1389e4b26c

📥 Commits

Reviewing files that changed from the base of the PR and between 2d0e768 and 90e3bfb.

📒 Files selected for processing (12)
  • README.md
  • TODO.md
  • docs/src/config.md
  • docs/src/usage.md
  • src/app.rs
  • src/cli.rs
  • src/main.rs
  • src/settings.rs
  • src/structs.rs
  • tests/crate/cli.rs
  • tests/crate/settings.rs
  • tests/integration.rs

seapagan added 2 commits April 5, 2026 16:54
Signed-off-by: Grant Ramsay <seapagan@gmail.com>
Signed-off-by: Grant Ramsay <seapagan@gmail.com>
@seapagan
Copy link
Copy Markdown
Owner Author

seapagan commented Apr 5, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 5, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Repository owner deleted a comment from coderabbitai bot Apr 5, 2026
Signed-off-by: Grant Ramsay <seapagan@gmail.com>
@seapagan seapagan merged commit 376cd74 into main Apr 5, 2026
5 checks passed
@seapagan seapagan deleted the feat/gnu-compat-bootstrap branch April 5, 2026 17:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant