Skip to content

Commit

Permalink
Merge pull request #1149 from ruby/refactor-collection
Browse files Browse the repository at this point in the history
Refactor collection
  • Loading branch information
soutaro authored Dec 5, 2022
2 parents 57c07bb + 7cd6aac commit e926a9a
Show file tree
Hide file tree
Showing 25 changed files with 723 additions and 378 deletions.
7 changes: 6 additions & 1 deletion lib/rbs/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,12 @@ def loader
end

loader = EnvironmentLoader.new(core_root: core_root, repository: repository)
lock = config_path&.then { |p| Collection::Config.lockfile_of(p) }
if config_path
lock_path = Collection::Config.to_lockfile_path(config_path)
if lock_path.file?
lock = Collection::Config::Lockfile.from_lockfile(lockfile_path: lock_path, data: YAML.load_file(lock_path.to_s))
end
end
loader.add_collection(lock) if lock

dirs.each do |dir|
Expand Down
1 change: 1 addition & 0 deletions lib/rbs/collection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

require_relative './collection/sources'
require_relative './collection/config'
require_relative './collection/config/lockfile'
require_relative './collection/config/lockfile_generator'
require_relative './collection/installer'
require_relative './collection/cleaner'
Expand Down
50 changes: 11 additions & 39 deletions lib/rbs/collection/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ def initialize

PATH = Pathname('rbs_collection.yaml')

attr_reader :config_path, :data

def self.find_config_path
current = Pathname.pwd

Expand All @@ -30,18 +32,16 @@ def self.find_config_path
# Generate a rbs lockfile from Gemfile.lock to `config_path`.
# If `with_lockfile` is true, it respects existing rbs lockfile.
def self.generate_lockfile(config_path:, gemfile_lock_path:, with_lockfile: true)
LockfileGenerator.generate(config_path: config_path, gemfile_lock_path: gemfile_lock_path, with_lockfile: with_lockfile)
config = from_path(config_path)
lockfile = LockfileGenerator.generate(config: config, gemfile_lock_path: gemfile_lock_path, with_lockfile: with_lockfile)

[config, lockfile]
end

def self.from_path(path)
new(YAML.load(path.read), config_path: path)
end

def self.lockfile_of(config_path)
lock_path = to_lockfile_path(config_path)
from_path lock_path if lock_path.exist?
end

def self.to_lockfile_path(config_path)
config_path.sub_ext('.lock' + config_path.extname)
end
Expand All @@ -51,16 +51,16 @@ def initialize(data, config_path:)
@config_path = config_path
end

def add_gem(gem)
gems << gem
end

def gem(gem_name)
gems.find { |gem| gem['name'] == gem_name }
end

def repo_path
@config_path.dirname.join @data['path']
@config_path.dirname.join repo_path_data
end

def repo_path_data
Pathname(@data["path"])
end

def sources
Expand All @@ -72,37 +72,9 @@ def sources
)
end

def dump_to(io)
YAML.dump(@data, io)
end

def gems
@data['gems'] ||= []
end

def gemfile_lock_path=(path)
@data['gemfile_lock_path'] = path.relative_path_from(@config_path.dirname).to_s
end

def gemfile_lock_path
path = @data['gemfile_lock_path']
return unless path
@config_path.dirname.join path
end

# It raises an error when there are non-available libraries
def check_rbs_availability!
raise CollectionNotAvailable unless repo_path.exist?

gems.each do |gem|
case gem['source']['type']
when 'git'
meta_path = repo_path.join(gem['name'], gem['version'], Sources::Git::METADATA_FILENAME)
raise CollectionNotAvailable unless meta_path.exist?
raise CollectionNotAvailable unless gem == YAML.load(meta_path.read)
end
end
end
end
end
end
115 changes: 115 additions & 0 deletions lib/rbs/collection/config/lockfile.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# frozen_string_literal: true

module RBS
module Collection
class Config
class Lockfile
attr_reader :lockfile_path, :lockfile_dir, :path, :gemfile_lock_path, :sources, :gems

def initialize(lockfile_path:, path:, gemfile_lock_path:)
@lockfile_path = lockfile_path
@lockfile_dir = lockfile_path.parent
@path = path
@gemfile_lock_path = gemfile_lock_path

@sources = {}
@gems = {}
end

def fullpath
lockfile_dir + path
end

def gemfile_lock_fullpath
if gemfile_lock_path
lockfile_dir + gemfile_lock_path
end
end

def each_source(&block)
if block
sources.each_value(&block)
yield Sources::Rubygems.instance
yield Sources::Stdlib.instance
else
enum_for :each_source
end
end

def to_lockfile
# @type var data: lockfile_data

data = {
"sources" => sources.each_value.sort_by {|s| s.name }.map {|source| source.to_lockfile },
"path" => path.to_s,
"gems" => gems.each_value.sort_by {|g| g[:name] }.map {|hash| library_data(hash) },
"gemfile_lock_path" => gemfile_lock_path.to_s
}

data.delete("sources") if sources.empty?
data.delete("gems") if gems.empty?

data
end

def self.from_lockfile(lockfile_path:, data:)
path = Pathname(data["path"])
if p = data["gemfile_lock_path"]
gemfile_lock_path = Pathname(p)
end

lockfile = Lockfile.new(lockfile_path: lockfile_path, path: path, gemfile_lock_path: gemfile_lock_path)

if sources = data["sources"]
sources.each do |src|
git = Sources::Git.new(
name: src["name"],
revision: src["revision"],
remote: src["remote"],
repo_dir: src["repo_dir"]
)
lockfile.sources[git.name] = git
end
end

if gems = data["gems"]
gems.each do |gem|
src = gem["source"]
source = Sources.from_config_entry(src)
lockfile.gems[gem["name"]] = {
name: gem["name"],
version: gem["version"],
source: source
}
end
end

lockfile
end

def library_data(lib)
{
"name" => lib[:name],
"version" => lib[:version],
"source" => lib[:source].to_lockfile
}
end

def check_rbs_availability!
raise CollectionNotAvailable unless fullpath.exist?

gems.each_value do |gem|
source = gem[:source]

case source
when Sources::Git
meta_path = fullpath.join(gem[:name], gem[:version], Sources::Git::METADATA_FILENAME)
raise CollectionNotAvailable unless meta_path.exist?
raise CollectionNotAvailable unless library_data(gem) == YAML.load(meta_path.read)
end
end
end
end
end
end
end
Loading

0 comments on commit e926a9a

Please sign in to comment.