Class: Textus::Store::Sentinel
- Inherits:
-
Object
- Object
- Textus::Store::Sentinel
- Defined in:
- lib/textus/store/sentinel.rb
Overview
Value object for sentinel files written by Infra::Publisher and inspected by Doctor::Check::Sentinels. Owns the JSON shape (target, sha256, mode) and the on-disk path layout (<store_root>/sentinels/ <target-rel-to-repo>.textus-managed.json). Target/source are repo-relative when the published file is under the repo root, absolute otherwise.
Constant Summary collapse
- SUFFIX =
".textus-managed.json".freeze
- DIR =
"sentinels".freeze
Instance Attribute Summary collapse
-
#mode ⇒ Object
readonly
Returns the value of attribute mode.
-
#sha256 ⇒ Object
readonly
Returns the value of attribute sha256.
-
#source ⇒ Object
readonly
Returns the value of attribute source.
-
#target ⇒ Object
readonly
Returns the value of attribute target.
Class Method Summary collapse
- .absolutize(path, repo_root) ⇒ Object
- .load(path, repo_root) ⇒ Object
- .rel_or_abs(path, repo_root) ⇒ Object
- .relative_to(path, repo_root) ⇒ Object
- .sentinel_path(target, store_root) ⇒ Object
- .write!(target:, source:, store_root:) ⇒ Object
Instance Method Summary collapse
- #drift? ⇒ Boolean
-
#initialize(target:, source:, sha256:, mode:) ⇒ Sentinel
constructor
A new instance of Sentinel.
- #orphan? ⇒ Boolean
Constructor Details
#initialize(target:, source:, sha256:, mode:) ⇒ Sentinel
Returns a new instance of Sentinel.
67 68 69 70 71 72 |
# File 'lib/textus/store/sentinel.rb', line 67 def initialize(target:, source:, sha256:, mode:) @target = target @source = source @sha256 = sha256 @mode = mode end |
Instance Attribute Details
#mode ⇒ Object (readonly)
Returns the value of attribute mode.
16 17 18 |
# File 'lib/textus/store/sentinel.rb', line 16 def mode @mode end |
#sha256 ⇒ Object (readonly)
Returns the value of attribute sha256.
16 17 18 |
# File 'lib/textus/store/sentinel.rb', line 16 def sha256 @sha256 end |
#source ⇒ Object (readonly)
Returns the value of attribute source.
16 17 18 |
# File 'lib/textus/store/sentinel.rb', line 16 def source @source end |
#target ⇒ Object (readonly)
Returns the value of attribute target.
16 17 18 |
# File 'lib/textus/store/sentinel.rb', line 16 def target @target end |
Class Method Details
.absolutize(path, repo_root) ⇒ Object
60 61 62 63 64 65 |
# File 'lib/textus/store/sentinel.rb', line 60 def self.absolutize(path, repo_root) return path if path.nil? return path if File.absolute_path?(path) File.(path, repo_root) end |
.load(path, repo_root) ⇒ Object
30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/textus/store/sentinel.rb', line 30 def self.load(path, repo_root) raw = JSON.parse(File.read(path)) new( target: absolutize(raw["target"], repo_root), source: absolutize(raw["source"], repo_root), sha256: raw["sha256"], mode: raw["mode"], ) rescue JSON::ParserError, Errno::ENOENT nil end |
.rel_or_abs(path, repo_root) ⇒ Object
48 49 50 |
# File 'lib/textus/store/sentinel.rb', line 48 def self.rel_or_abs(path, repo_root) relative_to(path, repo_root) || File.(path) end |
.relative_to(path, repo_root) ⇒ Object
52 53 54 55 56 57 58 |
# File 'lib/textus/store/sentinel.rb', line 52 def self.relative_to(path, repo_root) path = File.(path) base = File.(repo_root) return nil unless path.start_with?(base + File::SEPARATOR) path[(base.length + 1)..] end |
.sentinel_path(target, store_root) ⇒ Object
42 43 44 45 46 |
# File 'lib/textus/store/sentinel.rb', line 42 def self.sentinel_path(target, store_root) repo_root = File.dirname(store_root) rel = relative_to(target, repo_root) || File.basename(target) File.join(store_root, DIR, rel + SUFFIX) end |
.write!(target:, source:, store_root:) ⇒ Object
18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/textus/store/sentinel.rb', line 18 def self.write!(target:, source:, store_root:) path = sentinel_path(target, store_root) FileUtils.mkdir_p(File.dirname(path)) repo_root = File.dirname(store_root) File.write(path, JSON.generate( "source" => rel_or_abs(source, repo_root), "target" => rel_or_abs(target, repo_root), "sha256" => Digest::SHA256.hexdigest(File.binread(target)), "mode" => "copy", )) end |
Instance Method Details
#drift? ⇒ Boolean
78 79 80 81 82 83 |
# File 'lib/textus/store/sentinel.rb', line 78 def drift? return false if orphan? return false if @sha256.nil? Digest::SHA256.hexdigest(File.binread(@target)) != @sha256 end |
#orphan? ⇒ Boolean
74 75 76 |
# File 'lib/textus/store/sentinel.rb', line 74 def orphan? @target.nil? || !File.exist?(@target) end |