Skip to content

Commit

Permalink
Merge pull request #1402 from ruby/fix-lockfile-generator
Browse files Browse the repository at this point in the history
Generate gem specific sources in lockfile
  • Loading branch information
soutaro committed Jul 31, 2023
1 parent 2995ca3 commit 7027563
Show file tree
Hide file tree
Showing 3 changed files with 144 additions and 10 deletions.
25 changes: 16 additions & 9 deletions lib/rbs/collection/config/lockfile_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def message
end
end

attr_reader :config, :lockfile, :definition, :existing_lockfile, :gem_hash
attr_reader :config, :lockfile, :definition, :existing_lockfile, :gem_hash, :gem_entries

def self.generate(config:, definition:, with_lockfile: true)
generator = new(config: config, definition: definition, with_lockfile: with_lockfile)
Expand All @@ -31,6 +31,11 @@ def self.generate(config:, definition:, with_lockfile: true)
def initialize(config:, definition:, with_lockfile:)
@config = config

@gem_entries = config.gems.each.with_object({}) do |entry, hash| #$ Hash[String, gem_entry?]
name = entry["name"]
hash[name] = entry
end

lockfile_path = Config.to_lockfile_path(config.config_path)
lockfile_dir = lockfile_path.parent

Expand Down Expand Up @@ -58,15 +63,13 @@ def initialize(config:, definition:, with_lockfile:)
end

def generate
ignored_gems = config.gems.select {|gem| gem["ignore"] }.map {|gem| gem["name"] }.to_set

config.gems.each do |gem|
if Sources::Stdlib.instance.has?(gem["name"], nil) || gem.dig("source", "type") == "stdlib"
unless ignored_gems.include?(gem["name"])
unless gem.fetch("ignore", false)
assign_stdlib(name: gem["name"], from_gem: nil)
end
else
assign_gem(name: gem["name"], version: gem["version"], ignored_gems: ignored_gems, src_data: gem["source"])
assign_gem(name: gem["name"], version: gem["version"])
end
end

Expand All @@ -76,7 +79,7 @@ def generate
end

if spec = gem_hash[dep.name]
assign_gem(name: dep.name, version: spec.version, ignored_gems: ignored_gems, src_data: nil, skip: dep.source.is_a?(Bundler::Source::Gemspec))
assign_gem(name: dep.name, version: spec.version, skip: dep.source.is_a?(Bundler::Source::Gemspec))
end
end

Expand All @@ -91,8 +94,12 @@ def generate
end
end

private def assign_gem(name:, version:, src_data:, ignored_gems:, skip: false)
return if ignored_gems.include?(name)
private def assign_gem(name:, version:, skip: false)
entry = gem_entries[name]
src_data = entry&.fetch("source", nil)
ignored = entry&.fetch("ignore", false)

return if ignored
return if lockfile.gems.key?(name)

unless skip
Expand Down Expand Up @@ -136,7 +143,7 @@ def generate
if spec = gem_hash.fetch(name, nil)
spec.dependencies.each do |dep|
if dep_spec = gem_hash[dep.name]
assign_gem(name: dep.name, version: dep_spec.version, src_data: nil, ignored_gems: ignored_gems)
assign_gem(name: dep.name, version: dep_spec.version)
end
end
else
Expand Down
5 changes: 4 additions & 1 deletion sig/collection/config/lockfile_generator.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ module RBS
# A hash table to look up a spec from name of the gem
attr_reader gem_hash: Hash[String, Bundler::LazySpecification]

# A hash table to look up a gem entry in collection config from the name of the gem
attr_reader gem_entries: Hash[String, gem_entry?]

def self.generate: (config: Config, definition: Bundler::Definition, ?with_lockfile: boolish) -> Lockfile

def initialize: (config: Config, definition: Bundler::Definition, with_lockfile: boolish) -> void
Expand All @@ -38,7 +41,7 @@ module RBS
#
# * If `skip:` is true, it skips adding the gem, but adds it's dependencies.
#
def assign_gem: (name: String, version: String?, src_data: Sources::source_entry?, ignored_gems: Set[String], ?skip: bool) -> void
def assign_gem: (name: String, version: String?, ?skip: bool) -> void

def assign_stdlib: (name: String, from_gem: String?) -> void

Expand Down
124 changes: 124 additions & 0 deletions test/rbs/collection/config_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -761,6 +761,130 @@ def test_generate_lockfile__gems_not_included_in_gemfile
end
end

def test_generate_lockfile__dependency_source
mktmpdir do |tmpdir|
config_path = tmpdir / 'rbs_collection.yaml'
config_path.write <<~YAML
sources:
- type: git
name: ruby/gem_rbs_collection
remote: https://github.com/ruby/gem_rbs_collection.git
revision: 9612e5e67697153dcc7464c01115db44d29b1e34
repo_dir: gems
path: '.gem_rbs_collection'
gems:
- name: activesupport
- name: concurrent-ruby
source:
type: git
name: concurrent-ruby specific source
remote: https://github.com/ruby/gem_rbs_collection.git
revision: 9612e5e67697153dcc7464c01115db44d29b1e34
repo_dir: gems
- name: i18n
ignore: true
YAML
gemfile_path = tmpdir / 'Gemfile'
gemfile_path.write <<~GEMFILE
source "https://rubygems.org"
gem "activesupport"
GEMFILE
gemfile_lock_path = tmpdir / 'Gemfile.lock'
gemfile_lock_path.write <<~GEMFILE_LOCK
GEM
remote: https://rubygems.org/
specs:
activesupport (6.1.4.1)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
tzinfo (~> 2.0)
zeitwerk (~> 2.3)
concurrent-ruby (1.1.9)
i18n (1.8.11)
concurrent-ruby (~> 1.0)
minitest (5.14.4)
tzinfo (2.0.4)
concurrent-ruby (~> 1.0)
zeitwerk (2.5.1)
PLATFORMS
x86_64-linux
DEPENDENCIES
activesupport
BUNDLED WITH
2.2.0
GEMFILE_LOCK

definition = Bundler::Definition.build(gemfile_path, gemfile_lock_path, false)
_config, lockfile = RBS::Collection::Config.generate_lockfile(config_path: config_path, definition: definition)
string = YAML.dump(lockfile.to_lockfile)

assert_config <<~YAML, string
sources:
- type: git
name: ruby/gem_rbs_collection
remote: https://github.com/ruby/gem_rbs_collection.git
revision: 9612e5e67697153dcc7464c01115db44d29b1e34
repo_dir: gems
path: ".gem_rbs_collection"
gemfile_lock_path: 'Gemfile.lock'
gems:
- name: activesupport
version: "7.0"
source:
name: ruby/gem_rbs_collection
remote: https://github.com/ruby/gem_rbs_collection.git
revision: 9612e5e67697153dcc7464c01115db44d29b1e34
repo_dir: gems
type: git
- name: concurrent-ruby
version: "1.1"
source:
name: concurrent-ruby specific source
remote: https://github.com/ruby/gem_rbs_collection.git
revision: 9612e5e67697153dcc7464c01115db44d29b1e34
repo_dir: gems
type: git
- name: date
version: "0"
source:
type: stdlib
- name: logger
version: "0"
source:
type: stdlib
- name: minitest
version: '0'
source:
type: stdlib
- name: monitor
version: "0"
source:
type: stdlib
- name: mutex_m
version: "0"
source:
type: stdlib
- name: securerandom
version: "0"
source:
type: stdlib
- name: singleton
version: "0"
source:
type: stdlib
- name: time
version: "0"
source:
type: stdlib
YAML
end
end

private def assert_config(expected_str, actual_str)
assert_equal YAML.load(expected_str), YAML.load(actual_str)
end
Expand Down

0 comments on commit 7027563

Please sign in to comment.