Class: Ace::Git::Worktree::Models::WorktreeConfig

Inherits:
Object
  • Object
show all
Defined in:
lib/ace/git/worktree/models/worktree_config.rb

Overview

Configuration model for worktree settings

Represents the configuration loaded from .ace/git/worktree.yml with defaults, validation, and accessors for all configuration options.

Examples:

Create configuration with defaults

config = WorktreeConfig.new
config.root_path # => ".ace-wt"

Load from configuration hash

config = WorktreeConfig.new({
  "git" => {
    "worktree" => {
      "root_path" => "~/worktrees",
      "mise_trust_auto" => false
    }
  }
})

Constant Summary collapse

DEFAULT_CONFIG =

Default configuration values

{
  "root_path" => ".ace-wt",
  "auto_navigate" => true,
  "tmux" => false,
  "mise_trust_auto" => true,
  "task" => {
    "directory_format" => "t.{task_id}",
    "branch_format" => "{id}-{slug}",
    "auto_mark_in_progress" => true,
    "auto_commit_task" => true,
    "auto_push_task" => true,
    "push_remote" => "origin",
    "commit_message_format" => "chore({task_id}): mark as in-progress, creating worktree for {slug}",
    "add_worktree_metadata" => true,
    "auto_setup_upstream" => false,
    "auto_create_pr" => false,
    "pr_title_format" => "{id} - {slug}",
    "create_current_symlink" => true,
    "current_symlink_name" => "_current"
  },
  "pr" => {
    "directory_format" => "ace-pr-{number}",
    "branch_format" => "pr-{number}-{slug}",
    "remote_name" => "origin",
    "fetch_before_create" => true,
    "configure_push_for_mismatch" => true
  },
  "branch" => {
    "fetch_if_remote" => true,
    "auto_detect_remote" => true
  },
  "cleanup" => {
    "on_merge" => false,
    "on_delete" => true
  },
  "hooks" => {
    "after_create" => []
  }
}.freeze
CONFIG_NAMESPACE =

Configuration namespace paths

["git", "worktree"].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config_hash = {}, project_root = Dir.pwd) ⇒ WorktreeConfig

Initialize a new WorktreeConfig

Parameters:

  • config_hash (Hash) (defaults to: {})

    Configuration hash (typically from ace-core)

  • project_root (String) (defaults to: Dir.pwd)

    Project root directory for relative paths



78
79
80
81
82
83
84
# File 'lib/ace/git/worktree/models/worktree_config.rb', line 78

def initialize(config_hash = {}, project_root = Dir.pwd)
  @project_root = project_root
  @raw_config = extract_worktree_config(config_hash)
  @merged_config = merge_with_defaults(@raw_config)

  initialize_attributes
end

Instance Attribute Details

#auto_navigateObject (readonly)

Returns the value of attribute auto_navigate.



72
73
74
# File 'lib/ace/git/worktree/models/worktree_config.rb', line 72

def auto_navigate
  @auto_navigate
end

#branch_configObject (readonly)

Returns the value of attribute branch_config.



72
73
74
# File 'lib/ace/git/worktree/models/worktree_config.rb', line 72

def branch_config
  @branch_config
end

#cleanup_configObject (readonly)

Returns the value of attribute cleanup_config.



72
73
74
# File 'lib/ace/git/worktree/models/worktree_config.rb', line 72

def cleanup_config
  @cleanup_config
end

#hooks_configObject (readonly)

Returns the value of attribute hooks_config.



72
73
74
# File 'lib/ace/git/worktree/models/worktree_config.rb', line 72

def hooks_config
  @hooks_config
end

#mise_trust_autoObject (readonly)

Returns the value of attribute mise_trust_auto.



72
73
74
# File 'lib/ace/git/worktree/models/worktree_config.rb', line 72

def mise_trust_auto
  @mise_trust_auto
end

#pr_configObject (readonly)

Returns the value of attribute pr_config.



72
73
74
# File 'lib/ace/git/worktree/models/worktree_config.rb', line 72

def pr_config
  @pr_config
end

#root_pathObject (readonly)

Returns the value of attribute root_path.



72
73
74
# File 'lib/ace/git/worktree/models/worktree_config.rb', line 72

def root_path
  @root_path
end

#task_configObject (readonly)

Returns the value of attribute task_config.



72
73
74
# File 'lib/ace/git/worktree/models/worktree_config.rb', line 72

def task_config
  @task_config
end

#tmuxObject (readonly)

Returns the value of attribute tmux.



72
73
74
# File 'lib/ace/git/worktree/models/worktree_config.rb', line 72

def tmux
  @tmux
end

Instance Method Details

#absolute_root_pathString

Get the root path for worktrees (expanded and absolute)

Returns:

  • (String)

    Absolute path to worktree root directory



213
214
215
# File 'lib/ace/git/worktree/models/worktree_config.rb', line 213

def absolute_root_path
  @absolute_root_path ||= expand_root_path
end

#add_worktree_metadata?Boolean

Check if worktree metadata should be added to tasks

Returns:

  • (Boolean)

    true if metadata should be added



159
160
161
# File 'lib/ace/git/worktree/models/worktree_config.rb', line 159

def add_worktree_metadata?
  @task_config["add_worktree_metadata"]
end

#after_create_hooksArray<Hash>

Get after-create hooks configuration

Returns:

  • (Array<Hash>)

    Array of hook definitions



234
235
236
# File 'lib/ace/git/worktree/models/worktree_config.rb', line 234

def after_create_hooks
  @hooks_config["after_create"] || []
end

#auto_commit_task?Boolean

Check if task changes should be committed automatically

Returns:

  • (Boolean)

    true if task changes should be committed



131
132
133
# File 'lib/ace/git/worktree/models/worktree_config.rb', line 131

def auto_commit_task?
  @task_config["auto_commit_task"]
end

#auto_create_pr?Boolean

Check if draft PR should be created automatically

Returns:

  • (Boolean)

    true if auto PR creation is enabled



173
174
175
# File 'lib/ace/git/worktree/models/worktree_config.rb', line 173

def auto_create_pr?
  @task_config["auto_create_pr"]
end

#auto_mark_in_progress?Boolean

Check if tasks should be marked as in-progress automatically

Returns:

  • (Boolean)

    true if tasks should be marked in-progress



124
125
126
# File 'lib/ace/git/worktree/models/worktree_config.rb', line 124

def auto_mark_in_progress?
  @task_config["auto_mark_in_progress"]
end

#auto_navigate?Boolean

Check if auto-navigation should be performed

Returns:

  • (Boolean)

    true if auto-navigation should be performed



103
104
105
# File 'lib/ace/git/worktree/models/worktree_config.rb', line 103

def auto_navigate?
  @auto_navigate
end

#auto_push_task?Boolean

Check if task changes should be pushed automatically

Returns:

  • (Boolean)

    true if task changes should be pushed



138
139
140
# File 'lib/ace/git/worktree/models/worktree_config.rb', line 138

def auto_push_task?
  @task_config["auto_push_task"] != false
end

#auto_setup_upstream?Boolean

Check if new worktree branch should be pushed to remote with upstream tracking

Returns:

  • (Boolean)

    true if upstream setup is enabled



166
167
168
# File 'lib/ace/git/worktree/models/worktree_config.rb', line 166

def auto_setup_upstream?
  @task_config["auto_setup_upstream"]
end

#branch_formatString

Get the branch format for task-based worktrees

Returns:

  • (String)

    Branch format template



96
97
98
# File 'lib/ace/git/worktree/models/worktree_config.rb', line 96

def branch_format
  @task_config["branch_format"]
end

#cleanup_on_delete?Boolean

Check if worktrees should be cleaned up on branch delete

Returns:

  • (Boolean)

    true if cleanup on delete



227
228
229
# File 'lib/ace/git/worktree/models/worktree_config.rb', line 227

def cleanup_on_delete?
  @cleanup_config["on_delete"]
end

#cleanup_on_merge?Boolean

Check if worktrees should be cleaned up on branch merge

Returns:

  • (Boolean)

    true if cleanup on merge



220
221
222
# File 'lib/ace/git/worktree/models/worktree_config.rb', line 220

def cleanup_on_merge?
  @cleanup_config["on_merge"]
end

#commit_message_formatString

Get the commit message format for task updates

Returns:

  • (String)

    Commit message template



152
153
154
# File 'lib/ace/git/worktree/models/worktree_config.rb', line 152

def commit_message_format
  @task_config["commit_message_format"]
end

#configure_push_for_mismatch?Boolean

Check if push should be configured for PR branches with name mismatches

Returns:

  • (Boolean)

    true if push should be configured for mismatched branch names



241
242
243
# File 'lib/ace/git/worktree/models/worktree_config.rb', line 241

def configure_push_for_mismatch?
  @pr_config["configure_push_for_mismatch"]
end

#create_current_symlink?Boolean

Check if _current symlink should be created

Returns:

  • (Boolean)

    true if symlink should be created



187
188
189
# File 'lib/ace/git/worktree/models/worktree_config.rb', line 187

def create_current_symlink?
  @task_config["create_current_symlink"] != false
end

Get the name for the _current symlink

Returns:

  • (String)

    Symlink name (default: “_current”)



194
195
196
# File 'lib/ace/git/worktree/models/worktree_config.rb', line 194

def current_symlink_name
  @task_config["current_symlink_name"] || "_current"
end

#directory_formatString

Get the directory format for task-based worktrees

Returns:

  • (String)

    Directory format template



89
90
91
# File 'lib/ace/git/worktree/models/worktree_config.rb', line 89

def directory_format
  @task_config["directory_format"]
end

#format_branch(task_data) ⇒ String

Format a branch name using task data

Examples:

config.format_branch(task) # => "081-fix-authentication-bug"

Parameters:

  • task_data (Hash)

    Task data hash from ace-task

Returns:

  • (String)

    Formatted branch name



279
280
281
282
# File 'lib/ace/git/worktree/models/worktree_config.rb', line 279

def format_branch(task_data)
  template = branch_format
  apply_template_variables(template, task_data)
end

#format_commit_message(task_data) ⇒ String

Format a commit message for task updates

Examples:

config.format_commit_message(task) # => "chore(task-081): mark as in-progress, creating worktree"

Parameters:

  • task_data (Hash)

    Task data hash from ace-task

Returns:

  • (String)

    Formatted commit message



291
292
293
294
# File 'lib/ace/git/worktree/models/worktree_config.rb', line 291

def format_commit_message(task_data)
  template = commit_message_format
  apply_template_variables(template, task_data)
end

#format_directory(task_data, counter = nil) ⇒ String

Format a directory path using task data

Examples:

config.format_directory(task) # => "t.081"
config.format_directory(task, 2) # => "t.081-2"

Parameters:

  • task_data (Hash)

    Task data hash from ace-task

  • counter (Integer, nil) (defaults to: nil)

    Counter for multiple worktrees of same task

Returns:

  • (String)

    Formatted directory path



262
263
264
265
266
267
268
269
270
# File 'lib/ace/git/worktree/models/worktree_config.rb', line 262

def format_directory(task_data, counter = nil)
  template = directory_format
  formatted = apply_template_variables(template, task_data)

  # Add counter if provided
  formatted = "#{formatted}-#{counter}" if counter

  formatted
end

#format_pr_title(task_data) ⇒ String

Format a PR title using task data

Examples:

config.format_pr_title(task) # => "081 - fix-authentication-bug"

Parameters:

  • task_data (Hash)

    Task data hash from ace-task

Returns:

  • (String)

    Formatted PR title



205
206
207
208
# File 'lib/ace/git/worktree/models/worktree_config.rb', line 205

def format_pr_title(task_data)
  template = pr_title_format
  apply_template_variables(template, task_data)
end

#hooks_enabled?Boolean

Check if hooks are configured

Returns:

  • (Boolean)

    true if any hooks are configured



248
249
250
251
# File 'lib/ace/git/worktree/models/worktree_config.rb', line 248

def hooks_enabled?
  hooks = after_create_hooks
  hooks.is_a?(Array) && hooks.any?
end

#mise_trust_auto?Boolean

Check if mise should automatically trust worktree directories

Returns:

  • (Boolean)

    true if mise auto-trust is enabled



117
118
119
# File 'lib/ace/git/worktree/models/worktree_config.rb', line 117

def mise_trust_auto?
  @mise_trust_auto
end

#pr_title_formatString

Get the PR title format template

Returns:

  • (String)

    PR title format template



180
181
182
# File 'lib/ace/git/worktree/models/worktree_config.rb', line 180

def pr_title_format
  @task_config["pr_title_format"]
end

#push_remoteString

Get the remote for pushing task changes

Returns:

  • (String)

    Remote name (default: “origin”)



145
146
147
# File 'lib/ace/git/worktree/models/worktree_config.rb', line 145

def push_remote
  @task_config["push_remote"] || "origin"
end

#tmux?Boolean

Check if tmux session should be launched after worktree creation

Returns:

  • (Boolean)

    true if tmux launch is enabled



110
111
112
# File 'lib/ace/git/worktree/models/worktree_config.rb', line 110

def tmux?
  @tmux
end

#to_hHash

Get configuration as a hash

Returns:

  • (Hash)

    Configuration hash



367
368
369
370
371
372
373
374
375
376
# File 'lib/ace/git/worktree/models/worktree_config.rb', line 367

def to_h
  {
    root_path: root_path,
    auto_navigate: auto_navigate?,
    mise_trust_auto: mise_trust_auto?,
    task: @task_config.dup,
    cleanup: @cleanup_config.dup,
    hooks: @hooks_config.dup
  }
end

#validateArray<String>

Validate configuration settings

Returns:

  • (Array<String>)

    Array of validation error messages (empty if valid)



299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
# File 'lib/ace/git/worktree/models/worktree_config.rb', line 299

def validate
  errors = []

  # Validate root_path
  unless root_path.is_a?(String) && !root_path.empty?
    errors << "root_path must be a non-empty string"
  end

  # Validate task template formats
  unless directory_format.is_a?(String) && !directory_format.empty?
    errors << "task.directory_format must be a non-empty string"
  end

  unless branch_format.is_a?(String) && !branch_format.empty?
    errors << "task.branch_format must be a non-empty string"
  end

  # Validate PR template formats
  pr_dir_format = @pr_config["directory_format"]
  unless pr_dir_format.is_a?(String) && !pr_dir_format.empty?
    errors << "pr.directory_format must be a non-empty string"
  end

  pr_branch_format = @pr_config["branch_format"]
  unless pr_branch_format.is_a?(String) && !pr_branch_format.empty?
    errors << "pr.branch_format must be a non-empty string"
  end

  # Validate template variables for task configuration
  task_templates = {
    "task.directory_format" => {template: directory_format, valid_vars: %w[task_id id slug]},
    "task.branch_format" => {template: branch_format, valid_vars: %w[id slug task_id]},
    "task.commit_message_format" => {template: commit_message_format, valid_vars: %w[task_id slug id]}
  }

  task_templates.each do |name, config|
    invalid_vars = find_invalid_template_variables(config[:template], config[:valid_vars])
    if invalid_vars.any?
      errors << "#{name} contains invalid variables: #{invalid_vars.join(", ")}. Valid variables: #{config[:valid_vars].map { |v| "{#{v}}" }.join(", ")}"
    end

    # Warn if template has no variables (except for commit_message_format which is optional)
    unless name == "task.commit_message_format"
      if config[:template] && !config[:template].match?(/\{[^}]+\}/)
        errors << "#{name} should include at least one template variable from: #{config[:valid_vars].map { |v| "{#{v}}" }.join(", ")}"
      end
    end
  end

  # Validate template variables for PR configuration
  pr_templates = {
    "pr.directory_format" => {template: pr_dir_format, valid_vars: %w[number slug title base_branch]},
    "pr.branch_format" => {template: pr_branch_format, valid_vars: %w[number slug title base_branch]}
  }

  pr_templates.each do |name, config|
    invalid_vars = find_invalid_template_variables(config[:template], config[:valid_vars])
    if invalid_vars.any?
      errors << "#{name} contains invalid variables: #{invalid_vars.join(", ")}. Valid variables: #{config[:valid_vars].map { |v| "{#{v}}" }.join(", ")}"
    end
  end

  errors
end