Class: Coat::Collector
- Inherits:
-
Object
- Object
- Coat::Collector
- Defined in:
- lib/coat/collector.rb
Overview
Turns work into patches. Provenance is recorded at the moment the scrap is made - what ran, where, how it exited, and what it touched - because none of that can be reconstructed honestly after the fact.
Defined Under Namespace
Classes: NoSuchFile
Constant Summary collapse
- COMMAND_NOT_RUN =
127
Instance Method Summary collapse
-
#add_captured(body:, label:, agent:, cmd: nil, exit_code: nil, cwd: Dir.pwd, claims: nil) ⇒ Object
Output some other harness already produced.
- #add_command(cmd:, label:, agent:, cwd: Dir.pwd, claims: nil) ⇒ Object
- #add_file(path:, label:, agent:, claims: nil) ⇒ Object
-
#initialize(ledger, patches_dir) ⇒ Collector
constructor
A new instance of Collector.
-
#pin(key, cwd: Dir.pwd) ⇒ Object
Marks where the working tree stands, so a patch added later can be asked what moved in between.
-
#since(key, cwd: Dir.pwd) ⇒ Object
What changed since that pin, and then the pin is spent - it described one boundary and that boundary has now been crossed.
Constructor Details
#initialize(ledger, patches_dir) ⇒ Collector
Returns a new instance of Collector.
19 20 21 22 23 24 |
# File 'lib/coat/collector.rb', line 19 def initialize(ledger, patches_dir) @ledger = ledger @patches_dir = patches_dir @state_dir = File.basename(File.dirname(patches_dir)) @pins_dir = File.join(File.dirname(patches_dir), "pins") end |
Instance Method Details
#add_captured(body:, label:, agent:, cmd: nil, exit_code: nil, cwd: Dir.pwd, claims: nil) ⇒ Object
Output some other harness already produced. coat did not run this, so it knows only what it was handed - which is still capture rather than guess, as long as whoever handed it over was there when it ran. Recorded as its own kind so the ledger never claims coat watched it happen.
Nothing is claimed by default: the body arrived as text, so there is no honest way to know what it touched. Pass claims, or pin first.
55 56 57 58 59 60 |
# File 'lib/coat/collector.rb', line 55 def add_captured(body:, label:, agent:, cmd: nil, exit_code: nil, cwd: Dir.pwd, claims: nil) record( origin: origin(label, agent, "captured").merge("cmd" => cmd, "cwd" => cwd, "exit" => exit_code), body: store(label, body), started: Time.now, claims: claims || [] ) end |
#add_command(cmd:, label:, agent:, cwd: Dir.pwd, claims: nil) ⇒ Object
26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/coat/collector.rb', line 26 def add_command(cmd:, label:, agent:, cwd: Dir.pwd, claims: nil) before = working_tree(cwd) started = Time.now output, code = run(cmd, cwd) record( origin: origin(label, agent, "command").merge("cmd" => cmd, "cwd" => cwd, "exit" => code), body: store(label, output), started: started, claims: claims || touched(before, working_tree(cwd)) ) end |
#add_file(path:, label:, agent:, claims: nil) ⇒ Object
38 39 40 41 42 43 44 45 46 |
# File 'lib/coat/collector.rb', line 38 def add_file(path:, label:, agent:, claims: nil) raise NoSuchFile, "no such file: #{path}" unless File.file?(path) record( origin: origin(label, agent, "file").merge("cwd" => File.dirname(File.(path))), body: store(label, File.read(path)), started: Time.now, claims: claims || [relative(path)] ) end |
#pin(key, cwd: Dir.pwd) ⇒ Object
Marks where the working tree stands, so a patch added later can be asked what moved in between. This is how ambient capture keeps honest claims: something has to look before the work, and after the fact is too late.
65 66 67 68 69 70 71 72 |
# File 'lib/coat/collector.rb', line 65 def pin(key, cwd: Dir.pwd) tree = working_tree(cwd) or return nil path = pin_path(key) FileUtils.mkdir_p(@pins_dir) File.write(path, JSON.generate(tree)) path end |
#since(key, cwd: Dir.pwd) ⇒ Object
What changed since that pin, and then the pin is spent - it described one boundary and that boundary has now been crossed.
ponytail: a pin nobody comes back for is left behind in .coat/pins. Sweep them if a long-lived checkout ever collects enough to notice.
79 80 81 82 83 84 85 86 |
# File 'lib/coat/collector.rb', line 79 def since(key, cwd: Dir.pwd) path = pin_path(key) return nil unless File.file?(path) before = JSON.parse(File.read(path)) File.delete(path) touched(before, working_tree(cwd)) end |