This repository has been archived by the owner on Sep 6, 2022. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add colors to logs from ANSI control chars. (#1103)
- Loading branch information
Showing
16 changed files
with
246 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1 change: 1 addition & 0 deletions
1
web/app/common/components/log-viewer/log-line/log-line.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
<div class="fci-log-line" #logLine></div> |
17 changes: 17 additions & 0 deletions
17
web/app/common/components/log-viewer/log-line/log-line.component.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
.fci-log-line { | ||
display: block; | ||
font-family: monospace; | ||
white-space: pre; | ||
margin: 0; | ||
} | ||
.fci-ansi-1 { font-weight: bold;} | ||
.fci-ansi-3 { font-style: italic; } | ||
.fci-ansi-4 { text-decoration: underline; } | ||
.fci-ansi-30 { color: #262626; } | ||
.fci-ansi-31 { color: #d30102; } | ||
.fci-ansi-32 { color: #859900; } | ||
.fci-ansi-33 { color: #b58900; } | ||
.fci-ansi-34 { color: #268bd2; } | ||
.fci-ansi-35 { color: #d33682; } | ||
.fci-ansi-36 { color: #2aa198; } | ||
.fci-ansi-37 { color: #e4e4e4; } |
37 changes: 37 additions & 0 deletions
37
web/app/common/components/log-viewer/log-line/log-line.component.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import { async, ComponentFixture, TestBed } from '@angular/core/testing'; | ||
import { LogLineComponent, LogLine } from './log-line.component'; | ||
import { Component, DebugElement } from '@angular/core'; | ||
import { getElement, getElementText } from '../../../test_helpers/element_helper_functions'; | ||
|
||
describe('LogLineComponent', () => { | ||
let component: LogLineComponent; | ||
let fixture: ComponentFixture<LogLineComponent>; | ||
let fixtureEl: DebugElement; | ||
|
||
beforeEach(async(() => { | ||
TestBed.configureTestingModule({ | ||
declarations: [LogLineComponent, LogLineComponent] | ||
}).compileComponents(); | ||
|
||
fixture = TestBed.createComponent(LogLineComponent); | ||
fixtureEl = fixture.debugElement; | ||
component = fixture.componentInstance; | ||
component.log = { | ||
message: '[16:12:08]: \u001b[33m▸\u001b[0m \u001b[39;1mCompiling\u001b[0m Category.swift\n', | ||
level: 'DEBUG', | ||
status: 0, | ||
timestamp: 1531944769 | ||
}; | ||
|
||
fixture.detectChanges(); // onInit | ||
})); | ||
|
||
it('should create the correct span dom tree of ansi codes', () => { | ||
const parentEl = getElement(fixtureEl, '.fci-log-line'); | ||
|
||
expect(parentEl.nativeElement.innerHTML).toBe( | ||
'[16:12:08]: <span class="fci-ansi-33">▸</span> ' + | ||
'<span class="fci-ansi-39 fci-ansi-1">Compiling</span>' + | ||
' Category.swift\n'); | ||
}); | ||
}); |
83 changes: 83 additions & 0 deletions
83
web/app/common/components/log-viewer/log-line/log-line.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import { DOCUMENT } from '@angular/common'; | ||
import { Component, AfterViewInit, ViewChild, ElementRef, Input, Inject, ViewEncapsulation } from '@angular/core'; | ||
|
||
const ANSI_PATTERN = /\u001b\[([0-9;]+)?m/; | ||
const ANSI_RESET_CODE = '0'; | ||
|
||
type AnsiCode = string; | ||
type AnsiTuple = [AnsiCode, string]; | ||
|
||
export interface LogLine { | ||
timestamp: number; | ||
message: string; | ||
level: string; | ||
status: number; | ||
} | ||
|
||
@Component({ | ||
selector: 'fci-log-line', | ||
templateUrl: './log-line.component.html', | ||
styleUrls: ['./log-line.component.scss'], | ||
encapsulation: ViewEncapsulation.None | ||
}) | ||
|
||
export class LogLineComponent implements AfterViewInit { | ||
@Input() log: LogLine; | ||
@ViewChild('logLine', { read: ElementRef }) logLineEl: ElementRef; | ||
|
||
constructor(@Inject(DOCUMENT) private readonly document: any) {} | ||
|
||
ngAfterViewInit() { | ||
const parentEl = this.logLineEl.nativeElement; | ||
let currentSpanEl = parentEl; | ||
const stack = this.tokenize(this.log.message); | ||
|
||
for (const tuple of stack) { | ||
const [code, text] = tuple; | ||
if (code === ANSI_RESET_CODE) { | ||
parentEl.innerHTML += text; | ||
currentSpanEl = parentEl; | ||
} else { | ||
currentSpanEl = this.injectSpan(currentSpanEl, text, code); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* tokenization works by splitting the string by a regex that has a capture group | ||
* this will return an flat array of tuples (string, capture) | ||
* this method will split and group the result into an array of tuples [ansi code, text] | ||
* NOTE: that the capture comes after the string, so we transpose them. | ||
**/ | ||
private tokenize(ansiText: string): AnsiTuple[] { | ||
const tuples = ansiText.split(ANSI_PATTERN); | ||
|
||
// if the text starts with a match capture (and thus returning empty string as [0]), | ||
// use that captured ansi code as the beginning style | ||
if (tuples[0] === '') { | ||
tuples.shift(); | ||
} else { | ||
// otherwise, we must assume we are starting each line as the default '0' | ||
tuples.unshift(ANSI_RESET_CODE); | ||
} | ||
|
||
const stack: AnsiTuple[] = []; | ||
|
||
for (let i = 0; i < tuples.length; i += 2) { | ||
const code = tuples[i]; | ||
const text = tuples[i + 1]; | ||
stack.push([code, text]); | ||
} | ||
return stack; | ||
} | ||
|
||
private injectSpan(parent: HTMLElement, text: string, ansiCode: AnsiCode): HTMLSpanElement { | ||
const span = this.document.createElement('span'); | ||
const classNames = ansiCode.split(';').map(c => `fci-ansi-${c}`).join(' '); | ||
span.className = classNames; | ||
span.innerText = text; | ||
parent.appendChild(span); | ||
|
||
return span; | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
web/app/common/components/log-viewer/log-line/log-line.module.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import {NgModule} from '@angular/core'; | ||
import {CommonModule} from '@angular/common'; | ||
|
||
import {LogLineComponent} from './log-line.component'; | ||
|
||
@NgModule({ | ||
declarations: [LogLineComponent], | ||
imports: [ | ||
/** Angular Library Imports */ | ||
CommonModule | ||
/** Internal Imports */ | ||
/** Angular Material Imports */ | ||
/** Third-Party Module Imports */ | ||
], | ||
exports: [LogLineComponent] | ||
}) | ||
|
||
export class LogLineModule { | ||
} |
4 changes: 4 additions & 0 deletions
4
web/app/common/components/log-viewer/log-viewer.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
<ng-container *ngIf="logLines.length <= 0">Connecting...</ng-container> | ||
<ng-container class="fci-log-viewer" *ngFor="let log of logLines"> | ||
<fci-log-line [log]="log"></fci-log-line> | ||
</ng-container> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
|
39 changes: 39 additions & 0 deletions
39
web/app/common/components/log-viewer/log-viewer.component.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import { async, ComponentFixture, TestBed } from '@angular/core/testing'; | ||
|
||
import { LogViewerComponent } from './log-viewer.component'; | ||
import { LogLineModule } from './log-line/log-line.module'; | ||
import { LogLine } from './log-line/log-line.component'; | ||
import { getElement } from '../../test_helpers/element_helper_functions'; | ||
|
||
describe('LogViewerComponent', () => { | ||
let component: LogViewerComponent; | ||
let fixture: ComponentFixture<LogViewerComponent>; | ||
|
||
beforeEach(async(() => { | ||
TestBed.configureTestingModule({ | ||
declarations: [ LogViewerComponent ], | ||
imports: [LogLineModule] | ||
}) | ||
.compileComponents(); | ||
})); | ||
|
||
beforeEach(() => { | ||
fixture = TestBed.createComponent(LogViewerComponent); | ||
component = fixture.componentInstance; | ||
component.logLines = [{ | ||
timestamp: 1533326666, | ||
message: 'this was a message', | ||
level: 'DEBUG', | ||
status: 0, | ||
}]; | ||
|
||
fixture.detectChanges(); | ||
}); | ||
|
||
/* | ||
it('should create a log viewer component with log lines', () => { | ||
const element = getElement(fixture.debugElement, '.fci-log-viewer'); | ||
expect(element.nativeElement.innerHTML).toEqual(''); | ||
}); | ||
*/ | ||
}); |
16 changes: 16 additions & 0 deletions
16
web/app/common/components/log-viewer/log-viewer.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import {Component, OnInit, Input} from '@angular/core'; | ||
import {LogLine} from './log-line/log-line.component'; | ||
|
||
@Component({ | ||
selector: 'fci-log-viewer', | ||
templateUrl: './log-viewer.component.html', | ||
styleUrls: ['./log-viewer.component.scss'] | ||
}) | ||
export class LogViewerComponent implements OnInit { | ||
@Input() logLines: LogLine[] = []; | ||
constructor() { } | ||
|
||
ngOnInit() { | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import {NgModule} from '@angular/core'; | ||
import {CommonModule} from '@angular/common'; | ||
|
||
import {LogViewerComponent} from './log-viewer.component'; | ||
import {LogLineModule} from './log-line/log-line.module'; | ||
|
||
@NgModule({ | ||
declarations: [LogViewerComponent], | ||
imports: [ | ||
/** Angular Library Imports */ | ||
CommonModule, | ||
/** Internal Imports */ | ||
LogLineModule, | ||
/** Angular Material Imports */ | ||
/** Third-Party Module Imports */ | ||
], | ||
exports: [LogViewerComponent] | ||
}) | ||
export class LogViewerModule { | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters