class VCLog::Repo

Encapsulate representaiton of the repository.

Constants

ROOT_GLOB

File glob used to find project root directory.

Attributes

options[R]

Options hash.

root[R]

Project’s root directory.

Public Class Methods

new(root, options={}) click to toggle source

Setup new Repo instance.

# File lib/vclog/repo.rb, line 35
def initialize(root, options={})
  options[:root] = root if root

  @config  = Config.new(options)
  @options = options

  vcs_type = @config.vcs_type

  raise ArgumentError, "Not a recognized version control system." unless vcs_type

  @adapter = Adapters.const_get(vcs_type.capitalize).new(self)
end

Public Instance Methods

adapter() click to toggle source

Returns instance of an Adapter subclass.

# File lib/vclog/repo.rb, line 51
def adapter
  @adapter
end
apply_heuristics(changes) click to toggle source

Apply heuristics to changes.

# File lib/vclog/repo.rb, line 128
def apply_heuristics(changes)
  changes.each do |change|
    change.apply_heuristics(heuristics)
  end
end
autotag(prefix=nil) click to toggle source

Read history file and make a commit tag for any release not already tagged. Unless the force option is set the user will be prompted for each new tag.

# File lib/vclog/repo.rb, line 95
def autotag(prefix=nil)
  history_file.tags.each do |tag|
    label = "#{prefix}#{tag.name}"
    if not adapter.tag?(label)
      chg = adapter.change_by_date(tag.date)
      if chg
        if force? or ask_yn(new_tag_message(label, tag) + "\nCreate tag? [yN] ")
          adapter.tag(chg.rev, label, tag.date, tag.message)
        end
      else
        puts "No commit found for #{label} #{tag.date.strftime('%Y-%m-%d')}."
      end
    end
  end
end
bump() click to toggle source

Make an educated guess as to the next version number based on changes made since previous release.

@return [String] version number

@todo Allow configuration of version bump thresholds

# File lib/vclog/repo.rb, line 214
def bump
  last_release = releases(changes).first
  max = last_release.changes.map{ |c| c.level }.max
  if max > 1
    bump_part('major')
  elsif max >= 0
    bump_part('minor')
  else
    bump_part('patch')
  end
end
bump_part(part=nil) click to toggle source

Provides a bumped version number.

# File lib/vclog/repo.rb, line 229
def bump_part(part=nil)
  raise "bad version part - #{part}" unless ['major', 'minor', 'patch', 'build', ''].include?(part.to_s)

  if tags.last
    v = tags[-1].name # TODO: ensure the latest version
    v = tags[-2].name if v == 'HEAD'
  else
    v = '0.0.0'
  end

  v = v.split(/\W/)    # TODO: preserve split chars

  case part.to_s
  when 'major'
    v[0] = v[0].succ
    (1..(v.size-1)).each{ |i| v[i] = '0' }
    v.join('.')
  when 'minor'
    v[1] = '0' unless v[1]
    v[1] = v[1].succ
    (2..(v.size-1)).each{ |i| v[i] = '0' }
    v.join('.')
  when 'patch'
    v[1] = '0' unless v[1]
    v[2] = '0' unless v[2]
    v[2] = v[2].succ
    (3..(v.size-1)).each{ |i| v[i] = '0' }
    v.join('.')
  else
    v[-1] = '0' unless v[-1]
    v[-1] = v[-1].succ
    v.join('.')
  end
end
change_points() click to toggle source

List of all change points.

# File lib/vclog/repo.rb, line 121
def change_points
  @change_points ||= apply_heuristics(adapter.change_points)
end
changes() click to toggle source

List of all changes.

# File lib/vclog/repo.rb, line 114
def changes
  @changes ||= apply_heuristics(adapter.changes)
end
config() click to toggle source

Configuration.

# File lib/vclog/repo.rb, line 58
def config
  @config
end
force?() click to toggle source

Check force option.

# File lib/vclog/repo.rb, line 79
def force?
  config.force?
end
heuristics() click to toggle source

Load heuristics script.

# File lib/vclog/repo.rb, line 72
def heuristics
  config.heuristics
end
history_file() click to toggle source

Access to Repo’s HISTORY file.

# File lib/vclog/repo.rb, line 86
def history_file
  @history_file ||= HistoryFile.new(options[:history_file] || root)
end
method_missing(s, *a, &b) click to toggle source

Delegate missing methods to SCM adapter.

Calls superclass method
# File lib/vclog/repo.rb, line 267
def method_missing(s, *a, &b)
  if adapter.respond_to?(s)
    adapter.send(s, *a, &b)
  else
    super(s,*a,&b)
  end
end
releases(changes) click to toggle source

Collect releases for the given set of changes.

Releases are groups of changes segregated by tags. The release version, release date and release note are defined by hard tag commits.

@param [Array<Change>] changes

List of Change objects.

@return [Array<Release>]

List of Release objects.
# File lib/vclog/repo.rb, line 146
def releases(changes)
  rel  = []
  tags = self.tags.dup

  #ver  = repo.bump(version)

  name = config.version || 'HEAD'
  user = adapter.user
  date = ::Time.now + (3600 * 24) # one day ahead

  change = Change.new(:id=>'HEAD', :date=>date, :who=>user)

  tags << Tag.new(:name=>name, :date=>date, :who=>user, :msg=>"Current Development", :commit=>change)

  # TODO: Do we need to add a Time.now tag?
  # add current verion to release list (if given)
  #previous_version = tags[0].name
  #if current_version < previous_version  # TODO: need to use natural comparision
  #  raise ArgumentError, "Release version is less than previous version (#{previous_version})."
  #end

  # sort by release date
  tags = tags.sort{ |a,b| a.date <=> b.date }

  # organize into deltas
  delta = []
  last  = nil
  tags.each do |tag|
    delta << [tag, [last, tag.commit.date]]
    last = tag.commit.date
  end

  # gather changes for each delta
  delta.each do |tag, (started, ended)|
    if started
      set = changes.select{ |c| c.date > started && c.date <= ended  }
      #gt_vers, gt_date = gt.name, gt.date
      #lt_vers, lt_date = lt.name, lt.date
      #gt_date = Time.parse(gt_date) unless Time===gt_date
      #lt_date = Time.parse(lt_date) unless Time===lt_date
      #log = changelog.after(gt).before(lt)
    else
      #lt_vers, lt_date = lt.name, lt.date
      #lt_date = Time.parse(lt_date) unless Time===lt_date
      #log = changelog.before(lt_date)
      set = changes.select{ |c| c.date <= ended }
    end
    rel << Release.new(tag, set)
  end
  rel.sort
end
report(options) click to toggle source

Print a report with given options.

# File lib/vclog/repo.rb, line 201
def report(options)
  report = Report.new(self, options)
  report.print
end

Private Instance Methods

ask_yn(message) click to toggle source

Ask yes/no question.

# File lib/vclog/repo.rb, line 280
def ask_yn(message)
  case ask(message)
  when 'y', 'Y', 'yes'
    true
  else
    false
  end
end
new_tag_message(label, tag) click to toggle source

Returns a String.

# File lib/vclog/repo.rb, line 292
def new_tag_message(label, tag)
  "#{label} / #{tag.date.strftime('%Y-%m-%d')}\n#{tag.message}"
end