qb 0.1.8 → 0.1.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +41 -2
  3. data/ansible.cfg +2 -2
  4. data/bin/qb +11 -2
  5. data/dev/ansible.cfg +1 -0
  6. data/dev/requirements.yml +4 -4
  7. data/dev/setup.yml +12 -0
  8. data/exe/qb +66 -59
  9. data/lib/qb.rb +120 -1
  10. data/lib/qb/role.rb +39 -0
  11. data/lib/qb/version.rb +1 -1
  12. data/qb.gemspec +1 -0
  13. data/requirements.yml +5 -1
  14. data/roles/qb.build_gem/defaults/main.yml +2 -0
  15. data/roles/qb.build_gem/meta/main.yml +6 -0
  16. data/roles/qb.build_gem/tasks/main.yml +26 -0
  17. data/roles/qb.gem/meta/main.yml +0 -27
  18. data/roles/qb.gem/meta/qb.yml +26 -0
  19. data/roles/qb.git_repo/meta/qb.yml +0 -0
  20. data/roles/qb.gitignore/meta/main.yml +0 -7
  21. data/roles/qb.gitignore/meta/qb.yml +8 -0
  22. data/roles/qb.install_gem/defaults/main.yml +3 -0
  23. data/roles/qb.install_gem/meta/main.yml +12 -0
  24. data/roles/qb.install_gem/meta/qb.yml +6 -0
  25. data/roles/qb.install_gem/tasks/main.yml +2 -0
  26. data/roles/qb.meteor_react_component/defaults/main.yml +6 -0
  27. data/roles/qb.meteor_react_component/library/component_facts.py +39 -0
  28. data/roles/qb.meteor_react_component/meta/main.yml +7 -0
  29. data/roles/qb.meteor_react_component/meta/qb.yml +51 -0
  30. data/roles/qb.meteor_react_component/tasks/main.yml +41 -0
  31. data/roles/qb.meteor_react_component/templates/component.jsx.j2 +75 -0
  32. data/roles/qb.meteor_react_component/templates/style.import.less.j2 +4 -0
  33. data/roles/qb.project/files/requirements.yml +1 -1
  34. data/roles/qb.project/meta/main.yml +0 -46
  35. data/roles/qb.project/meta/qb.yml +48 -0
  36. data/roles/qb.project/tasks/main.yml +0 -6
  37. data/roles/qb.qb_role/.qb-options.yml +3 -0
  38. data/roles/qb.qb_role/defaults/main.yml +10 -0
  39. data/roles/qb.qb_role/meta/main.yml +15 -0
  40. data/roles/qb.qb_role/meta/qb.yml +47 -0
  41. data/roles/qb.qb_role/tasks/main.yml +13 -0
  42. data/roles/qb.qb_role/templates/.gitkeep +0 -0
  43. data/roles/qb.qb_role/templates/qb.yml.j2 +21 -0
  44. data/roles/qb.role/defaults/main.yml +2 -1
  45. data/roles/qb.role/meta/main.yml +0 -26
  46. data/roles/qb.role/meta/qb.yml +47 -0
  47. data/roles/qb.role/templates/defaults/main.yml.j2 +1 -1
  48. data/roles/qb.role/templates/handlers/main.yml.j2 +1 -1
  49. data/roles/qb.role/templates/meta/main.yml.j2 +3 -1
  50. data/roles/qb.role/templates/tasks/main.yml.j2 +1 -1
  51. data/roles/qb.role/templates/vars/main.yml.j2 +1 -1
  52. metadata +43 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d706144a98f2797e7a3e769004fed6890b1b704f
4
- data.tar.gz: d942bae9e4910084d0a347c86f38b626710fd1e3
3
+ metadata.gz: 80033c6e7eace5353695c0cf1239a972bff0c76f
4
+ data.tar.gz: 15a2d8f53620eba3538be272165fdda0eb11f51f
5
5
  SHA512:
6
- metadata.gz: 09217bdb8cfc0226c872a77f4c36434bf03e5631ab4896161cd85cd89dfdc09e12043a896628068ac366d48861b74bba0933d246cda98c2ee7684e7933193028
7
- data.tar.gz: 3d1a3cd57388a88a7d707096297a6c0e195df62b1de7428dbc8f3be62a70f4598f0d82d6ea505c2812ccad190a59947b5cd216bb8b3da1e11c1a1a539ef29d32
6
+ metadata.gz: 0d317ec3cade70ada821b6952efdf28aca34a8a6ce5b8da308e50270509717326422b7c19a3d4625aeb3ce6037cb095a4429b6ea390aaff36ebd27bf984b7391
7
+ data.tar.gz: 306fdab6c084efa4351eafdc4541f3f0e0b9e1983ce7153f8f471218aa4fb827abcbd150e3b4e0dd95b1b5fb6523e63ea60f5c19f2ee52e49b348a529a30bbd9
data/README.md CHANGED
@@ -1,4 +1,43 @@
1
- qb
2
- ==
1
+ # qb #
3
2
 
4
3
  qb is all about projects. named after everyone's favorite projects.
4
+
5
+ ## meta/qb.yml ##
6
+
7
+ if this file exists in a role `qb` sees it will make that role available.
8
+
9
+ the contents of this file allow you to configure how `qb` uses the role.
10
+
11
+ ### var_prefix ###
12
+
13
+ declare prefix to be added to variable names from the command line for
14
+ use in the role.
15
+
16
+ because all variables are pretty much global in ansible, you really want to prefix all your variables names to try and achieve uniqueness. the way i've been doing that is to prefix them with the 'namespaceless' part of the role name.
17
+
18
+ for example, if you have a role named `qb.project`, the 'namespace' would be `qb` and the 'namespaceless' part would be `project`. it has been my convention to then name the role variables `project_*`, like `project_owner`, `project_name`, etc..
19
+
20
+ `var_prefix` therefore defaults to the 'namespaceless' part of the role name, so that a call like
21
+
22
+ qb qb.project --owner=nrser --name=blah
23
+
24
+ will pass variables
25
+
26
+ project_owner: "nrser"
27
+ project_name: "blah"
28
+
29
+ to the `qb.project` role.
30
+
31
+ however, this setting allows you to specify an alternative prefix.
32
+
33
+ if this is set to `null` or any varient of `false` the default will be used.
34
+
35
+ ### default_dir ###
36
+
37
+ every invocation of `qb` must have a directory it's targeting where it will place a `.qb-options.yml` if applicable. this directory is passed to the role as the `dir` option
38
+
39
+ this is often the project's root folder, and can sometimes be assembled from the values of other parameters.
40
+
41
+ ### vars ###
42
+
43
+ TODO
@@ -1,5 +1,5 @@
1
1
  [defaults]
2
2
 
3
- roles_path = ./tmp/roles:./roles
4
-
3
+ # roles_path = ./tmp/roles:./roles
5
4
  filter_plugins = ./roles/qb.gem/filter_plugins
5
+ retry_files_enabled = False
data/bin/qb CHANGED
@@ -1,4 +1,13 @@
1
1
  #!/usr/bin/env ruby
2
2
  # stub instead of `bundle exec qb ...`
3
- require 'bundler/setup'
4
- load 'exe/qb'
3
+
4
+ # so you know you're using the local repo version (vs an installed gem)...
5
+ puts "*** LOADING REPO VERSION ***\n\n"
6
+
7
+ root = File.dirname(File.realpath(File.join(__FILE__, '..')))
8
+
9
+ Dir.chdir root do
10
+ require 'bundler/setup'
11
+ end
12
+
13
+ load File.join(root, 'exe/qb')
@@ -2,3 +2,4 @@
2
2
 
3
3
  roles_path = ./roles/tmp:./roles
4
4
  inventory = ./hosts
5
+ retry_files_enabled = False
@@ -1,12 +1,12 @@
1
1
  - name: nrser.nodenv
2
2
  src: https://github.com/nrser/ansible-nrser.nodenv.git
3
- version: v0.1.0
3
+ version: v0.1.2
4
4
  - name: nrser.rbenv_gem
5
5
  src: https://github.com/nrser/ansible-nrser.rbenv_gem.git
6
- version: v0.1.1
6
+ version: v0.1.3
7
7
  - name: nrser.rbenv
8
8
  src: https://github.com/nrser/ansible-nrser.rbenv.git
9
- version: v0.1.0
9
+ version: v0.1.2
10
10
  - name: nrser.dev_setup
11
11
  src: https://github.com/nrser/ansible-nrser.dev_setup.git
12
- version: v0.1.1
12
+ version: v0.1.3
@@ -17,6 +17,18 @@
17
17
 
18
18
  - owner: nrser
19
19
  name: ansible-nrser.dev_setup
20
+
21
+ - owner: nrser
22
+ name: ansible-nrser.rbenv_gem
23
+
24
+ - owner: nrser
25
+ name: cmds
26
+
27
+ - owner: nrser
28
+ name: ansible-nrser.nodenv
29
+
30
+ - owner: nrser
31
+ name: ansible-nrser.rbenv
20
32
 
21
33
  # sources that are used for reference only
22
34
  dev_setup_refs:
data/exe/qb CHANGED
@@ -14,8 +14,8 @@ require 'qb'
14
14
  # constants
15
15
  # =========
16
16
 
17
- ROOT = (Pathname.new(__FILE__).dirname + '..').expand_path
18
- ROLES_DIR = ROOT + 'roles'
17
+ ROOT = QB::ROOT
18
+ ROLES_DIR = QB::ROLES_DIR
19
19
  ROLES = Pathname.glob(ROLES_DIR + 'qb.*').map {|path| path.basename.to_s}
20
20
  DEBUG_ARGS = ['-d', '--debug']
21
21
  TMP_DIR = ROOT + 'tmp'
@@ -23,8 +23,6 @@ TMP_DIR = ROOT + 'tmp'
23
23
  # globals
24
24
  # =======
25
25
 
26
- $debug = false
27
-
28
26
  # @api util
29
27
  # *pure*
30
28
  #
@@ -39,30 +37,21 @@ def format msg, dump = {}
39
37
  msg
40
38
  end
41
39
 
42
- def debug *args
43
- return unless $debug
44
-
45
- msg, values = case args.length
46
- when 0
47
- raise ArgumentError, "debug needs at least one argument"
48
- when 1
49
- if args[0].is_a? Hash
50
- ['', args[0]]
51
- else
52
- [args[0], {}]
53
- end
54
- when 2
55
- [args[0], args[1]]
56
- else
57
- raise ArgumentError, "debug needs at least one argument"
58
- end
40
+ def role? pathname
41
+ pathname.directory? && pathname.join('meta', 'qb.yml').file?
42
+ end
43
+
44
+ def role_matches
59
45
 
60
- $stderr.puts("DEBUG " + format(msg, values))
46
+ end
47
+
48
+ def debug *args
49
+ QB.debug *args
61
50
  end
62
51
 
63
52
  def set_debug! args
64
53
  if DEBUG_ARGS.any? {|arg| args.include? arg}
65
- $debug = true
54
+ QB.debug = true
66
55
  debug "ON"
67
56
  DEBUG_ARGS.each {|arg| args.delete arg}
68
57
  end
@@ -84,7 +73,8 @@ def parse! role_arg, var_prefix, vars, defaults, args
84
73
  options = {}
85
74
 
86
75
  opt_parser = OptionParser.new do |opts|
87
- opts.banner = "qb #{ role_arg } [OPTIONS]#{ positional_banner }"
76
+ # opts.banner = "qb #{ role_arg } [OPTIONS]#{ positional_banner }"
77
+ opts.banner = "qb #{ role_arg } [OPTIONS] DIRECTORY"
88
78
 
89
79
  vars.each do |var|
90
80
  arg_name = var.fetch 'name'
@@ -159,6 +149,15 @@ def parse! role_arg, var_prefix, vars, defaults, args
159
149
  options
160
150
  end
161
151
 
152
+ # needed for to clean the env if using bundler (like in dev)
153
+ def with_clean_env &block
154
+ if defined? Bundler
155
+ Bundler.with_clean_env &block
156
+ else
157
+ block.call
158
+ end
159
+ end
160
+
162
161
  def help
163
162
  puts <<-END
164
163
  version: #{ QB::VERSION }
@@ -172,7 +171,7 @@ use `qb ROLE -h` for role options.
172
171
  available roles:
173
172
 
174
173
  END
175
- puts ROLES
174
+ puts QB.available_roles
176
175
  puts
177
176
  exit 1
178
177
  end
@@ -186,9 +185,7 @@ def main args
186
185
 
187
186
  help if role_arg.nil? || ['-h', '--help', 'help'].include?(role_arg)
188
187
 
189
- matches = ROLES.select {|role|
190
- role.include? role_arg
191
- }
188
+ matches = QB.role_matches role_arg
192
189
  debug "role matches" => matches
193
190
 
194
191
  role = case matches.length
@@ -205,41 +202,32 @@ def main args
205
202
  end
206
203
  debug role: role
207
204
 
208
- role_dir = ROLES_DIR + role
205
+ defaults_path = role.path + 'defaults' + 'main.yml'
206
+ defaults = if defaults_path.file?
207
+ YAML.load(defaults_path.read) || {}
208
+ else
209
+ {}
210
+ end
209
211
 
210
- defaults = YAML.load (role_dir + 'defaults' + 'main.yml').read
211
- meta = YAML.load (role_dir + 'meta' + 'main.yml').read
212
+ qb_meta = YAML.load((role.path + 'meta' + 'qb.yml').read) || {}
212
213
 
213
- qb_info = meta['qb_info'] || {}
214
- vars = qb_info['vars'] || []
215
- var_prefix = qb_info['var_prefix'] || role.split('.').last
214
+ vars = qb_meta['vars'] || []
215
+ var_prefix = qb_meta['var_prefix'] || role.namespaceless
216
216
 
217
217
  options = parse! role_arg, var_prefix, vars, defaults, args
218
218
 
219
219
  debug options: options
220
220
 
221
+ cwd = Dir.getwd
222
+
221
223
  # get the target dir
222
224
  dir = case args.length
223
225
  when 0
224
226
  # in this case, a dir has not been provided
225
227
  #
226
- # in some cases (like projects) the dir can be figured out from other
227
- # variables. i created a hacky-ass way of dealing with this:
228
- #
229
- # when the sole positional arg is missing, we look for a `qb/get_dir`
230
- # executable in the role. if it exists, call it with the JSON encoded
231
- # options passed over STDIN. if the execuable succeeds, the result is
232
- # taken as dir.
228
+ # in some cases (like projects) the dir can be figured out in other ways:
233
229
  #
234
- get_dir_path = role_dir + 'qb' + 'get_dir'
235
-
236
- unless get_dir_path.exist?
237
- raise "no dir argument provided and no qb/get_dir exe found"
238
- end
239
-
240
- Cmds.chomp! get_dir_path.to_s do
241
- JSON.dump options
242
- end
230
+ QB.get_default_dir role, qb_meta, cwd, options
243
231
 
244
232
  when 1
245
233
  # there is a single positional arg, which is used as dir
@@ -247,7 +235,7 @@ def main args
247
235
 
248
236
  else
249
237
  # there are multiple positional args, which is not allowed
250
- raise "can't supply more than one argument"
238
+ raise "can't supply more than one argument: #{ args.inspect }"
251
239
 
252
240
  end
253
241
 
@@ -270,16 +258,18 @@ def main args
270
258
  {}
271
259
  end
272
260
 
273
- if saved_options.key? role
274
- options = saved_options[role].merge options
261
+ if saved_options.key? role.options_key
262
+ options = saved_options[role.options_key].merge options
275
263
  end
276
264
 
277
- playbook_role = {'role' => role}
265
+ playbook_role = {'role' => role.name}
278
266
  options.each do |arg_name, arg_value|
279
267
  playbook_role["#{ var_prefix }_#{ arg_name }"] = arg_value
280
268
  end
281
269
 
282
270
  playbook_role['dir'] = dir
271
+ playbook_role['qb_dir'] = dir
272
+ playbook_role['qb_cwd'] = cwd
283
273
 
284
274
  playbook = [
285
275
  {
@@ -303,21 +293,38 @@ def main args
303
293
  f.write YAML.dump(playbook)
304
294
  end
305
295
 
306
- unless options.empty?
307
- saved_options[role] = options
296
+ unless (
297
+ options.empty? ||
298
+ (qb_meta.key?('save_options') && qb_meta['save_options'] == false)
299
+ )
300
+ saved_options[role.options_key] = options
308
301
  FileUtils.mkdir_p saved_options_path.dirname unless saved_options_path.dirname.exist?
309
302
  saved_options_path.open('w') do |f|
310
303
  f.write YAML.dump(saved_options)
311
304
  end
312
305
  end
313
306
 
307
+ tmp_roles_path = QB::ROOT + 'tmp' + 'roles'
308
+
309
+ ansible_roles_path = (
310
+ [tmp_roles_path] +
311
+ QB.role_dirs
312
+ ).join(':')
313
+
314
314
  Dir.chdir ROOT do
315
315
  # install requirements
316
316
  unless (TMP_DIR + 'roles').directory?
317
- Cmds.stream! "ansible-galaxy install --ignore-errors -r %s", [ROOT + 'requirements.yml']
317
+ with_clean_env do
318
+ Cmds.stream! "ANSIBLE_ROLES_PATH=<%= roles_path %> ansible-galaxy install --ignore-errors -r <%= req_path%>",
319
+ req_path: (ROOT + 'requirements.yml'),
320
+ roles_path: tmp_roles_path.to_s
321
+ end
322
+ end
323
+ with_clean_env do
324
+ Cmds.stream! "ANSIBLE_ROLES_PATH=<%= roles_path %> ansible-playbook <%= playbook_path %>",
325
+ roles_path: ansible_roles_path,
326
+ playbook_path: playbook_path.to_s
318
327
  end
319
-
320
- Cmds.stream! "ansible-playbook %s", [playbook_path.to_s]
321
328
  end
322
329
  end
323
330
 
data/lib/qb.rb CHANGED
@@ -1,5 +1,124 @@
1
+ require 'nrser/extras'
2
+
1
3
  require "qb/version"
2
4
 
3
5
  module QB
4
- # Your code goes here...
6
+ ROOT = (Pathname.new(__FILE__).dirname + '..').expand_path
7
+ ROLES_DIR = ROOT + 'roles'
8
+
9
+ # TODO this should be in an instance that is run instead of module global
10
+ # hack for now
11
+ @@debug = false
12
+
13
+ def self.debug= bool
14
+ @@debug = !!bool
15
+ end
16
+
17
+ def self.debug *args
18
+ return unless @@debug
19
+
20
+ msg, values = case args.length
21
+ when 0
22
+ raise ArgumentError, "debug needs at least one argument"
23
+ when 1
24
+ if args[0].is_a? Hash
25
+ ['', args[0]]
26
+ else
27
+ [args[0], {}]
28
+ end
29
+ when 2
30
+ [args[0], args[1]]
31
+ else
32
+ raise ArgumentError, "debug needs at least one argument"
33
+ end
34
+
35
+ $stderr.puts("DEBUG " + format(msg, values))
36
+ end
37
+
38
+ def self.role_dirs
39
+ [
40
+ ROLES_DIR,
41
+ Pathname.new(Dir.getwd).join('roles'),
42
+ Pathname.new(Dir.getwd).join('dev', 'roles'),
43
+ Pathname.new(Dir.getwd).join('dev', 'roles', 'tmp'),
44
+ ]
45
+ end
46
+
47
+ def self.available_roles
48
+ role_dirs.
49
+ select {|role_dir|
50
+ role_dir.directory?
51
+ }.
52
+ map {|role_dir|
53
+ role_dir.children.select {|child| role? child }
54
+ }.
55
+ flatten.
56
+ uniq.
57
+ map {|role_dir|
58
+ QB::Role.new role_dir
59
+ }
60
+ end
61
+
62
+ def self.role_matches input
63
+ available_roles.each {|role|
64
+ # exact match to relitive path
65
+ return [role] if role.rel_path.to_s == input
66
+ }.each {|role|
67
+ # exact match to full name
68
+ return [role] if role.name == input
69
+ }.each {|role|
70
+ # exact match without the namespace prefix ('qb.' or similar)
71
+ return [role] if role.namespaceless == input
72
+ }.select {|role|
73
+ # select any that have that string in them
74
+ role.rel_path.to_s.include? input
75
+ }
76
+ end
77
+
78
+ def self.get_default_dir role, qb_meta, cwd, options
79
+ debug "get_default_dir", role: role,
80
+ qb_meta: qb_meta,
81
+ cwd: cwd,
82
+ options: options
83
+
84
+ key = 'default_dir'
85
+ case qb_meta[key]
86
+ when nil, false
87
+ # there is no get_dir info in meta/qb.yml, can't get the dir
88
+ raise "unable to infer default directory: no '#{ key }' key in meta/qb.yml"
89
+
90
+ when 'git_root'
91
+ debug "returning the git root relative to cwd"
92
+ NRSER.git_root cwd
93
+
94
+ when 'cwd'
95
+ debug "returing current working directory"
96
+ cwd
97
+
98
+ when Hash
99
+ debug "qb meta option is a Hash"
100
+
101
+ if qb_meta[key].key? 'exe'
102
+ exe_path = qb_meta[key]['exe']
103
+ exe_input_data = options
104
+
105
+ unless exe_path.start_with?('~') || exe_path.start_with?('/')
106
+ exe_path = File.join(role.path, exe_path)
107
+ debug 'exe path is relative, basing off role dir', exe_path: exe_path
108
+ end
109
+
110
+ debug "found 'exe' key, calling", exe_path: exe_path,
111
+ exe_input_data: exe_input_data
112
+
113
+ Cmds.chomp! exe_path do
114
+ JSON.dump exe_input_data
115
+ end
116
+ else
117
+ raise "not sure to process '#{ key }' in metea/qb.yml"
118
+ end
119
+ end
120
+ end
5
121
  end
122
+
123
+ # needs QB::ROLES_DIR
124
+ require 'qb/role'