Class: Do::Config
- Inherits:
-
Object
- Object
- Do::Config
- Defined in:
- lib/do/config.rb
Overview
Loads and represents the declarative TOML configuration.
The TOML file is the source of truth. Everything else do produces is a
derived artifact. This class only parses the file; validation is performed
by Validator.
Constant Summary collapse
- KNOWN_TASK_FIELDS =
%w[ command schedule time day working_directory environment enabled ].freeze
Instance Attribute Summary collapse
-
#path ⇒ Object
Returns the value of attribute path.
-
#raw ⇒ Object
readonly
Returns the value of attribute raw.
-
#tasks ⇒ Object
readonly
Returns the value of attribute tasks.
Class Method Summary collapse
-
.default_path ⇒ Object
Default location when no path is given.
- .load(path = default_path) ⇒ Object
-
.parse(raw_text, source: 'config.toml') ⇒ Array<String>
Validation errors found while parsing.
Instance Method Summary collapse
- #[](key) ⇒ Object
-
#initialize(raw, source: nil) ⇒ Config
constructor
A new instance of Config.
-
#remove_task(task_name) ⇒ Object
Remove a task's table from the file.
-
#set_task_field(task_name, field, toml_value) ⇒ Object
Edit a scalar field inside a task's table without re-serializing the whole file (preserving user comments/formatting elsewhere).
- #task(name) ⇒ Object
Constructor Details
#initialize(raw, source: nil) ⇒ Config
Returns a new instance of Config.
45 46 47 48 49 |
# File 'lib/do/config.rb', line 45 def initialize(raw, source: nil) @raw = raw || {} @source = source @tasks = build_tasks(@raw['tasks']) end |
Instance Attribute Details
#path ⇒ Object
Returns the value of attribute path.
43 44 45 |
# File 'lib/do/config.rb', line 43 def path @path end |
#raw ⇒ Object (readonly)
Returns the value of attribute raw.
42 43 44 |
# File 'lib/do/config.rb', line 42 def raw @raw end |
#tasks ⇒ Object (readonly)
Returns the value of attribute tasks.
42 43 44 |
# File 'lib/do/config.rb', line 42 def tasks @tasks end |
Class Method Details
.default_path ⇒ Object
Default location when no path is given.
17 18 19 20 21 |
# File 'lib/do/config.rb', line 17 def self.default_path dir = ENV.fetch('XDG_CONFIG_HOME', nil) dir = File.join(Dir.home, '.config') if dir.nil? || dir.empty? File.join(dir, 'do', 'config.toml') end |
.load(path = default_path) ⇒ Object
33 34 35 36 37 38 39 40 |
# File 'lib/do/config.rb', line 33 def self.load(path = default_path) raise Error, "Configuration file does not exist: #{path}" unless File.exist?(path) raw = File.read(path) config = parse(raw, source: path) config.path = path config end |
.parse(raw_text, source: 'config.toml') ⇒ Array<String>
Returns validation errors found while parsing.
24 25 26 27 28 29 30 31 |
# File 'lib/do/config.rb', line 24 def self.parse(raw_text, source: 'config.toml') parsed = TomlRB.parse(raw_text) new(parsed, source: source) rescue TomlRB::ParseError, Psych::SyntaxError => e raise ValidationError, ["Malformed TOML in #{source}: #{e.}"] rescue StandardError => e raise ValidationError, ["Failed to parse #{source}: #{e.}"] end |
Instance Method Details
#[](key) ⇒ Object
55 56 57 |
# File 'lib/do/config.rb', line 55 def [](key) @raw[key] end |
#remove_task(task_name) ⇒ Object
Remove a task's table from the file. Used by do remove. Also removes
any nested tables under the same task (e.g. [tasks.name.environment]).
80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/do/config.rb', line 80 def remove_task(task_name) text = File.read(@path) idx = block_start_index(text, task_name) raise Error, "task '#{task_name}' not present in configuration" if idx.nil? lines = text.lines block_end = task_block_end(lines, idx, task_name) removed = lines[0...idx] + lines[block_end..] # Collapse leftover blank lines around the removed block (best effort). File.write(@path, removed.join.gsub(/\n{3,}/, "\n\n")) end |
#set_task_field(task_name, field, toml_value) ⇒ Object
Edit a scalar field inside a task's table without re-serializing the
whole file (preserving user comments/formatting elsewhere). Used by
enable/disable.
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/do/config.rb', line 62 def set_task_field(task_name, field, toml_value) text = File.read(@path) idx = block_start_index(text, task_name) return edit_field_anywhere(text, task_name, field, toml_value) if idx.nil? lines = text.lines block_end = block_end_index(lines, idx) match = (idx...block_end).find { |i| lines[i] =~ /\A#{Regexp.escape(field)}\s*=/ } if match lines[match] = "#{field} = #{toml_value}\n" else lines.insert(idx + 1, "#{field} = #{toml_value}\n") end File.write(@path, lines.join) end |
#task(name) ⇒ Object
51 52 53 |
# File 'lib/do/config.rb', line 51 def task(name) @tasks.find { |t| t.name == name } end |