nayati 0.1.0

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 (81) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +79 -0
  4. data/Rakefile +32 -0
  5. data/app/models/nayati/application_record.rb +5 -0
  6. data/app/models/nayati/master_operation.rb +46 -0
  7. data/app/models/nayati/master_workflow.rb +67 -0
  8. data/app/models/nayati/name_based_constantable.rb +30 -0
  9. data/app/models/nayati/operation.rb +29 -0
  10. data/app/models/nayati/operation_configuration.rb +73 -0
  11. data/app/models/nayati/operation_implementer_base.rb +21 -0
  12. data/app/models/nayati/workflow.rb +170 -0
  13. data/config/operations.yml +3 -0
  14. data/db/migrate/20200127144219_create_workflow.rb +16 -0
  15. data/db/migrate/20200127144220_create_operation.rb +19 -0
  16. data/lib/generators/nayati/install/install_generator.rb +30 -0
  17. data/lib/generators/nayati/install/templates/create_operation.rb +19 -0
  18. data/lib/generators/nayati/install/templates/create_workflow.rb +16 -0
  19. data/lib/generators/nayati/install/templates/operations.yml +3 -0
  20. data/lib/generators/nayati/operation/operation_generator.rb +46 -0
  21. data/lib/generators/nayati/operation/templates/operation_template.txt +20 -0
  22. data/lib/generators/nayati/workflow/templates/nayati_service_template.txt +20 -0
  23. data/lib/generators/nayati/workflow/workflow_generator.rb +39 -0
  24. data/lib/nayati.rb +5 -0
  25. data/lib/nayati/engine.rb +12 -0
  26. data/lib/nayati/version.rb +3 -0
  27. data/lib/nayati/workflow_results/base.rb +18 -0
  28. data/lib/nayati/workflow_runner.rb +34 -0
  29. data/spec/dummy/Rakefile +6 -0
  30. data/spec/dummy/app/models/application_record.rb +3 -0
  31. data/spec/dummy/bin/bundle +3 -0
  32. data/spec/dummy/bin/rails +4 -0
  33. data/spec/dummy/bin/rake +4 -0
  34. data/spec/dummy/bin/setup +36 -0
  35. data/spec/dummy/bin/update +31 -0
  36. data/spec/dummy/bin/yarn +11 -0
  37. data/spec/dummy/config.ru +5 -0
  38. data/spec/dummy/config/application.rb +19 -0
  39. data/spec/dummy/config/boot.rb +5 -0
  40. data/spec/dummy/config/cable.yml +10 -0
  41. data/spec/dummy/config/database.yml +24 -0
  42. data/spec/dummy/config/environment.rb +5 -0
  43. data/spec/dummy/config/environments/development.rb +61 -0
  44. data/spec/dummy/config/environments/production.rb +94 -0
  45. data/spec/dummy/config/environments/test.rb +46 -0
  46. data/spec/dummy/config/initializers/application_controller_renderer.rb +8 -0
  47. data/spec/dummy/config/initializers/assets.rb +14 -0
  48. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  49. data/spec/dummy/config/initializers/content_security_policy.rb +25 -0
  50. data/spec/dummy/config/initializers/cookies_serializer.rb +5 -0
  51. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  52. data/spec/dummy/config/initializers/inflections.rb +16 -0
  53. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  54. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  55. data/spec/dummy/config/locales/en.yml +33 -0
  56. data/spec/dummy/config/operations.yml +3 -0
  57. data/spec/dummy/config/puma.rb +34 -0
  58. data/spec/dummy/config/spring.rb +6 -0
  59. data/spec/dummy/config/storage.yml +34 -0
  60. data/spec/dummy/db/migrate/20200202111127_create_workflow.rb +16 -0
  61. data/spec/dummy/db/migrate/20200202111128_create_operation.rb +19 -0
  62. data/spec/dummy/db/schema.rb +36 -0
  63. data/spec/dummy/log/development.log +56 -0
  64. data/spec/dummy/package.json +5 -0
  65. data/spec/dummy/public/404.html +67 -0
  66. data/spec/dummy/public/422.html +67 -0
  67. data/spec/dummy/public/500.html +66 -0
  68. data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
  69. data/spec/dummy/public/apple-touch-icon.png +0 -0
  70. data/spec/dummy/public/favicon.ico +0 -0
  71. data/spec/factories/operations_factory.rb +6 -0
  72. data/spec/factories/workflow_factory.rb +7 -0
  73. data/spec/lib/decider/workflow_runner_spec.rb +59 -0
  74. data/spec/lib/decider_spec.rb +4 -0
  75. data/spec/models/decider/master_operation_spec.rb +26 -0
  76. data/spec/models/decider/master_workflow_spec.rb +28 -0
  77. data/spec/models/decider/operation_spec.rb +48 -0
  78. data/spec/models/decider/workflow_spec.rb +159 -0
  79. data/spec/rails_helper.rb +57 -0
  80. data/spec/spec_helper.rb +120 -0
  81. metadata +259 -0
@@ -0,0 +1,3 @@
1
+ # This file should have the all the operations used in your application
2
+ # Make an entry in this file to add a workflow or operation. You can also use
3
+ # operationsg generator to create the entries along with implementer class
@@ -0,0 +1,16 @@
1
+ class CreateWorkflow < ActiveRecord::Migration[5.0]
2
+ def self.up
3
+ create_table :nayati_workflows do |t|
4
+ t.string :name
5
+ t.integer :initial_operation_id
6
+ t.string :identifier
7
+ t.timestamps
8
+ end
9
+
10
+ add_index :nayati_workflows, :identifier
11
+ end
12
+
13
+ def self.down
14
+ drop_table :nayati_workflows
15
+ end
16
+ end
@@ -0,0 +1,19 @@
1
+ class CreateOperation < ActiveRecord::Migration[5.0]
2
+ def self.up
3
+ create_table :nayati_operations do |t|
4
+ t.string :name
5
+ t.integer :after_success_operation_id
6
+ t.integer :after_failure_operation_id
7
+ t.integer :workflow_id
8
+ t.timestamps
9
+ end
10
+
11
+ add_index :nayati_operations, :workflow_id
12
+ add_index :nayati_operations, :after_failure_operation_id
13
+ add_index :nayati_operations, :after_success_operation_id
14
+ end
15
+
16
+ def self.down
17
+ drop_table :workflows
18
+ end
19
+ end
@@ -0,0 +1,30 @@
1
+ require 'rails/generators/migration'
2
+
3
+ module Nayati
4
+ module Generators
5
+ class InstallGenerator < ::Rails::Generators::Base
6
+ include Rails::Generators::Migration
7
+ source_root File.expand_path('../templates', __FILE__)
8
+ desc "add the migrations"
9
+
10
+ def self.next_migration_number(path)
11
+ unless @prev_migration_nr
12
+ @prev_migration_nr = Time.now.utc.strftime("%Y%m%d%H%M%S").to_i
13
+ else
14
+ @prev_migration_nr += 1
15
+ end
16
+ @prev_migration_nr.to_s
17
+ end
18
+
19
+ def copy_migrations
20
+ migration_template "create_workflow.rb", "db/migrate/create_workflow.rb"
21
+ migration_template "create_operation.rb", "db/migrate/create_operation.rb"
22
+ # migration_template "create_something_else.rb", "db/migrate/create_something_else.rb"
23
+ end
24
+
25
+ def copy_operations_yml
26
+ copy_file "operations.yml", "config/operations.yml"
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,19 @@
1
+ class CreateOperation < ActiveRecord::Migration[5.0]
2
+ def self.up
3
+ create_table :nayati_operations do |t|
4
+ t.string :name
5
+ t.integer :after_success_operation_id
6
+ t.integer :after_failure_operation_id
7
+ t.integer :workflow_id
8
+ t.timestamps
9
+ end
10
+
11
+ add_index :nayati_operations, :workflow_id
12
+ add_index :nayati_operations, :after_failure_operation_id
13
+ add_index :nayati_operations, :after_success_operation_id
14
+ end
15
+
16
+ def self.down
17
+ drop_table :workflows
18
+ end
19
+ end
@@ -0,0 +1,16 @@
1
+ class CreateWorkflow < ActiveRecord::Migration[5.0]
2
+ def self.up
3
+ create_table :nayati_workflows do |t|
4
+ t.string :name
5
+ t.integer :initial_operation_id
6
+ t.string :identifier
7
+ t.timestamps
8
+ end
9
+
10
+ add_index :nayati_workflows, :identifier
11
+ end
12
+
13
+ def self.down
14
+ drop_table :nayati_workflows
15
+ end
16
+ end
@@ -0,0 +1,3 @@
1
+ # This file should have the all the operations used in your application
2
+ # Make an entry in this file to add a workflow or operation. You can also use
3
+ # operationsg generator to create the entries along with implementer class
@@ -0,0 +1,46 @@
1
+ require 'rails/generators'
2
+ require 'pry'
3
+ module Nayati
4
+ module Generators
5
+ class OperationGenerator < Rails::Generators::Base
6
+
7
+
8
+ source_root File.expand_path('../templates', __FILE__)
9
+ desc "generate a operation"
10
+
11
+ def check_installation
12
+ raise 'Run rails generate nayati:install first' unless File.exists?("#{Rails.root}/config/operations.yml")
13
+ end
14
+
15
+ def generate_operation
16
+ raise "Operation and workflow name must be passed" unless args.size == 2
17
+ workflow_name = args.first
18
+ operation_name = args.last
19
+
20
+ workflow_namespace = Nayati::NameBasedConstantable.underscored_name(workflow_name)
21
+ operation_namespace = Nayati::NameBasedConstantable.underscored_name(operation_name)
22
+
23
+ master_worflow = Nayati::MasterWorkflow.new(workflow_name)
24
+ raise 'Please generate workflow first' unless master_worflow.exists?
25
+ # make entry in operations.yml
26
+
27
+ master_operation = Nayati::MasterOperation.new(master_worflow, operation_name)
28
+
29
+ raise 'Operation already exists' if master_operation.exists?
30
+
31
+ master_operation.save
32
+
33
+ # create operation implementer class
34
+ workflow_constant_name = Nayati::NameBasedConstantable.name_as_constant(workflow_namespace)
35
+ operation_constant_name = Nayati::NameBasedConstantable.name_as_constant(operation_namespace)
36
+
37
+ operation_file_path = "#{Rails.root}/app/nayati_operations/#{workflow_namespace}_nayati_workflow/#{operation_namespace}_nayati_operation.rb"
38
+
39
+
40
+ copy_file "operation_template.txt", operation_file_path
41
+ inject_into_file operation_file_path, " #{workflow_constant_name}NayatiWorkflow", after: 'module'
42
+ inject_into_file operation_file_path, "#{operation_constant_name}NayatiOperation ", after: 'class '
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,20 @@
1
+ module
2
+ class < Nayati::OperationImplementerBase
3
+ def initialize(operation_context, result)
4
+ @operation_context = operation_context
5
+ @result = result
6
+ end
7
+
8
+ def to_fail?
9
+ # To be implemented or deleted
10
+ end
11
+
12
+ def perform_failure
13
+ # Please implemented or deleted
14
+ end
15
+
16
+ def perform
17
+ # To be implemented
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ require 'nayati/workflow_runner'
2
+ class
3
+ def initialize()
4
+ end
5
+
6
+ def call
7
+ Nayati::WorkflowRunner.new(workflow, context).run
8
+ end
9
+
10
+ private
11
+ def context
12
+ {
13
+
14
+ }
15
+ end
16
+
17
+ def workflow
18
+ # Find workflow which is supposed to be run
19
+ end
20
+ end
@@ -0,0 +1,39 @@
1
+ require 'rails/generators'
2
+ require 'pry'
3
+ module Nayati
4
+ module Generators
5
+ class WorkflowGenerator < Rails::Generators::Base
6
+
7
+
8
+ source_root File.expand_path('../templates', __FILE__)
9
+ desc "generate a operation"
10
+
11
+ def check_installation
12
+ raise 'Run rails generate nayati:install first' unless File.exists?("#{Rails.root}/config/operations.yml")
13
+ end
14
+
15
+ def generate_workflow
16
+ raise "Workflow name must be passed" unless args.size == 1
17
+ workflow_name = args.first
18
+
19
+ underscored_workflow_name = Nayati::NameBasedConstantable.underscored_name(workflow_name)
20
+
21
+ master_workflow = Nayati::MasterWorkflow.new(underscored_workflow_name)
22
+
23
+ raise 'Workflow already exists' if master_workflow.exists?
24
+
25
+ # make entry in operations.yml
26
+ master_workflow.save!
27
+ workflow_constant_name = Nayati::NameBasedConstantable.name_as_constant(underscored_workflow_name)
28
+
29
+ # Create workflow directory
30
+ FileUtils.mkdir_p("#{Rails.root}/app/nayati_services")
31
+ service_file_path = "#{Rails.root}/app/nayati_services/#{underscored_workflow_name}_nayati_service.rb"
32
+
33
+ copy_file "nayati_service_template.txt", service_file_path
34
+
35
+ inject_into_file service_file_path, " #{workflow_constant_name}NayatiService\n", before: "\n def initialize"
36
+ end
37
+ end
38
+ end
39
+ end
data/lib/nayati.rb ADDED
@@ -0,0 +1,5 @@
1
+ require "nayati/engine"
2
+
3
+ module Nayati
4
+ # Your code goes here...
5
+ end
@@ -0,0 +1,12 @@
1
+ module Nayati
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace Nayati
4
+
5
+ config.generators do |g|
6
+ g.test_framework :rspec, :fixture => false
7
+ g.fixture_replacement :factory_girl, :dir => 'spec/factories'
8
+ g.assets false
9
+ g.helper false
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,3 @@
1
+ module Nayati
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,18 @@
1
+ module Nayati
2
+ module WorkflowResults
3
+ class Base
4
+ def initialize
5
+ @errors = {base: []}.with_indifferent_access
6
+ @data = {}.with_indifferent_access
7
+ end
8
+
9
+ def success?
10
+ !@errors.any?
11
+ end
12
+
13
+ def add_base_error(error_message)
14
+ @errors[:base] << error_message
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,34 @@
1
+ module Nayati
2
+ class WorkflowRunner
3
+ def initialize(workflow, context)
4
+ @workflow = workflow
5
+ @context = context
6
+ @result_obj = workflow.result_obj
7
+ end
8
+
9
+ def run
10
+ operation_to_perform = @workflow.initial_operation
11
+ operations_performed = []
12
+
13
+ while !operation_to_perform.nil? && !operations_performed.include?(operation_to_perform.name) # && safety_count > 0
14
+ operation_klass_instance = operation_to_perform.build_implementer(@context, @result_obj)
15
+ if operation_klass_instance.to_abandon?
16
+ operation_klass_instance.perform_abandonment
17
+ break
18
+ end
19
+
20
+ operations_performed << operation_to_perform.name
21
+
22
+ if operation_klass_instance.to_fail?
23
+ operation_klass_instance.perform_failure
24
+ operation_to_perform = operation_to_perform.after_failure_operation
25
+ else
26
+ operation_klass_instance.perform
27
+ operation_to_perform = operation_to_perform.after_success_operation
28
+ end
29
+ end
30
+
31
+ @result_obj
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,6 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require_relative 'config/application'
5
+
6
+ Rails.application.load_tasks
@@ -0,0 +1,3 @@
1
+ class ApplicationRecord < ActiveRecord::Base
2
+ self.abstract_class = true
3
+ end
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
3
+ load Gem.bin_path('bundler', 'bundle')
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ APP_PATH = File.expand_path('../config/application', __dir__)
3
+ require_relative '../config/boot'
4
+ require 'rails/commands'
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require_relative '../config/boot'
3
+ require 'rake'
4
+ Rake.application.run
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env ruby
2
+ require 'fileutils'
3
+ include FileUtils
4
+
5
+ # path to your application root.
6
+ APP_ROOT = File.expand_path('..', __dir__)
7
+
8
+ def system!(*args)
9
+ system(*args) || abort("\n== Command #{args} failed ==")
10
+ end
11
+
12
+ chdir APP_ROOT do
13
+ # This script is a starting point to setup your application.
14
+ # Add necessary setup steps to this file.
15
+
16
+ puts '== Installing dependencies =='
17
+ system! 'gem install bundler --conservative'
18
+ system('bundle check') || system!('bundle install')
19
+
20
+ # Install JavaScript dependencies if using Yarn
21
+ # system('bin/yarn')
22
+
23
+ # puts "\n== Copying sample files =="
24
+ # unless File.exist?('config/database.yml')
25
+ # cp 'config/database.yml.sample', 'config/database.yml'
26
+ # end
27
+
28
+ puts "\n== Preparing database =="
29
+ system! 'bin/rails db:setup'
30
+
31
+ puts "\n== Removing old logs and tempfiles =="
32
+ system! 'bin/rails log:clear tmp:clear'
33
+
34
+ puts "\n== Restarting application server =="
35
+ system! 'bin/rails restart'
36
+ end
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env ruby
2
+ require 'fileutils'
3
+ include FileUtils
4
+
5
+ # path to your application root.
6
+ APP_ROOT = File.expand_path('..', __dir__)
7
+
8
+ def system!(*args)
9
+ system(*args) || abort("\n== Command #{args} failed ==")
10
+ end
11
+
12
+ chdir APP_ROOT do
13
+ # This script is a way to update your development environment automatically.
14
+ # Add necessary update steps to this file.
15
+
16
+ puts '== Installing dependencies =='
17
+ system! 'gem install bundler --conservative'
18
+ system('bundle check') || system!('bundle install')
19
+
20
+ # Install JavaScript dependencies if using Yarn
21
+ # system('bin/yarn')
22
+
23
+ puts "\n== Updating database =="
24
+ system! 'bin/rails db:migrate'
25
+
26
+ puts "\n== Removing old logs and tempfiles =="
27
+ system! 'bin/rails log:clear tmp:clear'
28
+
29
+ puts "\n== Restarting application server =="
30
+ system! 'bin/rails restart'
31
+ end
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path('..', __dir__)
3
+ Dir.chdir(APP_ROOT) do
4
+ begin
5
+ exec "yarnpkg", *ARGV
6
+ rescue Errno::ENOENT
7
+ $stderr.puts "Yarn executable was not detected in the system."
8
+ $stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install"
9
+ exit 1
10
+ end
11
+ end