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
2 changes: 1 addition & 1 deletion .github/wiki
Submodule wiki updated from 3751f1 to 34c374
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Fixed

- Show DevTools version metadata in CLI application output so `list` and `--version` expose the installed package version from `Application` metadata (#339).

## [1.25.3] - 2026-05-11

### Fixed
Expand Down
5 changes: 4 additions & 1 deletion src/Console/DevTools.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
use FastForward\DevTools\SelfUpdate\SelfUpdateRunnerInterface;
use FastForward\DevTools\SelfUpdate\SelfUpdateScopeResolverInterface;
use FastForward\DevTools\SelfUpdate\VersionCheckNotifierInterface;
use FastForward\DevTools\SelfUpdate\VersionCheckerInterface;
use FastForward\DevTools\SelfUpdate\WorkingDirectorySwitcherInterface;
use Override;
use Symfony\Component\Console\Application;
Expand Down Expand Up @@ -73,6 +74,7 @@ final class DevTools extends Application
* @param VersionCheckNotifierInterface $versionCheckNotifier emits non-blocking version freshness warnings
* @param SelfUpdateRunnerInterface $selfUpdateRunner runs explicit or automatic self-update flows
* @param SelfUpdateScopeResolverInterface $selfUpdateScopeResolver resolves whether the active binary is global
* @param VersionCheckerInterface $versionChecker resolves the installed DevTools version for metadata output
* @param EnvironmentInterface $environment reads environment flags for optional auto-update behavior
* @param RuntimeEnvironmentInterface $runtimeEnvironment resolves runtime environment capabilities
*/
Expand All @@ -82,10 +84,11 @@ public function __construct(
private readonly VersionCheckNotifierInterface $versionCheckNotifier,
private readonly SelfUpdateRunnerInterface $selfUpdateRunner,
private readonly SelfUpdateScopeResolverInterface $selfUpdateScopeResolver,
private readonly VersionCheckerInterface $versionChecker,
private readonly EnvironmentInterface $environment,
private readonly RuntimeEnvironmentInterface $runtimeEnvironment,
) {
parent::__construct('Fast Forward Dev Tools');
parent::__construct('Fast Forward Dev Tools', $this->versionChecker->getCurrentVersion());

$this->setDefaultCommand('dev-tools:standards');
$this->setCommandLoader($commandLoader);
Expand Down
31 changes: 28 additions & 3 deletions src/SelfUpdate/ComposerVersionChecker.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
use FastForward\DevTools\Path\DevToolsPathResolver;
use FastForward\DevTools\Process\ProcessBuilderInterface;
use JsonException;
use Throwable;

use function Safe\preg_match;
use function Safe\json_decode;
Expand All @@ -34,6 +35,8 @@
{
private const string PACKAGE = 'fast-forward/dev-tools';

private const string VERSION_UNKNOWN = '0.0.0';

private const int TIMEOUT_SECONDS = 5;

/**
Expand All @@ -52,10 +55,9 @@ public function check(): ?VersionCheckResult
return null;
}

$currentVersion = InstalledVersions::getPrettyVersion(self::PACKAGE)
?? InstalledVersions::getVersion(self::PACKAGE);
$currentVersion = $this->getCurrentVersion();

if (null === $currentVersion) {
if (self::VERSION_UNKNOWN === $currentVersion) {
return null;
}

Expand All @@ -68,6 +70,29 @@ public function check(): ?VersionCheckResult
return new VersionCheckResult($currentVersion, $latestVersion);
}

/**
* Returns the installed DevTools version without running external Composer commands.
*
* This method MUST return the package version when composer metadata is
* available.
* It MUST return `VERSION_UNKNOWN` when metadata is unavailable or on
* resolution errors.
*/
Comment thread
coderabbitai[bot] marked this conversation as resolved.
public function getCurrentVersion(): string
{
if (! InstalledVersions::isInstalled(self::PACKAGE)) {
return self::VERSION_UNKNOWN;
}

try {
return InstalledVersions::getPrettyVersion(self::PACKAGE)
?? InstalledVersions::getVersion(self::PACKAGE)
?? self::VERSION_UNKNOWN;
} catch (Throwable) {
return self::VERSION_UNKNOWN;
}
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

/**
* Resolves the latest stable DevTools version available to Composer.
*/
Expand Down
9 changes: 9 additions & 0 deletions src/SelfUpdate/VersionCheckerInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,13 @@ interface VersionCheckerInterface
* Returns version information when it can be resolved without blocking command execution.
*/
public function check(): ?VersionCheckResult;

/**
* Returns the resolved DevTools version for display and internal comparison.
*
* The method MUST return a safe version string even when installed metadata
* is unavailable.
* It MAY be a fallback value.
*/
public function getCurrentVersion(): string;
}
11 changes: 11 additions & 0 deletions tests/Console/DevToolsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
use FastForward\DevTools\SelfUpdate\ComposerVersionChecker;
use FastForward\DevTools\SelfUpdate\SelfUpdateRunnerInterface;
use FastForward\DevTools\SelfUpdate\SelfUpdateScopeResolverInterface;
use FastForward\DevTools\SelfUpdate\VersionCheckerInterface;
use FastForward\DevTools\SelfUpdate\VersionCheckNotifier;
use FastForward\DevTools\SelfUpdate\VersionCheckNotifierInterface;
use FastForward\DevTools\SelfUpdate\WorkingDirectorySwitcher;
Expand Down Expand Up @@ -124,6 +125,11 @@ final class DevToolsTest extends TestCase
*/
private ObjectProphecy $selfUpdateScopeResolver;

/**
* @var ObjectProphecy<VersionCheckerInterface>
*/
private ObjectProphecy $versionChecker;

/**
* @var ObjectProphecy<EnvironmentInterface>
*/
Expand Down Expand Up @@ -154,8 +160,11 @@ protected function setUp(): void
$this->versionCheckNotifier = $this->prophesize(VersionCheckNotifierInterface::class);
$this->selfUpdateRunner = $this->prophesize(SelfUpdateRunnerInterface::class);
$this->selfUpdateScopeResolver = $this->prophesize(SelfUpdateScopeResolverInterface::class);
$this->versionChecker = $this->prophesize(VersionCheckerInterface::class);
$this->environment = $this->prophesize(EnvironmentInterface::class);
$this->runtimeEnvironment = $this->prophesize(RuntimeEnvironmentInterface::class);
$this->versionChecker->getCurrentVersion()
->willReturn('1.2.3');
$this->runtimeEnvironment->isAgentPresent()
->willReturn(false);
$this->originalWorkspaceDirectoryEnv = getenv(ManagedWorkspace::ENV_WORKSPACE_DIR);
Expand Down Expand Up @@ -214,6 +223,7 @@ public function __construct()
->willReturn($customCommand);

self::assertSame('Fast Forward Dev Tools', $this->devTools->getName());
self::assertSame('1.2.3', $this->devTools->getVersion());
self::assertTrue($this->devTools->has('custom'));
self::assertSame($customCommand, $this->devTools->get('custom'));
}
Expand Down Expand Up @@ -593,6 +603,7 @@ private function createDevTools(): DevTools
$this->versionCheckNotifier->reveal(),
$this->selfUpdateRunner->reveal(),
$this->selfUpdateScopeResolver->reveal(),
$this->versionChecker->reveal(),
$this->environment->reveal(),
$this->runtimeEnvironment->reveal(),
);
Expand Down
Loading