puppet-validator 0.0.9 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -13
- data/README.md +39 -104
- data/bin/puppet-validator +38 -1
- data/config.ru +0 -2
- data/lib/puppet-validator.rb +181 -136
- data/lib/puppet-validator/helpers.rb +40 -0
- data/lib/puppet-validator/validators.rb +5 -0
- data/lib/puppet-validator/validators/lint.rb +46 -0
- data/lib/puppet-validator/validators/rspec.rb +90 -0
- data/lib/puppet-validator/validators/syntax.rb +96 -0
- data/public/font-awesome-4.7.0/css/font-awesome.css +2337 -0
- data/public/font-awesome-4.7.0/css/font-awesome.min.css +4 -0
- data/public/font-awesome-4.7.0/fonts/FontAwesome.otf +0 -0
- data/public/font-awesome-4.7.0/fonts/fontawesome-webfont.eot +0 -0
- data/public/font-awesome-4.7.0/fonts/fontawesome-webfont.svg +2671 -0
- data/public/font-awesome-4.7.0/fonts/fontawesome-webfont.ttf +0 -0
- data/public/font-awesome-4.7.0/fonts/fontawesome-webfont.woff +0 -0
- data/public/font-awesome-4.7.0/fonts/fontawesome-webfont.woff2 +0 -0
- data/public/scripts.js +203 -35
- data/public/styles.css +85 -54
- data/public/validation.js +95 -0
- data/views/index.erb +29 -7
- data/views/result.erb +23 -27
- metadata +33 -43
- data/bin/grapher +0 -44
- data/public/info.png +0 -0
- data/public/prism-default.css +0 -227
- data/public/prism.js +0 -961
Binary file
|
Binary file
|
Binary file
|
data/public/scripts.js
CHANGED
@@ -8,11 +8,16 @@ function toggleMenu() {
|
|
8
8
|
$('#checks-menu').slideToggle();
|
9
9
|
}
|
10
10
|
|
11
|
+
function loadPaste() {
|
12
|
+
var location = $('#location').val();
|
13
|
+
window.location = "/load/"+location;
|
14
|
+
}
|
15
|
+
|
11
16
|
function gist() {
|
12
|
-
var code = $('#code').
|
17
|
+
var code = $('#code').val();
|
13
18
|
if (typeof(code) == 'string' && $.trim(code).length != 0) {
|
14
19
|
var data = {
|
15
|
-
"description": "Validated by
|
20
|
+
"description": "Validated by " + window.location.origin + '/load/referer',
|
16
21
|
"public": true,
|
17
22
|
"files": {
|
18
23
|
"init.pp": {
|
@@ -28,71 +33,234 @@ function gist() {
|
|
28
33
|
})
|
29
34
|
.success(function(response) {
|
30
35
|
console.log(response);
|
31
|
-
popup(null, 'Gist posted to:', response['html_url']);
|
36
|
+
popup(null, { text: 'Gist posted to:', url: response['html_url'] } );
|
32
37
|
})
|
33
38
|
.error(function(error) {
|
34
39
|
console.warn("Cannot save gist: ", error);
|
35
|
-
popup('Gist save failed.', error);
|
40
|
+
popup('Gist save failed.', { text: error });
|
36
41
|
});
|
37
42
|
}
|
38
43
|
}
|
39
44
|
|
40
|
-
function popup(title,
|
45
|
+
function popup(title, options) {
|
41
46
|
var dialog = $('<div id="popup" />');
|
42
|
-
|
43
|
-
|
44
|
-
if(url) {
|
45
|
-
$(dialog).append( '<ul><li id="url"></li></ul>' )
|
46
|
-
$(dialog).find('li#url').append( $("<a />", { href: url, text: url }) );
|
47
|
-
}
|
48
|
-
|
49
|
-
$(dialog).dialog({
|
47
|
+
var params = {
|
50
48
|
modal: true,
|
51
49
|
title: title,
|
52
|
-
width: 425,
|
53
50
|
buttons: {
|
54
51
|
Ok: function () {
|
55
52
|
$(this).dialog("close");
|
56
53
|
$("#popup").remove();
|
57
54
|
}
|
58
55
|
}
|
56
|
+
};
|
57
|
+
|
58
|
+
if (typeof options === 'object') {
|
59
|
+
if('html' in options) {
|
60
|
+
dialog.append( $(options.html) );
|
61
|
+
}
|
62
|
+
if('text' in options) {
|
63
|
+
dialog.append( $("<p/>").text(options.text) );
|
64
|
+
}
|
65
|
+
if('url' in options) {
|
66
|
+
dialog.append( '<ul><li id="url"></li></ul>' )
|
67
|
+
dialog.find('li#url').append( $("<a />", { href: options.url, text: options.url }) );
|
68
|
+
}
|
69
|
+
|
70
|
+
if('height' in options) {
|
71
|
+
params.height = options.height;
|
72
|
+
}
|
73
|
+
if('width' in options) {
|
74
|
+
params.width = options.width;
|
75
|
+
}
|
76
|
+
}
|
77
|
+
|
78
|
+
$(dialog).dialog(params);
|
79
|
+
}
|
80
|
+
|
81
|
+
function showRelationships() {
|
82
|
+
if(typeof editor != 'undefined' ) { editor.save(); }
|
83
|
+
|
84
|
+
$('#relationships').prop("disabled",true);
|
85
|
+
$('html,body').css('cursor','wait');
|
86
|
+
|
87
|
+
$.post('/api/v0/validate/relationships', {code: $('#code').val()}, function(data) {
|
88
|
+
popup('Resource Relationships', {
|
89
|
+
html: '<center>'+data+'</center>',
|
90
|
+
width: $(window).width() * .8,
|
91
|
+
height: $(window).height() * .8
|
92
|
+
});
|
93
|
+
|
94
|
+
}).fail(function(jqXHR) {
|
95
|
+
alert("Unknown API error:\n" + jqXHR.responseText);
|
96
|
+
|
97
|
+
}).always(function() {
|
98
|
+
$('html,body').css('cursor','default');
|
99
|
+
$('#relationships').prop("disabled",false);
|
59
100
|
});
|
60
101
|
}
|
61
102
|
|
103
|
+
function puppet_validator(cm, updateLinting, options) {
|
104
|
+
if(typeof editor == 'undefined' ) { return null; }
|
105
|
+
|
106
|
+
// propogates text to the textarea
|
107
|
+
editor.save();
|
108
|
+
|
109
|
+
var output = $('#results');
|
110
|
+
var spinner = $('#spinner');
|
111
|
+
var message = $('#message');
|
112
|
+
var version = $('#version');
|
113
|
+
var wrapper = $('form');
|
114
|
+
var params = {
|
115
|
+
code: $('#code').val(),
|
116
|
+
version: $('#versions').val(),
|
117
|
+
};
|
118
|
+
|
119
|
+
if( $('input#lint').is(':checked') ) {
|
120
|
+
params['lint'] = true;
|
121
|
+
params['checks'] = $('#checks input:checked').map(function() { return this.value; }).get();
|
122
|
+
}
|
123
|
+
|
124
|
+
message.empty();
|
125
|
+
spinner.show();
|
126
|
+
output.removeClass('hidden');
|
127
|
+
output.removeClass('validated');
|
128
|
+
$('#validate').prop("disabled",true);
|
129
|
+
|
130
|
+
var errors = [];
|
131
|
+
$.post('/api/v0/validate', params, function(data) {
|
132
|
+
console.log(data);
|
133
|
+
var results = jQuery.parseJSON(data);
|
134
|
+
|
135
|
+
spinner.hide();
|
136
|
+
message.text(results['message']);
|
137
|
+
version.text(results['version']);
|
138
|
+
wrapper.addClass('validated');
|
139
|
+
output.addClass('validated');
|
140
|
+
|
141
|
+
if(results.success) {
|
142
|
+
wrapper.removeClass('failed');
|
143
|
+
output.removeClass('failed');
|
144
|
+
$('#share').show();
|
145
|
+
}
|
146
|
+
else {
|
147
|
+
wrapper.addClass('failed');
|
148
|
+
output.addClass('failed');
|
149
|
+
$('#share').hide();
|
150
|
+
|
151
|
+
if('line' in results) {
|
152
|
+
var min = Math.max(results['line'] - 3, 0);
|
153
|
+
var max = Math.min(results['line'] + 3, editor.lineCount());
|
154
|
+
editor.scrollIntoView(min, max);
|
155
|
+
}
|
156
|
+
}
|
157
|
+
|
158
|
+
if ('messages' in results) {
|
159
|
+
var messages = results['messages'];
|
160
|
+
for ( var i = 0; i < messages.length; i++) {
|
161
|
+
var item = messages[i];
|
162
|
+
errors.push({
|
163
|
+
from: CodeMirror.Pos(item.from[0], item.from[1]),
|
164
|
+
to: CodeMirror.Pos(item.to[0], item.to[1] ),
|
165
|
+
message: item.message,
|
166
|
+
severity: item.severity
|
167
|
+
});
|
168
|
+
}
|
169
|
+
updateLinting(errors);
|
170
|
+
}
|
171
|
+
}).fail(function(jqXHR) {
|
172
|
+
alert("Unknown API error:\n" + jqXHR.responseText);
|
173
|
+
}).always(function() {
|
174
|
+
spinner.hide();
|
175
|
+
$('#validate').prop("disabled",false);
|
176
|
+
});
|
177
|
+
}
|
178
|
+
|
179
|
+
|
62
180
|
$( document ).ready(function() {
|
63
181
|
toggleChecks();
|
182
|
+
$('#checks-menu').hide();
|
64
183
|
|
65
|
-
$("
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
var end = this.selectionEnd;
|
184
|
+
$("input#load").on('click', function(event){
|
185
|
+
event.preventDefault();
|
186
|
+
loadPaste();
|
187
|
+
});
|
70
188
|
|
71
|
-
|
72
|
-
|
189
|
+
$("input#relationships").on('click', function(event){
|
190
|
+
event.preventDefault();
|
191
|
+
showRelationships();
|
192
|
+
});
|
73
193
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
194
|
+
// don't fail if the theme doesn't load codemirror
|
195
|
+
if(typeof CodeMirror != 'undefined') {
|
196
|
+
var textbox = $("textarea#code")[0]
|
197
|
+
editor = CodeMirror.fromTextArea(textbox, {
|
198
|
+
lineNumbers: true,
|
199
|
+
smartIndent: true,
|
200
|
+
indentWithTabs: true,
|
201
|
+
styleActiveLine: true,
|
202
|
+
mode: 'puppet',
|
203
|
+
gutters: ["CodeMirror-lint-markers"],
|
204
|
+
lint: {
|
205
|
+
getAnnotations: puppet_validator,
|
206
|
+
lintOnChange: false,
|
207
|
+
async: true
|
208
|
+
},
|
209
|
+
});
|
78
210
|
|
79
|
-
|
80
|
-
|
211
|
+
// this is slow as crap. There must be a faster way.
|
212
|
+
editor.on("renderLine", function(cm, lineHandle, element) {
|
213
|
+
if(element.querySelector('.CodeMirror-lint-mark-error')) {
|
214
|
+
//cm.getDoc().addLineClass(lineHandle, 'wrap', 'CodeMirror-lint-mark-error');
|
215
|
+
element.classList.add('CodeMirror-lint-mark-error');
|
216
|
+
}
|
81
217
|
|
82
|
-
|
83
|
-
|
218
|
+
if(element.querySelector('.CodeMirror-lint-mark-warning')) {
|
219
|
+
//cm.getDoc().addLineClass(lineHandle, 'wrap', 'CodeMirror-lint-mark-warning');
|
220
|
+
element.classList.add('CodeMirror-lint-mark-warning');
|
84
221
|
}
|
85
|
-
|
222
|
+
});
|
86
223
|
|
87
|
-
|
88
|
-
|
224
|
+
// indent with spaces to match style guide
|
225
|
+
editor.setOption("extraKeys", {
|
226
|
+
Tab: function(cm) {
|
227
|
+
var spaces = Array(cm.getOption("indentUnit") + 1).join(" ");
|
228
|
+
cm.replaceSelection(spaces);
|
229
|
+
}
|
230
|
+
});
|
231
|
+
|
232
|
+
$("input#validate").on('click', function(event){
|
233
|
+
event.preventDefault();
|
234
|
+
editor.performLint();
|
235
|
+
});
|
89
236
|
}
|
90
237
|
else {
|
91
|
-
$(
|
92
|
-
|
93
|
-
|
238
|
+
$("textarea#code").keydown(function(e) {
|
239
|
+
if(e.keyCode === 9) { // tab was pressed
|
240
|
+
// get caret position/selection
|
241
|
+
var start = this.selectionStart;
|
242
|
+
var end = this.selectionEnd;
|
243
|
+
|
244
|
+
var $this = $(this);
|
245
|
+
var value = $this.val();
|
246
|
+
|
247
|
+
// set textarea value to: text before caret + tab + text after caret
|
248
|
+
$this.val(value.substring(0, start)
|
249
|
+
+ "\t"
|
250
|
+
+ value.substring(end));
|
251
|
+
|
252
|
+
// put caret at right position again (add one for the tab)
|
253
|
+
this.selectionStart = this.selectionEnd = start + 1;
|
254
|
+
|
255
|
+
// prevent the loss of focus
|
256
|
+
e.preventDefault();
|
257
|
+
}
|
94
258
|
});
|
95
259
|
}
|
96
260
|
|
261
|
+
if ($('select#versions option').length == 1) {
|
262
|
+
$('select#versions').attr('disabled', true);
|
263
|
+
}
|
264
|
+
|
97
265
|
$('.share_icon').tooltip();
|
98
266
|
});
|
data/public/styles.css
CHANGED
@@ -3,51 +3,47 @@ body {
|
|
3
3
|
padding: 0 2em;
|
4
4
|
}
|
5
5
|
|
6
|
-
/*
|
7
|
-
pre
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
}
|
16
|
-
div.line-highlight.with-tooltip {
|
17
|
-
background-color: rgba(255, 255, 0, 0.25);
|
18
|
-
pointer-events: auto;
|
19
|
-
}
|
20
|
-
div.line-highlight.with-tooltip .marker {
|
21
|
-
width: 0px;
|
22
|
-
height: 0px;
|
23
|
-
border-top: 0.5em solid #000;
|
24
|
-
border-left: 0.5em solid transparent;
|
25
|
-
position: absolute;
|
26
|
-
top: 0;
|
27
|
-
right: 0;
|
28
|
-
}
|
29
|
-
div.line-highlight.with-tooltip .line-highlight-tooltip {
|
30
|
-
position: absolute;
|
31
|
-
top: -1.75em;
|
32
|
-
right: 0;
|
33
|
-
background-color: #aaccaa;
|
34
|
-
border: 1px solid black;
|
35
|
-
border-radius: 5px;
|
36
|
-
padding: 0 3px;
|
37
|
-
display: none;
|
6
|
+
/* css only line numbers for the fallback no-js results */
|
7
|
+
pre#highlighted {
|
8
|
+
counter-reset: line;
|
9
|
+
background-color: #f7f7f7;
|
10
|
+
line-height: 0;
|
11
|
+
}
|
12
|
+
pre#highlighted code {
|
13
|
+
counter-increment: line;
|
14
|
+
line-height: 1.25em;
|
38
15
|
}
|
39
|
-
|
40
|
-
|
16
|
+
pre#highlighted code:before {
|
17
|
+
content: counter(line);
|
18
|
+
-webkit-user-select: none;
|
19
|
+
display: inline-block;
|
20
|
+
width: 2em;
|
21
|
+
border-right: 2px solid #ccc;
|
22
|
+
text-align: right ;
|
23
|
+
padding-right: 0.5em;
|
24
|
+
margin-right: 0.5em;
|
41
25
|
}
|
42
26
|
|
27
|
+
#location {
|
28
|
+
width: 60%;
|
29
|
+
}
|
30
|
+
|
43
31
|
.results,
|
44
32
|
.warning {
|
45
33
|
width: 65%;
|
34
|
+
min-height: 3.5em;
|
46
35
|
border: 1px solid black;
|
47
36
|
border-radius: 0.25em;
|
48
37
|
padding: 0.5em;
|
49
|
-
margin:
|
38
|
+
margin: 1em auto;
|
39
|
+
background-color: #fcfcfc;
|
40
|
+
transition: opacity 1s, background-color 1s, border: 1s;
|
50
41
|
}
|
42
|
+
|
43
|
+
.results.hidden {
|
44
|
+
opacity: 0;
|
45
|
+
}
|
46
|
+
|
51
47
|
.results legend {
|
52
48
|
text-align: right;
|
53
49
|
padding: 3px;
|
@@ -55,19 +51,21 @@ div.line-highlight.with-tooltip {
|
|
55
51
|
border: 1px solid #ccc;
|
56
52
|
border-radius: 3px;
|
57
53
|
}
|
58
|
-
.results.
|
59
|
-
|
54
|
+
.results.validated {
|
55
|
+
border: 2px solid #1dd12d;
|
60
56
|
}
|
61
|
-
.results.
|
62
|
-
|
57
|
+
.results.validated.failed {
|
58
|
+
border: 2px solid #981818;
|
63
59
|
}
|
64
60
|
|
65
61
|
.results p {
|
66
|
-
margin: 0;
|
62
|
+
margin: 0 3em 0 0;
|
67
63
|
}
|
68
64
|
.results img.share_icon {
|
65
|
+
display: none;
|
69
66
|
float: right;
|
70
67
|
cursor: pointer;
|
68
|
+
height: 2em;
|
71
69
|
}
|
72
70
|
.results hr {
|
73
71
|
clear: both;
|
@@ -104,7 +102,21 @@ div.links {
|
|
104
102
|
div.entry {
|
105
103
|
width: 80%;
|
106
104
|
margin: 0 auto;
|
105
|
+
border: 1px solid #ccc;
|
106
|
+
padding: 0.5em;
|
107
|
+
border-radius: 0.5em;
|
108
|
+
background-color: #f7f7f7;
|
107
109
|
}
|
110
|
+
|
111
|
+
form.validated div.entry {
|
112
|
+
background-color: #f1ffe8;
|
113
|
+
border: 1px solid #1dd12d;
|
114
|
+
}
|
115
|
+
form.validated.failed div.entry {
|
116
|
+
background-color: #ffd4d4;
|
117
|
+
border: 1px solid #981818;
|
118
|
+
}
|
119
|
+
|
108
120
|
div.entry textarea {
|
109
121
|
width: 100%;
|
110
122
|
font-family: monospace;
|
@@ -113,6 +125,13 @@ div.row {
|
|
113
125
|
text-align: center;
|
114
126
|
}
|
115
127
|
|
128
|
+
.CodeMirror-line.CodeMirror-lint-mark-warning {
|
129
|
+
background-color: #fff9d2;
|
130
|
+
}
|
131
|
+
.CodeMirror-line.CodeMirror-lint-mark-error {
|
132
|
+
background-color: #ffefed;
|
133
|
+
}
|
134
|
+
|
116
135
|
input#validate,
|
117
136
|
select#versions,
|
118
137
|
a#customize {
|
@@ -123,7 +142,7 @@ a.button {
|
|
123
142
|
font-size: small;
|
124
143
|
background-color: #fff;
|
125
144
|
padding: 0 2px;
|
126
|
-
border: 1px solid #
|
145
|
+
border: 1px solid #ccc;
|
127
146
|
border-radius: 3px;
|
128
147
|
text-decoration: none;
|
129
148
|
}
|
@@ -132,23 +151,31 @@ a.button:hover {
|
|
132
151
|
border-color: #bbb;
|
133
152
|
}
|
134
153
|
fieldset.menu {
|
135
|
-
display: none;
|
136
154
|
border-radius: 0.5em;
|
155
|
+
background-color: #fff;
|
137
156
|
}
|
138
|
-
fieldset.menu
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
157
|
+
fieldset.menu legend {
|
158
|
+
background-color: #ffffff;
|
159
|
+
border-top: 1px solid #ccc;
|
160
|
+
border-left: 1px solid #ccc;
|
161
|
+
border-right: 1px solid #ccc;
|
162
|
+
border-radius: 3px 3px 0 0;
|
163
|
+
}
|
164
|
+
|
165
|
+
fieldset.menu ul {
|
166
|
+
list-style-type: none;
|
167
|
+
padding: 0;
|
168
|
+
margin: 0;
|
169
|
+
-moz-column-count: 2;
|
170
|
+
-moz-column-gap: 20px;
|
171
|
+
-webkit-column-count: 2;
|
172
|
+
-webkit-column-gap: 20px;
|
173
|
+
column-count: 2;
|
174
|
+
column-gap: 20px;
|
175
|
+
}
|
149
176
|
|
150
177
|
.info {
|
151
|
-
background: #fefefe
|
178
|
+
background: #fefefe;
|
152
179
|
border: 1px solid #efefef;
|
153
180
|
padding: 0.5em;
|
154
181
|
padding-left: 50px;
|
@@ -159,6 +186,10 @@ fieldset.menu ul {
|
|
159
186
|
-khtml-border-radius: 0.5em;
|
160
187
|
border-radius: 0.5em;
|
161
188
|
}
|
189
|
+
.info i.fa {
|
190
|
+
float: left;
|
191
|
+
margin-left: -45px;
|
192
|
+
}
|
162
193
|
|
163
194
|
/* jquery UI overrides */
|
164
195
|
.ui-widget {
|