-
Notifications
You must be signed in to change notification settings - Fork 6
/
elixir.js
121 lines (112 loc) · 4.07 KB
/
elixir.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
'use babel';
import fs from 'fs';
export function provideBuilder() {
return class ElixirBuildProvider {
constructor(cwd) {
this.cwd = cwd;
}
getNiceName() {
return 'Elixir';
}
isEligible() {
return fs.existsSync(`${this.cwd}/mix.exs`);
}
settings() {
const exec = /^win/.test(process.platform) ? 'mix.bat' : 'mix';
const functionMatch = function (output) {
const errorRE1 = /^\*\* (\(.+\)) (.+):(\d+): (.+)$/; // e.g.: ** (AnError) my_file.ex:11: a description
const errorRE2 = /^\*\* (\(.+\) .+)$/; // e.g.: ** (AnError) A description
const warningRE = /warning: (.*)$/; // e.g.: warning: variable "arg1" is unused
const testRE = /^\s*\d+\) (.*)$/; // e.g.: 2) test the truth (UnitTest)
const locationRE1 = /^\s*\((.+)\)(.+):(\d+): .*$/; // e.g.: (MyProject) my_file.ex:9: (module)
const locationRE2 = /^\s*(.+):(\d+).*$/; // e.g.: my_file.ex:9: (module)
const ignoredProjects = ['elixir', 'stdlib'];
const messages = [];
let message = null;
const lines = output.split('\n');
lines.forEach(function (line) {
let match = null;
if ((match = line.match(errorRE1))) {
// found start of error message
message = {type: 'error', message: match[1] + ' ' + match[4], file: match[2], line: match[3]};
} else if ((match = line.match(errorRE2))) {
// found start of error message
message = {type: 'error', message: match[1]};
} else if ((match = line.match(warningRE))) {
// found start of warning message
message = {type: 'warning', message: match[1]};
} else if ((match = line.match(testRE))) {
// found start of unit test message
message = {type: 'error', message: match[1]};
} else if (message) {
// we found the start of a message on the prior line,
// look for multi-line messages and stack traces
if ((match = line.match(locationRE1))) {
// found a file:line location, ignore locations in system libs
if (ignoredProjects.indexOf(match[1]) < 0) {
message.file = match[2];
message.line = match[3];
}
} else if ((match = line.match(locationRE2))) {
// found a file:line location
message.file = match[1];
message.line = match[2];
} else if (line.startsWith(' ')) {
// found multi-line message
message.message += '\n' + line;
} else if (line === '') {
// found blank line
message.message += '\n';
} else {
// we didn't recoginize what is on the line,
// assume that we've read all of the current
// mesage
messages.push(message);
message = null;
}
}
});
if (message) {
messages.push(message);
}
messages.forEach(m => m.message = m.message.trim());
return messages;
};
return [ {
name: 'Elixir: mix compile',
exec: exec,
args: [ 'compile' ],
sh: false,
functionMatch: functionMatch
},
{
name: 'Elixir: mix compile --warnings-as-errors',
exec: exec,
args: [ 'compile', '--warnings-as-errors' ],
sh: false,
functionMatch: functionMatch
},
{
name: 'Elixir: mix test',
exec: exec,
args: [ 'test' ],
sh: false,
functionMatch: functionMatch
},
{
name: 'Elixir: mix clean',
exec: exec,
args: [ 'clean' ],
sh: false,
keymap: 'cmd-alt-k'
},
{
name: 'Elixir: mix dialyzer',
exec: exec,
args: [ 'dialyzer', '--fullpath' ],
sh: false,
errorMatch: [ '(?<file>[\\/0-9a-zA-Z\\\\._-]+):(?<line>\\d+):\\s{1}(?<info>.*)' ]
} ];
}
};
}