ruote-kit 2.1.11 → 2.2.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. data/CHANGELOG.txt +6 -1
  2. data/CREDITS.txt +23 -0
  3. data/LICENSE.txt +1 -1
  4. data/README.rdoc +44 -7
  5. data/Rakefile +78 -45
  6. data/TODO.txt +8 -0
  7. data/lib/ruote-kit/helpers/json_helpers.rb +1 -1
  8. data/lib/ruote-kit/helpers/misc_helpers.rb +1 -1
  9. data/lib/ruote-kit/helpers/render_helpers.rb +18 -1
  10. data/lib/ruote-kit/public/_ruote/stylesheets/ruote-fluo-editor.css +1 -1
  11. data/lib/ruote-kit/resources/expressions.rb +6 -0
  12. data/lib/ruote-kit/resources/participants.rb +3 -1
  13. data/lib/ruote-kit/resources/schedules.rb +1 -1
  14. data/lib/ruote-kit/resources/workitems.rb +4 -0
  15. data/lib/ruote-kit/version.rb +1 -1
  16. data/lib/ruote-kit/views/expression.html.haml +2 -2
  17. data/lib/ruote-kit/views/layout.html.haml +1 -1
  18. data/lib/ruote-kit/views/participants.html.haml +19 -18
  19. data/lib/ruote-kit.rb +13 -3
  20. data/ruote-kit.gemspec +34 -133
  21. data/spec/resources/errors_spec.rb +20 -8
  22. data/spec/resources/expressions_spec.rb +211 -45
  23. data/spec/resources/index_spec.rb +1 -5
  24. data/spec/resources/participants_spec.rb +26 -9
  25. data/spec/resources/processes_spec.rb +77 -41
  26. data/spec/resources/schedules_spec.rb +33 -9
  27. data/spec/resources/workitems_spec.rb +174 -83
  28. data/spec/spec_helper.rb +11 -56
  29. data/spec/support/engine_helper.rb +97 -0
  30. data/spec/support/rack_helper.rb +21 -0
  31. data/spec/support/render_helper.rb +16 -0
  32. data/spec/webapp_helpers_spec.rb +1 -0
  33. metadata +121 -121
  34. data/.document +0 -0
  35. data/.gitignore +0 -10
  36. data/Gemfile +0 -51
  37. data/config.ru +0 -60
  38. data/lib/ruote-kit/spec/ruote_helpers.rb +0 -56
  39. data/spec/it_has_an_engine.rb +0 -69
  40. data/spec/spec.opts +0 -1
data/CHANGELOG.txt CHANGED
@@ -2,7 +2,12 @@
2
2
  = ruote-kit - CHANGELOG.txt
3
3
 
4
4
 
5
- == ruote-kit - 2.1.11 not yet released
5
+ == ruote-kit - 2.2.0 not yet released
6
+
7
+ - Adapted to ruote 2.2.0 : Parser -> Reader (patch by Chris Buben)
8
+
9
+
10
+ == ruote-kit - 2.1.11 not released
6
11
 
7
12
  - RuoteKit.run_worker(storage) will not return (since it will let the worker
8
13
  run in the current thread)
data/CREDITS.txt ADDED
@@ -0,0 +1,23 @@
1
+
2
+ = CREDITS
3
+
4
+
5
+ == Main project team
6
+
7
+ - Kenneth Kalmer - http://opensourcery.co.za
8
+ - Torsten Schönebaum - http://www.torstenschoenebaum.de
9
+ - John Mettraux - http://jmettraux.wordpress.com
10
+
11
+
12
+ == Contributors
13
+
14
+ - Chris Buben - https://github.com/cbuben
15
+ - Joeri Samson - https://github.com/joerixaop
16
+
17
+
18
+ == Feedback
19
+
20
+ - Eric Smith (broken 2.2.0.2)
21
+ - Simone Carletti - https://github.com/weppos
22
+ - Nicolai Reuschling - https://github.com/codeblogger
23
+
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2009-2010 Kenneth Kalmer (Internet Exchange CC, Clear Planet Information Solutions Pty Ltd)
1
+ Copyright (c) 2009-2011 Kenneth Kalmer (Internet Exchange CC, Clear Planet Information Solutions Pty Ltd)
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.rdoc CHANGED
@@ -1,10 +1,7 @@
1
1
 
2
- = ruote-kit (RESTful ruote & middleware)
2
+ = ruote-kit (ruote on rack)
3
3
 
4
- * http://kit.rubyforge.org/ruote (soon)
5
- * http://kit.rubyforge.org/ruote/rdoc (soon)
6
-
7
- A RESTful wrapper around the ruote[http://ruote.rubyforge.org] workflow engine,
4
+ A wrapper around the ruote[http://ruote.rubyforge.org] workflow engine,
8
5
  built as a modular sinatra[http://www.sinatrarb.com/] application.
9
6
 
10
7
  Follow development:
@@ -31,7 +28,7 @@ Have a look at the Gemfile if you want to see the various dependencies.
31
28
  === Using the source
32
29
 
33
30
  * Get the source files using git
34
- $ git clone http://github.com/kennethkalmer/ruote-kit.git && cd ruote-kit
31
+ $ git clone http://github.com/tosch/ruote-kit.git && cd ruote-kit
35
32
  * Make sure every dependency is resolved
36
33
  $ bundle install
37
34
  * Get going
@@ -108,6 +105,46 @@ Example:
108
105
 
109
106
  === Notes for Rails
110
107
 
108
+ ruote-kit ships with an application template for Ruby on Rails 3.
109
+
110
+ ==== Generate a new Rails app using ruote[-kit]
111
+
112
+ * install Rails
113
+ $ gem install rails
114
+ * create a new Rails app by running
115
+ $ rails new foo -m http://github.com/tosch/ruote-kit/raw/master/rails-template.rb
116
+ * cd into the new Rails dir
117
+ $ cd foo
118
+ * make sure all dependencies are met
119
+ $ bundle install
120
+
121
+ ==== Update an existing Rails app to use ruote[-kit]
122
+
123
+ * in your Rails dir, apply the app template
124
+ $ rake rails:template LOCATION=http://github.com/tosch/ruote-kit/raw/master/rails-template.rb
125
+
126
+ ==== Configure your ruote-kit integration
127
+
128
+ See config/initializers/ruote-kit.rb in your Rails app.
129
+
130
+ ==== Run
131
+
132
+ $ rails server
133
+
134
+ Browse to http://localhost:3000/_ruote and you'll see there are no running
135
+ processes. You could change that using the "Launch process" link ;-)
136
+
137
+ ==== Using Ruote from within Rails
138
+
139
+ You can access Ruote's engine anywhere in your Rails code by calling
140
+ RuoteKit.engine
141
+ So launching a workflow process is as easy as
142
+ RuoteKit.engine.launch your_process_definition
143
+ The storage participant (used by the catchall participant) is available at
144
+ RuoteKit.storage_participant
145
+
146
+ ==== Example application
147
+
111
148
  See http://github.com/tosch/ruote-on-rails for an example Rails app.
112
149
 
113
150
  == Configuring ruote-kit & ruote
@@ -242,7 +279,7 @@ Please do not hesitate to come back with *any* feedback.
242
279
 
243
280
  (The MIT License)
244
281
 
245
- Copyright (c) 2009-2010 Kenneth Kalmer (Internet Exchange CC, Clear Planet Information Solutions Pty Ltd)
282
+ Copyright (c) 2009-2011 Kenneth Kalmer (Internet Exchange CC, Clear Planet Information Solutions Pty Ltd)
246
283
 
247
284
  Permission is hereby granted, free of charge, to any person obtaining
248
285
  a copy of this software and associated documentation files (the
data/Rakefile CHANGED
@@ -1,55 +1,88 @@
1
1
 
2
- require 'rake/tasklib'
3
-
4
- require "rubygems"
5
- require "bundler"
6
- Bundler.setup(:default, :test, :build)
7
-
8
- require File.join(File.dirname(__FILE__), 'lib/ruote-kit/version')
9
-
10
- begin
11
- require 'jeweler'
12
- Jeweler::Tasks.new do |gemspec|
13
- gemspec.name = 'ruote-kit'
14
- gemspec.version = RuoteKit::VERSION
15
- gemspec.summary = 'ruote workflow engine, wrapped in a loving rack embrace'
16
- gemspec.description = 'ruote-kit is a RESTful Rack app for the ruote workflow engine'
17
- gemspec.email = 'kenneth.kalmer@gmail.com'
18
- gemspec.homepage = 'http://github.com/tosch/ruote-kit'
19
- gemspec.authors = [ 'kenneth.kalmer@gmail.com', 'Torsten Schoenebaum', 'John Mettraux' ]
20
- gemspec.extra_rdoc_files.include '*.txt'
21
-
22
- gemspec.files.include 'lib/ruote-kit/public/**/*'
23
- gemspec.executables.clear
24
-
25
- gemspec.add_bundler_dependencies
26
- end
27
- Jeweler::GemcutterTasks.new
28
- rescue LoadError
29
- puts "Jeweler not available. Install it with 'gem install jeweler'"
2
+ $:.unshift('.') # 1.9.2
3
+
4
+ require 'rubygems'
5
+ require 'rubygems/user_interaction' if Gem::RubyGemsVersion == '1.5.0'
6
+
7
+ require 'rake'
8
+ require 'rake/clean'
9
+ require 'rake/rdoctask'
10
+
11
+
12
+ #
13
+ # clean
14
+
15
+ CLEAN.include('pkg', 'rdoc')
16
+
17
+
18
+ #
19
+ # test / spec
20
+
21
+ task :spec do
22
+
23
+ #sh 'rspec spec/'
24
+ sh 'bundle exec rspec spec/'
25
+ end
26
+
27
+ task :test => :spec
28
+ task :default => :spec
29
+
30
+
31
+ #
32
+ # gem
33
+
34
+ GEMSPEC_FILE = Dir['*.gemspec'].first
35
+ GEMSPEC = eval(File.read(GEMSPEC_FILE))
36
+ GEMSPEC.validate
37
+
38
+
39
+ desc %{
40
+ builds the gem and places it in pkg/
41
+ }
42
+ task :build do
43
+
44
+ sh "gem build #{GEMSPEC_FILE}"
45
+ sh "mkdir pkg" rescue nil
46
+ sh "mv #{GEMSPEC.name}-#{GEMSPEC.version}.gem pkg/"
30
47
  end
31
48
 
32
- require 'spec/rake/spectask'
33
- Spec::Rake::SpecTask.new(:spec) do |spec|
34
- spec.libs << 'lib' << 'spec'
35
- spec.spec_files = FileList['spec/**/*_spec.rb']
49
+ desc %{
50
+ builds the gem and pushes it to rubygems.org
51
+ }
52
+ task :push => :build do
53
+
54
+ sh "gem push pkg/#{GEMSPEC.name}-#{GEMSPEC.version}.gem"
36
55
  end
37
56
 
38
- Spec::Rake::SpecTask.new(:rcov) do |spec|
39
- spec.libs << 'lib' << 'spec'
40
- spec.pattern = 'spec/**/*_spec.rb'
41
- spec.rcov = true
57
+
58
+ #
59
+ # rdoc
60
+ #
61
+ # make sure to have rdoc 2.5.x to run that
62
+
63
+ Rake::RDocTask.new do |rd|
64
+
65
+ rd.main = 'README.rdoc'
66
+ rd.rdoc_dir = 'rdoc'
67
+
68
+ rd.rdoc_files.include(
69
+ 'README.rdoc', 'CHANGELOG.txt', 'CREDITS.txt', 'lib/**/*.rb')
70
+
71
+ rd.title = "#{GEMSPEC.name} #{GEMSPEC.version}"
42
72
  end
43
73
 
44
- task :spec #=> :check_dependencies
45
74
 
46
- task :default => :spec
75
+ #
76
+ # upload_rdoc
47
77
 
48
- begin
49
- require 'yard'
50
- YARD::Rake::YardocTask.new
51
- rescue LoadError
52
- task :yardoc do
53
- abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
54
- end
78
+ desc %{
79
+ upload the rdoc to rubyforge
80
+ }
81
+ task :upload_rdoc => [ :clean, :rdoc ] do
82
+
83
+ account = 'jmettraux@rubyforge.org'
84
+ webdir = '/var/www/gforge-projects/ruote'
85
+
86
+ sh "rsync -azv -e ssh rdoc/#{GEMSPEC.name}_rdoc #{account}:#{webdir}/"
55
87
  end
88
+
data/TODO.txt CHANGED
@@ -9,4 +9,12 @@
9
9
  [ ] expression : re_apply OK but reply too
10
10
 
11
11
  [ ] If-Match etag
12
+ [ ] JSON pretty encode output mode (only necessary with CURL and co)
13
+
14
+ [ ] relative paths : http://groups.google.com/group/rack-devel/browse_thread/thread/32312e78f42351f0
15
+
16
+ [ ] application/vnd.ruote.lambda.io+json;type=xxx
17
+
18
+ [ ] update rspec
19
+ [ ] write ruote-kit.gemspec manually
12
20
 
@@ -147,7 +147,7 @@ module RuoteKit
147
147
  result << hlink(resource.to_s, :rel => 'all')
148
148
 
149
149
  lim = @limit || settings.limit
150
- las = (@count / lim) * lim
150
+ las = (@count / lim) * lim rescue 0
151
151
  pre = [ 0, @skip - lim ].max
152
152
  nex = [ @skip + lim, las ].min
153
153
 
@@ -27,7 +27,7 @@ end
27
27
 
28
28
  def sample_process_tree
29
29
 
30
- Rufus::Json.encode(Ruote::Parser.parse(sample_process))
30
+ Rufus::Json.encode(Ruote::Reader.read(sample_process))
31
31
  end
32
32
  end
33
33
  end
@@ -26,7 +26,8 @@ module RuoteKit
26
26
  #
27
27
  HTTP_CODES = {
28
28
  400 => 'bad request',
29
- 404 => 'resource not found'
29
+ 404 => 'resource not found',
30
+ 412 => 'precondition failed'
30
31
  }
31
32
 
32
33
  # HTTP errors
@@ -58,6 +59,22 @@ module RuoteKit
58
59
  end
59
60
  end
60
61
 
62
+ # http error 412 if if-match header is set to an etag different to the
63
+ # value given
64
+ #
65
+ def check_if_match_etag(value)
66
+ value = '"%s"' % value
67
+
68
+ if etags = request.env['HTTP_IF_MATCH']
69
+ etags = etags.split(/\s*,\s*/)
70
+
71
+ unless etags.include?(value) || etags.include?('*')
72
+ http_error(412)
73
+ halt
74
+ end
75
+ end
76
+ end
77
+
61
78
  # Extract the process tree
62
79
  #
63
80
  def process_tree(object)
@@ -1,6 +1,6 @@
1
1
 
2
2
  #fluo_editor {
3
- font: 14px/1.5em monaco, mono;
3
+ font: 14px/1.4em monaco, mono;
4
4
  text-align: left;
5
5
  color: #000;
6
6
  border: 1px solid #c1c1c1;
@@ -13,6 +13,8 @@ class RuoteKit::Application
13
13
 
14
14
  return http_error(404) unless @expression
15
15
 
16
+ etag @expression.to_h['_rev']
17
+
16
18
  respond_with :expression
17
19
  else
18
20
 
@@ -26,6 +28,8 @@ class RuoteKit::Application
26
28
 
27
29
  return http_error(404) unless expression
28
30
 
31
+ check_if_match_etag(expression.to_h['_rev'])
32
+
29
33
  if params[:_kill]
30
34
  RuoteKit.engine.kill_expression(expression.fei)
31
35
  else
@@ -44,6 +48,8 @@ class RuoteKit::Application
44
48
 
45
49
  return http_error(404) unless expression
46
50
 
51
+ check_if_match_etag(expression.to_h['_rev'])
52
+
47
53
  info = begin
48
54
  fetch_re_apply_info
49
55
  rescue Rufus::Json::ParserError => pe
@@ -36,7 +36,9 @@ class RuoteKit::Application
36
36
  end
37
37
  end
38
38
 
39
- RuoteKit.engine.participant_list = list
39
+ unless list.empty?
40
+ RuoteKit.engine.participant_list = list
41
+ end
40
42
 
41
43
  respond_to do |format|
42
44
 
@@ -5,7 +5,7 @@ class RuoteKit::Application
5
5
 
6
6
  get '/_ruote/schedules/?' do
7
7
 
8
- @count = RuoteKit.engine.processes(:count => true)
8
+ @count = RuoteKit.engine.schedules(:count => true)
9
9
  paginate
10
10
 
11
11
  @schedules = RuoteKit.engine.schedules(:skip => @skip, :limit => @limit)
@@ -34,6 +34,8 @@ class RuoteKit::Application
34
34
  return http_error(404) if @workitem.nil? && @workitems.nil?
35
35
 
36
36
  if @workitem
37
+ etag @workitem.to_h['_rev']
38
+
37
39
  respond_with :workitem
38
40
  else
39
41
  respond_with :workitems
@@ -46,6 +48,8 @@ class RuoteKit::Application
46
48
 
47
49
  return http_error(404) unless @workitem
48
50
 
51
+ check_if_match_etag(@workitem.to_h['_rev'])
52
+
49
53
  options = begin
50
54
  field_updates_and_proceed_from_put
51
55
  rescue Rufus::Json::ParserError => pe
@@ -8,6 +8,6 @@
8
8
 
9
9
  module RuoteKit
10
10
 
11
- VERSION = '2.1.11'
11
+ VERSION = '2.2.0'
12
12
  end
13
13
 
@@ -41,7 +41,7 @@
41
41
  %td
42
42
  original tree
43
43
  %td
44
- - ruby = Ruote::Parser.to_ruby(@expression.original_tree)
44
+ - ruby = Ruote::Reader.to_ruby(@expression.original_tree)
45
45
  - rubyline = ruby.split("\n").first
46
46
  - json = Rufus::Json.pretty_encode(@expression.original_tree)
47
47
  %pre.pdef{ :onclick => 'Rk.toggleNext(this);' } #{rubyline}
@@ -51,7 +51,7 @@
51
51
  %td
52
52
  tree
53
53
  %td
54
- - ruby = Ruote::Parser.to_ruby(@expression.tree)
54
+ - ruby = Ruote::Reader.to_ruby(@expression.tree)
55
55
  - rubyline = ruby.split("\n").first
56
56
  - json = Rufus::Json.pretty_encode(@expression.tree)
57
57
  %pre.pdef{ :onclick => 'Rk.toggleNext(this);' } #{rubyline}
@@ -54,7 +54,7 @@
54
54
 
55
55
  #footer
56
56
  %div
57
- &copy; 2009-2010 Kenneth Kalmer
57
+ &copy; 2009-2011 Kenneth Kalmer
58
58
  |
59
59
  %a{ :href => 'http://www.opensourcery.co.za' } blog
60
60
  |
@@ -15,28 +15,29 @@
15
15
 
16
16
  %table.participants
17
17
  %thead
18
- %td
19
- regex
20
- %td
21
- classname
22
- %td
23
- options
24
- %td
25
- &nbsp;
26
-
27
- - @participants.each_with_index do |pa, i|
28
18
  %tr
29
19
  %td
30
- %input.participant{ :type => :text, :value => pa.regex }
20
+ regex
31
21
  %td
32
- %input.participant{ :type => :text, :style => 'width: 350px;', :value => pa.classname }
22
+ classname
33
23
  %td
34
- %input.participant{ :type => :text, :style => 'width: 350px;', :value => Rufus::Json.encode(pa.options) }
24
+ options
35
25
  %td
36
- %a.ruote_button.ruote_minus_button{ :title => 'remove', :href => '', :onclick => 'remove(this); return false;' }
37
- %a.ruote_button.ruote_up_button{ :title => 'move up', :href => '', :onclick => 'move(this, "up"); return false;' }
38
- %a.ruote_button.ruote_down_button{ :title => 'move down', :href => '', :onclick => 'move(this, "down"); return false;' }
39
- %a.ruote_button.ruote_copy_button{ :title => 'copy', :href => '', :onclick => 'copy(this); return false;' }
26
+ &nbsp;
27
+ %tbody
28
+ - @participants.each_with_index do |pa, i|
29
+ %tr
30
+ %td
31
+ %input.participant{ :type => :text, :value => pa.regex }
32
+ %td
33
+ %input.participant{ :type => :text, :style => 'width: 350px;', :value => pa.classname }
34
+ %td
35
+ %input.participant{ :type => :text, :style => 'width: 350px;', :value => Rufus::Json.encode(pa.options) }
36
+ %td
37
+ %a.ruote_button.ruote_minus_button{ :title => 'remove', :href => '', :onclick => 'remove(this); return false;' }
38
+ %a.ruote_button.ruote_up_button{ :title => 'move up', :href => '', :onclick => 'move(this, "up"); return false;' }
39
+ %a.ruote_button.ruote_down_button{ :title => 'move down', :href => '', :onclick => 'move(this, "down"); return false;' }
40
+ %a.ruote_button.ruote_copy_button{ :title => 'copy', :href => '', :onclick => 'copy(this); return false;' }
40
41
 
41
42
  %input#put_button{ :type => 'submit', :value => 'PUT /_ruote/participants', :onclick => 'nameInputs(); return true;' }
42
43
 
@@ -44,7 +45,7 @@
44
45
  :javascript
45
46
 
46
47
  function nameInputs () {
47
- $('tr').each(function (index) {
48
+ $('tbody tr').each(function (index) {
48
49
  var inputs = $(this).children('td').map(function () {
49
50
  return $(this).children('input')[0];
50
51
  });
data/lib/ruote-kit.rb CHANGED
@@ -21,16 +21,26 @@ module RuoteKit
21
21
  @env ||= defined?(Rails) ? Rails.env : ENV['RACK_ENV'] || 'development'
22
22
  end
23
23
 
24
+ # Returns the storage participant associated automatically with any storage
25
+ #
24
26
  def storage_participant
25
27
  engine.storage_participant
26
28
  end
27
29
 
28
- def run_worker (storage)
30
+ # Given a storage, runs a worker and sets RuoteKit.engine accordingly.
31
+ #
32
+ # By default, this method won't return (it will 'join' the worker). If you
33
+ # need to go on after this call, pass false as second parameter
34
+ # (especially useful in an EventMachine setting).
35
+ #
36
+ def run_worker(storage, join=true)
29
37
  RuoteKit.engine = Ruote::Engine.new(
30
- Ruote::Worker.new(storage), :join => true)
38
+ Ruote::Worker.new(storage), :join => join)
31
39
  end
32
40
 
33
- def bind_engine (storage)
41
+ # Uses the given storage for the RuoteKit.engine (no worker running here).
42
+ #
43
+ def bind_engine(storage)
34
44
  RuoteKit.engine = Ruote::Engine.new(storage)
35
45
  end
36
46
  end