Skip to content

Support sorting in the list command and add an 'ls' alias - #42

Merged
dmccoystephenson merged 1 commit into
mainfrom
feat/list-sorting-and-ls-alias
Aug 8, 2026
Merged

Support sorting in the list command and add an 'ls' alias#42
dmccoystephenson merged 1 commit into
mainfrom
feat/list-sorting-and-ls-alias

Conversation

@dmccoystephenson

Copy link
Copy Markdown
Member

Summary

  • A --sort / -s option has been added to the list command. Supported values are name, impact, confidence, ease, reach, effort, ice and rice; matching is case-insensitive.
  • Sorting is delegated to a new ProjectSorter.sortBy(List<Project>, String) method, so the existing sorting component is reused rather than duplicated. name is ordered alphabetically (case-insensitive, A to Z); every other key is ordered highest to lowest, matching the existing score-sorting behavior used by the export command.
  • Existing behavior has been preserved: when --sort is omitted, projects are still listed in creation order and the header remains Projects:. When a sort is applied, the header reports it as Projects (sorted by <key>):.
  • An unsupported sort value is rejected with a message naming every supported value, following the error style already used by ExportProjectsCommand.
  • ls has been registered as an alias for list via the @ShellMethod key array.
  • README.md has been updated with the alias, a List Examples block, and the supported sort values. A hardcoded test count in CONTRIBUTING.md was found to be stale and has been replaced with a non-brittle statement, since this PR changes that count again.

Test plan

  • ./gradlew test passes locally (78 tests).
  • ProjectSorterTest covers the new sortBy method: null list, unsupported key, name ordering, integer-field ordering (impact, effort), RICE ordering, mixed-case keys, original-list immutability, and the isSupportedSortKey / getSupportedSortKeys helpers.
  • ListProjectsCommandTest covers creation-order preservation, name sorting, ice sorting, case-insensitive keys, rejection of an unsupported key, and registration of the ls alias.
  • Existing ProjectSorter and export behavior is untouched; the pre-existing sortByScore / sortByIce / sortByRice tests still pass unchanged.

Deferred issues

The remaining open backlog was not selected for this cycle, for the reasons below:

Closes #29
Closes #34

This PR description was drafted during a Gardener session (https://github.com/Stephenson-Software/gardener).

Adds a --sort option to the list command backed by a new
ProjectSorter.sortBy method that accepts name, impact, confidence,
ease, reach, effort, ice and rice. Omitting --sort keeps the existing
creation-order behavior. Registers 'ls' as an alias for 'list'.

Closes #29
Closes #34

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Aug 8, 2026

Copy link
Copy Markdown

Test Results

78 tests  +17   78 ✅ +17   1s ⏱️ ±0s
14 suites ± 0    0 💤 ± 0 
14 files   ± 0    0 ❌ ± 0 

Results for commit 5eb8d67. ± Comparison against base commit b4ef20c.

@dmccoystephenson

Copy link
Copy Markdown
Member Author

Self-review rubric

Scored adversarially against the diff and command output, not from judgment alone.

  • Manual validation / CI (external anchor): PASS./gradlew test passes locally (78 tests, 0 failures) and both GitHub Actions workflows are green on the PR head (build (21) pass, test pass, Test Results pass).
  • Scope: PASS — six files are touched and each is required by Support sorting in list command #29 or Add 'ls' alias for list command #34: ListProjectsCommand and ProjectSorter (implementation), their two test classes, and README.md. One caveat is disclosed below regarding CONTRIBUTING.md.
  • Tests-new: PASS — every new public method is exercised. ProjectSorter.sortBy is covered by seven new tests, isSupportedSortKey by two, and getSupportedSortKeys by one; the new execute(String) signature is covered by six new ListProjectsCommandTest cases.
  • Tests-fix (empirical mutation, not reasoning): PASS — although this is a feature rather than a bug fix, the regression value of the new tests was confirmed by mutation rather than by argument. With key = {"list", "ls"} reverted to key = {"list"} and boolean sorted forced to false, ./gradlew test --tests ListProjectsCommandTest reported 8 tests completed, 5 failed (shouldExposeLsAsAnAliasForTheListCommand, shouldSortByNameWhenNameSortIsRequested, shouldSortByIceWhenIceSortIsRequested, shouldAcceptSortKeyRegardlessOfCase, shouldRejectUnsupportedSortKey). Both mutations were reverted and the full suite re-run green; git diff --stat confirmed an empty working tree afterwards.
  • Sibling structure: PASS with a caveat — the --sort option, its @ShellOption(value = {"-s", "--sort"}) declaration, and the Invalid sort option. error style all mirror ExportProjectsCommand. The caveat is recorded under Findings below.
  • Sibling renames: PASS — no identifier in a parallel pair or series was renamed; sortByScore / sortByIce / sortByRice are untouched and their existing tests still pass unchanged.
  • Docs: PASSREADME.md's command list now records the ls alias and the sort option, and a List Examples block documents every supported value. CONTRIBUTING.md's ./gradlew test instruction remains accurate.
  • Issue resolution: PASSSupport sorting in list command #29's named surface area (list command sorting, including by name and by score) is implemented with eight sort keys; Add 'ls' alias for list command #34's (ls alias) is implemented via the @ShellMethod key array and asserted by test.
  • Shell command tests: PASS — the changed @ShellComponent has a corresponding ListProjectsCommandTest exercising its @ShellMethod.
  • Round-trip coverage: not applicable — no field was added to Project or any other Lombok domain class, so ProjectJsonReaderWriterImplTest needs no change.
  • I/O behind an interface: not applicable — no new code touches the filesystem or console input.

Findings

Three observations are recorded rather than fixed, since each is a judgment call or would widen scope:

  1. src/main/java/com/preponderous/parpt/export/ProjectSorter.java — a general-purpose sortBy method has been added to a class living in the export/ package, yet its first caller is now the list command rather than an export path. Duplicating the comparator logic into a second class was judged worse than the package mismatch, so reuse was chosen. Relocating the class to a neutral package would touch ProjectMarkdownWriterImpl and the export tests, which is out of scope here.
  2. src/main/java/com/preponderous/parpt/export/ProjectSorter.java — two sorting entry points now coexist: the older boolean-flag sortByScore(List, boolean) used by markdown export, and the new key-based sortBy(List, String). Converging ProjectMarkdownWriterImpl and ExportProjectsCommand onto the key-based API would remove the duplication, but it changes export behavior and belongs in its own PR. A follow-up issue has been filed.
  3. README.md:69 — the short form list -s impact is documented on the strength of the explicit @ShellOption(value = {"-s", "--sort"}) declaration, matching what ExportProjectsCommand already declares. The new tests invoke execute(String) directly, so Spring Shell's option-parsing layer itself is not covered by any test in this repo; the short form is declared but not exercised end to end.

Scope disclosure

CONTRIBUTING.md was edited by one line beyond the two issues. Its Continuous Integration section claimed "currently 58 tests", a figure this PR invalidates (the suite now stands at 78). The hardcoded count was replaced with a non-brittle statement rather than being updated to a number that would drift again on the next PR.

This comment was drafted during a Gardener session (https://github.com/Stephenson-Software/gardener).

@dmccoystephenson
dmccoystephenson merged commit 0743786 into main Aug 8, 2026
3 checks passed
@dmccoystephenson
dmccoystephenson deleted the feat/list-sorting-and-ls-alias branch August 8, 2026 07:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add 'ls' alias for list command Support sorting in list command

1 participant