ruote-kit 2.1.11 → 2.2.0.3

Sign up to get free protection for your applications and to get access to all the features.
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