Module: RailsAiContext::Install::SelectionRecord
- Defined in:
- lib/rails_ai_context/install/selection_record.rb
Overview
Which AI tools the user picked, written and read the same way whichever entry point ran. Two records exist because they answer to two owners: the YAML file is the installer's own, and the initializer line is Rails config a user hand-edits. The initializer therefore wins on read.
Reading is a textual parse, never an eval or a boot, so the standalone CLI can answer the question with no Rails in the process.
Constant Summary collapse
- YAML_FILE =
".rails-ai-context.yml"- INITIALIZER =
"config/initializers/rails_ai_context.rb"- YAML_KEY =
"ai_tools"- PERMITTED_YAML =
Dates and times because a hand-added
generated_at:is ordinary in a config file, and refusing to load one used to cost the user the write. [ Symbol, Date, Time ].freeze
- SELECTION_LINE =
Matches the line the installer writes, and nothing else. Anchored past any leading whitespace but not past a
#, so the commented-out default in the generated initializer is not mistaken for a selection. /^[ \t]*config\.ai_tools\s*=\s*%i\[([^\]]*)\]/- ANY_ASSIGNMENT =
Any assignment to the key, in any shape. A hand-written
config.ai_tools = [:claude]is not one this module rewrites, but inserting beside it would leave two assignments: the stale one wins at boot whilereadreturns the fresh one. /^[ \t]*config\.ai_tools\s*=/- CONFIGURE_BLOCK =
Where a selection line goes when the initializer has none yet.
/RailsAiContext\.configure do \|config\|\n/
Class Method Summary collapse
-
.add(tool, root:) ⇒ Object
Adds one tool to whatever is already recorded, for the per-tool context tasks.
- .initializer_line(tools) ⇒ Object
-
.messages(result) ⇒ Array<Array(Symbol, String)>
What a caller should tell the user about a write, as [level, text] pairs.
-
.read(root:) ⇒ Array<Symbol>?
The recorded tools, or nil if none.
-
.write(tools, root:, extra_yaml: {}, initializer: true) ⇒ Hash
Records the selection in both places and says what it did, because every entry prints its own "Created / Updated / unchanged" line and would otherwise keep its own copy of the writing just to know which.
Class Method Details
.add(tool, root:) ⇒ Object
Adds one tool to whatever is already recorded, for the per-tool context tasks. Reads first so the addition lands in both files together rather than only in whichever one the caller happened to know about.
80 81 82 83 84 85 86 87 88 89 |
# File 'lib/rails_ai_context/install/selection_record.rb', line 80 def add(tool, root:) addition = normalize([ tool ]) # `json` is a real context format and a real rake task but not an AI # tool. Recording the empty union would put `config.ai_tools = %i[]` # into the user's initializer and, worse, make the record look set, # so the first-run prompt never fires again. return { tools: [], yaml: :skipped, initializer: :skipped } if addition.empty? write((read(root: root) || []) | addition, root: root) end |
.initializer_line(tools) ⇒ Object
91 92 93 |
# File 'lib/rails_ai_context/install/selection_record.rb', line 91 def initializer_line(tools) " config.ai_tools = %i[#{normalize(tools).join(' ')}]" end |
.messages(result) ⇒ Array<Array(Symbol, String)>
What a caller should tell the user about a write, as [level, text]
pairs. The entries differ in voice - Thor say with a colour, puts
with an emoji, $stderr.puts - not in what there is to say, and
keeping that judgement here means a new outcome lands in one place
rather than three.
72 73 74 |
# File 'lib/rails_ai_context/install/selection_record.rb', line 72 def (result) [ (result[:yaml]), (result[:initializer]) ].compact end |
.read(root:) ⇒ Array<Symbol>?
Returns the recorded tools, or nil if none.
42 43 44 |
# File 'lib/rails_ai_context/install/selection_record.rb', line 42 def read(root:) from_initializer(root) || from_yaml(root) end |
.write(tools, root:, extra_yaml: {}, initializer: true) ⇒ Hash
Records the selection in both places and says what it did, because every entry prints its own "Created / Updated / unchanged" line and would otherwise keep its own copy of the writing just to know which.
55 56 57 58 59 60 61 62 63 |
# File 'lib/rails_ai_context/install/selection_record.rb', line 55 def write(tools, root:, extra_yaml: {}, initializer: true) tools = normalize(tools) { tools: tools, yaml: write_yaml(tools, root, extra_yaml), initializer: initializer ? write_initializer(tools, root) : :skipped } end |