Class: DRG::Tasks::ActivePinner

Inherits:
Object
  • Object
show all
Includes:
Log
Defined in:
lib/drg/tasks/active_pinner.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Log

log

Constructor Details

#initialize(type = :patch) ⇒ ActivePinner

Returns a new instance of ActivePinner.

Parameters:

  • type (Symbol) (defaults to: :patch)

    of pin to perform. Available options are [:available, :minor, :patch]



10
11
12
13
14
# File 'lib/drg/tasks/active_pinner.rb', line 10

def initialize(type = :patch)
  @type = type
  @gemfile = Gemfile.new
  @versions = {}
end

Instance Attribute Details

#gemfileObject (readonly)

Returns the value of attribute gemfile.



6
7
8
# File 'lib/drg/tasks/active_pinner.rb', line 6

def gemfile
  @gemfile
end

#typeObject (readonly)

Returns the value of attribute type.



6
7
8
# File 'lib/drg/tasks/active_pinner.rb', line 6

def type
  @type
end

#versions(name) ⇒ Array

Returns a list of available versions (e.g. [‘1.2.0’, ‘1.1.0’]).

Parameters:

  • name (String)

    of the gem

Returns:

  • (Array)

    a list of available versions (e.g. [‘1.2.0’, ‘1.1.0’])



89
90
91
92
93
94
# File 'lib/drg/tasks/active_pinner.rb', line 89

def versions(name)
  @versions[name] ||= begin
    log %Q(Searching for latest #{type} version of "#{name}" ...)
    `gem query -radn ^#{name}$`.scan(/([\d.]+),/).flatten.uniq
  end
end

Instance Method Details

#higher?(list, other_list) ⇒ Boolean

Parameters:

  • list (Array)

    of a gem version’s segments

  • other_list (Array)

    of another gem version’s segments

Returns:

  • (Boolean)


109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/drg/tasks/active_pinner.rb', line 109

def higher?(list, other_list)
  higher = false
  equal = false
  sem_ver_size = [list.size, other_list.size].max
  sem_ver_size.times do |i|
    if list[i].to_i >= other_list[i].to_i
      higher = true
      equal = list[i].to_i == other_list[i].to_i
    else
      break
    end
  end
  higher && !equal
end

#latest_available_version(name, current_version) ⇒ Object

Private



54
55
56
# File 'lib/drg/tasks/active_pinner.rb', line 54

def latest_available_version(name, current_version)
  new_versions(name, current_version).first
end

#latest_minor_version(name, current_version) ⇒ Object

Parameters:

  • name (String)

    of the gem

  • current_version (String)

    of the gem



60
61
62
63
64
65
66
67
# File 'lib/drg/tasks/active_pinner.rb', line 60

def latest_minor_version(name, current_version)
  new_versions(name, current_version).select { |version|
    segments = version.scan(/\d+/)
    major = segments[0].to_i
    minor = segments[1].to_i
    minor > current_version.segments[1] && major == current_version.segments[0]
  }.first
end

#latest_patch_version(name, current_version) ⇒ Object

Parameters:

  • name (String)

    of the gem

  • current_version (String)

    of the gem



71
72
73
74
75
76
77
78
79
# File 'lib/drg/tasks/active_pinner.rb', line 71

def latest_patch_version(name, current_version)
  new_versions(name, current_version).select { |version|
    segments = version.scan(/\d+/)
    major = segments[0].to_i
    minor = segments[1].to_i
    patch = segments[-1].to_i
    patch > current_version.segments[-1] && minor == current_version.segments[1] && major == current_version.segments[0]
  }.first
end

#load_gem_versions(gems) ⇒ Object



102
103
104
105
# File 'lib/drg/tasks/active_pinner.rb', line 102

def load_gem_versions(gems)
  log %Q(Searching for latest #{type} version of #{gems.join(', ')} ...)
  `gem query -ra #{gems.join(' ')}`
end

#load_versions(gems) ⇒ Object



96
97
98
99
100
# File 'lib/drg/tasks/active_pinner.rb', line 96

def load_versions(gems)
  load_gem_versions(gems).scan(/^(#{Array(gems).join('|')})\s\(([\d.\s,\w\-]+)\)$/).each do |gem_name, versions|
    @versions[gem_name] = versions.to_s.split(', ').map { |x| x[/([\d.\w\-]+)/, 1] }.compact
  end
end

#new_versions(name, current_version) ⇒ Object

Parameters:

  • name (String)

    of the gem

  • current_version (String)

    of the gem



83
84
85
# File 'lib/drg/tasks/active_pinner.rb', line 83

def new_versions(name, current_version)
  versions(name).select { |version| higher?(version.scan(/\d+/), current_version.segments) }
end

#perform(gem_name = nil) ⇒ Object



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/drg/tasks/active_pinner.rb', line 16

def perform(gem_name = nil)
  updated_gems = []
  if gem_name
    updated_gems << update(gem_name)
  else
    Updater.new.perform do |gems|
      load_versions gems
      gems.each do |gem|
        updated_gems << update(gem)
      end
    end
  end
  updated_gems.compact!
  log %Q(Done)
  log %Q(You may want to run: "bundle update #{updated_gems.join ' '}") if updated_gems.any?
  gemfile.write if gemfile.saved_lines.any?
end

#update(gem_name) ⇒ Object

Note:

calls #latest_minor_version and #latest_patch_version



36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/drg/tasks/active_pinner.rb', line 36

def update(gem_name)
  spec = ::Bundler.locked_gems.specs.find { |spec| spec.name == gem_name }
  gem = spec && gemfile.find_by_name(spec.name)
  return nil unless gem
  latest_version = public_send("latest_#{type}_version", spec.name, spec.version)
  if latest_version
    log %Q(Updating "#{spec.name}" from #{spec.version.to_s} to #{latest_version})
    gemfile.update gem, latest_version
    spec.name
  else
    log %Q(No newer #{type} versions found for "#{spec.name}"), :grey
  end
end