hoodie 0.5.5 → 1.0.1

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 (41) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/Gemfile +19 -0
  4. data/Rakefile +8 -23
  5. data/hoodie.gemspec +0 -23
  6. data/lib/hoodie.rb +40 -48
  7. data/lib/hoodie/configuration.rb +39 -2
  8. data/lib/hoodie/core_ext/blank.rb +6 -6
  9. data/lib/hoodie/core_ext/hash.rb +108 -13
  10. data/lib/hoodie/core_ext/string.rb +5 -3
  11. data/lib/hoodie/core_ext/try.rb +4 -3
  12. data/lib/hoodie/inflections.rb +18 -0
  13. data/lib/hoodie/inflections/defaults.rb +17 -0
  14. data/lib/hoodie/inflections/inflections.rb +17 -0
  15. data/lib/hoodie/inflections/rules_collection.rb +17 -0
  16. data/lib/hoodie/logging.rb +22 -4
  17. data/lib/hoodie/stash.rb +83 -80
  18. data/lib/hoodie/stash/disk_store.rb +142 -118
  19. data/lib/hoodie/stash/mem_store.rb +10 -9
  20. data/lib/hoodie/stash/memoizable.rb +46 -0
  21. data/lib/hoodie/utils.rb +13 -183
  22. data/lib/hoodie/utils/ansi.rb +199 -0
  23. data/lib/hoodie/utils/crypto.rb +288 -0
  24. data/lib/hoodie/utils/equalizer.rb +146 -0
  25. data/lib/hoodie/utils/file_helper.rb +225 -0
  26. data/lib/hoodie/utils/konstruktor.rb +77 -0
  27. data/lib/hoodie/utils/machine.rb +83 -0
  28. data/lib/hoodie/utils/os.rb +56 -0
  29. data/lib/hoodie/utils/retry.rb +235 -0
  30. data/lib/hoodie/utils/timeout.rb +54 -0
  31. data/lib/hoodie/utils/url_helper.rb +104 -0
  32. data/lib/hoodie/version.rb +4 -4
  33. metadata +13 -234
  34. data/lib/hoodie/identity_map.rb +0 -96
  35. data/lib/hoodie/memoizable.rb +0 -43
  36. data/lib/hoodie/obfuscate.rb +0 -121
  37. data/lib/hoodie/observable.rb +0 -309
  38. data/lib/hoodie/os.rb +0 -43
  39. data/lib/hoodie/proxy.rb +0 -68
  40. data/lib/hoodie/rash.rb +0 -125
  41. data/lib/hoodie/timers.rb +0 -355
@@ -1,8 +1,8 @@
1
1
  # encoding: UTF-8
2
2
  #
3
- # Author: Stefano Harding <riddopic@gmail.com>
4
- #
5
- # Copyright (C) 2014-2015 Stefano Harding
3
+ # Author: Stefano Harding <riddopic@gmail.com>
4
+ # License: Apache License, Version 2.0
5
+ # Copyright: (C) 2014-2015 Stefano Harding
6
6
  #
7
7
  # Licensed under the Apache License, Version 2.0 (the "License");
8
8
  # you may not use this file except in compliance with the License.
@@ -41,6 +41,8 @@ class String
41
41
  def mustard; colorize(self, "\e[1;35m"); end
42
42
  def cyan; colorize(self, "\e[0;36m"); end
43
43
  def cyan2; colorize(self, "\e[1;36m"); end
44
+ def light_gray; colorize(self, "\e[2;37m"); end
45
+ def bright_red; colorize(self, "\e[1;41m"); end
44
46
  def white; colorize(self, "\e[0;97m"); end
45
47
  def on_black; colorize(self, "\e[40m"); end
46
48
  def on_red; colorize(self, "\e[41m"); end
@@ -1,8 +1,8 @@
1
1
  # encoding: UTF-8
2
2
  #
3
- # Author: Stefano Harding <riddopic@gmail.com>
4
- #
5
- # Copyright (C) 2014-2015 Stefano Harding
3
+ # Author: Stefano Harding <riddopic@gmail.com>
4
+ # License: Apache License, Version 2.0
5
+ # Copyright: (C) 2014-2015 Stefano Harding
6
6
  #
7
7
  # Licensed under the Apache License, Version 2.0 (the "License");
8
8
  # you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@
17
17
  # limitations under the License.
18
18
  #
19
19
 
20
+
20
21
  # Add #try and #try!
21
22
  class Object
22
23
  # Invokes the public method whose name goes as first argument just like
@@ -1,3 +1,21 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Author: Stefano Harding <riddopic@gmail.com>
4
+ # License: Apache License, Version 2.0
5
+ # Copyright: (C) 2014-2015 Stefano Harding
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
1
19
 
2
20
  require 'set'
3
21
 
@@ -1,4 +1,21 @@
1
1
  # encoding: UTF-8
2
+ #
3
+ # Author: Stefano Harding <riddopic@gmail.com>
4
+ # License: Apache License, Version 2.0
5
+ # Copyright: (C) 2014-2015 Stefano Harding
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
2
19
 
3
20
  Hoodie::Inflections.inflections do |inflect|
4
21
  inflect.plural(/$/, 's')
@@ -1,4 +1,21 @@
1
1
  # encoding: UTF-8
2
+ #
3
+ # Author: Stefano Harding <riddopic@gmail.com>
4
+ # License: Apache License, Version 2.0
5
+ # Copyright: (C) 2014-2015 Stefano Harding
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
2
19
 
3
20
  module Hoodie
4
21
  module Inflections
@@ -1,4 +1,21 @@
1
1
  # encoding: UTF-8
2
+ #
3
+ # Author: Stefano Harding <riddopic@gmail.com>
4
+ # License: Apache License, Version 2.0
5
+ # Copyright: (C) 2014-2015 Stefano Harding
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
2
19
 
3
20
  module Hoodie
4
21
  module Inflections
@@ -1,8 +1,8 @@
1
1
  # encoding: UTF-8
2
2
  #
3
- # Author: Stefano Harding <riddopic@gmail.com>
4
- #
5
- # Copyright (C) 2014-2015 Stefano Harding
3
+ # Author: Stefano Harding <riddopic@gmail.com>
4
+ # License: Apache License, Version 2.0
5
+ # Copyright: (C) 2014-2015 Stefano Harding
6
6
  #
7
7
  # Licensed under the Apache License, Version 2.0 (the "License");
8
8
  # you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@
17
17
  # limitations under the License.
18
18
  #
19
19
 
20
+ require 'hoodie/core_ext/string'
20
21
  require 'logger'
21
22
  require 'time'
22
23
 
@@ -95,7 +96,7 @@ module Hoodie
95
96
  def call(severity, time, progname, msg)
96
97
  format % [
97
98
  format_datetime(time).blue,
98
- severity.green,
99
+ format_severity(severity),
99
100
  msg2str(msg).strip.orange
100
101
  ]
101
102
  end
@@ -106,6 +107,23 @@ module Hoodie
106
107
  "[%s] %5s: %s\n"
107
108
  end
108
109
 
110
+ def format_severity(severity)
111
+ case severity
112
+ when 'FATAL'
113
+ severity.bright_red
114
+ when 'ERROR'
115
+ severity.red
116
+ when 'WARN'
117
+ severity.yellow
118
+ when 'DEBUG'
119
+ severity.light_gray
120
+ when 'INFO'
121
+ severity.green
122
+ else
123
+ severity
124
+ end
125
+ end
126
+
109
127
  def format_datetime(time)
110
128
  if @datetime_format.nil?
111
129
  time.strftime("%Y-%m-%dT%H:%M:%S.") << "%06d " % time.usec
@@ -1,8 +1,8 @@
1
1
  # encoding: UTF-8
2
2
  #
3
- # Author: Stefano Harding <riddopic@gmail.com>
4
- #
5
- # Copyright (C) 2014 Stefano Harding
3
+ # Author: Stefano Harding <riddopic@gmail.com>
4
+ # License: Apache License, Version 2.0
5
+ # Copyright: (C) 2014-2015 Stefano Harding
6
6
  #
7
7
  # Licensed under the Apache License, Version 2.0 (the "License");
8
8
  # you may not use this file except in compliance with the License.
@@ -17,102 +17,105 @@
17
17
  # limitations under the License.
18
18
  #
19
19
 
20
- require 'hoodie/stash/disk_store' unless defined?(DiskStash)
21
- require 'hoodie/stash/mem_store' unless defined?(MemStash)
22
- require 'hoodie/memoizable' unless defined?(Memoizable)
20
+ require 'hoodie/stash/disk_stash'
21
+ require 'hoodie/stash/mem_stash'
22
+ require 'hoodie/stash/memoizable'
23
+ require 'hoodie/utils/os'
23
24
 
24
- # Define the basic cache and default store objects
25
- module Stash
26
- # check if we're using a version if Ruby that supports caller_locations
27
- NEW_CALL = Kernel.respond_to? 'caller_locations'
25
+ module Hoodie
26
+ # Define the basic cache and default store objects
27
+ #
28
+ module Stash
29
+ # check if we're using a version if Ruby that supports caller_locations
30
+ NEW_CALL = Kernel.respond_to? 'caller_locations'
28
31
 
29
- class << self
30
32
  # insert a helper .new() method for creating a new object
31
33
  #
32
- def new(*args)
34
+ def self.new(*args)
33
35
  self::Cache.new(*args)
34
36
  end
35
37
 
36
38
  # helper to get the calling function name
37
39
  #
38
- def caller_name
40
+ def self.caller_name
39
41
  NEW_CALL ? caller_locations(2, 1).first.label : caller[1][/`([^']*)'/, 1]
40
42
  end
41
- end
42
43
 
43
- # Default store type
44
- DEFAULT_STORE = MemStash::Cache
44
+ # Default store type
45
+ DEFAULT_STORE = MemStash
45
46
 
46
- # Key/value cache store
47
- class Cache
48
- # @return [Hash] of the mem stash cache hash store
49
- #
50
- attr_reader :store
47
+ # Key/value cache store
48
+ class Cache
51
49
 
52
- # Initializes a new empty store
53
- #
54
- def initialize(params = {})
55
- params = { store: params } unless params.is_a? Hash
56
- @store = params.fetch(:store) { Stash::DEFAULT_STORE.new }
57
- end
50
+ # @!attribute [r] :store
51
+ # @return [Stash::DiskStore] location of Stash::DiskStore store.
52
+ attr_reader :store
58
53
 
59
- # Clear the whole stash store or the value of a key
60
- #
61
- # @param key [Symbol, String] (optional) representing the key to
62
- # clear.
63
- #
64
- # @return nothing.
65
- #
66
- def clear!(key = nil)
67
- key = key.to_sym unless key.nil?
68
- @store.clear! key
69
- end
54
+ # Initializes a new empty store
55
+ #
56
+ def initialize(params = {})
57
+ params = { store: params } unless params.is_a? Hash
58
+ @store = params.fetch(:store) { Hoodie::DEFAULT_STORE.new }
59
+ end
70
60
 
71
- # Retrieves the value for a given key, if nothing is set,
72
- # returns KeyError
73
- #
74
- # @param key [Symbol, String] representing the key
75
- #
76
- # @raise [KeyError] if no such key found
77
- #
78
- # @return [Hash, Array, String] value for key
79
- #
80
- def [](key = nil)
81
- key ||= Stash.caller_name
82
- fail KeyError, 'Key not cached' unless include? key.to_sym
83
- @store[key.to_sym]
84
- end
61
+ # Clear the whole stash store or the value of a key
62
+ #
63
+ # @param key [Symbol, String] (optional) representing the key to
64
+ # clear.
65
+ #
66
+ # @return nothing.
67
+ #
68
+ def clear!(key = nil)
69
+ key = key.to_sym unless key.nil?
70
+ @store.clear! key
71
+ end
85
72
 
86
- # Retrieves the value for a given key, if nothing is set,
87
- # run the code, cache the result, and return it
88
- #
89
- # @param key [Symbol, String] representing the key
90
- # @param block [&block] that returns the value to set (optional)
91
- #
92
- # @return [Hash, Array, String] value for key
93
- #
94
- def cache(key = nil, &code)
95
- key ||= Stash.caller_name
96
- @store[key.to_sym] ||= code.call
97
- end
73
+ # Retrieves the value for a given key, if nothing is set,
74
+ # returns KeyError
75
+ #
76
+ # @param key [Symbol, String] representing the key
77
+ #
78
+ # @raise [KeyError] if no such key found
79
+ #
80
+ # @return [Hash, Array, String] value for key
81
+ #
82
+ def [](key = nil)
83
+ key ||= Stash.caller_name
84
+ fail KeyError, 'Key not cached' unless include? key.to_sym
85
+ @store[key.to_sym]
86
+ end
98
87
 
99
- # return the size of the store as an integer
100
- #
101
- # @return [Fixnum]
102
- #
103
- def size
104
- @store.size
105
- end
88
+ # Retrieves the value for a given key, if nothing is set,
89
+ # run the code, cache the result, and return it
90
+ #
91
+ # @param key [Symbol, String] representing the key
92
+ # @param block [&block] that returns the value to set (optional)
93
+ #
94
+ # @return [Hash, Array, String] value for key
95
+ #
96
+ def cache(key = nil, &code)
97
+ key ||= Stash.caller_name
98
+ @store[key.to_sym] ||= code.call
99
+ end
106
100
 
107
- # return a boolean indicating presence of the given key in the store
108
- #
109
- # @param key [Symbol, String] a string or symbol representing the key
110
- #
111
- # @return [TrueClass, FalseClass]
112
- #
113
- def include?(key = nil)
114
- key ||= Stash.caller_name
115
- @store.include? key.to_sym
101
+ # return the size of the store as an integer
102
+ #
103
+ # @return [Fixnum]
104
+ #
105
+ def size
106
+ @store.size
107
+ end
108
+
109
+ # return a boolean indicating presence of the given key in the store
110
+ #
111
+ # @param key [Symbol, String] a string or symbol representing the key
112
+ #
113
+ # @return [Boolean]
114
+ #
115
+ def include?(key = nil)
116
+ key ||= Stash.caller_name
117
+ @store.include? key.to_sym
118
+ end
116
119
  end
117
120
  end
118
121
  end
@@ -1,8 +1,8 @@
1
1
  # encoding: UTF-8
2
2
  #
3
- # Author: Stefano Harding <riddopic@gmail.com>
4
- #
5
- # Copyright (C) 2014-2015 Stefano Harding
3
+ # Author: Stefano Harding <riddopic@gmail.com>
4
+ # License: Apache License, Version 2.0
5
+ # Copyright: (C) 2014-2015 Stefano Harding
6
6
  #
7
7
  # Licensed under the Apache License, Version 2.0 (the "License");
8
8
  # you may not use this file except in compliance with the License.
@@ -12,140 +12,164 @@
12
12
  #
13
13
  # Unless required by applicable law or agreed to in writing, software
14
14
  # distributed under the License is distributed on an "AS IS" BASIS,
15
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
16
- # implied. See the License for the specific language governing
17
- # permissions and limitations under the License.
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
18
  #
19
19
 
20
20
  require 'tmpdir'
21
21
 
22
- module DiskStash
22
+ module Hoodie
23
23
  # Disk stashing method variable caching hash, string, array store.
24
- class Cache
25
- include Enumerable
26
-
27
- # @return [String] location of DiskStash::Cache.store
28
- #
29
- attr_reader :store
30
-
31
- # Initializes a new disked backed stash hash cache store.
32
- #
33
- # @param path [String] location for stash store cache.
34
- #
35
- # @return nothing.
36
- #
37
- def initialize(store = file_store)
38
- @store = store
39
- _ensure_store_directory
40
- end
24
+ #
25
+ class Stash
26
+ class DiskStash
27
+
28
+ # @!attribute [r] :store
29
+ # @return [Stash::DiskStore] location of Stash::DiskStore store.
30
+ attr_reader :store
31
+
32
+ # Initializes a new disked backed stash hash cache store.
33
+ #
34
+ # @param path [String] location for stash store cache.
35
+ #
36
+ # @return nothing.
37
+ #
38
+ def initialize(store = file_store)
39
+ @store = store
40
+ end
41
+
42
+ # Retrieves a value from the cache, if available and not expired, or
43
+ # yields to a block that calculates the value to be stored in the cache.
44
+ #
45
+ # @param [Object] key
46
+ # The key to look up or store at.
47
+ #
48
+ # @yield yields when the value is not present.
49
+ #
50
+ # @yieldreturn [Object]
51
+ # The value to store in the cache.
52
+ #
53
+ # @return [Object]
54
+ # The value at the key.
55
+ #
56
+ def cache(key = nil, &code)
57
+ key ||= Stash.caller_name
58
+ @store[key.to_sym] ||= code.call
59
+ end
41
60
 
42
- # Clear the whole stash or the value of a key
43
- #
44
- # @param key [Symbol, String] (optional) string or symbol
45
- # representing the key to clear
46
- #
47
- # @return [Hash] with a key, return the value it had, without
48
- # returns {}
49
- #
50
- def clear!(key = nil)
51
- if key.nil?
52
- ::Dir[::File.join(store, '*.cache')].each do |file|
53
- ::File.delete(file)
61
+ # Clear the whole stash or the value of a key.
62
+ #
63
+ # @param [Symbol, String] key
64
+ # String or symbol representing the key to clear.
65
+ #
66
+ # @return [Hash]
67
+ # Previously stored Key/Value pair before the delete operation.
68
+ #
69
+ def clear!(key = nil)
70
+ if key.nil?
71
+ Dir[File.join(store, '*.cache')].each do |file|
72
+ File.delete(file)
73
+ end
74
+ else
75
+ File.delete(cache_file(key)) if File.exist?(cache_file(key))
54
76
  end
55
- else
56
- ::File.delete(cache_file(key)) if ::File.exist?(cache_file(key))
57
77
  end
58
- end
59
78
 
60
- # Retrieves the value for a given key, if nothing is set,
61
- # returns nil
62
- #
63
- # @param key [Symbol, String] representing the key
64
- #
65
- # @return [Hash, Array, String] value for key
66
- #
67
- def [](key)
68
- if key.is_a? Array
69
- hash = {}
70
- key.each do |k|
71
- hash[k] = Marshal.load(_read_cache_file(k))
79
+ # Retrieves the value for a given key, if nothing is set returns nil.
80
+ #
81
+ # @param [Symbol, String] key
82
+ # String or symbol representing the key.
83
+ #
84
+ # @return [Hash]
85
+ # The value for the key.
86
+ #
87
+ def [](key)
88
+ if key.is_a? Array
89
+ hash = {}
90
+ key.each do |k|
91
+ hash[k] = Marshal.load(read_cache_file(k))
92
+ end
93
+ hash unless hash.empty?
94
+ else
95
+ Marshal.load(read_cache_file(key))
72
96
  end
73
- hash unless hash.empty?
74
- else
75
- Marshal.load(_read_cache_file(key))
97
+ rescue Errno::ENOENT
98
+ nil # key hasn't been created
76
99
  end
77
- rescue Errno::ENOENT
78
- nil # key hasn't been created
79
- end
80
100
 
81
- # Store the given value with the given key, either an an argument
82
- # or block. If a previous value was set it will be overwritten
83
- # with the new value.
84
- #
85
- # @param key [Symbol, String] representing the key
86
- # @param value [Object] that represents the value (optional)
87
- # @param block [&block] that returns the value to set (optional)
88
- #
89
- # @return nothing.
90
- #
91
- def []=(key, value)
92
- _write_cache_file(key, Marshal.dump(value))
93
- end
101
+ # Store the given value with the given key, either an an argument or
102
+ # block. If a previous value was set it will be overwritten with the new
103
+ # value.
104
+ #
105
+ # @param [Symbol, String] key
106
+ # String or symbol representing the key.
107
+ #
108
+ # @param [Object] value
109
+ # That represents the value (optional)
110
+ #
111
+ # @param [&block] block
112
+ # That returns the value to set (optional)
113
+ #
114
+ # @return [undefined]
115
+ #
116
+ def []=(key, value)
117
+ write_cache_file(key, Marshal.dump(value))
118
+ end
94
119
 
95
- # returns path to cache file with 'key'
96
- def cache_file(key)
97
- ::File.join(store, key.to_s + '.cache')
98
- end
120
+ # returns path to cache file with 'key'
121
+ def cache_file(key)
122
+ File.join(store, key.to_s + '.cache')
123
+ end
99
124
 
100
- private # P R O P R I E T À P R I V A T A divieto di accesso
101
-
102
- # return Chef tmpfile path if running under Chef, else return OS
103
- # temp path. On Winders Dir.tmpdir returns the correct path.
104
- #
105
- def file_store
106
- if OS.windows?
107
- win_friendly_path('/chef/._stash_')
108
- elsif OS.mac?
109
- ::File.join(::File::SEPARATOR, 'var', 'tmp', '._stash')
110
- else
111
- ::File.join(::File::SEPARATOR, 'var', 'lib', '._stash')
125
+ private # P R O P R I E T À P R I V A T A divieto di accesso
126
+
127
+ def file_store
128
+ if Hoodie::OS.windows?
129
+ win_friendly_path('/chef/._stash_')
130
+ elsif Hoodie::OS.mac?
131
+ File.join(File::SEPARATOR, 'var', 'tmp', '._stash')
132
+ else
133
+ File.join(File::SEPARATOR, 'var', 'lib', '._stash')
134
+ end
112
135
  end
113
- end
114
136
 
115
- # returns windows friendly version of the provided path, ensures
116
- # backslashes are used everywhere
117
- #
118
- def win_friendly_path(path)
119
- system_drive = ENV['SYSTEMDRIVE'] ? ENV['SYSTEMDRIVE'] : ''
120
- path = ::File.join(system_drive, path)
121
- path.gsub!(::File::SEPARATOR, (::File::ALT_SEPARATOR || '\\'))
122
- end
137
+ # returns windows friendly version of the provided path, ensures
138
+ # backslashes are used everywhere
139
+ #
140
+ def win_friendly_path(path)
141
+ system_drive = ENV['SYSTEMDRIVE'] ? ENV['SYSTEMDRIVE'] : ''
142
+ path = File.join(system_drive, path)
143
+ path.gsub!(File::SEPARATOR, (File::ALT_SEPARATOR || '\\'))
144
+ end
123
145
 
124
- def _write_cache_file(key, content)
125
- mode = OS.windows? ? 'wb' : 'w+'
126
- f = ::File.open(cache_file(key), mode)
127
- f.flock(::File::LOCK_EX)
128
- f.write(content)
129
- f.close
130
- content
131
- end
146
+ def write_cache_file(key, content)
147
+ mode = OS.windows? ? 'wb' : 'w+'
148
+ file = File.open(cache_file(key), mode)
149
+ ensure_enclosing_dir(File.dirname file)
150
+ file.flock(File::LOCK_EX)
151
+ file.write(content)
152
+ file.close
153
+ content
154
+ end
132
155
 
133
- def _read_cache_file(key)
134
- mode = OS.windows? ? 'rb' : 'r'
135
- f = ::File.open(cache_file(key), mode)
136
- f.flock(::File::LOCK_SH)
137
- out = f.read
138
- f.close
139
- out
140
- end
156
+ def read_cache_file(key)
157
+ mode = OS.windows? ? 'rb' : 'r'
158
+ f = File.open(cache_file(key), mode)
159
+ f.flock(File::LOCK_SH)
160
+ out = f.read
161
+ f.close
162
+ out
163
+ end
141
164
 
142
- def read_cache_mtime(key)
143
- nil unless ::File.exist?(cache_file(key))
144
- ::File.mtime(cache_file(key))
145
- end
165
+ def read_cache_mtime(key)
166
+ nil unless File.exist?(cache_file(key))
167
+ File.mtime(cache_file(key))
168
+ end
146
169
 
147
- def _ensure_store_directory
148
- ::Dir.mkdir(store) unless ::File.directory?(store)
149
- end
170
+ def ensure_enclosing_dir(dir)
171
+ FileUtils.mkdir_p(file_store) unless File.directory?(dir)
172
+ end
173
+ end
150
174
  end
151
175
  end