pa 1.0.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.
data/lib/pa.rb ADDED
@@ -0,0 +1,175 @@
1
+ require_relative "pa/core"
2
+
3
+ require "bundler/setup"
4
+ Bundler.require
5
+
6
+ =begin rdoc
7
+ Pa(Path) is similary to Pathname, but more powerful.
8
+ it combines fileutils, tmpdir, find, tempfile, File, Dir, Pathname
9
+
10
+ all class methods support Pa as parameter.
11
+
12
+ Examples:
13
+ ---------
14
+ pa = Pa('/home/a.vim')
15
+ pa.dir #=> '/home'
16
+ pa.base #=> 'a.vim'
17
+ pa.name #=> 'a'
18
+ pa.ext #=> 'vim'
19
+ pa.fext #=> '.vim'
20
+
21
+ Filename parts:
22
+ ---------
23
+ /home/guten.ogg
24
+ base: guten.ogg
25
+ dir: /home
26
+ ext: ogg
27
+ name: guten
28
+
29
+ Additional method list
30
+ ---------------------
31
+ * Pa.absolute _alias from `File.absolute_path`_
32
+ * Pa.expand _aliss from `File.expand_path`_
33
+
34
+ === create, modify path
35
+ Example1:
36
+ pa = Pa('/home/foo')
37
+ pa.join('a.txt') #=> new Pa('/home/foo/a.txt')
38
+
39
+ Example2:
40
+ pa1 = Pa('/home/foo/a.txt')
41
+ pa2 = Pa('/home/bar/b.txt')
42
+ pa1+'~' #=> new Pa('/home/foo/a.txt~')
43
+ Pa.join(pa1.dir, pa2.base) #=> '/home/foo/b.txt'
44
+
45
+ Example3:
46
+ pa1 = Pa('/home/foo/a.txt')
47
+ pa2 = Pa('/home/bar')
48
+ pa2.join(pa1.base) #=> new Pa('/home/bar/a.txt')
49
+
50
+ **Attributes**
51
+
52
+ name abbr description
53
+
54
+ path p
55
+ absolute a absolute path
56
+ dir d dirname of a path
57
+ base b basename of a path
58
+ fname fn alias of base
59
+ name n filename of a path
60
+ ext e extname of a path, return "" or "ogg"
61
+ fext fe return "" or ".ogg"
62
+
63
+ == used with rspec
64
+
65
+ File.exists?(path).should be_true
66
+ Pa(path).should be_exists
67
+
68
+ =end
69
+ class Pa
70
+ Error = Class.new Exception
71
+ EUnkonwType = Class.new Error
72
+
73
+ attr_reader :path
74
+
75
+ # @param [String,#path] path
76
+ def initialize path
77
+ @path = path.respond_to?(:path) ? path.path : path
78
+ initialize_variables
79
+ end
80
+
81
+ def ok
82
+ initialize_variables
83
+ end
84
+
85
+ chainable = Module.new do
86
+ def initialize_variables; end
87
+ end
88
+ include chainable
89
+
90
+ alias p path
91
+
92
+ # @param [String,#path]
93
+ # @return [Pa] the same Pa object
94
+ def replace path
95
+ @path = path.respond_to?(:path) ? path.path : path
96
+ initialize_variables
97
+ end
98
+
99
+ # return '#<Pa @path="foo", @absolute="/home/foo">'
100
+ #
101
+ # @return [String]
102
+ def inspect
103
+ ret="#<" + self.class.to_s + " "
104
+ ret += "@path=\"#{path}\", @absolute=\"#{absolute}\""
105
+ ret += " >"
106
+ ret
107
+ end
108
+
109
+ # return '/home/foo'
110
+ #
111
+ # @return [String] path
112
+ def to_s
113
+ @path
114
+ end
115
+
116
+ # missing method goes to Pa.class-method
117
+ def method_missing(name, *args, &blk)
118
+ ret = self.class.__send__(name, path, *args, &blk)
119
+
120
+ case ret
121
+
122
+ # e.g. readlink ..
123
+ when String
124
+ Pa(ret)
125
+
126
+ # e.g. directory?
127
+ else
128
+ ret
129
+ end
130
+
131
+ end
132
+
133
+
134
+ end
135
+
136
+ class Pa
137
+ module ClassMethods
138
+ UNDEFS = [:open, :fstat]
139
+
140
+ # missing method goes to File class method
141
+ def method_missing name, *args, &blk
142
+ raise NoMethodError, name.inspect if UNDEFS.include?(name)
143
+ return if args.size>1
144
+ File.__send__ name, get(args[0]), &blk
145
+ end
146
+ end
147
+ end
148
+
149
+ require_relative "pa/path"
150
+ require_relative "pa/cmd"
151
+ require_relative "pa/dir"
152
+ require_relative "pa/state"
153
+ class Pa
154
+ extend ClassMethods
155
+ extend ClassMethods::Path
156
+ extend ClassMethods::Dir
157
+ extend ClassMethods::State
158
+ extend ClassMethods::Cmd
159
+
160
+ include Path
161
+ include State
162
+ end
163
+
164
+ module Kernel
165
+ private
166
+ # a very convient function.
167
+ #
168
+ # @example
169
+ # Pa('/home').exists?
170
+ def Pa(path)
171
+ return path if Pa===path
172
+ Pa.new path
173
+ end
174
+ end
175
+
data/pa.gemspec ADDED
@@ -0,0 +1,22 @@
1
+ $: << "."
2
+ require "version"
3
+ require "bundler"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "pa"
7
+ s.version = Pa::VERSION::IS
8
+ s.summary = "a good lib"
9
+ s.description = <<-EOF
10
+ a good lib
11
+ EOF
12
+
13
+ s.author = "Guten"
14
+ s.email = "ywzhaifei@Gmail.com"
15
+ s.homepage = "http://github.com/GutenLinux/pa"
16
+ s.rubyforge_project = "xx"
17
+
18
+ s.files = `git ls-files`.split("\n")
19
+
20
+ s.add_bundler_dependencies
21
+ #s.add_dependency "x"
22
+ end
data/pa.watchr ADDED
@@ -0,0 +1,22 @@
1
+ # lib/**/*.rb
2
+ watch %r~lib/(.*)\.rb~ do |m|
3
+ test "spec/#{m[1]}_spec.rb"
4
+ end
5
+
6
+ # spec/**/*_spec.rb
7
+ watch %r~spec/.*_spec\.rb~ do |m|
8
+ test m[0]
9
+ end
10
+
11
+ # Ctrl-\
12
+ Signal.trap('QUIT') do
13
+ puts "--- Running all tests ---\n\n"
14
+ test "spec"
15
+ end
16
+
17
+ def test path
18
+ cmd = "rspec #{path}"
19
+ puts cmd
20
+ system cmd
21
+ end
22
+
@@ -0,0 +1,278 @@
1
+ require "spec_helper"
2
+ require "fileutils"
3
+ require "tmpdir"
4
+
5
+ describe Pa do
6
+ it "a" do
7
+ Pa._copy 'a','b'
8
+ end
9
+ end
10
+
11
+
12
+ =begin
13
+ describe Pa do
14
+ before :all do
15
+ @curdir = Dir.pwd
16
+ @tmpdir = Dir.mktmpdir
17
+ Dir.chdir(@tmpdir)
18
+ end
19
+
20
+ after(:all) do
21
+ Dir.chdir(@curdir)
22
+ FileUtils.rm_r @tmpdir
23
+ end
24
+
25
+ describe "#_rmdir" do
26
+ # dir/
27
+ # a
28
+ # dira/
29
+ # aa
30
+ before(:all) do
31
+ @_rmdir = Pa.method(:_rmdir)
32
+ FileUtils.mkdir_p(%w(dir/dira))
33
+ FileUtils.touch(%w(dir/a dir/dira/aa))
34
+ end
35
+
36
+ it "remove directory" do
37
+ @_rmdir.call Pa("dir")
38
+ File.exists?("dir").should be_false
39
+ end
40
+ end
41
+
42
+ # rm family
43
+ describe "" do
44
+ # a
45
+ # dir/
46
+ # dira/
47
+ # a
48
+ before :each do
49
+ FileUtils.mkdir_p(%w(dir/dira))
50
+ FileUtils.touch(%w(a dir/a))
51
+ end
52
+
53
+ describe "#rm" do
54
+ it "remove file" do
55
+ Pa.rm "a"
56
+ File.exists?("a").should be_false
57
+ lambda{Pa.rm("dir")}.should raise_error(Errno::EISDIR)
58
+ end
59
+ end
60
+
61
+ describe "#rm_f" do
62
+ it "remove file force" do
63
+ lambda{Pa.rm_f("dir")}.should_not raise_error(Errno::EISDIR)
64
+ end
65
+ end
66
+
67
+ describe "#rmdir" do
68
+ it "remove directory" do
69
+ Pa.rmdir "dir"
70
+ File.exists?("dir").should be_false
71
+ lambda{Pa.rmdir("a")}.should raise_error(Errno::ENOTDIR)
72
+ end
73
+ end
74
+
75
+ describe "#rmdir_f" do
76
+ it "remove directory force" do
77
+ lambda{Pa.rmdir_r("a")}.should_not raise_error(Errno::ENOTDIR)
78
+ end
79
+ end
80
+
81
+ describe "#rm_r" do
82
+ it "remove both file and directory" do
83
+ Pa.rm "a"
84
+ File.exists?("a").should be_false
85
+ Pa.rm_r "dir"
86
+ File.exists?("dir").should be_false
87
+ end
88
+ end
89
+
90
+
91
+
92
+ describe "#rm_if" do
93
+ it "remove if condition" do
94
+ Pa.rm_if "." do |pa|
95
+ next if pa.p=="a"
96
+ yield if pa.b=="a"
97
+ end
98
+
99
+ File.exists?("a").should be_true
100
+ File.exists?("dir/dira/a").should be_false
101
+ end
102
+ end
103
+
104
+ end
105
+
106
+ describe "#mkdir" do
107
+ after :each do
108
+ FileUtils.rm_r Dir["*"]-%w(. ..)
109
+ end
110
+
111
+ it "mkdir" do
112
+ Pa.mkdir("guten/tag")
113
+ File.exists?("guten/tag").should be_true
114
+ end
115
+ end
116
+
117
+ describe "#_copy" do
118
+ # a symfile
119
+ # ab
120
+ # ac
121
+ # dir/
122
+ # b # guten
123
+ # dira/
124
+ # c
125
+ # destdir/
126
+ # b # tag
127
+ # dir/
128
+ before :all do
129
+ FileUtils.mkdir_p(%w(dir/dira destdir/dir))
130
+ FileUtils.touch(%w(a ab ac dir/b dir/dira/c destdir/dir/b))
131
+ File.symlink("a", "symfile")
132
+ open("dir/b", "w"){|f|f.write "guten"}
133
+ open("destdir/dir/b", "w"){|f|f.write "tag"}
134
+ end
135
+
136
+ it "_copy file" do
137
+ Pa._copy 'a', 'b', verbose: true
138
+ File.exists?('b').should be_true
139
+ end
140
+
141
+ it "_copy directory" do
142
+ Pa._copy 'dir', 'dirc'
143
+ Dir.entries('dirc').should == Dir.entries('dir')
144
+ end
145
+
146
+ context "with :symlink" do
147
+
148
+ it "_copy" do
149
+ Pa._copy 'symfile', 'symfilea'
150
+ File.symlink?('symfilea').should be_true
151
+ end
152
+
153
+ it "_copy with :folsymlink" do
154
+ Pa._copy 'symfile', 'folsymlink', folsymlink:true
155
+ File.symlink?('folsymlink').should be_false
156
+ File.file?('folsymlink').should be_true
157
+ end
158
+
159
+ end
160
+
161
+ context "with :mkdir" do
162
+ it "_copy" do
163
+ lambda{Pa.cp "a", "destdir/mkdir/dir"}.should raise_error(Errno::ENOENT)
164
+ end
165
+
166
+ it "_copy with :mkdir" do
167
+ lambda{Pa.cp "a", "destdir/mkdir/dir", mkdir:true}.should_not raise_error(Errno::ENOENT)
168
+ File.exists?("destdir/mkdir/dir/a").should be_true
169
+ end
170
+
171
+ it "_copy with :mkdir" do
172
+ lambda{Pa.cp "a", "destdir/mkdira", mkdir:true}.should_not raise_error(Errno::ENOENT)
173
+ File.exists?("destdir/mkdira/a").should be_true
174
+ end
175
+ end
176
+
177
+ context "with :force" do
178
+ it "_copy" do
179
+ File.open("destdir/overwrite","w"){|f|f.write("")}
180
+ lambda{Pa.cp "a", "destdir/overwrite"}.should raise_error(Errno::EEXIST)
181
+ end
182
+
183
+ it "_copy with :force" do
184
+ lambda{Pa.cp "a", "destdir/overwrite", force:true}.should_not raise_error(Errno::EEXIST)
185
+ end
186
+ end
187
+
188
+ it "_copy with :normal" do
189
+ Pa._copy 'dir', 'dir_normal', special: true
190
+ Dir.empty?('dir_normal').should be_true
191
+ end
192
+
193
+ end
194
+
195
+ describe "#cp" do
196
+ it "cp file destdir/file" do
197
+ Pa.cp "a", "destdir/aa"
198
+ File.exists?("destdir/aa").should be_true
199
+ end
200
+
201
+ it "cp file destdir/" do
202
+ Pa.cp "a", "destdir"
203
+ File.exists?("destdir/a").should be_true
204
+ end
205
+
206
+ it "cp file1 file2 .. dest_file" do
207
+ lambda{Pa.cp(%w(a ab), "ac")}.should raise_error(Errno::ENOTDIR)
208
+ end
209
+
210
+ it "cp file1 file2 .. dird/" do
211
+ Dir.mkdir 'dird'
212
+ Pa.cp %w(a ab), "dird"
213
+ File.exists?("dird/a").should be_true
214
+ File.exists?("dird/ab").should be_true
215
+ end
216
+ end
217
+
218
+ describe "#_move" do
219
+ # a
220
+ # dir/ b
221
+ before :each do
222
+ FileUtils.mkdir_p(%w(dir))
223
+ FileUtils.touch(%w(a dir/b))
224
+ end
225
+ after :each do
226
+ FileUtils.rm_r Dir["*"]-%w(. ..)
227
+ end
228
+
229
+ it "mv a dir/a" do
230
+ ino = File.stat('a').ino
231
+ Pa._move "a", "dir/a", {}
232
+ File.stat('dir/a').ino.should == ino
233
+ File.exists?("a").should be_false
234
+ end
235
+
236
+ context "with :force" do
237
+ it "mv a dir/b" do
238
+ lambda{Pa._move "a", "dir/b", {}}.should raise_error Errno::EEXIST
239
+ end
240
+
241
+ it "mv a dir/b :force" do
242
+ ino = File.stat('a').ino
243
+ Pa._move "a", "dir/b", force:true
244
+ File.stat("dir/b").ino.should == ino
245
+ end
246
+ end
247
+
248
+ end
249
+
250
+ describe "#mv" do
251
+ # a b c
252
+ # dir/ aa
253
+ before :each do
254
+ FileUtils.mkdir_p(%w(dir))
255
+ FileUtils.touch(%w(a b c dir/aa))
256
+ end
257
+ after :each do
258
+ FileUtils.rm_r Dir["*"]-%w(. ..)
259
+ end
260
+
261
+ it "mv a dir/" do
262
+ Pa.mv "a", "dir"
263
+ File.exists?("dir/a").should be_true
264
+ end
265
+
266
+ it "mv a b .. file" do
267
+ lambda{Pa.mv(%w(a b), "c")}.should raise_error(Errno::ENOTDIR)
268
+ end
269
+
270
+ it "mv file1 file2 .. dir/" do
271
+ Pa.mv %w(a b), "dir"
272
+ File.exists?("dir/a").should be_true
273
+ File.exists?("dir/b").should be_true
274
+ end
275
+ end
276
+
277
+ end
278
+ =end
@@ -0,0 +1,137 @@
1
+ require "spec_helper"
2
+ require "fileutils"
3
+ require "tmpdir"
4
+
5
+ class Pa
6
+ class << self
7
+ public :_copy, :_move, :_rmdir, :_mktmpname, :_mkdir, :_touch
8
+ end
9
+ end
10
+
11
+ describe Pa do
12
+ before :all do
13
+ @curdir = Dir.pwd
14
+ @tmpdir = Dir.mktmpdir
15
+ Dir.chdir(@tmpdir)
16
+ end
17
+
18
+ after(:all) do
19
+ Dir.chdir(@curdir)
20
+ FileUtils.rm_r @tmpdir
21
+ end
22
+
23
+ describe "#glob" do
24
+ before(:each) do
25
+ @files = %w(fa .fa)
26
+ FileUtils.touch(@files)
27
+ end
28
+ after(:each) do
29
+ FileUtils.rm @files
30
+ end
31
+
32
+ context "call without any option" do
33
+ it "returns 1 items" do
34
+ Pa.glob("*").should have(1).items
35
+ end
36
+ end
37
+
38
+ context "call with :dotmatch option" do
39
+ it "returns 2 items" do
40
+ Pa.glob("*", dotmatch: true).should have(2).items
41
+ end
42
+ end
43
+ end
44
+
45
+ describe "#each" do
46
+ # fa .fa fa~
47
+ # dira/
48
+ # dirb/
49
+ # b
50
+ before(:each) do
51
+ @dirs = %w(dira/dirb)
52
+ @files = %w(fa .fa fa~ dira/dirb/b)
53
+ FileUtils.mkdir_p(@dirs)
54
+ FileUtils.touch(@files)
55
+ end
56
+ after(:each) do
57
+ FileUtils.rm @files
58
+ FileUtils.rm_r @dirs
59
+ end
60
+
61
+ it "runs on" do
62
+ ret = []
63
+ Pa.each{|pa| ret << pa.fname}
64
+ ret.sort.should == %w(.fa dira fa fa~)
65
+ end
66
+
67
+ it "return a Enumerator when call without block" do
68
+ Pa.each.should be_an_instance_of Enumerator
69
+ end
70
+
71
+ it "raise Errno::ENOENT if path doesn't exists" do
72
+ lambda { Pa.each("path_doesn't_exits"){} }.should raise_error(Errno::ENOENT)
73
+ end
74
+
75
+ it "raise Errno::ENOTDIDR if path isn't a directory" do
76
+ lambda { Pa.each("fa"){} }.should raise_error(Errno::ENOTDIR)
77
+ end
78
+
79
+ it "each(.) return 'foo' not '.foo'" do
80
+ Pa.each.with_object([]){|pa,m| m<<pa.p}.sort.should == %w(.fa dira fa fa~)
81
+ end
82
+
83
+ it "each(nodot: true) -> list all files except dot file" do
84
+ Pa.each(nodot: true).with_object([]){|pa,m|m<<pa.b}.sort.should == %w(dira fa fa~)
85
+ end
86
+
87
+ end
88
+
89
+ describe "#each_r" do
90
+ # fa .fa fa~
91
+ # dira/
92
+ # dirb/
93
+ # b
94
+ before(:each) do
95
+ @dirs = %w(dira/dirb)
96
+ @files = %w(fa .fa fa~ dira/dirb/b)
97
+ FileUtils.mkdir_p(@dirs)
98
+ FileUtils.touch(@files)
99
+ end
100
+ after(:each) do
101
+ FileUtils.rm @files
102
+ FileUtils.rm_r @dirs
103
+ end
104
+
105
+ it "each_r -> Enumerator" do
106
+ Pa.each_r.should be_an_instance_of Enumerator
107
+ Pa.each_r.with_object([]){|(pa,r),m|m<<r}.sort.should == %w(.fa dira dira/dirb dira/dirb/b fa fa~)
108
+ end
109
+ end
110
+
111
+
112
+ describe "#ls" do
113
+ # filea
114
+ # dira/
115
+ # fileb
116
+ before(:each) do
117
+ @dirs = %w(dira)
118
+ @files = %w(filea dira/fileb)
119
+ FileUtils.mkdir_p(@dirs)
120
+ FileUtils.touch(@files)
121
+ end
122
+ after(:each) do
123
+ FileUtils.rm @files
124
+ FileUtils.rm_r @dirs
125
+ end
126
+
127
+ it "runs ok -> Array" do
128
+ Pa.ls.should == ["filea", "dira"]
129
+ end
130
+
131
+ it "call a block" do
132
+ Pa.ls { |pa, fname| pa.directory? }.should == ["dira"]
133
+ end
134
+ end
135
+
136
+
137
+ end