File Coverage

blib/lib/CIPP/Compile/NewSpirit.pm
Criterion Covered Total %
statement 13 15 86.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 20 90.0


line stmt bran cond sub pod time code
1             # $Id: NewSpirit.pm,v 1.23 2006/05/16 14:58:29 joern Exp $
2              
3             package CIPP::Compile::NewSpirit;
4              
5             @ISA = qw ( CIPP::Compile::Generator );
6              
7 1     1   468 use strict;
  1         2  
  1         25  
8 1     1   5 use Carp;
  1         1  
  1         1033  
9 1     1   2819 use FileHandle;
  1         12503  
  1         5  
10 1     1   497 use File::Basename;
  1         2  
  1         117  
11 1     1   915 use CIPP::Compile::Generator;
  0            
  0            
12              
13             sub new {
14             my $type = shift;
15             my %par = @_;
16             my ($shebang, $project_root, $project_prod, $mime_type) =
17             @par{'shebang','project_root','project_prod','mime_type'};
18              
19             confess "Please specify the following parameters:\n".
20             "project_root\n".
21             "Got: ".join(', ', keys(%par))."\n"
22             unless $project_root;
23            
24             my $self = bless $type->SUPER::new(@_), $type;
25              
26             my $back_prod_path = $self->get_program_name;
27             $back_prod_path =~ s!\.!/!g;
28             $back_prod_path =~ s![^/]+!..!g;
29              
30             $self->set_gen_ns_shebang ($shebang);
31             $self->set_gen_ns_project_root ($project_root);
32             $self->set_gen_ns_project_prod ($project_prod);
33             $self->set_gen_ns_back_prod_path ($back_prod_path);
34              
35             $self->get_state->{autoprint} = 1 if $mime_type ne 'cipp/dynamic';
36              
37             my $program_name = $self->get_program_name;
38             $program_name =~ s/^[^.]+/$self->get_project/e;
39             $self->{program_name} = $program_name;
40              
41             ( $self->{in_filename}, $self->{out_filename},
42             $self->{prod_filename}, $self->{dep_filename},
43             $self->{iface_filename}, $self->{err_filename},
44             $self->{http_filename} )
45             = $self->get_object_filenames;
46              
47             $self->set_err_copy_filename ($self->get_out_filename.".err");
48              
49             # cipp-html objects always depend on the base configuration
50             if ( $self->get_object_type eq 'cipp-html' ) {
51             $self->add_used_object (
52             name => "x.configuration",
53             ext => "cipp-base-config",
54             type => "cipp-base-conf",
55             );
56             $self->set_dont_cache (1);
57             }
58              
59             return $self;
60             }
61              
62             sub get_gen_ns_shebang { shift->{gen_ns_shebang} }
63             sub get_gen_ns_back_prod_path { shift->{gen_ns_back_prod_path} }
64             sub get_gen_ns_project_root { shift->{gen_ns_project_root} }
65             sub get_gen_ns_project_prod { shift->{gen_ns_project_prod} }
66              
67             sub set_gen_ns_shebang { shift->{gen_ns_shebang} = $_[1] }
68             sub set_gen_ns_back_prod_path { shift->{gen_ns_back_prod_path}= $_[1] }
69             sub set_gen_ns_project_root { shift->{gen_ns_project_root} = $_[1] }
70             sub set_gen_ns_project_prod { shift->{gen_ns_project_prod} = $_[1] }
71              
72             #---------------------------------------------------------------------
73             # This interface must be implemented by the Generator/* modules
74             #---------------------------------------------------------------------
75              
76             sub create_new_parser {
77             my $self = shift; $self->trace_in;
78             my %par = @_;
79             my ($object_type, $program_name, $in_filename, $in_fh) =
80             @par{'object_type','program_name','in_filename','in_fh'};
81            
82             my $parser = (ref $self)->new (
83             object_type => $object_type,
84             program_name => $program_name,
85             in_filename => $in_filename,
86             in_fh => $in_fh,
87             project => $self->get_project,
88             start_context => $self->get_start_context, # ??? not actual context?
89             shebang => $self->get_gen_ns_shebang,
90             project_root => $self->get_gen_ns_project_root,
91             lib_path => $self->get_lib_path,
92             );
93              
94             $parser->set_inc_trace (
95             $self->get_inc_trace.$self->get_normalized_object_name (
96             name => $program_name
97             ).":"
98             );
99            
100             return $parser;
101             }
102              
103             sub generate_start_program {
104             my $self = shift; $self->trace_in;
105              
106             $self->write($self->get_gen_ns_shebang, "\n\n");
107             $self->write ("use strict;\n\n");
108             $self->write ("package main;\n\n");
109             $self->write ('my ($_cipp_project, $_cipp_line_nr);'."\n\n");
110              
111             1;
112             }
113              
114             sub generate_project_handler {
115             my $self = shift; $self->trace_in;
116            
117             $self->writef (<<'__EOC'
118             use CIPP::Runtime::NewSpirit;
119              
120             BEGIN {#
121             #-- Do initialization in a BEGIN block, to get a proper
122             #-- @INC, so "use Some::Module::Coded::In::CIPP" will work.
123             CIPP::Runtime::NewSpirit::Project->init (
124             project => "%s",
125             back_prod_path => "%s",
126             );
127             }
128              
129             #-- Do initialization (again). We couldn't get the $_cipp_project
130             #-- Variable out of the BEGIN{} block above, so we need to
131             #-- get it here. Also the BEGIN block above is executed only once
132             #-- in persistent environments (mod_perl, SpeedyCGI). Double
133             #-- initialization is prevented by the init() method itself, the
134             #-- overhead here is minimal.
135             $_cipp_project = CIPP::Runtime::NewSpirit::Project->init (
136             project => "%s",
137             back_prod_path => "%s",
138             );
139             __EOC
140             , $self->get_project,
141             $self->get_gen_ns_back_prod_path,
142             $self->get_project,
143             $self->get_gen_ns_back_prod_path,
144             );
145             }
146              
147             sub generate_open_request {
148             my $self = shift; $self->trace_in;
149            
150             $self->write (
151             '$_cipp_project->new_request ('."\n",
152             ' program_name => "'.$self->get_program_name.'",'."\n",
153             ' mime_type => "'.$self->get_mime_type,'",'."\n",
154             ');'."\n\n",
155             );
156            
157             if ( not $self->get_no_http_header ) {
158             my $http_header_file = $self->custom_http_header_file;
159             if ( $http_header_file ) {
160             $self->writef (
161             '$CIPP::request->print_http_header ('."\n".
162             ' custom_http_header_file => "%s",'."\n".
163             ');'."\n",
164             $http_header_file
165             );
166             } else {
167             $self->write (
168             '$CIPP::request->print_http_header;'."\n",
169             );
170             }
171             }
172              
173             1;
174             }
175              
176             sub get_normalized_object_name {
177             my $self = shift; $self->trace_in;
178             my %par = @_;
179             my ($name) = @par{'name'};
180            
181             $name =~ s/^[^.]+\.//;
182             $name =~ tr!.!/!;
183            
184             return $name;
185             }
186              
187             sub get_object_filename {
188             my $self = shift; $self->trace_in;
189             my %par = @_;
190             my ($name, $name_is_normalized) =
191             @par{'name','name_is_normalized'};
192              
193             my $file;
194             if ( $name_is_normalized ) {
195             $file = $name;
196             } else {
197             $file = $self->get_normalized_object_name ( name => $name );
198             }
199              
200             $file = $self->get_gen_ns_project_root."/src/".$file;
201              
202             my $dir = dirname $file;
203             my $filename = basename $file;
204              
205             my $dh = FileHandle->new;
206             opendir $dh, $dir or return;
207             my @filenames = grep (!/\.m$/, (grep /^$filename\.[^\.]+$/, readdir $dh));
208             closedir $dh;
209            
210             return if scalar @filenames != 1;
211             return $dir."/".$filenames[0];
212             }
213              
214             sub determine_object_type {
215             my $self = shift; $self->trace_in;
216             my %par = @_;
217             my ($name, $filename) = @par{'name','filename'};
218              
219             confess "name *and* filename given" if $name and $filename;
220              
221             $filename ||= $self->get_object_filename ( name => $name );
222             return if not defined $filename;
223              
224             $filename =~ /\.([^\.]+)$/;
225              
226             my $ext = $1;
227             my $type = $ext;
228            
229             if ( $ext =~ /^(gif|jpg|jpeg|jpe|png)$/i ) {
230             $type = 'cipp-img';
231             } elsif ( $ext eq 'ns-unknown' ) {
232             $type = 'generic';
233             } elsif ( $ext =~ /^(jar|cab|class|properties)$/i ) {
234             $type = 'jar';
235             } elsif ( $ext =~ /^cipp-/ and
236             $ext !~ /^cipp-(config|db|module|inc|sql)$/ ) {
237             $type = 'cipp-html';
238             } elsif ( $ext =~ /^(js|css|txt|html)$/ ) {
239             $type = 'text'
240             }
241            
242             return $type;
243             }
244              
245             sub get_object_url {
246             my $self = shift; $self->trace_in;
247             my %par = @_;
248             my ($name, $add_message_if_has_no) =
249             @par{'name','add_message_if_has_no'};
250              
251             my $object_url;
252             eval {
253             my $filename = $self->get_object_filename ( name => $name ) or die;
254             my $object_type = $self->determine_object_type ( filename => $filename ) or die;
255              
256             my $src_dir = $self->get_gen_ns_project_root."/src";
257             $filename =~ s!^$src_dir/?!!;
258             $filename =~ s!\.([^\.]+)$!!;
259             my $ext = $1;
260              
261             if ( $object_type eq 'cipp' ) {
262             $object_url = '}.$CIPP::request->get_cgi_url.qq{/'.$filename.'.cgi';
263              
264             } elsif ( $object_type eq 'cipp-html' or $object_type eq 'text' or
265             $object_type eq 'jar' ) {
266             $ext =~ m!cipp-(.*)$!;
267             $object_url = '}.$CIPP::request->get_doc_url.qq{/'.$filename.".$1";
268              
269             } elsif ( $object_type eq 'cipp-img' or $object_type eq 'blob' ) {
270             $object_url = '}.$CIPP::request->get_doc_url.qq{/'.$filename.".".$ext;
271              
272             } elsif ( $object_type eq 'generic' ) {
273             my $meta_file = $self->get_object_filename ( name => $name ).".m";
274             die if not -r $meta_file;
275             my $meta_data = do $meta_file;
276             die if not $meta_data->{install_target_dir};
277             $filename =~ s![^/]+$!!;
278             my $orig_filename = $meta_data->{_original_filename};
279             if ( $meta_data->{install_target_dir} eq 'htdocs' ) {
280             $object_url = '}.$CIPP::request->get_doc_url.qq{'.
281             $filename.'/'.$orig_filename;
282             } else {
283             $object_url = '}.$CIPP::request->get_cgi_url.qq{'.
284             $filename.'/'.$orig_filename;
285             }
286             $object_url =~ s!/+!/!g;
287             } else {
288             confess "unknown object type '$object_type'";
289             }
290             };
291              
292             $self->add_tag_message (
293             message => "The object '$name' has no URL."
294             ) if not $object_url and $add_message_if_has_no;
295              
296             return $object_url;
297             }
298              
299             sub get_object_filenames {
300             my $self = shift; $self->trace_in;
301             my %par = @_;
302             my ($norm_name, $object_type) =
303             @par{'norm_name','object_type'};
304              
305             $norm_name ||= $self->get_normalized_object_name
306             ( name => $self->get_program_name );
307             $object_type ||= $self->get_object_type;
308              
309             my $base_dir = $self->get_gen_ns_project_root;
310             my $project = $self->get_project;
311             my $prod_dir = $self->get_gen_ns_project_prod;
312            
313             $prod_dir ||= "$base_dir/prod";
314              
315             my ($in_filename, $out_filename, $prod_filename,
316             $dep_filename, $iface_filename, $err_filename,
317             $http_filename);
318            
319             if ( $object_type eq 'cipp-inc' ) {
320             $in_filename = "$base_dir/src/$norm_name.cipp-inc";
321             $out_filename = "$prod_dir/inc/$norm_name.code";
322             $prod_filename = "$prod_dir/inc/$norm_name.code";
323             $dep_filename = "$base_dir/meta/##cipp_dep/$norm_name.dep";
324             $iface_filename = "$base_dir/meta/##cipp_dep/$norm_name.iface";
325             $err_filename = "$base_dir/meta/##cipp_dep/$norm_name.err";
326             $http_filename = "$prod_dir/inc/$norm_name.http";
327              
328             } elsif ( $object_type eq 'cipp' ) {
329             $in_filename = "$base_dir/src/$norm_name.cipp";
330             $out_filename = "$prod_dir/cgi-bin/$project/$norm_name.cgi";
331             $prod_filename = "$prod_dir/cgi-bin/$project/$norm_name.cgi";
332             $dep_filename = "$base_dir/meta/##cipp_dep/$norm_name.dep";
333             $iface_filename = "";
334             $err_filename = "$base_dir/meta/##cipp_dep/$norm_name.err";
335             $http_filename = "$prod_dir/inc/$norm_name.http";
336              
337             } elsif ( $object_type eq 'cipp-html' ) {
338             my $src_filename = $self->get_object_filename (
339             name => $norm_name,
340             name_is_normalized => 1
341             );
342              
343             confess "can't resolve source filename for object '$norm_name'"
344             if not $src_filename;
345              
346             $src_filename =~ /cipp-(.*)$/;
347             my $ext = $1;
348            
349             $in_filename = "$base_dir/src/$norm_name.cipp-$ext";
350             $out_filename = "/tmp/cipp_html_$$";
351             $prod_filename = "$prod_dir/htdocs/$project/$norm_name.$ext";
352             $dep_filename = "$base_dir/meta/##cipp_dep/$norm_name.dep";
353             $iface_filename = "";
354             $err_filename = "$base_dir/meta/##cipp_dep/$norm_name.err";
355             $http_filename = "";
356              
357             } elsif ( $object_type eq 'cipp-module' ) {
358             my $module_name = $self->get_module_name;
359             $module_name =~ s!::!/!g;
360            
361             $in_filename = "$base_dir/src/$norm_name.cipp-module";
362             $out_filename = "/tmp/cipp_module_$$";
363            
364             if ( not $module_name ) {
365             $prod_filename = "/tmp/cipp_module_$$";
366             } else {
367             $prod_filename = "$prod_dir/lib/$module_name.pm";
368             }
369              
370             $dep_filename = "$base_dir/meta/##cipp_dep/$norm_name.dep";
371             $iface_filename = "";
372             $err_filename = "$base_dir/meta/##cipp_dep/$norm_name.err";
373             $http_filename = "";
374              
375             } else {
376             confess "unknown object type '$object_type'";
377             }
378              
379             return ($in_filename, $out_filename,
380             $prod_filename, $dep_filename,
381             $iface_filename, $err_filename,
382             $http_filename);
383             }
384              
385             sub get_relative_inc_path {
386             my $self = shift;
387             my %par = @_;
388             my ($filename) = @par{'filename'};
389            
390             my $base_dir = $self->get_gen_ns_project_root;
391            
392             $filename =~ s!^$base_dir/prod/inc/!!;
393            
394             return $filename;
395             }
396              
397             sub determine_text_domain {
398             my $self = shift;
399            
400             my $last_dir = $self->get_in_filename;
401              
402             while ( 1 ) {
403             my $dir = dirname($last_dir);
404             last if $last_dir eq $dir;
405             $last_dir = $dir;
406             my $file = "$dir/po/domain.text-domain";
407             if ( -f $file ) {
408             open (my $fh, $file) or die "can't read $file";
409             my $domain = <$fh>;
410             chomp $domain;
411             close $fh;
412             return $domain;
413             }
414             }
415              
416             return;
417             }
418              
419             1;