renovatebot / renovate

Home of the Renovate CLI: Cross-platform Dependency Automation by Mend.io
https://mend.io/renovate
GNU Affero General Public License v3.0
17.15k stars 2.23k forks source link

Parse `gemspec` files #10616

Open HonkingGoose opened 3 years ago

HonkingGoose commented 3 years ago

What would you like Renovate to be able to do?

Copy/paste of comment from @rarkins in discussion #10585.

I would definitely like to parse gemspec files, but only using JS-based parsing and therefore they may need to confirm to "conventions" rather than being completely free of convention. Let's have a feature request issue to discuss it if we don't already

Did you already have any implementation ideas?

Nope. 😄

viceice commented 3 years ago

As far as i understand the docs, we can use a simple regex to parse the deps.

marvin-bitterlich commented 3 years ago

I encountered this same need just now and took a stab at a regexManager, its not working but maybe someone with more knowledge about these might know what is missing to get this over the line:

  "regexManagers": [
    {
      "fileMatch": ["^*.gemspec"],
      "matchStrings": [
        ".*add.*dependency '(?<depName>.*?)','(?<currentValue>.*?)'"
      ],
      "datasourceTemplate": "rubygems"
    }
  ]
github-actions[bot] commented 3 years ago

Hi there,

Help us by making a minimal reproduction repository.

Before we can start work on your issue we first need to know exactly what's causing the current behavior. A minimal reproduction helps us with this.

To get started, please read our guide on creating a minimal reproduction to understand what is needed.

We may close the issue if you (or someone else) have not provided a minimal reproduction within two weeks. If you need more time, or are stuck, please ask for help or more time in a comment.

Good luck,

The Renovate team

marvin-bitterlich commented 3 years ago

The discussion already references examples like https://github.com/mdub/config_hound/blob/master/config_hound.gemspec If that helps :)

marvin-bitterlich commented 3 years ago
Gem::Specification.new do |spec|
  spec.name          = "renovate-gemspec-example"
  spec.version       = '1.0.0'
  spec.authors       = ["reggaemuffin"]
  spec.email         = ["reggaemuffin@xxx.com"]

  spec.summary       = %q{A minimal example for a gemspec file to parse}
  spec.description   = %q{A minimal example for a gemspec file to parse}
  spec.homepage      = "https://github.com/renovatebot/renovate/issues/10616"
  spec.license       = "MIT"

  spec.files         = `git ls-files -z`.split("\x0").reject do |f|
    f.match(%r{^(spec|images)/})
  end
  spec.bindir        = "exe"
  spec.executables   = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
  spec.require_paths = ["lib"]

  spec.required_ruby_version = '>= 2.1.0' # keyword args

  spec.add_runtime_dependency 'apollo-federation', '~> 1.0'
  spec.add_runtime_dependency 'apollo-tracing', '~> 1.6'
  spec.add_runtime_dependency 'activesupport', '~> 6.0', '>= 5.0'
  spec.add_dependency 'batch-loader', '~> 1.5'
  spec.add_dependency 'graphql', '~> 1.9.19'
  spec.add_dependency 'vault', '0.12.0'
  spec.add_development_dependency 'bundler', '~> 2.1', '>= 2.1.4'
  spec.add_development_dependency 'rspec', '~> 3.9', '>= 3.9.0'
  spec.add_development_dependency 'pry', '~> 0.13'
  spec.add_development_dependency "rake", "~> 13.0"
  spec.add_development_dependency "benchmark-ips", "~> 2.7"
  spec.add_development_dependency "ruby-prof", "~> 0.16"
end

This would be an example with some random diverse esample of dependencies from a few public repositories, I tried to get a few semi edge cases in there that can of course be removed too

marvin-bitterlich commented 3 years ago

image

It seems that ^.*add.*dependency.*['"](?<depName>.*?)['"],.*['"](?<currentValue>.*?)['"].* might work as a generic enough regex for this example

marvin-bitterlich commented 3 years ago

Tested this locally and it does not register in the logs of renovate except in the config

So far unclear:

rarkins commented 3 years ago

So for a feature request like this, our goal would be for a gemspec which is both minimal as well as covering all the use cases. There's no point in having 20 entries all with the same syntax, for example - and it slows things down by making debugging harder to do. We can move this to reproduction:provided and status:ready once someone can put such a thing into a public repo which an be used as part of development

rarkins commented 3 years ago
  • Is datasource rubygems or bundler or something else, and should it be datasource or the template

You can see the full list here: https://docs.renovatebot.com/modules/datasource/

(the answer is rubygems)

  • Is semver supporting the ~> versions or should that be excluded

See https://docs.renovatebot.com/modules/versioning/#ruby-versioning

There is no one "semver" because semver itself defines no ranges at all, while most package managers have different syntax to each other for ranges.

marvin-bitterlich commented 3 years ago

I created https://github.com/reggaemuffin/renovate-gemspec-minimal-example and will try to update it with the ruby version strategy to see if that works

marvin-bitterlich commented 3 years ago

You can see a run of it as https://app.renovatebot.com/dashboard#github/reggaemuffin/renovate-gemspec-minimal-example/432999060

image

Not sure how to extract more information out of this but let me know if you have any ideas

mattwynne commented 2 years ago

We'd also like something like this. We're currently manually upgrading gemspecs using a bash script.

narwold commented 2 years ago

Any progress on this per chance?

mattwynne commented 2 years ago

FWIW @narwold we switched to DependaBot which supports this out of the box.

mpkorstanje commented 1 year ago

@marvin-bitterlich at a glance it seems your attempt at using the regex matcher won't work because you start the regex with ^.

The regex manager matches are done per-file and not per-line, you should be aware when using the ^ and/or $ regex assertions. https://docs.renovatebot.com/modules/manager/regex/

mpkorstanje commented 1 year ago

I've created a working version of the regex manager here:

https://github.com/mpkorstanje/renovate-gemspec-minimal-example

{
  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
  "extends": [
    "config:base",
  ],
  "regexManagers": [
    {
      "fileMatch": [
        "^*.gemspec"
      ],
      "matchStrings": [
        ".*\\.add_(:?(?<depType>.*?)_)?dependency\\s*(['\"])(?<depName>[^'\"]+)(['\"])(\\s*,\\s*(?<currentValue>(['\"])[^'\"]+['\"](\\s*,\\s*['\"][^'\"]+['\"])?))?"
      ],
      "datasourceTemplate": "rubygems",
      "versioningTemplate": "ruby"
    }
  ]
}
AlexWayfer commented 10 months ago

regexManagers is deprecated, as I see, so I've tried to actualize it:

"customManagers": [
    {
        "customType": "regex",
        "fileMatch": ["^*.gemspec"],
        "matchStrings": [
            ".*\\.add_(:?(?<depType>.*?)_)?dependency\\s*(['\"])(?<depName>[^'\"]+)(['\"])(\\s*,\\s*(?<currentValue>(['\"])[^'\"]+['\"](\\s*,\\s*['\"][^'\"]+['\"])?))?"
        ],
        "datasourceTemplate": "rubygems",
        "versioningTemplate": "ruby"
    }
],

But now I have this error in dashboard:

image

rangeStrategy is disallowed in custom managers,replace value in root gives the same error, so now we're in a dead-end.

mpkorstanje commented 5 months ago

Yup. Fairly easy to reproduce. Updated https://github.com/mpkorstanje/renovate-gemspec-minimal-example with the customManagers.

It appears that this code here:

https://github.com/renovatebot/renovate/blob/3bfad40cc580045b4b1a513637c335cacb4bf1e9/lib/modules/manager/index.ts#L79-L83

Is checking against the managerList rather than the allManagersList:

https://github.com/renovatebot/renovate/blob/3bfad40cc580045b4b1a513637c335cacb4bf1e9/lib/modules/manager/index.ts#L16-L19

Started a new issue here https://github.com/renovatebot/renovate/discussions/28090

D1X7R4 commented 5 months ago

Hi!

Is there any chance of gemspec support soon?

On our particular case we defined gemspec in our Gemfile. Where the gemspec file specifies the dependencies required by the gem and the Gemfile the required ones for testing and development.

In this case, the manager should update ranges in the gemspec but also the Gemfile.lock definition.

References: