hoodie 0.3.21 → 0.4.0
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.
- checksums.yaml +4 -4
- data/.gitattributes +17 -0
- data/.gitignore +193 -0
- data/Gemfile +0 -1
- data/Rakefile +0 -1
- data/hoodie.gemspec +11 -10
- data/lib/hoodie/hash.rb +1 -1
- data/lib/hoodie/identity_map.rb +94 -0
- data/lib/hoodie/memoizable.rb +0 -1
- data/lib/hoodie/obfuscate.rb +14 -14
- data/lib/hoodie/rash.rb +2 -2
- data/lib/hoodie/stash/disk_store.rb +34 -34
- data/lib/hoodie/stash/mem_store.rb +1 -1
- data/lib/hoodie/stash.rb +0 -1
- data/lib/hoodie/timers.rb +355 -0
- data/lib/hoodie/utils.rb +214 -83
- data/lib/hoodie/version.rb +1 -1
- data/lib/hoodie.rb +2 -0
- metadata +20 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e83cfa47334c8e94fa85098671646220f6c68712
|
|
4
|
+
data.tar.gz: 1ac0f613e7637ccb84207e66aa134b75c67c9bdf
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9a09de6da5bc364aea2c32178386be400b90d2aaa25e0f67c427c995cac31f7e0c62a85222adfbe878ba48488a96d645639d93d87971607ba03735970855555f
|
|
7
|
+
data.tar.gz: dea4407f8d58b047b222f3e061be98091f2208327a293d006c0720f3064144731c5e11844df931bc4a52590fe5deef9f3657037004b70410df315fe0ff3fd482
|
data/.gitattributes
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Autodetect text files
|
|
2
|
+
* text=auto
|
|
3
|
+
|
|
4
|
+
# Make sure unix shell scripts use the correct line endings
|
|
5
|
+
*.sh eol=lf
|
|
6
|
+
|
|
7
|
+
# ...Unless the name matches the following
|
|
8
|
+
# overriding patterns
|
|
9
|
+
|
|
10
|
+
# Definitively text files
|
|
11
|
+
*.txt text
|
|
12
|
+
*.c text
|
|
13
|
+
*.h text
|
|
14
|
+
|
|
15
|
+
# Ensure those won't be messed up with
|
|
16
|
+
*.jpg binary
|
|
17
|
+
*.data binary
|
data/.gitignore
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
# Created by http://www.gitignore.io
|
|
2
|
+
|
|
3
|
+
### OSX ###
|
|
4
|
+
.DS_Store
|
|
5
|
+
.AppleDouble
|
|
6
|
+
.LSOverride
|
|
7
|
+
|
|
8
|
+
# Icon must end with two \r
|
|
9
|
+
Icon
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
# Thumbnails
|
|
13
|
+
._*
|
|
14
|
+
|
|
15
|
+
# Files that might appear on external disk
|
|
16
|
+
.Spotlight-V100
|
|
17
|
+
.Trashes
|
|
18
|
+
|
|
19
|
+
# Directories potentially created on remote AFP share
|
|
20
|
+
.AppleDB
|
|
21
|
+
.AppleDesktop
|
|
22
|
+
Network Trash Folder
|
|
23
|
+
Temporary Items
|
|
24
|
+
.apdisk
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
### Windows ###
|
|
28
|
+
# Windows image file caches
|
|
29
|
+
Thumbs.db
|
|
30
|
+
ehthumbs.db
|
|
31
|
+
|
|
32
|
+
# Folder config file
|
|
33
|
+
Desktop.ini
|
|
34
|
+
|
|
35
|
+
# Recycle Bin used on file shares
|
|
36
|
+
$RECYCLE.BIN/
|
|
37
|
+
|
|
38
|
+
# Windows Installer files
|
|
39
|
+
*.cab
|
|
40
|
+
*.msi
|
|
41
|
+
*.msm
|
|
42
|
+
*.msp
|
|
43
|
+
|
|
44
|
+
# Windows shortcuts
|
|
45
|
+
*.lnk
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
### Linux ###
|
|
49
|
+
*~
|
|
50
|
+
|
|
51
|
+
# KDE directory preferences
|
|
52
|
+
.directory
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
### Vagrant ###
|
|
56
|
+
.vagrant/
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
### Packer ###
|
|
60
|
+
# Cache objects
|
|
61
|
+
packer_cache/
|
|
62
|
+
|
|
63
|
+
# For built boxes
|
|
64
|
+
*.box
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
### TextMate ###
|
|
68
|
+
*.tmproj
|
|
69
|
+
*.tmproject
|
|
70
|
+
tmtags
|
|
71
|
+
tmtagsHistory
|
|
72
|
+
|
|
73
|
+
### SublimeText ###
|
|
74
|
+
# workspace files are user-specific
|
|
75
|
+
*.sublime-workspace
|
|
76
|
+
|
|
77
|
+
# project files should be checked into the repository, unless a significant
|
|
78
|
+
# proportion of contributors will probably not be using SublimeText
|
|
79
|
+
# *.sublime-project
|
|
80
|
+
|
|
81
|
+
#sftp configuration file
|
|
82
|
+
sftp-config.json
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
### vim ###
|
|
86
|
+
[._]*.s[a-w][a-z]
|
|
87
|
+
[._]s[a-w][a-z]
|
|
88
|
+
*.un~
|
|
89
|
+
Session.vim
|
|
90
|
+
.netrwhist
|
|
91
|
+
*~
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
### Emacs ###
|
|
95
|
+
# -*- mode: gitignore; -*-
|
|
96
|
+
*~
|
|
97
|
+
\#*\#
|
|
98
|
+
/.emacs.desktop
|
|
99
|
+
/.emacs.desktop.lock
|
|
100
|
+
*.elc
|
|
101
|
+
auto-save-list
|
|
102
|
+
tramp
|
|
103
|
+
.\#*
|
|
104
|
+
|
|
105
|
+
# Org-mode
|
|
106
|
+
.org-id-locations
|
|
107
|
+
*_archive
|
|
108
|
+
|
|
109
|
+
# flymake-mode
|
|
110
|
+
*_flymake.*
|
|
111
|
+
|
|
112
|
+
# eshell files
|
|
113
|
+
/eshell/history
|
|
114
|
+
/eshell/lastdir
|
|
115
|
+
|
|
116
|
+
# elpa packages
|
|
117
|
+
/elpa/
|
|
118
|
+
|
|
119
|
+
# reftex files
|
|
120
|
+
*.rel
|
|
121
|
+
|
|
122
|
+
# AUCTeX auto folder
|
|
123
|
+
/auto/
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
### ChefCookbook ###
|
|
127
|
+
.vagrant
|
|
128
|
+
/cookbooks
|
|
129
|
+
|
|
130
|
+
# Bundler
|
|
131
|
+
bin/*
|
|
132
|
+
.bundle/*
|
|
133
|
+
|
|
134
|
+
.kitchen/
|
|
135
|
+
.kitchen.local.yml
|
|
136
|
+
.chef-runner/
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
### Ruby ###
|
|
140
|
+
*.gem
|
|
141
|
+
*.rbc
|
|
142
|
+
/.config
|
|
143
|
+
/coverage/
|
|
144
|
+
/InstalledFiles
|
|
145
|
+
/pkg/
|
|
146
|
+
/spec/reports/
|
|
147
|
+
/test/tmp/
|
|
148
|
+
/test/version_tmp/
|
|
149
|
+
/tmp/
|
|
150
|
+
|
|
151
|
+
## Specific to RubyMotion:
|
|
152
|
+
.dat*
|
|
153
|
+
.repl_history
|
|
154
|
+
build/
|
|
155
|
+
|
|
156
|
+
## Documentation cache and generated files:
|
|
157
|
+
/.yardoc/
|
|
158
|
+
/_yardoc/
|
|
159
|
+
/doc/
|
|
160
|
+
/rdoc/
|
|
161
|
+
|
|
162
|
+
## Environment normalisation:
|
|
163
|
+
/.bundle/
|
|
164
|
+
/lib/bundler/man/
|
|
165
|
+
|
|
166
|
+
# for a library or gem, you might want to ignore these files since the code is
|
|
167
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
168
|
+
# Gemfile.lock
|
|
169
|
+
# .ruby-version
|
|
170
|
+
# .ruby-gemset
|
|
171
|
+
|
|
172
|
+
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
|
173
|
+
.rvmrc
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
### Tags ###
|
|
177
|
+
# Ignore tags created by etags, ctags, gtags (GNU global) and cscope
|
|
178
|
+
TAGS
|
|
179
|
+
!TAGS/
|
|
180
|
+
tags
|
|
181
|
+
!tags/
|
|
182
|
+
gtags.files
|
|
183
|
+
GTAGS
|
|
184
|
+
GRTAGS
|
|
185
|
+
GPATH
|
|
186
|
+
cscope.files
|
|
187
|
+
cscope.out
|
|
188
|
+
cscope.in.out
|
|
189
|
+
cscope.po.out
|
|
190
|
+
.bundle
|
|
191
|
+
vendor/bundle
|
|
192
|
+
vendor/cache
|
|
193
|
+
Gemfile.lock
|
data/Gemfile
CHANGED
data/Rakefile
CHANGED
data/hoodie.gemspec
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
2
|
lib = File.expand_path('../lib/', __FILE__)
|
|
3
|
-
|
|
3
|
+
$LOAD_PATH.unshift lib unless $LOAD_PATH.include?(lib)
|
|
4
4
|
|
|
5
|
-
require
|
|
5
|
+
require 'hoodie/version'
|
|
6
6
|
|
|
7
7
|
Gem::Specification.new do |s|
|
|
8
8
|
s.name = 'hoodie'
|
|
9
9
|
s.version = Hoodie::VERSION
|
|
10
10
|
s.platform = Gem::Platform::RUBY
|
|
11
|
-
s.date = Time.now.strftime(
|
|
11
|
+
s.date = Time.now.strftime('%Y-%m-%d')
|
|
12
12
|
s.summary = 'Pragmatic hoodie concurrency hipster with ruby'
|
|
13
|
-
s.description =
|
|
13
|
+
s.description = 'A collection of hipster methods and hoodie tools to make even the nerdy rubyist look cool'
|
|
14
14
|
s.authors = ['Stefano Harding']
|
|
15
15
|
s.email = 'riddopic@gmail.com'
|
|
16
16
|
s.homepage = 'https://github.com/riddopic/hoodie'
|
|
@@ -19,12 +19,13 @@ Gem::Specification.new do |s|
|
|
|
19
19
|
s.files = `git ls-files`.split
|
|
20
20
|
s.test_files = `git ls-files spec/*`.split
|
|
21
21
|
|
|
22
|
-
s.
|
|
22
|
+
s.add_runtime_dependency 'anemone', '>= 0.7.2'
|
|
23
|
+
s.add_runtime_dependency 'hitimes'
|
|
23
24
|
|
|
24
|
-
s.add_development_dependency 'rubocop',
|
|
25
|
-
s.add_development_dependency 'rake',
|
|
25
|
+
s.add_development_dependency 'rubocop', '~> 0.26.0'
|
|
26
|
+
s.add_development_dependency 'rake', '~> 10.3.2'
|
|
26
27
|
s.add_development_dependency 'coveralls', '~> 0.7.1'
|
|
27
|
-
s.add_development_dependency 'rspec',
|
|
28
|
-
s.add_development_dependency 'fuubar',
|
|
29
|
-
s.add_development_dependency 'timecop',
|
|
28
|
+
s.add_development_dependency 'rspec', '~> 3.1.0'
|
|
29
|
+
s.add_development_dependency 'fuubar', '~> 2.0.0'
|
|
30
|
+
s.add_development_dependency 'timecop', '~> 0.7.1'
|
|
30
31
|
end
|
data/lib/hoodie/hash.rb
CHANGED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
#
|
|
3
|
+
# Author: Stefano Harding <riddopic@gmail.com>
|
|
4
|
+
#
|
|
5
|
+
# Copyright (C) 2014 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
|
|
16
|
+
# implied. See the License for the specific language governing
|
|
17
|
+
# permissions and limitations under the License.
|
|
18
|
+
#
|
|
19
|
+
|
|
20
|
+
module Hoodie::IdentityMap
|
|
21
|
+
def self.enabled=(flag)
|
|
22
|
+
Thread.current[:identity_map_enabled] = flag
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def self.enabled
|
|
26
|
+
Thread.current[:identity_map_enabled]
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def self.enabled?
|
|
30
|
+
enabled == true
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def self.repository
|
|
34
|
+
Thread.current[:identity_map] ||= {}
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def self.clear
|
|
38
|
+
repository.clear
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def self.include?(object)
|
|
42
|
+
repository.keys.include?(object.id)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def self.use
|
|
46
|
+
old, self.enabled = enabled, true
|
|
47
|
+
yield if block_given?
|
|
48
|
+
ensure
|
|
49
|
+
self.enabled = old
|
|
50
|
+
clear
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def self.without
|
|
54
|
+
old, self.enabled = enabled, false
|
|
55
|
+
yield if block_given?
|
|
56
|
+
ensure
|
|
57
|
+
self.enabled = old
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
module ClassMethods
|
|
61
|
+
def get(id, options = nil)
|
|
62
|
+
get_from_identity_map(id) || super
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def get_from_identity_map(id)
|
|
66
|
+
IdentityMap.repository[id] if IdentityMap.enabled?
|
|
67
|
+
end
|
|
68
|
+
private :get_from_identity_map
|
|
69
|
+
|
|
70
|
+
def load(id, attrs)
|
|
71
|
+
if IdentityMap.enabled? && instance = IdentityMap.repository[id]
|
|
72
|
+
instance
|
|
73
|
+
else
|
|
74
|
+
super.tap { |doc| doc.add_to_identity_map }
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def save(options={})
|
|
80
|
+
super.tap { |result| add_to_identity_map if result }
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def delete
|
|
84
|
+
super.tap { remove_from_identity_map }
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def add_to_identity_map
|
|
88
|
+
IdentityMap.repository[id] = self if IdentityMap.enabled?
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def remove_from_identity_map
|
|
92
|
+
IdentityMap.repository.delete(id) if IdentityMap.enabled?
|
|
93
|
+
end
|
|
94
|
+
end
|
data/lib/hoodie/memoizable.rb
CHANGED
|
@@ -23,7 +23,6 @@ require 'hoodie/stash' unless defined?(Stash)
|
|
|
23
23
|
# method so it doesn't need to be re-computed every time that method
|
|
24
24
|
# is called.
|
|
25
25
|
module Memoizable
|
|
26
|
-
|
|
27
26
|
# Create a new memoized method. To use, extend class with Memoizable,
|
|
28
27
|
# then, in initialize, call memoize
|
|
29
28
|
#
|
data/lib/hoodie/obfuscate.rb
CHANGED
|
@@ -23,7 +23,7 @@ module Hoodie
|
|
|
23
23
|
INCOMPREHENSIBLE_ERROR = nil
|
|
24
24
|
rescue LoadError => err
|
|
25
25
|
raise unless err.to_s.include?('openssl')
|
|
26
|
-
warn
|
|
26
|
+
warn 'Oea pieoYreb h wYoerh dl hwsnhoib r Lrbea tbte wbnaetvoouahe h rbe.'
|
|
27
27
|
warn "olorbvtelYShnSben irrSwoet eto eihSrLoS'do n See wLiape."
|
|
28
28
|
INCOMPREHENSIBLE_ERROR = err
|
|
29
29
|
end
|
|
@@ -38,7 +38,7 @@ module Hoodie
|
|
|
38
38
|
|
|
39
39
|
def self.check_platform_can_discombobulate!
|
|
40
40
|
return true unless INCOMPREHENSIBLE_ERROR
|
|
41
|
-
|
|
41
|
+
fail INCOMPREHENSIBLE_ERROR.class, "b0rked! #{INCOMPREHENSIBLE_ERROR}"
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
# Befuddle the given string
|
|
@@ -49,7 +49,7 @@ module Hoodie
|
|
|
49
49
|
# @return [String] befuddleed text, suitable for deciphering with
|
|
50
50
|
# Obfuscate#enlighten (decrypt)
|
|
51
51
|
#
|
|
52
|
-
def self.befuddle
|
|
52
|
+
def self.befuddle(plaintext, befuddle_pass, options = {})
|
|
53
53
|
cipher = new_cipher :befuddle, befuddle_pass, options
|
|
54
54
|
cipher.iv = iv = cipher.random_iv
|
|
55
55
|
ciphertext = cipher.update(plaintext)
|
|
@@ -65,7 +65,7 @@ module Hoodie
|
|
|
65
65
|
#
|
|
66
66
|
# @return [String] the enlightened plaintext
|
|
67
67
|
#
|
|
68
|
-
def self.enlighten
|
|
68
|
+
def self.enlighten(enc_ciphertext, befuddle_pass, options = {})
|
|
69
69
|
iv_and_ciphertext = Base64.decode64(enc_ciphertext)
|
|
70
70
|
cipher = new_cipher :enlighten, befuddle_pass, options
|
|
71
71
|
cipher.iv, ciphertext = separate_iv_and_ciphertext(cipher, iv_and_ciphertext)
|
|
@@ -74,7 +74,7 @@ module Hoodie
|
|
|
74
74
|
plaintext
|
|
75
75
|
end
|
|
76
76
|
|
|
77
|
-
|
|
77
|
+
protected # A T T E N Z I O N E A R E A P R O T E T T A
|
|
78
78
|
|
|
79
79
|
# Cipher create machine do, befuddle engage, enlighten. Dials set
|
|
80
80
|
# direction to infinity
|
|
@@ -82,7 +82,7 @@ module Hoodie
|
|
|
82
82
|
# @param [:befuddle, :enlighten] to befuddle or enlighten
|
|
83
83
|
# @param [String] befuddle_pass secret sauce to enlighten with
|
|
84
84
|
#
|
|
85
|
-
def self.new_cipher
|
|
85
|
+
def self.new_cipher(direction, befuddle_pass, options = {})
|
|
86
86
|
check_platform_can_discombobulate!
|
|
87
87
|
cipher = OpenSSL::Cipher::Cipher.new(ESOTERIC_TYPE)
|
|
88
88
|
case direction
|
|
@@ -90,30 +90,30 @@ module Hoodie
|
|
|
90
90
|
cipher.encrypt
|
|
91
91
|
when :enlighten
|
|
92
92
|
cipher.decrypt
|
|
93
|
-
else
|
|
93
|
+
else fail "Bad cipher direction #{direction}"
|
|
94
94
|
end
|
|
95
95
|
cipher.key = befuddle_key(befuddle_pass, options)
|
|
96
96
|
cipher
|
|
97
97
|
end
|
|
98
98
|
|
|
99
99
|
# vector inspect encoder serialize prepend initialization message
|
|
100
|
-
def self.combine_iv_and_ciphertext
|
|
101
|
-
message.force_encoding(
|
|
102
|
-
iv.force_encoding(
|
|
100
|
+
def self.combine_iv_and_ciphertext(iv, message)
|
|
101
|
+
message.force_encoding('BINARY') if message.respond_to?(:force_encoding)
|
|
102
|
+
iv.force_encoding('BINARY') if iv.respond_to?(:force_encoding)
|
|
103
103
|
iv + message
|
|
104
104
|
end
|
|
105
105
|
|
|
106
106
|
# front vector initialization, encoded pull message
|
|
107
|
-
def self.separate_iv_and_ciphertext
|
|
107
|
+
def self.separate_iv_and_ciphertext(cipher, iv_and_ciphertext)
|
|
108
108
|
idx = cipher.iv_len
|
|
109
|
-
[
|
|
109
|
+
[iv_and_ciphertext[0..(idx - 1)], iv_and_ciphertext[idx..-1]]
|
|
110
110
|
end
|
|
111
111
|
|
|
112
112
|
# Convert the befuddle_pass passphrase into the key used for
|
|
113
113
|
# befuddletion
|
|
114
|
-
def self.befuddle_key
|
|
114
|
+
def self.befuddle_key(befuddle_pass, _options = {})
|
|
115
115
|
befuddle_pass = befuddle_pass.to_s
|
|
116
|
-
|
|
116
|
+
fail 'Missing befuddled password!' if befuddle_pass.empty?
|
|
117
117
|
# 256 beers on the wall, keys for cipher required of aes cbc
|
|
118
118
|
Digest::SHA256.digest(befuddle_pass)
|
|
119
119
|
end
|
data/lib/hoodie/rash.rb
CHANGED
|
@@ -103,7 +103,7 @@ module Anemone
|
|
|
103
103
|
key = ::File.basename(file, '.*').downcase.to_sym
|
|
104
104
|
type = ::File.extname(file)[1..-1].downcase.to_sym
|
|
105
105
|
id = Hoodie::Obfuscate.befuddle(file, Digest::MD5.hexdigest(body.to_s))
|
|
106
|
-
utime = Time
|
|
106
|
+
utime = Time.now.to_i
|
|
107
107
|
key = { key => { type => {
|
|
108
108
|
id: id,
|
|
109
109
|
file: file,
|
|
@@ -119,7 +119,7 @@ module Anemone
|
|
|
119
119
|
utime: utime,
|
|
120
120
|
md5_digest: Digest::MD5.hexdigest(body.to_s),
|
|
121
121
|
sha256_digest: Digest::SHA256.hexdigest(body.to_s)
|
|
122
|
-
}}}
|
|
122
|
+
} } }
|
|
123
123
|
end
|
|
124
124
|
end
|
|
125
125
|
end
|
|
@@ -20,9 +20,9 @@
|
|
|
20
20
|
require 'tmpdir'
|
|
21
21
|
|
|
22
22
|
module DiskStash
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
# Disk stashing method variable caching hash, string, array store.
|
|
24
|
+
class Cache
|
|
25
|
+
include Enumerable
|
|
26
26
|
|
|
27
27
|
# @return [String] location of DiskStash::Cache.store
|
|
28
28
|
#
|
|
@@ -35,29 +35,29 @@ module DiskStash
|
|
|
35
35
|
# @return nothing.
|
|
36
36
|
#
|
|
37
37
|
def initialize(store = file_store)
|
|
38
|
-
|
|
38
|
+
@store = store
|
|
39
39
|
_ensure_store_directory
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
# Clear the whole stash or the value of a key
|
|
43
|
+
#
|
|
44
|
+
# @param key [Symbol, String] (optional) string or symbol
|
|
45
45
|
# representing the key to clear
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
#
|
|
47
|
+
# @return [Hash] with a key, return the value it had, without
|
|
48
48
|
# returns {}
|
|
49
|
-
|
|
49
|
+
#
|
|
50
50
|
def clear!(key = nil)
|
|
51
51
|
if key.nil?
|
|
52
52
|
::Dir[::File.join(store, '*.cache')].each do |file|
|
|
53
53
|
::File.delete(file)
|
|
54
54
|
end
|
|
55
55
|
else
|
|
56
|
-
::File.delete(cache_file(key)) if ::File.
|
|
56
|
+
::File.delete(cache_file(key)) if ::File.exist?(cache_file(key))
|
|
57
57
|
end
|
|
58
58
|
end
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
# Retrieves the value for a given key, if nothing is set,
|
|
61
61
|
# returns nil
|
|
62
62
|
#
|
|
63
63
|
# @param key [Symbol, String] representing the key
|
|
@@ -68,11 +68,11 @@ module DiskStash
|
|
|
68
68
|
if key.is_a? Array
|
|
69
69
|
hash = {}
|
|
70
70
|
key.each do |k|
|
|
71
|
-
hash[k] = Marshal
|
|
71
|
+
hash[k] = Marshal.load(_read_cache_file(k))
|
|
72
72
|
end
|
|
73
73
|
hash unless hash.empty?
|
|
74
74
|
else
|
|
75
|
-
Marshal
|
|
75
|
+
Marshal.load(_read_cache_file(key))
|
|
76
76
|
end
|
|
77
77
|
rescue Errno::ENOENT
|
|
78
78
|
nil # key hasn't been created
|
|
@@ -89,15 +89,15 @@ module DiskStash
|
|
|
89
89
|
# @return nothing.
|
|
90
90
|
#
|
|
91
91
|
def []=(key, value)
|
|
92
|
-
|
|
92
|
+
_write_cache_file(key, Marshal.dump(value))
|
|
93
93
|
end
|
|
94
94
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
95
|
+
# returns path to cache file with 'key'
|
|
96
|
+
def cache_file(key)
|
|
97
|
+
::File.join(store, key.to_s + '.cache')
|
|
98
|
+
end
|
|
99
99
|
|
|
100
|
-
|
|
100
|
+
private # P R O P R I E T À P R I V A T A divieto di accesso
|
|
101
101
|
|
|
102
102
|
# return Chef tmpfile path if running under Chef, else return OS
|
|
103
103
|
# temp path. On Winders Dir.tmpdir returns the correct path.
|
|
@@ -114,7 +114,7 @@ module DiskStash
|
|
|
114
114
|
# backslashes are used everywhere
|
|
115
115
|
#
|
|
116
116
|
def win_friendly_path(path)
|
|
117
|
-
system_drive = ENV['SYSTEMDRIVE'] ? ENV['SYSTEMDRIVE'] :
|
|
117
|
+
system_drive = ENV['SYSTEMDRIVE'] ? ENV['SYSTEMDRIVE'] : ''
|
|
118
118
|
path = ::File.join(system_drive, path)
|
|
119
119
|
path.gsub!(::File::SEPARATOR, (::File::ALT_SEPARATOR || '\\'))
|
|
120
120
|
end
|
|
@@ -130,20 +130,20 @@ module DiskStash
|
|
|
130
130
|
|
|
131
131
|
def _read_cache_file(key)
|
|
132
132
|
mode = OS.windows? ? 'rb' : 'r'
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
133
|
+
f = ::File.open(cache_file(key), mode)
|
|
134
|
+
f.flock(::File::LOCK_SH)
|
|
135
|
+
out = f.read
|
|
136
|
+
f.close
|
|
137
|
+
out
|
|
138
138
|
end
|
|
139
139
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
140
|
+
def read_cache_mtime(key)
|
|
141
|
+
nil unless ::File.exist?(cache_file(key))
|
|
142
|
+
::File.mtime(cache_file(key))
|
|
143
|
+
end
|
|
144
144
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
145
|
+
def _ensure_store_directory
|
|
146
|
+
::Dir.mkdir(store) unless ::File.directory?(store)
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
149
|
end
|
data/lib/hoodie/stash.rb
CHANGED