Skip to content

gemspec

Categories: ruby

Renovate supports updating gemspec dependencies.

File Matching

By default, Renovate will check any files matching the following regular expression: /\.gemspec$/.

For details on how to extend a manager's managerFilePatterns value, please follow this link.

Supported datasources

This manager supports extracting the following datasources: rubygems.

Dependency types

This manager extracts the following depType values:

depType Description
runtime Dependencies required at runtime
development Dependencies required during development

Default config

{
  "managerFilePatterns": [
    "/\\.gemspec$/"
  ],
  "versioning": "ruby"
}

Additional Information

The gemspec manager extracts Ruby runtime and development dependencies declared with add_dependency, add_runtime_dependency, and add_development_dependency in *.gemspec files.

For example:

Gem::Specification.new do |spec|
  spec.add_dependency 'rack', '~> 3.1'
  spec.add_runtime_dependency 'rails', '>= 7.0', '< 8.0'
  spec.add_development_dependency 'rspec', '~> 3.13'
  spec.add_dependency 'zeitwerk', ['>= 2.6', '< 3']
end

Renovate also reads a declaration that wraps over several lines, while a bracket is open or a line ends in a comma:

spec.add_dependency(
  'rails',
  '>= 7.0',
  '< 8.0',
)

When Renovate updates a constraint whose parts span several lines, it writes the new parts on one line. Renovate skips a wrapped declaration with a comment between its parts.

Lock file updates

When a sibling Gemfile loads the *.gemspec file, for example with the gemspec directive, Renovate refreshes the sibling Gemfile.lock with Bundler after changing a constraint. Renovate reads this from the lock file: Bundler records a gem loaded from the lock file's own directory in a PATH section with remote: .. Renovate matches that entry against the literal spec.name of the *.gemspec file, or else against its file name. If there is no such entry, then Renovate only updates the *.gemspec file.

When the lock file belongs to the *.gemspec file, Renovate reads each dependency's locked version from it. With the default rangeStrategy of auto, which resolves to update-lockfile, a release that still satisfies the constraint only updates Gemfile.lock. A release outside the constraint replaces the constraint in the *.gemspec file and refreshes Gemfile.lock.

The gemspec manager does not perform lock file maintenance. A gemspec directive only works inside a Gemfile, so the bundler manager already maintains the same Gemfile.lock.

Limitations

A .gemspec file is a Ruby program, so fully evaluating one requires a Ruby interpreter. That is out of scope for Renovate, so this manager parses the file statically instead. In practice nearly all .gemspec files declare their dependencies in the conventional literal form shown above, but Renovate skips declarations that it cannot read statically.

Renovate does not support dependencies generated by loops:

%w[core model controller].each do |variant|
  spec.add_dependency "my-framework-#{variant}", '~> 1.0'
end

Renovate does not support conditional dependencies, and extracts the declarations from all branches, regardless of which branch Ruby would take:

if RUBY_VERSION >= '4.0'
  spec.add_dependency 'foo', '~> 2.0'
else
  spec.add_dependency 'foo', '~> 1.0'
end

Renovate also does not support version constraints built from variables or interpolation, and skips those dependencies:

spec.add_dependency 'foo', "~> #{FooVersion::MAJOR}.0"

Renovate does not support gem names written as percent literals, or names and constraints with .freeze, which is the style that gem build writes into generated gemspecs. Renovate lists those dependencies as skipped with the reason unsupported:

s.add_runtime_dependency(%q<rack>.freeze, ['>= 0'.freeze])
s.add_dependency 'rack'.freeze, '~> 3.1'

If your .gemspec file uses any of these patterns, then update those dependencies manually.