module Subtrigger
# A simple wrapper around the output of Subversion's svnlook
# command.
#
# This class will let you make simple queries against the properties of a
# Subversion revision. It parses its output into keys and values so you can
# perform operations on them.
#
# == Attributes
#
# It knows about the following attributes:
#
# * Revision number
# * Author
# * Timestamp
# * Log message
# * changed directories
#
# This works by passing in the number of the revision to use, the raw
# output of svnlook info and the raw output of
# svnlook dirs-changed.
#
# == Special attributes
#
# Revision knows about changed projects. This is extracted from the list
# of changed directories. A project is a directory that is directly above
# a directory named trunk, branches or tags. So
# when a directory /internal/accounting/trunk is changed, the
# project /internal/accounting is reported.
#
# @example Example of raw input for info
# john
# 2010-07-05 17:00:00 +0200 (Mon, 01 Jan 2010)
# 215
# Description of log
#
# @example Usage
# @revision = Revision.new('...')
# @revision.author # => 'john'
# @revision.message # => 'Description of log'
# @revision.date # => (instance of Time)
# @revision.projects # => ['/project1', 'project2', ...]
#
# @author Arjan van der Gaag
# @since 0.3.0
class Revision
# The raw output of the svnlook command.
attr_reader :raw
# A list of all directories that were changed in this revision
attr_reader :dirs_changed
# the parsed Hash of attributes for this revision
attr_reader :attributes
def initialize(revision_number, info, dirs_changed)
@attributes = { :number => revision_number.to_i }
@raw = info
@dirs_changed = dirs_changed.split
parse
end
%w{author date message number}.each do |name|
define_method(name) do
attributes[name.to_sym]
end
end
# Creates a list of directory paths in the repository that have changes
# and contain a trunk, branches or tags
# directory.
#
# For example, a changed path in like /topdir/project_name/trunk
# would result in /topdir/project_name.
#
# @return [Array] list of changed project paths
def projects
pattern = /\/(trunk|branches|tags)/
dirs_changed.grep(pattern).map do |dir|
dir.split(pattern, 2).first
end.uniq
end
private
# Parses the raw log of svnlook into a Hash of attributes.
def parse
raise ArgumentError, 'Could not parse Subversion info: expected at least 4 lines' if raw.split("\n").size < 4
author, timestamp, size, message = raw.split("\n", 4)
attributes[:author] = author
attributes[:date] = Time.parse(timestamp)
attributes[:message] = message.chomp
end
end
end