App-Sqitch
view release on metacpan or search on metacpan
lib/App/Sqitch/Command/rework.pm view on Meta::CPAN
sub execute {
my $self = shift;
my ($name, $targets, $changes) = $self->parse_args(
names => [$self->change_name],
all => $self->all,
args => \@_,
no_changes => 1,
);
# Check if the name is identified as a change.
$name ||= shift @{ $changes } || $self->usage;
my $note = join "\n\n", => @{ $self->note };
my ($first_change, %reworked, @files, %seen);
for my $target (@{ $targets }) {
my $plan = $target->plan;
my $file = $plan->file;
my $spec = $reworked{$file} ||= { scripts => [] };
my ($prev, $reworked);
if ($prev = $spec->{prev}) {
# Need a dupe for *this* target so script names are right.
$reworked = ref($prev)->new(
plan => $plan,
name => $name,
);
# Copy the rework tags to the previous instance in this plan.
my $new_prev = $spec->{prev} = $plan->get(
$name . [$plan->last_tagged_change->tags]->[-1]->format_name
);
$new_prev->add_rework_tags($prev->rework_tags);
$prev = $new_prev;
} else {
# Rework it.
$reworked = $spec->{change} = $plan->rework(
name => $name,
requires => $self->requires,
conflicts => $self->conflicts,
note => $note,
);
$first_change ||= $reworked;
# Get the latest instance of the change.
$prev = $spec->{prev} = $plan->get(
$name . [$plan->last_tagged_change->tags]->[-1]->format_name
);
}
# Record the files to be copied to the previous change name.
push @{ $spec->{scripts} } => map {
push @files => $_->[0] if -e $_->[0];
$_;
} grep {
!$seen{ $_->[0] }++;
} (
[ $reworked->deploy_file, $prev->deploy_file ],
[ $reworked->revert_file, $prev->revert_file ],
[ $reworked->verify_file, $prev->verify_file ],
);
# Replace the revert file with the previous deploy file.
push @{ $spec->{scripts} } => [
$reworked->deploy_file,
$reworked->revert_file,
$prev->revert_file,
] unless $seen{$prev->revert_file}++;
}
# Make sure we have a note.
$note = $first_change->request_note(
for => __ 'rework',
scripts => \@files,
);
# Time to write everything out.
for my $target (@{ $targets }) {
my $plan = $target->plan;
my $file = $plan->file;
my $spec = delete $reworked{$file} or next;
# Copy the files for this spec.
$self->_copy(@{ $_ }) for @{ $spec->{scripts } };
# We good, write the plan file back out.
$plan->write_to( $plan->file );
# Let the user know.
$self->info(__x(
'Added "{change}" to {file}.',
change => $spec->{change}->format_op_name_dependencies,
file => $plan->file,
));
}
# Now tell them what to do.
$self->info(__n(
'Modify this file as appropriate:',
'Modify these files as appropriate:',
scalar @files,
));
$self->info(" * $_") for @files;
# Let 'em at it.
if ($self->open_editor) {
my $sqitch = $self->sqitch;
$sqitch->shell( $sqitch->editor . ' ' . $sqitch->quote_shell(@files) );
}
return $self;
}
sub _copy {
my ( $self, $src, $dest, $orig ) = @_;
$orig ||= $src;
if (!-e $orig) {
$self->debug(__x(
'Skipped {dest}: {src} does not exist',
dest => $dest,
src => $orig,
));
return;
}
# Create the directory for the file, if it does not exist.
$self->_mkpath($dest->dir->stringify);
# Stringify to work around bug in File::Copy warning on 5.10.0.
File::Copy::syscopy "$src", "$dest" or hurl rework => __x(
'Cannot copy {src} to {dest}: {error}',
src => $src,
dest => $dest,
error => $!,
);
$self->debug(__x(
'Copied {src} to {dest}',
dest => $dest,
src => $src,
));
return $orig;
}
1;
__END__
=head1 Name
App::Sqitch::Command::rework - Rework a Sqitch change
=head1 Synopsis
my $cmd = App::Sqitch::Command::rework->new(%params);
$cmd->execute;
=head1 Description
Reworks a change. This will result in the copying of the existing deploy,
revert, and verify scripts for the change to preserve the earlier instances of
the change.
=head1 Interface
=head2 Class Methods
=head3 C<options>
my @opts = App::Sqitch::Command::rework->options;
Returns a list of L<Getopt::Long> option specifications for the command-line
options for the C<rework> command.
=head3 C<configure>
my $params = App::Sqitch::Command::rework->configure(
$config,
$options,
);
Processes the configuration and command options and returns a hash suitable
for the constructor.
=head2 Attributes
=head3 C<change_name>
The name of the change to be reworked.
=head3 C<note>
Text of the change note.
=head3 C<requires>
List of required changes.
=head3 C<conflicts>
List of conflicting changes.
=head3 C<all>
Boolean indicating whether or not to run the command against all plans in the
project.
=head2 Instance Methods
=head3 C<execute>
$rework->execute($command);
Executes the C<rework> command.
=head1 See Also
=over
=item L<sqitch-rework>
( run in 1.217 second using v1.01-cache-2.11-cpan-5a3173703d6 )