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.
@@ -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').text();
17
+ var code = $('#code').val();
13
18
  if (typeof(code) == 'string' && $.trim(code).length != 0) {
14
19
  var data = {
15
- "description": "Validated by puppetlinter.com",
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, text, url) {
45
+ function popup(title, options) {
41
46
  var dialog = $('<div id="popup" />');
42
- $(dialog).append( $("<p/>").text(text) );
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
- $("textarea#code").keydown(function(e) {
66
- if(e.keyCode === 9) { // tab was pressed
67
- // get caret position/selection
68
- var start = this.selectionStart;
69
- var end = this.selectionEnd;
184
+ $("input#load").on('click', function(event){
185
+ event.preventDefault();
186
+ loadPaste();
187
+ });
70
188
 
71
- var $this = $(this);
72
- var value = $this.val();
189
+ $("input#relationships").on('click', function(event){
190
+ event.preventDefault();
191
+ showRelationships();
192
+ });
73
193
 
74
- // set textarea value to: text before caret + tab + text after caret
75
- $this.val(value.substring(0, start)
76
- + "\t"
77
- + value.substring(end));
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
- // put caret at right position again (add one for the tab)
80
- this.selectionStart = this.selectionEnd = start + 1;
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
- // prevent the loss of focus
83
- e.preventDefault();
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
- if ($('select#versions option').length == 1) {
88
- $('select#versions').attr('disabled', true);
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
- $('select#versions').change(function() {
92
- var action = ('/' + $( this ).val() + '/validate').replace(/^\/+/, '/');
93
- $('form').attr('action', action );
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
  });
@@ -3,51 +3,47 @@ body {
3
3
  padding: 0 2em;
4
4
  }
5
5
 
6
- /* keeps the tooltip from clipping to the pre */
7
- pre[class*="language-"] {
8
- overflow: visible;
9
- }
10
- div.line-highlight {
11
- /* Cannot use opacity, because that affects tooltip children as well */
12
- background-color: rgba(255, 181, 181, 0.25);
13
- color: black;
14
- font-weight: bold;
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
- div.line-highlight.with-tooltip:hover .line-highlight-tooltip {
40
- display: block;
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: 0 auto;
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.success {
59
- background-color: #61ff6e;
54
+ .results.validated {
55
+ border: 2px solid #1dd12d;
60
56
  }
61
- .results.fail {
62
- background-color: #ffb6b6;
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 #fff;
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 ul {
139
- list-style-type: none;
140
- padding: 0;
141
- margin: 0;
142
- -moz-column-count: 2;
143
- -moz-column-gap: 20px;
144
- -webkit-column-count: 2;
145
- -webkit-column-gap: 20px;
146
- column-count: 2;
147
- column-gap: 20px;
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 url('info.png') no-repeat 5px 5px !important;
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 {