Module: QB::Util

Defined in:
lib/qb/util.rb,
lib/qb/util/stdio.rb,
lib/qb/util/bundler.rb,
lib/qb/util/interop.rb,
lib/qb/util/resource.rb,
lib/qb/util/docker_mixin.rb

Defined Under Namespace

Modules: Bundler, DockerMixin, Interop, STDIO Classes: Resource

Class Method Summary collapse

Class Method Details

.contract_path(path) ⇒ Pathname

do kind of the opposite of File.expand_path -- turn the home dir into ~ and the current dir into .

Parameters:

  • path (Pathname | String)

    to contract.

Returns:

  • (Pathname)

    contracted path.



78
79
80
81
82
83
84
85
86
87
88
# File 'lib/qb/util.rb', line 78

def self.contract_path path
  contracted = if path.start_with? Dir.pwd
    path.sub Dir.pwd, '.'
  elsif path.start_with? ENV['HOME']
    path.sub ENV['HOME'], '~'
  else
    path
  end
  
  Pathname.new contracted
end

.find_up(filename, from = Pathname.pwd, raise_on_not_found: true) ⇒ Pathname?

find filename in from or closest parent directory.

Parameters:

  • filename (String)

    name of file to search for.

  • from (Pathname) (defaults to: Pathname.pwd)

    (Pathname.pwd) directory to start from.

  • raise_on_not_found: (Boolean) (defaults to: true)

    When true, a FSStateError will be raised if no file is found (default behavior).

    This is something of a legacy behavior - I think it would be better to have find_up return nil in that case and add a find_up! method that raises on not found. But I'm not going to do it right now.

Returns:

  • (Pathname)

    Pathname of found file.

  • (nil)

    If no file is found and the raise_on_not_found option is false.

Raises:

  • (QB::FSStateError)

    If file is not found in from or any of it's parent directories and the raise_on_not_found option is true (default behavior).



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/qb/util.rb', line 116

def self.find_up filename, from = Pathname.pwd, raise_on_not_found: true
  path = from + filename
  
  return from if path.exist?
  
  parent = from.parent
  
  if from == parent
    if raise_on_not_found
      raise "not found in current or any parent directories: #{ filename }"
    else
      return nil
    end
  end
  
  return find_up filename, parent, raise_on_not_found: raise_on_not_found
end

.resolve(*segments) ⇒ Pathname

Returns absolute resolved path.

Returns:

  • (Pathname)

    absolute resolved path.



57
58
59
60
61
62
63
64
65
66
67
# File 'lib/qb/util.rb', line 57

def self.resolve *segments
  joined = Pathname.new ''
  
  ([Dir.pwd] + segments).reverse.each_with_index {|segment, index|
    joined = Pathname.new(segment).join joined
    return joined if joined.absolute?
  }
  
  # shouldn't ever happen
  raise "resolution failed: #{ segments.inspect }"
end

.words(string) ⇒ Object

split a string into 'words' for word-based matching



11
12
13
# File 'lib/qb/util.rb', line 11

def self.words string
  string.split(/[\W_\-\/]+/).reject {|w| w.empty?}
end

.words_start_with?(full_string, input) ⇒ Boolean

see if words from an input match words

Returns:

  • (Boolean)


16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/qb/util.rb', line 16

def self.words_start_with? full_string, input
  # QB.debug "does #{ input } match #{ full_string }?"
  
  input_words = words input
  
  # short-circuit if there are no input words ('./' for example)
  return false if input_words.empty?
  
  full_string_words = words full_string
  
  QB.debug "HERE",
    input_words: input_words,
    full_string_words: full_string_words
  
  full_string_words.each_with_index {|word, start_index|
    # compute the end index in full_string_words
    end_index = start_index + input_words.length - 1
    
    # short-circuit if can't match (more input words than full words left)
    if end_index >= full_string_words.length
      return false
    end
    
    # create the slice to test against
    slice = full_string_words[start_index..end_index]
    
    # see if every word in the slice starts with the corresponding word
    # in the input
    if slice.zip(input_words).all? {|full_word, input_word|
      full_word.start_with? input_word
    }
      # got a match!
      return true
    end
  }
  
  # no match
  false
end