qb 0.3.1 → 0.3.2

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/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