Class: Rails::Hyperdrive::LockFile

Inherits:
Object
  • Object
show all
Defined in:
lib/rails/hyperdrive/lock_file.rb

Overview

installed_at is volatile metadata, never an input to any comparison.

Defined Under Namespace

Classes: Entry

Constant Summary collapse

SCHEMA_VERSION =
1
STATE_PRESENT =
"present".freeze
STATE_REMOVED =
"removed-by-user".freeze
DISABLED_KEYS =
{ skill: "skills", guideline: "guidelines" }.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path) ⇒ LockFile

Returns a new instance of LockFile.



30
31
32
33
34
35
36
# File 'lib/rails/hyperdrive/lock_file.rb', line 30

def initialize(path)
  @path = path.to_s
  @claude_md_state = nil # nil = no lock has been written yet
  @files = {}            # path(String) => Entry
  @document = {}         # raw parsed YAML, kept so unknown keys survive
  @disabled = empty_disabled
end

Instance Attribute Details

#claude_md_stateObject

Returns the value of attribute claude_md_state.



23
24
25
# File 'lib/rails/hyperdrive/lock_file.rb', line 23

def claude_md_state
  @claude_md_state
end

#pathObject (readonly)

Returns the value of attribute path.



22
23
24
# File 'lib/rails/hyperdrive/lock_file.rb', line 22

def path
  @path
end

Class Method Details

.load(path) ⇒ Object

Load existing lock state from disk (absent file → empty lock).



26
27
28
# File 'lib/rails/hyperdrive/lock_file.rb', line 26

def self.load(path)
  new(path).tap(&:read)
end

Instance Method Details

#carry(entry) ⇒ Object



93
94
95
96
# File 'lib/rails/hyperdrive/lock_file.rb', line 93

def carry(entry)
  return unless entry && entry.path
  @files[entry.path] = entry
end

#carry_settings(other) ⇒ Object

Adopt the state that is not derived from installed content, so rewriting the file preserves it.



76
77
78
79
80
# File 'lib/rails/hyperdrive/lock_file.rb', line 76

def carry_settings(other)
  @document = other.document.dup
  @disabled = other.disabled_lists.dup
  self
end

#disabled?(type, name) ⇒ Boolean

Returns:

  • (Boolean)


70
71
72
# File 'lib/rails/hyperdrive/lock_file.rb', line 70

def disabled?(type, name)
  Array(@disabled[type.to_sym]).include?(name.to_s)
end

#each_entry(&block) ⇒ Object



66
67
68
# File 'lib/rails/hyperdrive/lock_file.rb', line 66

def each_entry(&block)
  @files.values.each(&block)
end

#entry(file_path) ⇒ Object



58
59
60
# File 'lib/rails/hyperdrive/lock_file.rb', line 58

def entry(file_path)
  @files[file_path.to_s]
end

#guideline_pathsObject



62
63
64
# File 'lib/rails/hyperdrive/lock_file.rb', line 62

def guideline_paths
  @files.values.select { |e| e.kind == "guideline" }.map(&:path)
end

#readObject



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/rails/hyperdrive/lock_file.rb', line 38

def read
  return self unless File.exist?(@path)

  data = YAML.safe_load(File.read(@path))
  return self unless data.is_a?(Hash)

  @document = data
  claude_md = data["claude_md"]
  @claude_md_state = claude_md["state"] if claude_md.is_a?(Hash)
  @disabled = parse_disabled(data["disabled"])
  Array(data["files"]).each do |raw|
    next unless raw.is_a?(Hash)
    entry = build_entry(raw)
    @files[entry.path] = entry if entry.path
  end
  self
rescue Psych::SyntaxError
  self
end

#to_yamlObject



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/rails/hyperdrive/lock_file.rb', line 98

def to_yaml
  carried = @document["claude_md"]
  carried = {} unless carried.is_a?(Hash)

  document = @document.merge(
    "version"   => SCHEMA_VERSION,
    "claude_md" => carried.merge("state" => @claude_md_state),
    "disabled"  => DISABLED_KEYS.each_with_object({}) { |(type, key), h| h[key] = @disabled[type] },
    "files"     => @files.values.sort_by(&:path).map { |e| serialize_entry(e) }
  )
  # A nil state means no import line is being managed. Recording one anyway
  # would make the next run read the absent line as a deletion the user
  # made, and never add it back.
  document.delete("claude_md") if @claude_md_state.nil?
  document.to_yaml
end

#upsert(path:, kind:, source_gem:, source_version:, source_sha:, installed_at:) ⇒ Object



82
83
84
85
86
87
88
89
90
91
# File 'lib/rails/hyperdrive/lock_file.rb', line 82

def upsert(path:, kind:, source_gem:, source_version:, source_sha:, installed_at:)
  @files[path.to_s] = Entry.new(
    path: path.to_s,
    kind: kind.to_s,
    source_gem: source_gem.to_s,
    source_version: source_version.to_s,
    source_sha: source_sha.to_s,
    installed_at: installed_at.to_s
  )
end