| Age | Commit message (Collapse) | Author |
|
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>
|
|
Several Preg::*() call sites lost their PHP delimiter (and in one case
the `i` modifier) during porting, since preg_*() expects the delimiter
to be preserved in the caller's pattern literal and stripped internally.
This made compile_php_pattern panic or silently misparse the pattern.
Un-ignore the Version tests that were blocked by this bug.
|
|
|
|
Extends no_banned_use to cover std::any::Any, std::io::Read/Write, and
std::process::Command, and teaches the linter to allow `as _` imports
so trait methods can still be brought into scope without binding the
banned name. Fully qualifies all existing usages across the codebase.
|
|
PathRepository already implements RepositoryInterface and create_repository
already handles the "path" class, so the prior ignore reason no longer
applies; verify the FilterRepository/PathRepository wrapping via
RepositoryInterfaceHandle::is/downcast_rc.
|
|
Port testNoPluginsDisablesPluginsWhenScriptCommandsExist and
testScriptCommandTakesPriorityOverAbbreviatedBuiltinCommand. Both stay
#[ignore]d because do_run panics at the script-registration todo!()
(application.rs:2461) when composer.json has scripts. Add a test-only
ApplicationHandle::__get_composer accessor so the first test's
getPluginManager assertions can be expressed.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Wire a git downloader into the test's DownloadManager (mirroring
Factory::createDownloadManager) so the archive path clones the package
source as PHP does. Both remain #[ignore]'d on PharData tar archiving
(new_with_format/build_from_iterator are todo!() in the php-shim).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
The faithful port drives a real HttpDownloader + Loop over a file://
dist URL, but RemoteFilesystem::get_remote_contents is a phase-c stub
returning None, so the download fails with a "could not be downloaded"
TransportException before reaching the ZipArchive "is not a zip
archive" path. Kept #[ignore] with the corrected reason (the previous
curl_multi_init note was wrong, file:// never uses curl).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
These three tests exercise getContents/copy against a file:// URL (and a
real network download for BitBucket). They remain #[ignore] because
get_remote_contents has no stream/file layer yet (TODO(phase-c)) and
returns None, so the calls raise a TransportException. The ignore
reasons are updated to reflect the actual failure point.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Port testVendorDirExcludedFromWorkingDir, testUpLevelRelativePaths,
testGeneratesPlatformCheck (all 12 data-provider rows), and both
testAbsoluteSymlinkWith* tests from the Composer suite.
testVendorDirExcludedFromWorkingDir passes. The other four expose
behavioral gaps in shirabe (exclude-from-classmap with up-level/symlink
paths, psr-4 symlink warnings, get_platform_check provider matching), so
they keep their fully-ported bodies but are marked #[ignore] with the
specific incompatibility rather than weakening expectations.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Model Git::runCommand's mixed $commandOutput parameter with the
RunCommandOutput trait (one impl per PHP mode: discard, by-ref capture,
callable handler), mirroring ProcessExecutor's IntoExecOutput. This moves
the is_callable($commandOutput) value-inspection into the type system and
drops the dependency on the shim's incomplete is_callable.
Co-Authored-By: Claude Opus 4.8 (1M context) <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>
|
|
It is faithful to PHP's by-value array/string semantics.
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>
|
|
Validate JSON syntax with serde_json's parse errors in JsonFile, and detect
duplicate keys in ConfigValidator with a hand-written serde visitor, dropping
the now-unused JsonParser/Lexer/DuplicateKeyException ports. ParsingException
is kept as the thrown error type and downcast signal.
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.
|
|
Port composer/tests/Composer/Test/InstallerTest.php. testInstaller (the
provideInstaller cases) is fully ported and passes; the three integration
tests port doTestIntegration in full (the .test fixture loader, FactoryMock,
the in-process console Application with install/update commands, and the
PHPUnit assertStringMatchesFormat matcher) and remain #[ignore]'d since the
install pipeline is not yet executable end-to-end.
Add test-only `__`-seams to the concrete types the test depends on, since
their consumers (e.g. Locker takes the concrete InstallationManager) and the
subclass-style mocks have no trait to mock: InstallationManager (recording
mock + as_any), Factory (__create_mock), VersionGuesser, and
InstalledFilesystemRepository. The production path (mock: false) is unchanged.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Implements the todo!() stubs in all_functional_test.rs by faithfully
porting parseTestFile, cleanOutput and the inline %regex% EXPECT matcher,
plus a subprocess runner that drives CARGO_BIN_EXE_shirabe (in place of
PHP's composer.phar) over the reused Fixtures/functional .test files.
The five fixtures are wired as individual #[serial] #[ignore] tests with
per-fixture reasons: the two create-project cases need network + a real
git clone, and the three update cases need the not-yet-implemented Plugin
API. test_build_phar stays an ignored stub since Rust has no phar build.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
|
|
JsonFormatter is intentionally unported in crates/shirabe/src/json, so
the ignored todo!() stub test serves no purpose. Remove the file and its
module declaration.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Replace the todo!() markTestSkipped placeholders in set_up with a
compile-time cfg gate on the test function, mirroring PHP's setUp
skips on Windows and 32bit.
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>
|
|
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>
|
|
Implement the four privateBitbucketWithOauthProvider cases that were
stubbed as an ignored todo!(). Extend IOStub with per-question
askAndHideAnswer responses and auth pre-seeding so the stateful OAuth
flow can be driven without willReturnCallback, and inject a mock
HttpDownloader plus no-op config sources to mirror PHPUnit's Config mock.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Implement the previously-ignored test, which dumps installed.php via
FilesystemRepository::write and byte-matches the Composer fixture. The
package link setters needed by configureLinks are now reachable through
the __set_provides/__set_replaces test hatches, so the PHP getPackage +
configureLinks shape can be reproduced faithfully.
Also switch both InstallationManager stubs in this file to a single
mockall mock, replacing the hand-rolled impls and call counter.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
setCatchErrors is an old-Symfony compatibility shim that exists in
neither Composer's PHP class nor Shirabe, and setAutoExit(false) is the
default in Shirabe, so neither is a reason a test is unportable. Drop
those mentions and point the application_test ignores at the real
blocker: do_run's script-command registration is still a todo!().
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Add __base_application accessor on ApplicationHandle so the test can
build an ApplicationDescription the way console commands do.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Process::fromShellCommandline and ZipArchive are now ported, so the git
pipeline + zip reading have faithful equivalents. Kept #[ignore]d: the finder
applies .gitattributes rules through BaseExcludeFilter::generate_pattern,
whose (?=$|/) look-ahead regexes the regex crate cannot compile (same blocker
as test_manual_excludes); also needs a git executable.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
|
Ported faithfully via PackageHandle::new + __set_extra (now available on
PackageHandle). Kept #[ignore]d: date-based cases expose a shirabe_semver
normalize divergence (v20121020 -> 20121020.0.0.0), not a test-port issue.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
|
The FilesystemMock seam (already used by FileDownloaderTest) intercepts
removeDirectoryAsync before any rm -rf, so the prior execute_async blocker
no longer applies. getDownloaderMock gains the optional filesystem param.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
|
The IOMock and ConfigStubBuilder helpers now cover the writeError
verification and the get('disable-tls')=>true stub the PHP test needs.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
|
The IOMock helper is now available, so the verify_peer/verify_peer_name
SSL warning case can be exercised instead of left as todo!().
Co-Authored-By: Claude Opus 4.8 <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>
|
|
minify is intentionally unported, so only the expand half of
testMinifyExpand() is exercised.
Co-Authored-By: Claude Opus 4.8 (1M context) <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>
|
|
Several tests read process-global env vars and set/clear them via
TearDown but were not #[serial], so parallel execution could race.
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>
|
|
Composer/PartialComposer exposed its RepositoryManager, InstallationManager,
EventDispatcher, Locker, DownloadManager, AutoloadGenerator and ArchiveManager
as concrete types, but Composer's public setters (setDownloadManager() etc.)
let plugins swap in subclasses. Introduce a *Interface trait per manager and
store each as Rc<RefCell<dyn ...Interface>> so a replacement is honored.
Only Composer's slots and the sinks fed from its accessors become trait
objects; managers injected concretely at construction keep their concrete
references, matching PHP semantics. Fluent setters on the affected classes now
return () and Locker::update_hash is de-generified to a boxed FnOnce so the
traits stay object-safe.
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>
|