qb 0.3.1 → 0.3.2

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 (52) hide show
  1. checksums.yaml +4 -4
  2. data/exe/qb +39 -1
  3. data/lib/qb/cli.rb +104 -1
  4. data/lib/qb/errors.rb +25 -2
  5. data/lib/qb/options.rb +33 -2
  6. data/lib/qb/options/option.rb +1 -0
  7. data/lib/qb/role.rb +53 -21
  8. data/lib/qb/role/errors.rb +3 -3
  9. data/lib/qb/version.rb +1 -1
  10. data/qb.gemspec +1 -1
  11. data/roles/qb.project/tasks/main.yml +1 -0
  12. data/roles/qb.role/defaults/main.yml +3 -1
  13. data/roles/qb/gem/new/defaults/main.yml +12 -0
  14. data/roles/{qb.git_check_clean → qb/gem/new}/meta/main.yml +1 -1
  15. data/roles/qb/gem/new/meta/qb.yml +90 -0
  16. data/roles/qb/gem/new/tasks/bundle_gem.yml +97 -0
  17. data/roles/qb/gem/new/tasks/main.yml +22 -0
  18. data/roles/qb/gem/release/defaults/main.yml +5 -0
  19. data/roles/{qb.release_gem → qb/gem/release}/meta/main.yml +1 -1
  20. data/roles/{qb.release_gem → qb/gem/release}/meta/qb.yml +2 -2
  21. data/roles/{qb.release_gem → qb/gem/release}/tasks/main.yml +57 -35
  22. data/roles/qb/git/check/clean/README.md +4 -0
  23. data/roles/qb/git/check/clean/meta/main.yml +8 -0
  24. data/roles/{qb.git_check_clean → qb/git/check/clean}/tasks/main.yml +5 -5
  25. data/roles/qb/osx/notif/defaults/main.yml +4 -0
  26. data/roles/qb/osx/notif/meta/main.yml +8 -0
  27. data/roles/qb/osx/notif/meta/qb.yml +81 -0
  28. data/roles/qb/osx/notif/tasks/main.yml +14 -0
  29. metadata +20 -32
  30. data/roles/qb.gem/.qb-options.yml +0 -4
  31. data/roles/qb.gem/defaults/main.yml +0 -17
  32. data/roles/qb.gem/files/.gitkeep +0 -0
  33. data/roles/qb.gem/files/.rspec +0 -2
  34. data/roles/qb.gem/files/Rakefile +0 -6
  35. data/roles/qb.gem/files/setup +0 -7
  36. data/roles/qb.gem/filter_plugins/ruby_constantize.py +0 -22
  37. data/roles/qb.gem/meta/main.yml +0 -8
  38. data/roles/qb.gem/meta/qb.yml +0 -26
  39. data/roles/qb.gem/tasks/main.yml +0 -105
  40. data/roles/qb.gem/templates/.gitkeep +0 -0
  41. data/roles/qb.gem/templates/.travis.yml.j2 +0 -4
  42. data/roles/qb.gem/templates/BSD2-LICENSE.txt.j2 +0 -23
  43. data/roles/qb.gem/templates/BSD3-LICENSE.txt.j2 +0 -27
  44. data/roles/qb.gem/templates/Gemfile.j2 +0 -4
  45. data/roles/qb.gem/templates/MIT-LICENSE.txt.j2 +0 -21
  46. data/roles/qb.gem/templates/console.j2 +0 -14
  47. data/roles/qb.gem/templates/gemspec.j2 +0 -36
  48. data/roles/qb.gem/templates/module.rb.j2 +0 -5
  49. data/roles/qb.gem/templates/spec.rb.j2 +0 -11
  50. data/roles/qb.gem/templates/spec_helper.rb.j2 +0 -2
  51. data/roles/qb.gem/templates/version.rb.j2 +0 -3
  52. data/roles/qb.release_gem/defaults/main.yml +0 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 58d2c1fbf4d57fdd1b607cf1c8716104b61a9909
4
- data.tar.gz: 0b845dc2f323e3fb3e0f00a006af1f04f5d1a6a9
3
+ metadata.gz: aecaf8f95cd10cc55b8193bc77ffff7fd0d1010e
4
+ data.tar.gz: eb52aa099c5e8b7fa1131799cbf536a5b3b20783
5
5
  SHA512:
6
- metadata.gz: b3491012bb23264bc31f2f7c52f655f9b4a5a30e26c5efcaca05ed83f8240bad2402e8b1d14700be7433a30f14bbd2b990997b9b0a960b2244803117ac972f29
7
- data.tar.gz: 2386308ce3bb76e0eea32a7dc6f6f9ca44c85d9cf90ef035b86e8cb3bd4f638d7b0bdf8b01e7653d601c775df4ffa73081fa8c6f27652754a65319b5a8fd2413
6
+ metadata.gz: 6e6a2772f752a0118d218cb84c31f220d3f3ccbe6dc09da03052c9a381a33fba2bb1532e23f73d70cf4f6fd0b8e64f61512ce779ec9c7ea99e5aa47a81d1ee40
7
+ data.tar.gz: d31d2a6d530cca5f201a0a366590110966dcef054195529cde8b56a44aece10220f4d55da9c803e54dd42f2a19f28b46c39ea2f59ba81b54779ff1a7ef3c7099
data/exe/qb CHANGED
@@ -10,6 +10,13 @@ require 'cmds'
10
10
 
11
11
  require 'qb'
12
12
 
13
+ require 'nrser/refinements'
14
+ using NRSER
15
+
16
+ require 'nrser/refinements/types'
17
+ using NRSER::Types
18
+
19
+
13
20
  # constants
14
21
  # =========
15
22
 
@@ -98,7 +105,21 @@ def main args
98
105
  #
99
106
  # in some cases (like projects) the dir can be figured out in other ways:
100
107
  #
101
- role.default_dir cwd, options.role_options
108
+
109
+ if options.ask?
110
+ default = begin
111
+ role.default_dir cwd, options.role_options
112
+ rescue QB::UserInputError => e
113
+ NRSER::NO_ARG
114
+ end
115
+
116
+ QB::CLI.ask name: "target directory (`qb_dir`)",
117
+ type: t.non_empty_str,
118
+ default: default
119
+
120
+ else
121
+ role.default_dir cwd, options.role_options
122
+ end
102
123
 
103
124
  when 1
104
125
  # there is a single positional arg, which is used as dir
@@ -159,6 +180,23 @@ def main args
159
180
  end
160
181
  end # unless default_dir == false
161
182
 
183
+
184
+ # Interactive Input
185
+ # =====================================================================
186
+
187
+ if options.ask?
188
+ # Incomplete
189
+ raise "COMING SOON!!!...?"
190
+ QB::CLI.ask_for_options role: role, options: options
191
+ end
192
+
193
+
194
+ # Validation
195
+ # =====================================================================
196
+ #
197
+ # Should have already been taken care of if we used interactive input.
198
+ #
199
+
162
200
  # check that required options are present
163
201
  missing = options.role_options.values.select {|option|
164
202
  option.required? && option.value.nil?
@@ -1,4 +1,107 @@
1
+ require 'nrser/refinements'
2
+ using NRSER
3
+
4
+
1
5
  module QB; end
2
- module QB::CLI; end
6
+ module QB::CLI
7
+
8
+ # Eigenclass (Singleton Class)
9
+ # ========================================================================
10
+ #
11
+ class << self
12
+
13
+
14
+ # @todo Document ask method.
15
+ #
16
+ # @param [type] arg_name
17
+ # @todo Add name param description.
18
+ #
19
+ # @return [return_type]
20
+ # @todo Document return value.
21
+ #
22
+ def ask name:,
23
+ description: nil,
24
+ type:,
25
+ default: NRSER::NO_ARG
26
+ puts
27
+
28
+ value = loop do
29
+
30
+ puts "Enter value for #{ name }"
31
+
32
+ if description
33
+ puts description.indent
34
+ end
35
+
36
+ puts "TYPE #{ type.to_s }".indent
37
+
38
+ if default
39
+ puts "DEFAULT #{ default.to_s }".indent
40
+ end
41
+
42
+ $stdout.write '> '
43
+
44
+ value = gets.chomp
45
+
46
+ QB.debug "User input", value
47
+
48
+ if value == '' && default != NRSER::NO_ARG
49
+ puts <<-END.dedent
50
+
51
+ Using default value #{ default.to_s }
52
+
53
+ END
54
+
55
+ return default
56
+ end
57
+
58
+ begin
59
+ type.from_s value
60
+ rescue TypeError => e
61
+ puts <<-END.dedent
62
+ Input value #{ value.inspect } failed to satisfy type
63
+
64
+ #{ type.to_s }
65
+
66
+ END
67
+ else
68
+ break value
69
+ end
70
+
71
+ end # loop
72
+
73
+ puts "Using value #{ value.inspect }"
74
+
75
+ return value
76
+
77
+ end # #ask
78
+
79
+
80
+ def ask_for_option role:, option:
81
+ default = if role.defaults.key?(option.var_name)
82
+ role.defaults[option.var_name]
83
+ elsif option.required?
84
+ NRSER::NO_ARG
85
+ else
86
+ nil
87
+ end
88
+
89
+ ask name: option.name,
90
+ description: option.description,
91
+ default: default
92
+ # type:
93
+ end
94
+
95
+
96
+ def ask_for_options role:, options:
97
+ options.select { |opt| opt.value.nil? }.each { |option|
98
+ ask_for_option role: role, option: option
99
+ }
100
+ end # #ask_for_options
101
+
102
+
103
+ end # class << self (Eigenclass)
104
+
105
+ end
3
106
 
4
107
  require_relative './cli/play'
@@ -2,8 +2,20 @@ module QB
2
2
  # Base class for QB errors.
3
3
  class Error < StandardError; end
4
4
 
5
+
6
+ # State Errors
7
+ # =====================================================================
8
+ #
9
+ # Raised when something - a role, the file system, etc. - is in a state
10
+ # that we can't deal with.
11
+ #
12
+
13
+ # Raised when something is in a bad state and no more specific error
14
+ # subclass applies.
15
+ class StateError < Error; end
16
+
5
17
  # Raised when a version mismatch occurs.
6
- class VersionError < Error; end
18
+ class VersionError < StateError; end
7
19
 
8
20
  # Raised when the current Ansible version doesn't satisfy:
9
21
  #
@@ -19,5 +31,16 @@ module QB
19
31
 
20
32
  # Raised when the file system is in a state that doesn't work for what we're
21
33
  # trying to do.
22
- class FSStateError < Error; end
34
+ class FSStateError < StateError; end
35
+
36
+
37
+ # User Input Errors
38
+ # =====================================================================
39
+ #
40
+ # Raised when we got bad user input.
41
+ #
42
+
43
+ # Raised when we got bad user input and no more specific error applies.
44
+ class UserInputError < Error; end
45
+
23
46
  end # module QB
@@ -19,6 +19,7 @@ module QB
19
19
  'print' => ['cmd'],
20
20
  'verbose' => false,
21
21
  'run' => true,
22
+ 'ask' => false,
22
23
  }
23
24
 
24
25
  # appended on the end of an `opts.on` call to create a newline after
@@ -310,10 +311,27 @@ module QB
310
311
  def initialize role, argv
311
312
  @role = role
312
313
  @argv = argv
314
+ @qb = QB_DEFAULTS.clone
313
315
 
314
316
  parse!
315
317
  end
316
318
 
319
+
320
+
321
+ # @todo Document ask? method.
322
+ #
323
+ # @param [type] arg_name
324
+ # @todo Add name param description.
325
+ #
326
+ # @return [return_type]
327
+ # @todo Document return value.
328
+ #
329
+ def ask?
330
+ @qb['ask']
331
+ end # #ask?
332
+
333
+
334
+
317
335
  private
318
336
  # =======================================================================
319
337
 
@@ -324,8 +342,6 @@ module QB
324
342
 
325
343
  @role_options = {}
326
344
 
327
- @qb = QB_DEFAULTS.clone
328
-
329
345
  if @role.meta['default_user']
330
346
  @qb['user'] = @role.meta['default_user']
331
347
  end
@@ -426,6 +442,21 @@ module QB
426
442
  @qb['run'] = false
427
443
  end
428
444
 
445
+ opts.on(
446
+ '-A',
447
+ '--ASK',
448
+ "interactively ask for argument and option values",
449
+ SPACER
450
+ ) do |value|
451
+ if value && !$stdin.isatty
452
+ raise ArgumentError.squished <<-END
453
+ Interactive args & options only works with TTY $stdin.
454
+ END
455
+ end
456
+
457
+ @qb['ask'] = value
458
+ end
459
+
429
460
  self.class.add opts, @role_options, @role
430
461
 
431
462
  opts.on_tail("-h", "--help", "Show this message") do
@@ -108,6 +108,7 @@ module QB
108
108
  if value.is_a? String then [value] else value end
109
109
  end
110
110
 
111
+
111
112
  private
112
113
 
113
114
  # get the value at the first found of the keys or the default.
@@ -1,10 +1,11 @@
1
1
  require 'yaml'
2
2
  require 'cmds'
3
3
  require 'parseconfig'
4
- require 'nrser/refinements'
5
4
 
6
5
  require_relative 'role/errors'
7
6
 
7
+ require 'nrser/refinements'
8
+
8
9
  using NRSER
9
10
 
10
11
  module QB
@@ -373,6 +374,7 @@ module QB
373
374
  end
374
375
  end
375
376
 
377
+
376
378
  # the path we display in the CLI, see {#display_path}.
377
379
  #
378
380
  # @param [Pathname | String] path
@@ -390,6 +392,25 @@ module QB
390
392
  end
391
393
 
392
394
 
395
+ def self.guess_role_name dest
396
+ path = QB::Util.resolve dest
397
+
398
+ search_dirs = search_path.find_all { |pathname|
399
+ path.fnmatch? pathname.join('**')
400
+ }
401
+
402
+ case search_dirs.length
403
+ when 0
404
+ # It's not in any of the search directories
405
+ #
406
+ # If it has 'roles' as a segment than use what's after that
407
+ #
408
+ split = path.to_s.split('/roles/')
409
+
410
+ end
411
+ end
412
+
413
+
393
414
  # Attributes
394
415
  # =======================================================================
395
416
 
@@ -469,10 +490,6 @@ module QB
469
490
  # Instance Methods
470
491
  # =====================================================================
471
492
 
472
- def to_s
473
- @display_path.to_s
474
- end
475
-
476
493
  def namespace
477
494
  *namespace_segments, last = @name.split File::Separator
478
495
 
@@ -698,7 +715,7 @@ module QB
698
715
  case value
699
716
  when nil
700
717
  # there is no get_dir info in meta/qb.yml, can't get the dir
701
- raise <<-END.dedent
718
+ raise QB::UserInputError.dedented <<-END
702
719
  unable to infer default directory: no '#{ key }' key in 'meta/qb.yml'
703
720
  for role #{ self }
704
721
  END
@@ -706,7 +723,9 @@ module QB
706
723
  when false
707
724
  # this method should not get called when the value is false (an entire
708
725
  # section is skipped in exe/qb when `default_dir = false`)
709
- raise "role does not use default directory (meta/qb.yml:default_dir = false)"
726
+ raise QB::StateError.squished <<-END
727
+ role does not use default directory (meta/qb.yml:default_dir = false)
728
+ END
710
729
 
711
730
  when 'git_root'
712
731
  QB.debug "returning the git root relative to cwd"
@@ -761,7 +780,9 @@ module QB
761
780
  QB::Util.find_up filename
762
781
 
763
782
  else
764
- raise "bad key: #{ hash_key } in #{ self.meta_path.to_s }:default_dir"
783
+ raise QB::Role::MetadataError.squised <<-END
784
+ bad key: #{ hash_key } in #{ self.meta_path.to_s }:default_dir
785
+ END
765
786
 
766
787
  end
767
788
  end
@@ -798,28 +819,39 @@ module QB
798
819
  path.realpath.hash
799
820
  end
800
821
 
822
+
801
823
  def == other
802
824
  other.is_a?(Role) && other.path.realpath == path.realpath
803
825
  end
804
826
 
805
827
  alias_method :eql?, :==
806
828
 
829
+ # @return [String]
830
+ # {QB::Role#display_path}
831
+ #
832
+ def to_s
833
+ @display_path.to_s
834
+ end
835
+
836
+
807
837
  private
808
838
  # -----------------------------------------------------------------------
809
839
 
810
- # get the value at the first found of the keys or the default.
811
- #
812
- # `nil` (`null` in yaml files) are treated like they're not there at
813
- # all. you need to use `false` if you want to tell QB not to do something.
814
- #
815
- def meta_or keys, default
816
- keys = [keys] if keys.is_a? String
817
- keys.each do |key|
818
- if meta.key?(key) && !meta[key].nil?
819
- return meta[key]
840
+ # get the value at the first found of the keys or the default.
841
+ #
842
+ # `nil` (`null` in yaml files) are treated like they're not there at
843
+ # all. you need to use `false` if you want to tell QB not to do something.
844
+ #
845
+ def meta_or keys, default
846
+ keys = [keys] if keys.is_a? String
847
+ keys.each do |key|
848
+ if meta.key?(key) && !meta[key].nil?
849
+ return meta[key]
850
+ end
820
851
  end
821
- end
822
- default
823
- end # meta_or
852
+ default
853
+ end # meta_or
854
+
855
+ # end private
824
856
  end # Role
825
857
  end # QB
@@ -1,7 +1,7 @@
1
1
  module QB
2
2
  class Role
3
3
  # raised by `.require` when no roles match input
4
- class NoMatchesError < QB::Error
4
+ class NoMatchesError < QB::UserInputError
5
5
  attr_accessor :input
6
6
 
7
7
  def initialize input
@@ -12,7 +12,7 @@ module QB
12
12
  end
13
13
 
14
14
  # raised by `.require` when multiple roles match
15
- class MultipleMatchesError < QB::Error
15
+ class MultipleMatchesError < QB::UserInputError
16
16
  attr_accessor :input, :matches
17
17
 
18
18
  def initialize input, matches
@@ -33,7 +33,7 @@ END
33
33
  end
34
34
 
35
35
  # raised when there's bad metadata
36
- class MetadataError < QB::Error
36
+ class MetadataError < QB::StateError
37
37
  end
38
38
  end # Role
39
39
  end # QB