| Age | Commit message (Collapse) | Author |
|
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.
|
|
Composer's classmap generator re-issues the same PHP-derived pattern
string for every scanned file (and every token within it), relying on
PCRE's built-in compiled-pattern cache to make that free. shirabe had
no equivalent, so every Preg::* call recompiled the pattern from
scratch via regex::Regex::new(), making `composer create-project`
autoload generation ~130x slower than Composer on a fresh laravel/laravel
install (130s vs ~1s). Memoizing compiled patterns by their raw string
in compile_php_pattern closes that gap.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
|
|
|
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.
|
|
Give DirectoryIteratorEntry a backing path (mirroring
RecursiveIteratorFileInfo) and make directory_iterator enumerate entries,
returning Result to match PHP DirectoryIterator's UnexpectedValueException
on an unopenable directory. Wire the new Result through DumpCompletionCommand's
get_supported_shells.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
|
|
PHP var_export breaks NUL bytes out of single-quoted string literals as
`' . "\0" . '` because a raw NUL byte is invalid in PHP source. The
shim embedded the raw byte instead, diverging from Composer's generated
installed.php (where references can contain NUL).
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>
|
|
PHP arrays do not distinguish an empty map from an empty list, and
json_encode([]) always emits []. The Serialize impl emitted {} for an
empty associative array, which diverged from Composer when computing
the lock file content-hash for a composer.json with an empty require.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
|
|
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
|
|
Compiled Rust never loads a class by name, so the registered callback is dropped.
Return success so callers that register an autoloader during startup can proceed.
Kept the TODO(phase-d) comment: this is an unblocking stub, not a faithful
implementation.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
The stashed binary_installer port was blocked on posix_getpwuid (reached via
Platform::is_virtual_box_guest); implement it via getpwuid(3) extern "C". The
4 install-and-exec tests now pass with the stream I/O and Process cwd fixes.
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>
|
|
Add fcntl/select extern "C" declarations and a PhpResource::raw_fd seam so the
symfony Process pipe loop can read a live child's stdout/stderr. Fix fread on a
non-blocking fd (WouldBlock -> "") and the Process null-cwd default. Real
subprocess output capture now works; un-ignore the process_executor tests.
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>
|
|
Port auth_helper (14), library_installer (8), console_io (7), zip_downloader (3),
git_bitbucket_driver (3) tests. Implement date_create/strtotime for the ISO8601/
RFC3339/relative formats Composer uses (unknown input -> None, no silent guess).
Fix production bugs: Question::is_assoc list-vs-assoc, auth_helper gitlab-domains
list handling, LibraryInstaller RefCell double-borrow, ZipArchive::extract_to
ErrorException propagation.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Port perforce (36), locker (10), composer_repository (7), installation_manager
(6), file_downloader (5), and event_dispatcher (6) tests via the mock infra.
Fix production porting bugs surfaced en route: BufferIO::get_output look-behind
regex, ComposerRepository list-form package iteration and initialize dispatch,
gethostname and spl_autoload_functions shims; add EventDispatcher get_listeners
test seam.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Port git, version_guesser, gitlab_driver, github_driver, and git_downloader
tests using the ProcessExecutor/HttpDownloader mocks and IO/Config stubs.
Fix production regex-porting bugs surfaced by the now-reachable paths:
Url::sanitize and Response::find_header_value had non-delimited PCRE patterns;
implement array_search_mixed non-strict branch and a datetime format mapping.
Add HttpDownloader::__new_mock so mocked downloaders skip curl construction.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Port seld/jsonlint JsonParser (+hand-written Lexer), unblocking 10 json_file
parse-error tests verified byte-for-byte against PHP. Implement Symfony Finder
SplFileInfo, executable finders, String classes (byte/code-point/unicode),
ZipArchive shim (via the zip crate), SPDX license validation, and shim
date/stream functions. Genuinely-blocked sites (reflection, PHP runtime
constants, non-UTF-8 transcoding, recursive PCRE) stay todo!() with reasons.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
The PCRE delimiter `(?<!^|as|[=>< ,]) *(?<!-)[, ](?!-) *(?!,|as|$)` used to
split AND-constraints relies on look-around, which the regex crate cannot
compile (parse_constraints panicked). Reproduce its semantics in a hand-written
`split_and_constraints` scanner shared by VersionParser and RootPackageLoader.
Also model `method_exists` for the class-name form (shirabe runs no dumped
Composer ClassLoader) and un-ignore the InstalledVersions tests, serialized via
`#[serial]` since they share global static state.
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 the todo!() json_schema::Validator stub with the jsonschema crate.
Errors are surfaced as 'property : message'; the message wording follows the
jsonschema crate and is *not* justinrainbow-compatible.
Port the ComposerSchemaTest and JsonFileTest schema cases to the new wording
(noted per test).
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>
|
|
Replace the deferred todo!() path with loose_eq, implementing PHP's
== semantics for in_array's non-strict mode (numeric-string-aware
comparison, bool/null coercion, recursive array comparison).
|
|
PHP's JSON_PRETTY_PRINT uses a 4-space indent, so use serde_json's
PrettyFormatter with a 4-space indent when the flag is set.
|
|
|
|
proc_open/proc_close/proc_get_status/proc_terminate represented the
process handle as a PhpMixed, which cannot hold a live child process or
its pipes, so they were stubs or todo!(). Model the handle as a new
PhpResource::Process variant and child pipes as a StreamBacking::Pipe,
with a native Descriptor enum for descriptorspec; proc_open now returns
io::Result and fills pipes as IndexMap<i64, PhpResource>.
Rewire the Symfony Process pipes and the Console terminal/cursor onto
the new types, removing the "PhpMixed cannot carry a PhpResource"
todo!()s. The remaining todo!()s are genuine syscall leaves
(proc_terminate signal delivery, stream_select, stream_set_blocking,
posix_kill, pty, fd>=3) left unimplemented since no syscall crate is
introduced.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
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>
|
|
Implements a minimal, PHP-compatible subset of \DOMDocument, \DOMNode and
\DOMNodeList for use by Symfony's XmlDescriptor. save_xml mirrors libxml2's
formatOutput serialization (XML declaration, 2-space indent, self-closing
empty elements, and no pretty-printing of text-bearing elements) and writes
to a std::io::Write sink. Verified byte-for-byte against real PHP libxml.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Give RecursiveDirectoryIterator/RecursiveIteratorIterator real backing
data: the iterator walks the tree in SELF_FIRST/CHILD_FIRST order, yields
SplFileInfo-like entries (is_dir/is_file/is_link/get_pathname/get_size),
and a Cell cursor lets get_sub_pathname() report the current entry.
Implement the std-backed file helpers: lstat, mkdir (umask-aware via
DirBuilder), symlink, chmod, fileperms, fileowner, is_executable,
unlink_silent, touch (create-if-absent), file()/file_put_contents3/
file_get_contents5, tempnam, umask (via /proc/self/status), and a glob()
supporting *, ?, [...] and {..} brace expansion.
The PhpMixed-keyed fopen stream family, disk_free_space, touch with an
explicit time, opendir and DirectoryIterator remain TODO(phase-d): they
need a PhpMixed stream representation or syscalls std does not expose.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Port php_version_compare (canonicalization + special-form ordering) and
expose it via version_compare()/version_compare_2(). Implement clone()
(via Clone), spl_object_hash()/spl_object_hash_process() (address-based),
get_loaded_extensions() and the main-version case of phpversion().
Interpreter/reflection/autoload/eval/$GLOBALS/memory-accounting and
Windows-only SAPI helpers remain TODO(phase-d): they have no equivalent
in the compiled shim.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Implement the bulk of string.rs shims:
- sprintf() with flags/width/precision/positional args for the common
conversions (s/d/u/b/o/x/X/c/f/F)
- pack()/unpack() for the C/c/n/v/N/V (+ s/S/i/I unpack) format codes
- base64_encode()/base64_decode() (non-strict)
- substr_replace, str_bitand, chr, hexdec, stripcslashes, addcslashes,
number_format (round-half-away-from-zero), uniqid, strip_tags,
html_entity_decode, iconv (UTF-8/ASCII identity)
%e/%E/%g/%G, wordwrap, sscanf, php_strip_whitespace and non-UTF-8 iconv
remain TODO(phase-d) (exact float-exponent/tokenizer/encoding-table
behavior not yet ported). Divergences in ported functions are noted with
TODO(phase-d) comments.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Run exec()/shell_exec()/system() through /bin/sh -c with PHP-faithful
line handling and return values. Port escapeshellcmd() (Unix branch,
including paired-quote handling) and escapeshellarg(). Implement
posix_isatty() via std::io::IsTerminal.
uid/signal/process-title helpers and proc_open-dependent status calls
remain TODO(phase-d): they need a libc/syscall crate or the deferred
process/signal subsystems.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Implement var.rs shims: serialize() (scalars/arrays with canonical
integer-key normalization), var_export()/var_export_str() (PHP-faithful
indentation and quoting), to_array() ((array) cast semantics),
get_debug_type() and is_iterable() for the scalar/array cases.
Reflection-dependent helpers (is_a, is_callable, get_class, instance_of,
etc.) and object variants remain TODO(phase-d) as they need runtime
class information PhpMixed does not carry.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
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>
|
|
Implement array_unique, array_splice, array_merge_recursive, krsort,
ksort, asort, sort_with_flags and sort_natural_flag_case, plus the
strnatcmp/strnatcasecmp port they rely on. Drop array_key_last and
array_splice_mixed in favour of existing helpers at the call sites.
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>
|
|
Support md5, sha1, sha256, and xxh3 algorithms.
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 todo!() bodies of filter_var_email, filter_var_ip, and
filter_var_int_with_range with working validators. Like filter_var_url
these are pragmatic rather than byte-for-byte compatible with PHP's
hand-written filters; the divergences are noted in comments.
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>
|