2 # This file is part of App::CPAN2Pkg.
3 # Copyright (c) 2009 Jerome Quelin, all rights reserved.
5 # This program is free software; you can redistribute it and/or modify
6 # it under the same terms as Perl itself.
10 package App
::CPAN2Pkg
::Module
;
17 constructor
=> '_new',
20 shortname
=> 'shortname',
22 _prereqs
=> '_prereqs',
26 use POE
::Filter
::Line
;
31 # $ apt-file find Audio/MPD.pm
32 # libaudio-mpd-perl: /usr/share/perl5/Audio/MPD.pm
34 # - find dist hosting module
35 # - computing dependencies
36 # - installing dependencies
37 # - check cooker availability
40 # - check local availability
43 # - wait for kenobi build
53 my ($class, $module) = @_;
58 $short =~ s/[[:lower:]]//g;
59 my $obj = App
::CPAN2Pkg
::Module
->_new(
66 # spawning the session
67 my $session = POE
::Session
->create(
70 find_prereqs
=> \
&find_prereqs
,
71 is_in_dist
=> \
&is_in_dist
,
72 is_installed
=> \
&is_installed
,
74 _find_prereqs
=> \
&_find_prereqs
,
75 _is_in_dist
=> \
&_is_in_dist
,
80 _stop
=> sub { warn "stop"; },
94 my ($k, $self) = @_[KERNEL
, HEAP
];
97 my $module = $self->name;
98 my $cmd = "cpanp /prereqs show $module";
99 $self->_log_new_step('Finding module prereqs', "Running command: $cmd" );
104 my $wheel = POE
::Wheel
::Run
->new(
106 CloseEvent
=> '_find_prereqs',
107 StdoutEvent
=> '_stdout',
108 StderrEvent
=> '_stderr',
109 StdoutFilter
=> POE
::Filter
::Line
->new,
110 StderrFilter
=> POE
::Filter
::Line
->new,
113 # need to store the wheel, otherwise the process goes woo!
114 $self->_wheel($wheel);
118 my ($k, $self) = @_[KERNEL
, HEAP
];
121 my $name = $self->name;
122 my $cmd = "urpmq --whatprovides 'perl($name)'";
123 $self->_log_new_step('Checking if packaged upstream', "Running command: $cmd" );
128 my $wheel = POE
::Wheel
::Run
->new(
130 #CloseEvent => '_is_in_dist', # FIXME: cf rt#42757
131 StdoutEvent
=> '_stdout',
132 StderrEvent
=> '_stderr',
133 Conduit
=> 'pty-pipe', # urpmq wants a pty
134 StdoutFilter
=> POE
::Filter
::Line
->new,
135 StderrFilter
=> POE
::Filter
::Line
->new,
137 $k->sig( CHLD
=> '_is_in_dist' );
139 # need to store the wheel, otherwise the process goes woo!
140 $self->_wheel($wheel);
145 my ($k, $self) = @_[KERNEL
, HEAP
];
147 my $name = $self->name;
148 my $cmd = qq{ require $name };
149 $self->_log_new_step(
150 'Checking if module is installed',
151 "Evaluating command: $cmd"
155 my $what = $@
|| "$name loaded successfully\n";
156 $k->post('ui', 'append', $self, $what);
158 my $event = $@ ?
'module_not_installed' : 'module_installed';
159 my $status = $@ ?
'not installed' : 'installed';
160 $self->_log_result("$name is $status locally.");
161 $k->post('app', $event, $self);
167 my ($k, $self, $id) = @_[KERNEL
, HEAP
, ARG0
];
170 my $wheel = $self->_wheel;
171 $self->_wheel(undef);
176 split /\n/, $self->_output;
177 shift @lines; # remove the title line
179 map { (split /\s+/, $_)[0] }
183 foreach my $prereq ( @prereqs ) {
184 $k->post('ui', 'append', $self, "prereq found: $prereq\n");
185 $self->_prereqs->{$prereq} = 1;
188 $k->post('app', 'prereqs', $self, @prereqs);
192 my($k, $self, $pid, $rv) = @_[KERNEL
, HEAP
, ARG1
, ARG2
];
194 # since it's a sigchld handler, it also gets called for other
195 # spawned processes. therefore, screen out processes that are
196 # not related to this object.
197 return unless defined $self->_wheel;
198 return unless $self->_wheel->PID == $pid;
201 # FIXME: should be done in CloseEvent
202 $self->_wheel(undef);
204 # check if we got a hit
205 # urpmq returns 0 if found, 1 otherwise.
206 my $name = $self->name;
207 my $exval = $rv >> 8;
210 $self->_log_result( "$name is already packaged upstream." );
211 $k->post('app', 'module_available', $self);
213 $self->_log_result( "$name is not packaged upstream." );
214 $k->post('app', 'module_not_available', $self);
219 my ($k, $self, $line) = @_[KERNEL
, HEAP
, ARG0
];
220 $k->post('ui', 'append', $self, "stderr: $line\n");
224 my ($k, $self, $line) = @_[KERNEL
, HEAP
, ARG0
];
226 $self->_output( $self->_output . $line );
227 $k->post('ui', 'append', $self, "stdout: $line");
231 # -- poe inline states
234 my ($k, $self) = @_[KERNEL
, HEAP
];
236 $k->alias_set($self);
237 $k->post('ui', 'new_module', $self);
238 $k->post('app', 'new_module', $self);
247 sub _log_empty_line
{
248 my ($self, $nb) = @_;
249 $nb //= 1; #/ FIXME padre syntaxic color glitch
250 POE
::Kernel
->post('ui', 'append', $self, "\n" x
$nb);
253 sub _log_prefixed_lines
{
254 my ($self, @lines) = @_;
257 POE
::Kernel
->post('ui', 'append', $self, $_)
258 for map { "$prefix $_\n" } @lines;
262 my ($self, $step, $comment) = @_;
264 $self->_log_prefixed_lines('-' x
10, $step, '', $comment, '');
265 $self->_log_empty_line;
269 my ($self, $text) = @_;
271 $self->_log_empty_line;
272 $self->_log_prefixed_lines( '', $text, '', '' );
282 App::CPAN2Pkg::Module - poe session to drive a module packaging
288 C<App::CPAN2Pkg::Module> implements a POE session driving the whole
289 packaging process of a given module.
291 It is spawned by C<App::CPAN2Pkg> and implements the logic related to
292 the module availability in the distribution.
296 =head1 PUBLIC PACKAGE METHODS
298 =head2 my $id = App::CPAN2Pkg::Module->spawn( $module )
300 This method will create a POE session responsible for packaging &
301 installing the wanted C<$module>.
303 It will return the POE id of the session newly created.
307 =head1 PUBLIC EVENTS ACCEPTED
309 =head2 find_prereqs()
311 Start looking for any other module needed by current module.
316 Check whether the package is provided by an existing upstream package.
321 This package is also a class, used B<internally> to store private data
322 needed for the packaging stuff. The following accessors are therefore
323 available, but should not be used directly:
327 =item name() - the module name
329 =item shortname() - the module shortname (only capital letters)
337 For all related information (bug reporting, source code repository,
338 etc.), refer to C<App::CPAN2Pkg>'s pod, section C<SEE ALSO>.
344 Jerome Quelin, C<< <jquelin@cpan.org> >>
348 =head1 COPYRIGHT & LICENSE
350 Copyright (c) 2009 Jerome Quelin, all rights reserved.
352 This program is free software; you can redistribute it and/or modify
353 it under the same terms as Perl itself.