| Age | Commit message (Collapse) | Author |
|
Options and arguments were stored and passed as PhpMixed even though
Symfony only ever puts a string, a bool, a list of strings or null in
one. get_option already narrowed to InputOptionValue at the boundary;
this widens that enum into InputValue and pushes it through
InputInterface, InputOption/InputArgument defaults, the Input storage,
ArgvInput/ArrayInput/StringInput/CompletionInput, Command::add_option
and add_argument, and the Composer-side wrappers.
Two neighbouring string|int unions get types of their own:
InputDefinition::{get_argument,has_argument} take an ArgumentName, and
ArrayInput keys its parameters by ParameterName. has_parameter_option
and get_parameter_option take the values they look for as &[&str],
which is what PHP's `(array) $values` cast produced anyway.
Two behaviours change along the way. Input::set_option on a negated
option now negates with PHP's loose bool cast rather than treating a
non-bool as false, matching `!$value`. ArrayInput::parse now resolves
an integer key to an argument position instead of looking up an
argument literally named "0".
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
|
Preg had shed everything it owned: after the last few rounds its methods
were one-line forwards to the shim's preg_*(), differing only in a
default argument or a wrapper the caller unwrapped anyway. The 460 call
sites now name the shim function, and shirabe-pcre is gone from the
workspace along with its LICENSE entry.
The forwards expand as they read: isMatch becomes
preg_match2(.., 0).is_some() (is_none() where PHP negates it), isMatch3
and match3 drop the .is_some(), matchAll counts through
preg_match_all2(..).occurrence_count(), and replace4/replace5 spell out
the limit and count arguments preg_replace2 takes. Callbacks are the one
place the shapes differ: preg_replace_callback carries an error out of
the callback, so the fourteen infallible closures wrap their result in
Ok() and expect() it back.
Config::process() is the fifteenth, and it drops the `error` cell it
captured to smuggle a failure past a closure that could only return a
String. The `?` in the closure now carries it, which is what the PHP
does -- a throw from the callback leaves preg_replace_callback at the
failing match rather than running the remaining replacements and
reporting the last error.
The module doc that explained why composer/pcre's exceptions and
*StrictGroups() variants have no counterpart moves to the shim's preg
module, where the functions it describes live.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
|
The command's own definition covers only --dev/--no-dev and the args
array, so any other application-level option reaching it (as when
GlobalCommand re-parses `--no-interaction=1` out of ArrayInput's
stringification) aborted the run with "does not accept a value".
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
|
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
|
Every parent module in the symfony-* crates already re-exported its leaf
modules with `pub use`, so each item was reachable by two paths. Make the
leaf modules private and route all callers through the single re-exported
path.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
|
shirabe-symfony-console crate
Move `Symfony\Component\Console` out of shirabe-external-packages and
into its own crate, so the path is
`shirabe_symfony_console::application::Application` instead of
`shirabe_external_packages::symfony::console::application::Application`.
The `delegate_to_inner!` and `delegate_command_trait_impls_to_inner!`
macros move with it.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
|
Move `Composer\Pcre` out of shirabe-external-packages and into its own
crate, so the path is `shirabe_pcre::preg::Preg` instead of
`shirabe_external_packages::composer::pcre::preg::Preg`.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
|
Ported exceptions were flat structs reached with `downcast_ref`, so
Composer's `catch (\RuntimeException $e)` only matched the exact leaf
type and `get_class($e)` had nothing to report. Each exception now
embeds an instance of the class it extends and travels inside an
`AnyThrowable`; `Catch::catch`/`catch_mut` walk that chain, and
`PhpClass::php_class_name` yields the PHP FQCN.
Dropping the `std::error::Error` impls from the exception types leaves
`AnyThrowable` as the only route into an `anyhow::Error`, so the walk
cannot be bypassed. A `no_exception_downcast` linter catches the
`downcast::<X>()` calls that would now silently answer `None`.
Three sites change behavior as a result: the `TransportException`
exit-code override reaches `MaxFileSizeExceededException`, the
`catch (\LogicException)` in findSimilar() reaches its subclasses, and
rendered exception titles carry the real class name rather than a
guess. `get_class_err()` is no longer a `todo!()`, which re-enables
FilesystemRepositoryTest::testCorruptedRepositoryFile.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
|
Rust has no runtime class name, so `Command::get_class` existed purely to
let each command hand back its PHP class name, supplied through the
two-argument variant of `delegate_command_trait_impls_to_inner!` at the
impl site. Replace it with a general `PhpClass` trait plus an
`impl_php_class!` macro, so the name is stated once next to the type
definition and the mechanism is reusable outside commands.
`Command` gains `PhpClass` as a supertrait and drops `get_class`, and
`VcsDriverKind`'s hand-rolled `php_class_name` table moves onto the trait.
Behavior is unchanged: the same class-name strings are reported, and the
base command state still panics when asked for a name it cannot supply.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
|
Ports the per-command completion metadata that PHP passes as the
suggestedValues constructor argument, resolving all TODO(cli-completion)
markers:
- CompletionTrait providers on 18 argument/option sites (installed/root/
available package names, package types, prefer-install)
- static value lists (--format on show/outdated/search/fund/licenses/
check-platform-reqs, archive's FORMATS, audit --ignore-severity,
update --bump-after-update, repository's action list)
- command-specific closures: ConfigCommand::suggest_setting_keys,
ShowCommand::suggest_package_based_on_mode, RepositoryCommand's
suggest_repo_names/suggest_type_for_add, exec/run-script inline
closures (downcast from the this argument, as the closures are bound
to their concrete command in PHP)
- GlobalCommand::complete, delegating completion to the wrapped
subcommand through CompletionInput::from_string
- a complete() override on every Composer command forwarding to
base_command_complete (BaseCommand inheritance restoration)
Also fixes CompleteCommand to call merge_application_definition(true) as
PHP's default-argument call does; with false the application-level
"command" argument was missing from the bound definition, shifting every
argument-position detection by one.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
|
InputArgument/InputOption
Composer backports symfony/console 6.1's $suggestedValues parameter in
Composer\Console\Input\{InputArgument,InputOption}; the Rust newtypes had
dropped it. PHP closures are bound to the command ($this), but a command
cannot capture a handle to itself while configure() runs inside new(), so
the closure receives the bound command as an explicit `this` argument at
call time instead.
- add SuggestedValues (list | this-taking closure) and wire it through
InputArgument::new5 / InputOption::new6 and their complete() methods
- track Composer-typed definition entries by name in BaseCommandData side
maps, standing in for PHP's instanceof checks (set_definition converts
entries to the Symfony types for storage)
- add base_command_complete, the BaseCommand::complete dispatch shared by
every Composer command
- introduce BaseCommand::base_command_data and make command_data a default
method on top of it
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
|
The _complete and completion commands were registered but always panicked:
get_class_of_command / instantiate_completion_output / tail_debug_log were
todo!() and the completion.bash resource was not shipped.
- make Command::complete return anyhow::Result so completion errors
propagate to CompleteCommand's catch-all (exit code 2) like PHP
- add Command::get_class as the port hook for PHP's get_class() debug log;
every command supplies its PHP FQCN via the delegation macro
- embed Resources/completion.bash at compile time (single-binary port);
get_supported_shells becomes a static list
- implement tail_debug_log by moving the shared output handle into the
'static process callback
- add OutputInterface::as_console_output so unsupported-shell errors go to
stderr as in PHP
- fix CompletionInput::bind to keep the argument name PHP assigns in the
foreach head even when the loop breaks on the first unset argument;
application-level completion always hit this and returned no suggestions
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
|
regex::Regex::clone() does not share the underlying meta engine's
search-cache pool, so every fresh clone pays a ~10us warmup cost on
its first use. Two changes together eliminate this across nearly all
preg_* call sites:
- A php_regex! macro resolves PHP-style patterns to a per-call-site
&'static regex::Regex (via regex-macro's LazyLock), applied at the
majority of call sites throughout the codebase.
- Call sites still passing dynamic pattern strings go through
PATTERN_CACHE, which now stores Arc<(Regex, bool)> and hands out
Arc::clone()s instead of cloning the Regex itself.
PregPattern::resolve() returns a ResolvedPattern enum (Arc or
'static reference) rather than an owned Regex, so neither path ever
clones the Regex proper.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
|
|
|
Add a no_banned_use linter that forbids importing anyhow::Result, and
update all call sites to reference it via its fully-qualified path so
it is never confused with std::result::Result.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
|
|
The compiler confirms none of the call sites invoke a &mut self method
on the returned Composer, so the exclusive RefMut borrow was never
needed and only risked borrow check conflict. Switch every site to the
shared composer_full borrow and drop the now-dead composer_full_mut
helper.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
|
|
The Command trait and Composer's BaseCommand took &mut self, so dispatch
held a borrow_mut on the command's RefCell for the whole call. A command
re-entering itself (e.g. the help command describing itself) then panicked
with "RefCell already borrowed".
All Command/BaseCommand methods now take &self and the command state is
interior-mutable (Cell/RefCell). Shared borrows coexist, so re-entrant
describe paths no longer conflict. Getters that returned references now
return Ref guards; the descriptor describe_* methods take &dyn Command;
mixin accessors return Ref/RefMut.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
|
|
|
|
|
|
The Preg methods panic on PCRE failure (per the file header rationale),
so their anyhow::Result wrappers never carried an Err.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
|
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
|
Wire up ConsoleIO with HelperSet/QuestionHelper, register the
ErrorHandler with the IO instance, and fall back to a default output
in run(). Replace resolved phase-b TODOs across the console, command,
io, factory, installer, dependency_resolver, and util modules; reclassify
the remaining blockers (typed Symfony command registry, stdin resource
caching) as phase-c.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
|
|
Align the Symfony namespace mapping with the documented convention
(symfony::component::X -> symfony::X) and remove now-unused console
stub files. Update all import paths across the workspace.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Convert InputInterface and OutputInterface parameters from &dyn/&mut dyn
references to Rc<RefCell<dyn ...>> shared ownership across the command,
console, and IO layers, matching the Phase C shared-ownership approach
already used for IOInterface.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Model PHP's `Composer extends PartialComposer` as a PartialOrFullComposer
enum and merge partial_composer.rs into composer.rs. Introduce
ComposerHandle / PartialComposerHandle (plus their Weak variants) so the
graph can be shared, and build it at once with Rc::new_cyclic in the
factory to resolve the back-reference cycles.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
|
|
|
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
|
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
|
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
Symfony Command was a struct but used as dyn Trait (Box<dyn Command>)
in console/application.rs. Convert it to a trait with CommandBase as
the concrete stub, and add impl Command for all Composer commands.
|
|
Implement BaseCommand trait and other abstract class traits across
all command, downloader, io, package, and VCS driver types. Also
fix trait method signatures for composer_mut and io_mut to return
mutable references to Option rather than Option of mutable references.
|
|
|
|
|
|
|