api_engine_base 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +28 -0
- data/Rakefile +32 -0
- data/app/controllers/api_engine_base/application_controller.rb +47 -0
- data/app/controllers/api_engine_base/auth/plain_text_controller.rb +132 -0
- data/app/controllers/api_engine_base/username_controller.rb +26 -0
- data/app/controllers/concerns/api_engine_base/schematizable.rb +5 -0
- data/app/helpers/api_engine_base/application_helper.rb +4 -0
- data/app/helpers/api_engine_base/schema_helper.rb +29 -0
- data/app/jobs/api_engine_base/application_job.rb +4 -0
- data/app/mailers/api_engine_base/application_mailer.rb +8 -0
- data/app/mailers/api_engine_base/email_verification_mailer.rb +12 -0
- data/app/models/api_engine_base/application_record.rb +7 -0
- data/app/models/user.rb +50 -0
- data/app/models/user_secret.rb +72 -0
- data/app/services/api_engine_base/argument_validation/class_methods.rb +179 -0
- data/app/services/api_engine_base/argument_validation/instance_methods.rb +136 -0
- data/app/services/api_engine_base/argument_validation.rb +11 -0
- data/app/services/api_engine_base/jwt/authenticate_user.rb +71 -0
- data/app/services/api_engine_base/jwt/decode.rb +21 -0
- data/app/services/api_engine_base/jwt/encode.rb +15 -0
- data/app/services/api_engine_base/jwt/login_create.rb +21 -0
- data/app/services/api_engine_base/jwt/time_delay_token.rb +17 -0
- data/app/services/api_engine_base/login_strategy/plain_text/create.rb +42 -0
- data/app/services/api_engine_base/login_strategy/plain_text/email_verification/generate.rb +29 -0
- data/app/services/api_engine_base/login_strategy/plain_text/email_verification/required.rb +20 -0
- data/app/services/api_engine_base/login_strategy/plain_text/email_verification/send.rb +23 -0
- data/app/services/api_engine_base/login_strategy/plain_text/email_verification/verify.rb +24 -0
- data/app/services/api_engine_base/login_strategy/plain_text/login.rb +50 -0
- data/app/services/api_engine_base/secrets/cleanse.rb +14 -0
- data/app/services/api_engine_base/secrets/generate.rb +62 -0
- data/app/services/api_engine_base/secrets/verify.rb +27 -0
- data/app/services/api_engine_base/secrets.rb +15 -0
- data/app/services/api_engine_base/service_base.rb +90 -0
- data/app/services/api_engine_base/service_logging.rb +41 -0
- data/app/services/api_engine_base/username/available.rb +64 -0
- data/app/views/api_engine_base/email_verification_mailer/verify_email.html.erb +26 -0
- data/config/routes.rb +23 -0
- data/db/migrate/20241117043720_create_api_engine_base_users.rb +33 -0
- data/db/migrate/20241204065708_create_api_engine_base_user_secrets.rb +16 -0
- data/lib/api_engine_base/configuration/application/config.rb +40 -0
- data/lib/api_engine_base/configuration/base.rb +11 -0
- data/lib/api_engine_base/configuration/config.rb +59 -0
- data/lib/api_engine_base/configuration/email/config.rb +87 -0
- data/lib/api_engine_base/configuration/jwt/config.rb +22 -0
- data/lib/api_engine_base/configuration/login/config.rb +18 -0
- data/lib/api_engine_base/configuration/login/strategy/plain_text/config.rb +57 -0
- data/lib/api_engine_base/configuration/login/strategy/plain_text/email_verify.rb +50 -0
- data/lib/api_engine_base/configuration/login/strategy/plain_text/lockable.rb +27 -0
- data/lib/api_engine_base/configuration/otp/config.rb +54 -0
- data/lib/api_engine_base/configuration/username/check.rb +31 -0
- data/lib/api_engine_base/configuration/username/config.rb +41 -0
- data/lib/api_engine_base/engine.rb +21 -0
- data/lib/api_engine_base/schema/error/base.rb +15 -0
- data/lib/api_engine_base/schema/error/invalid_argument.rb +15 -0
- data/lib/api_engine_base/schema/error/invalid_argument_response.rb +17 -0
- data/lib/api_engine_base/schema/plain_text/create_user_request.rb +18 -0
- data/lib/api_engine_base/schema/plain_text/create_user_response.rb +17 -0
- data/lib/api_engine_base/schema/plain_text/email_verify_request.rb +11 -0
- data/lib/api_engine_base/schema/plain_text/email_verify_response.rb +11 -0
- data/lib/api_engine_base/schema/plain_text/email_verify_send_request.rb +9 -0
- data/lib/api_engine_base/schema/plain_text/email_verify_send_response.rb +11 -0
- data/lib/api_engine_base/schema/plain_text/login_request.rb +15 -0
- data/lib/api_engine_base/schema/plain_text/login_response.rb +13 -0
- data/lib/api_engine_base/schema.rb +25 -0
- data/lib/api_engine_base/spec_helper.rb +18 -0
- data/lib/api_engine_base/version.rb +5 -0
- data/lib/api_engine_base.rb +33 -0
- data/lib/generators/api_engine_base/configure/USAGE +8 -0
- data/lib/generators/api_engine_base/configure/configure_generator.rb +12 -0
- data/lib/tasks/auto_annotate_models.rake +60 -0
- metadata +216 -0
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "class_composer"
|
4
|
+
|
5
|
+
module ApiEngineBase
|
6
|
+
module Configuration
|
7
|
+
module Otp
|
8
|
+
class Config
|
9
|
+
include ClassComposer::Generator
|
10
|
+
|
11
|
+
add_composer :default_code_interval,
|
12
|
+
desc: "The length of time a code is good for",
|
13
|
+
allowed: ActiveSupport::Duration,
|
14
|
+
default: 30.seconds,
|
15
|
+
validator: -> (val) { (val <= 5.minutes) && (val >= 30.seconds) }
|
16
|
+
|
17
|
+
add_composer :default_code_length,
|
18
|
+
desc: "The default length of the OTP. Used when one not provided",
|
19
|
+
allowed: Integer,
|
20
|
+
default: 6,
|
21
|
+
validator: -> (val) { (val <= 10) && (val >= 4) },
|
22
|
+
invalid_message: ->(val) { "Provided #{val}. Value must be less than or equal to 10 and greater than or equal to 4." }
|
23
|
+
|
24
|
+
add_composer :secret_code_length,
|
25
|
+
desc: "The size of each users base32 Secret value generated",
|
26
|
+
allowed: Integer,
|
27
|
+
default: 32,
|
28
|
+
validator: -> (val) { (val <= 128) && (val >= 32) },
|
29
|
+
invalid_message: ->(val) { "Provided #{val}. Value must be less than or equal to 128 and greater than or equal to 32." }
|
30
|
+
|
31
|
+
add_composer :backup_code_length,
|
32
|
+
desc: "The length of each backup code for User",
|
33
|
+
allowed: Integer,
|
34
|
+
default: 32,
|
35
|
+
validator: -> (val) { (val <= 64) && (val >= 10) },
|
36
|
+
invalid_message: ->(val) { "Provided #{val}. Value must be less than or equal to 64 and greater than or equal to 20." }
|
37
|
+
|
38
|
+
add_composer :backup_code_count,
|
39
|
+
desc: "The number of backup codes that get generated",
|
40
|
+
allowed: Integer,
|
41
|
+
default: 10,
|
42
|
+
validator: -> (val) { (val <= 10) && (val >= 2) },
|
43
|
+
invalid_message: ->(val) { "Provided #{val}. Value must be less than or equal to 10 and greater than or equal to 2." }
|
44
|
+
|
45
|
+
add_composer :allowed_drift_behind,
|
46
|
+
desc: "Sometimes a user is just a tad slow. This allows a small drift behind to allow codes within drift to be accepted",
|
47
|
+
allowed: ActiveSupport::Duration,
|
48
|
+
default: 15.seconds,
|
49
|
+
validator: -> (val) { (val <= 15.seconds) && (val >= 0.seconds) },
|
50
|
+
invalid_message: ->(val) { "Provided #{val}. Value must be less than or equal to 15.seconds" }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "class_composer"
|
4
|
+
|
5
|
+
module ApiEngineBase
|
6
|
+
module Configuration
|
7
|
+
module Username
|
8
|
+
class Check
|
9
|
+
include ClassComposer::Generator
|
10
|
+
|
11
|
+
add_composer :enable,
|
12
|
+
desc: "Enable Controller method for checking Real time username availability",
|
13
|
+
allowed: [FalseClass, TrueClass],
|
14
|
+
default: true
|
15
|
+
|
16
|
+
add_composer :local_cache,
|
17
|
+
desc: "Local Cache store. Instantiated before fork",
|
18
|
+
allowed: [ActiveSupport::Cache::MemoryStore, ActiveSupport::Cache::FileStore],
|
19
|
+
default: ActiveSupport::Cache::MemoryStore.new
|
20
|
+
|
21
|
+
add_composer :local_cache_ttl,
|
22
|
+
desc: "TTL on local cache data before data is invalidated and upstream is queried",
|
23
|
+
allowed: ActiveSupport::Duration,
|
24
|
+
default_shown: "1.minutes",
|
25
|
+
default: 1.minute,
|
26
|
+
validator: -> (val) { val < 60.minutes },
|
27
|
+
invalid_message: ->(val) { "Provided #{val}. Value must be less than #{60.minutes}" }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "class_composer"
|
4
|
+
require "api_engine_base/configuration/username/check"
|
5
|
+
|
6
|
+
module ApiEngineBase::Configuration
|
7
|
+
module Username
|
8
|
+
class Config
|
9
|
+
include ClassComposer::Generator
|
10
|
+
|
11
|
+
DEFAULT_MAX_LENGTH = 32
|
12
|
+
DEFAULT_MIN_LENGTH = 4
|
13
|
+
|
14
|
+
add_composer_blocking :realtime_username_check,
|
15
|
+
desc: "Adds components to check if the username is available in real time",
|
16
|
+
composer_class: Check,
|
17
|
+
enable_attr: :enable
|
18
|
+
|
19
|
+
add_composer :username_length_min,
|
20
|
+
desc: "Min Length for Username",
|
21
|
+
allowed: Integer,
|
22
|
+
default: DEFAULT_MIN_LENGTH
|
23
|
+
|
24
|
+
add_composer :username_length_max,
|
25
|
+
desc: "Max Length for Username",
|
26
|
+
allowed: Integer,
|
27
|
+
default: DEFAULT_MAX_LENGTH
|
28
|
+
|
29
|
+
add_composer :username_regex,
|
30
|
+
desc: "Regex for username.",
|
31
|
+
allowed: Regexp,
|
32
|
+
default: /\A\w{#{DEFAULT_MIN_LENGTH},#{DEFAULT_MAX_LENGTH}}\z/,
|
33
|
+
default_shown: "Regexp.new(\"/\A\w{#{DEFAULT_MIN_LENGTH},#{DEFAULT_MAX_LENGTH}}\z/\")"
|
34
|
+
|
35
|
+
add_composer :username_failure_message,
|
36
|
+
desc: "Max Length for Username",
|
37
|
+
allowed: String,
|
38
|
+
default: "Username length must be between #{DEFAULT_MIN_LENGTH} and #{DEFAULT_MAX_LENGTH}. Must contain only letters and/or numbers"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "api_engine_base/schema"
|
4
|
+
|
5
|
+
module ApiEngineBase
|
6
|
+
class Engine < ::Rails::Engine
|
7
|
+
isolate_namespace ApiEngineBase
|
8
|
+
|
9
|
+
# Run after Rails loads the initializes and environment files
|
10
|
+
# Ensures User has already set their desired config before we lock this down
|
11
|
+
initializer "api_engine_base.config.instantiate", after: :load_config_initializers do |_app|
|
12
|
+
# ensure defaults are instantiated and all variables are assigned
|
13
|
+
ApiEngineBase.config.class_composer_assign_defaults!(children: true)
|
14
|
+
|
15
|
+
unless Rails.env.test?
|
16
|
+
# Now that we can confirm all variables are defined, freeze all objects an their children
|
17
|
+
ApiEngineBase.config.class_composer_freeze_objects!(behavior: :raise, children: true)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "json_schematize/generator"
|
4
|
+
|
5
|
+
module ApiEngineBase
|
6
|
+
module Schema
|
7
|
+
module Error
|
8
|
+
class Base < JsonSchematize::Generator
|
9
|
+
add_field name: :status, type: String
|
10
|
+
add_field name: :message, type: String
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ApiEngineBase
|
4
|
+
module Schema
|
5
|
+
module Error
|
6
|
+
class InvalidArgument < JsonSchematize::Generator
|
7
|
+
add_field name: :schema, type: JsonSchematize::Generator, required: true, converter: ->(val) { val }
|
8
|
+
add_field name: :argument, type: String, required: true
|
9
|
+
add_field name: :argument_type, type: String, required: true
|
10
|
+
add_field name: :reason, type: String
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "api_engine_base/schema/error/invalid_argument"
|
4
|
+
|
5
|
+
module ApiEngineBase
|
6
|
+
module Schema
|
7
|
+
module Error
|
8
|
+
class InvalidArgumentResponse < JsonSchematize::Generator
|
9
|
+
add_field name: :message, type: String, required: true
|
10
|
+
add_field name: :status, type: String, required: true
|
11
|
+
add_field name: :invalid_arguments, array_of_types: true, type: InvalidArgument
|
12
|
+
add_field name: :invalid_argument_keys, type: Array
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ApiEngineBase
|
4
|
+
module Schema
|
5
|
+
module PlainText
|
6
|
+
class CreateUserRequest < JsonSchematize::Generator
|
7
|
+
schema_default option: :dig_type, value: :string
|
8
|
+
|
9
|
+
add_field name: :first_name, type: String, required: false
|
10
|
+
add_field name: :last_name, type: String, required: false
|
11
|
+
add_field name: :username, type: String, required: false
|
12
|
+
add_field name: :email, type: String, required: false
|
13
|
+
add_field name: :password, type: String, required: false
|
14
|
+
add_field name: :password_confirmation, type: String, required: false
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ApiEngineBase
|
4
|
+
module Schema
|
5
|
+
module PlainText
|
6
|
+
class CreateUserResponse < JsonSchematize::Generator
|
7
|
+
add_field name: :full_name, type: String
|
8
|
+
add_field name: :first_name, type: String
|
9
|
+
add_field name: :last_name, type: String
|
10
|
+
add_field name: :username, type: String
|
11
|
+
add_field name: :email, type: String
|
12
|
+
add_field name: :msg, type: String
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ApiEngineBase
|
4
|
+
module Schema
|
5
|
+
module PlainText
|
6
|
+
class LoginRequest < JsonSchematize::Generator
|
7
|
+
schema_default option: :dig_type, value: :string
|
8
|
+
|
9
|
+
add_field name: :username, type: String, required: false
|
10
|
+
add_field name: :email, type: String, required: false
|
11
|
+
add_field name: :password, type: String, required: false
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ApiEngineBase
|
4
|
+
module Schema
|
5
|
+
module PlainText
|
6
|
+
class LoginResponse < JsonSchematize::Generator
|
7
|
+
add_field name: :token, type: String
|
8
|
+
add_field name: :header_name, type: String
|
9
|
+
add_field name: :message, type: String
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ApiEngineBase
|
4
|
+
module Schema
|
5
|
+
require "json_schematize"
|
6
|
+
require "json_schematize/generator"
|
7
|
+
|
8
|
+
## Generic Error Schemas
|
9
|
+
require "api_engine_base/schema/error/base"
|
10
|
+
require "api_engine_base/schema/error/invalid_argument_response"
|
11
|
+
|
12
|
+
## Plain Text Controller
|
13
|
+
require "api_engine_base/schema/plain_text/create_user_response"
|
14
|
+
require "api_engine_base/schema/plain_text/create_user_request"
|
15
|
+
|
16
|
+
require "api_engine_base/schema/plain_text/email_verify_request"
|
17
|
+
require "api_engine_base/schema/plain_text/email_verify_response"
|
18
|
+
|
19
|
+
require "api_engine_base/schema/plain_text/email_verify_send_response"
|
20
|
+
require "api_engine_base/schema/plain_text/email_verify_send_request"
|
21
|
+
|
22
|
+
require "api_engine_base/schema/plain_text/login_request"
|
23
|
+
require "api_engine_base/schema/plain_text/login_response"
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ApiEngineBase
|
4
|
+
module SpecHelper
|
5
|
+
def set_jwt_token!(user:, token: nil)
|
6
|
+
if token.nil?
|
7
|
+
result = ApiEngineBase::Jwt::LoginCreate.(user:)
|
8
|
+
token = result.token
|
9
|
+
end
|
10
|
+
|
11
|
+
@request.headers[ApiEngineBase::ApplicationController::AUTHORIZATION_HEADER] = "Bearer: #{token}"
|
12
|
+
end
|
13
|
+
|
14
|
+
def unset_jwt_token!
|
15
|
+
@request.headers[ApiEngineBase::ApplicationController::AUTHORIZATION_HEADER] = nil
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require "api_engine_base/version"
|
2
|
+
require "api_engine_base/engine"
|
3
|
+
require "api_engine_base/configuration/config"
|
4
|
+
|
5
|
+
module ApiEngineBase
|
6
|
+
class Error < StandardError; end
|
7
|
+
|
8
|
+
def self.config
|
9
|
+
@config ||= Configuration::Config.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.configure
|
13
|
+
yield(config)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.config=(configuration)
|
17
|
+
raise ArgumentError, "Expected Configuration::Config. Given #{configuration.class}" unless Configuration::Config === configuration
|
18
|
+
|
19
|
+
@config = configuration
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.app_name
|
23
|
+
Proc === config.app.app_name ? config.app.app_name.() : config.app.app_name
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.app_name_for_comms
|
27
|
+
Proc === config.app.communication_name ? config.app.communication_name.() : config.app.communication_name
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.default_app_name
|
31
|
+
::Rails.application.class.module_parent_name
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class ApiEngineBase::ConfigureGenerator < Rails::Generators::Base
|
2
|
+
source_root File.expand_path("templates", __dir__)
|
3
|
+
|
4
|
+
def create_config_file
|
5
|
+
create_file Rails.root.join("config", "initializers", "api_engine_base.rb"),
|
6
|
+
ApiEngineBase.config.class.composer_generate_config(wrapping: "ApiEngineBase.configure", require_file: "api_engine_base")
|
7
|
+
end
|
8
|
+
|
9
|
+
def create_route
|
10
|
+
route "mount ApiEngineBase::Engine => \"/\""
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# NOTE: only doing this in development as some production environments (Heroku)
|
2
|
+
# NOTE: are sensitive to local FS writes, and besides -- it's just not proper
|
3
|
+
# NOTE: to have a dev-mode tool do its thing in production.
|
4
|
+
|
5
|
+
# if Rails.env.development?
|
6
|
+
require 'annotate'
|
7
|
+
task :set_annotation_options do
|
8
|
+
# You can override any of these by setting an environment variable of the
|
9
|
+
# same name.
|
10
|
+
Annotate.set_defaults(
|
11
|
+
'active_admin' => 'false',
|
12
|
+
'additional_file_patterns' => [],
|
13
|
+
'routes' => 'false',
|
14
|
+
'models' => 'true',
|
15
|
+
'position_in_routes' => 'before',
|
16
|
+
'position_in_class' => 'before',
|
17
|
+
'position_in_test' => 'before',
|
18
|
+
'position_in_fixture' => 'before',
|
19
|
+
'position_in_factory' => 'before',
|
20
|
+
'position_in_serializer' => 'before',
|
21
|
+
'show_foreign_keys' => 'true',
|
22
|
+
'show_complete_foreign_keys' => 'false',
|
23
|
+
'show_indexes' => 'true',
|
24
|
+
'simple_indexes' => 'false',
|
25
|
+
'model_dir' => 'app/models',
|
26
|
+
'root_dir' => '',
|
27
|
+
'include_version' => 'false',
|
28
|
+
'require' => '',
|
29
|
+
'exclude_tests' => 'false',
|
30
|
+
'exclude_fixtures' => 'false',
|
31
|
+
'exclude_factories' => 'false',
|
32
|
+
'exclude_serializers' => 'false',
|
33
|
+
'exclude_scaffolds' => 'true',
|
34
|
+
'exclude_controllers' => 'true',
|
35
|
+
'exclude_helpers' => 'true',
|
36
|
+
'exclude_sti_subclasses' => 'false',
|
37
|
+
'ignore_model_sub_dir' => 'false',
|
38
|
+
'ignore_columns' => nil,
|
39
|
+
'ignore_routes' => nil,
|
40
|
+
'ignore_unknown_models' => 'false',
|
41
|
+
'hide_limit_column_types' => 'integer,bigint,boolean',
|
42
|
+
'hide_default_column_types' => 'json,jsonb,hstore',
|
43
|
+
'skip_on_db_migrate' => 'false',
|
44
|
+
'format_bare' => 'true',
|
45
|
+
'format_rdoc' => 'false',
|
46
|
+
'format_yard' => 'false',
|
47
|
+
'format_markdown' => 'false',
|
48
|
+
'sort' => 'false',
|
49
|
+
'force' => 'false',
|
50
|
+
'frozen' => 'false',
|
51
|
+
'classified_sort' => 'true',
|
52
|
+
'trace' => 'false',
|
53
|
+
'wrapper_open' => nil,
|
54
|
+
'wrapper_close' => nil,
|
55
|
+
'with_comment' => 'true'
|
56
|
+
)
|
57
|
+
end
|
58
|
+
|
59
|
+
Annotate.load_tasks
|
60
|
+
# end
|