1 | import {cached, defineAssoc} from "./decorators.js";
|
2 | import {lib, Collection, RallyBase} from "./rally-tools.js";
|
3 |
|
4 | export async function findLineInFile(renderedPreset, lineNumber){
|
5 | let trueFileLine = lineNumber;
|
6 |
|
7 | let linedRenderedPreset = renderedPreset.split("\n").slice(2,-2);
|
8 | renderedPreset = renderedPreset.split("\n").slice(2,-2).join("\n");
|
9 | let includeLocation = renderedPreset.split("\n").filter(x => x.includes("@include"));
|
10 |
|
11 | let endIncludeNumber = -1, addTabDepth = 2;
|
12 | let lineBeforeIncludeStatement = '';
|
13 | let withinInclude = true;
|
14 |
|
15 | if (lineNumber > linedRenderedPreset.indexOf(includeLocation[includeLocation.length -1])){
|
16 | addTabDepth = 0;
|
17 | withinInclude = false;
|
18 | }
|
19 |
|
20 | for (let index = includeLocation.length - 1; index >= 0; index--){
|
21 | let currIncludeIndex = linedRenderedPreset.indexOf(includeLocation[index]);
|
22 | let tabDepth = includeLocation[index].split(" ").length;
|
23 | if (lineNumber > currIncludeIndex) {
|
24 | if (includeLocation[index].split(" ").filter(Boolean)[1] != "ERROR:"){
|
25 | if (lineBeforeIncludeStatement.split(" ").length == tabDepth && withinInclude){
|
26 | trueFileLine = trueFileLine - currIncludeIndex;
|
27 | break;
|
28 | } else if ((lineBeforeIncludeStatement.split(" ").length + addTabDepth) == tabDepth && endIncludeNumber == -1){
|
29 | endIncludeNumber = currIncludeIndex;
|
30 | } else if ((lineBeforeIncludeStatement.split(" ").length + addTabDepth) == tabDepth){
|
31 | trueFileLine = trueFileLine - (endIncludeNumber - currIncludeIndex);
|
32 | endIncludeNumber = -1;
|
33 | }
|
34 | }
|
35 | } else {
|
36 | lineBeforeIncludeStatement = includeLocation[index];
|
37 | }
|
38 | }
|
39 |
|
40 | let funcLine = ""
|
41 | for(let line of linedRenderedPreset.slice(0, lineNumber).reverse()){
|
42 | let match = /def (\w+)/.exec(line);
|
43 | if(match){
|
44 | funcLine = match[1];
|
45 | break;
|
46 | }
|
47 | }
|
48 |
|
49 | let includeFilename;
|
50 |
|
51 | if(lineBeforeIncludeStatement != ""){
|
52 | includeFilename = lineBeforeIncludeStatement.slice(1).trim().slice(14, -1)
|
53 | }else{
|
54 | includeFilename = null;
|
55 | }
|
56 |
|
57 | if(includeLocation.length !== 0){
|
58 | trueFileLine -= 1;
|
59 | lineNumber -= 1;
|
60 | }
|
61 |
|
62 | return {
|
63 | lineNumber: trueFileLine,
|
64 | includeFilename,
|
65 | line: linedRenderedPreset[lineNumber],
|
66 | funcLine,
|
67 | };
|
68 |
|
69 | }
|
70 |
|
71 | export function printOutLine(eLine){
|
72 | return log(chalk`{blue ${eLine.includeFilename || "Main"}}:{green ${eLine.lineNumber}} in ${eLine.funcLine}
|
73 | ${eLine.line}`)
|
74 | }
|
75 |
|
76 | export async function getInfo(env, jobid){
|
77 | log(env, jobid);
|
78 | let trace = lib.makeAPIRequest({
|
79 | env, path: `/jobs/${jobid}/artifacts/trace`,
|
80 | }).catch(x => null);
|
81 |
|
82 | let renderedPreset = lib.makeAPIRequest({
|
83 | env, path: `/jobs/${jobid}/artifacts/preset`,
|
84 | }).catch(x => null);
|
85 |
|
86 | let result = lib.makeAPIRequest({
|
87 | env, path: `/jobs/${jobid}/artifacts/result`,
|
88 | }).catch(x => null);
|
89 |
|
90 | let error = lib.makeAPIRequest({
|
91 | env, path: `/jobs/${jobid}/artifacts/error`,
|
92 | }).catch(x => null);
|
93 |
|
94 | let output = lib.makeAPIRequest({
|
95 | env, path: `/jobs/${jobid}/artifacts/output`,
|
96 | }).catch(x => null);
|
97 |
|
98 | [trace, renderedPreset, result, output, error] = await Promise.all([trace, renderedPreset, result, output, error]);
|
99 |
|
100 | return {trace, renderedPreset, result, output, error}
|
101 | }
|
102 |
|
103 | export async function parseTrace(env, jobid){
|
104 |
|
105 | let {trace, renderedPreset} = await getInfo(env, jobid);
|
106 |
|
107 | let fileName = '';
|
108 | let lineNumber = -1;
|
109 |
|
110 | let errorLines = []
|
111 | let shouldBreak = 0;
|
112 | for(let tr of trace.split("\n\n").reverse()){
|
113 | errorLines.push(tr);
|
114 | shouldBreak--;
|
115 | if(tr.includes("Exception")) shouldBreak = 1;
|
116 | if(tr.includes("raised")) shouldBreak = 1;
|
117 | if(!shouldBreak) break;
|
118 | }
|
119 |
|
120 | let errorList = [];
|
121 | for(let errLine of errorLines){
|
122 |
|
123 | lineNumber = /^[\w ]+:(\d+):/g.exec(errLine);
|
124 | if(lineNumber && lineNumber[1]){
|
125 | errorList.push(await findLineInFile(renderedPreset, lineNumber[1]));
|
126 | }else{
|
127 | errorList.push(errLine);
|
128 | }
|
129 | }
|
130 |
|
131 | return errorList;
|
132 | }
|
133 |
|
134 | const Trace = {parseTrace, printOutLine, getInfo, findLineInFile};
|
135 | export default Trace;
|