Skip to content

Commit

Permalink
Merge branch 'rework_tags'
Browse files Browse the repository at this point in the history
Closes issue #70.
  • Loading branch information
theory committed Jan 8, 2013
2 parents 1def355 + f13c903 commit 4fca705
Show file tree
Hide file tree
Showing 6 changed files with 244 additions and 88 deletions.
31 changes: 18 additions & 13 deletions lib/App/Sqitch/Engine.pm
Expand Up @@ -236,7 +236,7 @@ sub revert {
}

# Make change objects and check that all dependencies will be satisfied.
@changes = $self->_load_changes( reverse @changes );
@changes = reverse $self->_load_changes( @changes );
$self->check_revert_dependencies(@changes);

# Do we want to support modes, where failures would re-deploy to previous
Expand Down Expand Up @@ -605,22 +605,27 @@ sub find_change {
sub _load_changes {
my $self = shift;
my $plan = $self->sqitch->plan;
map {
my $tags = $_->{tags} || [];
my $c = App::Sqitch::Plan::Change->new(%{ $_ }, plan => $plan );

# Assign a suffix from the planned change.
if (my $pc = $plan->get( $_->{id} )) {
my $suffix = $pc->suffix;
$c->suffix( $suffix ) if length $suffix;
}
my (@changes, %seen);
for my $params (@_) {
my $tags = $params->{tags} || [];
my $c = App::Sqitch::Plan::Change->new(%{ $params }, plan => $plan );

# Add tags.
$c->add_tag(
App::Sqitch::Plan::Tag->new(name => $_, plan => $plan, change => $c )
) for map { s/^@//; $_ } @{ $tags };
$c;
} @_;

if ( defined ( my $idx = $seen{ $params->{name} } ) ) {
# It's reworked; add rework tags in reverse order by change.
my $dupe = $changes[$idx];
$dupe->add_rework_tags(map { $changes[$_]->tags } reverse $idx..$#changes);
}

push @changes => $c;
$seen{ $params->{name} } = $#changes;
}

return @changes;
}

sub _deploy_by_change {
Expand Down Expand Up @@ -1579,7 +1584,7 @@ number of changes before the latest change will be returned.
my @change_hashes = $engine->deployed_changes;
Returns a list of hash reference, each representing a change from the current
Returns a list of hash references, each representing a change from the current
project in the order in which they were deployed. The keys in each hash
reference must be:
Expand Down
11 changes: 8 additions & 3 deletions lib/App/Sqitch/Plan.pm
Expand Up @@ -420,8 +420,13 @@ sub _parse {
push @lines => $prev_change;

if (my $duped = $change_named{ $params{name} }) {
# Mark previously-seen change of same name as duped.
$duped->suffix($prev_tag->format_name);
# Get rework tags by change in reverse order to reworked change.
my @rework_tags;
for (my $i = $#changes; $changes[$i] ne $duped; $i--) {
push @rework_tags => $changes[$i]->tags;
}
# Add list of rework tags to the reworked change.
$duped->add_rework_tags(@rework_tags, $duped->tags);
}
$change_named{ $params{name} } = $prev_change;
}
Expand Down Expand Up @@ -755,7 +760,7 @@ sub rework {
$self->_check_dependencies( $new, 'rework' );

# We good.
$orig->suffix( $tag->format_name );
$orig->add_rework_tags($tag);
$changes->append( $new );
$self->_lines->append( $new );
return $new;
Expand Down
65 changes: 48 additions & 17 deletions lib/App/Sqitch/Plan/Change.pm
Expand Up @@ -49,19 +49,28 @@ has parent => (
required => 0,
);

has suffix => (
is => 'rw',
isa => 'Str',
has _rework_tags => (
is => 'ro',
isa => 'ArrayRef[App::Sqitch::Plan::Tag]',
traits => ['Array'],
required => 1,
default => '',
init_arg => 'rework_tags',
traits => ['Array'],
lazy => 1,
default => sub { [] },
handles => {
rework_tags => 'elements',
add_rework_tags => 'push',
clear_rework_tags => 'clear',
},
);

sub is_reworked { length shift->suffix }
sub is_reworked { @{ shift->_rework_tags } > 0 }

after suffix => sub {
after add_rework_tags => sub {
my $self = shift;
# Need to reset the file name if a new value is passed.
$self->meta->get_attribute('_path_segments')->clear_value($self) if @_;
$self->meta->get_attribute('_path_segments')->clear_value($self);
};

has _tags => (
Expand All @@ -87,12 +96,25 @@ has _path_segments => (
default => sub {
my $self = shift;
my @path = split m{/} => $self->name;
$path[-1] = join '', (
$path[-1],
$self->suffix,
'.',
$self->sqitch->extension,
);
my $ext = '.' . $self->sqitch->extension;
if (my @rework_tags = $self->rework_tags) {
# Determine suffix based on the first one found in the deploy dir.
my $dir = $self->sqitch->deploy_dir;
my $bn = pop @path;
my $first;
for my $tag (@rework_tags) {
my $fn = join '', $bn, $tag->format_name, $ext;
$first //= $fn;
if ( -e $dir->file(@path, $fn) ) {
push @path => $fn;
$first = undef;
last;
}
}
push @path => $first if defined $first;
} else {
$path[-1] .= $ext;
}
return \@path;
},
);
Expand Down Expand Up @@ -339,10 +361,6 @@ plan B<before> the change. May be C<undef>.
Blank space separating the change name from the dependencies, timestamp, and
planner in the file.
=head3 C<suffix>
Suffix to append to file names, if any. Used for reworked changes.
=head3 C<is_reworked>
Boolean indicting whether or not the change has been reworked.
Expand Down Expand Up @@ -400,6 +418,19 @@ Returns the path to the revert script file for the change.
Returns the path to the verify script file for the change.
=head3 C<rework_tags>
my @tags = $change->rework_tags;
Returns a list of tags that occur between a change and its next reworking.
Returns an empty list if the change is not reworked.
=head3 C<add_rework_tags>
$change->add_rework_tags(@tags);
Add to the list of rework tags.
=head3 C<requires>
my @requires = $change->requires;
Expand Down
48 changes: 33 additions & 15 deletions t/change.t
Expand Up @@ -4,7 +4,7 @@ use strict;
use warnings;
use 5.010;
use utf8;
use Test::More tests => 79;
use Test::More tests => 85;
#use Test::More 'no_plan';
use Test::NoWarnings;
use App::Sqitch;
Expand Down Expand Up @@ -40,7 +40,8 @@ can_ok $CLASS, qw(
note
parent
since_tag
suffix
rework_tags
add_rework_tags
is_reworked
tags
add_tag
Expand Down Expand Up @@ -82,6 +83,12 @@ ok !$change->is_revert, 'It should not be a revert change';
is $change->action, 'deploy', 'And it should say so';
isa_ok $change->timestamp, 'App::Sqitch::DateTime', 'Timestamp';

my $tag = App::Sqitch::Plan::Tag->new(
plan => $plan,
name => 'alpha',
change => $change,
);

is_deeply [ $change->path_segments ], ['foo.sql'],
'path_segments should have the file name';
is $change->deploy_file, $sqitch->deploy_dir->file('foo.sql'),
Expand All @@ -91,11 +98,32 @@ is $change->revert_file, $sqitch->revert_dir->file('foo.sql'),
is $change->verify_file, $sqitch->verify_dir->file('foo.sql'),
'The verify file should be correct';
ok !$change->is_reworked, 'The change should not be reworked';
ok $change->suffix('@foo'), 'Set the suffix';
is_deeply [ $change->path_segments ], ['foo.sql'],
'path_segments should not include suffix';

# Identify it as reworked.
ok $change->add_rework_tags($tag), 'Add a rework tag';
is_deeply [$change->rework_tags], [$tag], 'Reworked tag should be stored';
ok $change->is_reworked, 'The change should be reworked';
is_deeply [ $change->path_segments ], ['foo@foo.sql'],
$sqitch->deploy_dir->mkpath;
$sqitch->deploy_dir->file('foo@alpha.sql')->touch;
is_deeply [ $change->path_segments ], ['foo@alpha.sql'],
'path_segments should now include suffix';

# Make sure all rework tags are searched.
$change->clear_rework_tags;
ok !$change->is_reworked, 'The change should not be reworked';

my $tag2 = App::Sqitch::Plan::Tag->new(
plan => $plan,
name => 'beta',
change => $change,
);
ok $change->add_rework_tags($tag2, $tag), 'Add two rework tags';
ok $change->is_reworked, 'The change should again be reworked';
is_deeply [ $change->path_segments ], ['foo@alpha.sql'],
'path_segments should now include the correct suffixc';

is $change->format_name, 'foo', 'Name should format as "foo"';
is $change->format_name_with_tags,
'foo', 'Name should format with tags as "foo"';
Expand Down Expand Up @@ -149,12 +177,6 @@ is $change->id, do {
)->hexdigest;
},'Change ID should be correct';

my $tag = App::Sqitch::Plan::Tag->new(
plan => $plan,
name => 'alpha',
change => $change,
);

my $date = App::Sqitch::DateTime->new(
year => 2012,
month => 7,
Expand Down Expand Up @@ -238,11 +260,6 @@ is $change2->format_name_with_tags, 'yo/howdy @alpha',
'Should format name with tags';

# Add another tag.
my $tag2 = App::Sqitch::Plan::Tag->new(
plan => $plan,
name => 'beta',
change => $change,
);
ok $change2->add_tag($tag2), 'Add another tag';
is_deeply [$change2->tags], [$tag, $tag2], 'Should have both tags';
is $change2->format_name_with_tags, 'yo/howdy @alpha @beta',
Expand All @@ -262,6 +279,7 @@ is $change2->format_content, '- yo/howdy [foo bar @baz !dr_evil] '

# Check file names.
my @fn = ('yo', 'howdy@beta.sql');
$change2->add_rework_tags($tag2);
is_deeply [ $change2->path_segments ], \@fn,
'path_segments should include directories';
is $change2->deploy_file, $sqitch->deploy_dir->file(@fn),
Expand Down

0 comments on commit 4fca705

Please sign in to comment.