App-Puppet-Environment-Updater
view release on metacpan or search on metacpan
lib/App/Puppet/Environment/Updater.pm view on Meta::CPAN
package App::Puppet::Environment::Updater;
$App::Puppet::Environment::Updater::VERSION = '0.001002';
# ABSTRACT: Update a Puppet environment in a Git branch
use Moose;
use MooseX::FollowPBP;
with 'MooseX::Getopt';
use Carp;
use Git::Wrapper;
use File::pushd;
use Path::Class::Dir;
use MooseX::Types::Path::Class;
use Log::Dispatchouli;
use List::MoreUtils qw(any);
use Term::ANSIColor qw(:constants);
use Try::Tiny;
use namespace::autoclean;
has 'from' => (
is => 'ro',
isa => 'Str',
required => 1,
documentation => 'Environment/branch which should be merged',
);
has 'environment' => (
is => 'ro',
isa => 'Str',
required => 1,
documentation => 'Environment/branch which should be updated',
);
has 'remote' => (
is => 'ro',
isa => 'Str',
documentation => 'Git remote to fetch latest changes from, defaults to "origin"',
default => 'origin',
);
has 'workdir' => (
is => 'ro',
isa => 'Path::Class::Dir',
coerce => 1,
documentation => 'Directory to work in, should be the directory with the environment that should be updated',
default => sub {
return Path::Class::Dir->new('.')->absolute();
},
);
has 'git' => (
is => 'ro',
isa => 'Git::Wrapper',
traits => ['NoGetopt'],
lazy => 1,
default => sub {
my ($self) = @_;
return Git::Wrapper->new(
$self->get_workdir()->absolute()->resolve()->stringify()
);
},
);
has 'logger' => (
is => 'ro',
isa => 'Log::Dispatchouli',
traits => ['NoGetopt'],
lazy => 1,
default => sub {
my ($self) = @_;
my $logger = Log::Dispatchouli->new({
ident => 'environment-updater',
to_stderr => 1,
log_pid => 0,
});
$logger->set_prefix('[update-'.$self->get_environment().'] ');
return $logger;
},
);
sub get_proxy_logger {
my ($self, $prefix) = @_;
return $self->get_logger()->proxy({
proxy_prefix => $prefix,
});
}
sub run {
my ($self) = @_;
if ($self->get_git()->status()->is_dirty()) {
$self->get_logger()->log_fatal(BOLD.RED."Dirty sandbox, aborting".RESET);
}
try {
$self->get_logger()->log(CYAN.'Fetching latest changes from '.$self->get_remote().'...'.RESET);
$self->get_git()->fetch($self->get_remote());
for my $branch ($self->get_from(), $self->get_environment()) {
unless (any { $_ eq $branch } $self->get_local_branches()) {
lib/App/Puppet/Environment/Updater.pm view on Meta::CPAN
sub create_and_switch_to_branch {
my ($self, $branch) = @_;
$self->get_proxy_logger(BLUE.'[create-branch] '.RESET)->log(
'Creating local branch '.$branch.' from '.$self->remote_branch_for($branch).'...'
);
$self->get_git()->checkout('-b', $branch, $self->remote_branch_for($branch));
return;
}
sub update_branch {
my ($self, $branch) = @_;
my $logger = $self->get_proxy_logger(YELLOW.'[update-branch] '.RESET);
my $remote_branch = $self->remote_branch_for($branch);
$logger->log(
'Updating local branch '.$branch.' from '.$remote_branch.'...'
);
$self->get_git()->checkout($branch);
try {
$logger->log($self->get_git()->merge('--ff-only', $remote_branch));
}
catch {
chomp;
$logger->log_fatal(
"$_ - does ".$remote_branch.' exist and is local branch '
.$branch.' not diverged from it?'
);
};
return;
}
sub merge {
my ($self, $from, $to) = @_;
my $logger = $self->get_proxy_logger(MAGENTA.'[merge] '.RESET);
$logger->log('Merging '.$from.' into '.$to.'...');
$self->get_git()->checkout($to);
$logger->log($self->get_git()->merge('--no-ff', $from));
return;
}
sub update_submodules {
my ($self) = @_;
my $workdir = pushd($self->get_workdir());
my $logger = $self->get_proxy_logger(YELLOW.'[update-submodules] '.RESET);
$logger->log('Updating submodules...');
if (my @updated = $self->get_git()->submodule('update', '--init')) {
$logger->log($_) for @updated;
}
else {
$logger->log('No submodules to update.');
}
return;
}
__PACKAGE__->meta()->make_immutable();
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
App::Puppet::Environment::Updater - Update a Puppet environment in a Git branch
=head1 VERSION
version 0.001002
=head1 SYNOPSIS
use App::Puppet::Environment::Updater;
App::Puppet::Environment::Updater->new_with_options()->run();
=head1 DESCRIPTION
App::Puppet::Environment::Updater is intended to update Puppet environments which
are in Git branches. There are many ways to organize a Puppet setup and Puppet
environments, and this application supports the following approach:
=over
=item *
There is one Git repository with four branches, each of which represents a
Puppet environment:
=over
=item *
C<development>
=item *
C<test>
=item *
C<staging>
=item *
lib/App/Puppet/Environment/Updater.pm view on Meta::CPAN
Get a list with local branches.
=head3 Result
The local branches.
=head2 remote_branch_for
Construct the name of a remote branch given a branch name.
=head3 Parameters
This method expects positional parameters.
=over
=item branch
Name of the branch the remote branch name should be constructed for.
=back
=head3 Result
The name of the remote branch.
=head2 create_and_switch_to_branch
Create a local branch starting at the corresponding remote branch and switch to
it.
=head3 Parameters
This method expects positional parameters.
=over
=item branch
Name of the branch.
=back
=head3 Result
Nothing on success, an exception otherwise.
=head2 update_branch
Update a local branch from the corresponding remote branch, using a fast-forward
merge.
=head3 Parameters
This method expects positional parameters.
=over
=item branch
The name of the branch which should be updated.
=back
=head3 Result
Nothing on success, an exception otherwise.
=head2 merge
Merge a given branch into another branch.
=head3 Parameters
This method expects positional parameters.
=over
=item from
The branch to merge from.
=item to
The branch to merge to.
=back
=head3 Result
Nothing on success, an exception otherwise.
=head2 update_submodules
Update the submodules.
=head3 Result
Nothing on success, an exception otherwise.
=head1 SEE ALSO
=over
=item *
L<http://www.puppetlabs.com/> - Puppet
=item *
L<http://docs.puppetlabs.com/guides/environment.html> - How to configure Puppet
environments.
=item *
L<http://git-scm.com/> - Git
=back
=head1 AUTHOR
( run in 0.762 second using v1.01-cache-2.11-cpan-39bf76dae61 )