| Age | Commit message (Collapse) | Author |
|
|
|
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>
|
|
|
|
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>
|
|
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.
|
|
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>
|
|
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>
|
|
|
|
apcu_fetch/apcu_add only ran when apcuPrefix was non-null, but
Composer never calls setApcuPrefix on the loaders it instantiates
itself; the prefix is only emitted into the generated target-project
autoload_real.php. So the cache branches were unreachable in Shirabe's
execution paths. Remove the apcu shim and the now-dead lookups.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
|
|
Fill in the shim functions that have an easy, accurate pure-Rust port:
array (merge/flip/fill_keys/slice/search/is_list), string (substr_count,
strpbrk, raw/urlencode, ucfirst/ucwords, strstr, strcspn, explode limit,
str_replace arrays), mb_* (strlen/substr/str_split), sort callbacks
(uasort/uasort_map/uksort), levenshtein, intdiv, ceil, ctype_digit,
json_encode, count_mixed and the PhpMixed/to_* boolean casts.
Runtime- or crate-dependent and hard-to-port-accurately stubs (sprintf,
version_compare, natural sort, hashing, etc.) are left as todo!().
|
|
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>
|
|
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>
|
|
Back parse_url/parse_url_all with reqwest::Url and add the
FILTER_VALIDATE_URL and FILTER_VALIDATE_BOOLEAN arms to filter_var, so
Config::prohibit_url_by_config no longer hits todo!(). reqwest::Url is
not a byte-for-byte port of PHP's parser; the divergences are noted with
TODO(phase-c).
Switch the scheme in_array in prohibit_url_by_config to strict: the
needle is a string-or-null and the haystack holds only non-numeric
string literals, so loose and strict comparison are provably equivalent
here, avoiding a dependency on PHP loose `==` semantics.
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!() with a std-only check on the path's permission bits.
A TODO notes this approximates PHP's access(2)/W_OK and can diverge for
files the current user does not own; to be refined with a syscall crate.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Port Symfony's Application::doRenderThrowable so command failures render
the error box instead of hitting todo!(). This unblocks six CLI no-panic
tests (config, depends, global, prohibits, remove, repository), whose
ignore attributes are now removed.
Also fill in the php-shim functions on the render path that were still
todo!(): php_exception_get_code, intval, str_pad, str_split,
mb_detect_encoding, mb_convert_encoding, mb_strwidth, mb_convert_variables.
PHP file/line and the verbose getTrace() block have no faithful Rust
equivalent; file/line use PHP's own 'n/a' fallback and the trace block is
intentionally omitted.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
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>
|
|
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Composer's Application::getComposer() calls exit(1) when a required
Composer instance fails to build under areExceptionsCaught(). Replace the
deep std::process::exit with a php-shim ExitException that mirrors PHP's
`exit` construct: it bypasses parent::doRun()'s catch and Symfony's
renderThrowable (excluded at both broad catches), so the already-written
plain error message is not re-rendered and the process exits with code 1.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Was a todo!() that panicked while building HTTP downloader options
(browse, and the stream/remote filesystem option merging). Recurses only
when both the existing and replacing value are arrays, merging assoc
arrays by key and lists by index; otherwise the replacing value wins.
Verified against PHP on a nested http/ssl option structure.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Was a todo!() that panicked in Factory::get_lock_file (require, and the
file/gzip downloaders). Handles the four PATHINFO_* single-component
options by reusing dirname/basename, computing extension and filename
around the last dot of the basename. Verified against PHP for eight
representative paths, including dotfiles and trailing-dot names.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Was a todo!() that panicked when ProcessExecutor::reset_max_jobs probed
COMPOSER_MAX_PARALLEL_PROCESSES (archive, diagnose, init, ...). Ints and
floats are numeric; strings delegate to the existing is_numeric_string,
which agrees with PHP across the tested vectors. Booleans, null and
arrays are not numeric.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Was a todo!() that panicked for every command reading composer.json
(validate, status, show, update, ...). Parses via serde_json (built with
preserve_order, so insertion order is kept) and converts to PhpMixed.
Mirrors PHP's flagless json_decode: returns null rather than erroring on
malformed input, and decodes objects to ArrayObject when assoc is false,
to an associative array when true. Out-of-i64 and fractional numbers
become floats, matching PHP's default non-bigint behaviour.
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>
|
|
|
|
|
|
|
|
|
|
PHP's random_int/random_bytes are cryptographically secure, but Composer
does not rely on that property, so a non-cryptographic PRNG suffices.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
|
|
|
The free preg_* functions, the CaptureKey type, and the PREG_* constants
move from the pcre crate into shirabe-php-shim, where the rest of the
PHP standard-library shims live. Colliding names take a 2 suffix
(preg_match2, preg_split2, etc.) since the shim already exposes
differently-shaped variants. Preg keeps its public API and delegates to
the relocated functions; CaptureKey is re-exported from composer::pcre
so consumers are unaffected.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Replace the todo!() stubs backing the Preg class and the standalone
preg_* shim helpers with regex-crate implementations.
|
|
|
|
PHP wraps fopen/file_get_contents/file_put_contents in set_error_handler
to capture warning text into error_message. Rust reports I/O failures
through return values rather than warnings, so this side channel cannot
work; replace the calls with TODO(phase-c) notes and leave error_message
empty until the I/O layer surfaces a reason. Also remove the now-unused
set_error_handler_closure shim and make set_error_handler a no-op.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Composer\Console\Application embedded Symfony's Application as an
`inner` field and delegated to it, so polymorphic calls inside the
Symfony base (e.g. doRun -> $this->getLongVersion()) resolved to
Symfony's own methods and never reached Composer's overrides. As a
result `--version` bypassed Composer's getLongVersion()/doRun()
entirely.
Flatten the PHP inheritance chain into the single shirabe Application
struct: take in the Symfony base methods (parent-calling overrides kept
under a `base_` prefix) and drop the `inner` delegation. Replace the
Symfony Application struct in shirabe-external-packages with an
`Application` trait that the merged struct implements, so commands and
descriptors can reference it without a reverse crate dependency.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Convert every sprintf() call with a compile-time literal format string to
format!, implementing Display for PhpMixed (delegating to php_to_string) so
PhpMixed values render with PHP string semantics through {}. Also merge the
format!-wrapped and conditional-literal dynamic sites into single format!
calls. Genuinely runtime format strings (table styles, configurable error
messages, command synopsis, progress-bar modifiers, regex-built messages)
still go through sprintf.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Replace todo!() stubs reached on the `composer --version` path so the
command runs without panicking and exits cleanly:
- introspection (function_exists, class_exists, extension_loaded,
defined) via white-lists modeling a standard Linux PHP CLI
- type casts: php_to_string/strval, php_truthy/boolval, substr,
byte_at, explode, strtr_array
- config/env: error_reporting, ini_get, date_default_timezone_*,
server_get/server_contains_key, php_uname("s")
- IO: turn PhpResource into an enum (Stdin/Stdout/Stderr/File) and
implement fwrite/fflush/stream_isatty/php_fopen resource helpers
- shutdown/exit: register_shutdown_function + run_shutdown_functions,
exit, error_get_last
- preg_match_all_offset_capture via the regex crate; the formatter
pattern drops PCRE possessive quantifiers (original kept in a
comment with a TODO)
proc_open reports unavailable for now (TODO(phase-c)); terminal-size
and tty detection fall back to defaults. sprintf calls on this path
are rewritten with format!(). OutputFormatterStyleInterface gains
clone_box to return shared styles.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
|
|
|
The server_argv() shim merely wrapped command-line arguments, so call
std::env::args() directly at each use site and drop the unused shim.
|
|
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
|
The Compiler.php is PHP-tooling only (bin/compile) with no Rust
equivalent, so it is not ported. Remove the compiler module along with
the symbols used solely by it.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
|
|
|
* Catch specific exception types instead of broad/placeholder handling.
* Drop the shim Countable trait.
|
|
Introduce shim functions and constants, replacing the ad-hoc chrono
format strings and parse helpers used as phase-b placeholders.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|