Ver Fonte

fix(tauri-utils): include `\n` in `io::read_line`, closes #6388 (#6519)

Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
fix(tauri-utils): include `\n` in `io::read_line`, closes #6388
Amr Bashir há 2 anos atrás
pai
commit
a6b52e44f2

+ 5 - 0
.changes/tauri-utils-read-line.md

@@ -0,0 +1,5 @@
+---
+'tauri-utils': 'patch:bug'
+---
+
+Fix `io::read_line` not including the new line character `\n`.

+ 2 - 4
core/tauri-utils/src/io.rs

@@ -6,7 +6,7 @@
 
 use std::io::BufRead;
 
-/// Read a line breaking in both \n and \r.
+/// Read all bytes until a newline (the `0xA` byte) or a carriage return (`\r`) is reached, and append them to the provided buffer.
 ///
 /// Adapted from <https://doc.rust-lang.org/std/io/trait.BufRead.html#method.read_line>.
 pub fn read_line<R: BufRead + ?Sized>(r: &mut R, buf: &mut Vec<u8>) -> std::io::Result<usize> {
@@ -16,6 +16,7 @@ pub fn read_line<R: BufRead + ?Sized>(r: &mut R, buf: &mut Vec<u8>) -> std::io::
       let available = match r.fill_buf() {
         Ok(n) => n,
         Err(ref e) if e.kind() == std::io::ErrorKind::Interrupted => continue,
+
         Err(e) => return Err(e),
       };
       match memchr::memchr(b'\n', available) {
@@ -40,9 +41,6 @@ pub fn read_line<R: BufRead + ?Sized>(r: &mut R, buf: &mut Vec<u8>) -> std::io::
     r.consume(used);
     read += used;
     if done || used == 0 {
-      if buf.ends_with(&[b'\n']) {
-        buf.pop();
-      }
       return Ok(read);
     }
   }

+ 1 - 1
core/tauri/src/api/process/command.rs

@@ -468,7 +468,7 @@ mod test {
             assert_eq!(payload.code, Some(1));
           }
           CommandEvent::Stderr(line) => {
-            assert_eq!(line, "cat: test/api/: Is a directory".to_string());
+            assert_eq!(line, "cat: test/api/: Is a directory\n".to_string());
           }
           _ => {}
         }

Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 0
examples/api/dist/assets/index.js


+ 29 - 4
examples/api/src/views/Shell.svelte

@@ -13,6 +13,7 @@
   let encoding = ''
   let stdin = ''
   let child
+  let output = []
 
   function _getEnv() {
     return env.split(' ').reduce((env, clause) => {
@@ -26,10 +27,11 @@
 
   function spawn() {
     child = null
+    output = []
     const command = new Command(cmd, [...args, script], {
       cwd: cwd || null,
       env: _getEnv(),
-      encoding,
+      encoding: encoding || null
     })
 
     command.on('close', (data) => {
@@ -40,8 +42,23 @@
     })
     command.on('error', (error) => onMessage(`command error: "${error}"`))
 
-    command.stdout.on('data', (line) => onMessage(`command stdout: "${line}"`))
-    command.stderr.on('data', (line) => onMessage(`command stderr: "${line}"`))
+    function onOutput(line, kind) {
+      onMessage(`command ${kind}: "${line}"`)
+
+      if (line.endsWith('\n')) {
+        line = line.substring(0, line.length - 1)
+      }
+
+      const last = output[output.length - 1]
+      if (last && last.endsWith('\r')) {
+        output = [...output.slice(0, output.length - 1), line]
+      } else {
+        output = [...output, line]
+      }
+    }
+
+    command.stdout.on('data', (line) => onOutput(line, 'stdout'))
+    command.stderr.on('data', (line) => onOutput(line, 'stderr'))
 
     command
       .spawn()
@@ -90,11 +107,19 @@
   </div>
   <div class="flex children:grow gap-1">
     <button class="btn" on:click={spawn}>Run</button>
-    <button class="btn" on:click={kill}>Kill</button>
+    {#if child}
+      <button class="btn" on:click={kill}>Kill</button>
+    {/if}
   </div>
   {#if child}
     <br />
     <input class="input" placeholder="write to stdin" bind:value={stdin} />
     <button class="btn" on:click={writeToStdin}>Write</button>
   {/if}
+
+  <div>
+    {#each output as l}
+      <p>{l}</p>
+    {/each}
+  </div>
 </div>

Alguns ficheiros não foram mostrados porque muitos ficheiros mudaram neste diff