Class: Terret::Home
- Inherits:
-
Object
- Object
- Terret::Home
- Defined in:
- lib/terret/home.rb
Overview
Terret home: where profiles live (docs/composition.md §3).
~/.terret/
├── patch.yml # applies to every profile
└── profiles/<name>/{profile.yml,patch.yml}
TERRET_HOME overrides ~/.terret wholesale, which is what makes the layer stack testable — every composition test points it at a tmpdir — and what lets a deployment ship a home directory as an artifact rather than as instructions for populating a user's dotfiles.
A home that does not hold the named profile falls back to the templates
this gem ships (gems/terret/profiles), so trt boot --profile headless
works on a machine whose home is empty. The home always wins where it has
an opinion; the shipped templates are only the floor.
Constant Summary collapse
- DEFAULT =
"~/.terret"- SHIPPED =
File.("../../profiles", __dir__)
Instance Attribute Summary collapse
-
#path ⇒ Object
readonly
Returns the value of attribute path.
Class Method Summary collapse
-
.resolve(path = nil) ⇒ Object
ENV is read here rather than at load time so a test can set TERRET_HOME after this file is required.
Instance Method Summary collapse
-
#initialize(path) ⇒ Home
constructor
A new instance of Home.
-
#label(file) ⇒ Object
dump-config prints these, so they are home-relative rather than absolute: a command whose whole purpose is "show me my config" should be safe to paste into an issue, and an absolute path names the operator.
- #patch ⇒ Object
- #profile_config(name) ⇒ Object
- #profile_dir(name) ⇒ Object
-
#profile_files(name) ⇒ Object
The pair of files a profile resolves to, home first and the shipped template as the floor.
-
#profile_names ⇒ Object
Profile names offered by this home and by the shipped templates.
- #profile_patch(name) ⇒ Object
- #shipped_profile_config(name) ⇒ Object
- #shipped_profile_dir(name) ⇒ Object
- #shipped_profile_patch(name) ⇒ Object
- #to_s ⇒ Object
Constructor Details
#initialize(path) ⇒ Home
Returns a new instance of Home.
35 36 37 |
# File 'lib/terret/home.rb', line 35 def initialize(path) @path = File.(path.to_s) end |
Instance Attribute Details
#path ⇒ Object (readonly)
Returns the value of attribute path.
33 34 35 |
# File 'lib/terret/home.rb', line 33 def path @path end |
Class Method Details
.resolve(path = nil) ⇒ Object
ENV is read here rather than at load time so a test can set TERRET_HOME after this file is required.
25 26 27 28 29 30 31 |
# File 'lib/terret/home.rb', line 25 def self.resolve(path = nil) return path if path.is_a?(Home) env = ENV["TERRET_HOME"] env = nil if env.nil? || env.empty? new(path || env || DEFAULT) end |
Instance Method Details
#label(file) ⇒ Object
dump-config prints these, so they are home-relative rather than absolute: a command whose whole purpose is "show me my config" should be safe to paste into an issue, and an absolute path names the operator.
75 76 77 78 79 80 81 |
# File 'lib/terret/home.rb', line 75 def label(file) f = file.to_s return f.delete_prefix("#{path}/") if f.start_with?("#{path}/") return "terret:#{f.delete_prefix("#{SHIPPED}/")}" if f.start_with?("#{SHIPPED}/") f end |
#patch ⇒ Object
39 |
# File 'lib/terret/home.rb', line 39 def patch = File.join(path, "patch.yml") |
#profile_config(name) ⇒ Object
41 |
# File 'lib/terret/home.rb', line 41 def profile_config(name) = File.join(profile_dir(name), "profile.yml") |
#profile_dir(name) ⇒ Object
40 |
# File 'lib/terret/home.rb', line 40 def profile_dir(name) = File.join(path, "profiles", name.to_s) |
#profile_files(name) ⇒ Object
The pair of files a profile resolves to, home first and the shipped template as the floor. Either may be nil; a profile with neither does not exist.
The two files are found independently on purpose. A home holding only a patch.yml is an operator who edited the one file the template told them to edit, and tying the patch's fate to a sibling profile.yml would drop it in silence — including when what it drops is a tightening of policy.
56 57 58 59 60 61 62 |
# File 'lib/terret/home.rb', line 56 def profile_files(name) config = [profile_config(name), shipped_profile_config(name)].find { |f| File.file?(f) } shipped = config && config == shipped_profile_config(name) patch = [profile_patch(name), (shipped_profile_patch(name) if shipped)] .compact.find { |f| File.file?(f) } [config, patch] end |
#profile_names ⇒ Object
Profile names offered by this home and by the shipped templates.
65 66 67 68 69 70 |
# File 'lib/terret/home.rb', line 65 def profile_names [File.join(path, "profiles"), SHIPPED] .flat_map { |d| Dir.glob(File.join(d, "*", "profile.yml")) } .map { |f| File.basename(File.dirname(f)) } .uniq.sort end |
#profile_patch(name) ⇒ Object
42 |
# File 'lib/terret/home.rb', line 42 def profile_patch(name) = File.join(profile_dir(name), "patch.yml") |
#shipped_profile_config(name) ⇒ Object
45 |
# File 'lib/terret/home.rb', line 45 def shipped_profile_config(name) = File.join(shipped_profile_dir(name), "profile.yml") |
#shipped_profile_dir(name) ⇒ Object
44 |
# File 'lib/terret/home.rb', line 44 def shipped_profile_dir(name) = File.join(SHIPPED, name.to_s) |
#shipped_profile_patch(name) ⇒ Object
46 |
# File 'lib/terret/home.rb', line 46 def shipped_profile_patch(name) = File.join(shipped_profile_dir(name), "patch.yml") |
#to_s ⇒ Object
83 |
# File 'lib/terret/home.rb', line 83 def to_s = path |