Class: RubyLsp::SetupBundler

Inherits:
Object
  • Object
show all
Extended by:
T::Sig
Defined in:
lib/ruby_lsp/setup_bundler.rb

Defined Under Namespace

Classes: BundleNotLocked

Constant Summary collapse

FOUR_HOURS =
T.let(4 * 60 * 60, Integer)

Instance Method Summary collapse

Constructor Details

#initialize(project_path, branch: nil) ⇒ SetupBundler

Returns a new instance of SetupBundler.



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/ruby_lsp/setup_bundler.rb', line 24

def initialize(project_path, branch: nil)
  @project_path = project_path
  @branch = branch

  # Custom bundle paths
  @custom_dir = T.let(Pathname.new(".ruby-lsp").expand_path(Dir.pwd), Pathname)
  @custom_gemfile = T.let(@custom_dir + "Gemfile", Pathname)
  @custom_lockfile = T.let(@custom_dir + "Gemfile.lock", Pathname)
  @lockfile_hash_path = T.let(@custom_dir + "main_lockfile_hash", Pathname)
  @last_updated_path = T.let(@custom_dir + "last_updated", Pathname)

  # Regular bundle paths
  @gemfile = T.let(
    begin
      Bundler.default_gemfile
    rescue Bundler::GemfileNotFound
      nil
    end,
    T.nilable(Pathname),
  )
  @lockfile = T.let(@gemfile ? Bundler.default_lockfile : nil, T.nilable(Pathname))

  @dependencies = T.let(load_dependencies, T::Hash[String, T.untyped])
end

Instance Method Details

#setup!Object

Raises:



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/ruby_lsp/setup_bundler.rb', line 52

def setup!
  raise BundleNotLocked if @gemfile&.exist? && !@lockfile&.exist?

  # Do not setup a custom bundle if both `ruby-lsp` and `debug` are already in the Gemfile
  if @dependencies["ruby-lsp"] && @dependencies["debug"]
    warn("Ruby LSP> Skipping custom bundle setup since both `ruby-lsp` and `debug` are already in #{@gemfile}")

    # If the user decided to add the `ruby-lsp` and `debug` to their Gemfile after having already run the Ruby LSP,
    # then we need to remove the `.ruby-lsp` folder, otherwise we will run `bundle install` for the top level and
    # try to execute the Ruby LSP using the custom bundle, which will fail since the gems are not installed there
    @custom_dir.rmtree if @custom_dir.exist?
    return run_bundle_install
  end

  # Automatically create and ignore the .ruby-lsp folder for users
  @custom_dir.mkpath unless @custom_dir.exist?
  ignore_file = @custom_dir + ".gitignore"
  ignore_file.write("*") unless ignore_file.exist?

  write_custom_gemfile

  unless @gemfile&.exist? && @lockfile&.exist?
    warn("Ruby LSP> Skipping lockfile copies because there's no top level bundle")
    return run_bundle_install(@custom_gemfile)
  end

  lockfile_contents = @lockfile.read
  current_lockfile_hash = Digest::SHA256.hexdigest(lockfile_contents)

  if @custom_lockfile.exist? && @lockfile_hash_path.exist? && @lockfile_hash_path.read == current_lockfile_hash
    warn("Ruby LSP> Skipping custom bundle setup since #{@custom_lockfile} already exists and is up to date")
    return run_bundle_install(@custom_gemfile)
  end

  FileUtils.cp(@lockfile.to_s, @custom_lockfile.to_s)
  @lockfile_hash_path.write(current_lockfile_hash)
  run_bundle_install(@custom_gemfile)
end