/[cvs]/nfo/perl/libs/Data/Rap/Engine.pm
ViewVC logotype

Diff of /nfo/perl/libs/Data/Rap/Engine.pm

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.3 by joko, Fri Feb 21 01:46:17 2003 UTC revision 1.15 by joko, Wed Jun 16 16:37:59 2004 UTC
# Line 2  Line 2 
2  ##  $Id$  ##  $Id$
3  ## ----------------------------------------------------------------------  ## ----------------------------------------------------------------------
4  ##  $Log$  ##  $Log$
5    ##  Revision 1.15  2004/06/16 16:37:59  joko
6    ##  attempt to get things going in a generic way (Linux/FreeBSD/Win32)
7    ##
8    ##  Revision 1.14  2004/05/12 14:23:31  jonen
9    ##   add comment/code related to PERL5LIB var at different OS's
10    ##
11    ##  Revision 1.13  2003/12/05 05:02:08  joko
12    ##  + minor update: disabled some unnecessary loggers or changed to debug-level
13    ##
14    ##  Revision 1.12  2003/06/24 20:59:51  jonen
15    ##  added option 'detach'
16    ##
17    ##  Revision 1.11  2003/06/23 17:54:32  joko
18    ##  prepared execution of in-process perl-code via eval (not activated yet!)
19    ##
20    ##  Revision 1.10  2003/05/13 07:56:12  joko
21    ##  enhanced: *hierarchical* containers for context handling
22    ##  fixes: some pre-flight checks
23    ##  new: propagate "end-tag" event to e.g. close containers
24    ##
25    ##  Revision 1.9  2003/04/04 17:23:11  joko
26    ##  minor update: debugging output
27    ##
28    ##  Revision 1.8  2003/03/29 07:11:54  joko
29    ##  modified: sub run_executable
30    ##  new: sub run_script
31    ##
32    ##  Revision 1.7  2003/03/28 07:02:56  joko
33    ##  modified structure around '$wrapper_program'
34    ##
35    ##  Revision 1.6  2003/03/27 15:31:05  joko
36    ##  fixes to modules regarding new namespace(s) below Data::Mungle::*
37    ##
38    ##  Revision 1.5  2003/03/27 15:03:03  joko
39    ##  enhanced 'sub run_executable'
40    ##
41    ##  Revision 1.4  2003/02/22 16:51:21  joko
42    ##  + enhanced run_executable
43    ##  modified logging output
44    ##
45  ##  Revision 1.3  2003/02/21 01:46:17  joko  ##  Revision 1.3  2003/02/21 01:46:17  joko
46  ##  renamed core function  ##  renamed core function
47  ##  ##
# Line 26  use Data::Dumper; Line 66  use Data::Dumper;
66  use Hash::Merge qw( merge );  use Hash::Merge qw( merge );
67  use Iterate;  use Iterate;
68    
69  use shortcuts qw( run_cmd );  use shortcuts qw( run_cmd RUNNING_IN_HELL );
70  use Data::Code::Ref qw( ref_slot );  use Data::Mungle::Code::Ref qw( ref_slot );
71  use Data::Transform::Deep qw( expand );  use Data::Mungle::Transform::Deep qw( expand deep_copy );
72    use File::Temp qw/ tempfile tempdir /;
73    
74    my $DEBUG = 0;
75    
76  sub performTarget {  sub performTarget {
77    my $self = shift;    my $self = shift;
# Line 41  sub perform_target { Line 83  sub perform_target {
83    my $self = shift;    my $self = shift;
84    my $targetname = shift;    my $targetname = shift;
85    
86      # pre-flight checks
87      if (!$targetname) {
88        $self->log("Target name empty. Please try to specify (e.g.) on the command line.", 'critical');
89        return;
90      }
91    
92      my $header = ("- " x 12) . "   " . $targetname . "   " . ("- " x 6);
93      
94      # V1
95      #$self->log("- " x 35, 'notice');
96      #$self->log("Performing Target '$targetname'.", 'notice');
97    
98      # V2
99      #$self->log($header, 'notice');
100    
101      # V3
102      #$self->log("- " x 20, 'info');
103    $self->log("Performing Target '$targetname'.", 'notice');    $self->log("Performing Target '$targetname'.", 'notice');
104    
105    #exit;    #exit;
# Line 53  sub perform_target { Line 112  sub perform_target {
112            
113    $self->perform_dependencies($target);    $self->perform_dependencies($target);
114    $self->perform_details($target);    $self->perform_details($target);
115      
116      return 1;
117    
118  }  }
119    
# Line 84  sub perform_details { Line 145  sub perform_details {
145    foreach my $entry (@{$target->{content}}) {    foreach my $entry (@{$target->{content}}) {
146      my $command = $entry->{name};      my $command = $entry->{name};
147      my $args = $entry->{attrib};      my $args = $entry->{attrib};
148      $self->perform_command($command, $args);      my $content = $entry->{content};
149        $self->perform_command($command, $args, $content, { warn => 1 } );
150      # check recursiveness      # check recursiveness
151      if ($entry->{content} && ref $entry->{content}) {      # new condition: don't recurse if node is flagged to have inline-args (2003-04-17)
152        my $has_inline_args = ($entry->{attrib}->{_args} && $entry->{attrib}->{_args} eq 'inline');
153        if ($entry->{content} && ref $entry->{content} && !$has_inline_args) {
154        $self->perform_details($entry);        $self->perform_details($entry);
155      }      }
156        # new of 2003-05-08
157        $command ||= '';
158        $self->perform_command($command . '_end', undef, undef, { warn => 0 } );
159    }    }
160  }  }
161    
# Line 100  sub rc { Line 167  sub rc {
167  sub perform_command {  sub perform_command {
168    my $self = shift;    my $self = shift;
169    my $command = shift;    my $command = shift;
170      my $args_list = shift;
171      my $content = shift;
172      my $options = shift;
173    
174    if (!$command) {    if (!$command) {
175      $self->log("Command was empty!", 'warning');      $self->log("Command was empty!", 'debug') if $DEBUG;
176      return;      return;
177    }    }
178    
179    # FIXME: make '__PACKAGE__' go one level deeper properly!    # FIXME: make '__PACKAGE__' go one level deeper properly!
180    $self->log( __PACKAGE__ . "->perform_command: " . $command, 'debug');    $self->log( __PACKAGE__ . "->perform_command: " . $command, 'debug') if $DEBUG;
181        
182    my $args_list = shift;    
183      # 1. make arguments from list of arguments(?)
184    
185    my $args = {};    my $args = {};
186    #print Dumper($args_list);    #print Dumper($args_list);
187    if ($args_list) {    if ($args_list) {
# Line 121  sub perform_command { Line 193  sub perform_command {
193        $args = $args_list;        $args = $args_list;
194      }      }
195    }    }
   $command = '_' . $command;  
196        
197        
198    # determine container    # 2. prepare command
199      
200      # default setting for internal rap commands
201      my $method_prefix_default = '_';
202      # setting from property database
203      my $method_prefix_setting = $self->get_property('core.method_prefix');
204      #print "setting: ", $method_prefix_setting, "\n";
205      my $prefix = $method_prefix_setting;
206      if (not defined $prefix) {
207        $prefix = $method_prefix_default;
208      }
209      $command = $prefix . $command;
210      
211      
212      # 3. determine container
213    my $container; # = $self->getInstance();    my $container; # = $self->getInstance();
214      #$container ||= $self->getInstance();
215    $container ||= $self;    $container ||= $self;
216        
217      # 4. run method
218    if ($container->can($command)) {    if ($container->can($command)) {
219      $container->$command($args);      $container->$command($args, $content);
220    } else {    } else {
221      $self->log("Command '$command' not implemented.", "warning");      my $level = "debug";
222        $level = "warning" if $options->{warn};
223        $self->log("Command '$command' not implemented.", $level) if $DEBUG;
224    }    }
225        
226  }  }
# Line 195  sub set_property { Line 284  sub set_property {
284    
285    $self->log("set-name: $name");    $self->log("set-name: $name");
286    
287      #print Dumper($name, $value, '.');
288    
289    # fill property slot with given value    # fill property slot with given value
290    if ($value) {    # fix (2003-04-17): always do fill if value is *defined*!!!
291      if (defined $value) {
292      ref_slot($self, $name, $value, '.');      ref_slot($self, $name, $value, '.');
293    }    }
294        
# Line 255  sub get_property { Line 347  sub get_property {
347    
348      $name = '__rap.properties.' . $name;      $name = '__rap.properties.' . $name;
349            
350      $self->log("get-name: $name");      $self->log("get-name: $name") if $DEBUG;
351            
352      # get property slot and return value      # get property slot and return value
353      $result = ref_slot($self, $name, undef, '.');      $result = ref_slot($self, $name, undef, '.');
# Line 282  sub run_executable { Line 374  sub run_executable {
374    my $self = shift;    my $self = shift;
375    my $opts = shift;    my $opts = shift;
376    
377      my $meta = deep_copy($opts);
378    
379      delete $opts->{caption};
380      delete $opts->{async};
381      delete $opts->{detach};
382    
383      #print Dumper($meta);
384    
385    if ($opts->{executable}) {    if ($opts->{executable}) {
386    
387      my $program = $opts->{executable};      my $program = $opts->{executable};
388      delete $opts->{executable};      delete $opts->{executable};
389    
390        # determine execution method
391        my $wrapper_program = '';
392        
393        # check if program is a namespace-string (contains '::') - use 'do' in this case!
394        if ($program =~ /::/) {
395          #$wrapper_program = 'rap.pl';
396          $wrapper_program = $0;
397        }
398    
399        # prepare arguments
400      my @buf;      my @buf;
401      foreach (keys %$opts) {      foreach (keys %$opts) {
402        my $value = $opts->{$_};        my $value = $opts->{$_};
403          if (m/^_/) {
404            if ($_ eq '_switches') {
405              my @switches = split(/,\s|,/, $value);
406              foreach my $switch (@switches) {
407                push @buf, '--' . $switch;
408              }
409            }
410            next;
411          }
412          
413        if ($value =~ /\s/) {        if ($value =~ /\s/) {
414          $value = "\"$value\"";          $value = "\"$value\"";
415        }        }
416        push @buf, "--$_=$value";        push @buf, "--$_=$value";
417      }      }
418      
419      my $cmd = $program . ' ' . join(' ', @buf);      # build {program} & {arguments}  
420        my $cmd = ($wrapper_program ? $wrapper_program . ' ' : '') . $program . ' ' . join(' ', @buf);
421            
422      # trace      # trace
423        #print "command: $cmd", "\n";        #print "command: $cmd", "\n";
424            
425      # start process      # start process
426        # V1: via shortcut        # 2004-05-11 - seems like only ONE args is valid at PERL5LIB, so we use V2!
427        #$ENV{PERL5LIB} = join(' ', @INC);        # 2004-06-16 - found out delimiter required for PERL5LIB, reverting back to V1!
428                
429        # FIXME!!! what about the other slots of @INC?        # V1: join all args
430        $ENV{PERL5LIB} = $INC[0];        my $delimiter = ':';
431          $delimiter = ';' if RUNNING_IN_HELL();
432          $ENV{PERL5LIB} = join($delimiter, @INC);
433          # V2: insert only FIRST arg
434          #$ENV{PERL5LIB} = $INC[0];
435          # WARNING: at (free)BSD our var is the SECOND, NOT FIRST!!
436          # FIXME!! Do this in an abstract way!!
437          #$ENV{PERL5LIB} = $INC[1];
438                
439        #print Dumper(%ENV);        #print Dumper(%ENV);
440        run_cmd($cmd);        
441          #print "command: '$cmd'", "\n";
442    
443          # V1 - basic
444          #run_cmd($cmd);
445    
446          # V1.b - enhanced: variable local method
447          $meta->{caption} ||= '';
448          $meta->{async} ||= 0;
449          $meta->{detach} ||= 0;
450          # new of 2003-05-08: USE_PATH!
451          $meta->{USE_PATH} ||= 0;
452          my $evalstr = "run_cmd('$cmd', '$meta->{caption}', { async => $meta->{async}, detach => $meta->{detach}, USE_PATH => $meta->{USE_PATH} });";
453          eval($evalstr);
454          #my $res = do "$cmd";
455          #print $res, "\n" if $res;
456    
457          #$self->log("run_executable: $evalstr", 'info');
458          $self->raiseException("run_executable: $evalstr\n$@") if $@;
459    
460        # V2: via IPC::Run        # V2: via IPC::Run
461        # ....  (TODO)        # ....  (TODO)
462              
463            
464    }    }
465        
466  }  }
467    
468    
469    sub run_script {
470    
471      my $self = shift;
472      my $args = shift;
473      my $code = shift;
474    
475      if ($args->{language} eq 'msdos/bat') {
476        
477        #print "code: $code", "\n";
478        
479        # reporting
480        $self->log("Executing some arbitrary unsigned code (probably unsafe). [language=$args->{language}]", 'info');
481        $self->log("\n<code>\n$code\n</code>", 'info');
482        
483        # create temporary intermediate file to execute code
484        my $tmpdir = '/tmp/rap';
485        mkdir $tmpdir;
486        (my $fh, my $filename) = tempfile( DIR => $tmpdir, SUFFIX => '.bat' );
487        print $fh $code, "\n";
488        run_cmd( $filename, '', { async => 1 } );
489        
490        # FIXME: DELETE code inside temp-files as soon as possible!
491        #print $fh '';
492        
493        # TODO: delete FILE completely!
494        # required for this: wait until execution has finished, then unlink....
495        # but: "how to wait until execution is finished"?
496        # i believe the best is to spawn *another* process directly from here,
497        # let's call it 'watcher-agent'.
498        # This one should monitor a certain running process and delete its
499        # executable file after it has finished execution.
500        # Possible extensions could be:
501        #   keep track of all stuff sent to STDOUT or STDERR and
502        #   send that stuff to the task-owner indirectly (not via shell/console)
503        #   (e.g. via email, by posting report to a newsgroup or publishing on a specified web-page: use mod-dav!)
504        
505      } elsif ($args->{language} eq 'bash') {
506        $self->log("FIXME: - - - - - -- - - --  BASH -  - -    -  - -   -    --   - ", 'error');
507    
508      } elsif ($args->{language} eq 'perl') {
509        
510        # reporting
511        #$self->log("Executing some arbitrary unsigned code (probably unsafe). [language=$args->{language}]", 'info');
512        #$self->log("\n<code>\n$code\n</code>", 'info');
513        
514        # do it
515        #eval($code);
516        #$self->log("\n<code>\n$code\n</code>", 'error') if $@;
517        
518      } else {
519        $self->log("FIXME: Script language '$args->{language}' not implemented.", 'error');
520        
521      }
522    
523    }
524    
525  1;  1;
526  __END__  __END__

Legend:
Removed from v.1.3  
changed lines
  Added in v.1.15

MailToCvsAdmin">MailToCvsAdmin
ViewVC Help
Powered by ViewVC 1.1.26 RSS 2.0 feed