ruote-library 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ coverage
6
+ InstalledFiles
7
+ lib/bundler/man
8
+ pkg
9
+ rdoc
10
+ spec/reports
11
+ test/tmp
12
+ test/version_tmp
13
+ tmp
14
+
15
+ # YARD artifacts
16
+ .yardoc
17
+ _yardoc
18
+ doc/
19
+
20
+ Gemfile.lock
21
+ ruote_work/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in ruote-library.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Hartog C. de Mik
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,24 @@
1
+ # ruote-library
2
+
3
+ A process library for Ruote
4
+
5
+ ## Usage
6
+
7
+ ```ruby
8
+ require 'ruote-library'
9
+
10
+ library = Ruote::ProcessLibrary.new("/path/to/processes")
11
+ radial_pdef = library.fetch "some_process"
12
+
13
+ dashboard.launch(radial_pdef, workitem, vars)
14
+ ```
15
+
16
+ ## Contributing
17
+
18
+ Contributions are most welcome - please follow this convention:
19
+
20
+ 1. Fork it
21
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
22
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
23
+ 4. Push to the branch (`git push origin my-new-feature`)
24
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,120 @@
1
+ require 'singleton'
2
+ require 'strscan'
3
+ require 'ruote/reader'
4
+
5
+ module Ruote
6
+ # A keeper of books^W processes
7
+ #
8
+ # === Usage
9
+ # lib = ProcessLibrary.new("/path/to/processes")
10
+ # pdef_radial = lib.fetch('process_name')
11
+ #
12
+ class ProcessLibrary
13
+ class ProcessNotFound < RuntimeError; end
14
+
15
+ # @param [String] root The path to the process library on disk.
16
+ def initialize(root)
17
+ @root = root
18
+ end
19
+
20
+ # Fetch a process definition from the library. Possible making it more
21
+ # complete
22
+ #
23
+ # === Fetching referenced
24
+ #
25
+ # Imagine you have these files:
26
+ # > cat process_one.radial
27
+ # define process_one
28
+ # do_something
29
+ # subprocess ref: process_two
30
+ #
31
+ # > cat process_two.radial
32
+ # define process_two
33
+ # do_something_spectacular
34
+ # subprocess 'funny/three'
35
+ #
36
+ # > cat funny/three.radial
37
+ # define 'funny/three'
38
+ # be_funny
39
+ #
40
+ # When you do ProcessLibrary.fetch("process_one") you will receive:
41
+ #
42
+ # define process_one
43
+ # do_something
44
+ # subprocess ref: process_two
45
+ #
46
+ # define process_two
47
+ # do_something_spectacular
48
+ # subprocess funny/three
49
+ #
50
+ # define funny/three
51
+ # be_funny
52
+ #
53
+ # In other words: fetch() loads any referenced subprocess that are not
54
+ # defined in the original definition. (Notice the missing single-quotes?)
55
+ #
56
+ # === Caveat
57
+ # In order for this to work you must:
58
+ #
59
+ # * Name your files like your (sub)processes, including path from @root
60
+ # * Use the 'subprocess' expression
61
+ # (see: http://ruote.rubyforge.org/exp/subprocess.html)
62
+ # otherwise the library will not be able to tell the diference between a
63
+ # participant and a subprocess
64
+ #
65
+ # @param [String] name The name of the file to fetch
66
+ # @return [String] radial process definition (regardless of what was in
67
+ # the file)
68
+ def fetch(name, indent=0)
69
+ # turn into a radial, with the given indent depth
70
+ radial = ::Ruote::Reader.to_radial(
71
+ ::Ruote::Reader.read(self.read(name)),
72
+ indent
73
+ )
74
+
75
+ # check if the radial references any subprocesses not defined in this
76
+ # definition and fetch-and-append them
77
+ #
78
+ if radial =~ /subprocess/
79
+ # find the subs
80
+ subs = radial.scan(/subprocess (.+)$/).flatten.map do |sub|
81
+ sub.split(/, ?/).first.gsub(/[\'\"]/, '').gsub('ref: ', '')
82
+ end
83
+
84
+ # find the definitions
85
+ defines = radial.scan(/define (.+)$/).flatten.map do |define|
86
+ define.gsub(/[\'\"]/, '').gsub('name: ', '')
87
+ end
88
+
89
+ # substract the defs from the subs and load the remaining subs
90
+ subs -= defines
91
+ subs.each do |sub|
92
+ radial += "\n" + fetch(sub, 1) + "\n"
93
+ end
94
+ end
95
+
96
+ return radial
97
+ end
98
+
99
+ # Read a process definition from file
100
+ #
101
+ # @param [String] name The name of the process - should be the filename,
102
+ # the extension is optional and tried in the order .radial, .json and
103
+ # finaly .xml
104
+ #
105
+ # @return [String] The contents of the first found file
106
+ #
107
+ def read(name)
108
+ path = File.join(@root, name)
109
+ return File.read(path) if File.exists?(path)
110
+
111
+ %w[radial json xml].each do |ext|
112
+ ext_path = path + ".#{ext}"
113
+ return File.read(ext_path) if File.exists?(ext_path)
114
+ end
115
+
116
+ raise ProcessNotFound,
117
+ "Coud not find a process named: #{name}[.radial|.json|.xml] in #{@root}"
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,20 @@
1
+ # -*- encoding: utf-8 -*-
2
+ Gem::Specification.new do |gem|
3
+ gem.authors = ["Hartog C. de Mik"]
4
+ gem.email = ["hartog@organisedminds.com"]
5
+ gem.description = %q{A library for Ruote processes, based on FS storage and sub-processes}
6
+ gem.summary = %q{Ruote process library}
7
+ gem.homepage = "https://github.com/coffeeaddict/ruote-library"
8
+
9
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
10
+ gem.files = `git ls-files`.split("\n")
11
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
12
+ gem.name = "ruote-library"
13
+ gem.require_paths = ["lib"]
14
+ gem.version = "1.0.0"
15
+
16
+ gem.add_dependency 'ruote', ['~> 2.3']
17
+
18
+ gem.add_development_dependency 'rspec'
19
+ gem.add_development_dependency 'mocha'
20
+ end
@@ -0,0 +1,106 @@
1
+ require 'spec_helper'
2
+
3
+ root = File.expand_path("../../support/processes", __FILE__)
4
+
5
+ describe Ruote::ProcessLibrary do
6
+ before(:each) do
7
+ @library = Ruote::ProcessLibrary.new(root)
8
+
9
+ @dash.register_participant "debug" do |wi|
10
+ text = wi.params['text'] || wi.params['message']
11
+ wi.fields["trace"] << "debug"
12
+
13
+ if text
14
+ text.gsub!(/\$\{f:([^\}]+)\}/) { wi.fields[$1] }
15
+ STDERR.puts "{#{wi.wfid}}: #{text}"
16
+ else
17
+ STDERR.puts "{#{wi.wfid}}: WORKITEM : #{wi.fields.inspect}"
18
+ end
19
+ end
20
+
21
+ @dash.register_participant "*" do |wi|
22
+ wi.fields['trace'] << wi.params['ref']
23
+ end
24
+ end
25
+
26
+ describe :single_process do
27
+ it "should raise an error on non-existing files" do
28
+ expect {
29
+ @library.fetch("ce-ci-nest-pas-une-file")
30
+ }.to raise_error(Ruote::ProcessLibrary::ProcessNotFound)
31
+ end
32
+
33
+ it "should fetch a json process" do
34
+ pdef = @library.fetch("json.json")
35
+ pdef.should be_kind_of String
36
+ end
37
+
38
+ it "should fetch an xml process" do
39
+ pdef = @library.fetch("xml.xml")
40
+ pdef.should be_kind_of String
41
+ end
42
+
43
+ it "should auto-apply an extension" do
44
+ pdef = @library.fetch("xml")
45
+ pdef.should be_kind_of String
46
+ end
47
+
48
+ it "should return a radial process" do
49
+ pdef = @library.fetch("json")
50
+ pdef.should be_kind_of String
51
+
52
+ Ruote::Reader.to_radial(Ruote::Reader.read(pdef)).should eq pdef
53
+ end
54
+
55
+ it "should be executable" do
56
+ pdef = @library.fetch("json")
57
+ wfid = @dash.launch(pdef, { trace: [] } )
58
+ res = @dash.wait_for(wfid)
59
+
60
+ res.should trace(%w[alpha bravo charlie])
61
+ end
62
+ end
63
+
64
+ describe :sub_process do
65
+ it "should not read a subprocess when defined" do
66
+ pdef = @library.fetch("defined")
67
+ wfid = @dash.launch(pdef, { trace: [] } )
68
+ res = @dash.wait_for(wfid)
69
+
70
+ res.should trace(%w[abc_alpha abc_bravo abc_charlie])
71
+ end
72
+
73
+ it "should read a subprocess when not defined" do
74
+ pdef = @library.fetch("subs")
75
+ wfid = @dash.launch(pdef, { trace: [] } )
76
+ res = @dash.wait_for(wfid)
77
+
78
+ res.should trace(%w[root_alpha root_beta alpha bravo charlie])
79
+ end
80
+
81
+ it "should read subprocess recursively" do
82
+ pdef = @library.fetch("recursive")
83
+ wfid = @dash.launch(pdef, { trace: [] } )
84
+ res = @dash.wait_for(wfid)
85
+
86
+ res.should trace(%w[recursive_alpha root_alpha alpha])
87
+ end
88
+
89
+ it "should read from subdirectories" do
90
+ pdef = @library.fetch("army/build")
91
+ pdef.should be_kind_of String
92
+ end
93
+
94
+ it "should read from subdirectories recursively" do
95
+ pdef = @library.fetch("country/attack")
96
+ pdef.should be_kind_of String
97
+
98
+ wfid = @dash.launch(pdef, { trace: [] } )
99
+ res = @dash.wait_for(wfid)
100
+
101
+ res.should trace(
102
+ %w[recruit_troops train_troops build_phalanx_formation send_formation]
103
+ )
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,24 @@
1
+ require 'ruby_parser'
2
+ require 'sexp_processor'
3
+ require 'ruby2ruby'
4
+
5
+ require 'ruote-library'
6
+
7
+ require 'rufus-json/automatic'
8
+ require 'ruote'
9
+ require 'ruote/storage/fs_storage'
10
+
11
+ require 'singleton'
12
+
13
+ Dir[File.expand_path( "../support/**/*.rb", __FILE__)].sort.each { |f| require f }
14
+
15
+ RSpec.configure do |config|
16
+ config.tty = true
17
+ config.mock_with :mocha
18
+
19
+ config.before(:all) do
20
+ @dash = Ruote::Dashboard.new(
21
+ Ruote::Worker.new(
22
+ Ruote::FsStorage.new('ruote_work')))
23
+ end
24
+ end
@@ -0,0 +1,9 @@
1
+ module RSpecWorldHelper
2
+ def RWorld(constant)
3
+ RSpec.configure do |config|
4
+ config.include constant
5
+ end
6
+ end
7
+ end
8
+
9
+ include RSpecWorldHelper
@@ -0,0 +1,4 @@
1
+ define army/attack
2
+ # roman army style
3
+ build_phalanx_formation
4
+ send_formation direction: 'forward'
@@ -0,0 +1,3 @@
1
+ define army/build
2
+ recruit_troops
3
+ train_troops
@@ -0,0 +1,4 @@
1
+ define country/attack
2
+ iterator on_val: 'army, navy, airforce', to_var: 'type'
3
+ subprocess army/build, type: '${v:type}'
4
+ subprocess army/attack, type: '${v:type}'
@@ -0,0 +1,10 @@
1
+ define defined
2
+ alpha
3
+ bravo
4
+ subprocess ref: abc
5
+
6
+ define abc
7
+ sequence
8
+ abc_alpha
9
+ abc_bravo
10
+ abc_charlie
@@ -0,0 +1 @@
1
+ ["define",{"json":null},[["sequence",{},[["alpha",{},[]],["bravo",{},[]],["charlie",{},[]]]]]]
@@ -0,0 +1,3 @@
1
+ define recursive
2
+ recursive_alpha
3
+ subprocess ref: subs
@@ -0,0 +1,4 @@
1
+ define subs
2
+ root_alpha
3
+ root_beta
4
+ subprocess ref: json
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+
3
+ <define ref="xml">
4
+ <sequence>
5
+ <alpha/>
6
+ <charlie/>
7
+ </sequence>
8
+ </define>
@@ -0,0 +1,31 @@
1
+ module TraceMatcher
2
+ def trace(list)
3
+ list = [list] unless list.is_a?(Array)
4
+ TraceMatcher::Matcher.new(list)
5
+ end
6
+
7
+ class Matcher
8
+ def initialize(list)
9
+ @expected = list
10
+ end
11
+
12
+ def matches?(actual)
13
+ @actual = actual
14
+ matches = @expected.map do |e|
15
+ @actual['workitem']['fields']['trace'].include?(e)
16
+ end
17
+
18
+ !matches.any? { |x| x == false }
19
+ end
20
+
21
+ def failure_message
22
+ "Expected #{@actual['workitem']['fields']} to execute all of #{@expected}"
23
+ end
24
+
25
+ def negative_failure_message
26
+ "Expected #{@actual['workitem']['fields']} to not execute any of #{@expected}"
27
+ end
28
+ end
29
+ end
30
+
31
+ RWorld(TraceMatcher)
metadata ADDED
@@ -0,0 +1,98 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruote-library
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Hartog C. de Mik
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-10-21 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: ruote
16
+ requirement: &16232700 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '2.3'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *16232700
25
+ - !ruby/object:Gem::Dependency
26
+ name: rspec
27
+ requirement: &16232300 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *16232300
36
+ - !ruby/object:Gem::Dependency
37
+ name: mocha
38
+ requirement: &14938560 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *14938560
47
+ description: A library for Ruote processes, based on FS storage and sub-processes
48
+ email:
49
+ - hartog@organisedminds.com
50
+ executables: []
51
+ extensions: []
52
+ extra_rdoc_files: []
53
+ files:
54
+ - .gitignore
55
+ - Gemfile
56
+ - LICENSE
57
+ - README.md
58
+ - Rakefile
59
+ - lib/ruote-library.rb
60
+ - ruote-library.gemspec
61
+ - spec/library/01_basic_spec.rb
62
+ - spec/spec_helper.rb
63
+ - spec/support/01_rspec_helper.rb
64
+ - spec/support/processes/army/attack.radial
65
+ - spec/support/processes/army/build.radial
66
+ - spec/support/processes/country/attack.radial
67
+ - spec/support/processes/defined.radial
68
+ - spec/support/processes/json.json
69
+ - spec/support/processes/recursive.radial
70
+ - spec/support/processes/subs.radial
71
+ - spec/support/processes/xml.xml
72
+ - spec/support/trace_matcher.rb
73
+ homepage: https://github.com/coffeeaddict/ruote-library
74
+ licenses: []
75
+ post_install_message:
76
+ rdoc_options: []
77
+ require_paths:
78
+ - lib
79
+ required_ruby_version: !ruby/object:Gem::Requirement
80
+ none: false
81
+ requirements:
82
+ - - ! '>='
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ required_rubygems_version: !ruby/object:Gem::Requirement
86
+ none: false
87
+ requirements:
88
+ - - ! '>='
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ requirements: []
92
+ rubyforge_project:
93
+ rubygems_version: 1.8.11
94
+ signing_key:
95
+ specification_version: 3
96
+ summary: Ruote process library
97
+ test_files: []
98
+ has_rdoc: