Module: Ace::Assign::Atoms::PresetStepResolver

Defined in:
lib/ace/assign/atoms/preset_step_resolver.rb

Overview

Resolves preset step definitions by exact or base-name matching.

Constant Summary collapse

ITERATION_SUFFIX_REGEX =
/-\d+\z/.freeze

Class Method Summary collapse

Class Method Details

.base_name(name) ⇒ Object



37
38
39
# File 'lib/ace/assign/atoms/preset_step_resolver.rb', line 37

def self.base_name(name)
  name.to_s.sub(ITERATION_SUFFIX_REGEX, "")
end

.find_step(preset, name) ⇒ Object

Raises:

  • (Ace::Support::Cli::Error)


14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/ace/assign/atoms/preset_step_resolver.rb', line 14

def self.find_step(preset, name)
  requested = name.to_s.strip
  raise Ace::Support::Cli::Error, "Step name cannot be empty" if requested.empty?

  steps = Array(preset["steps"])
  if steps.empty?
    raise Ace::Support::Cli::Error,
      "Preset '#{preset['name'] || 'unknown'}' has no steps defined. Add a non-empty 'steps' array."
  end

  exact = steps.find { |step| step_name(step) == requested }
  return exact if exact

  base = base_name(requested)
  matched = steps.find { |step| base_name(step_name(step)) == base }
  return matched if matched

  available = available_names(steps)
  raise Ace::Support::Cli::Error,
    "Step '#{requested}' not found in preset '#{preset['name'] || 'unknown'}'. " \
    "Available: #{available.join(', ')}"
end

.find_steps(preset, names) ⇒ Object



10
11
12
# File 'lib/ace/assign/atoms/preset_step_resolver.rb', line 10

def self.find_steps(preset, names)
  Array(names).map { |name| find_step(preset, name) }
end

.iteration_name?(name) ⇒ Boolean

Returns:

  • (Boolean)


41
42
43
# File 'lib/ace/assign/atoms/preset_step_resolver.rb', line 41

def self.iteration_name?(name)
  name.to_s.match?(ITERATION_SUFFIX_REGEX)
end

.next_iteration_name(base, existing_names) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
# File 'lib/ace/assign/atoms/preset_step_resolver.rb', line 45

def self.next_iteration_name(base, existing_names)
  stem = base_name(base)
  existing = Array(existing_names).map(&:to_s)
  numbers = existing.filter_map do |name|
    match = name.match(/\A#{Regexp.escape(stem)}-(\d+)\z/)
    match && match[1].to_i
  end

  next_number = numbers.empty? ? 1 : numbers.max + 1
  "#{stem}-#{next_number}"
end