class Twig::Branch

Represents a Git branch.

Constants

PARENT_PROPERTY
PROPERTY_NAME_FROM_GIT_CONFIG
RESERVED_BRANCH_PROPERTY_NAMES

Attributes

last_commit_time[RW]
name[RW]

Public Class Methods

all_branch_names() click to toggle source
# File lib/twig/branch.rb, line 36
def self.all_branch_names
  @_all_branch_names ||= all_branches.map { |branch| branch.name }
end
all_branches() click to toggle source
# File lib/twig/branch.rb, line 20
def self.all_branches
  @_all_branches ||= begin
    branch_tuples = Twig.
      run(%{git for-each-ref #{ REF_PREFIX } --format="#{ REF_FORMAT }"}).
      split("\n")

    branch_tuples.inject([]) do |result, branch_tuple|
      name, time_string = branch_tuple.split(REF_FORMAT_SEPARATOR)
      time        = Time.parse(time_string)
      commit_time = Twig::CommitTime.new(time)
      branch      = Branch.new(name, :last_commit_time => commit_time)
      result << branch
    end
  end
end
all_property_names() click to toggle source
# File lib/twig/branch.rb, line 40
def self.all_property_names
  @_all_property_names ||= begin
    config_lines = Twig.run('git config --list').split("\n")

    properties = config_lines.map do |line|
      # Split by rightmost `=`, allowing branch names to contain `=`
      match_data = line.match(/(.+)=(.+)/)
      key, value = match_data[1..2] if match_data
      next unless key

      key_parts = key.split('.')
      key_parts.last if key_parts[0] == 'branch' && key_parts.size > 2
    end.compact

    properties.uniq.sort - RESERVED_BRANCH_PROPERTY_NAMES
  end
end
new(name, attrs = {}) click to toggle source
# File lib/twig/branch.rb, line 66
def initialize(name, attrs = {})
  self.name = name
  raise ArgumentError, '`name` is required' if name.empty?

  self.last_commit_time = attrs[:last_commit_time]
end
shellescape_property_value(property_value) click to toggle source
# File lib/twig/branch.rb, line 62
def self.shellescape_property_value(property_value)
  Shellwords.escape(property_value).gsub('\\ ', ' ')
end
validate_property_name(property_name) click to toggle source
# File lib/twig/branch.rb, line 58
def self.validate_property_name(property_name)
  raise EmptyPropertyNameError if property_name.empty?
end

Public Instance Methods

escaped_property_names(property_names) click to toggle source
# File lib/twig/branch.rb, line 91
def escaped_property_names(property_names)
  property_names.map do |property_name|
    property_name = sanitize_property(property_name)
    Branch.validate_property_name(property_name)
    Regexp.escape(property_name)
  end
end
get_properties(property_names) click to toggle source
# File lib/twig/branch.rb, line 99
def get_properties(property_names)
  return {} if property_names.empty?

  property_names_regexp = escaped_property_names(property_names).join('|')
  git_config_regexp     = "branch\.#{Shellwords.escape(name)}\.(#{ property_names_regexp })$"
  cmd = %{git config --get-regexp "#{git_config_regexp}"}

  git_result = Twig.run(cmd) || ''
  git_result_lines = git_result.split("\n")

  git_result_lines.inject({}) do |properties, line|
    match_data = line.match(/^branch\.#{Regexp.escape(name)}\.([^\s]+)\s+(.*)$/)

    if match_data
      property_name = match_data[1]
      property_value = match_data[2]
    else
      property_value = ''
    end

    if property_value.empty?
      properties
    else
      properties.merge(property_name => property_value)
    end
  end
end
get_property(property_name) click to toggle source
# File lib/twig/branch.rb, line 127
def get_property(property_name)
  property_name = sanitize_property(property_name)
  get_properties([property_name])[property_name]
end
parent_name() click to toggle source
# File lib/twig/branch.rb, line 83
def parent_name
  get_property(PARENT_PROPERTY)
end
sanitize_property(property_name) click to toggle source
# File lib/twig/branch.rb, line 87
def sanitize_property(property_name)
  property_name.gsub(/[ _]+/, '')
end
set_property(property_name, value) click to toggle source
# File lib/twig/branch.rb, line 132
def set_property(property_name, value)
  property_name = sanitize_property(property_name)
  value = value.to_s.strip
  Branch.validate_property_name(property_name)

  if RESERVED_BRANCH_PROPERTY_NAMES.include?(property_name)
    raise ArgumentError,
      %{Can't modify the reserved property "#{property_name}".}
  elsif value.empty?
    raise ArgumentError,
      %{Can't set a branch property to an empty string.}
  else
    git_config = "branch.#{name.shellescape}.#{property_name}"
    escaped_value = Branch.shellescape_property_value(value)
    Twig.run(%{git config #{git_config} "#{escaped_value}"})
    result_body = %{property "#{property_name}" as "#{value}" for branch "#{name}".}
    if $?.success?
      "Saved #{result_body}"
    else
      raise RuntimeError, "Could not save #{result_body}"
    end
  end
end
to_hash(property_names) click to toggle source
# File lib/twig/branch.rb, line 75
def to_hash(property_names)
  {
    'name' => name,
    'last-commit-time' => last_commit_time.iso8601,
    'properties' => get_properties(property_names)
  }
end
to_s() click to toggle source
# File lib/twig/branch.rb, line 73
def to_s ; name ; end
unset_property(property_name) click to toggle source
# File lib/twig/branch.rb, line 156
def unset_property(property_name)
  property_name = sanitize_property(property_name)
  Branch.validate_property_name(property_name)

  value = get_property(property_name)

  if value
    git_config = "branch.#{name.shellescape}.#{property_name}"
    Twig.run(%{git config --unset #{git_config}})
    %{Removed property "#{property_name}" for branch "#{name}".}
  else
    raise MissingPropertyError,
      %{The branch "#{name}" does not have the property "#{property_name}".}
  end
end