Skip to content

Commit

Permalink
introduce Collaboration::Structure that parses structure and "lane hi…
Browse files Browse the repository at this point in the history
…nts".
  • Loading branch information
apotonick committed Apr 19, 2024
1 parent cefc7d9 commit e719890
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 34 deletions.
40 changes: 32 additions & 8 deletions lib/trailblazer/workflow/collaboration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ module Trailblazer
module Workflow
# User-friendly builder.
def self.Collaboration(json_file:, lanes:, state_guards: nil)
ctx = Collaboration.structure_from_filename(json_file)
_, (ctx, _) = Collaboration::Structure.invoke([{json_filename: json_file}, {}])

lane_options_from_structure = ctx[:lane_hints]

lanes_options = lanes.collect do |json_id, user_options|
lane_options = normalize_lane_options(**user_options)
lane_options = normalize_lane_options(**lane_options_from_structure[json_id])

activity = build_lane_for(**ctx, **user_options, json_id: json_id)

Expand All @@ -27,8 +29,8 @@ def self.Collaboration(json_file:, lanes:, state_guards: nil)
end

# DISCUSS: use Activity here?
def self.normalize_lane_options(label:, icon:, **)
{label: label, icon: icon}
def self.normalize_lane_options(label:, icon:, name:, **)
{label: label, icon: icon, name: name}
end

def self.build_lane_for(intermediates:, implementation:, json_id:, **)
Expand All @@ -41,10 +43,32 @@ def self.build_lane_for(intermediates:, implementation:, json_id:, **)
end

class Collaboration
def self.structure_from_filename(json_file)
json_from_pro = File.read(json_file)
signal, (ctx, _) = Trailblazer::Workflow::Generate.invoke([{json_document: json_from_pro}, {}])
ctx
class Structure < Trailblazer::Activity::Railway
step :read_file
step Subprocess(Trailblazer::Workflow::Parse)
step :compute_lane_hints

def read_file(ctx, json_filename:, **)
ctx[:json_document] = File.read(json_filename)
end

def compute_lane_hints(ctx, structure:, **)
lane_hints = structure.lanes.collect do |lane|
icon, label, name = lane.id.split(".") # TODO: validate/default.


hints = {
json_id: lane.id,
label: label,
icon: icon,
name: name
}

[lane.id, hints]
end.to_h

ctx[:lane_hints] = lane_hints
end
end

class Schema
Expand Down
10 changes: 5 additions & 5 deletions lib/trailblazer/workflow/discovery.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ def stub_task(lane_label, task_label)
stub_task = Trailblazer::Activity::Testing.def_tasks(stub_task_name).method(stub_task_name)
end

def call(json_filename:, lane_hints:)
ctx = Trailblazer::Workflow::Collaboration.structure_from_filename(json_filename)
def call(json_filename:)
_, (ctx, _) = Collaboration::Structure.invoke([{json_filename: json_filename}, {}])

stubbed_lanes = ctx[:intermediates].collect do |json_id, intermediate|
lane_task_2_wiring = intermediate.wiring.find_all { |task_ref, _| task_ref.data[:type] == :task }
Expand All @@ -31,7 +31,7 @@ def call(json_filename:, lane_hints:)

[
json_id,
{label: rand, icon: rand, implementation: stubbed_tasks}.merge(lane_hints[json_id])
{implementation: stubbed_tasks}
]
end.to_h

Expand All @@ -44,7 +44,7 @@ def call(json_filename:, lane_hints:)
# Find all possible configurations for a {collaboration} by replacing
# its tasks with mocks, and run through all possible paths.
# FIXME: initial_lane_positions defaulting is not tested.
def call(json_filename:, start_lane:, dsl_options_for_run_multiple_times: {}, lane_hints: {})
def call(json_filename:, start_lane:, dsl_options_for_run_multiple_times: {})
# State discovery:
# The idea is that we collect suspend events and follow up on all their resumes (catch) events.
# We can't see into {Collaboration.call}, meaning we can really only collect public entry points,
Expand All @@ -58,7 +58,7 @@ def call(json_filename:, start_lane:, dsl_options_for_run_multiple_times: {}, la
# imply we start from a public resume and discover the path?
# we could save work on {run_multiple_times} with this.

collaboration = Stub.(json_filename: json_filename, lane_hints: lane_hints)
collaboration = Stub.(json_filename: json_filename)

initial_lane_positions = Collaboration::Synchronous.initial_lane_positions(collaboration.to_h[:lanes])
initial_lane_positions = Collaboration::Positions.new(initial_lane_positions.collect { |activity, task| Trailblazer::Workflow::Collaboration::Position.new(activity, task) }) # FIXME: initial_lane_positions should return {Collaboration::Positions}
Expand Down
29 changes: 8 additions & 21 deletions test/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,9 @@ def build_schema()
implementing_editor = Trailblazer::Activity::Testing.def_steps(:Notify, :Reject, :Approve)

schema = Trailblazer::Workflow.Collaboration(
json_file: "test/fixtures/v1/posting-v10.json",
json_file: "test/fixtures/v1/posting-v11.json",
lanes: {
"article moderation" => {
label: "lifecycle",
icon: "⛾",
"⛾.lifecycle.posting" => {
implementation: {
"Create" => Trailblazer::Activity::Railway.Subprocess(Create),
"Update" => implementing.method(:update),
Expand All @@ -53,9 +51,7 @@ def build_schema()
"Delete" => implementing.method(:delete),
}
},
"<ui> author workflow" => {
label: "UI",
icon: "☝",
"☝.UI.blogger" => {
implementation: {
"Create form" => implementing_ui.method(:create_form),
"Create" => implementing_ui.method(:ui_create),
Expand All @@ -75,9 +71,7 @@ def build_schema()

}
},
"reviewer"=> {
label: "editor",
icon: "☑",
"☑.editor.reviewer" => {
implementation: {
"Notify" => implementing_editor.method(:Notify),
"Reject" => implementing_editor.method(:Reject),
Expand All @@ -98,7 +92,7 @@ module DiscoveredStates
def states
states, stub_schema = Trailblazer::Workflow::Discovery.(
json_filename: "test/fixtures/v1/posting-v10.json",
start_lane: "<ui> author workflow",
start_lane: "UI",

# TODO: allow translating the original "id" (?) to the stubbed.
dsl_options_for_run_multiple_times: {
Expand All @@ -109,18 +103,11 @@ def states
# }, config_payload: {outcome: :failure}},

# Click [UI Create] again, with invalid data.
["<ui> author workflow", "Create"] => {ctx_merge: {:"article moderation:Create" => Trailblazer::Activity::Left}, config_payload: {outcome: :failure}},
["UI", "Create"] => {ctx_merge: {:"article moderation:Create" => Trailblazer::Activity::Left}, config_payload: {outcome: :failure}},
# Click [UI Update] again, with invalid data.
["<ui> author workflow", "Update"] => {ctx_merge: {:"article moderation:Update" => Trailblazer::Activity::Left}, config_payload: {outcome: :failure}},
["<ui> author workflow", "Revise"] => {ctx_merge: {:"article moderation:Revise" => Trailblazer::Activity::Left}, config_payload: {outcome: :failure}},
["UI", "Update"] => {ctx_merge: {:"article moderation:Update" => Trailblazer::Activity::Left}, config_payload: {outcome: :failure}},
["UI", "Revise"] => {ctx_merge: {:"article moderation:Revise" => Trailblazer::Activity::Left}, config_payload: {outcome: :failure}},
},

# DISCUSS: compute this automatically/from diagram?
lane_hints: {
"<ui> author workflow" => {label: "UI", icon: "☝"},
"article moderation" => {label: "lifecycle", icon: "⛾"},
"reviewer" => {label: "editor", icon: "☑"},
}
)

return states, stub_schema, stub_schema.to_h[:lanes]
Expand Down

0 comments on commit e719890

Please sign in to comment.