App-Gitc

 view release on metacpan or  search on metacpan

lib/App/Gitc/Util.pm  view on Meta::CPAN

=pod

=head1 NAME

App::Gitc::Util - The workhorse of gitc

=head1 VERSION

version 0.60

=head1 Exported Subroutines

=head2 confirm($message)

Displays C<$message> and waits for the user to press 'y' or 'n'.  If he enters
'y', a true value is returned.  If he enters 'n', a false value is returned.

=head2 current_branch

Returns the name of the branch that's currently checked out in Git.

=head2 its_config

Returns the config specific to this project's ITS.

=head2 eventum_statuses

Returns the from and to state based on a command provided to GITC.

=head2 its

Returns an ITS pseudo-object

Some day it would be nice to add 'new' to these and return a real instantiated
object... but this fits the bill.

=head2 its_for_changeset

Guesses which ITS object we need based on the changeset name, returns the
object if it supports it, or just the class name.

=head2 git

A wrapper for executing git commands and handling errors.
In void context, the command is executed using C<system>.  In scalar context,
the command's output is captured, chomped and returned.  In list context, a
list of chomped lines is returned.

=head2 git_config

Returns a nested hash data structure representing Git's configuration.

=head2 guarantee_a_clean_working_directory

Make sure that all tracked files match the index and match the commit object.
If the working directory is not clean, ask the user whether to proceed.  If he
wants to proceed, this sub stashes the current changes and returns the stash's
commit ID.  In this case, it's the caller's responsibility to invoke "git
stash apply" with this ID to restore the changes, when appropriate.

If the user does not want to proceed, an exception is thrown.  In most cases,
this will accomplish what the user desired by halting the program.

If the directory is clean, a false value is returned which indicates that
nothing was stashed while guaranteeing cleanliness.

=head2 let_user_edit($filename)

Open's the user's preferred editor so that he can interactively edit
C<$filename>.

=head2 meta_data_add($data)

Appends the contents of the hashref C<$data> to the changeset meta data.
Returns a unique identifier which can be used by L</meta_data_rm>.

=head2 meta_data_rm({id => $id, changeset => $changeset})

Deletes the meta data entry with ID C<$id> in changeset C<$changeset>.

=head2 meta_data_rm_all($changeset)

Deletes all changeset meta data for the changeset named C<$changeset>.  The
project is determined by the current working directory.  Returns the number of
meta data entries that were deleted.

=head2 meta_data_rm_project($project)

Deletes all changeset meta data for the project named C<$project>.  Returns
the number of meta data entries that were deleted.

=head2 new_branch_version($branch, $new_major_version)

Increments and returns the most recent version tagged for the given C<$branch>.
This only applies to projects that have the 'use_version_tags' config set to true.
If $new_major_version is truthy, increment the major version # and make minor 0

=head2 new_version_tag($branch)

Returns a tag name for an updated version of the given C<$branch>.
This only applies to projects that have the 'use_version_tags' config set to true.

=head2 project_config

Returns a hashref with configuration details about this project.

Configuration is loaded from the following sources:
* /etc/gitc/gitc.config
* $PROJECT_ROOT/gitc.config
* $HOME/.gitc/gitc.config

It will then parse all the paths in the GITC_CONFIG environment variable 
(separated by :).

These configuration files are all merged together with the later files
overriding the earlier.  

Finally we merge the default config with the per-project configuration
we found to generate a final fully baked configuration for the project.

=head1 Optionally Exported Subroutines

lib/App/Gitc/Util.pm  view on Meta::CPAN

"test/2009-12-29T12_13_14") into the name of the branch (such as "test").  If
we can't determine the branch name, returns 'unknown'.

=head2 branch_point($ref)

Returns a commit ID indicating the commit on which the branch at C<$ref>
is based.  For example, if we have a topology like this

              o-----A
             /
    o---o---X---o---M

where A is the head of a branch and M is the head of master.  The branch point
of A is commit X.  If A is later merged into M, the branch point remains the
same.

See L</full_changeset_name> for a way to convert a changeset name into
a value suitable for C<$ref>.

=head2 changeset_group($changeset)

Given a C<$changeset> name, returns an arrayref of the changeset names (for
existing changesets) in this same changeset group.  A changeset group is
defined as any changesets that share the same Eventum number or prefix (if the
group is not associated with an Eventum issue).  The resulting list of
changesets is sorted in the traditional order.  See
L</sort_changesets_by_name>.

TODO: This code should be reworked to use logic for each its

=head2 changeset_merged_to($changeset)

Returns a list (or string, depending on context) of environments to which this
changeset has been merged.  If it's not been merged yet, the list is empty (of
course).

=head2 changesets_promoted_between

Given a hashref of named arguments, returns a list of changeset names
indicating which changesets were promoted to C<$target> for C<$project>
between the times C<$start> and C<$end>.  The times should be in the format
'yyyy-mm-ddTHH:MM:SS'

=head2 commit_decorations($commit)

Returns a list (or arrayref, depending on context) of decorations associated
with C<$commit> (a commit ID).  In cases where many Git processes are forked
to obtain decoration info, this function can be substantially faster.

=head2 current_branch_version($branch)

Determines the most recent version tagged for the given C<$branch>.  This only
applies to projects that have the 'use_version_tags' config set to true.

=head2 environment_preceding($environment)

Given an C<$environment> name, returns the name of the environment that
precedes that one in promotion order.  For instance
C<environment_preceding('stage')> produces 'test'.

If there is no such C<$environment>, an exception is thrown.  If no
environment precedes the one given, returns C<undef>.

=head2 full_changeset_name($name)

Given the C<$name> of a changeset, returns a Git ref which correctly addresses
that changeset's head.  It doesn't matter if the changeset is newly opened,
pending review or merged.  The resulting ref points at the head of that
changeset.

See also L<short_ref_name>.

=head2 git_dir

Returns the absolute path of the current .git directory.  Bare repositories
and normal repositories are both handled correctly.

=head2 git_fetch_and_clean_up

Fetches the remote repository and does a little routine maintenance to make
sure that the repository performs optimally.  This is called from commands
which are consistently, but infrequently, run by developers.  It helps to hide
some of the repository maintenace that Git requires.

=head2 git_tag

A wrapper around "git tag" which updates the commit decoration hash (See
L</commit_decorations>.  This should always be used instead of calling "git
tag" directly.

Returns nothing useful.

=head2 highest_quickfix_number($project_name)

Returns the highest number used for any quickfix changeset in
C<$project_name>.  If there have been no quickfix changesets, returns 0.

=head2 history($project_name, $changeset)

Returns a list (or arrayref, depending on context) of hashes.  Each hash
represents the details about a particular event related to the changeset named
C<$changeset> within the project named C<$project_name>.  The events are
returned in chronological order.

If C<$project_name> is omitted, the name of the project in the current working
directory is used instead.

=head2 history_owner($history)

Returns the name of the owner of a changeset based on a changeset's
C<$history>.

=head2 history_reviewer

Returns the name of the most recent reviewer of this changeset.  If this
changeset has never been submitted for review, returns C<undef>.

=head2 history_status

Returns the current status of a changeset based on a changeset's C<$history>.

=head2 history_submitter

Returns the user ID of the most recent submitter.  If there is no submitter in
the history, returns C<undef>.

=head2 is_auto_fetch

Returns a true value if this user wants to automatically fetch from the
origin.

=head2 is_merge_commit($ref)

Returns true if the commit pointed at by C<$ref> is a merge commit. Otherwise,
it returns false.

=head2 is_suspendable

Marks the currently running gitc command as suspendable.  If a command which
is marked as suspendable is currently suspended, calling this function throws
an exception.

Any command which suspends itself should call this function.  It helps avoid
user error when the user tries to run the same command again instead of
resuming the suspended command.

=head2 is_valid_ref($name)

Returns a commit ID if C<$name> is a valid Git "ref".  Otherwise, it returns
false.

=head2 open_packed_refs($prefix)

Opens the current repository's packed refs and returns:

    * a file handle to the opened packed refs
    * a file handle to a temporary file
    * the name of the temporary file

The first line read from the first filehandle is the first packed ref in the
file.  Any header lines are stripped and automatically copied to the new
temporary file.

The mandatory C<$prefix> argument specifies a prefix for the temporary file.
This should usually be the name of the gitc command calling
L</open_packed_refs>.

The temporary file does not automatically delete itself.  The caller is
responsible for that.

=head2 parse_changeset_spec($spec)

C<$spec> is a single command line argument which is supposed to uniquely
identify a changeset and its associated project.  C<undef> means "infer
everything from the repository I'm in".  C<project#changeset> means to use the
specified project and changeset.  C<changeset> means to use the given
changeset within the current directory's project.

Returns a list containing the project name and the changeset name.  If there's
any trouble obtaining those two, an exception is thrown.

=head2 project_name

Returns the name of the project in the current working directory.

=head2 project_root

Returns an absolute path to the current repository's project root.
If called from a bare repository, it throws an exception.

=head2 remote_branch_exists($branch_name)

Returns true if origin has a branch named C<$branch_name>.  Otherwise, it
returns false.

=head2 sendmail($args)

Sends an email with a standard format, allowing the user to edit the template.
C<$args> is a single hashref of named arguments.  The argument C<to> specifies
the username of the recipient.  C<subject> provides the email subject.
C<changeset> is the name of the changeset associated with this email.

The following optional arguments are also accepted.  C<project> is the name of
the project related to this changeset email.  If it's omitted, the project in
the current working directory is used instead.  C<content> specifies the main
body of the email.  If omitted, an empty body template is used.  C<link>
provides a URL which is included at the top of the email.

If the C<lazy> argument is true, the email message is built but not sent.
Instead, L</sendmail> returns a code reference.  When that code reference is
called, the email is sent.  This is particularly useful when you want a user
to compose an email in one context (so he can cancel an operation early, for
example) but delay sending the email until you're certain it should go out.

=head2 find_sendmail()

Returns the full path to the sendmail binary.

=head2 short_ref_name($ref)

Given a Git C<$ref>, returns a shorter name for it.  This is typically the
name of the changeset to which C<$ref> refers.  This function is the inverse
of L</full_changeset_name>.

=head2 sort_changesets_by_name

Sorts a list of changeset names into a sensible order.  Typical usage is:

    sort_changesets_by_name( \@list_of_changesets );
    # @list_of_changesets is now sorted

=head2 split_decorations($decorations)

Converts a string of C<$decorations> as produced by C<git log --decorate> or
C<git log --pretty=format:%d> into a list of full ref names.

=head2 toplevel

Returns the top-level directory for the current branch.

=head2 traverse_commits( $log_string, $callback )

Invokes C<git log $log_string> and calls the code reference C<$callback> for
each commit encountered.  C<$callback> is invoked with the following
arguments in a hashref:

    commit  - this commit's ID
    parents - an arrayref of the commit's parent commit IDs
    message - an arrayref of the commit's message lines

=head2 unmerged_changesets($project_name)

Returns a hashref whose keys are the names of unmerged changesets and whose
values are the respective changeset histories (see L</history>).

=head2 unpromoted($from, $to)

Returns a list of the changesets which are included in C<$from> but not yet
part of C<$to>.  For example, C<unpromoted('origin/master', 'origin/test')>,
returns the changesets that are in C<master> but not in C<test>.

One way to think about it is that if you promoted C<$from> into C<$to>, what
other things would be promoted to C<$to> as a result.  This is the way that
F<gitc-unpromoted> is implemented. This subroutine implements a more
general idea of "not included in" than that command makes available.

C<$from> can also be an arrayref of branches.  In this case it means, "If I
were to promote everything listed in C<@$from>, what all would be promoted.

The order of the returned changesets is significant.  Changesets always appear
in the list before their dependencies.  In Git terms, "child commits are given
before their parents."  Since demotions are not accomodated by Git's data
model, they are placed at the end of the list of unpromoted changesets.

=head1 Private Subroutines

=head2 command_name

Returns the name of the gitc command that started this whole mess.
This is mostly a helper subroutine for eventum_transition_status.
If the command name can't be determined, an exception is thrown.

=head2 _states

Used internally to calculate target for state change.

=head2 state_blocked

Given a C<command> and a specified C<state> this checks the block list in the
project configuration and returns true if the state should block the command
from proceeding.

NOTE: Block list must be an arraref in the project configuration 

=head1 AUTHOR

Grant Street Group <developers@grantstreet.com>

=head1 COPYRIGHT AND LICENSE

This software is Copyright (c) 2013 by Grant Street Group.

This is free software, licensed under:

  The GNU Affero General Public License, Version 3, November 2007

=cut



( run in 1.614 second using v1.01-cache-2.11-cpan-39bf76dae61 )