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.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/ansible.cfg +10 -1
- data/exe/.qb_interop_receive +3 -10
- data/exe/qb +8 -2
- data/lib/python/qb/__init__.py +6 -0
- data/{roles/qb/ruby/rspec/setup/tasks/persistence.yml → lib/python/qb/ansible/__init__.py} +0 -0
- data/lib/python/qb/ansible/modules/__init__.py +0 -0
- data/lib/python/qb/ansible/modules/docker/__init__.py +0 -0
- data/lib/python/qb/ansible/modules/docker/client.py +177 -0
- data/lib/python/qb/ansible/modules/docker/image_manager.py +754 -0
- data/lib/python/qb/ipc/__init__.py +0 -0
- data/lib/python/qb/ipc/stdio/__init__.py +99 -0
- data/lib/python/qb/ipc/stdio/logging.py +151 -0
- data/lib/qb.rb +3 -3
- data/lib/qb/ansible/cmds/playbook.rb +5 -14
- data/lib/qb/ansible/env.rb +36 -6
- data/lib/qb/ansible/module.rb +396 -152
- data/lib/qb/ansible/module/response.rb +195 -0
- data/lib/qb/ansible/modules.rb +42 -0
- data/lib/qb/ansible/modules/docker/image.rb +273 -0
- data/lib/qb/cli.rb +5 -18
- data/lib/qb/cli/run.rb +2 -2
- data/lib/qb/data.rb +22 -0
- data/lib/qb/data/immutable.rb +39 -0
- data/lib/qb/docker.rb +2 -0
- data/lib/qb/docker/cli.rb +430 -0
- data/lib/qb/docker/image.rb +207 -0
- data/lib/qb/docker/image/name.rb +309 -0
- data/lib/qb/docker/image/tag.rb +113 -0
- data/lib/qb/docker/repo.rb +0 -0
- data/lib/qb/errors.rb +17 -3
- data/lib/qb/execution.rb +83 -0
- data/lib/qb/ipc.rb +48 -0
- data/lib/qb/ipc/stdio.rb +32 -0
- data/lib/qb/ipc/stdio/client.rb +267 -0
- data/lib/qb/ipc/stdio/server.rb +229 -0
- data/lib/qb/ipc/stdio/server/in_service.rb +18 -0
- data/lib/qb/ipc/stdio/server/log_service.rb +168 -0
- data/lib/qb/ipc/stdio/server/out_service.rb +20 -0
- data/lib/qb/ipc/stdio/server/service.rb +229 -0
- data/lib/qb/options.rb +360 -502
- data/lib/qb/options/option.rb +293 -115
- data/lib/qb/options/option/option_parser_concern.rb +228 -0
- data/lib/qb/options/types.rb +73 -0
- data/lib/qb/package.rb +0 -1
- data/lib/qb/package/version.rb +179 -58
- data/lib/qb/package/version/from.rb +192 -51
- data/lib/qb/package/version/leveled.rb +1 -1
- data/lib/qb/path.rb +3 -2
- data/lib/qb/repo/git.rb +9 -85
- data/lib/qb/role/default_dir.rb +2 -2
- data/lib/qb/role/errors.rb +2 -8
- data/lib/qb/util.rb +1 -2
- data/lib/qb/util/bundler.rb +73 -43
- data/lib/qb/util/decorators.rb +99 -0
- data/lib/qb/util/interop.rb +7 -8
- data/lib/qb/util/resource.rb +12 -13
- data/lib/qb/version.rb +10 -0
- data/library/path_facts +5 -10
- data/library/qb.module.rb +105 -0
- data/library/stream +6 -26
- data/load/ansible/module/autorun.rb +25 -0
- data/load/ansible/module/script.rb +123 -0
- data/load/rebundle.rb +39 -0
- data/plugins/filter/dict_filters.py +56 -0
- data/plugins/{filter_plugins/path_plugins.py → filter/path_filters.py} +0 -0
- data/plugins/{filter_plugins/ruby_interop_plugins.py → filter/ruby_interop_filters.py} +1 -17
- data/plugins/{filter_plugins/string_plugins.py → filter/string_filters.py} +1 -20
- data/plugins/{filter_plugins/version_plugins.py → filter/version_filters.py} +3 -18
- data/plugins/{lookup_plugins/every.py → lookup/every_lookups.py} +0 -0
- data/plugins/{lookup_plugins/resolve.py → lookup/resolve_lookups.py} +0 -0
- data/plugins/{lookup_plugins/version.py → lookup/version_lookups.py} +0 -16
- data/plugins/test/dict_tests.py +36 -0
- data/plugins/test/string_tests.py +36 -0
- data/qb.gemspec +7 -3
- data/roles/nrser.rb/library/set_fact_with_ruby.rb +3 -9
- data/roles/nrser.state_mate/library/state +3 -17
- data/roles/qb/call/meta/qb.yml +1 -1
- data/roles/qb/dev/ref/repo/git/meta/qb.yml +1 -1
- data/roles/qb/{ruby/rspec/setup → docker/mac/kubernetes}/defaults/main.yml +1 -1
- data/roles/qb/{ruby/rspec/setup → docker/mac/kubernetes}/meta/main.yml +3 -2
- data/roles/qb/{ruby/rspec/setup → docker/mac/kubernetes}/meta/qb.yml +12 -7
- data/roles/qb/docker/mac/kubernetes/tasks/main.yml +45 -0
- data/roles/qb/git/check/clean/meta/qb.yml +1 -1
- data/roles/qb/git/ignore/meta/qb +10 -3
- data/roles/qb/git/submodule/update/library/git_submodule_update +17 -27
- data/roles/qb/github/pages/setup/meta/qb.yml +1 -1
- data/roles/qb/labs/atom/apm/meta/qb.yml +1 -1
- data/roles/qb/osx/git/change_case/meta/qb.yml +1 -1
- data/roles/qb/osx/notif/meta/qb.yml +1 -1
- data/roles/qb/pkg/bump/library/bump +4 -16
- data/roles/qb/role/qb/defaults/main.yml +2 -0
- data/roles/qb/role/qb/meta/qb.yml +10 -5
- data/roles/qb/role/qb/templates/qb.yml.j2 +7 -2
- data/roles/qb/role/templates/library/module.rb.j2 +12 -23
- data/roles/qb/role/templates/meta/main.yml.j2 +14 -1
- data/roles/qb/ruby/bundler/meta/qb.yml +1 -1
- data/roles/qb/ruby/dependency/meta/qb.yml +1 -1
- data/roles/qb/ruby/gem/bin_stubs/meta/qb.yml +1 -1
- data/roles/qb/ruby/gem/bin_stubs/templates/console +8 -2
- data/roles/qb/ruby/gem/build/meta/qb.yml +1 -1
- data/roles/qb/ruby/gem/new/meta/qb.yml +1 -1
- data/roles/qb/ruby/nrser/rspex/generate/meta/qb.yml +5 -5
- data/roles/qb/ruby/nrser/rspex/issue/meta/qb.yml +1 -1
- data/roles/qb/ruby/yard/clean/meta/qb.yml +1 -1
- data/roles/qb/ruby/yard/config/library/yard.get_output_dir +5 -15
- data/roles/qb/ruby/yard/config/meta/qb.yml +1 -1
- data/roles/qb/ruby/yard/setup/meta/qb.yml +1 -1
- metadata +71 -22
- data/lib/qb/ansible_module.rb +0 -5
- data/lib/qb/util/stdio.rb +0 -187
- 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?
|
|
79
|
+
return RELEASE if prerelease.empty?
|
|
80
80
|
|
|
81
81
|
return DEV if prerelease[0] == DEV
|
|
82
82
|
|
data/lib/qb/path.rb
CHANGED
|
@@ -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::
|
|
36
|
+
include NRSER::Props::Immutable::InstanceVariables
|
|
36
37
|
|
|
37
38
|
|
|
38
39
|
# Props
|
data/lib/qb/repo/git.rb
CHANGED
|
@@ -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 **
|
|
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
|
|
344
|
-
|
|
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
|
-
|
|
301
|
+
lib.tags.map &:name
|
|
378
302
|
end
|
|
379
303
|
|
|
380
|
-
end # class QB::Repo::Git
|
|
304
|
+
end; end; end # class QB::Repo::Git
|
data/lib/qb/role/default_dir.rb
CHANGED
|
@@ -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.
|
|
74
|
-
self.instance_variable_get
|
|
73
|
+
role: self.instance_variables.assoc_to { |key|
|
|
74
|
+
self.instance_variable_get key
|
|
75
75
|
},
|
|
76
76
|
cwd: cwd,
|
|
77
77
|
options: options
|
data/lib/qb/role/errors.rb
CHANGED
|
@@ -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
|
data/lib/qb/util.rb
CHANGED
data/lib/qb/util/bundler.rb
CHANGED
|
@@ -1,56 +1,86 @@
|
|
|
1
1
|
module QB; end
|
|
2
2
|
module QB::Util; end
|
|
3
3
|
|
|
4
|
-
module QB::Util::Bundler
|
|
5
|
-
|
|
4
|
+
module QB::Util::Bundler
|
|
5
|
+
|
|
6
|
+
# Are we running inside `bundler exec`?
|
|
6
7
|
#
|
|
7
|
-
#
|
|
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
|
-
|
|
13
|
-
|
|
14
|
-
#
|
|
15
|
-
|
|
16
|
-
|
|
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
|
-
#
|
|
19
|
-
#
|
|
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
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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
|
|
79
|
+
qb_env.each { |k, v| ENV[k] = v }
|
|
36
80
|
|
|
37
|
-
|
|
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
|
data/lib/qb/util/interop.rb
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
require 'nrser
|
|
1
|
+
require 'nrser'
|
|
2
|
+
require 'nrser/props'
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
module QB
|
|
6
|
-
module Util
|
|
4
|
+
module QB
|
|
5
|
+
module Util
|
|
7
6
|
|
|
8
7
|
module Interop
|
|
9
|
-
include
|
|
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::
|
|
18
|
-
NRSER::
|
|
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
|