#!/usr/bin/perl # Created on: 2014-03-11 21:17:31 # Create by: Ivan Wills # $Id$ # $Revision$, $HeadURL$, $Date$ # $Revision$, $Source$, $Date$ use strict; use warnings; use Getopt::Long; use Pod::Usage (); use Data::Dumper qw/Dumper/; use English qw/ -no_match_vars /; use Git::Workflow::Pom; our $VERSION = 0.6; my ($name) = $PROGRAM_NAME =~ m{^.*/(.*?)$}mxs; my $workflow = Git::Workflow::Pom->new; my %option = ( pom => $workflow->config('workflow.pom') || 'pom.xml', local => $workflow->config('workflow.pom-local') || undef, fetch => 1, url => $workflow->config('jira.url'), verbose => 0, man => 0, help => 0, VERSION => 0, ); if ( !@ARGV ) { Pod::Usage::pod2usage( -verbose => 1 ); } main(); exit 0; sub main { Getopt::Long::Configure('bundling'); GetOptions( \%option, 'tag|t=s', 'branch|b=s', 'local|l!', 'pom|x=s', 'url|u=s', 'user|U=s', 'pass|password|P=s', 'jira|j=s', 'fetch|f!', 'new_pom|new-pom|n!', 'push|p', 'test|t', 'verbose|v+', 'man', 'help', 'VERSION!', ) or Pod::Usage::pod2usage(2); if ( $option{'VERSION'} ) { print "$name Version = $VERSION\n"; exit 1; } elsif ( $option{'man'} ) { Pod::Usage::pod2usage( -verbose => 2 ); } elsif ( $option{'help'} ) { Pod::Usage::pod2usage( -verbose => 1 ); } # do stuff here $workflow->{VERBOSE} = $option{verbose}; $workflow->{TEST } = $option{test}; my ($feature_branch) = shift @ARGV || jira(); my ($type, $regex); if ($option{tag}) { $type = 'tag'; $regex = $option{tag}; } elsif ($option{branch}) { $type = 'branch'; $regex = $option{branch}; } elsif ( !$option{tag} && !$option{branch} ) { my $prod = $workflow->config('workflow.prod') || ( $option{local} ? 'branch=^master$' : 'branch=^origin/master$' ); ($type, $regex) = split /\s*=\s*/, $prod; } $workflow->git->fetch() if $option{fetch} && !$option{local}; my $release = $workflow->release($type, $option{local}, $regex); # checkout branch $workflow->git->checkout( '-b', $feature_branch, '--no-track', $release ); if ($option{new_pom}) { my $version = $workflow->next_pom_version($option{pom}); $workflow->runner(qw/mvn versions:set/, "–DnewVersion=$version"); } # push if requested to if ($option{push}) { $workflow->git->push( qw/-u origin/, $feature_branch ); } return; } sub jira { die "No JIRA specified!" if !$option{jira}; die "No JIRA url specified!" if !$option{url}; require JIRA::REST; my $jira_rest = JIRA::REST->new($option{url}, $option{user}, $option{pass}); my $issue = $jira_rest->GET("/issue/$option{jira}"); my $branch = lc "$option{jira} $issue->{fields}{summary}"; $branch =~ s/[ !?-]+/_/gxms; return $branch; } __DATA__ =head1 NAME git-feature - Create a feature branch from the "current release" =head1 VERSION This documentation refers to git-feature version 0.6 =head1 SYNOPSIS git-feature [option] branch-name git-feature [option] [--jira|-j] JIRAID OPTIONS: branch-name The name of the new branch to create from the current release branch/tag -j --jira[=]JIRAID Specify a JIRA ID to use to find the summary of an make it branch name for the feature. -u --url[=]URL Use URL as the JIRA instance for looking up summaries. -U --user[=]str JIRA user name to use when looking up JIRA -P --password[=]str JIRA password for --user -t --tag[=]str Specify a tag that any branch with newer commits must contain -b --branch[=]str Similarly a branch that other branches with newer commits must contain (Default origin/master) -l --local Shorthand for --branch '^master$' -p --push Push the new brach upstream --no-fetch Don't fetch before trying to find the remote branch -n --new-pom Set the pom.xml version to the next available version -x --pom[=]dir/pom.xml The location of the master pom.xml if it isn't in the current directory. -t --test Test don't actually run -v --verbose Show more details --VERSION Prints the version information --help Prints this help information --man Prints the full documentation for git-feature =head1 DESCRIPTION The C<git feature> command allows a simplified way to create and switch to feature branches using whatever you define as the I<current release>. By default I<current release> is defined as the I<origin/master> branch that can be changed either on the command line using the --tag or --branch arguments or by setting the C<workflow.prod> git config. Example of a commonly used alternatives include using release version tags where you might use something like C<--tag ^v\d+[.]\d+'> to match tags like v0.1 or v1.0 etc. Other examples include different branches containing release versions of code. The branch I<origin/master> is used over I<master> to save you from having to switch to master and pull any new changes, a C<git fetch> is called by default before branching to further ensure the latest version of code is available. =head1 SUBROUTINES/METHODS =head1 DIAGNOSTICS =head1 CONFIGURATION AND ENVIRONMENT Defaults for this script can be set thought C<git config> workflow.prod Sets how a prod release is determined eg the default equavilent is branch=^origin/master$ workflow.pom The default location for the pom.xml file (used C<--new-pom> and updating the pom.xml for the new branch) workflow.pom-local Can set default value of C<--local> You can set these values either by editing the repository local C<.git/config> file or C<~/.gitconfig> or use the C<git config> command # eg Setting the global value git config --global workflow.prod 'branch=^origin/master$' # or set a repository's local value git config workflow.prod 'tag=^release_\d{4}_\d{2}\d{2}$' # or setting pom.xml location to a sub directory git config workflow.pom 'somedir/pom.xml' =head1 DEPENDENCIES =head1 INCOMPATIBILITIES =head1 BUGS AND LIMITATIONS There are no known bugs in this module. Please report problems to Ivan Wills (ivan.wills@gmail.com). Patches are welcome. =head1 AUTHOR Ivan Wills - (ivan.wills@gmail.com) =head1 LICENSE AND COPYRIGHT Copyright (c) 2014 Ivan Wills (14 Mullion Close, Hornsby Heights, NSW Australia 2077). All rights reserved. This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See L<perlartistic>. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. =cut