aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe/src/package/version/version_guesser.rs
AgeCommit message (Collapse)Author
2026-08-06chore: drop @param/@return tags that only restate Rust typesnsfisis
The ported docblocks copied @param and @return straight from the PHP source. When such a tag carries nothing but a type and an argument name, the Rust signature already states it, so the line is noise. Tags whose text adds prose beyond the type are kept. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04docs: state code facts instead of porting-phase progressnsfisis
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25refactor: replace redundant clones with movesnsfisis
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-20fix(process-executor): un-ignore 11 tests by implementing execute_async mock ↵nsfisis
support ProcessExecutor::execute_async's mock branch was an unimplemented todo!(), blocking every test whose code path calls it (feature-branch git diffing, system-unzip/7z fallback extraction). Implement it by: - Adding Process::__mock (mirroring the existing ZipArchive::__mock pattern) so execute_async can resolve with a fabricated, already- terminated Process instead of spawning a real subprocess. - Extracting the sync mock's expectation-matching logic into a shared ProcessExecutor::mock_match, wrapping the mock state in a RefCell so it works from execute_async's &self/&mut self receivers. - Setting error_output/capture_output from the mock branch, matching PHP's ProcessExecutorMock::executeAsync sharing doExecute with the sync path; execute_async now takes &mut self for this (safe, since the borrow only needs to live through the synchronous setup, not across the .await). - Turning a strict-mode expectation mismatch from a panic!() into a shirabe_php_shim::RuntimeException Err, mirroring PHPUnit's AssertionFailedError extending \RuntimeException: PHP call sites that catch (\RuntimeException $e) around a mocked git/hg/svn call (e.g. Git::get_mirror_default_branch, GitDriver::supports) treat a mismatch as an ordinary recoverable failure, and now so does the port. The RefMut is dropped before firing an expectation's optional callback so a re-entrant callback doesn't panic on double-borrow. Also fixes two real bugs found while porting test_private_repository_ no_interaction: GitHub::authorize_oauth and GitLab::authorize_oauth checked their domains config via PhpMixed::as_array(), which only matches the Array (map) variant, but github-domains/gitlab-domains default to PhpMixed::List, so the check always returned false and OAuth token lookup was silently skipped. Use the in_array shim instead, matching PHP's in_array() semantics. Also fix Git::run_command's "capture credentials from git remote -v" call, which used the panic- swallowing execute_args wrapper instead of a fallible execute(), so a mock mismatch there couldn't reach get_mirror_default_branch's catch. Un-ignores: - zip_downloader_test::test_system_unzip_only_{good,failed} - zip_downloader_test::test_non_windows_fallback_{good,failed} - event_dispatcher_test::test_dispatcher_outputs_error_on_failed_command - root_package_loader_test::test_feature_branch_pretty_version - version_guesser_test::test_guess_version_reads_and_respects_non_feature_branches_configuration_for_arbitrary_naming{,_regex} - version_guesser_test::test_remote_branches_are_selected - github_driver_test::test_private_repository_no_interaction (also adds the missing #[serial], since it seeds the shared Git::VERSION static that vcs_repository_test::test_load_versions depends on for real) - init_command_test::test_get_git_config, made deterministic by pointing HOME at a throwaway dir with its own .gitconfig instead of depending on the host's global git config Deduplicates the GitVersionGuard/RestoreEnv test-drop-guard idioms into tests/common/test_case.rs instead of reimplementing them per file. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-18chore: rustfmtnsfisis
2026-07-18refactor(downloader): take &self across the downloader hierarchynsfisis
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>
2026-07-18perf(process-executor): make execute_async genuinely concurrentnsfisis
execute_async was a serial pump: it queued a job, then drove it to completion itself via wait_id()'s blocking usleep loop before returning, so concurrent callers never overlapped even when polled together through FuturesUnordered. Rewrite it as a single &self async fn mirroring the CurlDownloader/ HttpDownloader rework: a tokio Semaphore sized by max_jobs (COMPOSER_MAX_PARALLEL_PROCESSES, PHP parity) gates admission, the child is started non-blocking, and an async 1ms sleep loop pumps is_running()/check_timeout() while yielding to the reactor so sibling jobs genuinely run in parallel. The Job table, STATUS_* lifecycle, start_job/mark_job_done/count_active_jobs/wait/wait_id all had no remaining callers and are removed. &self also lets callers hold only a shared borrow across their awaits (zip_downloader, version_guesser, filesystem via the new get_process_handle), which would otherwise panic with 'already mutably borrowed' once two async jobs overlap on the same Rc<RefCell<ProcessExecutor>>. The async mock branch no longer consumes the expectation before hitting its todo!(): the panic made that bookkeeping unobservable. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-18perf(regex): eliminate per-call clone overhead in preg_* dispatchnsfisis
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>
2026-06-29chore(lint): ban bare `use anyhow::Result` and fully qualify itnsfisis
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>
2026-06-28test(installer): port InstallerTest unit and integration harnessnsfisis
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>
2026-06-28fix(http): avoid nested tokio runtime panic in download pathnsfisis
The CurlDownloader owned a tokio runtime and block_on'd reqwest from its sync tick(), while the repository/installer/downloader sync bridges each created another Runtime and block_on'd async fns that reach that leaf. Driving one Runtime::block_on from within another panics with "Cannot start a runtime from within a runtime", hit by `require` when fetching p2 metadata. Switch CurlDownloader to a blocking reqwest client (its own internal thread, never nested) and replace the per-call Runtime::new().block_on bridges with a no-reactor sync_executor::block_on helper. No awaited future parks on a reactor once the only async I/O is blocking, so the helper can be nested freely. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28refactor: add linternsfisis
2026-06-27test: port Composer tests unblocked by mockall, add seamsnsfisis
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>
2026-06-27refactor: fix compiler warnings and clippy warningsnsfisis
2026-06-24refactor(process): take cwd as Option<&str> instead of IntoExecCwdnsfisis
Replace the generic cwd parameter backed by the IntoExecCwd trait with a concrete Option<&str> across execute/execute_args/execute_tty/execute_async. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24refactor(semver): re-export shirabe-semver at crate root, drop ↵nsfisis
composer::semver stubs Flatten shirabe-semver's modules into glob re-exports at the crate root and route all consumers through the short paths. Remove the duplicate composer::semver stubs from shirabe-external-packages in favor of the shirabe-semver types. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20feat(symfony-process): port full Process class from PHPnsfisis
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>
2026-06-20refactor(php-shim): drop Box wrapping from PhpMixed List/Arraynsfisis
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>
2026-06-20refactor: auto-fix clippy warningsnsfisis
2026-06-14refactor(pcre): drop Result from Preg method return typesnsfisis
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>
2026-06-14refactor(pcre): drop strict-groups Preg variantsnsfisis
Rust's type system already distinguishes participating from non-participating capture groups via Option, so the *StrictGroups methods add no safety here. Remove them and switch callers to the plain variants.
2026-06-11feat(console): resolve phase-b TODOs in doRun and IO wiringnsfisis
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>
2026-06-10feat(phase-c): resolve cross-module phase-b TODOsnsfisis
2026-06-08refactor(external-packages): drop component segment from symfony pathsnsfisis
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>
2026-06-07feat(metadata-minifier): port expand for minified package metadatansfisis
Implement MetadataMinifier::expand with the PHP list-of-arrays signature (Vec<IndexMap>) and wire it into ComposerRepository so composer/2.0 minified package metadata is expanded, resolving the phase-b TODO. minify() is left unported as it is not used in Composer itself. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03refactor(downloader,repository,json): drop stale try/catch TODOs; fix svn ↵nsfisis
getFileContent catch type Remove 17 TODO(phase-b) markers across exception-modeling sites where the existing single-Result closure+match already faithfully models the PHP try/catch (catch paths only rethrow, retry, log, or silently ignore and never yield a recoverable value, so a double Result is unnecessary). Fix SvnDriver::get_file_content to catch only RuntimeException (matching PHP's catch RuntimeException) and extract its .message instead of calling e.to_string() on the anyhow::Error, which would panic while the shim exception Display is unimplemented; other errors now propagate. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-26refactor(io): share IOInterface via Rc<RefCell<dyn _>> handlensfisis
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23refactor(promise): drop \React\Promisensfisis
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-23refactor(promise): rewrite promise bodies to async/awaitnsfisis
Mechanically convert promise-returning function bodies to async/await: resolve() returns the value directly, forwarding calls get .await, and simple .then chains become await sequences. Also collapse the installer double-Option (Result<Option<Option<PhpMixed>>> -> Result<Option<PhpMixed>>). Hard spots that depend on the Loop::wait / job-machine boundary (accept/reject orchestration, closures capturing &mut self, batch waits) are left intact and marked with TODO(phase-c-promise) for manual porting. The crate does not compile yet; traits still need #[async_trait]. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20refactor: re-export module items to shorten import pathsnsfisis
2026-05-20fix(compile): fix all remaining compile errorsnsfisis
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19fix(compile): fix more random compile errorsnsfisis
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17chore(style): cargo fmtnsfisis
2026-05-16feat(port): port VersionGuesser.phpnsfisis
2026-05-12feat(init): add scaffold filesnsfisis