rails_ops 1.0.21 → 1.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +16 -0
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/lib/rails_ops/mixins/schema_validation.rb +12 -9
- data/lib/rails_ops/operation.rb +6 -0
- data/rails_ops.gemspec +16 -26
- metadata +5 -5
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: cdab9d5d1726697193bc8d5632e7ade4c57a49c27416018e410b28a8d1c3b783
         | 
| 4 | 
            +
              data.tar.gz: 9259adafa233ebed44044d4cd4ab5078887afda51998e3eb7eff636c0f0daef7
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: c55be3207fd1de748ac2085254b59d2265f60c412bb1d53b613b442aa513c6f5fdf714c90b3558b344483518cb9b749544927297b0f1f986bfbff431085d8ecc
         | 
| 7 | 
            +
              data.tar.gz: a1b915c512f18e2c439339673b57c7bbb695db578826de6d22434c06d67687d2c45a8a11fc7a83a90d53278dd0658e4cd271217bdcd2f17fedab0a78d2ce63ae
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,5 +1,21 @@ | |
| 1 1 | 
             
            # Change log
         | 
| 2 2 |  | 
| 3 | 
            +
            ## 1.1.0 (2020-02-25)
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            * **Breaking changes**:
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              * Schema validations defined with `schema` are now always run **on operation
         | 
| 8 | 
            +
                instantiation** and not, as before, at time of `before_perform`.
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              * The argument `policy_chain` for the static operation method `schema` is now
         | 
| 11 | 
            +
                removed.
         | 
| 12 | 
            +
             | 
| 13 | 
            +
              * Schema validation now overrides the `params` hash with the return value from
         | 
| 14 | 
            +
                Schemacop. This means that Schemacop defaults and casts now can be used for
         | 
| 15 | 
            +
                operation params (with both `params` and `osparams` methods).
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              * RailsOps now requires `schemacop ~> 2.4.2`.
         | 
| 18 | 
            +
             | 
| 3 19 | 
             
            ## 1.0.21 (2020-02-13)
         | 
| 4 20 |  | 
| 5 21 | 
             
            * Exclude param named `format` from `op_params`.
         | 
    
        data/Rakefile
    CHANGED
    
    | @@ -23,7 +23,7 @@ task :gemspec do | |
| 23 23 | 
             
                spec.add_dependency 'minitest'
         | 
| 24 24 | 
             
                spec.add_dependency 'rails'
         | 
| 25 25 | 
             
                spec.add_dependency 'request_store'
         | 
| 26 | 
            -
                spec.add_dependency 'schemacop', '~> 2. | 
| 26 | 
            +
                spec.add_dependency 'schemacop', '~> 2.4.2'
         | 
| 27 27 | 
             
              end
         | 
| 28 28 |  | 
| 29 29 | 
             
              File.open('rails_ops.gemspec', 'w') { |f| f.write(gemspec.to_ruby.strip) }
         | 
    
        data/VERSION
    CHANGED
    
    | @@ -1 +1 @@ | |
| 1 | 
            -
            1.0 | 
| 1 | 
            +
            1.1.0
         | 
| @@ -4,22 +4,25 @@ | |
| 4 4 | 
             
            module RailsOps::Mixins::SchemaValidation
         | 
| 5 5 | 
             
              extend ActiveSupport::Concern
         | 
| 6 6 |  | 
| 7 | 
            +
              included do
         | 
| 8 | 
            +
                class_attribute :_op_schema
         | 
| 9 | 
            +
                self._op_schema = nil
         | 
| 10 | 
            +
              end
         | 
| 11 | 
            +
             | 
| 7 12 | 
             
              module ClassMethods
         | 
| 8 13 | 
             
                # Creates a policy to validate the params hash against the given schema. See
         | 
| 9 14 | 
             
                # {Schemacop::Validator} for more information on how schemas are built.
         | 
| 10 15 | 
             
                #
         | 
| 11 | 
            -
                #  | 
| 12 | 
            -
                #  | 
| 16 | 
            +
                # Schemas are always validated on instantiation and, using defaults and
         | 
| 17 | 
            +
                # casts, can also alter the params hash assigned to the operation.
         | 
| 18 | 
            +
                #
         | 
| 19 | 
            +
                # Only one schema can be active at a time. Defining multiple schemata or
         | 
| 20 | 
            +
                # defining schemas in a subclass always override previously defined schemas.
         | 
| 13 21 | 
             
                #
         | 
| 14 22 | 
             
                # @param *args [Array] Parameters to pass at schema initialization
         | 
| 15 | 
            -
                # @param policy_chain [Symbol] The policy chain to perform the schema validation in
         | 
| 16 23 | 
             
                # @yield Block to pass at schema initialization
         | 
| 17 | 
            -
                def schema(*args,  | 
| 18 | 
            -
                   | 
| 19 | 
            -
             | 
| 20 | 
            -
                  policy policy_chain do
         | 
| 21 | 
            -
                    full_schema.validate!(params)
         | 
| 22 | 
            -
                  end
         | 
| 24 | 
            +
                def schema(*args, &block)
         | 
| 25 | 
            +
                  self._op_schema = Schemacop::Schema.new(*args, &block)
         | 
| 23 26 | 
             
                end
         | 
| 24 27 | 
             
              end
         | 
| 25 28 | 
             
            end
         | 
    
        data/lib/rails_ops/operation.rb
    CHANGED
    
    
    
        data/rails_ops.gemspec
    CHANGED
    
    | @@ -1,43 +1,33 @@ | |
| 1 1 | 
             
            # -*- encoding: utf-8 -*-
         | 
| 2 | 
            -
            # stub: rails_ops 1.0 | 
| 2 | 
            +
            # stub: rails_ops 1.1.0 ruby lib
         | 
| 3 3 |  | 
| 4 4 | 
             
            Gem::Specification.new do |s|
         | 
| 5 5 | 
             
              s.name = "rails_ops".freeze
         | 
| 6 | 
            -
              s.version = "1.0 | 
| 6 | 
            +
              s.version = "1.1.0"
         | 
| 7 7 |  | 
| 8 8 | 
             
              s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
         | 
| 9 9 | 
             
              s.require_paths = ["lib".freeze]
         | 
| 10 10 | 
             
              s.authors = ["Sitrox".freeze]
         | 
| 11 | 
            -
              s.date = "2020-02- | 
| 11 | 
            +
              s.date = "2020-02-25"
         | 
| 12 12 | 
             
              s.files = [".gitignore".freeze, ".releaser_config".freeze, ".rubocop.yml".freeze, ".travis.yml".freeze, "CHANGELOG.md".freeze, "Gemfile".freeze, "LICENSE.txt".freeze, "README.md".freeze, "Rakefile".freeze, "VERSION".freeze, "lib/rails_ops.rb".freeze, "lib/rails_ops/authorization_backend/abstract.rb".freeze, "lib/rails_ops/authorization_backend/can_can_can.rb".freeze, "lib/rails_ops/configuration.rb".freeze, "lib/rails_ops/context.rb".freeze, "lib/rails_ops/controller_mixin.rb".freeze, "lib/rails_ops/exceptions.rb".freeze, "lib/rails_ops/hooked_job.rb".freeze, "lib/rails_ops/hookup.rb".freeze, "lib/rails_ops/hookup/dsl.rb".freeze, "lib/rails_ops/hookup/dsl_validator.rb".freeze, "lib/rails_ops/hookup/hook.rb".freeze, "lib/rails_ops/log_subscriber.rb".freeze, "lib/rails_ops/mixins.rb".freeze, "lib/rails_ops/mixins/authorization.rb".freeze, "lib/rails_ops/mixins/log_settings.rb".freeze, "lib/rails_ops/mixins/model.rb".freeze, "lib/rails_ops/mixins/model/authorization.rb".freeze, "lib/rails_ops/mixins/model/nesting.rb".freeze, "lib/rails_ops/mixins/param_authorization.rb".freeze, "lib/rails_ops/mixins/policies.rb".freeze, "lib/rails_ops/mixins/require_context.rb".freeze, "lib/rails_ops/mixins/routes.rb".freeze, "lib/rails_ops/mixins/schema_validation.rb".freeze, "lib/rails_ops/mixins/sub_ops.rb".freeze, "lib/rails_ops/model_casting.rb".freeze, "lib/rails_ops/model_mixins.rb".freeze, "lib/rails_ops/model_mixins/ar_extension.rb".freeze, "lib/rails_ops/model_mixins/parent_op.rb".freeze, "lib/rails_ops/model_mixins/virtual_attributes.rb".freeze, "lib/rails_ops/model_mixins/virtual_attributes/virtual_column_wrapper.rb".freeze, "lib/rails_ops/model_mixins/virtual_has_one.rb".freeze, "lib/rails_ops/model_mixins/virtual_model_name.rb".freeze, "lib/rails_ops/operation.rb".freeze, "lib/rails_ops/operation/model.rb".freeze, "lib/rails_ops/operation/model/create.rb".freeze, "lib/rails_ops/operation/model/destroy.rb".freeze, "lib/rails_ops/operation/model/load.rb".freeze, "lib/rails_ops/operation/model/update.rb".freeze, "lib/rails_ops/patches/active_type_patch.rb".freeze, "lib/rails_ops/profiler.rb".freeze, "lib/rails_ops/profiler/node.rb".freeze, "lib/rails_ops/railtie.rb".freeze, "lib/rails_ops/scoped_env.rb".freeze, "lib/rails_ops/virtual_model.rb".freeze, "rails_ops.gemspec".freeze, "test/db/models.rb".freeze, "test/db/schema.rb".freeze, "test/dummy/Rakefile".freeze, "test/dummy/app/assets/config/manifest.js".freeze, "test/dummy/app/assets/images/.keep".freeze, "test/dummy/app/assets/javascripts/application.js".freeze, "test/dummy/app/assets/javascripts/cable.js".freeze, "test/dummy/app/assets/javascripts/channels/.keep".freeze, "test/dummy/app/assets/stylesheets/application.css".freeze, "test/dummy/app/channels/application_cable/channel.rb".freeze, "test/dummy/app/channels/application_cable/connection.rb".freeze, "test/dummy/app/controllers/application_controller.rb".freeze, "test/dummy/app/controllers/concerns/.keep".freeze, "test/dummy/app/helpers/application_helper.rb".freeze, "test/dummy/app/jobs/application_job.rb".freeze, "test/dummy/app/mailers/application_mailer.rb".freeze, "test/dummy/app/models/application_record.rb".freeze, "test/dummy/app/models/concerns/.keep".freeze, "test/dummy/app/models/group.rb".freeze, "test/dummy/app/views/layouts/application.html.erb".freeze, "test/dummy/app/views/layouts/mailer.html.erb".freeze, "test/dummy/app/views/layouts/mailer.text.erb".freeze, "test/dummy/bin/bundle".freeze, "test/dummy/bin/rails".freeze, "test/dummy/bin/rake".freeze, "test/dummy/bin/setup".freeze, "test/dummy/bin/update".freeze, "test/dummy/bin/yarn".freeze, "test/dummy/config.ru".freeze, "test/dummy/config/application.rb".freeze, "test/dummy/config/boot.rb".freeze, "test/dummy/config/cable.yml".freeze, "test/dummy/config/database.yml".freeze, "test/dummy/config/environment.rb".freeze, "test/dummy/config/environments/development.rb".freeze, "test/dummy/config/environments/production.rb".freeze, "test/dummy/config/environments/test.rb".freeze, "test/dummy/config/initializers/application_controller_renderer.rb".freeze, "test/dummy/config/initializers/assets.rb".freeze, "test/dummy/config/initializers/backtrace_silencers.rb".freeze, "test/dummy/config/initializers/cookies_serializer.rb".freeze, "test/dummy/config/initializers/filter_parameter_logging.rb".freeze, "test/dummy/config/initializers/inflections.rb".freeze, "test/dummy/config/initializers/mime_types.rb".freeze, "test/dummy/config/initializers/rails_ops.rb".freeze, "test/dummy/config/initializers/wrap_parameters.rb".freeze, "test/dummy/config/locales/en.yml".freeze, "test/dummy/config/puma.rb".freeze, "test/dummy/config/routes.rb".freeze, "test/dummy/config/secrets.yml".freeze, "test/dummy/config/spring.rb".freeze, "test/dummy/db/schema.rb".freeze, "test/dummy/lib/assets/.keep".freeze, "test/dummy/log/.keep".freeze, "test/dummy/package.json".freeze, "test/dummy/public/404.html".freeze, "test/dummy/public/422.html".freeze, "test/dummy/public/500.html".freeze, "test/dummy/public/apple-touch-icon-precomposed.png".freeze, "test/dummy/public/apple-touch-icon.png".freeze, "test/dummy/public/favicon.ico".freeze, "test/dummy/tmp/.keep".freeze, "test/test_helper.rb".freeze, "test/unit/rails_ops/mixins/model/nesting.rb".freeze, "test/unit/rails_ops/mixins/policies_test.rb".freeze, "test/unit/rails_ops/operation/model/create_test.rb".freeze, "test/unit/rails_ops/operation/model/load_test.rb".freeze, "test/unit/rails_ops/operation/model/update_test.rb".freeze, "test/unit/rails_ops/operation/model_test.rb".freeze, "test/unit/rails_ops/operation_test.rb".freeze]
         | 
| 13 | 
            -
              s.rubygems_version = "3. | 
| 13 | 
            +
              s.rubygems_version = "3.1.2".freeze
         | 
| 14 14 | 
             
              s.summary = "An operations service layer for rails projects.".freeze
         | 
| 15 15 | 
             
              s.test_files = ["test/db/models.rb".freeze, "test/db/schema.rb".freeze, "test/dummy/Rakefile".freeze, "test/dummy/app/assets/config/manifest.js".freeze, "test/dummy/app/assets/images/.keep".freeze, "test/dummy/app/assets/javascripts/application.js".freeze, "test/dummy/app/assets/javascripts/cable.js".freeze, "test/dummy/app/assets/javascripts/channels/.keep".freeze, "test/dummy/app/assets/stylesheets/application.css".freeze, "test/dummy/app/channels/application_cable/channel.rb".freeze, "test/dummy/app/channels/application_cable/connection.rb".freeze, "test/dummy/app/controllers/application_controller.rb".freeze, "test/dummy/app/controllers/concerns/.keep".freeze, "test/dummy/app/helpers/application_helper.rb".freeze, "test/dummy/app/jobs/application_job.rb".freeze, "test/dummy/app/mailers/application_mailer.rb".freeze, "test/dummy/app/models/application_record.rb".freeze, "test/dummy/app/models/concerns/.keep".freeze, "test/dummy/app/models/group.rb".freeze, "test/dummy/app/views/layouts/application.html.erb".freeze, "test/dummy/app/views/layouts/mailer.html.erb".freeze, "test/dummy/app/views/layouts/mailer.text.erb".freeze, "test/dummy/bin/bundle".freeze, "test/dummy/bin/rails".freeze, "test/dummy/bin/rake".freeze, "test/dummy/bin/setup".freeze, "test/dummy/bin/update".freeze, "test/dummy/bin/yarn".freeze, "test/dummy/config.ru".freeze, "test/dummy/config/application.rb".freeze, "test/dummy/config/boot.rb".freeze, "test/dummy/config/cable.yml".freeze, "test/dummy/config/database.yml".freeze, "test/dummy/config/environment.rb".freeze, "test/dummy/config/environments/development.rb".freeze, "test/dummy/config/environments/production.rb".freeze, "test/dummy/config/environments/test.rb".freeze, "test/dummy/config/initializers/application_controller_renderer.rb".freeze, "test/dummy/config/initializers/assets.rb".freeze, "test/dummy/config/initializers/backtrace_silencers.rb".freeze, "test/dummy/config/initializers/cookies_serializer.rb".freeze, "test/dummy/config/initializers/filter_parameter_logging.rb".freeze, "test/dummy/config/initializers/inflections.rb".freeze, "test/dummy/config/initializers/mime_types.rb".freeze, "test/dummy/config/initializers/rails_ops.rb".freeze, "test/dummy/config/initializers/wrap_parameters.rb".freeze, "test/dummy/config/locales/en.yml".freeze, "test/dummy/config/puma.rb".freeze, "test/dummy/config/routes.rb".freeze, "test/dummy/config/secrets.yml".freeze, "test/dummy/config/spring.rb".freeze, "test/dummy/db/schema.rb".freeze, "test/dummy/lib/assets/.keep".freeze, "test/dummy/log/.keep".freeze, "test/dummy/package.json".freeze, "test/dummy/public/404.html".freeze, "test/dummy/public/422.html".freeze, "test/dummy/public/500.html".freeze, "test/dummy/public/apple-touch-icon-precomposed.png".freeze, "test/dummy/public/apple-touch-icon.png".freeze, "test/dummy/public/favicon.ico".freeze, "test/dummy/tmp/.keep".freeze, "test/test_helper.rb".freeze, "test/unit/rails_ops/mixins/model/nesting.rb".freeze, "test/unit/rails_ops/mixins/policies_test.rb".freeze, "test/unit/rails_ops/operation/model/create_test.rb".freeze, "test/unit/rails_ops/operation/model/load_test.rb".freeze, "test/unit/rails_ops/operation/model/update_test.rb".freeze, "test/unit/rails_ops/operation/model_test.rb".freeze, "test/unit/rails_ops/operation_test.rb".freeze]
         | 
| 16 16 |  | 
| 17 17 | 
             
              if s.respond_to? :specification_version then
         | 
| 18 18 | 
             
                s.specification_version = 4
         | 
| 19 | 
            +
              end
         | 
| 19 20 |  | 
| 20 | 
            -
             | 
| 21 | 
            -
             | 
| 22 | 
            -
             | 
| 23 | 
            -
             | 
| 24 | 
            -
             | 
| 25 | 
            -
             | 
| 26 | 
            -
             | 
| 27 | 
            -
             | 
| 28 | 
            -
             | 
| 29 | 
            -
             | 
| 30 | 
            -
                else
         | 
| 31 | 
            -
                  s.add_dependency(%q<bundler>.freeze, [">= 0"])
         | 
| 32 | 
            -
                  s.add_dependency(%q<rake>.freeze, [">= 0"])
         | 
| 33 | 
            -
                  s.add_dependency(%q<sqlite3>.freeze, [">= 0"])
         | 
| 34 | 
            -
                  s.add_dependency(%q<rubocop>.freeze, ["= 0.47.1"])
         | 
| 35 | 
            -
                  s.add_dependency(%q<active_type>.freeze, ["~> 0.7.1"])
         | 
| 36 | 
            -
                  s.add_dependency(%q<minitest>.freeze, [">= 0"])
         | 
| 37 | 
            -
                  s.add_dependency(%q<rails>.freeze, [">= 0"])
         | 
| 38 | 
            -
                  s.add_dependency(%q<request_store>.freeze, [">= 0"])
         | 
| 39 | 
            -
                  s.add_dependency(%q<schemacop>.freeze, ["~> 2.0"])
         | 
| 40 | 
            -
                end
         | 
| 21 | 
            +
              if s.respond_to? :add_runtime_dependency then
         | 
| 22 | 
            +
                s.add_development_dependency(%q<bundler>.freeze, [">= 0"])
         | 
| 23 | 
            +
                s.add_development_dependency(%q<rake>.freeze, [">= 0"])
         | 
| 24 | 
            +
                s.add_development_dependency(%q<sqlite3>.freeze, [">= 0"])
         | 
| 25 | 
            +
                s.add_development_dependency(%q<rubocop>.freeze, ["= 0.47.1"])
         | 
| 26 | 
            +
                s.add_runtime_dependency(%q<active_type>.freeze, ["~> 0.7.1"])
         | 
| 27 | 
            +
                s.add_runtime_dependency(%q<minitest>.freeze, [">= 0"])
         | 
| 28 | 
            +
                s.add_runtime_dependency(%q<rails>.freeze, [">= 0"])
         | 
| 29 | 
            +
                s.add_runtime_dependency(%q<request_store>.freeze, [">= 0"])
         | 
| 30 | 
            +
                s.add_runtime_dependency(%q<schemacop>.freeze, ["~> 2.4.2"])
         | 
| 41 31 | 
             
              else
         | 
| 42 32 | 
             
                s.add_dependency(%q<bundler>.freeze, [">= 0"])
         | 
| 43 33 | 
             
                s.add_dependency(%q<rake>.freeze, [">= 0"])
         | 
| @@ -47,6 +37,6 @@ Gem::Specification.new do |s| | |
| 47 37 | 
             
                s.add_dependency(%q<minitest>.freeze, [">= 0"])
         | 
| 48 38 | 
             
                s.add_dependency(%q<rails>.freeze, [">= 0"])
         | 
| 49 39 | 
             
                s.add_dependency(%q<request_store>.freeze, [">= 0"])
         | 
| 50 | 
            -
                s.add_dependency(%q<schemacop>.freeze, ["~> 2. | 
| 40 | 
            +
                s.add_dependency(%q<schemacop>.freeze, ["~> 2.4.2"])
         | 
| 51 41 | 
             
              end
         | 
| 52 42 | 
             
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: rails_ops
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 1.0 | 
| 4 | 
            +
              version: 1.1.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Sitrox
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2020-02- | 
| 11 | 
            +
            date: 2020-02-25 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: bundler
         | 
| @@ -128,14 +128,14 @@ dependencies: | |
| 128 128 | 
             
                requirements:
         | 
| 129 129 | 
             
                - - "~>"
         | 
| 130 130 | 
             
                  - !ruby/object:Gem::Version
         | 
| 131 | 
            -
                    version:  | 
| 131 | 
            +
                    version: 2.4.2
         | 
| 132 132 | 
             
              type: :runtime
         | 
| 133 133 | 
             
              prerelease: false
         | 
| 134 134 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 135 135 | 
             
                requirements:
         | 
| 136 136 | 
             
                - - "~>"
         | 
| 137 137 | 
             
                  - !ruby/object:Gem::Version
         | 
| 138 | 
            -
                    version:  | 
| 138 | 
            +
                    version: 2.4.2
         | 
| 139 139 | 
             
            description: 
         | 
| 140 140 | 
             
            email: 
         | 
| 141 141 | 
             
            executables: []
         | 
| @@ -286,7 +286,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 286 286 | 
             
                - !ruby/object:Gem::Version
         | 
| 287 287 | 
             
                  version: '0'
         | 
| 288 288 | 
             
            requirements: []
         | 
| 289 | 
            -
            rubygems_version: 3. | 
| 289 | 
            +
            rubygems_version: 3.1.2
         | 
| 290 290 | 
             
            signing_key: 
         | 
| 291 291 | 
             
            specification_version: 4
         | 
| 292 292 | 
             
            summary: An operations service layer for rails projects.
         |