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 )