File Coverage

blib/lib/Project/Easy/Helper.pm
Criterion Covered Total %
statement 30 167 17.9
branch 0 38 0.0
condition 0 20 0.0
subroutine 10 19 52.6
pod 0 7 0.0
total 40 251 15.9


line stmt bran cond sub pod time code
1             package Project::Easy::Helper;
2              
3 2     2   176780 use Data::Dumper;
  2         23985  
  2         152  
4 2     2   21 use Class::Easy;
  2         3  
  2         26  
5 2     2   1200 use IO::Easy;
  2         4614  
  2         15  
6              
7 2     2   47522 use Time::Piece;
  2         46187  
  2         15  
8              
9             require Project::Easy;
10              
11 2     2   1996 use Project::Easy::Config;
  2         6  
  2         71  
12              
13 2     2   1724 use Project::Easy::Helper::DB;
  2         8  
  2         66  
14 2     2   1340 use Project::Easy::Helper::Status;
  2         9  
  2         68  
15 2     2   1529 use Project::Easy::Helper::Config;
  2         6  
  2         49  
16 2     2   1074 use Project::Easy::Helper::Console;
  2         6  
  2         4925  
17              
18             our @scriptable = (qw(status config updatedb console));
19              
20             my $is_colored = 0;
21              
22             $is_colored = 1
23             if try_to_use ('Term::ANSIColor');
24              
25             sub ::initialize {
26 0     0     my $params = \@_;
27 0 0         $params = \@ARGV
28             unless scalar @$params;
29            
30 0           my $namespace = shift @$params;
31              
32 0           my @path = ('lib', split '::', $namespace);
33 0           my $last = pop @path;
34              
35 0   0       my $project_id = shift @ARGV || lc ($last);
36            
37 0           debug "initialization of $namespace, project id is: $project_id";
38            
39 0 0         unless ($namespace) {
40 0           die "please specify package namespace";
41             }
42            
43 0           my $data_files = file->__data__files;
44            
45 0           my $data = {
46             namespace => $namespace,
47             project_id => $project_id,
48             };
49            
50 0           my $project_pm = Project::Easy::Config::string_from_template (
51             $data_files->{'Project.pm'},
52             $data
53             );
54              
55 0           my $login = eval {scalar getpwuid ($<)};
  0            
56              
57 0 0         my $instance = 'local' . (defined $login ? ".$login" : '');
58            
59 0           my $root = dir->current;
60            
61 0           my $lib_dir = $root->append (@path)->as_dir;
62 0           $lib_dir->create; # recursive directory creation
63            
64 0           $last .= '.pm';
65 0           my $class_file = $lib_dir->append ($last)->as_file;
66 0           $class_file->store_if_empty ($project_pm);
67            
68             # ok, project skeleton created. now we need to create 'bin' dir
69 0           $root->dir_io ('bin')->create;
70            
71             # now we create several perl scripts to complete installation
72 0           create_scripts ($root, $data_files);
73            
74             # ok, project skeleton created. now we need to create config
75 0           my $etc = $root->append ('etc')->as_dir;
76 0           $etc->append ($instance)->as_dir->create;
77            
78             # TODO: store database config
79 0           $etc->append ("$project_id.json")->as_file->store_if_empty ('{}');
80 0           $etc->append ($instance, "$project_id.json")->as_file->store_if_empty ('{}');
81            
82 0           $etc->append ('project-easy')->as_file->store_if_empty ("#!/usr/bin/perl
83             package LocalConf;
84             our \$pack = '$namespace';
85              
86             our \@paths = qw(
87             );
88              
89             1;
90             ");
91            
92 0           my $var = create_var ($root);
93            
94 0           my $instance_file = $var->append ('instance')->as_file;
95 0           $instance_file->store_if_empty ($instance);
96              
97 0           my $t = $root->append ('t')->as_dir;
98 0           $t->create;
99            
100 0           create_entity ($namespace, $root, 'default');
101            
102             # adding sqlite database (sqlite is dependency for dbi::easy)
103            
104 0           debug "file contents saving done";
105            
106 0           $0 = dir->current->append (qw(etc project-easy))->path;
107            
108 0           my $date = localtime->ymd;
109            
110 0           my $schema_file = file ('share/sql/default.sql');
111 0           $schema_file->parent->create;
112 0           $schema_file->store (
113             "--- $date\ncreate table var (var_name text, var_value text);\n"
114             );
115              
116 0           config (qw(db.default template db.sqlite));
117 0           config (qw(db.default.attributes.dbname = ), '{$root}/var/test.sqlite');
118 0           config (qw(db.default.update =), "$schema_file");
119            
120 0           $namespace->config ($instance);
121            
122 0           update_schema (
123             mode => 'install'
124             );
125            
126             # TODO: be more user-friendly: show help after finish
127            
128            
129             }
130              
131             sub create_scripts {
132 0     0 0   my $root = shift;
133 0           my $data_files = shift;
134              
135 0           foreach (@scriptable) {
136 0           my $script = $root->file_io ('bin', $_);
137              
138 0           my $script_contents = Project::Easy::Config::string_from_template (
139             $data_files->{'script.template'},
140             {script_name => $_}
141             );
142              
143 0           $script->store_if_empty ($script_contents);
144            
145 0 0         warn "can't chmod " . $script->path
146             unless chmod 0755, $script->path;
147            
148             }
149              
150             }
151              
152 0     0 0   sub helping_hand {
153            
154             }
155              
156             sub create_entity {
157 0     0 0   my $namespace = shift;
158 0           my $root = shift;
159 0           my $datasource = shift;
160            
161 0 0         if (defined $::project) {
162 0           $namespace = $::project;
163             }
164              
165 0           my @namespace_chunks = split /\:\:/, $namespace;
166            
167             # here we must create default entity classes
168 0           my $project_lib = $root->dir_io ('lib', @namespace_chunks, 'Entity');
169 0           $project_lib->create;
170            
171 0           my $scope_prefix = '';
172 0 0         if ($datasource ne 'default') {
173 0           $scope_prefix = ($namespace->_detect_entity ("${datasource}_test"))[2];
174             }
175            
176 0           my $data_files = file->__data__files;
177              
178 0           my $entity_template = $data_files->{'Entity.pm'};
179              
180 0           my $entity_pm = Project::Easy::Config::string_from_template (
181             $entity_template,
182             {
183             namespace => $namespace,
184             scope => $scope_prefix.'Record', #
185             dbi_easy_scope => 'Record',
186             datasource => $datasource
187             }
188             );
189              
190 0           $project_lib->append ("${scope_prefix}Record.pm")->as_file->store_if_empty ($entity_pm);
191              
192 0           $entity_pm = Project::Easy::Config::string_from_template (
193             $entity_template,
194             {
195             namespace => $namespace,
196             scope => $scope_prefix.'Collection', #
197             dbi_easy_scope => 'Record::Collection',
198             datasource => $datasource
199             }
200             );
201              
202 0           $project_lib->append ("${scope_prefix}Collection.pm")->as_file->store_if_empty ($entity_pm);
203              
204             }
205              
206             sub create_var {
207 0     0 0   my $root = shift;
208 0           my $var = $root->dir_io ('var');
209 0           foreach (qw(db lock log run)) {
210 0           $var->dir_io ($_)->create;
211             }
212            
213 0           return $var;
214             }
215              
216             sub shell {
217 0     0 0   my ($pack, $libs) = &_script_wrapper;
218            
219 0           my $core = $pack->singleton;
220            
221 0           my $instance = $ARGV[0];
222            
223 0           my $conf = $core->config ($instance);
224 0           my $sconf = $conf->{shell};
225            
226 0 0 0       unless (try_to_use 'Net::SSH::Perl' and try_to_use 'Term::ReadKey') {
227 0           die "for remote shell you must install Net::SSH::Perl and Term::ReadKey packages";
228             }
229            
230 0           my %args = ();
231 0           foreach (qw(compression cipher port debug identity_files use_pty options protocol)) {
232 0 0         $args{$_} = $sconf->{$_}
233             if $sconf->{$_};
234             }
235            
236 0           $args{interactive} = 1;
237            
238 0           my $ssh = Net::SSH::Perl->new ($conf->{host}, %args);
239 0           $ssh->login ($sconf->{user});
240            
241 0           ReadMode('raw');
242 0           eval "END { ReadMode('restore') };";
243 0           $ssh->shell;
244              
245             }
246              
247             sub _script_wrapper {
248             # because some calls dispatched to external scripts, but called from project dir
249 0   0 0     my $local_conf = shift || $0;
250 0   0       my $importing = shift || 0;
251 0           my $lib_path;
252            
253 0 0         return ($::project, $::libs)
254             if defined $::project;
255              
256 0           debug "called from $local_conf";
257            
258 0           $local_conf = dir ($local_conf);
259            
260 0           my $root;
261            
262 0 0 0       if (exists $ENV{'MOD_PERL'}) {
    0          
263            
264 0           my $server_root;
265            
266 0 0 0       if (
    0 0        
267             exists $ENV{MOD_PERL_API_VERSION}
268             and $ENV{MOD_PERL_API_VERSION} >= 2
269             and try_to_use_inc ('Apache2::ServerUtil')
270             ) {
271            
272 0           $server_root = Apache2::ServerUtil::server_root();
273            
274             } elsif (try_to_use_inc ('Apache')) {
275            
276 0           $server_root = Apache::server_root_relative('');
277            
278             } else {
279 0           die "you try to run project::easy under mod_perl, but we cannot work with your version. if you have mod_perl-1.99, use solution from CGI::minimal or upgrade your mod_perl";
280             }
281            
282 0           $root = dir ($server_root);
283 0           $local_conf = $root->dir_io (qw(etc project-easy));
284 0           $lib_path = $root->dir_io ("lib");
285            
286             } elsif ($local_conf->name eq 'project-easy' and $local_conf->parent->name eq 'etc') {
287             # TODO: use etc method from project package
288 0           $root = $local_conf->parent->parent;
289 0           $lib_path = $local_conf->parent->parent->dir_io ('lib');
290             } else {
291            
292 0           my $parent = $local_conf;
293 0           PROJECT_ROOT: while ($parent = $parent->parent) {
294            
295 0           foreach (qw(t cgi-bin tools bin)) {
296 0 0         if ($parent->name eq $_) {
297 0           $root = $parent->parent;
298 0           $local_conf = $root->file_io (qw(etc project-easy));
299 0           $lib_path = $root->dir_io ('lib');
300 0           last PROJECT_ROOT;
301             }
302             }
303            
304 0 0         last if ($parent->path eq $parent->parent->path);
305            
306             }
307 0 0         die unless defined $root;
308             }
309            
310 0           $lib_path = $lib_path->abs_path;
311            
312 0           debug "local conf is: $local_conf, lib path is: ",
313             join (', ', @LocalConf::paths, $lib_path), "\n";
314            
315 0           require $local_conf;
316              
317 0           push @INC, @LocalConf::paths, $lib_path->path;
318            
319 0           my $pack = $LocalConf::pack;
320            
321 0           debug "main project module is: $pack";
322              
323             #use Carp;
324             #$SIG{ __DIE__ } = sub { Carp::confess( @_ ) };
325            
326             # check for required directories, create if necessary
327 0 0         if (! -d $root->dir_io ('var')) {
328 0           create_var ($root);
329             }
330            
331             # here we check for real package availability
332            
333 0 0         eval "use Class::Easy; use IO::Easy; use DBI::Easy; " . ($importing ? '' : "use $pack;");
334 0 0         if ($@) {
335 0           die 'base modules fails: ', $@;
336             }
337              
338 0           my @result = ($::project, $::libs) = ($pack, [@LocalConf::paths, $lib_path->path]);
339            
340 0           return @result;
341             }
342              
343             sub table_from_package {
344 0     0 0   my $entity = shift;
345            
346 2     2   2306 lc join ('_', split /(?=\p{IsUpper}\p{IsLower})/, $entity);
  2         23  
  2         26  
  0            
347             }
348              
349             sub package_from_table {
350 0     0 0   my $table = shift;
351            
352 0           join '', map {ucfirst} split /_/, $table;
  0            
353             }
354              
355             1;
356              
357              
358             __DATA__