qb 0.3.25 → 0.4.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 (113) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/ansible.cfg +10 -1
  4. data/exe/.qb_interop_receive +3 -10
  5. data/exe/qb +8 -2
  6. data/lib/python/qb/__init__.py +6 -0
  7. data/{roles/qb/ruby/rspec/setup/tasks/persistence.yml → lib/python/qb/ansible/__init__.py} +0 -0
  8. data/lib/python/qb/ansible/modules/__init__.py +0 -0
  9. data/lib/python/qb/ansible/modules/docker/__init__.py +0 -0
  10. data/lib/python/qb/ansible/modules/docker/client.py +177 -0
  11. data/lib/python/qb/ansible/modules/docker/image_manager.py +754 -0
  12. data/lib/python/qb/ipc/__init__.py +0 -0
  13. data/lib/python/qb/ipc/stdio/__init__.py +99 -0
  14. data/lib/python/qb/ipc/stdio/logging.py +151 -0
  15. data/lib/qb.rb +3 -3
  16. data/lib/qb/ansible/cmds/playbook.rb +5 -14
  17. data/lib/qb/ansible/env.rb +36 -6
  18. data/lib/qb/ansible/module.rb +396 -152
  19. data/lib/qb/ansible/module/response.rb +195 -0
  20. data/lib/qb/ansible/modules.rb +42 -0
  21. data/lib/qb/ansible/modules/docker/image.rb +273 -0
  22. data/lib/qb/cli.rb +5 -18
  23. data/lib/qb/cli/run.rb +2 -2
  24. data/lib/qb/data.rb +22 -0
  25. data/lib/qb/data/immutable.rb +39 -0
  26. data/lib/qb/docker.rb +2 -0
  27. data/lib/qb/docker/cli.rb +430 -0
  28. data/lib/qb/docker/image.rb +207 -0
  29. data/lib/qb/docker/image/name.rb +309 -0
  30. data/lib/qb/docker/image/tag.rb +113 -0
  31. data/lib/qb/docker/repo.rb +0 -0
  32. data/lib/qb/errors.rb +17 -3
  33. data/lib/qb/execution.rb +83 -0
  34. data/lib/qb/ipc.rb +48 -0
  35. data/lib/qb/ipc/stdio.rb +32 -0
  36. data/lib/qb/ipc/stdio/client.rb +267 -0
  37. data/lib/qb/ipc/stdio/server.rb +229 -0
  38. data/lib/qb/ipc/stdio/server/in_service.rb +18 -0
  39. data/lib/qb/ipc/stdio/server/log_service.rb +168 -0
  40. data/lib/qb/ipc/stdio/server/out_service.rb +20 -0
  41. data/lib/qb/ipc/stdio/server/service.rb +229 -0
  42. data/lib/qb/options.rb +360 -502
  43. data/lib/qb/options/option.rb +293 -115
  44. data/lib/qb/options/option/option_parser_concern.rb +228 -0
  45. data/lib/qb/options/types.rb +73 -0
  46. data/lib/qb/package.rb +0 -1
  47. data/lib/qb/package/version.rb +179 -58
  48. data/lib/qb/package/version/from.rb +192 -51
  49. data/lib/qb/package/version/leveled.rb +1 -1
  50. data/lib/qb/path.rb +3 -2
  51. data/lib/qb/repo/git.rb +9 -85
  52. data/lib/qb/role/default_dir.rb +2 -2
  53. data/lib/qb/role/errors.rb +2 -8
  54. data/lib/qb/util.rb +1 -2
  55. data/lib/qb/util/bundler.rb +73 -43
  56. data/lib/qb/util/decorators.rb +99 -0
  57. data/lib/qb/util/interop.rb +7 -8
  58. data/lib/qb/util/resource.rb +12 -13
  59. data/lib/qb/version.rb +10 -0
  60. data/library/path_facts +5 -10
  61. data/library/qb.module.rb +105 -0
  62. data/library/stream +6 -26
  63. data/load/ansible/module/autorun.rb +25 -0
  64. data/load/ansible/module/script.rb +123 -0
  65. data/load/rebundle.rb +39 -0
  66. data/plugins/filter/dict_filters.py +56 -0
  67. data/plugins/{filter_plugins/path_plugins.py → filter/path_filters.py} +0 -0
  68. data/plugins/{filter_plugins/ruby_interop_plugins.py → filter/ruby_interop_filters.py} +1 -17
  69. data/plugins/{filter_plugins/string_plugins.py → filter/string_filters.py} +1 -20
  70. data/plugins/{filter_plugins/version_plugins.py → filter/version_filters.py} +3 -18
  71. data/plugins/{lookup_plugins/every.py → lookup/every_lookups.py} +0 -0
  72. data/plugins/{lookup_plugins/resolve.py → lookup/resolve_lookups.py} +0 -0
  73. data/plugins/{lookup_plugins/version.py → lookup/version_lookups.py} +0 -16
  74. data/plugins/test/dict_tests.py +36 -0
  75. data/plugins/test/string_tests.py +36 -0
  76. data/qb.gemspec +7 -3
  77. data/roles/nrser.rb/library/set_fact_with_ruby.rb +3 -9
  78. data/roles/nrser.state_mate/library/state +3 -17
  79. data/roles/qb/call/meta/qb.yml +1 -1
  80. data/roles/qb/dev/ref/repo/git/meta/qb.yml +1 -1
  81. data/roles/qb/{ruby/rspec/setup → docker/mac/kubernetes}/defaults/main.yml +1 -1
  82. data/roles/qb/{ruby/rspec/setup → docker/mac/kubernetes}/meta/main.yml +3 -2
  83. data/roles/qb/{ruby/rspec/setup → docker/mac/kubernetes}/meta/qb.yml +12 -7
  84. data/roles/qb/docker/mac/kubernetes/tasks/main.yml +45 -0
  85. data/roles/qb/git/check/clean/meta/qb.yml +1 -1
  86. data/roles/qb/git/ignore/meta/qb +10 -3
  87. data/roles/qb/git/submodule/update/library/git_submodule_update +17 -27
  88. data/roles/qb/github/pages/setup/meta/qb.yml +1 -1
  89. data/roles/qb/labs/atom/apm/meta/qb.yml +1 -1
  90. data/roles/qb/osx/git/change_case/meta/qb.yml +1 -1
  91. data/roles/qb/osx/notif/meta/qb.yml +1 -1
  92. data/roles/qb/pkg/bump/library/bump +4 -16
  93. data/roles/qb/role/qb/defaults/main.yml +2 -0
  94. data/roles/qb/role/qb/meta/qb.yml +10 -5
  95. data/roles/qb/role/qb/templates/qb.yml.j2 +7 -2
  96. data/roles/qb/role/templates/library/module.rb.j2 +12 -23
  97. data/roles/qb/role/templates/meta/main.yml.j2 +14 -1
  98. data/roles/qb/ruby/bundler/meta/qb.yml +1 -1
  99. data/roles/qb/ruby/dependency/meta/qb.yml +1 -1
  100. data/roles/qb/ruby/gem/bin_stubs/meta/qb.yml +1 -1
  101. data/roles/qb/ruby/gem/bin_stubs/templates/console +8 -2
  102. data/roles/qb/ruby/gem/build/meta/qb.yml +1 -1
  103. data/roles/qb/ruby/gem/new/meta/qb.yml +1 -1
  104. data/roles/qb/ruby/nrser/rspex/generate/meta/qb.yml +5 -5
  105. data/roles/qb/ruby/nrser/rspex/issue/meta/qb.yml +1 -1
  106. data/roles/qb/ruby/yard/clean/meta/qb.yml +1 -1
  107. data/roles/qb/ruby/yard/config/library/yard.get_output_dir +5 -15
  108. data/roles/qb/ruby/yard/config/meta/qb.yml +1 -1
  109. data/roles/qb/ruby/yard/setup/meta/qb.yml +1 -1
  110. metadata +71 -22
  111. data/lib/qb/ansible_module.rb +0 -5
  112. data/lib/qb/util/stdio.rb +0 -187
  113. data/roles/qb/ruby/rspec/setup/tasks/main.yml +0 -4
@@ -76,7 +76,7 @@ class QB::Package::Version::Leveled < QB::Package::Version
76
76
  # If the values do have a level.
77
77
  #
78
78
  def self.level_for prerelease: [], build: [], **etc
79
- return RELEASE if prerelease.empty? && build.empty?
79
+ return RELEASE if prerelease.empty?
80
80
 
81
81
  return DEV if prerelease[0] == DEV
82
82
 
@@ -8,6 +8,8 @@ require 'pathname'
8
8
  # Deps
9
9
  # -----------------------------------------------------------------------
10
10
  require 'nrser'
11
+ require 'nrser/refinements/types'
12
+ require 'nrser/props/immutable/instance_variables'
11
13
 
12
14
  # Package
13
15
  # -----------------------------------------------------------------------
@@ -17,7 +19,6 @@ require 'qb/repo/git'
17
19
  # Refinements
18
20
  # =======================================================================
19
21
 
20
- using NRSER
21
22
  using NRSER::Types
22
23
 
23
24
 
@@ -32,7 +33,7 @@ class QB::Path < Pathname
32
33
  # Mixins
33
34
  # =====================================================================
34
35
 
35
- include NRSER::Meta::Props
36
+ include NRSER::Props::Immutable::InstanceVariables
36
37
 
37
38
 
38
39
  # Props
@@ -17,17 +17,9 @@ require 'qb/util/resource'
17
17
  # Refinements
18
18
  # =======================================================================
19
19
 
20
- using NRSER
21
20
  using NRSER::Types
22
21
 
23
22
 
24
- # Declarations
25
- # =======================================================================
26
-
27
- module QB; end
28
- class QB::Repo < QB::Util::Resource; end
29
-
30
-
31
23
  # Definitions
32
24
  # =======================================================================
33
25
 
@@ -36,6 +28,8 @@ class QB::Repo < QB::Util::Resource; end
36
28
  #
37
29
  # The main entry point is {QB::Repo::Git.from_path}, which creates a
38
30
  #
31
+ module QB
32
+ class QB::Repo < QB::Util::Resource
39
33
  class QB::Repo::Git < QB::Repo
40
34
  autoload :User, 'qb/repo/git/user'
41
35
  autoload :GitHub, 'qb/repo/git/github'
@@ -60,78 +54,6 @@ class QB::Repo::Git < QB::Repo
60
54
  prop :is_clean, type: t.bool, source: :clean?
61
55
 
62
56
 
63
-
64
-
65
-
66
- # class GitHubRemote < NRSER::Meta::Props::Base
67
- # SSH_URL_RE = /^git@github\.com\:(?<owner>.*)\/(?<name>.*)\.git$/
68
- # HTTPS_URL_RE = /^https:\/\/github\.com\/(?<owner>.*)\/(?<name>.*)\.git$/
69
- #
70
- # prop :owner, type: t.str
71
- # prop :name, type: t.str
72
- # prop :api_response, type: t.maybe(t.hash)
73
- #
74
- # prop :full_name, type: t.str, source: :full_name
75
- #
76
- #
77
- # # Class Methods
78
- # # =====================================================================
79
- #
80
- # # Test if a Git SSH or HTTPS remote url points to GitHub.
81
- # #
82
- # # @param [String] url
83
- # #
84
- # # @return [Boolean]
85
- # #
86
- # def self.url? url
87
- # SSH_URL_RE.match(url) || HTTPS_URL_RE.match(url)
88
- # end # .url?
89
- #
90
- #
91
- # # Instantiate an instance from a Git SSH or HTTPS remote url that points
92
- # # to GitHub.
93
- # #
94
- # # @param [type] arg_name
95
- # # @todo Add name param description.
96
- # #
97
- # # @return [QB::Repo::Git::GitHubRemote]
98
- # # @todo Document return value.
99
- # #
100
- # def self.from_url url, use_api: false
101
- # match = SSH_URL_RE.match(git.origin) ||
102
- # HTTPS_URL_RE.match(git.origin)
103
- #
104
- # unless match
105
- # raise ArgumentError.new NRSER.squish <<-END
106
- # url #{ url.inspect } does not match GitHub SSH or HTTPS patterns.
107
- # END
108
- # end
109
- #
110
- # owner = match['owner']
111
- # name = match['name']
112
- #
113
- # if use_api
114
- #
115
- # end
116
- # end # .from_url
117
- #
118
- #
119
- #
120
- # # @todo Document full_name method.
121
- # #
122
- # # @param [type] arg_name
123
- # # @todo Add name param description.
124
- # #
125
- # # @return [return_type]
126
- # # @todo Document return value.
127
- # #
128
- # def full_name arg_name
129
- # "#{ owner }/#{ name }"
130
- # end # #full_name
131
- #
132
- # end
133
-
134
-
135
57
  # Class Methods
136
58
  # =====================================================================
137
59
 
@@ -194,7 +116,7 @@ class QB::Repo::Git < QB::Repo
194
116
 
195
117
  root_path = Pathname.new root_result.out.chomp
196
118
 
197
- user = User.new **NRSER.map_values(User.props.keys) {|key, _|
119
+ user = User.new **User.props.keys.assoc_to { |key|
198
120
  begin
199
121
  Cmds.chomp! "git config user.#{ key }"
200
122
  rescue
@@ -340,8 +262,10 @@ class QB::Repo::Git < QB::Repo
340
262
  end
341
263
 
342
264
 
343
- def api
344
- @api ||= ::Git.open root_path
265
+ def lib
266
+ lazy_var :@lib do
267
+ ::Git.open root_path
268
+ end
345
269
  end
346
270
 
347
271
 
@@ -374,7 +298,7 @@ class QB::Repo::Git < QB::Repo
374
298
 
375
299
 
376
300
  def tags
377
- api.tags.map &:name
301
+ lib.tags.map &:name
378
302
  end
379
303
 
380
- end # class QB::Repo::Git
304
+ end; end; end # class QB::Repo::Git
@@ -70,8 +70,8 @@ class QB::Role
70
70
  #
71
71
  def default_dir cwd, options
72
72
  logger.debug "CALLING default_dir",
73
- role: self.instance_variables.map_values { |k, v|
74
- self.instance_variable_get k
73
+ role: self.instance_variables.assoc_to { |key|
74
+ self.instance_variable_get key
75
75
  },
76
76
  cwd: cwd,
77
77
  options: options
@@ -1,9 +1,3 @@
1
- # Refinements
2
- # =======================================================================
3
-
4
- require 'nrser/refinements'
5
- using NRSER
6
-
7
1
 
8
2
  # Definitions
9
3
  # =======================================================================
@@ -40,8 +34,8 @@ module QB
40
34
  end
41
35
  end
42
36
 
43
- # raised when there's bad metadata
37
+ # raised when there's bad metadata
44
38
  class MetadataError < QB::StateError
45
39
  end
46
40
  end # Role
47
- end # QB
41
+ end # QB
@@ -1,9 +1,8 @@
1
- require_relative './util/stdio'
2
1
  require_relative './util/interop'
3
2
  require_relative './util/bundler'
3
+ require_relative './util/decorators'
4
4
 
5
5
  require 'nrser'
6
- using NRSER
7
6
 
8
7
  module QB
9
8
  module Util
@@ -1,56 +1,86 @@
1
1
  module QB; end
2
2
  module QB::Util; end
3
3
 
4
- module QB::Util::Bundler
5
- # needed for to clean the env if using bundler (like in dev).
4
+ module QB::Util::Bundler
5
+
6
+ # Are we running inside `bundler exec`?
6
7
  #
7
- # this is because the ansible gem module doesn't work right with the bundler
8
- # env vars set, so we need to remove them, but when running in dev we want
9
- # modules written in ruby like nrser.state_mate's `state` script to have
10
- # access to them so it can fire up bundler and get the right libraries.
8
+ # @return [Boolean]
11
9
  #
12
- # to accomplish this, we detect Bundler, and when it's present we copy the
13
- # bundler-related env vars (which i found by looking at
14
- # https://github.com/bundler/bundler/blob/master/lib/bundler.rb#L257)
15
- # into a hash to pass around the env sanitization, then copy them into
16
- # corresponding 'QB_DEV_ENV_<NAME>' vars that modules can restore.
10
+ def self.bundled?
11
+ defined? ::Bundler
12
+ end # .bundled?
13
+
14
+
15
+ # Wrapper around {Bundler.with_clean_env} that copies the Bundler ENV vars
16
+ # to other keys, allowing that Bundler ENV to be re-instated later,
17
+ # specifically by child processes like Ansible module scripts that inherit
18
+ # the ENV.
17
19
  #
18
- # we also set a 'QB_DEV_ENV=true' env var for modules to easily detect that
19
- # we're running in dev and restore the variables.
20
+ # We execute Ansible commands in this context because any Ruby processes it
21
+ # starts want the system environment, not the Bundler environment that QB
22
+ # may be running in. In particular, Ansible's `gem` module fails if the
23
+ # Bundler ENV vars are still in place, which totally make sense.
24
+ #
25
+ # Instead, we let programs that want to boot up the possibly separate
26
+ # environment that QB is running in (so they can require it - again,
27
+ # Ansible module scripts, specifically those using {QB::Ansible::Module})
28
+ # can load `//load/rebundle.rb`, which will restore the Bundler ENV vars
29
+ # (and `require 'bundler/setup'`).
30
+ #
31
+ # We make the absolute path to `//load/rebundle.rb` available in the "clean"
32
+ # ENV as the `QB_REBUNDLE_PATH` var, so child Ruby programs can drop a
33
+ # single line at the top of the file:
34
+ #
35
+ # load ENV['QB_REBUNDLE_PATH'] if ENV['QB_REBUNDLE_PATH']
36
+ #
37
+ # and be set up to require QB files.
38
+ #
39
+ # If QB is *not* running in Bundler ({#bundled?} returns `false`) then
40
+ # this method simply calls `&block` and returns the value.
41
+ #
42
+ # @param [Proc<() => RESULT>] &block
43
+ # Block to execute in the "clean" env.
44
+ #
45
+ # @return [RESULT]
46
+ # Whatever `&block` returns when called.
20
47
  #
21
48
  def self.with_clean_env &block
22
- if defined? ::Bundler
23
- # copy the Bundler env vars into a hash
24
- dev_env = ENV.select {|k, v|
25
- k.start_with?("BUNDLE_") ||
26
- [
27
- 'GEM_HOME',
28
- 'GEM_PATH',
29
- 'MANPATH',
30
- 'RUBYOPT',
31
- 'RUBYLIB',
32
- ].include?(k)
33
- }
49
+ # If we're not running "bundled" then just call the block and return
50
+ return block.call unless bundled?
51
+
52
+ # copy the Bundler env vars into a hash
53
+ dev_env = ENV.select {|k, v|
54
+ k.start_with?("BUNDLE_") ||
55
+ [
56
+ 'GEM_HOME',
57
+ 'GEM_PATH',
58
+ 'MANPATH',
59
+ 'RUBYOPT',
60
+ 'RUBYLIB',
61
+ ].include?(k)
62
+ }
63
+
64
+ qb_env = ENV.select { |k, v| k.start_with? 'QB_' }
65
+
66
+ ::Bundler.with_clean_env do
67
+ # Now that we're in a clean env, copy the Bundler env vars into
68
+ # 'QB_BUNDLER_ENV_<NAME>' vars.
69
+ dev_env.each { |k, v| ENV["QB_BUNDLER_ENV_#{ k }"] = v }
70
+
71
+ # Set the path to the `//load/rebundle.rb` script in an ENV var.
72
+ #
73
+ # Child Ruby processes that want to load up the environment QB was run
74
+ # in look for this and load it if they find it, restoring the Bundler /
75
+ # Ruby Gems ENV vars, allowing them to `require 'qb'`, etc.
76
+ #
77
+ ENV['QB_REBUNDLE_PATH'] = (QB::ROOT / 'load' / 'rebundle.rb').to_s
34
78
 
35
- qb_env = ENV.select {|k, v| k.start_with? 'QB_'}
79
+ qb_env.each { |k, v| ENV[k] = v }
36
80
 
37
- ::Bundler.with_clean_env do
38
- # now that we're in a clean env, copy the Bundler env vars into
39
- # 'QB_DEV_ENV_<NAME>' vars.
40
- dev_env.each {|k, v| ENV["QB_DEV_ENV_#{ k }"] = v}
41
-
42
- # set the flag that will be used by modules to know to restore the
43
- # variables
44
- ENV['QB_DEV_ENV'] = 'true'
45
-
46
- qb_env.each {|k, v| ENV[k] = v}
47
-
48
- # invoke the block
49
- block.call
50
- end
51
- else
52
- # bundler isn't loaded, so no env var silliness to deal with
81
+ # invoke the block
53
82
  block.call
54
- end
83
+ end # ::Bundler.with_clean_env
55
84
  end # .with_clean_env
85
+
56
86
  end # module QB::Util::Bundler
@@ -0,0 +1,99 @@
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+
4
+ # Requirements
5
+ # =======================================================================
6
+
7
+ # Deps
8
+ # -----------------------------------------------------------------------
9
+
10
+ require 'method_decorators'
11
+
12
+
13
+ # Definitions
14
+ # =======================================================================
15
+
16
+ # Python-style decorators using the `method_decorators` gem.
17
+ #
18
+ # @see https://rubygems.org/gems/method_decorators
19
+ #
20
+ # @example Usage
21
+ # class A
22
+ # extend MethodDecorators
23
+ #
24
+ # +QB::Util::Decorators::EnumFor
25
+ # def get_stuff
26
+ # yield 1
27
+ # yield 2
28
+ # yield 3
29
+ # end
30
+ #
31
+ # end
32
+ #
33
+ # A.new.get_stuff.class
34
+ # # => Enumerator
35
+ #
36
+ module QB; module Util; module Decorators
37
+
38
+ # Wrap a method that yields, returning an {Enumerator} if no block is
39
+ # given.
40
+ #
41
+ # Implements the common "enum_for" pattern:
42
+ #
43
+ # def f
44
+ # return enum_for( __method__ ) unless block_given?
45
+ # yield 1
46
+ # # ...
47
+ # end
48
+ #
49
+ class EnumFor < MethodDecorators::Decorator
50
+ # @param [Method] target
51
+ # The decorated method, already bound to the receiver.
52
+ #
53
+ # The `method_decorators` gem calls this `orig`, but I thought `target`
54
+ # made more sense.
55
+ #
56
+ # @param [*] receiver
57
+ # The object that will receive the call to `target`.
58
+ #
59
+ # The `method_decorators` gem calls this `this`, but I thought `receiver`
60
+ # made more sense.
61
+ #
62
+ # It's just `target.receiver`, but the API is how it is.
63
+ #
64
+ # @param [Array] *args
65
+ # Any arguments the decorated method was called with.
66
+ #
67
+ # @param [Proc?] &block
68
+ # The block the decorated method was called with (if any).
69
+ #
70
+ def call target, receiver, *args, &block
71
+ if block
72
+ target.call *args, &block
73
+ else
74
+ receiver.enum_for target.name, *args
75
+ end
76
+ end
77
+ end # EnumFor
78
+
79
+
80
+ # Don't all {NRSER::Props} arguments in last position to become keyword
81
+ # options.
82
+ #
83
+ # Since {NRSER::Props} objects can be subclasses of {Hash}, etc., they can
84
+ # erroneously end up being considered keyword options.
85
+ #
86
+ # This decorator prevents that. If you want to pass an {NRSER::Props} as the
87
+ # keywords, calling `#to_h` or something on it first should work.
88
+ #
89
+ class NoPropsInKwds < MethodDecorators::Decorator
90
+ def call target, receiver, *args, &block
91
+ if args.last.is_a? NRSER::Props
92
+ target.call *args, {}, &block
93
+ else
94
+ target.call *args, &block
95
+ end
96
+ end
97
+ end # class NoPropsInKwds
98
+
99
+ end; end; end # module QB::Util::Decorators
@@ -1,12 +1,11 @@
1
- require 'nrser/refinements'
1
+ require 'nrser'
2
+ require 'nrser/props'
2
3
 
3
- using NRSER
4
-
5
- module QB
6
- module Util
4
+ module QB
5
+ module Util
7
6
 
8
7
  module Interop
9
- include SemanticLogger::Loggable
8
+ include NRSER::Log::Mixin
10
9
 
11
10
  class << self
12
11
 
@@ -14,8 +13,8 @@ module Interop
14
13
  logger.debug "Starting #send_to_instance..."
15
14
 
16
15
  obj = if data.is_a?( Hash ) &&
17
- data.key?( NRSER::Meta::Props::DEFAULT_CLASS_KEY )
18
- NRSER::Meta::Props.UNSAFE_load_instance_from_data data
16
+ data.key?( NRSER::Props::DEFAULT_CLASS_KEY )
17
+ NRSER::Props.UNSAFE_load_instance_from_data data
19
18
  else
20
19
  data
21
20
  end