Skip to content

Commit 8a38db7

Browse files
committed
Remove unused code
1 parent b781fe3 commit 8a38db7

File tree

1 file changed

+1
-331
lines changed

1 file changed

+1
-331
lines changed

src/logs/parser.ts

Lines changed: 1 addition & 331 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,15 @@
22
// From azure pipelines UI.
33
// Class names have been changed to work with Primer styles
44
// Source: https://github.com/microsoft/azure-devops-ui/blob/22b5ae5969d405f4459caf9b020019e95bbded38/packages/azure-pipelines-ui/src/Utilities/Parser.ts#L1
5-
import {ILine, IParseNode, IParsedFindResult, NodeType} from './parserTypes'
6-
import {TemplateResult, html} from 'lit-html/lit-html'
5+
import { IParseNode } from './parserTypes'
76

87
// #region ANSII section
98

109
const ESC = '\u001b'
11-
const TimestampLength = 29
12-
const TimestampRegex = /^.{27}Z /gm
1310
const BrightClassPostfix = '-br'
1411

1512
// match characters that could be enclosing url to cleanly handle url formatting
1613
export const URLRegex = /([{([]*https?:\/\/[a-z0-9]+(?:-[a-z0-9]+)*\.[^\s<>|'",]{2,})/gi
17-
// URLs in logs can be wrapped in punctuation to assist with parsing
18-
const URLPunctuation = {
19-
'(': ')',
20-
'[': ']',
21-
'{': '}'
22-
}
23-
type URLStartPunctuation = keyof typeof URLPunctuation
24-
type URLEndPunctuation = typeof URLPunctuation[URLStartPunctuation]
25-
const matchingURLPunctuation = (ch: string): URLEndPunctuation => URLPunctuation[ch as URLStartPunctuation]
26-
const regexpEscape = (ch: string) => `\\${ch}`
2714

2815
/**
2916
* Regex for matching ANSII escape codes
@@ -148,20 +135,6 @@ const END_GROUP = 'endgroup'
148135
const ICON = 'icon'
149136
const NOTICE = 'notice'
150137

151-
const commandToType: {[command: string]: NodeType} = {
152-
command: NodeType.Command,
153-
debug: NodeType.Debug,
154-
error: NodeType.Error,
155-
info: NodeType.Info,
156-
section: NodeType.Section,
157-
verbose: NodeType.Verbose,
158-
warning: NodeType.Warning,
159-
notice: NodeType.Notice,
160-
group: NodeType.Group,
161-
endgroup: NodeType.EndGroup,
162-
icon: NodeType.Icon
163-
}
164-
165138
const typeToCommand: {[type: string]: string} = {
166139
'0': PLAIN,
167140
'1': COMMAND,
@@ -177,10 +150,6 @@ const typeToCommand: {[type: string]: string} = {
177150
'11': NOTICE
178151
}
179152

180-
// Store the max command length we support, for example, we support "section", "command" which are of length 7, which highest of all others
181-
const maxCommandLength = 8
182-
const supportedCommands = [COMMAND, DEBUG, ERROR, INFO, SECTION, VERBOSE, WARNING, GROUP, END_GROUP, ICON, NOTICE]
183-
184153
export function getType(node: IParseNode) {
185154
return typeToCommand[node.type]
186155
}
@@ -213,310 +182,11 @@ interface IAnsiEscapeCodeState {
213182
style?: IStyle
214183
}
215184

216-
enum CharacterType {
217-
Standard,
218-
Search,
219-
EOL
220-
}
221185

222186
// Set max to prevent any perf degradations
223187
export const maxLineMatchesToParse = 100
224188

225-
const maxMatches = 50
226-
const unsetValue = -1
227-
const newLineChar = '\n'
228-
const hashChar = '#'
229-
const commandStart = '['
230-
const commandEnd = ']'
231-
232189
export class Parser {
233-
/**
234-
* Converts the content to HTML with appropriate styles, escapes content to prevent XSS
235-
* @param content
236-
*/
237-
public parse(content: string): TemplateResult {
238-
let result = html``
239-
const states = this.getStates(content)
240-
for (const x of states) {
241-
const classNames: string[] = []
242-
const styles: string[] = []
243-
const currentText = x.output
244-
if (x.style) {
245-
const fg = x.style.fg
246-
const bg = x.style.bg
247-
const isFgRGB = x.style.isFgRGB
248-
const isBgRGB = x.style.isBgRGB
249-
if (fg && !isFgRGB) {
250-
classNames.push(`ansifg-${fg}`)
251-
}
252-
if (bg && !isBgRGB) {
253-
classNames.push(`ansibg-${bg}`)
254-
classNames.push(`d-inline-flex`)
255-
}
256-
if (fg && isFgRGB) {
257-
styles.push(`color:rgb(${fg})`)
258-
}
259-
if (bg && isBgRGB) {
260-
styles.push(`background-color:rgb(${bg})`)
261-
classNames.push(`d-inline-flex`)
262-
}
263-
if (x.style.bold) {
264-
classNames.push('text-bold')
265-
}
266-
if (x.style.italic) {
267-
classNames.push('text-italic')
268-
}
269-
if (x.style.underline) {
270-
classNames.push('text-underline')
271-
}
272-
}
273-
274-
let output
275-
const parseResult = Array(currentText.length).fill(CharacterType.Standard)
276-
277-
result = html`${result}<span class="${classNames.join(' ')}" style="${styles.join(';')}">${output}</span>`
278-
}
279-
280-
return result
281-
}
282-
283-
/**
284-
* Parses the content into lines with nodes
285-
* @param content content to parse
286-
*/
287-
public parseLines(content: string): ILine[] {
288-
// lines we return
289-
const lines: ILine[] = []
290-
// accumulated nodes for a particular line
291-
let nodes: IParseNode[] = []
292-
293-
// start of a particular line
294-
let lineStartIndex = 0
295-
// start of plain node content
296-
let plainNodeStart = unsetValue
297-
298-
// tells to consider the default logic where we check for plain text etc.,
299-
let considerDefaultLogic = true
300-
301-
// stores the command, to match one of the 'supportedCommands'
302-
let currentCommand = ''
303-
// helps in finding commands in our format "##[command]" or "[command]"
304-
let commandSeeker = ''
305-
306-
// when line ends, this tells if there's any pending node
307-
let pendingLastNode: number = unsetValue
308-
309-
const resetCommandVar = () => {
310-
commandSeeker = ''
311-
currentCommand = ''
312-
}
313-
314-
const resetPlain = () => {
315-
plainNodeStart = unsetValue
316-
}
317-
318-
const resetPending = () => {
319-
pendingLastNode = unsetValue
320-
}
321-
322-
const parseCommandEnd = () => {
323-
// possible continuation of our well-known commands
324-
const commandIndex = supportedCommands.indexOf(currentCommand)
325-
if (commandIndex !== -1) {
326-
considerDefaultLogic = false
327-
// we reached the end and found the command
328-
resetPlain()
329-
// command is for the whole line, so we are not pushing the node here but defering this to when we find the new line
330-
pendingLastNode = commandToType[currentCommand]
331-
332-
if (
333-
currentCommand === SECTION ||
334-
currentCommand === GROUP ||
335-
currentCommand === END_GROUP ||
336-
currentCommand === COMMAND ||
337-
currentCommand === ERROR ||
338-
currentCommand === WARNING ||
339-
currentCommand === NOTICE
340-
) {
341-
// strip off ##[$(currentCommand)] if there are no timestamps at start
342-
const possibleTimestamp = content.substring(lineStartIndex, lineStartIndex + TimestampLength) || ''
343-
if (!possibleTimestamp.match(TimestampRegex)) {
344-
// Replace command only if it's found at the beginning of the line
345-
if (possibleTimestamp.indexOf(currentCommand) < 4) {
346-
// ## is optional, so pick the right offset
347-
const offset = content.substring(lineStartIndex, lineStartIndex + 2) === '##' ? 4 : 2
348-
lineStartIndex = lineStartIndex + offset + currentCommand.length
349-
}
350-
}
351-
}
352-
353-
if (currentCommand === GROUP) {
354-
groupStarted = true
355-
}
356-
357-
// group logic- happyCase1: we found endGroup and there's already a group starting
358-
if (currentCommand === END_GROUP && currentGroupNode) {
359-
groupEnded = true
360-
}
361-
}
362-
363-
resetCommandVar()
364-
}
365-
366-
let groupStarted = false
367-
let groupEnded = false
368-
let currentGroupNode: IParseNode | undefined
369-
let nodeIndex = 0
370-
let groupCount = 0
371-
372-
for (let index = 0; index < content.length; index++) {
373-
const char = content.charAt(index)
374-
// start with considering default logic, individual conditions are responsible to set it false
375-
considerDefaultLogic = true
376-
if (char === newLineChar || index === content.length - 1) {
377-
if (char === commandEnd) {
378-
parseCommandEnd()
379-
}
380-
381-
const node = {
382-
type: pendingLastNode,
383-
start: lineStartIndex,
384-
end: index,
385-
lineIndex: lines.length,
386-
groupCount
387-
} as IParseNode
388-
389-
let pushNode = false
390-
// end of the line/text, push any final nodes
391-
if (pendingLastNode !== NodeType.Plain) {
392-
// there's pending special node to be pushed
393-
pushNode = true
394-
// a new group has just started
395-
if (groupStarted) {
396-
currentGroupNode = node
397-
groupStarted = false
398-
}
399-
400-
// a group has ended
401-
if (groupEnded && currentGroupNode) {
402-
// links to specifc lines in the UI need to match exactly what was provided by the runner for things like annotations so nodes can't be discarded
403-
// lineIndexes are further adjusted based on the number of groups to ensure consistent and continuout numbering of lines in the UI
404-
pushNode = true
405-
node.group = {
406-
lineIndex: currentGroupNode.lineIndex - 1,
407-
nodeIndex: currentGroupNode.index
408-
}
409-
node.groupCount = groupCount
410-
currentGroupNode.isGroup = true
411-
412-
// since group has ended, clear all of our pointers
413-
groupEnded = false
414-
currentGroupNode = undefined
415-
groupCount++
416-
}
417-
} else if (pendingLastNode === NodeType.Plain) {
418-
// there's pending plain node to be pushed
419-
pushNode = true
420-
}
421-
422-
if (pushNode) {
423-
node.index = nodeIndex++
424-
nodes.push(node)
425-
}
426-
427-
// A group is pending
428-
if (currentGroupNode && node !== currentGroupNode) {
429-
node.group = {
430-
lineIndex: currentGroupNode.lineIndex,
431-
nodeIndex: currentGroupNode.index
432-
}
433-
}
434-
435-
// end of the line, push all nodes that are accumulated till now
436-
if (nodes.length > 0) {
437-
lines.push({nodes})
438-
}
439-
440-
// clear node as we are done with the line
441-
nodes = []
442-
// increment lineStart for the next line
443-
lineStartIndex = index + 1
444-
// unset
445-
resetPlain()
446-
resetPending()
447-
resetCommandVar()
448-
449-
considerDefaultLogic = false
450-
} else if (char === hashChar) {
451-
// possible start of our well-known commands
452-
if (commandSeeker === '' || commandSeeker === '#') {
453-
considerDefaultLogic = false
454-
commandSeeker += hashChar
455-
}
456-
} else if (char === commandStart) {
457-
// possible continuation of our well-known commands
458-
if (commandSeeker === '##') {
459-
considerDefaultLogic = false
460-
commandSeeker += commandStart
461-
} else if (commandSeeker.length === 0) {
462-
// covers - "", for live logs, commands will be of [section], with out "##"
463-
considerDefaultLogic = false
464-
commandSeeker += commandStart
465-
}
466-
} else if (char === commandEnd) {
467-
if (currentCommand === ICON) {
468-
const startIndex = index + 1
469-
let endIndex = startIndex
470-
for (let i = startIndex; i < content.length; i++) {
471-
const iconChar = content[i]
472-
if (iconChar === ' ') {
473-
endIndex = i
474-
break
475-
}
476-
}
477-
nodes.push({
478-
type: NodeType.Icon,
479-
lineIndex: lines.length,
480-
start: startIndex,
481-
end: endIndex,
482-
index: nodeIndex++,
483-
groupCount
484-
})
485-
// jump to post Icon content
486-
index = endIndex + 1
487-
lineStartIndex = index
488-
continue
489-
} else {
490-
parseCommandEnd()
491-
}
492-
}
493-
494-
if (considerDefaultLogic) {
495-
if (commandSeeker === '##[' || commandSeeker === '[') {
496-
// it's possible that we are parsing a command
497-
currentCommand += char.toLowerCase()
498-
}
499-
500-
if (currentCommand.length > maxCommandLength) {
501-
// to avoid accumulating command unncessarily, let's check max length, if it exceeds, it's not a command
502-
resetCommandVar()
503-
}
504-
505-
// considering as plain text
506-
if (plainNodeStart === unsetValue) {
507-
// we didn't set this yet, set now
508-
plainNodeStart = lineStartIndex
509-
// set pending node if there isn't one pending
510-
if (pendingLastNode === unsetValue) {
511-
pendingLastNode = NodeType.Plain
512-
}
513-
}
514-
}
515-
}
516-
517-
return lines
518-
}
519-
520190
/**
521191
* Parses the content into ANSII states
522192
* @param content content to parse

0 commit comments

Comments
 (0)