Class: Roast::CLI

Inherits:
Thor
  • Object
show all
Defined in:
lib/roast.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.exit_on_failure?Boolean

Returns:

  • (Boolean)


349
350
351
# File 'lib/roast.rb', line 349

def exit_on_failure?
  true
end

Instance Method Details

#diagram(workflow_file) ⇒ Object



256
257
258
259
260
261
262
263
264
265
266
267
268
# File 'lib/roast.rb', line 256

def diagram(workflow_file)
  unless File.exist?(workflow_file)
    raise Thor::Error, "Workflow file not found: #{workflow_file}"
  end

  workflow = Workflow::Configuration.new(workflow_file)
  generator = WorkflowDiagramGenerator.new(workflow, workflow_file)
  output_path = generator.generate(options[:output])

  puts ::CLI::UI.fmt("{{success:✓}} Diagram generated: #{output_path}")
rescue StandardError => e
  raise Thor::Error, "Error generating diagram: #{e.message}"
end

#execute(*paths) ⇒ Object

Raises:

  • (Thor::Error)


58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/roast.rb', line 58

def execute(*paths)
  raise Thor::Error, "Workflow configuration file is required" if paths.empty?

  workflow_path, *files = paths

  expanded_workflow_path = if workflow_path.include?("workflow.yml")
    File.expand_path(workflow_path)
  else
    File.expand_path("roast/#{workflow_path}/workflow.yml")
  end

  raise Thor::Error, "Expected a Roast workflow configuration file, got directory: #{expanded_workflow_path}" if File.directory?(expanded_workflow_path)

  Roast::Workflow::ConfigurationParser.new(expanded_workflow_path, files, options.transform_keys(&:to_sym)).begin!
end

#initObject



119
120
121
122
123
124
125
# File 'lib/roast.rb', line 119

def init
  if options[:example]
    copy_example(options[:example])
  else
    show_example_picker
  end
end

#listObject



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/roast.rb', line 128

def list
  roast_dir = File.join(Dir.pwd, "roast")

  unless File.directory?(roast_dir)
    raise Thor::Error, "No roast/ directory found in current path"
  end

  workflow_files = Dir.glob(File.join(roast_dir, "**/workflow.yml")).sort

  if workflow_files.empty?
    raise Thor::Error, "No workflow.yml files found in roast/ directory"
  end

  puts "Available workflows:"
  puts

  workflow_files.each do |file|
    workflow_name = File.dirname(file.sub("#{roast_dir}/", ""))
    puts "  #{workflow_name} (from project)"
  end

  puts
  puts "Run a workflow with: roast execute <workflow_name>"
end

#resume(workflow_path) ⇒ Object



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/roast.rb', line 78

def resume(workflow_path)
  expanded_workflow_path = if workflow_path.include?("workflow.yml")
    File.expand_path(workflow_path)
  else
    File.expand_path("roast/#{workflow_path}/workflow.yml")
  end

  unless File.exist?(expanded_workflow_path)
    raise Thor::Error, "Workflow file not found: #{expanded_workflow_path}"
  end

  # Store the event in the session
  repository = Workflow::StateRepositoryFactory.create

  unless repository.respond_to?(:add_event)
    raise Thor::Error, "Event resumption requires SQLite storage. Set ROAST_STATE_STORAGE=sqlite"
  end

  # Parse event data if provided
  event_data = options[:event_data] ? JSON.parse(options[:event_data]) : nil

  # Add the event to the session
  session_id = options[:session_id]
  repository.add_event(expanded_workflow_path, session_id, options[:event], event_data)

  # Resume workflow execution from the wait state
  resume_options = options.transform_keys(&:to_sym).merge(
    resume_from_event: options[:event],
    session_id: session_id,
  )

  Roast::Workflow::ConfigurationParser.new(expanded_workflow_path, [], resume_options).begin!
end

#session(session_id) ⇒ Object



206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
# File 'lib/roast.rb', line 206

def session(session_id)
  repository = Workflow::StateRepositoryFactory.create

  unless repository.respond_to?(:get_session_details)
    raise Thor::Error, "Session details are only available with SQLite storage. Set ROAST_STATE_STORAGE=sqlite"
  end

  details = repository.get_session_details(session_id)

  unless details
    raise Thor::Error, "Session not found: #{session_id}"
  end

  session = details[:session]
  states = details[:states]
  events = details[:events]

  puts "Session: #{session[0]}"
  puts "Workflow: #{session[1]}"
  puts "Path: #{session[2]}"
  puts "Status: #{session[3]}"
  puts "Created: #{session[6]}"
  puts "Updated: #{session[7]}"

  if session[5]
    puts
    puts "Final output:"
    puts session[5]
  end

  if states && !states.empty?
    puts
    puts "Steps executed:"
    states.each do |step_index, step_name, created_at|
      puts "  #{step_index}: #{step_name} (#{created_at})"
    end
  end

  if events && !events.empty?
    puts
    puts "Events:"
    events.each do |event_name, event_data, received_at|
      puts "  #{event_name} at #{received_at}"
      puts "    Data: #{event_data}" if event_data
    end
  end
end

#sessionsObject



165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/roast.rb', line 165

def sessions
  repository = Workflow::StateRepositoryFactory.create

  unless repository.respond_to?(:list_sessions)
    raise Thor::Error, "Session listing is only available with SQLite storage. Set ROAST_STATE_STORAGE=sqlite"
  end

  if options[:cleanup] && options[:older_than]
    count = repository.cleanup_old_sessions(options[:older_than])
    puts "Cleaned up #{count} old sessions"
    return
  end

  sessions = repository.list_sessions(
    status: options[:status],
    workflow_name: options[:workflow],
    older_than: options[:older_than],
  )

  if sessions.empty?
    puts "No sessions found"
    return
  end

  puts "Found #{sessions.length} session(s):"
  puts

  sessions.each do |session|
    id, workflow_name, _, status, current_step, created_at, updated_at = session

    puts "Session: #{id}"
    puts "  Workflow: #{workflow_name}"
    puts "  Status: #{status}"
    puts "  Current step: #{current_step || "N/A"}"
    puts "  Created: #{created_at}"
    puts "  Updated: #{updated_at}"
    puts
  end
end

#validate(workflow_path = nil) ⇒ Object



155
156
157
158
# File 'lib/roast.rb', line 155

def validate(workflow_path = nil)
  validation_command = Roast::Workflow::ValidationCommand.new(options)
  validation_command.execute(workflow_path)
end

#versionObject



113
114
115
# File 'lib/roast.rb', line 113

def version
  puts "Roast version #{Roast::VERSION}"
end