Class: QB::Role

Inherits:
Object
  • Object
show all
Defined in:
lib/qb/role.rb,
lib/qb/role/errors.rb

Overview

Contains info on a QB role.

Defined Under Namespace

Classes: MetadataError, MultipleMatchesError, NoMatchesError

Constant Summary collapse

BUILTIN_PATH =

Array of string paths to directories to search for roles or paths to ansible.cfg files to look for an extract role paths from.

For the moment at least you can just mutate this value like you would $LOAD_PATH:

QB::Role::PATH.unshift '~/where/some/roles/be'
QB::Role::PATH.unshift '~/my/ansible.cfg'

The paths are searched from first to last.

WARNING

Search is deep - don't point this at large directory trees and expect any sort of reasonable performance (any directory that contains node_modules is usually a terrible idea for instance).

[
  
  # Development Paths
  # =================
  # 
  # These come first because:
  # 
  # 1.  They are working dir-local.
  # 
  # 2.  They should only be present in local development, and should be
  #     capable of overriding roles in other local directories to allow
  #     custom development behavior (the same way `./dev/bin` is put in
  #     front or `./bin`).
  # 
  
  # Role paths declared in ./dev/ansible.cfg, if it exists.
  File.join('.', 'dev', 'ansible.cfg'),
  
  # Roles in ./dev/roles
  File.join('.', 'dev', 'roles'),
  
  
  # Working Directory Paths
  # =======================
  # 
  # Next up, `ansible.cfg` and `roles` directory in the working dir.
  # Makes sense, right?
  # 
  
  # ./ansible.cfg
  File.join('.', 'ansible.cfg'),
  
  # ./roles
  File.join('.', 'roles'),
  
  
  # Working Directory-Local Ansible Directory
  # =========================================
  # 
  # `ansible.cfg` and `roles` in a `./ansible` directory, making a common
  # place to put Ansible stuff in an project accessible when running from
  # the project root.
  # 
  
  # ./ansible/ansible.cfg
  File.join('.', 'ansible', 'ansible.cfg'),
  
  # ./ansible/roles
  File.join('.', 'ansible', 'roles'),
  
  # TODO  Git repo root relative?
  #       Some sort of flag file for a find-up?
  #       System Ansible locations?
  
  
  # QB Gem Role Directories
  # =======================
  # 
  # Last, but far from least, paths provided by the QB Gem to the user's
  # QB role install location and the roles that come built-in to the gem.
  
  QB::USER_ROLES_DIR,
  
  QB::GEM_ROLES_DIR,
].freeze
PATH =

Array of string paths to directories to search for roles or paths to ansible.cfg files to look for an extract role paths from.

Value is a duplicate of the frozen BUILTIN_PATH. You can reset to those values at any time via reset_path!.

For the moment at least you can just mutate this value like you would $LOAD_PATH:

QB::Role::PATH.unshift '~/where/some/roles/be'
QB::Role::PATH.unshift '~/my/ansible.cfg'

The paths are searched from first to last.

WARNING

Search is deep - don't point this at large directory trees and expect any sort of reasonable performance (any directory that contains node_modules is usually a terrible idea for instance).

BUILTIN_PATH.dup

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path, search_dir: nil) ⇒ Role

Instantiate a Role.

Parameters:

  • path (String|Pathname)

    location of the role directory

  • search_dir (nil, Pathname) (defaults to: nil)

    Directory in search_path that the role was found in. Used to figure out it's name correctly when using directory-structure namespacing.



492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
# File 'lib/qb/role.rb', line 492

def initialize path, search_dir: nil
  @path = if path.is_a?(Pathname) then path else Pathname.new(path) end
  
  # check it...
  unless @path.exist?
    raise Errno::ENOENT.new @path.to_s
  end
  
  unless @path.directory?
    raise Errno::ENOTDIR.new @path.to_s
  end
  
  @display_path = self.class.to_display_path @path
  
  @meta_path = if (@path + 'meta' + 'qb').exist?
    @path + 'meta' + 'qb'
  elsif (@path + 'meta' + 'qb.yml').exist?
    @path + 'meta' + 'qb.yml'
  else
    raise Errno::ENOENT.new "#{ @path.join('meta').to_s }/[qb|qb.yml]"
  end
  
  
  if search_dir.nil?
    @name = @path.to_s.split(File::SEPARATOR).last
  else
    @name = @path.relative_path_from(search_dir).to_s
  end
end

Instance Attribute Details

#display_pathObject (readonly)

the path to the role that we display. we only show the directory name for QB roles, and use Util.compact_path to show . and ~ for paths relative to the current directory and home directory, respectively.

@return [Pathname]



469
470
471
# File 'lib/qb/role.rb', line 469

def display_path
  @display_path
end

#meta_pathObject (readonly)

Returns the value of attribute meta_path.



476
477
478
# File 'lib/qb/role.rb', line 476

def meta_path
  @meta_path
end

#nameObject (readonly)

Returns the value of attribute name.



459
460
461
# File 'lib/qb/role.rb', line 459

def name
  @name
end

#pathObject (readonly)

Returns the value of attribute path.



453
454
455
# File 'lib/qb/role.rb', line 453

def path
  @path
end

Class Method Details

.availableObject

array of QB::Role found in search path.



215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
# File 'lib/qb/role.rb', line 215

def self.available
  search_path.
    select {|search_dir|
      # make sure it's there (and a directory)
      search_dir.directory?
    }.
    map {|search_dir|
      Pathname.glob(search_dir.join '**', 'meta', 'qb.yml').
        map {|meta_path|
          [meta_path.dirname.dirname, search_dir: search_dir] 
        }
    }.
    flatten(1).
    map {|args|
      QB::Role.new *args
    }.
    uniq
end

.get_include_path(role, option_meta, current_include_path) ⇒ Array<string>

Get the include path for an included role based on the option metadata that defines the include and the current include path.

Parameters:

  • role (Role)

    the role to include.

  • option_meta (Hash)

    the entry for the option in qb.yml

  • current_include_path (Array<string>)

Returns:

  • (Array<string>)

    include path for the included role.



371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
# File 'lib/qb/role.rb', line 371

def self.get_include_path role, option_meta, current_include_path      
  new_include_path = if option_meta.key? 'as'
    case option_meta['as']
    when nil, false
      # include it in with the parent role's options
      current_include_path
    when String
      current_include_path + [option_meta['as']]
    else
      raise QB::Role::MetadataError.new,
        "bad 'as' value: #{ option_meta.inspect }"
    end
  else
    current_include_path + [role.namespaceless]
  end
end

.guess_role_name(dest) ⇒ Object



408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
# File 'lib/qb/role.rb', line 408

def self.guess_role_name dest
  raise "TODO: Not implemented!!!"
  
  path = QB::Util.resolve dest
  
  search_dirs = search_path.find_all { |pathname|
    path.fnmatch?( pathname / '**' )
  }
  
  case search_dirs.length
  when 0
    # It's not in any of the search directories
    # 
    # If it has 'roles' as a segment than use what's after the last occurrence
    # of that (unless there isn't anything).
    # 
    segments = path.to_s.split File::SEPARATOR
    
    if index = segments.rindex( 'roles' )
      name_segs = segments[index..-1]
      
      unless name_segs.empty?
        return File.join name_segs
      end
    end
    
    # Ok, that didn't work... just return the basename I guess...
    File.basename path
    
  when 1
    
  else
    # Multiple matches?!?!?
    
    
  end
end

.matches(input) ⇒ Array<QB::Role>

Get an array of QB::Role that match an input string.

Returns:



238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
# File 'lib/qb/role.rb', line 238

def self.matches input
  # keep this here to we don't re-gen every loop
  available = self.available
  
  # first off, see if input matches any relative paths exactly
  available.each {|role|
    return [role] if role.display_path.to_s == input
  }
  
  # create an array of "separator" variations to try *exact* matching 
  # against. in order of preference:
  # 
  # 1.  exact input
  #     -   this means if you ended up with roles that actually *are*
  #         differnetiated by '_/-' differences (which, IMHO, is a 
  #         horrible fucking idea), you can get exactly what you ask for
  #         as a first priority
  # 2.  input with '-' changed to '_'
  #     -   prioritized because convetion is to underscore-separate
  #         role names.
  # 3.  input with '_' changed to '-'
  #     -   really just for convience's sake so you don't really have to 
  #         remember what separator is used.
  #     
  separator_variations = [
    input,
    input.gsub('-', '_'),
    input.gsub('_', '-'),
  ]
  
  separator_variations.each { |variation|
    available.each { |role|
      # exact match to full name
      return [role] if role.name == variation
    }.each { |role|
      # exact match without the namespace prefix ('qb.' or similar)
      return [role] if role.namespaceless == variation
    }  
  }
  
  # see if we prefix match any full names
  separator_variations.each { |variation|
    name_prefix_matches = available.select { |role|
      role.name.start_with? variation
    }
    return name_prefix_matches unless name_prefix_matches.empty?
  }
  
  # see if we prefix match any name
  separator_variations.each { |variation|
    namespaceless_prefix_matches = available.select { |role|
      role.namespaceless.start_with? variation
    }
    unless namespaceless_prefix_matches.empty?
      return namespaceless_prefix_matches 
    end
  }
  
  # see if we prefix match any display paths
  separator_variations.each { |variation|
    path_prefix_matches = available.select { |role|
      role.display_path.start_with? variation
    }
    return path_prefix_matches unless path_prefix_matches.empty?
  }
  
  # see if we word match any display paths
  name_word_matches = available.select { |role|
    QB::Util.words_start_with? role.display_path.to_s, input
  }
  return name_word_matches unless name_word_matches.empty?
  
  # nada
  []
end

.require(input) ⇒ QB::Role

Find exactly one matching role for the input string or raise.

Where we look is determined by PATH via search_path.

Parameters:

  • input (String)

    Input string term used to search (what we got off the CLI args).

Returns:

  • (QB::Role)

    The single matching role.

Raises:



331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
# File 'lib/qb/role.rb', line 331

def self.require input
  as_pathname = Pathname.new(input)
    
  # allow a path to a role dir
  if role_dir? as_pathname
    return QB::Role.new as_pathname
  end
  
  matches = self.matches input
  
  role = case matches.length
  when 0
    raise QB::Role::NoMatchesError.new input
  when 1
    matches[0]
  else
    raise QB::Role::MultipleMatchesError.new input, matches
  end
  
  QB.debug "role match" => role
  
  role
end

.reset_path!Array<String>

Reset PATH to the original built-in values in BUILTIN_PATH.

Created for testing but might be useful elsewhere as well.

Returns:

  • (Array<String>)

    The reset PATH.



153
154
155
156
157
# File 'lib/qb/role.rb', line 153

def self.reset_path!
  PATH.clear
  BUILTIN_PATH.each { |path| PATH << path }
  PATH
end

.role_dir?(pathname) ⇒ Boolean

true if pathname is a QB role directory.

Returns:

  • (Boolean)


161
162
163
164
165
166
# File 'lib/qb/role.rb', line 161

def self.role_dir? pathname
  # must be a directory
  pathname.directory? &&
  # and must have meta/qb.yml or meta/qb file
  ['qb.yml', 'qb'].any? {|filename| pathname.join('meta', filename).file?}
end

.roles_paths(dir) ⇒ Object

Parameters:

  • dir (Pathname)

    dir to include.



170
171
172
173
174
175
# File 'lib/qb/role.rb', line 170

def self.roles_paths dir
  cfg_roles_path(dir) + [
    dir.join('roles'),
    dir.join('roles', 'tmp'),
  ]
end

.search_pathArray<Pathname>

places to look for qb role directories. these paths are also included when qb runs a playbook.

TODO resolution order:

  1. paths specific to this run: a. TODO paths provided on the cli.
  2. paths specific to the current directory: a. paths specified in ./ansible.cfg (if it exists) b. ./roles d. paths specified in ./ansible/ansible.cfg (if it exists) e. ./ansible/roles g. paths specified in ./dev/ansible.cfg (if it exists) h. ./dev/roles i. ./dev/roles/tmp - used for roles that are downloaded but shouldn't be included in source control. 3.

Returns:

  • (Array<Pathname>)

    places to look for role dirs.



199
200
201
202
203
204
205
206
207
208
209
210
211
212
# File 'lib/qb/role.rb', line 199

def self.search_path
  QB::Role::PATH.
    map { |path|
      if QB::Ansible::ConfigFile.end_with_config_file?(path)
        if File.file?(path)
          QB::Ansible::ConfigFile.new(path).defaults.roles_path
        end
      else
        QB::Util.resolve path
      end
    }.
    flatten.
    reject(&:nil?)
end

.to_display_path(path) ⇒ Pathname

The path we display in the CLI, see #display_path.

Parameters:

  • path (Pathname | String)

    input path to transform.

Returns:

  • (Pathname)

    path to display.



397
398
399
400
401
402
403
# File 'lib/qb/role.rb', line 397

def self.to_display_path path
  if path.realpath.start_with? QB::GEM_ROLES_DIR
    path.realpath.sub (QB::GEM_ROLES_DIR.to_s + '/'), ''
  else
    QB::Util.contract_path path
  end
end

Instance Method Details

#==(other) ⇒ Object Also known as: eql?



898
899
900
# File 'lib/qb/role.rb', line 898

def == other
  other.is_a?(self.class) && other.path.realpath == path.realpath
end

#ask_vault_pass?Boolean

should qb ask for an ansible vault password?

Returns:

  • (Boolean)

    true if qb should ask for a vault password.

See Also:



763
764
765
# File 'lib/qb/role.rb', line 763

def ask_vault_pass?
  !!@meta['ask_vault_pass']
end

get the CLI banner for the role



696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
# File 'lib/qb/role.rb', line 696

def banner
  lines = []
  
  name_line = "#{ name } role"
  lines << name_line
  lines << "=" * name_line.length
  lines << ''
  if meta['description']
    lines << meta['description']
    lines << ''
  end
  lines << 'usage:'
  lines << "  #{ usage }"
  lines << ''
  lines << 'options:'
  
  lines.join("\n")
end

#default_ansible_optionsHash<String, *>

Returns default ansible-playbook CLI options from role qb metadata. Hash of option name to value.

Returns:

  • (Hash<String, *>)

    default ansible-playbook CLI options from role qb metadata. Hash of option name to value.



869
870
871
# File 'lib/qb/role.rb', line 869

def default_ansible_options
  meta_or 'ansible_options', {}
end

#default_dir(cwd, options) ⇒ Object

gets the default qb_dir value, raising an error if the role doesn't define how to get one or there is a problem getting it.



780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
# File 'lib/qb/role.rb', line 780

def default_dir cwd, options
  QB.debug "get_default_dir",
    role: self,
    meta: self.meta,
    cwd: cwd,
    options: options
  
  key = 'default_dir'
  value = self.meta[key]
  case value
  when nil
    # there is no get_dir info in meta/qb.yml, can't get the dir
    raise QB::UserInputError.dedented <<-END
      unable to infer default directory: no '#{ key }' key in 'meta/qb.yml'
      for role #{ self }
    END
  
  when false
    # this method should not get called when the value is false (an entire
    # section is skipped in exe/qb when `default_dir = false`)
    raise QB::StateError.squished <<-END
      role does not use default directory (meta/qb.yml:default_dir = false)
    END
  
  when 'git_root'
    QB.debug "returning the git root relative to cwd"
    NRSER.git_root cwd
  
  when 'cwd'
    QB.debug "returning current working directory"
    cwd
    
  when Hash
    QB.debug "qb meta option is a Hash"
    
    unless value.length == 1
      raise "#{ meta_path.to_s }:default_dir invalid: #{ value.inspect }"
    end
    
    hash_key, hash_value = value.first
    
    case hash_key
    when 'exe'
      exe_path = hash_value
      
      # supply the options to the exe so it can make work off those values
      # if it wants.
      exe_input_data = Hash[
        options.map {|option|
          [option.cli_option_name, option.value]
        }
      ]
      
      unless exe_path.start_with?('~') || exe_path.start_with?('/')
        exe_path = File.join(self.path, exe_path)
        debug 'exe path is relative, basing off role dir', exe_path: exe_path
      end
      
      debug "found 'exe' key, calling", exe_path: exe_path,
                                        exe_input_data: exe_input_data
      
      Cmds.chomp! exe_path do
        JSON.dump exe_input_data
      end
      
    when 'find_up'
      filename = hash_value
      
      unless filename.is_a? String
        raise "find_up filename must be string, found #{ filename.inspect }"
      end
      
      QB.debug "found 'find_up', looking for file named #{ filename }"
      
      QB::Util.find_up filename
      
    else
      raise QB::Role::MetadataError.squised <<-END
        bad key: #{ hash_key } in #{ self.meta_path.to_s }:default_dir
      END
      
    end
  end
end

#defaultsObject

gets the role variable defaults from defaults/main.yml, or {}



647
648
649
# File 'lib/qb/role.rb', line 647

def defaults
  @defaults || load_defaults
end

#examplesObject



716
717
718
# File 'lib/qb/role.rb', line 716

def examples
  @meta['examples']
end

#format_examplesString

format the meta.examples hash into a string suitable for cli output.

Returns:

  • (String)

    the CLI-formatted examples.



726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
# File 'lib/qb/role.rb', line 726

def format_examples
  examples.
    map {|title, body|
      [
        "#{ title }:",
        body.lines.map {|l|
          # only indent non-empty lines
          # makes compacting newline sequences easier (see below)
          if l.match(/^\s*$/)
            l
          else
            '  ' + l
          end
        },
        ''
      ]
    }.
    flatten.
    join("\n").
    # compact newline sequences
    gsub(/\n\n+/, "\n\n")
end

#hashObject

Language Inter-Op



893
894
895
# File 'lib/qb/role.rb', line 893

def hash
  path.realpath.hash
end

#load_defaults(cache = true) ⇒ Object

loads the defaults from vars/main.yml and defaults/main.yml, caching by default. vars override defaults values.



622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
# File 'lib/qb/role.rb', line 622

def load_defaults cache = true
  defaults_path = @path + 'defaults' + 'main.yml'
  defaults = if defaults_path.file?
    YAML.load(defaults_path.read) || {}
  else
    {}
  end
  
  vars_path = @path + 'vars' + 'main.yml'
  vars = if vars_path.file?
    YAML.load(vars_path.read) || {}
  else
    {}
  end
  
  defaults = defaults.merge! vars
  
  if cache
    @defaults = defaults
  end
  
  defaults
end

#load_meta(cache = true) ⇒ Object

load qb metadata from meta/qb.yml or from executing meta/qb and parsing the YAML written to stdout.

if cache is true caches it as @meta



551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
# File 'lib/qb/role.rb', line 551

def load_meta cache = true
  meta = if @meta_path.extname == '.yml'
    contents = begin
      @meta_path.read
    rescue Exception => error
      raise QB::Role::MetadataError,
        "Failed to read metadata file at #{ @meta_path.to_s }, " +
        "error: #{ error.inspect }"
    end
    
    begin
      YAML.load(contents) || {}
    rescue Exception => error
      raise QB::Role::MetadataError,
        "Failed to load metadata YAML from #{ @meta_path.to_s }, " +
        "error: #{ error.inspect }"
    end
  else
    YAML.load(Cmds.out!(@meta_path.realpath.to_s)) || {}
  end
  
  if cache
    @meta = meta
  end
  
  meta
end

#metaHash{String => Object}

Returns the QB metadata for the role.

Returns:

  • (Hash{String => Object})

    the QB metadata for the role.



582
583
584
# File 'lib/qb/role.rb', line 582

def meta
  @meta || load_meta
end

#mkdirObject

if the exe should auto-make the directory. this is nice for most roles but some need it to be missing



657
658
659
# File 'lib/qb/role.rb', line 657

def mkdir
  !!meta_or('mkdir', true)
end

#namespaceObject

Instance Methods



526
527
528
529
530
531
532
533
534
535
536
# File 'lib/qb/role.rb', line 526

def namespace
  *namespace_segments, last = @name.split File::Separator
  
  namespace_segments << last.split('.').first if last.include?('.')
   
  if namespace_segments.empty?
    nil
  else
    File.join *namespace_segments
  end
end

#namespacelessObject



538
539
540
# File 'lib/qb/role.rb', line 538

def namespaceless
  File.basename(@name).split('.', 2).last
end

#option_metasObject

get the options from the metadata, defaulting to [] if none defined



599
600
601
# File 'lib/qb/role.rb', line 599

def option_metas
  meta_or ['options', 'opts', 'vars'], []
end

#options(include_path = []) ⇒ Array<QB::Options::Option> an array of Option for the role, including any included roles.

Returns ArrayQB::Options::Option an array of Option for the role, including any included roles.

Returns:



607
608
609
610
611
612
613
614
615
616
617
# File 'lib/qb/role.rb', line 607

def options include_path = []
  option_metas.map {|option_meta|
    if option_meta.key? 'include'
      role_name = option_meta['include']
      role = QB::Role.require role_name
      role.options QB::Role.get_include_path(role, option_meta, include_path)
    else
      QB::Options::Option.new self, option_meta, include_path
    end
  }.flatten
end

#options_keyObject



542
543
544
# File 'lib/qb/role.rb', line 542

def options_key
  @display_path.to_s
end

#puts_examplesObject

examples text



750
751
752
753
754
# File 'lib/qb/role.rb', line 750

def puts_examples
  return unless examples
  
  puts "\n" + format_examples + "\n"
end

#qb_requirementGem::Requirement?

Get the Gem::Requirement parse of the qb_requirement key in #meta (if it is defined), which specifies the required version of qb for the role.

Returns:

  • (Gem::Requirement, nil)

    The requirement if required_qb_version key is in #meta, else nil.



881
882
883
884
885
886
887
# File 'lib/qb/role.rb', line 881

def qb_requirement
  if  meta['requirements'] &&
      meta['requirements']['gems'] &&
      meta['requirements']['gems']['qb']
    Gem::Requirement.new meta['requirements']['gems']['qb']
  end
end

#save_optionsObject



651
652
653
# File 'lib/qb/role.rb', line 651

def save_options
  !!meta_or('save_options', true)
end

#to_sString

Returns #display_path.

Returns:



908
909
910
# File 'lib/qb/role.rb', line 908

def to_s
  @display_path.to_s
end

#usageString

Returns usage information formatted as plain text for the CLI.

Returns:

  • (String)

    usage information formatted as plain text for the CLI.



664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
# File 'lib/qb/role.rb', line 664

def usage
  # Split up options by required and optional.
  required_options = []
  optional_options = []
  
  options.each { |option|
    if option.required?
      required_options << option
    else
      optional_options << option
    end
  }
  
  parts = ['qb [run]', name]
  
  required_options.each { |option|
    parts << option.usage
  }
  
  unless optional_options.empty?
    parts << '[OPTIONS]'
  end
  
  if uses_default_dir?
    parts << 'DIRECTORY'
  end
  
  parts.join ' '
end

#uses_default_dir?Boolean

Returns @todo Document return value.

Returns:

  • (Boolean)

    @todo Document return value.



771
772
773
# File 'lib/qb/role.rb', line 771

def uses_default_dir?
  meta['default_dir'] != false
end

#var_prefixObject

gets the variable prefix that will be appended to cli options before passing them to the role. defaults to #namespaceless unless specified in meta.



590
591
592
593
594
595
# File 'lib/qb/role.rb', line 590

def var_prefix
  # ugh, i was generating meta/qb.yml files that set 'var_prefix' to
  # `null`, but it would be nice to 
  # 
  meta_or 'var_prefix', namespaceless
end