qb 0.1.88 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/exe/qb +3 -53
  3. data/lib/qb.rb +3 -1
  4. data/lib/qb/ansible.rb +5 -0
  5. data/lib/qb/ansible/config_file.rb +147 -0
  6. data/lib/qb/ansible/env.rb +49 -0
  7. data/lib/qb/ansible/playbook.rb +4 -0
  8. data/lib/qb/cli.rb +4 -0
  9. data/lib/qb/cli/play.rb +33 -0
  10. data/lib/qb/options.rb +48 -7
  11. data/lib/qb/role.rb +228 -74
  12. data/lib/qb/util.rb +2 -2
  13. data/lib/qb/util/bundler.rb +56 -0
  14. data/lib/qb/version.rb +1 -1
  15. data/node_modules/.bin/semver +1 -1
  16. data/plugins/filter_plugins/{path.py → path_plugins.py} +35 -0
  17. data/plugins/filter_plugins/{ruby_interop.py → ruby_interop_plugins.py} +0 -0
  18. data/plugins/filter_plugins/{string.py → string_plugins.py} +19 -0
  19. data/plugins/filter_plugins/{version.py → version_plugins.py} +0 -0
  20. data/qb.gemspec +1 -0
  21. data/roles/nrser.blockinfile/tests/expected/test-follow/link2.txt +1 -1
  22. data/roles/nrser.blockinfile/tests/fixtures/test-follow/link0.txt +1 -1
  23. data/roles/nrser.blockinfile/tests/fixtures/test-follow/link1.txt +1 -1
  24. data/roles/nrser.blockinfile/tests/fixtures/test-follow/link2.txt +1 -1
  25. data/roles/nrser.blockinfile/tests/roles/yaegashi.blockinfile +1 -1
  26. data/roles/qb.gitignore/files/gitignore/Clojure.gitignore +1 -1
  27. data/roles/qb.gitignore/files/gitignore/Fortran.gitignore +1 -1
  28. data/roles/qb.qb_role/templates/qb.yml.j2 +1 -1
  29. data/roles/qb/dev/ref/repo/git/defaults/main.yml +32 -0
  30. data/roles/qb/dev/ref/repo/git/meta/main.yml +8 -0
  31. data/roles/qb/dev/ref/repo/git/meta/qb.yml +67 -0
  32. data/roles/qb/dev/ref/repo/git/tasks/main.yml +16 -0
  33. data/roles/qb/facts/defaults/main.yml +3 -0
  34. data/roles/{qb.facts → qb/facts}/meta/main.yml +1 -1
  35. data/roles/{qb.facts → qb/facts}/meta/qb.yml +1 -1
  36. data/roles/{qb.facts → qb/facts}/tasks/main.yml +1 -1
  37. data/roles/qb/osx/git/change_case/README.md +16 -0
  38. data/roles/qb/osx/git/change_case/defaults/main.yml +2 -0
  39. data/roles/qb/osx/git/change_case/meta/main.yml +8 -0
  40. data/roles/qb/osx/git/change_case/meta/qb.yml +80 -0
  41. data/roles/qb/osx/git/change_case/tasks/main.yml +6 -0
  42. data/roles/qb/osx/git/change_case/tasks/upcase.yml +26 -0
  43. metadata +42 -11
  44. data/roles/qb.facts/defaults/main.yml +0 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5723177f21a7a76d3c4eac339f7e87f24235f080
4
- data.tar.gz: a39e95984a295ac9b39b1f8df157fbbb64be69ef
3
+ metadata.gz: 58d2c1fbf4d57fdd1b607cf1c8716104b61a9909
4
+ data.tar.gz: 0b845dc2f323e3fb3e0f00a006af1f04f5d1a6a9
5
5
  SHA512:
6
- metadata.gz: 48f81a50982b092f1f776516225a77321c15f8ab5a5060e868847356c107f2b51d9139f56eaf955ed84d656ea4f26655a050df30e1b085d8ca3d5b181b3d4f83
7
- data.tar.gz: 35b50434cd7e57c4a57b8efea0f727238f852887d680a7c899dc8252be25495cb9f7c999da3680ea4f776efc9de07cb7f5f6910fb2620bd940e8dac0fc247eb9
6
+ metadata.gz: b3491012bb23264bc31f2f7c52f655f9b4a5a30e26c5efcaca05ed83f8240bad2402e8b1d14700be7433a30f14bbd2b990997b9b0a960b2244803117ac972f29
7
+ data.tar.gz: 2386308ce3bb76e0eea32a7dc6f6f9ca44c85d9cf90ef035b86e8cb3bd4f638d7b0bdf8b01e7653d601c775df4ffa73081fa8c6f27652754a65319b5a8fd2413
data/exe/qb CHANGED
@@ -26,58 +26,6 @@ def set_debug! args
26
26
  end
27
27
  end
28
28
 
29
- # needed for to clean the env if using bundler (like in dev).
30
- #
31
- # this is because the ansible gem module doesn't work right with the bundler
32
- # env vars set, so we need to remove them, but when running in dev we want
33
- # modules written in ruby like nrser.state_mate's `state` script to have
34
- # access to them so it can fire up bundler and get the right libraries.
35
- #
36
- # to accomplish this, we detect Bundler, and when it's present we copy the
37
- # bundler-related env vars (which i found by looking at
38
- # https://github.com/bundler/bundler/blob/master/lib/bundler.rb#L257)
39
- # into a hash to pass around the env sanitization, then copy them into
40
- # corresponding 'QB_DEV_ENV_<NAME>' vars that modules can restore.
41
- #
42
- # we also set a 'QB_DEV_ENV=true' env var for modules to easily detect that
43
- # we're running in dev and restore the variables.
44
- #
45
- def with_clean_env &block
46
- if defined? Bundler
47
- # copy the Bundler env vars into a hash
48
- dev_env = ENV.select {|k, v|
49
- k.start_with?("BUNDLE_") ||
50
- [
51
- 'GEM_HOME',
52
- 'GEM_PATH',
53
- 'MANPATH',
54
- 'RUBYOPT',
55
- 'RUBYLIB',
56
- ].include?(k)
57
- }
58
-
59
- qb_env = ENV.select {|k, v| k.start_with? 'QB_'}
60
-
61
- Bundler.with_clean_env do
62
- # now that we're in a clean env, copy the Bundler env vars into
63
- # 'QB_DEV_ENV_<NAME>' vars.
64
- dev_env.each {|k, v| ENV["QB_DEV_ENV_#{ k }"] = v}
65
-
66
- # set the flag that will be used by modules to know to restore the
67
- # variables
68
- ENV['QB_DEV_ENV'] = 'true'
69
-
70
- qb_env.each {|k, v| ENV[k] = v}
71
-
72
- # invoke the block
73
- block.call
74
- end
75
- else
76
- # bundler isn't loaded, so no env var silliness to deal with
77
- block.call
78
- end
79
- end
80
-
81
29
  def metadata
82
30
  if QB.gemspec.metadata && !QB.gemspec.metadata.empty?
83
31
  "metadata:\n" + QB.gemspec.metadata.map {|key, value|
@@ -115,6 +63,8 @@ def main args
115
63
 
116
64
  help if role_arg.nil? || ['-h', '--help', 'help'].include?(role_arg)
117
65
 
66
+ return QB::CLI.play(args) if role_arg == 'play'
67
+
118
68
  begin
119
69
  role = QB::Role.require role_arg
120
70
  rescue QB::Role::NoMatchesError => e
@@ -411,7 +361,7 @@ def main args
411
361
  end
412
362
  end
413
363
 
414
- with_clean_env do
364
+ QB::Util::Bundler.with_clean_env do
415
365
  # boot up stdio out services so that ansible modules can stream to our
416
366
  # stdout and stderr to print stuff (including debug lines) in real-time
417
367
  stdio_out_services = {'out' => $stdout, 'err' => $stderr}.
data/lib/qb.rb CHANGED
@@ -38,4 +38,6 @@ end
38
38
  # needs QB::*_ROLES_DIR
39
39
  require 'qb/role'
40
40
  require 'qb/options'
41
- require_relative './qb/repo'
41
+ require_relative './qb/repo'
42
+ require_relative './qb/cli'
43
+ require_relative './qb/ansible'
data/lib/qb/ansible.rb ADDED
@@ -0,0 +1,5 @@
1
+
2
+ module QB; end
3
+ module QB::Ansible; end
4
+
5
+ require_relative './ansible/config_file'
@@ -0,0 +1,147 @@
1
+ # Requirements
2
+ # =====================================================================
3
+
4
+ # stdlib
5
+ require 'ostruct'
6
+
7
+ # deps
8
+ require 'parseconfig'
9
+
10
+ # project
11
+ require 'qb/util'
12
+
13
+
14
+ # Refinements
15
+ # =====================================================================
16
+
17
+ require 'nrser/refinements'
18
+ using NRSER
19
+
20
+
21
+ module QB; end
22
+ module QB::Ansible; end
23
+
24
+
25
+ # A parse of an `ansible.cfg` file, extending {ParseConfig}.
26
+ #
27
+ # We need these to read role path and other Ansible variables so we can setup
28
+ # paths correctly.
29
+ #
30
+ class QB::Ansible::ConfigFile < ParseConfig
31
+
32
+ # Sub-Scopes
33
+ # =====================================================================
34
+
35
+
36
+ # Wrapper around the Hash from the `[defaults]` group in an Asnible
37
+ # config file.
38
+ #
39
+ # Instances are returned from {QB::Ansible::ConfigFile#defaults}.
40
+ #
41
+ class Defaults < Hash
42
+
43
+ # Attributes
44
+ # =====================================================================
45
+
46
+ # @!attribute [r] rel_root
47
+ # @return [Pathname]
48
+ # Absolute path to use as root for relative paths.
49
+ attr_reader :rel_root
50
+
51
+
52
+ # Constructor
53
+ # =====================================================================
54
+
55
+ # Instantiate a new `QB::Ansible::ConfigFile`.
56
+ #
57
+ # @param [#each_pair] source
58
+ # Source for the keys and values.
59
+ #
60
+ def initialize source, rel_root:
61
+ super()
62
+ source.each_pair { |k, v| self[k] = v }
63
+ @rel_root = rel_root
64
+ end # #initialize
65
+
66
+
67
+ # Instance Methods
68
+ # =====================================================================
69
+
70
+ # @return [Array<Pathname>]
71
+ # Array of resolved (absolute) {Pathname} instances parsed from the
72
+ # `roles_path` value. Empty array `roles_path` key is missing.
73
+ #
74
+ def roles_path
75
+ if key? 'roles_path'
76
+ self['roles_path'].
77
+ split(':').
78
+ map { |path| QB::Util.resolve @rel_root, path }
79
+ else
80
+ []
81
+ end
82
+ end # #roles_path
83
+
84
+ end # class Defaults
85
+
86
+
87
+ # Constants
88
+ # =====================================================================
89
+
90
+ # The "well-known" name we look for.
91
+ FILE_NAME = 'ansible.cfg'
92
+
93
+
94
+ # Class Methods
95
+ # =====================================================================
96
+
97
+
98
+ # @todo Document path? method.
99
+ #
100
+ # @param [String, Pathname] file_path
101
+ #
102
+ #
103
+ # @return [Boolean]
104
+ # `true`
105
+ #
106
+ def self.file_path? file_path
107
+ File.basename(file_path).to_s == FILE_NAME
108
+ end # .path?
109
+
110
+
111
+ # Attributes
112
+ # =====================================================================
113
+
114
+ # @!attribute [r] rel_root
115
+ # @return [Pathname]
116
+ # Absolute path to the directory `ansible.cfg` is in; used as the
117
+ # root for relative paths found in there.
118
+ attr_reader :rel_root
119
+
120
+
121
+ # Constructor
122
+ # =====================================================================
123
+
124
+ # Instantiate a new `QB::Ansible::ConfigFile`.
125
+ def initialize path
126
+ super path
127
+ @rel_root = QB::Util.resolve(path).dirname
128
+ end # #initialize
129
+
130
+
131
+ # Instance Methods
132
+ # =====================================================================
133
+
134
+ # @todo Document defaults method.
135
+ #
136
+ # @return [QB::Ansible::ConfigFile::Defaults]
137
+ # @todo Document return value.
138
+ #
139
+ def defaults
140
+ Defaults.new (self['defaults'] || {}), rel_root: @rel_root
141
+ end # #defaults
142
+
143
+
144
+ end # class QB::Ansible::ConfigFile
145
+
146
+
147
+
@@ -0,0 +1,49 @@
1
+ module QB; end
2
+ module QB::Ansible; end
3
+
4
+
5
+ # @todo document QB::Ansible::Env class.
6
+ class QB::Ansible::Env < Hash
7
+
8
+ # Constants
9
+ # ======================================================================
10
+
11
+ VAR_NAME_PREFIX = 'ANSIBLE'
12
+
13
+
14
+ # Class Methods
15
+ # ======================================================================
16
+
17
+
18
+ # @todo Document to_var_name method.
19
+ #
20
+ # @param [type] name
21
+ # @todo Add name param description.
22
+ #
23
+ # @return [return_type]
24
+ # @todo Document return value.
25
+ #
26
+ def self.to_var_name name
27
+ "#{ VAR_NAME_PREFIX }_ #{ name.to_s.upcase }"
28
+ end # .to_var_name
29
+
30
+
31
+
32
+ # Attributes
33
+ # ======================================================================
34
+
35
+
36
+ # Constructor
37
+ # ======================================================================
38
+
39
+ # Instantiate a new `QB::Ansible::Env`.
40
+ def initialize
41
+
42
+ end # #initialize
43
+
44
+
45
+ # Instance Methods
46
+ # ======================================================================
47
+
48
+
49
+ end # class QB::Ansible::Env
@@ -0,0 +1,4 @@
1
+ module QB; end
2
+ module QB::Ansible; end
3
+
4
+
data/lib/qb/cli.rb ADDED
@@ -0,0 +1,4 @@
1
+ module QB; end
2
+ module QB::CLI; end
3
+
4
+ require_relative './cli/play'
@@ -0,0 +1,33 @@
1
+
2
+ module QB; end
3
+
4
+ # @todo document QB::CLI module.
5
+ module QB::CLI
6
+
7
+ # Play an Ansible playbook (like `state.yml`) in the QB environment
8
+ # (sets up path env vars, IO streams, etc.).
9
+ #
10
+ # @param [type] arg_name
11
+ # @todo Add name param description.
12
+ #
13
+ # @return [return_type]
14
+ # @todo Document return value.
15
+ #
16
+ def self.play args
17
+ if args.empty?
18
+ raise "Need path to playbook in first arg."
19
+ end
20
+
21
+ path = QB::Util.resolve args[0]
22
+
23
+ unless path.file?
24
+ raise "Can't find Ansible playbook at #{ path.to_s }"
25
+ end
26
+
27
+
28
+
29
+ end # .play
30
+
31
+ end # module QB::CLI
32
+
33
+
data/lib/qb/options.rb CHANGED
@@ -4,6 +4,10 @@ require_relative "role/errors"
4
4
  require_relative "options/option"
5
5
  require 'qb/package/version'
6
6
 
7
+ require 'nrser/refinements'
8
+ using NRSER
9
+
10
+
7
11
  module QB
8
12
  class Options
9
13
  # constants
@@ -126,33 +130,69 @@ module QB
126
130
  else
127
131
  ruby_type = case option.meta['type']
128
132
  when nil
129
- raise QB::Role::MetadataError,
130
- "must provide type in qb metadata for option #{ option.meta_name }"
133
+ raise QB::Role::MetadataError.squished <<-END
134
+ must provide type in QB metadata for option
135
+ #{ option.meta_name }
136
+ END
137
+
131
138
  when 'string', 'str'
132
139
  String
140
+
133
141
  when 'array', 'list'
134
142
  Array
143
+
135
144
  when 'integer', 'int'
136
145
  Integer
146
+
137
147
  when 'version'
138
148
  QB::Package::Version
149
+
139
150
  when 'hash', 'dict'
140
151
  Class.new.tap { |klass|
141
- opts.accept(klass) {|value|
152
+ opts.accept(klass) { |value|
142
153
  value.split(',').map { |pair_str|
143
154
  split = pair_str.split ':'
144
155
  if split.length > 2
145
- raise "Can only have a single ':' in hash options, " +
146
- "found #{ pair_str.inspect } in #{ value.inspect }"
156
+ raise ArgumentError.dedented <<-END
157
+
158
+ Can only have a single ':' in `hash` options.
159
+
160
+ Found #{ pair_str.inspect }
161
+
162
+ In #{ value.inspect }
163
+
164
+ END
147
165
  end
148
166
  [split[0], split[1]]
149
167
  }.to_h
150
168
  }
151
169
  }
170
+
171
+ when 'path'
172
+ String
173
+ # Class.new.tap { |klass|
174
+ # opts.accept(klass) { |value|
175
+ #
176
+ # }
177
+ # }
178
+
179
+ when 'glob'
180
+ Class.new.tap { |klass|
181
+ opts.accept(klass) { |glob|
182
+ if glob.start_with? '//'
183
+ glob = NRSER.git_root(Dir.getwd).
184
+ join(glob[2..-1]).
185
+ to_s
186
+ end
187
+
188
+ Dir[glob]
189
+ }
190
+ }
191
+
152
192
  when Hash
153
193
  if option.meta['type'].key? 'one_of'
154
194
  Class.new.tap { |klass|
155
- opts.accept(klass) {|value|
195
+ opts.accept(klass) { |value|
156
196
  if option.meta['type']['one_of'].include? value
157
197
  value
158
198
  else
@@ -209,7 +249,8 @@ module QB
209
249
  option.examples.each_with_index {|example, index|
210
250
  lines = example.lines.to_a
211
251
 
212
- pp lines
252
+ # was this debuggin? had to be...
253
+ # pp lines
213
254
 
214
255
  on_args << ((index + 1).to_s + '.').ljust(4) + lines.first.chomp
215
256