Class: RuboCop::Server::Cache Private

Inherits:
Object
  • Object
show all
Defined in:
lib/rubocop/server/cache.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

Caches the states of server process.

Constant Summary collapse

GEMFILE_NAMES =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

%w[Gemfile gems.rb].freeze
LOCKFILE_NAMES =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

%w[Gemfile.lock gems.locked].freeze

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.cache_root_pathObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.


28
29
30
# File 'lib/rubocop/server/cache.rb', line 28

def cache_root_path
  @cache_root_path
end

Class Method Details

.acquire_lockObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

[View source]

142
143
144
145
146
147
148
149
150
# File 'lib/rubocop/server/cache.rb', line 142

def acquire_lock
  lock_file = File.open(lock_path, File::CREAT)
  # flock returns 0 if successful, and false if not.
  flock_result = lock_file.flock(File::LOCK_EX | File::LOCK_NB)
  yield flock_result != false
ensure
  lock_file.flock(File::LOCK_UN)
  lock_file.close
end

.cache_pathObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

[View source]

69
70
71
72
73
74
75
76
77
# File 'lib/rubocop/server/cache.rb', line 69

def cache_path
  cache_root_dir = if cache_root_path
                     File.join(cache_root_path, 'rubocop_cache')
                   else
                     cache_root_dir_from_config
                   end

  File.expand_path(File.join(cache_root_dir, 'server'))
end

.cache_root_dir_from_configObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

rubocop:disable Metrics/MethodLength

[View source]

80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/rubocop/server/cache.rb', line 80

def cache_root_dir_from_config
  CacheConfig.root_dir do
    # `RuboCop::ConfigStore` has heavy dependencies, this is a lightweight implementation
    # so that only the necessary `CacheRootDirectory` can be obtained.
    config_path = ConfigFinder.find_config_path(Dir.pwd)
    file_contents = File.read(config_path)

    # Returns early if `CacheRootDirectory` is not used before requiring `erb` or `yaml`.
    next unless file_contents.include?('CacheRootDirectory')

    require 'erb'
    yaml_code = ERB.new(file_contents).result

    require 'yaml'
    config_yaml = YAML.safe_load(
      yaml_code, permitted_classes: [Regexp, Symbol], aliases: true
    )

    # For compatibility with Ruby 3.0 or lower.
    if Gem::Version.new(Psych::VERSION) < Gem::Version.new('4.0.0')
      config_yaml == false ? nil : config_yaml
    end

    config_yaml&.dig('AllCops', 'CacheRootDirectory')
  end
end

.dirObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

rubocop:enable Metrics/AbcSize

[View source]

63
64
65
66
67
# File 'lib/rubocop/server/cache.rb', line 63

def dir
  Pathname.new(File.join(cache_path, project_dir_cache_key)).tap do |d|
    d.mkpath unless d.exist?
  end
end

.inherit_from_data(yaml) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

[View source]

172
173
174
175
176
177
178
179
180
181
182
# File 'lib/rubocop/server/cache.rb', line 172

def inherit_from_data(yaml)
  return '' unless (inherit_from_paths = yaml['inherit_from'])

  Array(inherit_from_paths).map do |path|
    next if PathUtil.remote_file?(path)

    path = Pathname(path)

    path.exist? ? path.read : ''
  end.join
end

.lock_pathObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

[View source]

120
121
122
# File 'lib/rubocop/server/cache.rb', line 120

def lock_path
  dir.join('lock')
end

.pid_pathObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

[View source]

116
117
118
# File 'lib/rubocop/server/cache.rb', line 116

def pid_path
  dir.join('pid')
end

.pid_running?Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:

  • (Boolean)
[View source]

136
137
138
139
140
# File 'lib/rubocop/server/cache.rb', line 136

def pid_running?
  Process.kill(0, pid_path.read.to_i) == 1
rescue Errno::ESRCH, Errno::ENOENT, Errno::EACCES, Errno::EROFS, Errno::ENAMETOOLONG
  false
end

.port_pathObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

rubocop:enable Metrics/MethodLength

[View source]

108
109
110
# File 'lib/rubocop/server/cache.rb', line 108

def port_path
  dir.join('port')
end

.project_dirObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Searches for Gemfile or gems.rb in the current dir or any parent dirs

[View source]

31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/rubocop/server/cache.rb', line 31

def project_dir
  current_dir = Dir.pwd
  while current_dir != '/'
    return current_dir if GEMFILE_NAMES.any? do |gemfile|
      File.exist?(File.join(current_dir, gemfile))
    end

    current_dir = File.expand_path('..', current_dir)
  end
  # If we can't find a Gemfile, just use the current directory
  Dir.pwd
end

.project_dir_cache_keyObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

[View source]

44
45
46
# File 'lib/rubocop/server/cache.rb', line 44

def project_dir_cache_key
  @project_dir_cache_key ||= project_dir[1..].tr('/', '+')
end

.require_data(yaml) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

[View source]

184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/rubocop/server/cache.rb', line 184

def require_data(yaml)
  return '' unless (require_paths = yaml['require'])

  Array(require_paths).map do |path|
    # NOTE: This targets only relative or absolute path specifications.
    # For example, specifications like `require: rubocop-performance`,
    # which can be loaded from `$LOAD_PATH`, are ignored.
    next unless path.start_with?('.', '/')

    # NOTE: `.so` files are not typically specified, so only `.rb` files are targeted.
    path = "#{path}.rb" unless path.end_with?('.rb')
    path = Pathname(path)

    path.exist? ? path.read : ''
  end.join
end

.restart_keyObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

rubocop:disable Metrics/AbcSize

[View source]

49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/rubocop/server/cache.rb', line 49

def restart_key
  lockfile_path = LOCKFILE_NAMES.map do |lockfile_name|
    Pathname(project_dir).join(lockfile_name)
  end.find(&:exist?)
  version_data = lockfile_path&.read || RuboCop::Version::STRING
  config_data = Pathname(ConfigFinder.find_config_path(Dir.pwd)).read
  yaml = YAML.safe_load(config_data, permitted_classes: [Regexp, Symbol], aliases: true)
  inherit_from_data = inherit_from_data(yaml)
  require_data = require_data(yaml)

  Digest::SHA1.hexdigest(version_data + config_data + inherit_from_data + require_data)
end

.status_pathObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

[View source]

124
125
126
# File 'lib/rubocop/server/cache.rb', line 124

def status_path
  dir.join('status')
end

.stderr_pathObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

[View source]

132
133
134
# File 'lib/rubocop/server/cache.rb', line 132

def stderr_path
  dir.join('stderr')
end

.token_pathObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

[View source]

112
113
114
# File 'lib/rubocop/server/cache.rb', line 112

def token_path
  dir.join('token')
end

.version_pathObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

[View source]

128
129
130
# File 'lib/rubocop/server/cache.rb', line 128

def version_path
  dir.join('version')
end

.write_pid_fileObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

[View source]

157
158
159
160
161
162
# File 'lib/rubocop/server/cache.rb', line 157

def write_pid_file
  pid_path.write(Process.pid)
  yield
ensure
  dir.rmtree
end

.write_port_and_token_files(port:, token:) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

[View source]

152
153
154
155
# File 'lib/rubocop/server/cache.rb', line 152

def write_port_and_token_files(port:, token:)
  port_path.write(port)
  token_path.write(token)
end

.write_status_file(status) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

[View source]

164
165
166
# File 'lib/rubocop/server/cache.rb', line 164

def write_status_file(status)
  status_path.write(status)
end

.write_version_file(version) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

[View source]

168
169
170
# File 'lib/rubocop/server/cache.rb', line 168

def write_version_file(version)
  version_path.write(version)
end