The Perl and Raku Conference 2025: Greenville, South Carolina - June 27-29 Learn more

#!/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 Pod::Usage ();
use Data::Dumper qw/Dumper/;
use English qw/ -no_match_vars /;
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