File Coverage

blib/lib/Galileo/DB/Deploy.pm
Criterion Covered Total %
statement 17 19 89.4
branch n/a
condition n/a
subroutine 7 7 100.0
pod n/a
total 24 26 92.3


line stmt bran cond sub pod time code
1             package Galileo::DB::Deploy;
2 3     3   35429 use Moose;
  3         1147776  
  3         21  
3 3     3   19373 BEGIN{ extends 'DBIx::Class::DeploymentHandler' }
4              
5             # A wrapper class for DBICDH for use with Galileo
6              
7 3     3   2813551 use Mojo::JSON 'j';
  3         268501  
  3         233  
8              
9 3     3   1793 use File::ShareDir qw/dist_dir/;
  3         14509  
  3         191  
10 3     3   22 use File::Spec;
  3         10  
  3         69  
11 3     3   13 use File::Temp ();
  3         4  
  3         56  
12 3     3   4882 use File::Copy::Recursive 'dircopy';
  0            
  0            
13              
14             has 'temp_script_dir' => (
15             is => 'rw',
16             lazy => 1,
17             builder => '_build_temp_script_dir',
18             );
19              
20             sub _build_temp_script_dir {
21             File::Temp->newdir( $ENV{KEEP_TEMP_DIR} ? (CLEANUP => 0) : () );
22             }
23              
24             has 'real_script_dir' => (
25             is => 'rw',
26             lazy => 1,
27             builder => '_build_real_script_dir',
28             );
29              
30             sub _build_real_script_dir {
31             my $dev_dir = File::Spec->catdir( qw/ lib Galileo files sql / );
32             -e $dev_dir ? $dev_dir : File::Spec->catdir( dist_dir('Galileo'), 'sql' );
33             }
34              
35             has 'script_directory' => (
36             is => 'rw',
37             lazy => 1,
38             builder => '_build_script_directory',
39             );
40              
41             sub _build_script_directory {
42             my $self = shift;
43             my $dir = $self->real_script_dir;
44             my $temp = $self->temp_script_dir;
45             dircopy $dir, $temp or die "Cannot copy from $dir to $temp";
46             return "$temp";
47             }
48              
49             has 'databases' => (
50             is => 'rw',
51             lazy => 1,
52             builder => '_build_databases',
53             );
54              
55             sub _build_databases { [ shift->schema->storage->sqlt_type ] }
56              
57             has '+force_overwrite' => (
58             default => 1,
59             );
60              
61             has '+ignore_ddl' => (
62             default => 1,
63             );
64              
65             sub installed_version {
66             my $self = shift;
67             return eval{ $self->database_version }
68             }
69              
70             sub do_install {
71             my $self = shift;
72              
73             $self->prepare_install;
74             $self->install( @_ ? {version => shift} : () );
75             }
76              
77             sub do_upgrade {
78             my $self = shift;
79              
80             $self->prepare_upgrade;
81             $self->upgrade;
82             }
83              
84             sub has_admin_user {
85             my $self = shift;
86             return eval { $self->schema->resultset('User')->first }
87             }
88              
89             sub inject_sample_data {
90             my $self = shift;
91             my $schema = $self->schema;
92              
93             my $user = shift or die "Must provide an admin username\n";
94             my $pass = shift or die "Must provide a password for admin user\n";
95             my $full = shift || "Administrator";
96              
97             my $admin = $schema->resultset('User')->create({
98             name => $user,
99             full => $full,
100             password => $pass,
101             is_author => 1,
102             is_admin => 1,
103             });
104              
105             $schema->resultset('Page')->create({
106             name => 'home',
107             title => 'Galileo CMS',
108             html => <<'HTML',
109             <h2>Welcome to your Galileo CMS site!</h2>
110              
111             <blockquote>
112             <p>Galileo Galilei was "an Italian physicist, mathematician, astronomer, and philosopher who played a major role in the Scientific Revolution." -- <a href="https://en.wikipedia.org/wiki/Galileo_Galilei">Wikipedia</a> </p>
113             </blockquote>
114              
115             <p>When he first turned the telescope to face Jupiter, he used modern technology to improve the world around him.</p>
116              
117             <p>Like the great scientist it is named for, Galileo CMS is not afraid to be very modern. Learn more about it on the <a href="/page/about">about</a> page.</p>
118              
119             <p><img src="/portrait.jpg" alt="Portrait of Galileo Galilei" title="" /></p>
120             HTML
121             md => <<'MARKDOWN',
122             ##Welcome to your Galileo CMS site!
123              
124             > Galileo Galilei was "an Italian physicist, mathematician, astronomer, and philosopher who played a major role in the Scientific Revolution." -- [Wikipedia](https://en.wikipedia.org/wiki/Galileo_Galilei)
125              
126             When he first turned the telescope to face Jupiter, he used modern technology to improve the world around him.
127              
128             Like the great scientist it is named for, Galileo CMS is not afraid to be very modern. Learn more about it on the [about](/page/about) page.
129              
130             ![Portrait of Galileo Galilei](/portrait.jpg)
131             MARKDOWN
132             author_id => $admin->user_id,
133             });
134              
135             my $about = $schema->resultset('Page')->create({
136             name => 'about',
137             title => 'About Galileo',
138             html => <<'HTML',
139             <p>Galileo CMS is built upon some great open source projects:</p>
140              
141             <ul>
142             <li><a href="http://perl.org">Perl</a> - if you haven't looked at Perl lately, give it another try!</li>
143             <li><a href="http://mojolicio.us">Mojolicious</a> - a next generation web framework for the Perl programming language</li>
144             <li><a href="http://www.dbix-class.org/">DBIx::Class</a> - an extensible and flexible Object/Relational Mapper written in Perl</li>
145             <li><a href="http://code.google.com/p/pagedown/">PageDown</a> (Markdown engine) - the version of Attacklab's Showdown and WMD as used on Stack Overflow and the other Stack Exchange sites</li>
146             <li><a href="http://twitter.github.com/bootstrap">Bootstrap</a> - the beautiful CSS/JS library from Twitter</li>
147             <li><a href="http://jquery.com/">jQuery</a> - because everything uses jQuery</li>
148             <li><a href="http://wavded.github.com/humane-js/">HumaneJS</a> - A simple, modern, browser notification system</li>
149             </ul>
150              
151             <p>Galileo is developed by <a href="https://github.com/jberger">Joel Berger</a>. <a href="https://github.com/jberger/Galileo">Fork it</a> on GitHub!</p>
152             HTML
153             md => <<'MARKDOWN',
154             Galileo CMS is built upon some great open source projects:
155              
156             * [Perl](http://perl.org) - if you haven't looked at Perl lately, give it another try!
157             * [Mojolicious](http://mojolicio.us) - a next generation web framework for the Perl programming language
158             * [DBIx::Class](http://www.dbix-class.org/) - an extensible and flexible Object/Relational Mapper written in Perl
159             * [PageDown](http://code.google.com/p/pagedown/) (Markdown engine) - the version of Attacklab's Showdown and WMD as used on Stack Overflow and the other Stack Exchange sites
160             * [Bootstrap](http://twitter.github.com/bootstrap) - the beautiful CSS/JS library from Twitter
161             * [jQuery](http://jquery.com/) - because everything uses jQuery
162             * [HumaneJS](http://wavded.github.com/humane-js/) - A simple, modern, browser notification system
163              
164             Galileo is developed by [Joel Berger](https://github.com/jberger). [Fork it](https://github.com/jberger/Galileo) on GitHub!
165             MARKDOWN
166             author_id => $admin->user_id,
167             });
168              
169             my $syntax = $schema->resultset('Page')->create({
170             name => 'syntax',
171             title => 'Syntax',
172             html => <<'HTML',
173             <h2>Highlighting</h2>
174              
175             <p>Default highlighter is <a href="http://highlightjs.org/">highlight.js</a>. But Galileo just generates HTML so if you want to see colorized output then you have to load javascript and css.</p>
176              
177             <pre class="hljs"><code class="language-xml">&lt;!-- example --&gt;
178             &lt;link rel="stylesheet" href="http://yandex.st/highlightjs/8.0/styles/default.min.css"&gt;
179             &lt;script src="http://yandex.st/highlightjs/8.0/highlight.min.js"&gt;&lt;/script&gt;
180             &lt;script&gt; (fuction () { hljs.initHighlightingOnLoad(); })(); &lt;/script&gt;</code></pre>
181              
182             <h2>Tables</h2>
183              
184             <p><em>source</em>:</p>
185              
186             <pre class="hljs"><code class="language-markdown">| Item | Value | Qty |
187             | --------- | -----:|:--: |
188             | Computer | $1600 | 5 |
189             | Phone | $12 | 12 |
190             | Pipe | $1 |234 |</code></pre>
191              
192             <p><em>result</em>:</p>
193              
194             <table class="table table-striped">
195             <thead>
196             <tr>
197             <th>Item</th>
198             <th style="text-align:right;">Value</th>
199             <th style="text-align:center;">Qty</th>
200             </tr>
201             </thead>
202             <tr>
203             <td>Computer</td>
204             <td style="text-align:right;">$1600</td>
205             <td style="text-align:center;">5</td>
206             </tr>
207             <tr>
208             <td>Phone</td>
209             <td style="text-align:right;">$12</td>
210             <td style="text-align:center;">12</td>
211             </tr>
212             <tr>
213             <td>Pipe</td>
214             <td style="text-align:right;">$1</td>
215             <td style="text-align:center;">234</td>
216             </tr>
217             </table>
218              
219              
220             <h2>Fenced Code Blocks</h2>
221              
222             <p><em>source</em>:</p>
223              
224             <pre class="hljs"><code>```perl
225             #!/usr/bin/env perl
226              
227             use strict;
228             use warnings;
229             use Galileo;
230             ```
231             </code></pre>
232              
233             <p><em>result</em>:</p>
234              
235             <pre class="hljs"><code class="language-perl">#!/usr/bin/env perl
236              
237             use strict;
238             use warnings;
239             use Galileo;</code></pre>
240              
241             <h2>Definition Lists</h2>
242              
243             <p><em>source</em>:</p>
244              
245             <pre class="hljs"><code>Term 1
246             : Definition 1
247              
248             Term 2
249             : This definition has a code block.
250              
251             code block</code></pre>
252              
253             <p><em>result</em>:</p>
254              
255             <dl>
256             <dt>Term 1</dt>
257             <dd>Definition 1</dd>
258              
259             <dt>Term 2</dt>
260             <dd>
261             <p>This definition has a code block.</p>
262              
263             <pre class="hljs"><code>code block
264             </code></pre>
265             </dd>
266             </dl>
267              
268             <h2>Special Attributes</h2>
269              
270             <p>You can add class and id attributes to headers and gfm fenced code blocks.</p>
271              
272             <p><em>source</em>:</p>
273              
274             <pre class="hljs"><code>``` {#gfm-id .gfm-class}
275             var foo = bar;
276             ```
277              
278             ## A Header {#header-id}
279              
280             ### Another One ### {#header-id .hclass}
281              
282             Underlined {#what}
283             ==========
284             </code></pre>
285              
286             <p><em>result</em>:</p>
287              
288             <pre class="hljs"><code class="language-html">&lt;pre id="gfm-id" class="gfm-class prettyprint"&gt;&lt;code&gt;var foo = bar;&lt;/code&gt;&lt;/pre&gt;
289              
290             &lt;h2 id="header-id"&gt;A Header&lt;/h2&gt;
291              
292             &lt;h3 id="header-id" class="hclass"&gt;Another One&lt;/h3&gt;
293              
294             &lt;h1 id="what"&gt;Underlined &lt;/h1&gt;</code></pre>
295              
296             <h2>Footnotes</h2>
297              
298             <p><em>source</em>:</p>
299              
300             <pre class="hljs"><code>Here is a footnote which will be located at the end of the page[^footnote].
301              
302             [^footnote]: Here is the *text* of the **footnote**.</code></pre>
303              
304             <p><em>result</em>:</p>
305              
306             <p>Here is a footnote which will be located at the end of the page<a href="#fn:footnote" id="fnref:footnote" title="See footnote" class="footnote">1</a>.</p>
307              
308             <h2>SmartyPants</h2>
309              
310             <p>SmartyPants extension converts ASCII punctuation characters into &#8220;smart&#8221; typographic punctuation HTML entities.</p>
311              
312             <table class="table table-striped">
313             <thead>
314             <tr>
315             <th></th>
316             <th>ASCII</th>
317             <th>HTML</th>
318             </tr>
319             </thead>
320             <tr>
321             <td>Single backticks</td>
322             <td><code>'Isn't this fun?'</code></td>
323             <td>&#8216;Isn&#8217;t this fun?&#8217;</td>
324             </tr>
325             <tr>
326             <td>Quotes</td>
327             <td><code>"Isn't this fun?"</code></td>
328             <td>&#8220;Isn&#8217;t this fun?&#8221;</td>
329             </tr>
330             <tr>
331             <td>Dashes</td>
332             <td><code>This -- is an en-dash and this --- is an em-dash</code></td>
333             <td>This &#8211; is an en-dash and this &#8212; is an em-dash</td>
334             </tr>
335             </table>
336              
337              
338             <h2>Newlines</h2>
339              
340             <p><em>source</em>:</p>
341              
342             <pre class="hljs"><code>Roses are red
343             Violets are blue</code></pre>
344              
345             <p><em>result</em>:</p>
346              
347             <p>Roses are red <br>
348             Violets are blue</p>
349              
350             <h2>Strikethrough</h2>
351              
352             <p><em>source</em>:</p>
353              
354             <pre class="hljs"><code>~~Mistaken text.~~</code></pre>
355              
356             <p><em>result</em>:</p>
357              
358             <p><del>Mistaken text.</del></p>
359              
360             <div class="footnotes">
361             <hr>
362             <ol>
363              
364             <li id="fn:footnote">Here is the <em>text</em> of the <strong>footnote</strong>. <a href="#fnref:footnote" title="Return to article" class="reversefootnote">&#8617;</a></li>
365              
366             </ol>
367             </div>
368             HTML
369             md => <<'MARKDOWN',
370             ## Highlighting
371              
372             Default highlighter is [highlight.js](http://highlightjs.org/). But Galileo just generates HTML so if you want to see colorized output then you have to load javascript and css.
373              
374             ```xml
375             <!-- example -->
376             <link rel="stylesheet" href="http://yandex.st/highlightjs/8.0/styles/default.min.css">
377             <script src="http://yandex.st/highlightjs/8.0/highlight.min.js"></script>
378             <script> (fuction () { hljs.initHighlightingOnLoad(); })(); </script>
379             ```
380              
381             ## Tables
382              
383             *source*:
384              
385             ```markdown
386             | Item | Value | Qty |
387             | --------- | -----:|:--: |
388             | Computer | $1600 | 5 |
389             | Phone | $12 | 12 |
390             | Pipe | $1 |234 |
391             ```
392              
393             *result*:
394              
395             | Item | Value | Qty |
396             | --------- | -----:|:--: |
397             | Computer | $1600 | 5 |
398             | Phone | $12 | 12 |
399             | Pipe | $1 |234 |
400              
401              
402             ## Fenced Code Blocks
403              
404             *source*:
405              
406             ```perl
407             #!/usr/bin/env perl
408              
409             use strict;
410             use warnings;
411             use Galileo;
412             ```
413              
414             *result*:
415              
416             ```perl
417             #!/usr/bin/env perl
418              
419             use strict;
420             use warnings;
421             use Galileo;
422             ```
423              
424             ## Definition Lists
425              
426             *source*:
427              
428             ```
429             Term 1
430             : Definition 1
431              
432             Term 2
433             : This definition has a code block.
434              
435             code block
436             ```
437              
438             *result*:
439              
440             Term 1
441             : Definition 1
442              
443             Term 2
444             : This definition has a code block.
445              
446             code block
447              
448             ## Special Attributes
449              
450             You can add class and id attributes to headers and gfm fenced code blocks.
451              
452             *source*:
453              
454             ``` {#gfm-id .gfm-class}
455             var foo = bar;
456             ```
457              
458             ## A Header {#header-id}
459              
460             ### Another One ### {#header-id .hclass}
461              
462             Underlined {#what}
463             ==========
464              
465             *result*:
466              
467             ```html
468             <pre id="gfm-id" class="gfm-class prettyprint"><code>var foo = bar;</code></pre>
469              
470             <h2 id="header-id">A Header</h2>
471              
472             <h3 id="header-id" class="hclass">Another One</h3>
473              
474             <h1 id="what">Underlined </h1>
475             ```
476              
477             ## Footnotes
478              
479             *source*:
480              
481             ```
482             Here is a footnote which will be located at the end of the page[^footnote].
483              
484             [^footnote]: Here is the *text* of the **footnote**.
485             ```
486              
487             *result*:
488              
489             Here is a footnote which will be located at the end of the page[^footnote].
490              
491             [^footnote]: Here is the *text* of the **footnote**.
492              
493             ## SmartyPants
494              
495             SmartyPants extension converts ASCII punctuation characters into "smart" typographic punctuation HTML entities.
496              
497             | | ASCII | HTML |
498             ------------------|----------------------------------------------------|-------------------------------------
499             | Single backticks | `'Isn't this fun?'` | &#8216;Isn&#8217;t this fun?&#8217; |
500             | Quotes | `"Isn't this fun?"` | &#8220;Isn&#8217;t this fun?&#8221; |
501             | Dashes | `This -- is an en-dash and this --- is an em-dash` | This &#8211; is an en-dash and this &#8212; is an em-dash |
502              
503             ## Newlines
504              
505             *source*:
506              
507             ```
508             Roses are red
509             Violets are blue
510             ```
511              
512             *result*:
513              
514             Roses are red
515             Violets are blue
516              
517             ## Strikethrough
518              
519             *source*:
520              
521             ```
522             ~~Mistaken text.~~
523             ```
524              
525             *result*:
526              
527             ~~Mistaken text.~~
528             MARKDOWN
529             author_id => $admin->user_id,
530             });
531              
532             $schema->resultset('Menu')->create({
533             name => 'main',
534             list => j( [ $syntax->page_id, $about->page_id ] ),
535             });
536             }
537              
538             sub create_test_object {
539             my $class = shift;
540             my $opts = ref $_[-1] eq 'HASH' ? pop : {};
541              
542             require Galileo;
543             require Galileo::DB::Schema;
544              
545             my $db = Galileo::DB::Schema->connect('dbi:SQLite:dbname=:memory:','','',{sqlite_unicode=>1});
546              
547             my $dh = __PACKAGE__->new(
548             databases => [],
549             schema => $db,
550             );
551             $dh->do_install;
552             $dh->inject_sample_data('admin', 'pass', 'Joe Admin');
553              
554              
555             if ($opts->{test}) {
556             require Test::More;
557             Test::More::ok(
558             $db->resultset('User')->single({name => 'admin'})->check_password('pass'),
559             'DB user checks out'
560             );
561             Test::More::ok( $dh->installed_version, 'Found version information' );
562             }
563              
564             require Test::Mojo;
565             my $t = Test::Mojo->new(Galileo->new(db => $db));
566              
567             return wantarray ? ($t, $dh) : $t;
568             }
569              
570             1;
571