fast 0.1.3 → 0.1.4
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.
- data/.gitignore +1 -0
- data/.travis.yml +10 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +5 -1
- data/README.md +122 -0
- data/fast.gemspec +2 -1
- data/lib/fast.rb +1 -0
- data/lib/fast/dir.rb +73 -35
- data/lib/fast/exceptions.rb +3 -0
- data/lib/fast/fast.rb +3 -0
- data/lib/fast/file.rb +16 -37
- data/lib/fast/filesystemobject.rb +69 -0
- data/lib/fast/version.rb +1 -1
- data/lib/patterns/adapter/fast/dir.rb +19 -0
- data/lib/sub-setter/fast/dir.rb +8 -0
- data/spec/fast/dir_spec.rb +152 -94
- data/spec/fast/file_spec.rb +72 -80
- data/spec/fast/filesystemobject_spec.rb +309 -0
- data/spec/patterns/adapter/fast/dir_spec.rb +16 -0
- data/spec/sub-setter/fast/dir_spec.rb +20 -0
- metadata +47 -10
- data/README.rdoc +0 -81
data/.gitignore
CHANGED
data/.travis.yml
ADDED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,14 +1,16 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
fast (0.1.
|
4
|
+
fast (0.1.4)
|
5
5
|
metafun (>= 0.2.0)
|
6
|
+
sub-setter (>= 0.0.2)
|
6
7
|
|
7
8
|
GEM
|
8
9
|
remote: http://rubygems.org/
|
9
10
|
specs:
|
10
11
|
diff-lcs (1.1.3)
|
11
12
|
metafun (0.2.0)
|
13
|
+
rake (0.9.2.2)
|
12
14
|
rspec (2.8.0)
|
13
15
|
rspec-core (~> 2.8.0)
|
14
16
|
rspec-expectations (~> 2.8.0)
|
@@ -17,6 +19,7 @@ GEM
|
|
17
19
|
rspec-expectations (2.8.0)
|
18
20
|
diff-lcs (~> 1.1.2)
|
19
21
|
rspec-mocks (2.8.0)
|
22
|
+
sub-setter (0.0.2)
|
20
23
|
zucker (12.1)
|
21
24
|
|
22
25
|
PLATFORMS
|
@@ -24,5 +27,6 @@ PLATFORMS
|
|
24
27
|
|
25
28
|
DEPENDENCIES
|
26
29
|
fast!
|
30
|
+
rake
|
27
31
|
rspec
|
28
32
|
zucker
|
data/README.md
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
Fast
|
2
|
+
====
|
3
|
+
|
4
|
+
[](http://travis-ci.org/xaviervia/fast)
|
5
|
+
|
6
|
+
Tired of having a hard time working with files? Take a look at Fast...
|
7
|
+
|
8
|
+
require "fast"
|
9
|
+
|
10
|
+
lib_dir = dir! :lib # Creates a new dir "lib"
|
11
|
+
|
12
|
+
lib_dir["demo.txt"] = "I love creating files from a Hash-like API"
|
13
|
+
# Creates lib/demo.txt containing the text
|
14
|
+
|
15
|
+
lib_dir.list # => ['demo.txt']
|
16
|
+
|
17
|
+
file! "lib/empty.txt" # New file lib/empty.txt
|
18
|
+
|
19
|
+
lib_dir.files do |path|
|
20
|
+
puts path
|
21
|
+
end # => demo.txt
|
22
|
+
# empty.txt
|
23
|
+
|
24
|
+
lib_dir.destroy
|
25
|
+
|
26
|
+
dir? :lib # => false
|
27
|
+
|
28
|
+
...and finally is **quite stable** so you can use it if you wish so.
|
29
|
+
|
30
|
+
Fast is a DSL for file and dir handling focused in intuitivity and semantics. Fast is pure Ruby, don't relays on OS functions, so is a little slower but more portable.
|
31
|
+
|
32
|
+
Installation
|
33
|
+
------------
|
34
|
+
|
35
|
+
gem install fast
|
36
|
+
|
37
|
+
Usage
|
38
|
+
-----
|
39
|
+
|
40
|
+
Fast declares two sets of methods in its DSL:
|
41
|
+
|
42
|
+
### Dir methods
|
43
|
+
|
44
|
+
dir :lib # The same as => Fast::Dir.new "lib"
|
45
|
+
dir.delete! "demo" # The same as => Fast::Dir.new.delete! "demo"
|
46
|
+
|
47
|
+
dir! :new_dir # The same as => Fast::Dir.new.create! :new_dir
|
48
|
+
dir? :new_dir # The same as => Fast::Dir.new.exist? :new_dir
|
49
|
+
|
50
|
+
### File methods
|
51
|
+
|
52
|
+
file "demo.txt" # The same as => Fast::File.new "demo.txt"
|
53
|
+
file.copy "demo.txt", "new.txt" # The same as =>
|
54
|
+
# Fast::File.new.copy "demo.txt", "new.txt"
|
55
|
+
|
56
|
+
file! "demo.txt" # The same as => Fast::File.new.create! "demo.txt"
|
57
|
+
file? "demo.txt" # The same as => Fast::File.new.exist? "demo.txt"
|
58
|
+
|
59
|
+
Philosophy
|
60
|
+
----------
|
61
|
+
|
62
|
+
*Fast* embraces the more straightforward view of files as strings of data and directories as arrays of files/directories. Why?
|
63
|
+
|
64
|
+
* It is more realistic in everyday usage
|
65
|
+
* It makes them more object-like (and thus, more friendly to OOP)
|
66
|
+
* It is more semantic
|
67
|
+
* Files as IOs are still accessible through the harder-to-use native Ruby API
|
68
|
+
|
69
|
+
<tt>Fast::Dir</tt> is a subclass of <tt>Array</tt>, usable as a hash, and <tt>Fast::File</tt> if a subclass of String.
|
70
|
+
|
71
|
+
Conflicts
|
72
|
+
---------
|
73
|
+
|
74
|
+
It is a known issue that the DSL of Fast conflicts with [Pry][pry-gem] and most notable with [Rake][rake-gem]; I am aware that is a bold move to reclaim `file` from the standard namespace for Fast to use.
|
75
|
+
|
76
|
+
In order to workaround that, you can require fast in a not-so-much DSL way:
|
77
|
+
|
78
|
+
require "fast/fast"
|
79
|
+
|
80
|
+
Fast.file "myfile.txt" # The same as `file "myfile.txt"`
|
81
|
+
|
82
|
+
Fast.dir! :lib # etc...
|
83
|
+
|
84
|
+
This is also the recommended form when using Fast in the context of a library.
|
85
|
+
|
86
|
+
> Also: try to avoid using Fast in a library, because Fast is mostly semantic sugar and you want to avoid adding loading time just for the sake of having a couple of convenience methods. Fast is more fun when used for code sketching and simple scripts.
|
87
|
+
|
88
|
+
[pry-gem]: https://github.com/pry/pry
|
89
|
+
[rake-gem]: http://rake.rubyforge.org/
|
90
|
+
|
91
|
+
Quick notes (to self)
|
92
|
+
---------------------
|
93
|
+
|
94
|
+
* Rename FilesystemObject: Item, CommonMethods, AbstractFile, FastHelpers (think!)
|
95
|
+
* Deliberate whether is a good idea to make Fast::Dir and Fast::File Multitons. (May be only when an absolute path is used)
|
96
|
+
* The path can be setted indirectly by any method of Fast::File instances, and the same works for Dir. This is fine because allows for very quick calls, but once an instance gets a path setted it should be fixed and raise an exception in case some other method call is trying to change it.
|
97
|
+
|
98
|
+
### Fast::File
|
99
|
+
* Read bytes as binary ASCII-8BIT always and then try to perform an heuristic conversion, if there is any reasonable way to do it. Otherwise, leave it to the user. Google: "ruby string encode utf-8 ascii" for some good readings.
|
100
|
+
|
101
|
+
### Fast::Dir
|
102
|
+
* Calls to #dirs and #files should delegate to a SubSetter
|
103
|
+
* Change the behaviour in the calls to #dirs and #files: return a new instance, with no @path setted.
|
104
|
+
* Change the behaviour in the initialization: call #list always if there's a path an the path matches an existing directory
|
105
|
+
* Allow for easy recursive calls (#list_all, #files_all, #dirs_all for example, think of better synonyms)
|
106
|
+
* Deliberate whether "#<<" should be kept in Fast::Dir and if it should be used as alias for merge
|
107
|
+
* An instance of Fast::Dir should be possible to be created from a Array. (pity I didn't specified an usage case)
|
108
|
+
* Add documentation to Patterns::Adapter::Fast::Dir
|
109
|
+
|
110
|
+
Remote future
|
111
|
+
-------------
|
112
|
+
|
113
|
+
* Make Fast a REST client (well, use <tt>rest-client</tt>) in order to transparently use files and directories from a compliant REST server.
|
114
|
+
* Include REST methods: Dir#post, File#get, File#head, etc and equivalents for local files (prepare ground for Piano Rest)
|
115
|
+
* Allow Files to behave as Dirs with the right method calls
|
116
|
+
|
117
|
+
License
|
118
|
+
-------
|
119
|
+
|
120
|
+
GPL License. Why other?
|
121
|
+
|
122
|
+
@ Xavier Via
|
data/fast.gemspec
CHANGED
data/lib/fast.rb
CHANGED
data/lib/fast/dir.rb
CHANGED
@@ -2,7 +2,13 @@ require "sub-setter/fast/dir" # This call should be automated in the sub-setter
|
|
2
2
|
|
3
3
|
module Fast
|
4
4
|
# Directory handling class
|
5
|
+
#
|
6
|
+
# Inherits from Array in order to be usable as a Array
|
7
|
+
# Includes the module Fast::FilesystemObject for common
|
8
|
+
# functionality with Fast::File
|
5
9
|
class Dir < Array
|
10
|
+
include FilesystemObject
|
11
|
+
|
6
12
|
def initialize path = nil
|
7
13
|
super()
|
8
14
|
@path = normalize path if path
|
@@ -55,8 +61,20 @@ module Fast
|
|
55
61
|
if args.length > 0
|
56
62
|
return_me = nil
|
57
63
|
args.each do |path|
|
58
|
-
|
59
|
-
|
64
|
+
unless path.is_a? Hash
|
65
|
+
raise ArgumentError, "Dir '#{path}' already exists" if Dir.new.exist? path
|
66
|
+
return_me = do_create path
|
67
|
+
else
|
68
|
+
if @path
|
69
|
+
subdir = Dir.new.create! "#{@path}"
|
70
|
+
else
|
71
|
+
subdir = Dir.new "."
|
72
|
+
end
|
73
|
+
path.each do |item_name, item_content|
|
74
|
+
subdir[item_name] = item_content
|
75
|
+
end
|
76
|
+
return subdir
|
77
|
+
end
|
60
78
|
end
|
61
79
|
return return_me
|
62
80
|
else
|
@@ -72,7 +90,19 @@ module Fast
|
|
72
90
|
if args.length > 0
|
73
91
|
return_me = nil
|
74
92
|
args.each do |path|
|
75
|
-
|
93
|
+
unless path.is_a? Hash
|
94
|
+
return_me = do_create path
|
95
|
+
else
|
96
|
+
if @path
|
97
|
+
subdir = Dir.new.create! "#{@path}"
|
98
|
+
else
|
99
|
+
subdir = Dir.new "."
|
100
|
+
end
|
101
|
+
path.each do |item_name, item_content|
|
102
|
+
subdir[item_name] = item_content
|
103
|
+
end
|
104
|
+
return subdir
|
105
|
+
end
|
76
106
|
end
|
77
107
|
return return_me
|
78
108
|
else
|
@@ -125,15 +155,7 @@ module Fast
|
|
125
155
|
alias :destroy! :delete!
|
126
156
|
alias :del! :delete!
|
127
157
|
alias :unlink! :delete!
|
128
|
-
|
129
|
-
# Checks for existence. True if the directory exists, false otherwise
|
130
|
-
def exist? path = nil
|
131
|
-
@path = normalize path if path
|
132
|
-
::File.directory? @path
|
133
|
-
end
|
134
|
-
|
135
|
-
alias :exists? :exist?
|
136
|
-
|
158
|
+
|
137
159
|
# Returns true if all passed dirs exist, false otherwise
|
138
160
|
def exist_all? *args
|
139
161
|
unless args.empty?
|
@@ -172,32 +194,17 @@ module Fast
|
|
172
194
|
|
173
195
|
return existing_ones
|
174
196
|
end
|
197
|
+
|
198
|
+
# This will be ported to a pattern exactly like SubSetter
|
199
|
+
def to
|
200
|
+
Patterns::Adapter::Fast::Dir.new self
|
201
|
+
end
|
175
202
|
|
176
203
|
# Returns a String brief of the dir
|
177
204
|
def to_s
|
178
205
|
return "#{@path}"
|
179
206
|
end
|
180
|
-
|
181
|
-
# Sends self to a SubSetter for Fast::Dir
|
182
|
-
def filter
|
183
|
-
SubSetter::Fast::Dir.new self
|
184
|
-
end
|
185
|
-
|
186
|
-
alias :by :filter
|
187
207
|
|
188
|
-
# Expands the path to absolute is it is relative
|
189
|
-
def expand path = nil
|
190
|
-
@path = normalize path if path
|
191
|
-
::File.expand_path @path
|
192
|
-
end
|
193
|
-
|
194
|
-
alias :absolute :expand
|
195
|
-
|
196
|
-
# Returns the path to the dir, if defined
|
197
|
-
def path
|
198
|
-
@path if @path
|
199
|
-
end
|
200
|
-
|
201
208
|
# Renames this dir into the target path, unless the target path
|
202
209
|
# points to an existing dir.
|
203
210
|
def rename *args
|
@@ -297,6 +304,37 @@ module Fast
|
|
297
304
|
end
|
298
305
|
end
|
299
306
|
end
|
307
|
+
|
308
|
+
# Checks the given dirs should be merged if any conflict would arise.
|
309
|
+
#
|
310
|
+
# Returns true if any file in the target directory has the same
|
311
|
+
# path (ie: the same name and subdirectory structure) as other file
|
312
|
+
# in the source directory.
|
313
|
+
def conflicts_with? *args
|
314
|
+
if args.length > 1
|
315
|
+
current, target = *args
|
316
|
+
@path = normalize current
|
317
|
+
target = Dir.new target
|
318
|
+
else
|
319
|
+
target = Dir.new args.first
|
320
|
+
end
|
321
|
+
|
322
|
+
files do |file|
|
323
|
+
target.files do |target_file|
|
324
|
+
return true if file == target_file
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
328
|
+
dirs do |dir|
|
329
|
+
target.dirs do |target_dir|
|
330
|
+
if dir == target_dir
|
331
|
+
return true if Fast::Dir.new.conflicts_with? "#{@path}/#{dir}", "#{target.path}/#{target_dir}"
|
332
|
+
end
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
336
|
+
false
|
337
|
+
end
|
300
338
|
|
301
339
|
private
|
302
340
|
def do_delete path = nil
|
@@ -345,9 +383,9 @@ module Fast
|
|
345
383
|
|
346
384
|
target_dir
|
347
385
|
end
|
348
|
-
|
349
|
-
def
|
350
|
-
|
386
|
+
|
387
|
+
def do_exist? path
|
388
|
+
::File.directory? path
|
351
389
|
end
|
352
390
|
end
|
353
391
|
end
|
data/lib/fast/fast.rb
CHANGED
data/lib/fast/file.rb
CHANGED
@@ -2,7 +2,12 @@ require "sub-setter/fast/file" # This call should be automated in the sub-sette
|
|
2
2
|
|
3
3
|
module Fast
|
4
4
|
# File handling class.
|
5
|
+
#
|
6
|
+
# Inherits from String in order to be usable as a String
|
7
|
+
# Includes the module Fast::FilesystemObject for common
|
8
|
+
# functionality with Fast::Dir
|
5
9
|
class File < String
|
10
|
+
include FilesystemObject
|
6
11
|
|
7
12
|
# Initializes the file
|
8
13
|
def initialize source = nil
|
@@ -112,19 +117,17 @@ module Fast
|
|
112
117
|
alias :create! :touch
|
113
118
|
|
114
119
|
# Returns the contents of the file, all at once
|
115
|
-
def read path = nil
|
120
|
+
def read path = nil, &block
|
116
121
|
@path = normalize path if path
|
117
|
-
|
122
|
+
unless block
|
123
|
+
::File.read @path
|
124
|
+
else
|
125
|
+
::File.open @path, "r" do |the_file|
|
126
|
+
block.call the_file
|
127
|
+
end
|
128
|
+
end
|
118
129
|
end
|
119
130
|
|
120
|
-
# Returns true if file exists, false otherwise
|
121
|
-
def exist? path = nil
|
122
|
-
@path = normalize path if path
|
123
|
-
do_check_existence @path
|
124
|
-
end
|
125
|
-
|
126
|
-
alias :exists? :exist?
|
127
|
-
|
128
131
|
def exist_all? *args
|
129
132
|
unless args.empty?
|
130
133
|
return_me = true
|
@@ -157,21 +160,6 @@ module Fast
|
|
157
160
|
end
|
158
161
|
return_list
|
159
162
|
end
|
160
|
-
|
161
|
-
# Sends self to a SubSetter for Fast::File
|
162
|
-
def filter
|
163
|
-
SubSetter::Fast::File.new self
|
164
|
-
end
|
165
|
-
|
166
|
-
alias :by :filter
|
167
|
-
|
168
|
-
# Expands the path if it's a relative path
|
169
|
-
def expand path = nil
|
170
|
-
@path = normalize path if path
|
171
|
-
::File.expand_path @path
|
172
|
-
end
|
173
|
-
|
174
|
-
alias :absolute :expand
|
175
163
|
|
176
164
|
# Renames the file (by Fast::File own means, it does not call
|
177
165
|
# the underlying OS). Fails if the new path is an existent file
|
@@ -206,12 +194,7 @@ module Fast
|
|
206
194
|
end
|
207
195
|
|
208
196
|
alias :move! :rename!
|
209
|
-
|
210
|
-
# Returns the path to the current file
|
211
|
-
def path
|
212
|
-
@path if @path
|
213
|
-
end
|
214
|
-
|
197
|
+
|
215
198
|
# Appends the contents of the target file into self and erase the target
|
216
199
|
def merge *args
|
217
200
|
if args.length > 1
|
@@ -263,11 +246,7 @@ module Fast
|
|
263
246
|
do_copy target
|
264
247
|
end
|
265
248
|
|
266
|
-
private
|
267
|
-
def normalize path
|
268
|
-
"#{path}"
|
269
|
-
end
|
270
|
-
|
249
|
+
private
|
271
250
|
def do_copy target
|
272
251
|
target.write read
|
273
252
|
target
|
@@ -291,7 +270,7 @@ module Fast
|
|
291
270
|
self
|
292
271
|
end
|
293
272
|
|
294
|
-
def
|
273
|
+
def do_exist? path
|
295
274
|
::File.exist?(path) && !::File.directory?(path)
|
296
275
|
end
|
297
276
|
|