Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,30 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [1.3.2] - 2026-07-30

### Fixed

- Removed the hidden `ICommand`-to-`TBaseCommand` downcast during execution.
Commands that implement `ICommand` directly can now execute without an
invalid type-cast failure.
- Added the optional `ICommandParameterReceiver` capability used by
`TBaseCommand` to receive framework-parsed parameter values without making
it a requirement of the base `ICommand` contract.

### Deprecated

- Marked `TCLIApplication.RegisterFlagValueCompletion()` and
`RegisterPositionalCompletion()` as deprecated. These methods remain
source-compatible no-op stubs for the 1.x line and are planned for removal
in v2.0.0.

### Changed

- Added regression coverage for executing a command that implements
`ICommand` without inheriting from `TBaseCommand`.
- Updated the README badge and Lazarus package metadata to `1.3.2`.

## [1.3.1] - 2026-07-28

### Documentation
Expand Down Expand Up @@ -353,7 +377,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- README with quick start guide
- System requirements and compatibility information

[Unreleased]: https://github.com/ikelaiah/cli-fp/compare/v1.3.1...HEAD
[Unreleased]: https://github.com/ikelaiah/cli-fp/compare/v1.3.2...HEAD
[1.3.2]: https://github.com/ikelaiah/cli-fp/compare/v1.3.1...v1.3.2
[1.3.1]: https://github.com/ikelaiah/cli-fp/compare/v1.3.0...v1.3.1
[1.3.0]: https://github.com/ikelaiah/cli-fp/compare/v1.2.0...v1.3.0
[1.2.0]: https://github.com/ikelaiah/cli-fp/compare/v1.1.6...v1.2.0
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Command-Line Interface Framework for Free Pascal 🚀

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Version](https://img.shields.io/badge/version-1.3.1-blue.svg)](https://github.com/ikelaiah/cli-fp/releases)
[![Version](https://img.shields.io/badge/version-1.3.2-blue.svg)](https://github.com/ikelaiah/cli-fp/releases)
[![Free Pascal](https://img.shields.io/badge/Free%20Pascal-3.2.2-blue.svg)](https://www.freepascal.org/)
[![Lazarus](https://img.shields.io/badge/Lazarus-4.0-orange.svg)](https://www.lazarus-ide.org/)
[![GitHub stars](https://img.shields.io/github/stars/ikelaiah/cli-fp?style=social)](https://github.com/ikelaiah/cli-fp/stargazers)
Expand Down
3 changes: 1 addition & 2 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ lower maintenance cost. New convenience APIs should delegate to one underlying
implementation rather than creating parallel parsing, validation, or execution
paths.

## v1.3.2 — Correct the Current Contracts
## v1.3.2 — Correct the Current Contracts (completed 2026-07-30)

- Remove or clearly deprecate the non-functional completion callback APIs.
- Fix the mismatch between the public `ICommand` contract and the runtime
Expand Down Expand Up @@ -46,4 +46,3 @@ can be made and tested independently.
**Maintenance outcome:** command inputs and ownership are explicit, legacy
compatibility paths are retired, and the core has one coherent execution
model.

92 changes: 92 additions & 0 deletions docs/PULL_REQUEST_v1.3.2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# Pull Request: Release v1.3.2 - Contract Hardening

**Target Release:** v1.3.2

**Release Date:** 2026-07-30

## Summary

This PR delivers the `v1.3.2` roadmap milestone by correcting the mismatch
between the public `ICommand` contract and the runtime implementation, and by
clearly deprecating the non-functional custom-completion callback methods.

It also adds the maintenance roadmap, regression coverage, current
documentation, release notes, and version metadata for the patch release.

## Type of Change

- [x] Bug fix
- [x] Backward-compatible interface addition
- [x] API deprecation
- [x] Regression test
- [x] Documentation
- [ ] Breaking change

## Contract Correction

- [x] Add the optional `ICommandParameterReceiver` capability.
- [x] Make `TBaseCommand` implement the receiver.
- [x] Replace the unconditional `ICommand`-to-`TBaseCommand` downcast with a
`Supports()` capability check.
- [x] Remove the `CLI.Command` implementation dependency from
`CLI.Application`.
- [x] Verify that an independent `ICommand` implementation executes and
returns its exit code.

## Completion Callback Deprecation

- [x] Mark `RegisterFlagValueCompletion()` as deprecated.
- [x] Mark `RegisterPositionalCompletion()` as deprecated.
- [x] Retain both methods as no-ops for 1.x source compatibility.
- [x] State that removal is planned for v2.0.0.
- [x] Confirm that built-in metadata completion is unaffected.

## Documentation and Versioning

- [x] Add `ROADMAP.md` with maintenance outcomes through v2.0.0.
- [x] Update the API reference for `ICommandParameterReceiver`.
- [x] Update the technical completion notes and architecture description.
- [x] Add the dated `1.3.2` changelog entry and comparison links.
- [x] Update the README badge to `1.3.2`.
- [x] Update Lazarus package metadata to `1.3.2`.
- [x] Add v1.3.2 release notes.
- [x] Add this pull request note.

## Compatibility

Existing `TBaseCommand` descendants require no changes. Existing application
factories, command registration calls, generated projects, and schema-version-1
manifests retain their behaviour.

Direct `ICommand` implementations no longer fail merely because they do not
inherit from `TBaseCommand`. The new receiver interface is optional.

The deprecated custom-completion methods remain callable in 1.x but can emit
compiler warnings. Removing calls to them is behaviour-preserving because the
methods were already no-ops.

## Verification

- [x] Framework suite: 39 tests, 0 errors, 0 failures.
- [x] Interface-only command regression test.
- [x] Deprecation compiler-warning smoke test.
- [x] Windows generator unit tests.
- [x] Generator golden-output test.
- [x] Generated-project compile smoke test.
- [x] Generator operations test.
- [x] All seven example applications compiled.
- [x] Lazarus runtime package build with metadata at `1.3.2`.
- [x] Local Markdown targets and fenced code blocks across 39 Markdown files.
- [x] FPC 3.2.2.
- [ ] GitHub Actions after the PR is opened.

## Release Readiness

- [x] Release date finalized as 2026-07-30.
- [x] Version metadata updated to `1.3.2`.
- [x] Changelog section dated and comparison links updated.
- [x] Release notes prepared.
- [x] Pull request notes prepared.
- [ ] Confirm GitHub Actions on Windows and Linux.

After merge, create the `v1.3.2` tag and publish the prepared release notes.
94 changes: 94 additions & 0 deletions docs/RELEASE_NOTES_v1.3.2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# Release Notes - cli-fp v1.3.2

**Release Date:** 2026-07-30

## Overview

Version `1.3.2` is a contract-hardening patch release. It removes a hidden
runtime dependency on `TBaseCommand`, formally deprecates the non-functional
custom-completion callback registration methods, and establishes the
maintenance roadmap for the next releases.

Existing applications based on `TBaseCommand` remain source-compatible.

## `ICommand` Contract Fix

Earlier versions accepted commands through the `ICommand` interface but cast
the selected command to `TBaseCommand` before execution. A valid independent
implementation of `ICommand` could therefore register successfully and then
fail with an invalid type cast at runtime.

Version `1.3.2` removes that downcast. Parameter handoff now uses the optional
`ICommandParameterReceiver` capability:

- `TBaseCommand` implements `ICommandParameterReceiver`, preserving existing
parameter lookup behaviour.
- Commands that implement only `ICommand` can execute without inheriting from
`TBaseCommand`.
- Commands that need framework-managed parameter lookup can derive from
`TBaseCommand` or implement the optional receiver contract.

The regression suite now includes an interface-only command and verifies its
execution and exit code.

## Deprecated Completion Callback APIs

The following concrete `TCLIApplication` methods are now marked deprecated:

- `RegisterFlagValueCompletion()`
- `RegisterPositionalCompletion()`

These methods have always been non-functional stubs. They remain as no-ops in
the 1.x line for source compatibility and are planned for removal in v2.0.0.

Built-in completion is unchanged. Registered commands, subcommands, flags,
Boolean values, and enum values continue to be completed from command
metadata.

## Maintenance Roadmap

The new project roadmap records the intended sequence:

- `v1.3.2`: correct current contracts;
- `v1.4.0`: add a simple callback API and typed argument access;
- `v1.5.0`: split help and completion out of `TCLIApplication`; and
- `v2.0.0`: adopt an explicit execution context and retire legacy shared-state
plumbing.

Convenience APIs are expected to delegate to one underlying implementation so
that improved ergonomics do not create parallel parsing or validation paths.

## Verification

- Framework suite: 39 tests, 0 errors, 0 failures.
- Added regression coverage for an `ICommand` implementation that does not
inherit from `TBaseCommand`.
- Verified that use of a deprecated callback registration method produces the
intended FPC compiler warning.
- Full Windows generator suite passed:
- generator unit tests;
- golden-output test;
- generated-project compile smoke test; and
- generator operations test.
- All seven example applications compiled successfully.
- Lazarus runtime package compiled with version metadata at `1.3.2`.
- Local Markdown targets resolve and fenced code blocks are balanced across 39
Markdown files.
- FPC version: 3.2.2.

## Compatibility

No migration is required for applications using `TBaseCommand`,
`CreateCLIApplication`, existing command registration, schema-version-1
`clifp.json` files, or generated projects.

Applications that call either deprecated custom-completion registration method
may receive a compiler warning. Removing those calls does not change runtime
behaviour because the methods did not register callbacks.

## Versioning

- The README release badge now targets `1.3.2`.
- The Lazarus package metadata now targets `1.3.2`.

**Full Changelog:** [v1.3.1...v1.3.2](https://github.com/ikelaiah/cli-fp/compare/v1.3.1...v1.3.2)
19 changes: 16 additions & 3 deletions docs/api-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ with the [user manual](user-manual.md); it supplies complete program context
that the isolated declarations here intentionally omit.

The excerpts focus on supported application-facing members. Test hooks on
`TCLIApplication` and the currently disabled custom-completion callback
registry are documented in the
`TCLIApplication` and the deprecated, non-functional custom-completion
callback registry are documented in the
[technical completion notes](technical-docs.md#historical-investigation-disabled-custom-callbacks).
The declarations in [`src/`](../src/) remain authoritative.

Expand Down Expand Up @@ -77,6 +77,19 @@ ICommand = interface
end;
```

##### `ICommandParameterReceiver`

Optional capability used by the application to supply parsed parameter values
to commands that want framework-managed lookup. `TBaseCommand` implements this
interface. A command that implements only `ICommand` remains valid and can
execute without inheriting from `TBaseCommand`.

```pascal
ICommandParameterReceiver = interface
procedure SetParsedParams(const Params: TStringList);
end;
```

### Parameter Helper Methods

The `TBaseCommand` class provides helper methods for adding parameters. All helper methods are available on `TBaseCommand` and its descendants:
Expand Down Expand Up @@ -342,7 +355,7 @@ Base command implementation.
##### `TBaseCommand`
Abstract base class for all CLI commands.
```pascal
TBaseCommand = class(TInterfacedObject, ICommand)
TBaseCommand = class(TInterfacedObject, ICommand, ICommandParameterReceiver)
protected
function GetParameterValue(const Flag: string; out Value: string): Boolean;
procedure ShowHelp;
Expand Down
Loading