| Age | Commit message (Collapse) | Author |
|
Script\Event extends BaseEvent in PHP, so setOriginatingEvent accepts
both a base event and a nested Script\Event, and calculateOriginatingEvent
walks the chain via an instanceof check. The port had pinned the field to a
concrete Option<Box<BaseEvent>>, leaving calculate_originating_event as
todo!() and the nested-event test unportable.
Introduce an OriginatingEvent enum (Base/Script) to model the instanceof
tag, implement the recursive flattening, and un-ignore both originating
event tests.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
solve() previously dropped the SolverProblemsException and returned a
placeholder anyhow error, because its Rc<RefCell<Rule>> payload is not
Send+Sync and cannot ride anyhow::Error. Return
anyhow::Result<Result<LockTransaction, SolverProblemsException>> instead,
keeping fatal errors on the outer Result and the recoverable exception on
the inner one.
This lets the three Installer callsites port their PHP catch handlers
faithfully (pretty-string output, GithubActionError emit, getCode-based
exit codes) and lets solver_test.rs assert getProblems/getCode/
getPrettyString. The four ported assertion tests stay ignored: their
pretty-string path still reaches unimplemented todo!()s downstream.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Re-evaluate the reason'd #[ignore] tests under the Phase D criterion:
a test is unportable ONLY if the APIs/types needed to WRITE it do not
exist. A test that compiles but panics at runtime (todo!() body, a
regex the regex crate cannot compile) or fails at runtime (incomplete
or incorrect impl behavior) is portable -- it is written in full and
marked with a reason-less #[ignore].
About 120 test functions move from reason'd #[ignore] to reason-less
#[ignore] (the ported-but-not-yet-passing signal). Impl crates gain
only additive __ test hatches (init_command, pool, file_downloader,
package handle link setters, artifact/path repository, repository
manager, svn); no existing logic changes. Tests whose required APIs
genuinely do not exist (mock/reflection harness, ApplicationTester,
solve() discarding SolverProblemsException, a script::Event that
cannot be passed as an originating event) keep their reason'd
#[ignore].
cargo check -p shirabe --tests passes.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Redesign PhpResource into a real stream handle (File/Memory backing with
tracked position, eof, closed state) and unify the whole fopen family
(fopen/fwrite/fread/fgets/fgetc/feof/fclose/ftell/fseek/rewind/fstat/
ftruncate/fflush and stream_get_contents/stream_copy_to_stream) on
&PhpResource, replacing the split PhpMixed/PhpResource APIs and their
todo!() stubs. fopen now returns Result; read functions stay String for
now (TODO(phase-e) to move to byte strings).
Propagate the signatures through callers: Process stdout/stderr, Cursor
input, curl header/body handles (extracted into typed maps keyed by job
id), Filesystem copy/safe_copy/files_are_equal, BufferIO, error_handler,
platform, perforce, zip. The proc_open pipe paths cannot carry a
PhpResource in a PhpMixed list, so they are left as todo!() with notes.
|
|
JsonFile's schema paths previously relied on php_dir() (__DIR__), which has
no runtime equivalent. Add a build.rs that copies composer-schema.json and
composer-lock-schema.json next to the built executable, and resolve them with
std::env::current_exe(). FilesystemRepository now embeds InstalledVersions.php
directly via include_str! instead of reading it through php_dir().
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Collapse the dual Application API (static methods taking
`&Rc<RefCell<Application>>` plus `&mut self` bridges via `shared()`) into a
single handle type `ApplicationHandle(Rc<RefCell<Application>>)`, mirroring the
Composer handle pattern.
Methods that invoke command callbacks (add, run, do_run, base_run, base_do_run,
do_run_command, add_commands, init) move to `impl ApplicationHandle` with
short-scoped borrows; data-only methods and `impl BaseApplication` stay on
`Application`. `shared()` now returns the handle, and `new_shared`/`init_shared`
fold into `ApplicationHandle::new`/`init`.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Composer never uses Symfony's command loader, so LazyCommand is never
instantiated on any Composer execution path. Remove the stub port and
the instanceof branches that guarded against it.
|
|
These slice/map wrappers mirrored PHP's internal array pointer and
have no clean Rust equivalent. Remove them and replace the lone
caller with direct first-element access; the rest were unused imports.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
PHP's internal array pointer (current/key/end) has no clean Rust
equivalent. Remove these todo!() shim stubs and replace each call
site with direct first/last element access matching Composer's
original behavior. Unblocks Config::merge of anonymous {name: false}
disable entries, re-enabling test_add_packagist_repository.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Drop the get_as_float parameter; the Rust shim always returns f64.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
ArrayObject was only a thin wrapper around IndexMap<String, PhpMixed>
used as an empty-{} vs empty-[] marker and as the assoc=false JSON
object representation; no reference semantics were involved. Inline its
payload directly into PhpMixed::Object and drop the type along with the
now-dead StdClass.
Side effects of the unification:
- ArrayObject::new was todo!(); the config --global / object-typed get
paths that built PhpMixed::Object(ArrayObject::new(None)) no longer
panic.
- base_config_command wrote 'config' as PhpMixed::Array(empty), emitting
[] instead of {}; now matches PHP's new \ArrayObject ({}).
- The dead is::<StdClass>()/is::<ArrayObject>() instanceof checks in
JsonManipulator are replaced with the faithful as_object() mapping.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Replace the dispatch-on-constant filter_var() and filter_var_with_options()
with dedicated filter_var_boolean/url/email/ip and filter_var_int_with_range,
dropping the FILTER_VALIDATE_* constants and updating all call sites.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
apcu_fetch/apcu_add only ran when apcuPrefix was non-null, but
Composer never calls setApcuPrefix on the loaders it instantiates
itself; the prefix is only emitted into the generated target-project
autoload_real.php. So the cache branches were unreachable in Shirabe's
execution paths. Remove the apcu shim and the now-dead lookups.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
json_encode/json_encode_ex now return anyhow::Result<String> instead of
Option, so callers no longer need json_last_error() to get the failure
reason.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
|
|
Faithfully port every method, field and constant of Symfony's
Process.php into process.rs, replacing the reduced stub. Add the
supporting pipes module (PipesInterface/AbstractPipes/UnixPipes/
WindowsPipes), ProcessUtils and the missing process exceptions
(LogicException/InvalidArgumentException) with constructors.
Methods now return anyhow::Result where PHP throws, take the env
argument and a bool-returning callback, and borrow &mut for
status-updating accessors; all callers are updated accordingly.
Extend the php-shim with proc_open/proc_close (PHP-compatible
signatures), proc_get_status, proc_terminate, posix_kill, uniqid,
ftruncate, ftell_stream, fseek3, stream_get_contents3 and env
helpers.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
|
Back parse_url/parse_url_all with reqwest::Url and add the
FILTER_VALIDATE_URL and FILTER_VALIDATE_BOOLEAN arms to filter_var, so
Config::prohibit_url_by_config no longer hits todo!(). reqwest::Url is
not a byte-for-byte port of PHP's parser; the divergences are noted with
TODO(phase-c).
Switch the scheme in_array in prohibit_url_by_config to strict: the
needle is a string-or-null and the haystack holds only non-numeric
string literals, so loose and strict comparison are provably equivalent
here, avoiding a dependency on PHP loose `==` semantics.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
The execute() proxy was left as todo!(); wire it to the shared
Application handle so `outdated` re-enters the run flow as `show -l`,
matching PHP's $this->getApplication()->run(). Add Application::shared()
to expose the new_shared self-reference and un-ignore run_outdated.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Port the command body: resolve Config from tryComposer()'s composer or
Factory::createConfig(), then clear or garbage-collect each cache-* path
via Cache. try_composer is already implemented, so the prior blocker
comment is stale.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Port Symfony's Application::doRenderThrowable so command failures render
the error box instead of hitting todo!(). This unblocks six CLI no-panic
tests (config, depends, global, prohibits, remove, repository), whose
ignore attributes are now removed.
Also fill in the php-shim functions on the render path that were still
todo!(): php_exception_get_code, intval, str_pad, str_split,
mb_detect_encoding, mb_convert_encoding, mb_strwidth, mb_convert_variables.
PHP file/line and the verbose getTrace() block have no faithful Rust
equivalent; file/line use PHP's own 'n/a' fallback and the trace block is
intentionally omitted.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
The List and Array variants of PhpMixed boxed their elements
unnecessarily. Store PhpMixed values directly and update all callers
accordingly.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Composer's Application::getComposer() calls exit(1) when a required
Composer instance fails to build under areExceptionsCaught(). Replace the
deep std::process::exit with a php-shim ExitException that mirrors PHP's
`exit` construct: it bypasses parent::doRun()'s catch and Symfony's
renderThrowable (excluded at both broad catches), so the already-written
plain error message is not re-rendered and the process exits with code 1.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Composer's doCompare() calls `exit;` when the destination doTree fails,
but the source branch handles the identical failure with `return;`. The
asymmetry has been present since the class was first written (2413b55c6,
2018) and is almost certainly a bug. Treat it as `return` so a failed
local-change detection no longer terminates the whole process.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
GlobalCommand::run fell back to self.run when given fewer than two
args, recursing forever and overflowing the stack. PHP calls
parent::run there. Add Command::base_run holding the base run body so
the override can delegate to it, matching PHP's parent::run.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
InstallationManager::get_installer cached a per-type installer via a
Rust-only `clone_box` stub (`todo!()`). PHP caches the SAME instance
held in `$this->installers`. Store the index into `installers` instead,
reproducing that sharing without cloning; both `add_installer` and
`remove_installer` clear the cache, so indices never dangle. With the
only caller gone, `InstallerInterface::clone_box` is removed.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
PluginManager::get_plugins cloned each plugin through a Rust-only
`clone_box` stub (`todo!()`). PHP's getPlugins() returns `$this->plugins`
directly and the objects are shared by reference, so borrow the stored
instances (`&[Box<dyn PluginInterface>]`) instead of cloning. The sole
caller is adjusted and `PluginInterface::clone_box` is removed.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Resolve the 6 todo!() in ConsoleIO/NullIO by delegating the
IOInterfaceImmutable logger methods to BaseIO.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
PHP's PackageDiscoveryTrait is mixed into classes extending BaseCommand
and calls its methods directly. Model that with a supertrait bound so
get_io, try_composer, require_composer, get_platform_requirement_filter
and normalize_requirements come from BaseCommand instead of being
redeclared and delegated per command. Propagate the Result returns at
the call sites and drop the now-redundant per-command impls.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Add the repos and repositorySets fields backing PackageDiscoveryTrait,
mirroring RequireCommand, and return them from get_repos_mut /
get_repository_sets_mut.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Take config and process as shared Rc<RefCell<..>> handles matching the
struct fields and Util\Git's constructor, assigning them directly. PHP
stores the same Config object reference, so sharing the Rc is faithful;
update the three call sites to pass cloned handles.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Make the Rust-only as_package_interface a required trait method and
return self from each concrete implementation, replacing the todo!()
default that PHP needs no equivalent for (implicit subtype coercion).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
|
|
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Ported docblocks embed PHP usage examples as indented (and bare-fenced)
code blocks, which rustdoc compiled as Rust doctests and failed
`cargo test`. Mark them as `php` so they render as code without being
run.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
|
|
|
|
|
|
|
|
|
|
PHP's random_int/random_bytes are cryptographically secure, but Composer
does not rely on that property, so a non-cryptographic PRNG suffices.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
|
Document the conventions for porting PCRE patterns to the regex crate
(no PCRE crate, panic on compile failure, dropping performance-only
possessive quantifiers, ad-hoc compatibility comments). Apply the rule
to Platform::expand_path by rewriting its conditional subpattern as an
explicit alternation, which the regex crate can compile.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
The Phase B port invented an ArchivableFilesFilter trait whose filter
impls called self.filter, recursing forever; the name also collided
with the real ArchivableFilesFilter FilterIterator class. Composer has
no such interface: the finder holds GitExcludeFilter/ComposerExcludeFilter
(both extending BaseExcludeFilter) and calls $filter->filter().
Drop the invented trait, type the filters as Box<dyn BaseExcludeFilter>,
and implement BaseExcludeFilter on the concrete filters (accessors
delegating to inner). Remove the unused generic default methods from the
trait so it is dyn-compatible; they remain as inherent methods on
BaseExcludeFilterBase, which is where every caller already reaches them.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
ConfigCommand/InitCommand::initialize called self.initialize, which
resolved to the inherent method itself instead of the inherited
BaseCommand::initialize (PHP's parent::initialize), recursing forever.
Disambiguate to the trait method.
CreateProjectCommand's create_composer_instance/create_audit_config
were pure pass-through wrappers that PHP does not override; they
recursed into themselves. Remove them so calls resolve to the inherited
BaseCommand trait methods (the create_audit_config wrapper also had a
&Config vs &mut Config signature mismatch).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|