| Age | Commit message (Collapse) | Author |
|
executeBatch now builds one future per operation — the PHP promise
chain prepare -> install/update/uninstall -> cleanup -> repo->write,
including the '<Op> of <pkg> failed' rejection handler covering the
chain up to cleanup — and drives the whole batch through
waitOnPromises()/Loop::wait, so archive extraction (the unzip
subprocesses gated by ProcessExecutor's semaphore) finally overlaps
across packages. Alias operations stay synchronous in the collection
loop like PHP.
The shared repository is threaded through the chains as
RefCell<&mut dyn InstalledRepositoryInterface>: execute() wraps the
incoming &mut once, and InstallerInterface::install/update/uninstall
take the cell so implementations borrow it only in their synchronous
head/tail, never across an await. InstallationManager's own
install/update/uninstall/download/get_installer/get_install_path/
mark_for_notification move to &self (cache and notifiable_packages
behind RefCell) so every chain can capture &self.
WritableRepositoryInterface::write and the InstallationManagerInterface
get_install_path it relies on lose their &mut manager requirement —
the per-op repo->write inside the chains only reads install paths.
Warm-cache create-project laravel/laravel: the package-operations
phase (109 installs) drops from ~3.0-3.8s serial to ~1.9s, on par
with real Composer (~2.1s) measured back-to-back; the resulting
vendor tree, installed.json included, stays byte-identical to
Composer's (diff -rq clean).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
|
InstallationManager::downloadAndExecuteBatch now matches PHP: every
update/install operation's installer->download() promise is collected
and driven concurrently through waitOnPromises()/Loop::wait instead of
being awaited one package at a time. Concurrency caps stay where PHP
puts them (HttpDownloader 12, ProcessExecutor 10 via their semaphores).
Error semantics follow PHP too: all downloads settle before the first
rejection is rethrown, rather than aborting on the first failure.
To let the collected futures and the cleanup closures own their
installer beyond the loop iteration that created them, the installer
registry becomes Vec<Rc<dyn InstallerInterface>> and get_installer
hands out clones (PHP closures capture $installer the same way), with
InstallerInterface methods taking &self across the six implementors —
the only genuinely mutable state was LibraryInstaller.vendor_dir
(canonicalized in place), now behind a RefCell.
as_plugin_installer_mut/as_binary_presence_interface lose their &mut.
The cleanup_promises entries are now the real thing: the PHP closure
including the getInstallationSource() guard and the
installer->cleanup($opType, $package, $initialPackage) call, replacing
the no-op futures (drops one TODO(phase-b) and two TODO(phase-c)).
Verified against the real network: create-project laravel/laravel
produces a vendor tree byte-identical to real Composer's (diff -rq
clean across all 109 packages including vendor/composer).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
|
Concurrent package operations call into the same downloader instances
through Rc<RefCell<dyn DownloaderInterface>>; with &mut self methods
every call holds a RefMut across its awaits, which panics with
'already mutably borrowed' the moment two operations overlap. This is
groundwork for fanning out InstallationManager's download/install
loops (same rework HttpDownloader/CurlDownloader already got).
- DownloaderInterface/ChangeReportInterface/ArchiveDownloader/
VcsDownloader methods now take &self; as_change_report_interface
returns &dyn instead of &mut dyn.
- Implementors move their genuinely mutable state behind cells:
FileDownloader.additional_cleanup_paths, the archive downloaders'
cleanup_executed, ZipDownloader.zip_archive_object,
VcsDownloaderBase.has_cleaned_changes, GitDownloader's stash/discard/
cache maps and GitUtil, SvnDownloader.cache_credentials,
PerforceDownloader.perforce. FileDownloader.io gains a RefCell layer
so get_local_changes can keep PHP's NullIO swap under &self.
- ProcessExecutor::execute_async now returns a future that captures
everything up front instead of borrowing the executor, and call
sites build the future before awaiting, so no borrow on the shared
executor is held while a subprocess runs.
- Filesystem::remove_directory_async becomes remove_directory_async_via
taking the Rc handle: the Filesystem is only borrowed for the sync
head/tail, never across the rm subprocess await (sync borrow_mut
users like rename/ensure_directory_exists would otherwise collide).
- DownloadManager async call sites hold shared borrows only.
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>
|
|
The `regex` crate does not support negative lookahead, so the ported
`^dev-(?!main$|master$|trunk$|latest$)` pattern panicked at runtime on
any `require` invocation that reached version-selection. Replace it
with equivalent hand-written string logic per docs/dev/regex-porting.md.
|
|
11 downloader/installer integration-test files each redefined an
identical current_thread `run()` helper to block on async code. Extract
one shared multi_thread Runtime into tests/common/async_runtime.rs so
concurrent #[test] threads can all block_on it, matching the direction
item 7 (top-level Runtime) will take in production code.
|
|
Replaces Job/Request/JobHandle/id_gen/running_jobs/max_jobs with a
tokio::sync::Semaphore permit held for the duration of each request.
get/add/copy/add_copy are now &self (add/add_copy are also genuinely
async); a shared execute()/dispatch() core replaces
add_job/run_rfs_job/start_job/settle_job, returning the Response
directly instead of deferring to wait()/count_active_jobs()/
get_response() (all removed — confirmed zero callers, same for the
now-unused STATUS_* constants).
get()/copy() stay synchronous rather than becoming async wrappers
around add()/add_copy(), bridging via the existing sync_executor
instead of the curl_runtime() introduced for CurlDownloader: their
callers (~35 files reaching HttpDownloader) are mostly plain sync fns
with no async boundary anywhere in the call chain, and forcing that
propagation now would pull forward the dedicated async-propagation
task. curl-eligible requests still route through curl_runtime()
inside dispatch(), same as before — nesting sync_executor::block_on
(no real reactor) around curl_runtime().block_on() (a real, separate
Runtime) is safe; it's only nesting curl_runtime() inside itself that
would panic.
CurlDownloader no longer needs Rc<RefCell<>> wrapping despite the
original design sketch: since item 2 made all of its methods &self,
a plain Option<CurlDownloader> field works fine under HttpDownloader's
own &self methods.
get/add/copy/add_copy becoming &self (rather than &mut self) requires
no changes at any of their ~35 calling files: RefMut/Ref both deref to
a type that can call &self methods just fine.
Verified manually against real network I/O (sandbox disabled): `shirabe
show -a` (get()'s sync_executor-bridged path) and `shirabe
create-project` (add_copy()'s genuinely async path via file_downloader.rs)
both complete correctly with no hang.
|
|
Wrap RemoteFilesystem in Rc<RefCell<>> inside HttpDownloader, in prep
for the upcoming &self conversion of add()/get(). copy()/get_contents()
now bundle the response headers into their return value instead of
requiring a follow-up get_last_headers() call, since two separate calls
through a shared RefCell could otherwise race: nothing would guarantee
the reader observes the headers from its own request rather than one
clobbered by a concurrently borrowed call. get_last_headers() itself is
left in place, mirroring RemoteFilesystem::getLastHeaders() in PHP.
|
|
reset() eagerly rebuilt the ProxyManager singleton immediately,
capturing env vars before a caller could set them for the next
request. PHP's reset() just nulls the static instance; getInstance()
lazily constructs on next use. Match that so proxy env vars set after
reset() are observed.
get_instance() also ensured the singleton was constructed under its
own lock, dropped that lock, and returned the bare Mutex; every caller
then took a second, independent lock. A reset() landing in that gap
would leave the caller observing None and panicking on
.as_ref().unwrap(), a state the old eager-reconstructing reset() could
not produce. Return the already-locked MutexGuard from get_instance()
instead, so construction and use happen under one lock, and update all
call sites accordingly.
Holding that guard across a loop body then deadlocked in
diagnose_command, since check_http_proxy transitively re-enters
get_instance() via HttpDownloader -> CurlDownloader, and
std::sync::Mutex is not reentrant. Re-acquire the lock fresh each
iteration with a short-lived guard instead.
Finally, Mutex::new is a const fn, so the OnceLock wrapper around it
was unnecessary indirection; a bare static Mutex<Option<ProxyManager>>
initializes to the same state without the get_or_init/get dance.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
|
locker_test.rs defined its own installation_manager, identical to
test_case.rs's (both build a bare InstallationManager over a mock
HttpDownloader). Expose the shared one via pub(crate) and drop the
duplicate.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
|
reasons
Implement test_incapable_plugin_is_correctly_detected and
test_querying_non_provided_capability_returns_null_safely against a
real PluginManager, using hand-written PluginInterface/Capable stubs
in place of PHPUnit's ad-hoc mocks. Wire the shared config_stub test
helper into the plugin test binary, and derive Debug on the SetUp
struct per this project's convention.
The remaining plugin_installer_test.rs cases stay #[ignore]d:
install/update/uninstall wiring in PluginInstaller and class
instantiation in PluginManager::register_package are still
TODO(plugin) stubs, so no plugin ever actually gets registered. Each
now records its blocking TODO(plugin) site via // TODO(phase-d).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
|
No test logic changes.
|
|
zip/git/file downloader tests that were already #[ignore]d for a
documented reason lacked the required in-body // TODO(phase-d)
comment; record it for each.
Two git_downloader_test.rs cases,
test_download_uses_various_protocols_and_sets_push_url_for_github and
test_update_doesnt_throws_runtime_exception_if_git_command_fails_at_first_but_is_able_to_recover,
had been left as todo!() with a TODO(phase-d) claiming
ComposerMirror::process_git_url's github regex lacks PCRE delimiters
and panics. That regex already has delimiters and does not panic
(verified directly), and other tests in this same file already use
Package::set_source_mirrors to give a real package a mirror-prefixed
getSourceUrls() list, so the stated blocker no longer applies. Port
both tests using that existing technique instead of recording a
TODO(phase-d) for them.
No other test logic changes.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
|
Implement previously-todo!() tests in auth_helper_test.rs,
process_executor_test.rs, remote_filesystem_test.rs, and
stream_context_factory_test.rs by porting the corresponding PHPUnit
test methods. Extend IOStub with writeRaw/setAuthentication call
tracking and askAndValidate/getAuthentication overrides to model the
PHPUnit mocks these tests rely on, deduping the resulting
call-recording fields into a small generic CallRecorder<T> helper
instead of repeating the same RefCell<Vec<T>> push/borrow().clone()
boilerplate five times.
testStoreAuthWithPromptInvalidAnswer and
testPromptAuthIfNeededMultipleBitbucketDownloads had initially lost
the ported PHPUnit mock's argument/call-count assertions
(askAndValidate's exact prompt string, and
hasAuthentication/getAuthentication's exactly(2) call counts),
silently narrowing what the tests verify; IOStub now records these
calls and the tests assert on them, matching upstream.
Tests left unportable (PHP set_error_handler machinery, closures in
data providers, network/subclass-mock dependencies, etc.) keep
#[ignore] with a single // TODO(phase-d) reason recorded in the
function body.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
|
|
|
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.
|
|
Convert errors/warnings/config to RefCell so load() can satisfy the
trait's &self signature, matching upstream's `instanceof
ValidatingArrayLoader` check in VcsRepository. This makes the
InvalidPackageException downcast path in VcsRepository reachable for
the first time instead of being permanently dead code.
|
|
get_remote_contents was a full stub always returning None, so any
file:// download raised a TransportException. Read local files
directly for the file scheme, mirroring PHP's file_get_contents
transparently handling the file:// stream wrapper. Also fixes
file_get_contents5 to strip the file:// prefix like the 0-arg
variant already did.
|
|
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>
|