aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe/src/io
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-06-25 15:24:55 +0900
committernsfisis <nsfisis@gmail.com>2026-06-26 00:20:05 +0900
commitd4cdccb8de8758bd46a12283f8df90e020327b99 (patch)
treecd7c928cff2615a0bd599cf1f9e09c9852c399d7 /crates/shirabe/src/io
parent8117e5450693d19726da877bce8aacf5c7aa53af (diff)
downloadphp-shirabe-d4cdccb8de8758bd46a12283f8df90e020327b99.tar.gz
php-shirabe-d4cdccb8de8758bd46a12283f8df90e020327b99.tar.zst
php-shirabe-d4cdccb8de8758bd46a12283f8df90e020327b99.zip
test: port 70 perforce/repository/downloader/installer/dispatcher tests
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>
Diffstat (limited to 'crates/shirabe/src/io')
-rw-r--r--crates/shirabe/src/io/buffer_io.rs64
1 files changed, 41 insertions, 23 deletions
diff --git a/crates/shirabe/src/io/buffer_io.rs b/crates/shirabe/src/io/buffer_io.rs
index 16b97e4..75de4c7 100644
--- a/crates/shirabe/src/io/buffer_io.rs
+++ b/crates/shirabe/src/io/buffer_io.rs
@@ -67,31 +67,49 @@ impl BufferIO {
let output = stream_get_contents(stream).unwrap_or_default();
- Preg::replace_callback(
- r"{(?<=^|\n|\x08)(.+?)(\x08+)}",
- |matches: &indexmap::IndexMap<
- shirabe_external_packages::composer::pcre::CaptureKey,
- String,
- >|
- -> String {
- let empty = String::new();
- let g1 = matches
- .get(&shirabe_external_packages::composer::pcre::CaptureKey::ByIndex(1))
- .unwrap_or(&empty);
- let g2 = matches
- .get(&shirabe_external_packages::composer::pcre::CaptureKey::ByIndex(2))
- .unwrap_or(&empty);
- let pre = strip_tags(g1);
+ // Regex pattern compatibility:
+ // PHP uses `{(?<=^|\n|\x08)(.+?)(\x08+)}` to collapse backspace-overwritten spans (e.g.
+ // progress bars). The `regex` crate has no look-behind, so the `(?<=^|\n|\x08)` anchor is
+ // turned into a consuming optional leading group `(^|\n|\x08)` that is re-emitted in the
+ // replacement. Because PCRE's look-behind is zero-width, a `\x08` ending one match can also
+ // anchor the following match; consuming-and-restoring would break that chaining in a single
+ // pass, so the replacement is applied to a fixpoint (each pass strictly shrinks the string).
+ let mut output = output;
+ loop {
+ let next = Preg::replace_callback(
+ r"{(^|\n|\x08)(.+?)(\x08+)}",
+ |matches: &indexmap::IndexMap<
+ shirabe_external_packages::composer::pcre::CaptureKey,
+ String,
+ >|
+ -> String {
+ let empty = String::new();
+ let g1 = matches
+ .get(&shirabe_external_packages::composer::pcre::CaptureKey::ByIndex(1))
+ .unwrap_or(&empty);
+ let g2 = matches
+ .get(&shirabe_external_packages::composer::pcre::CaptureKey::ByIndex(2))
+ .unwrap_or(&empty);
+ let g3 = matches
+ .get(&shirabe_external_packages::composer::pcre::CaptureKey::ByIndex(3))
+ .unwrap_or(&empty);
+ let pre = strip_tags(g2);
- if pre.len() == g2.len() {
- return String::new();
- }
+ if pre.len() == g3.len() {
+ return g1.clone();
+ }
- // TODO reverse parse the string, skipping span tags and \033\[([0-9;]+)m(.*?)\033\[0m style blobs
- format!("{}\n", g1.trim_end())
- },
- &output,
- )
+ // TODO reverse parse the string, skipping span tags and \033\[([0-9;]+)m(.*?)\033\[0m style blobs
+ format!("{}{}\n", g1, g2.trim_end())
+ },
+ &output,
+ );
+ if next == output {
+ break;
+ }
+ output = next;
+ }
+ output
}
pub fn set_user_inputs(&mut self, inputs: Vec<String>) -> Result<()> {