| Age | Commit message (Collapse) | Author |
|
Application::find/reset_composer and the shared ApplicationHandle are
now available, so GlobalCommand can reset the composer instance before
building the sub-command input and proxy execution through the full
Application::run dispatch, matching PHP's behavior. Un-ignores the
tests that only depended on this wiring, and re-points the remaining
ignores at their real (unrelated) blockers.
|
|
Two related "already borrowed" panics reachable from
AutoloadGenerator::dump() (which holds the local-repository,
installation-manager, and config RefCells for the duration of its own
statement, per the temporary-lifetime-extension pattern fixed
separately in create_project_command.rs):
- ensure_bin_dir_is_in_path called config.borrow_mut() to read
"bin-dir", but Config::get only needs &self; use borrow() so it can
coexist with an outer borrow instead of conflicting with it.
- make_autoloader's real body needed composer_handle.borrow_mut() plus
the same local-repository/installation-manager RefCells the caller
already holds mutably, which cannot be made reentrant-safe without a
larger restructuring. Since all 3 call sites already discard its
return value, and its only effect (registering a Composer-generated
ClassLoader for autoloading during event-listener PHP execution) is
unobservable in this port — there's no embedded PHP interpreter to
register it into, and class_exists for user-defined classes is a
hardcoded-false shim so the caller's very next check always treats
the class as unavailable regardless — make it a genuine no-op.
This unblocks the post-autoload-dump event for any script listener
naming a PHP class (e.g. Illuminate\Foundation\ComposerScripts), which
every create-project/install run reaches once real packages get
installed.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
|
|
|
Port AuditCommand::getPackages's non-locked path: build an
InstalledRepository from the local repository and return its packages,
filtered by RootPackage requires when --no-dev is set. The prior
TODO(phase-c) assumption (InstalledRepository::new vs get_local_repository
type mismatch) no longer holds since both sides use RepositoryInterfaceHandle.
Enables the two previously ignored audit command tests.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Auditor::audit took io as &mut dyn IOInterface, forcing the audit and
installer post-audit call sites to hold a borrow_mut() on the shared IO
RefCell for the whole call. During advisory fetching the repositories
write to their own clones of the same handle, so the borrow_mut()
collided with their borrow() and panicked with 'RefCell already mutably
borrowed' on 'audit --locked'. Take the Rc<RefCell<dyn IOInterface>>
handle instead so writes borrow briefly and never overlap. Un-ignore the
locked-audit regression test that this unblocks.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
The platform: section is empty because PlatformRepository::get_packages
routes to ArrayRepository::initialize instead of its own initialize, which
needs the still-todo!() runtime::constant() shim. Record the real blocker.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
flattenRepositories must recurse into InstalledRepository (which extends
CompositeRepository in PHP) and ShowCommand must unwrap FilterRepository
when categorizing repos. Without this, installed/locked/platform packages
all fell through to the "available" bucket, dropping the version column
and per-section grouping. Un-ignores 10 show_command tests.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
execute_batch only awaited prepare(), leaving the install/update/
uninstall + cleanup + repo.write promise chain as a todo!() stub, so
packages were downloaded to cache but never installed into the target
directory. Wire the operation step (mirroring PHP's promise chain),
propagate errors from the install/update/uninstall wrappers instead of
swallowing them with .ok()?, and write the repo after each op.
Un-ignore the create-project functional tests and the install/remove
command tests this unblocks. The remaining --no-install case still fails
on a separate install-path bug; its ignore reason is updated to match.
|
|
|
|
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Replace hand-written mock/stub structs that re-implemented PHPUnit
mock-builder behavior (record-and-verify, manual call counters,
unreachable!() guards) with mockall::mock! locals across:
- package/loader: MockLoader, VersionGuesserMock
- command: ArchiveManager/RepositoryManager/EventDispatcher mocks
- util: ConfigSource/AuthJson mocks (auth_helper, bitbucket, github,
forgejo, gitlab)
- repository/vcs: github_driver NullConfigSource
- installer: CountingInstaller, RecordingBinaryInstaller, and the
DownloadManager mock (formerly common/downloader_stub.rs, now deleted)
- downloader: download_manager create_downloader_mock
Verification (counts/args) now lives in mockall expectations checked on
drop. installation_manager BinaryInstaller is left hand-written because
its as_binary_presence_interface seam returns Some(&mut self), which
mockall cannot express; io_stub and io_mock are left as-is.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Replace the todo!() stub with a faithful port of StatusCommandTest's
data-provided locally-modified-packages cases (source/dist), kept
#[ignore]d since install does not yet populate vendor/ offline.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
|
LibraryInstaller and PluginInstaller upgrade the Composer back-reference
in their constructors, so they could not be built inside Rc::new_cyclic
where the weak handle is not yet upgradeable. Defer create_default_
installers until after the cyclic Rc is established, where the weak
handle resolves, and implement it to register Library -> Plugin ->
Metapackage with a single shared BinaryInstaller.
To share one BinaryInstaller (as Composer does), LibraryInstaller's
binary_installer becomes Rc<RefCell<dyn BinaryInstallerInterface>>
instead of an owned Box; PluginInstaller and the __set_binary_installer
test seam follow.
This clears "Unknown installer type: metapackage". Un-ignores the six
remove tests that now pass; the remaining install/remove tests are
re-labeled for the next blocker (InstallationManager::execute_batch
still leaves the install/cleanup/repo.write promise chain as a todo!()
stub, so package operations do not actually execute).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Replace the empty set_definition stub with the full InputArgument/
InputOption set from Composer's UpdateCommand. The symfony input
modeling was already complete; this was the last command still passing
an empty definition, which made it reject its own options.
Un-ignores test_no_security_blocking_allows_insecure_packages (now
passing) and re-labels the six remaining update tests with their actual
blockers (regex porting, resolver temporary-constraint, interactive
mode, bump-after-update solver pool) since the old "empty
InputDefinition" reason no longer applies.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
- StreamContextFactory: User-Agent reports the HTTP stack as "reqwest"
- RequestProxy::supports_secure_proxy: always true (reqwest+rustls can always
TLS to a proxy); drop the now-dead curl<7.52 guard in get_curl_options
- DiagnoseCommand::get_curl_version: phase-D TODO placeholder
Empirically verified: reqwest sends no default User-Agent (shirabe sets it
explicitly) and accepts https:// proxy URLs. init+install output stays
byte-identical to Composer.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Empty PhpMixed::Array now serializes as [], so the several places that build a
PHP `new \stdClass` via an empty Array were emitting [] where Composer writes
{}. Use PhpMixed::Object for those empty-object cases:
- InitCommand: require / require-dev
- Locker::fixupJsonDataType: stability-flags / platform / platform-dev
- JsonConfigSource fallback: require/config keys that must stay objects
Align the affected test expectations with Composer: JsonFile::read() decodes
with assoc=true, collapsing the on-disk {} back to [], so reads expect [].
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Port 11 categories of previously-ignored Composer tests now reachable with
the mockall crate: DownloadManager, VCS/Perforce/File downloaders,
VersionSelector, PlatformRepository, Auditor, installer/FilesystemRepository,
RootPackageLoader, util auth/http, commands, and Cache.
Extract test seams additively on concrete structs as *Interface traits
(Runtime, HhvmDetector, VersionGuesser, RepositorySet, Perforce,
BinaryInstaller) plus mock-field seams (Cache, Filesystem); consumers take
trait objects. Mocks are defined locally in the test crates via
mockall::mock!, since automock-generated mocks are cfg(test)-gated and
invisible across the integration-test boundary.
dataProviders are ported in full; tests blocked by unported shims stay
#[ignore] with documented reasons rather than reduced or weakened.
Fix product bugs surfaced by the ports:
- util/github: use the exception code, not the HTTP status, for 401/403
- advisory: serialize empty audit maps as [] to match PHP json_encode
- repository/filesystem and downloader/file: fix RefCell double-borrow panics
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Three porting mismatches caused show/info output to diverge from PHP:
- "not found" hint appended " in /composer.json" whenever the
working-dir key existed; PHP uses isset(), which is false for the
null default. Now only appended when the value is non-null.
- printPackages and generatePackageTree inserted "" for a missing
description instead of null, so isset() rendered a spurious trailing
space (and JSON emitted "" instead of null). Both now preserve null.
Un-ignores the eight rendering-gap tests these fix (plus one already
passing), and rewrites the remaining ignore reasons to name the real
blocker (package categorization, --no-dev filtering, RefCell borrow,
installer resolution) instead of a stale generic message.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
The jsonschema crate reports a missing required property against its
parent object, leaving the instance path empty at the root. This skipped
the "PROPERTY : MESSAGE" formatting that Composer produces. Append the
missing property name to the path so the output shape matches.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
The ApplicationTester harness is in place, so port the four command
test bodies that were todo!() stubs and replace the stale "requires
ApplicationTester ... not implemented" ignore reasons with the actual
remaining Phase-C blockers. test_install_command_errors now passes;
the rest stay #[ignore] pending installer registration, the update
command InputDefinition, and the InstallationManager::execute port.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Holding a RefMut<Composer> across execute() conflicted with the shared
borrow taken inside EventDispatcher::get_script_listeners, panicking with
"RefCell already mutably borrowed". All accessors used here take &self, so
a shared borrow suffices.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
|
|
ShowCommand::configure registered an empty set_definition (placeholder), so every
show invocation failed with option/argument-does-not-exist. Port the full
argument/option list (package, version, --all/--locked/--installed/--platform/
--available/--self/--tree/--latest/--outdated/--format/... ) from PHP
ShowCommand::configure. Completion-suggestion closures and the format allowed-value
list are dropped to match the current InputArgument/InputOption API.
Un-ignores 14 ShowCommandTest cases; the remaining 28 keep faithful bodies but
stay ignored (show-rendering output gaps and remote-HTTP paths), reasons updated.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
PRE_POOL_CREATE todo
RemoveCommand::execute held composer_full_mut across deactivate_installed_plugins
and event dispatch, both of which re-enter the same RefCell (composer.rs:500/446);
it only uses &self getters, so borrow it immutably.
PoolBuilder dispatched PluginEvents::PRE_POOL_CREATE by building an event that
required moving the (unclonable) repositories/Request — left as todo!(). The
event is purely plugin-facing and its result is never read in the no-plugin path
(Pool::new reads self.packages directly), so skip it with a TODO(plugin) note.
Removes the composer.rs re-entrancy and two todo!()s from the remove install
path; remove's tests now reach the unregistered-installers blocker (factory.rs).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
execute nested the already-built InstalledRepository inside a second
InstalledRepository, tripping the assertion that an InstalledRepository may not
contain another. PHP adds a PlatformRepository to the existing composite via
addRepository; do the same.
Un-ignores CheckPlatformReqsCommandTest::test_failed_platform_requirement.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
show/remove/global/audit/check-platform-reqs/status/self-update/validate tests
Faithfully port the remaining stubbed command test bodies from their PHP
counterparts (expected values verbatim). Newly passing: remove (6), global (2),
check-platform-reqs (1), status (1), audit (1), self-update (1).
Tests whose ported bodies reach a genuine unported src path keep faithful bodies
but stay #[ignore] with precise reasons. Dominant blockers surfaced:
- ShowCommand::configure stub (empty set_definition) blocks all 42 show tests
- Composer-handle RefCell re-entrancy in the Installer (composer.rs:500) and
Factory::create_composer (composer.rs:446) paths
- check_platform_reqs nests InstalledRepository in InstalledRepository
- audit's non-locked branch (audit_command.rs:285) and write_error3 re-entrancy
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
style
is_console_output_interface downcasts dyn OutputInterface to the concrete
ConsoleOutput (the sole ConsoleOutputInterface implementor) via AsAny, mirroring
the existing ConsoleSectionOutput check. create_table now passes the customized
TableStyle directly through StyleName::Style instead of discarding it.
Un-ignores LicensesCommandTest::test_format_summary.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
The Table helper modeled a row's cells as PhpMixed and recovered the concrete
TableCell/TableSeparator types via runtime instance_of, leaving the entire
mixed/array bridge (to_row_vec, cell_colspan, row_get, ...) as todo!(). Replace
that with proper Row/Cell enums:
Row = HeaderDivider | Separator(TableSeparator) | Cells(Vec<Cell>)
Cell = Null | Value(String) | Cell(TableCell) | Separator(TableSeparator)
The internal header/body boundary that PHP detects by object identity
($divider === $row) becomes the dedicated Row::HeaderDivider variant. Style
arguments (PHP string|TableStyle) become a StyleName enum, so Table::new no
longer panics in resolve_style's instance_of stub; TableStyle derives Clone so
named styles resolve from the registry.
PhpMixed-based callers (SymfonyStyle::table, render_table, auditor's sanitize)
bridge via From<PhpMixed> for Cell/Row at the boundary.
Un-ignores LicensesCommandTest text-format cases (4) and
BaseDependencyCommandTest::why; output matches PHP exactly. Removes ~15 impl
todo!()s in the Table helper.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Unblocked by the Config::merge list-form repositories fix.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
execute only calls &self getters on the Composer, but borrowed it via
composer_full_mut. The held RefMut deadlocked the re-entrant shared borrow
taken by EventDispatcher::dispatch -> get_script_listeners ->
PartialComposerHandle::borrow_partial, panicking on every invocation.
Un-ignores all 12 DumpAutoloadCommandTest cases.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
RepositoryCommand's JSON-arg detection used the un-delimited regex r"^\s*\{";
the PHP source is the delimited '{^\s*\{}', which compile_php_pattern requires.
Config::merge only extracted repositories from PhpMixed::Array; a JSON array
decodes to PhpMixed::List (an array with integer keys in PHP) and was silently
dropped. Handle List by mapping to integer string keys.
Un-ignores all 10 remaining RepositoryCommandTest cases (16/16 pass).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Faithfully port repository, base_dependency, exec, dump_autoload, run_script,
licenses command tests from their PHP counterparts (expected values verbatim).
Newly passing: repository (6), base_dependency (5), exec (2). Tests whose ported
bodies hit a genuine unported path (HTTP/curl, event-dispatch re-entrancy,
spl_autoload_register, php_uname, instance_of, un-delimited Preg patterns,
Config::merge dropping list repos) keep faithful bodies but stay #[ignore] with
precise reasons; no assertions weakened.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
testSearch (HTTP layer)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Discovered via a full --include-ignored run: these tests have real (non-stub)
bodies and pass now, either because their blocker was since implemented (e.g.
config_command's stream_set_blocking via libc) or the ignore was stale.
Covers composer, config, forgejo_url, config_command, default_policy,
transaction, installed_repository, github_driver, version_bumper.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Add create_installed_json/create_composer_lock test helpers. Port command (8),
repository path/forgejo/perforce/vcs (11), and fossil/hg/download_manager (13)
tests. Fix production porting bugs: root_package_loader/forgejo_url/version_bumper
regex delimiters, repository_manager create_repository_by_class, array_loader
isset, licenses_command RefCell borrow; implement disk_free_space and
touch2/touch3 via libc.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Port command (9), util gitlab/forgejo/tls (6), package (6), repository (3)
tests. Implement TlsHelper. Fix porting bugs: config_command extra merge,
RootAliasPackage setters, ValidatingArrayLoader isset, repository_factory name
generation, forgejo exception code, version_parser error chaining.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Replace the libcurl-shim CurlDownloader with a reqwest+tokio implementation per
the .ken sketch, resolving the construction panic that blocked command tests
(mock path via __new_mock is untouched). Port remote_filesystem (7), hg/svn
driver (4), zip_archiver/git_exclude_filter (4) tests. Fix hg/svn/git_exclude
regex-delimiter and svn result-propagation porting bugs.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Port autoload_generator (24), bitbucket (14), suggested_packages (11),
git_driver (6), archive_manager (3), and a bump command test. Fix the
ApplicationTester output-capture root cause (php://memory streams must be
readable regardless of fopen mode). Implement posix_getuid/geteuid, the PCRE
'A' anchored modifier, php_strip_whitespace, stream_get_wrappers, is_callable
scalars; fix preg_quote angle-bracket escaping and class-map parser regexes.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
IOStub and ConfigStubBuilder provide getMockBuilder-style configurable
stubs. Wired into util/repository/downloader/command test targets.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Rework the environment shim around getenv/putenv on the real environment
and $_ENV/$_SERVER as startup snapshots, all over OsString. Migrate every
caller off the old server()/server_argv() helpers and force the snapshots
in main() before any putenv() runs. Document the porting rules in
docs/dev/env-vars-porting.md.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Port the pure-method cases (parse/namespace/formatAuthors/git/vendor-ignore)
and build the ApplicationTester / initTempComposer harness the run cases need.
Supporting production changes:
- carry the streamable input stream as PhpResource (not PhpMixed) and add
InputInterface::as_streamable so QuestionHelper reads the injected stream
- add StreamOutput/ConsoleOutput __set_stream test helpers and
ApplicationHandle::set_catch_exceptions for the tester
- implement the interact() author validator via parse_author_string
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>
|
|
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
The per-file stub!/encode_stub!/etc. macros generated #[ignore]d test
functions but obscured the individual test bodies. Expanding them inline
removes the macro indirection so future ports can fill in each function
directly.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Port PHP setUp/tearDown across the ported integration tests using
same-named set_up()/tear_down() functions and a TearDown struct whose
Drop runs tear_down(). Fixture-init setUp returns its fixtures;
tmpdir-style setUp/tearDown carry state in TearDown fields. Parts that
depend on unported infrastructure (PHPUnit mocks, Config::merge, the PHP
error handler) stay todo!() and are only wired into ignored stubs to
avoid breaking live tests.
Also fix shirabe-php-shim putenv to handle the no-'=' form (PHP unsets
the variable), which Platform::clear_env relies on for the env-clearing
tearDowns.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
|
Adds Base/Bump/Config/DumpAutoload/Fund/Global/Init/Install/Licenses/Remove/
Repository/Require/RunScript/Show/Suggests/Update command tests. All ignored:
they need the ApplicationTester/initTempComposer harness (Init also reflects
into protected helpers). setUp/tearDown not ported.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|