Class: NextRails::GemInfo

Inherits:
Object
  • Object
show all
Defined in:
lib/next_rails/gem_info.rb

Defined Under Namespace

Classes: NullGemInfo

Constant Summary collapse

RAILS_GEMS =
[
  "rails",
  "activemodel",
  "activerecord",
  "actionmailer",
  "actioncable",
  "actionpack",
  "actionview",
  "activejob",
  "activestorage",
  "activesupport",
  "actionmailbox",
  "actiontext",
  "railties",
].freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(gem_specification) ⇒ GemInfo

Returns a new instance of GemInfo.



55
56
57
58
59
# File 'lib/next_rails/gem_info.rb', line 55

def initialize(gem_specification)
  @gem_specification = gem_specification
  @version = gem_specification.version
  @name = gem_specification.name
end

Instance Attribute Details

#gem_specificationObject (readonly)

Returns the value of attribute gem_specification.



53
54
55
# File 'lib/next_rails/gem_info.rb', line 53

def gem_specification
  @gem_specification
end

#latest_compatible_versionObject (readonly)

Returns the value of attribute latest_compatible_version.



53
54
55
# File 'lib/next_rails/gem_info.rb', line 53

def latest_compatible_version
  @latest_compatible_version
end

#nameObject (readonly)

Returns the value of attribute name.



53
54
55
# File 'lib/next_rails/gem_info.rb', line 53

def name
  @name
end

#versionObject (readonly)

Returns the value of attribute version.



53
54
55
# File 'lib/next_rails/gem_info.rb', line 53

def version
  @version
end

Class Method Details

.allObject



47
48
49
50
51
# File 'lib/next_rails/gem_info.rb', line 47

def self.all
  Gem::Specification.each.map do |gem_specification|
    new(gem_specification)
  end
end

Instance Method Details

#ageObject



61
62
63
# File 'lib/next_rails/gem_info.rb', line 61

def age
  created_at.strftime("%b %e, %Y")
end

#compatible_with_rails?(rails_version: nil) ⇒ Boolean

Returns:

  • (Boolean)


113
114
115
# File 'lib/next_rails/gem_info.rb', line 113

def compatible_with_rails?(rails_version: nil)
  unsatisfied_rails_dependencies(rails_version: rails_version).empty?
end

#compatible_with_ruby?(ruby_version) ⇒ Boolean

Returns:

  • (Boolean)


162
163
164
# File 'lib/next_rails/gem_info.rb', line 162

def compatible_with_ruby?(ruby_version)
  gem_specification.required_ruby_version.satisfied_by?(Gem::Version.new(ruby_version))
end

#created_atObject



80
81
82
# File 'lib/next_rails/gem_info.rb', line 80

def created_at
  @created_at ||= gem_specification.date
end

#find_latest_compatible(rails_version: nil) ⇒ Object



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/next_rails/gem_info.rb', line 121

def find_latest_compatible(rails_version: nil)
  dependency = Gem::Dependency.new(@name)
  fetcher = Gem::SpecFetcher.fetcher # Use fetcher instead of ::new to reduce object allocation.

  # list all available data for released gems
  list, errors = fetcher.available_specs(:released)

  specs = []
  # filter only specs for the current gem and older versions
  list.each do |source, gem_tuples|
    gem_tuples.each do |gem_tuple|
      if gem_tuple.name == @name && gem_tuple.version > @version
        specs << source.fetch_spec(gem_tuple)
      end
    end
  end

  # if nothing is found, consider gem incompatible
  if specs.empty?
    @latest_compatible_version = NullGemInfo.new
    return
  end

  # if specs are found, look for the first one from that is compatible
  # with the desired rails version starting from the end
  specs.reverse.each do |spec|
    if spec_compatible_with_rails?(specification: spec, rails_version: rails_version).empty?
      @latest_compatible_version = spec
      break
    end
  end
end

#from_rails?Boolean

Returns:

  • (Boolean)


88
89
90
# File 'lib/next_rails/gem_info.rb', line 88

def from_rails?
  RAILS_GEMS.include?(name)
end

#latest_versionObject



104
105
106
107
108
109
110
111
# File 'lib/next_rails/gem_info.rb', line 104

def latest_version
  latest_gem_specification = Gem.latest_spec_for(name)
  return NullGemInfo.new unless latest_gem_specification

  GemInfo.new(latest_gem_specification)
rescue
  NullGemInfo.new
end

#sourced_from_git?Boolean

Returns:

  • (Boolean)


65
66
67
# File 'lib/next_rails/gem_info.rb', line 65

def sourced_from_git?
  !!gem_specification.git_version
end

#sourced_locally?Boolean

Returns:

  • (Boolean)


69
70
71
72
73
74
75
76
77
78
# File 'lib/next_rails/gem_info.rb', line 69

def sourced_locally?
  # Bundler defines Source::Path and patches Gem::Specification#source to return the
  # gem's real source. Without Bundler loaded, #source is RubyGems' own and returns a
  # Gem::Source::Installed, so no path source can exist; treat the gem as not local.
  return false unless defined?(Bundler::Source::Path)

  source = gem_specification.source
  # Git sources subclass Path, so exclude them; they are reported via #sourced_from_git?.
  source.is_a?(Bundler::Source::Path) && !source.is_a?(Bundler::Source::Git)
end

#spec_compatible_with_rails?(specification: nil, rails_version: nil) ⇒ Boolean

Returns:

  • (Boolean)


154
155
156
157
158
159
160
# File 'lib/next_rails/gem_info.rb', line 154

def spec_compatible_with_rails?(specification: nil, rails_version: nil)
  rails_dependencies = specification.runtime_dependencies.select {|dependency| RAILS_GEMS.include?(dependency.name) }

  rails_dependencies.reject do |rails_dependency|
    rails_dependency.requirement.satisfied_by?(Gem::Version.new(rails_version))
  end
end

#state(rails_version) ⇒ Object



92
93
94
95
96
97
98
99
100
101
102
# File 'lib/next_rails/gem_info.rb', line 92

def state(rails_version)
  if compatible_with_rails?(rails_version: rails_version)
    :compatible
  elsif latest_compatible_version && latest_compatible_version.version == "NOT FOUND"
    :no_new_version
  elsif latest_compatible_version
    :found_compatible
  else
    :incompatible
  end
end

#unsatisfied_rails_dependencies(rails_version: nil) ⇒ Object



117
118
119
# File 'lib/next_rails/gem_info.rb', line 117

def unsatisfied_rails_dependencies(rails_version: nil)
  spec_compatible_with_rails?(specification: gem_specification, rails_version: rails_version)
end

#up_to_date?Boolean

Returns:

  • (Boolean)


84
85
86
# File 'lib/next_rails/gem_info.rb', line 84

def up_to_date?
  version == latest_version.version
end