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
;
16 constructor
=> '_new',
19 shortname
=> 'shortname',
21 _prereqs
=> '_prereqs',
25 use POE
::Filter
::Line
;
32 # if ( not available in cooker ) is_in_dist
34 # compute dependencies find_prereqs
35 # repeat with each dep
37 # install local install_from_local
38 # while ( not available locally ) is_installed
40 # prompt user to fix manually
42 # import import_local_to_dist
43 # submit (included above)
44 # ack available (manual?)
47 # urpmi --auto perl(module::to::install) install_from_dist
51 # $ apt-file find Audio/MPD.pm
52 # libaudio-mpd-perl: /usr/share/perl5/Audio/MPD.pm
54 # - find dist hosting module
55 # - computing dependencies
56 # - installing dependencies
57 # - check cooker availability
60 # - check local availability
63 # - wait for kenobi build
73 my ($class, $module) = @_;
78 $short =~ s/[[:lower:]]//g;
79 my $obj = App
::CPAN2Pkg
::Module
->_new(
86 # spawning the session
87 my $session = POE
::Session
->create(
90 find_prereqs
=> \
&find_prereqs
,
91 is_in_dist
=> \
&is_in_dist
,
93 _find_prereqs
=> \
&_find_prereqs
,
94 _is_in_dist
=> \
&_is_in_dist
,
99 _stop
=> sub { warn "stop"; },
113 my ($k, $self) = @_[KERNEL
, HEAP
];
116 my $module = $self->name;
117 my $cmd = "cpanp /prereqs show $module";
118 $self->_log_new_step($k, 'Finding module prereqs',
119 "Running command: $cmd" );
124 my $wheel = POE
::Wheel
::Run
->new(
126 CloseEvent
=> '_find_prereqs',
127 StdoutEvent
=> '_stdout',
128 StderrEvent
=> '_stderr',
129 StdoutFilter
=> POE
::Filter
::Line
->new,
130 StderrFilter
=> POE
::Filter
::Line
->new,
133 # need to store the wheel, otherwise the process goes woo!
134 $self->_wheel($wheel);
138 my ($k, $self) = @_[KERNEL
, HEAP
];
141 my $name = $self->name;
142 my $cmd = "urpmq --whatprovides 'perl($name)'";
143 $self->_log_new_step($k, 'Checking if packaged upstream',
144 "Running command: $cmd" );
149 my $wheel = POE
::Wheel
::Run
->new(
151 #CloseEvent => '_is_in_dist', # FIXME: cf rt#42757
152 StdoutEvent
=> '_stdout',
153 StderrEvent
=> '_stderr',
154 Conduit
=> 'pty-pipe', # urpmq wants a pty
155 StdoutFilter
=> POE
::Filter
::Line
->new,
156 StderrFilter
=> POE
::Filter
::Line
->new,
158 $k->sig( CHLD
=> '_is_in_dist' );
160 # need to store the wheel, otherwise the process goes woo!
161 $self->_wheel($wheel);
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 my $name = $self->name;
206 my $exval = $rv >> 8;
208 # urpmq returns 0 if found, 1 otherwise.
209 $k->post('app', 'is_in_dist', $self, !$rv);
213 my ($k, $self, $line) = @_[KERNEL
, HEAP
, ARG0
];
214 $k->post('ui', 'append', $self, "stderr: $line\n");
218 my ($k, $self, $line) = @_[KERNEL
, HEAP
, ARG0
];
220 $self->_output( $self->_output . $line );
221 $k->post('ui', 'append', $self, "stdout: $line");
225 # -- poe inline states
228 my ($k, $self) = @_[KERNEL
, HEAP
];
230 $k->alias_set($self);
231 $k->post('ui', 'new_module', $self);
232 $k->post('app', 'new_module', $self);
241 sub _log_empty_line
{
242 my ($self, $nb) = @_;
243 $nb //= 1; #/ FIXME padre syntaxic color glitch
244 POE
::Kernel
->post('ui', 'append', $self, "\n" x
$nb);
248 my ($self, $k, $step, $comment) = @_;
251 map { "$PREFIX $_\n" }
252 ( '-' x
10, $step, '', $comment, '' );
253 $k->post('ui', 'append', $self, $_) for @lines;
254 $self->_log_empty_line;
263 App::CPAN2Pkg::Module - poe session to drive a module packaging
269 C<App::CPAN2Pkg::Module> implements a POE session driving the whole
270 packaging process of a given module.
272 It is spawned by C<App::CPAN2Pkg> and implements the logic related to
273 the module availability in the distribution.
277 =head1 PUBLIC PACKAGE METHODS
279 =head2 my $id = App::CPAN2Pkg::Module->spawn( $module )
281 This method will create a POE session responsible for packaging &
282 installing the wanted C<$module>.
284 It will return the POE id of the session newly created.
288 =head1 PUBLIC EVENTS ACCEPTED
290 =head2 find_prereqs()
292 Start looking for any other module needed by current module.
297 Check whether the package is provided by an existing upstream package.
302 This package is also a class, used B<internally> to store private data
303 needed for the packaging stuff. The following accessors are therefore
304 available, but should not be used directly:
308 =item name() - the module name
310 =item shortname() - the module shortname (only capital letters)
318 For all related information (bug reporting, source code repository,
319 etc.), refer to C<App::CPAN2Pkg>'s pod, section C<SEE ALSO>.
325 Jerome Quelin, C<< <jquelin@cpan.org> >>
329 =head1 COPYRIGHT & LICENSE
331 Copyright (c) 2009 Jerome Quelin, all rights reserved.
333 This program is free software; you can redistribute it and/or modify
334 it under the same terms as Perl itself.