diff --git a/psalm.xml b/psalm.xml
index 510148d..feccc34 100644
--- a/psalm.xml
+++ b/psalm.xml
@@ -14,4 +14,7 @@
+
+
+
diff --git a/src/Command.php b/src/Command.php
index bca2db6..c85ba22 100644
--- a/src/Command.php
+++ b/src/Command.php
@@ -11,10 +11,12 @@ interface Command
/**
* @return Attempt
*/
+ #[\NoDiscard]
public function __invoke(Console $console): Attempt;
/**
* @psalm-mutation-free
*/
+ #[\NoDiscard]
public function usage(): Usage;
}
diff --git a/src/Command/Arguments.php b/src/Command/Arguments.php
index c02d17d..c075bdd 100644
--- a/src/Command/Arguments.php
+++ b/src/Command/Arguments.php
@@ -30,6 +30,7 @@ public function __construct(?Map $arguments = null, ?Sequence $pack = null)
$this->pack = $pack ?? Sequence::strings();
}
+ #[\NoDiscard]
public function get(string $argument): string
{
return $this->maybe($argument)->match(
@@ -41,6 +42,7 @@ public function get(string $argument): string
/**
* @return Maybe
*/
+ #[\NoDiscard]
public function maybe(string $argument): Maybe
{
return $this->arguments->get($argument);
@@ -49,11 +51,13 @@ public function maybe(string $argument): Maybe
/**
* @return Sequence
*/
+ #[\NoDiscard]
public function pack(): Sequence
{
return $this->pack;
}
+ #[\NoDiscard]
public function contains(string $argument): bool
{
return $this->arguments->contains($argument);
diff --git a/src/Command/Name.php b/src/Command/Name.php
index a505392..73d8270 100644
--- a/src/Command/Name.php
+++ b/src/Command/Name.php
@@ -21,11 +21,13 @@ public function __construct(
/**
* @return non-empty-string
*/
+ #[\NoDiscard]
public function name(): string
{
return $this->name;
}
+ #[\NoDiscard]
public function shortDescription(): ?string
{
return $this->shortDescription;
diff --git a/src/Command/Options.php b/src/Command/Options.php
index 4808296..d27aa3d 100644
--- a/src/Command/Options.php
+++ b/src/Command/Options.php
@@ -25,6 +25,7 @@ public function __construct(?Map $options = null)
$this->options = $options ?? Map::of();
}
+ #[\NoDiscard]
public function get(string $option): string
{
return $this->maybe($option)->match(
@@ -36,11 +37,13 @@ public function get(string $option): string
/**
* @return Maybe
*/
+ #[\NoDiscard]
public function maybe(string $option): Maybe
{
return $this->options->get($option);
}
+ #[\NoDiscard]
public function contains(string $option): bool
{
return $this->options->contains($option);
diff --git a/src/Command/Usage.php b/src/Command/Usage.php
index 84b7483..e890d39 100644
--- a/src/Command/Usage.php
+++ b/src/Command/Usage.php
@@ -47,6 +47,7 @@ private function __construct(
*
* @param non-empty-string $name
*/
+ #[\NoDiscard]
public static function of(string $name): self
{
/** @var ?string */
@@ -67,6 +68,7 @@ public static function of(string $name): self
*
* @param class-string $class
*/
+ #[\NoDiscard]
public static function for(string $class): self
{
$refl = new \ReflectionClass($class);
@@ -94,6 +96,7 @@ public static function for(string $class): self
/**
* @psalm-pure
*/
+ #[\NoDiscard]
public static function parse(string $usage): self
{
$declaration = Str::of($usage)->trim();
@@ -144,6 +147,7 @@ public static function parse(string $usage): self
/**
* @param non-empty-string $name
*/
+ #[\NoDiscard]
public function argument(string $name): self
{
$_ = $this
@@ -168,6 +172,7 @@ public function argument(string $name): self
/**
* @param non-empty-string $name
*/
+ #[\NoDiscard]
public function optionalArgument(string $name): self
{
return new self(
@@ -180,6 +185,7 @@ public function optionalArgument(string $name): self
);
}
+ #[\NoDiscard]
public function packArguments(): self
{
return new self(
@@ -196,6 +202,7 @@ public function packArguments(): self
* @param non-empty-string $name
* @param ?non-empty-string $short
*/
+ #[\NoDiscard]
public function option(string $name, ?string $short = null): self
{
return new self(
@@ -212,6 +219,7 @@ public function option(string $name, ?string $short = null): self
* @param non-empty-string $name
* @param ?non-empty-string $short
*/
+ #[\NoDiscard]
public function flag(string $name, ?string $short = null): self
{
return new self(
@@ -224,6 +232,7 @@ public function flag(string $name, ?string $short = null): self
);
}
+ #[\NoDiscard]
public function withShortDescription(string $description): self
{
if (Str::of($description)->contains("\n")) {
@@ -240,6 +249,7 @@ public function withShortDescription(string $description): self
);
}
+ #[\NoDiscard]
public function withDescription(string $description): self
{
/** @var ?string */
@@ -262,6 +272,7 @@ public function withDescription(string $description): self
*
* @param callable(): self $load
*/
+ #[\NoDiscard]
public function load(callable $load): self
{
$usage = Identity::defer($load);
@@ -287,6 +298,7 @@ public function load(callable $load): self
/**
* @return non-empty-string
*/
+ #[\NoDiscard]
public function name(): string
{
return $this->name;
@@ -334,11 +346,13 @@ public function matches(string $command): bool
);
}
+ #[\NoDiscard]
public function shortDescription(): string
{
return $this->shortDescription ?? '';
}
+ #[\NoDiscard]
public function pattern(): Pattern
{
return new Pattern(
@@ -351,6 +365,7 @@ public function pattern(): Pattern
/**
* @return non-empty-string
*/
+ #[\NoDiscard]
public function toString(): string
{
$string = $this->name;
diff --git a/src/Commands.php b/src/Commands.php
index 5c7534d..66e3d1e 100644
--- a/src/Commands.php
+++ b/src/Commands.php
@@ -27,6 +27,7 @@ private function __construct(
/**
* @return Attempt
*/
+ #[\NoDiscard]
public function __invoke(Environment $env): Attempt
{
if ($this->commands instanceof Command) {
@@ -36,6 +37,7 @@ public function __invoke(Environment $env): Attempt
return self::find($env, $this->commands);
}
+ #[\NoDiscard]
public static function of(Command $command, Command ...$commands): self
{
return new self(match ($commands) {
@@ -50,6 +52,7 @@ public static function of(Command $command, Command ...$commands): self
*
* @param Sequence $commands
*/
+ #[\NoDiscard]
public static function for(Sequence $commands): self
{
return new self($commands);
diff --git a/src/Console.php b/src/Console.php
index 2ca6b0c..3c9b73b 100644
--- a/src/Console.php
+++ b/src/Console.php
@@ -41,11 +41,13 @@ public static function of(
);
}
+ #[\NoDiscard]
public function arguments(): Arguments
{
return $this->arguments;
}
+ #[\NoDiscard]
public function options(): Options
{
return $this->options;
@@ -56,6 +58,7 @@ public function options(): Options
*
* @return array{Attempt, self}
*/
+ #[\NoDiscard]
public function read(?int $length = null): array
{
[$data, $env] = $this->env->read($length);
@@ -70,6 +73,7 @@ public function read(?int $length = null): array
/**
* @return Attempt
*/
+ #[\NoDiscard]
public function output(Str $data): Attempt
{
return $this->env->output($data)->map(
@@ -84,6 +88,7 @@ public function output(Str $data): Attempt
/**
* @return Attempt
*/
+ #[\NoDiscard]
public function error(Str $data): Attempt
{
return $this->env->error($data)->map(
@@ -95,6 +100,7 @@ public function error(Str $data): Attempt
);
}
+ #[\NoDiscard]
public function interactive(): bool
{
return $this->env->interactive();
@@ -103,11 +109,13 @@ public function interactive(): bool
/**
* @return Map
*/
+ #[\NoDiscard]
public function variables(): Map
{
return $this->env->variables();
}
+ #[\NoDiscard]
public function workingDirectory(): Path
{
return $this->env->workingDirectory();
@@ -116,6 +124,7 @@ public function workingDirectory(): Path
/**
* @param int<0, 254> $exit
*/
+ #[\NoDiscard]
public function exit(int $exit): self
{
return new self(
@@ -128,6 +137,7 @@ public function exit(int $exit): self
/**
* @internal
*/
+ #[\NoDiscard]
public function environment(): Environment
{
return $this->env;
diff --git a/src/Environment.php b/src/Environment.php
index 2089f29..0cccb1b 100644
--- a/src/Environment.php
+++ b/src/Environment.php
@@ -63,6 +63,7 @@ public static function inMemory(
/**
* True if the environment running the script is an interactive terminal
*/
+ #[\NoDiscard]
public function interactive(): bool
{
return $this->implementation->interactive();
@@ -73,6 +74,7 @@ public function interactive(): bool
*
* @return array{Attempt, self}
*/
+ #[\NoDiscard]
public function read(?int $length = null): array
{
[$read, $implementation] = $this->implementation->read($length);
@@ -83,6 +85,7 @@ public function read(?int $length = null): array
/**
* @return Attempt
*/
+ #[\NoDiscard]
public function output(Str $data): Attempt
{
return $this
@@ -94,6 +97,7 @@ public function output(Str $data): Attempt
/**
* @return Attempt
*/
+ #[\NoDiscard]
public function error(Str $data): Attempt
{
return $this
@@ -105,6 +109,7 @@ public function error(Str $data): Attempt
/**
* @return Sequence
*/
+ #[\NoDiscard]
public function arguments(): Sequence
{
return $this->implementation->arguments();
@@ -113,6 +118,7 @@ public function arguments(): Sequence
/**
* @return Map
*/
+ #[\NoDiscard]
public function variables(): Map
{
return $this->implementation->variables();
@@ -121,6 +127,7 @@ public function variables(): Map
/**
* @param int<0, 254> $code
*/
+ #[\NoDiscard]
public function exit(int $code): self
{
return new self($this->implementation->exit($code));
@@ -129,11 +136,13 @@ public function exit(int $code): self
/**
* @return Maybe
*/
+ #[\NoDiscard]
public function exitCode(): Maybe
{
return $this->implementation->exitCode();
}
+ #[\NoDiscard]
public function workingDirectory(): Path
{
return $this->implementation->workingDirectory();
@@ -144,6 +153,7 @@ public function workingDirectory(): Path
*
* @return Sequence
*/
+ #[\NoDiscard]
public function outputted(): Sequence
{
return $this->implementation->outputted();
diff --git a/src/Environment/ExitCode.php b/src/Environment/ExitCode.php
index 9c78858..e25f112 100644
--- a/src/Environment/ExitCode.php
+++ b/src/Environment/ExitCode.php
@@ -21,11 +21,13 @@ public function __construct(private int $code)
/**
* @return int<0, 254>
*/
+ #[\NoDiscard]
public function toInt(): int
{
return $this->code;
}
+ #[\NoDiscard]
public function successful(): bool
{
return $this->code === 0;
diff --git a/src/Question/ChoiceQuestion.php b/src/Question/ChoiceQuestion.php
index 73f6966..9a0fe4d 100644
--- a/src/Question/ChoiceQuestion.php
+++ b/src/Question/ChoiceQuestion.php
@@ -34,6 +34,7 @@ private function __construct(
*
* @return Attempt>, T}> Returns nothing when no interactions available
*/
+ #[\NoDiscard]
public function __invoke(Environment|Console $env): Attempt
{
$noInteraction = match ($env::class) {
@@ -73,6 +74,7 @@ public function __invoke(Environment|Console $env): Attempt
*
* @param Map $values
*/
+ #[\NoDiscard]
public static function of(string $question, Map $values): self
{
return new self(Str::of($question), $values);
diff --git a/src/Question/Question.php b/src/Question/Question.php
index 28aaad0..aa38f49 100644
--- a/src/Question/Question.php
+++ b/src/Question/Question.php
@@ -28,6 +28,7 @@ private function __construct(private Str $question)
*
* @return Attempt, T}> Returns nothing when no interactions available
*/
+ #[\NoDiscard]
public function __invoke(Environment|Console $env): Attempt
{
$noInteraction = match ($env::class) {
@@ -52,6 +53,7 @@ public function __invoke(Environment|Console $env): Attempt
/**
* @psalm-pure
*/
+ #[\NoDiscard]
public static function of(string $question): self
{
return new self(Str::of($question)->append(' '));
diff --git a/tests/Command/PatternTest.php b/tests/Command/PatternTest.php
index 4bcfe77..42e977b 100644
--- a/tests/Command/PatternTest.php
+++ b/tests/Command/PatternTest.php
@@ -52,7 +52,7 @@ public function testThrowWhenRequirementArgumentFoundAfterAnOptionalOne()
$this->expectException(\LogicException::class);
$this->expectExceptionMessage('No required argument after an optional one');
- Usage::of('name')
+ $_ = Usage::of('name')
->argument('baz')
->optionalArgument('foo')
->flag('foo')
diff --git a/tests/Command/UsageTest.php b/tests/Command/UsageTest.php
index 1f36da0..8b84c60 100644
--- a/tests/Command/UsageTest.php
+++ b/tests/Command/UsageTest.php
@@ -153,7 +153,7 @@ public function testThrowWhenEmptyDeclaration()
$this->expectException(\LogicException::class);
$this->expectExceptionMessage('Empty usage');
- Usage::parse(' ');
+ $_ = Usage::parse(' ');
}
private function names(): Set