Sfoglia il codice sorgente

info stream

GitOrigin-RevId: 5d4cb01c250768ca00e15368b9c616b467e4f9ba
Domagoj Kriskovic 3 mesi fa
parent
commit
09af91a936

+ 1 - 1
services/web/frontend/js/features/ide-react/components/editor/python/pyodide-worker-client.ts

@@ -5,7 +5,7 @@ import type {
 } from './pyodide-worker-messages'
 } from './pyodide-worker-messages'
 
 
 export type OutputCallback = (
 export type OutputCallback = (
-  stream: 'stdout' | 'stderr',
+  stream: 'stdout' | 'stderr' | 'info',
   line: string,
   line: string,
   fileId: string,
   fileId: string,
   executionId: string
   executionId: string

+ 1 - 1
services/web/frontend/js/features/ide-react/components/editor/python/pyodide-worker-messages.ts

@@ -28,7 +28,7 @@ export type LoadingFailedEvent = { type: 'loading-failed'; error: string }
 
 
 export type OutputLineEvent = {
 export type OutputLineEvent = {
   type: 'output-line'
   type: 'output-line'
-  stream: 'stdout' | 'stderr'
+  stream: 'stdout' | 'stderr' | 'info'
   line: string
   line: string
   fileId: string
   fileId: string
   executionId: string
   executionId: string

+ 6 - 3
services/web/frontend/js/features/ide-react/components/editor/python/python-output-pane.tsx

@@ -74,9 +74,12 @@ export default function PythonOutputPane() {
         {error && (
         {error && (
           <div className="ide-redesign-python-output-pane-error">{error}</div>
           <div className="ide-redesign-python-output-pane-error">{error}</div>
         )}
         )}
-        {output.map((line, index) => (
-          <div className="ide-redesign-python-output-pane-line" key={index}>
-            {line}
+        {output.map((entry, index) => (
+          <div
+            className={`ide-redesign-python-output-pane-line ide-redesign-python-output-pane-line-${entry.stream}`}
+            key={index}
+          >
+            {entry.line}
           </div>
           </div>
         ))}
         ))}
       </div>
       </div>

+ 19 - 6
services/web/frontend/js/features/ide-react/components/editor/python/python-runner.ts

@@ -21,8 +21,13 @@ export type ExecutionContext = {
 
 
 type Listener = () => void
 type Listener = () => void
 
 
+export type OutputLine = {
+  stream: 'stdout' | 'stderr' | 'info'
+  line: string
+}
+
 export type PythonRunnerState = {
 export type PythonRunnerState = {
-  output: string[]
+  output: OutputLine[]
   status: ExecutionStatus
   status: ExecutionStatus
   error: string | null
   error: string | null
 }
 }
@@ -116,11 +121,13 @@ export class PythonRunner {
             this.updateState({ status: 'finished' })
             this.updateState({ status: 'finished' })
         }
         }
       },
       },
-      onOutput: (_stream, line, fileId, executionId) => {
+      onOutput: (stream, line, fileId, executionId) => {
         if (fileId !== this.fileId || this.activeExecutionId !== executionId) {
         if (fileId !== this.fileId || this.activeExecutionId !== executionId) {
           return
           return
         }
         }
-        this.updateState({ output: appendCapped(this.state.output, line) })
+        this.updateState({
+          output: appendCapped(this.state.output, { stream, line }),
+        })
       },
       },
     })
     })
   }
   }
@@ -185,7 +192,10 @@ export class PythonRunner {
       status: 'loading',
       status: 'loading',
       output:
       output:
         this.state.status === 'running'
         this.state.status === 'running'
-          ? appendCapped(this.state.output, 'Execution interrupted')
+          ? appendCapped(this.state.output, {
+              stream: 'info',
+              line: 'Execution interrupted',
+            })
           : this.state.output,
           : this.state.output,
     })
     })
   }
   }
@@ -198,8 +208,11 @@ export class PythonRunner {
   }
   }
 }
 }
 
 
-function appendCapped(existing: string[], line: string): string[] {
-  const updated = [...existing, line]
+function appendCapped(
+  existing: OutputLine[],
+  entry: OutputLine
+): OutputLine[] {
+  const updated = [...existing, entry]
   return updated.length > MAX_OUTPUT_LINES
   return updated.length > MAX_OUTPUT_LINES
     ? updated.slice(-MAX_OUTPUT_LINES)
     ? updated.slice(-MAX_OUTPUT_LINES)
     : updated
     : updated

+ 8 - 0
services/web/frontend/stylesheets/pages/editor/ide-redesign.scss

@@ -92,6 +92,14 @@
   word-break: break-word;
   word-break: break-word;
 }
 }
 
 
+.ide-redesign-python-output-pane-line-info {
+  color: var(--content-secondary);
+}
+
+.ide-redesign-python-output-pane-line-stderr {
+  color: var(--red-50);
+}
+
 .ide-redesign-python-output-pane-placeholder,
 .ide-redesign-python-output-pane-placeholder,
 .ide-redesign-python-output-pane-error {
 .ide-redesign-python-output-pane-error {
   white-space: pre-wrap;
   white-space: pre-wrap;

+ 11 - 6
services/web/test/frontend/features/ide-react/unit/editor/python-runner.spec.ts

@@ -135,7 +135,9 @@ describe('PythonRunner', function () {
         executionId: runMsg.executionId,
         executionId: runMsg.executionId,
         outputs: [],
         outputs: [],
       })
       })
-      expect(runner.getState().output).to.deep.equal(['first run output'])
+      expect(runner.getState().output).to.deep.equal([
+        { stream: 'stdout', line: 'first run output' },
+      ])
 
 
       await runner.run()
       await runner.run()
       expect(runner.getState().output).to.deep.equal([])
       expect(runner.getState().output).to.deep.equal([])
@@ -193,7 +195,10 @@ describe('PythonRunner', function () {
         executionId: runMsg.executionId,
         executionId: runMsg.executionId,
       })
       })
 
 
-      expect(runner.getState().output).to.deep.equal(['line 1', 'line 2'])
+      expect(runner.getState().output).to.deep.equal([
+        { stream: 'stdout', line: 'line 1' },
+        { stream: 'stderr', line: 'line 2' },
+      ])
     })
     })
 
 
     it('ignores output for a different fileId', async function () {
     it('ignores output for a different fileId', async function () {
@@ -250,8 +255,8 @@ describe('PythonRunner', function () {
 
 
       const output = runner.getState().output
       const output = runner.getState().output
       expect(output).to.have.length(100)
       expect(output).to.have.length(100)
-      expect(output[0]).to.equal('line 10')
-      expect(output[99]).to.equal('line 109')
+      expect(output[0]).to.deep.equal({ stream: 'stdout', line: 'line 10' })
+      expect(output[99]).to.deep.equal({ stream: 'stdout', line: 'line 109' })
     })
     })
   })
   })
 
 
@@ -274,8 +279,8 @@ describe('PythonRunner', function () {
 
 
       expect(runner.getState().status).to.equal('loading')
       expect(runner.getState().status).to.equal('loading')
       expect(runner.getState().output).to.deep.equal([
       expect(runner.getState().output).to.deep.equal([
-        'partial output',
-        'Execution interrupted',
+        { stream: 'stdout', line: 'partial output' },
+        { stream: 'info', line: 'Execution interrupted' },
       ])
       ])
     })
     })