Class: Changelogger::Versioner

Inherits:
Object
  • Object
show all
Defined in:
lib/changelogger/versioner.rb

Overview

Changelogger::Versioner calculates version numbers for anchor and in-between commits.

Class Method Summary collapse

Class Method Details

.assign(commits, anchor_indices, major: 0, minor_start: 1, base_patch: 10) ⇒ Array<(Integer, Changelogger::Commit, String)>

Changelogger::Versioner.assign -> Array<[Integer, Changelogger::Commit, String]>

Assigns versions for anchor commits (minor increments) and patch versions for in-between commits.

Parameters:

  • commits (Array<Changelogger::Commit>)

    all commits (chronological)

  • anchor_indices (Array<Integer>)

    indices into commits marking anchors

  • major (Integer) (defaults to: 0)

    major version (default: 0)

  • minor_start (Integer) (defaults to: 1)

    starting minor number (default: 1)

  • base_patch (Integer) (defaults to: 10)

    distribution base for patches (default: 10)

Returns:

Raises:

  • (ArgumentError)

    if fewer than 2 anchors are provided



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/changelogger/versioner.rb', line 38

def assign(commits, anchor_indices, major: 0, minor_start: 1, base_patch: 10)
  raise ArgumentError, 'Need at least 2 anchors' if anchor_indices.size < 2

  anchor_indices = anchor_indices.sort.uniq
  version_map = {}

  anchor_indices.each_with_index do |idx, j|
    version_map[idx] = [major, minor_start + j, 0]
  end

  anchor_indices.each_with_index do |start_idx, j|
    break if j >= anchor_indices.size - 1

    end_idx = anchor_indices[j + 1]
    k = [end_idx - start_idx - 1, 0].max
    patches = distribute_patches(k, base: base_patch)

    (start_idx + 1).upto(end_idx - 1) do |i|
      pnum = patches[i - start_idx - 1]
      version_map[i] = [major, minor_start + j, pnum]
    end
  end

  version_map.keys.sort.map do |i|
    v = version_map[i]
    [i, commits[i], "#{v[0]}.#{v[1]}.#{v[2]}"]
  end
end

.distribute_patches(k, base: 10) ⇒ Array<Integer>

Changelogger::Versioner.distribute_patches -> Array<Integer>

Evenly distributes patch numbers in the range 1..base across k in-between commits. Ensures strictly increasing sequence even when rounding collides.

Parameters:

  • k (Integer)

    number of in-between items

  • base (Integer) (defaults to: 10)

    upper bound for distribution (default: 10)

Returns:

  • (Array<Integer>)

    strictly increasing patch numbers



15
16
17
18
19
20
21
22
23
24
25
# File 'lib/changelogger/versioner.rb', line 15

def distribute_patches(k, base: 10) # rubocop:disable Naming/MethodParameterName
  patches = []
  prev = 0
  1.upto(k) do |i|
    x = (i * base.to_f / (k + 1)).round
    x = prev + 1 if x <= prev
    patches << x
    prev = x
  end
  patches
end