bowline 0.5.4 → 0.5.5
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/VERSION +1 -1
- data/bowline.gemspec +2 -3
- data/lib/bowline/initializer.rb +1 -29
- data/lib/bowline/library.rb +0 -2
- data/lib/bowline/tasks/libs.rake +26 -20
- data/lib/bowline/version.rb +1 -1
- metadata +2 -3
- data/vendor/pathname.rb +0 -1095
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.5.
|
1
|
+
0.5.5
|
data/bowline.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{bowline}
|
8
|
-
s.version = "0.5.
|
8
|
+
s.version = "0.5.5"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Alex MacCaw"]
|
12
|
-
s.date = %q{2009-12-
|
12
|
+
s.date = %q{2009-12-23}
|
13
13
|
s.default_executable = %q{bowline-gen}
|
14
14
|
s.description = %q{Ruby/JS GUI framework}
|
15
15
|
s.email = %q{alex@leadthinking.com}
|
@@ -116,7 +116,6 @@ Gem::Specification.new do |s|
|
|
116
116
|
"templates/script/init",
|
117
117
|
"templates/script/run",
|
118
118
|
"templates/window.rb",
|
119
|
-
"vendor/pathname.rb",
|
120
119
|
"vendor/progressbar.rb"
|
121
120
|
]
|
122
121
|
s.homepage = %q{http://github.com/maccman/bowline}
|
data/lib/bowline/initializer.rb
CHANGED
@@ -60,34 +60,6 @@ module Bowline
|
|
60
60
|
@configuration = configuration
|
61
61
|
@loaded_plugins = []
|
62
62
|
end
|
63
|
-
|
64
|
-
# Add all of Ruby's stdlib to the load path
|
65
|
-
def initialize_ruby
|
66
|
-
return unless Bowline::Desktop.enabled?
|
67
|
-
ruby_path = Bowline::Library.local_rubylib_path
|
68
|
-
unless File.directory?(ruby_path)
|
69
|
-
ruby_path = Bowline::Library.rubylib_path
|
70
|
-
return unless File.directory?(ruby_path)
|
71
|
-
end
|
72
|
-
# Remove old stdlib load paths
|
73
|
-
$:.delete_if {|path| path =~ /^\/usr\// }
|
74
|
-
|
75
|
-
# Add new stdlib load paths
|
76
|
-
version = Library::RUBY_LIB_VERSION
|
77
|
-
platform = Library::RUBY_ARCHLIB_PLATFORM
|
78
|
-
$: << File.join(ruby_path, version) # RUBY_LIB
|
79
|
-
$: << File.join(ruby_path, version, platform) # RUBY_ARCHLIB
|
80
|
-
$: << File.join(ruby_path, "site_path") # RUBY_SITE_LIB
|
81
|
-
$: << File.join(ruby_path, "site_path", version) # RUBY_SITE_LIB2
|
82
|
-
$: << File.join(ruby_path, "site_ruby", version, platform) # RUBY_SITE_ARCHLIB
|
83
|
-
$: << File.join(ruby_path, "vendor_ruby") # RUBY_VENDOR_LIB
|
84
|
-
$: << File.join(ruby_path, "vendor_ruby", version) # RUBY_VENDOR_LIB2
|
85
|
-
$: << File.join(ruby_path, "vendor_ruby", version, platform) # RUBY_VENDOR_ARCHLIB
|
86
|
-
|
87
|
-
# These two need to be required to fully setup internationalization
|
88
|
-
require File.join(*%w[enc encdb])
|
89
|
-
require File.join(*%w[enc trans transdb])
|
90
|
-
end
|
91
63
|
|
92
64
|
def require_frameworks
|
93
65
|
configuration.frameworks.each { |framework| require(framework.to_s) }
|
@@ -203,6 +175,7 @@ module Bowline
|
|
203
175
|
end
|
204
176
|
|
205
177
|
def initialize_gems
|
178
|
+
require "rubygems"
|
206
179
|
Gem.clear_paths
|
207
180
|
Gem.path.unshift(configuration.gem_path)
|
208
181
|
end
|
@@ -307,7 +280,6 @@ module Bowline
|
|
307
280
|
def process
|
308
281
|
Bowline.configuration = configuration
|
309
282
|
|
310
|
-
initialize_ruby
|
311
283
|
set_load_path
|
312
284
|
initialize_gems
|
313
285
|
load_gems
|
data/lib/bowline/library.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
module Bowline
|
2
2
|
# Provides paths to Bowline's required libraries.
|
3
3
|
module Library
|
4
|
-
RUBY_LIB_VERSION = "1.9.1"
|
5
|
-
RUBY_ARCHLIB_PLATFORM = "i386-darwin9.8.0"
|
6
4
|
PROJECT_URL = "http://bowline.s3.amazonaws.com/#{Platform.type}"
|
7
5
|
DESKTOP_URL = "#{PROJECT_URL}/bowline-desktop"
|
8
6
|
RUBYLIB_URL = "#{PROJECT_URL}/rubylib.zip"
|
data/lib/bowline/tasks/libs.rake
CHANGED
@@ -33,27 +33,33 @@ def unzip(fpath, tpath)
|
|
33
33
|
}
|
34
34
|
end
|
35
35
|
|
36
|
+
def sym_or_copy(from, to)
|
37
|
+
begin
|
38
|
+
FileUtils.ln_s(from, to)
|
39
|
+
rescue NotImplementedError
|
40
|
+
FileUtils.cp_r(from, to)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
36
44
|
namespace :libs do
|
37
|
-
# Lots of people are using Ruby 1.8 with Bowline.
|
38
|
-
# When bowline-desktop loads, it doesn't know where the
|
39
|
-
# Bowline gem is if it's an 1.8 gem dir. So, we just symlink
|
40
|
-
# it to vendor/bowline. One caveat though, is that you have to
|
41
|
-
# re-run this task when you update the gem.
|
42
45
|
task :unpack => :environment do
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
46
|
+
# Lots of people are using Ruby 1.8 with Bowline.
|
47
|
+
# When bowline-desktop loads, it doesn't know where the
|
48
|
+
# Bowline gem is if it's an 1.8 gem dir. So, we just symlink
|
49
|
+
# it to vendor/bowline. One caveat though, is that you have to
|
50
|
+
# re-run this task when you update the gem.
|
51
|
+
local_bowline_path = Bowline::Library.local_bowline_path
|
52
|
+
sym_or_copy(
|
53
|
+
Bowline.lib_path,
|
54
|
+
local_bowline_path
|
55
|
+
) unless File.directory?(local_bowline_path)
|
56
|
+
|
57
|
+
local_rubylib_path = Bowline::Library.local_rubylib_path
|
58
|
+
raise "Run libs:download task first" unless File.directory?(Bowline::Library.rubylib_path)
|
59
|
+
sym_or_copy(
|
60
|
+
Bowline::Library.rubylib_path,
|
61
|
+
local_rubylib_path
|
62
|
+
) unless File.directory?(local_rubylib_path)
|
57
63
|
end
|
58
64
|
|
59
65
|
desc "Download Bowline's binary and pre-compiled libs"
|
@@ -77,7 +83,7 @@ namespace :libs do
|
|
77
83
|
end
|
78
84
|
end
|
79
85
|
|
80
|
-
task :setup => [:environment, "gems:sync", "libs:
|
86
|
+
task :setup => [:environment, "gems:sync", "libs:download", "libs:unpack"]
|
81
87
|
|
82
88
|
desc "Update Bowline's binary and pre-compiled libs"
|
83
89
|
task :update => :environment do
|
data/lib/bowline/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bowline
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alex MacCaw
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-12-
|
12
|
+
date: 2009-12-23 00:00:00 +00:00
|
13
13
|
default_executable: bowline-gen
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -149,7 +149,6 @@ files:
|
|
149
149
|
- templates/script/init
|
150
150
|
- templates/script/run
|
151
151
|
- templates/window.rb
|
152
|
-
- vendor/pathname.rb
|
153
152
|
- vendor/progressbar.rb
|
154
153
|
has_rdoc: true
|
155
154
|
homepage: http://github.com/maccman/bowline
|
data/vendor/pathname.rb
DELETED
@@ -1,1095 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# = pathname.rb
|
3
|
-
#
|
4
|
-
# Object-Oriented Pathname Class
|
5
|
-
#
|
6
|
-
# Author:: Tanaka Akira <akr@m17n.org>
|
7
|
-
# Documentation:: Author and Gavin Sinclair
|
8
|
-
#
|
9
|
-
# For documentation, see class Pathname.
|
10
|
-
#
|
11
|
-
# <tt>pathname.rb</tt> is distributed with Ruby since 1.8.0.
|
12
|
-
#
|
13
|
-
|
14
|
-
#
|
15
|
-
# == Pathname
|
16
|
-
#
|
17
|
-
# Pathname represents a pathname which locates a file in a filesystem.
|
18
|
-
# The pathname depends on OS: Unix, Windows, etc.
|
19
|
-
# Pathname library works with pathnames of local OS.
|
20
|
-
# However non-Unix pathnames are supported experimentally.
|
21
|
-
#
|
22
|
-
# It does not represent the file itself.
|
23
|
-
# A Pathname can be relative or absolute. It's not until you try to
|
24
|
-
# reference the file that it even matters whether the file exists or not.
|
25
|
-
#
|
26
|
-
# Pathname is immutable. It has no method for destructive update.
|
27
|
-
#
|
28
|
-
# The value of this class is to manipulate file path information in a neater
|
29
|
-
# way than standard Ruby provides. The examples below demonstrate the
|
30
|
-
# difference. *All* functionality from File, FileTest, and some from Dir and
|
31
|
-
# FileUtils is included, in an unsurprising way. It is essentially a facade for
|
32
|
-
# all of these, and more.
|
33
|
-
#
|
34
|
-
# == Examples
|
35
|
-
#
|
36
|
-
# === Example 1: Using Pathname
|
37
|
-
#
|
38
|
-
# require 'pathname'
|
39
|
-
# p = Pathname.new("/usr/bin/ruby")
|
40
|
-
# size = p.size # 27662
|
41
|
-
# isdir = p.directory? # false
|
42
|
-
# dir = p.dirname # Pathname:/usr/bin
|
43
|
-
# base = p.basename # Pathname:ruby
|
44
|
-
# dir, base = p.split # [Pathname:/usr/bin, Pathname:ruby]
|
45
|
-
# data = p.read
|
46
|
-
# p.open { |f| _ }
|
47
|
-
# p.each_line { |line| _ }
|
48
|
-
#
|
49
|
-
# === Example 2: Using standard Ruby
|
50
|
-
#
|
51
|
-
# p = "/usr/bin/ruby"
|
52
|
-
# size = File.size(p) # 27662
|
53
|
-
# isdir = File.directory?(p) # false
|
54
|
-
# dir = File.dirname(p) # "/usr/bin"
|
55
|
-
# base = File.basename(p) # "ruby"
|
56
|
-
# dir, base = File.split(p) # ["/usr/bin", "ruby"]
|
57
|
-
# data = File.read(p)
|
58
|
-
# File.open(p) { |f| _ }
|
59
|
-
# File.foreach(p) { |line| _ }
|
60
|
-
#
|
61
|
-
# === Example 3: Special features
|
62
|
-
#
|
63
|
-
# p1 = Pathname.new("/usr/lib") # Pathname:/usr/lib
|
64
|
-
# p2 = p1 + "ruby/1.8" # Pathname:/usr/lib/ruby/1.8
|
65
|
-
# p3 = p1.parent # Pathname:/usr
|
66
|
-
# p4 = p2.relative_path_from(p3) # Pathname:lib/ruby/1.8
|
67
|
-
# pwd = Pathname.pwd # Pathname:/home/gavin
|
68
|
-
# pwd.absolute? # true
|
69
|
-
# p5 = Pathname.new "." # Pathname:.
|
70
|
-
# p5 = p5 + "music/../articles" # Pathname:music/../articles
|
71
|
-
# p5.cleanpath # Pathname:articles
|
72
|
-
# p5.realpath # Pathname:/home/gavin/articles
|
73
|
-
# p5.children # [Pathname:/home/gavin/articles/linux, ...]
|
74
|
-
#
|
75
|
-
# == Breakdown of functionality
|
76
|
-
#
|
77
|
-
# === Core methods
|
78
|
-
#
|
79
|
-
# These methods are effectively manipulating a String, because that's all a path
|
80
|
-
# is. Except for #mountpoint?, #children, and #realpath, they don't access the
|
81
|
-
# filesystem.
|
82
|
-
#
|
83
|
-
# - +
|
84
|
-
# - #join
|
85
|
-
# - #parent
|
86
|
-
# - #root?
|
87
|
-
# - #absolute?
|
88
|
-
# - #relative?
|
89
|
-
# - #relative_path_from
|
90
|
-
# - #each_filename
|
91
|
-
# - #cleanpath
|
92
|
-
# - #realpath
|
93
|
-
# - #children
|
94
|
-
# - #mountpoint?
|
95
|
-
#
|
96
|
-
# === File status predicate methods
|
97
|
-
#
|
98
|
-
# These methods are a facade for FileTest:
|
99
|
-
# - #blockdev?
|
100
|
-
# - #chardev?
|
101
|
-
# - #directory?
|
102
|
-
# - #executable?
|
103
|
-
# - #executable_real?
|
104
|
-
# - #exist?
|
105
|
-
# - #file?
|
106
|
-
# - #grpowned?
|
107
|
-
# - #owned?
|
108
|
-
# - #pipe?
|
109
|
-
# - #readable?
|
110
|
-
# - #world_readable?
|
111
|
-
# - #readable_real?
|
112
|
-
# - #setgid?
|
113
|
-
# - #setuid?
|
114
|
-
# - #size
|
115
|
-
# - #size?
|
116
|
-
# - #socket?
|
117
|
-
# - #sticky?
|
118
|
-
# - #symlink?
|
119
|
-
# - #writable?
|
120
|
-
# - #world_writable?
|
121
|
-
# - #writable_real?
|
122
|
-
# - #zero?
|
123
|
-
#
|
124
|
-
# === File property and manipulation methods
|
125
|
-
#
|
126
|
-
# These methods are a facade for File:
|
127
|
-
# - #atime
|
128
|
-
# - #ctime
|
129
|
-
# - #mtime
|
130
|
-
# - #chmod(mode)
|
131
|
-
# - #lchmod(mode)
|
132
|
-
# - #chown(owner, group)
|
133
|
-
# - #lchown(owner, group)
|
134
|
-
# - #fnmatch(pattern, *args)
|
135
|
-
# - #fnmatch?(pattern, *args)
|
136
|
-
# - #ftype
|
137
|
-
# - #make_link(old)
|
138
|
-
# - #open(*args, &block)
|
139
|
-
# - #readlink
|
140
|
-
# - #rename(to)
|
141
|
-
# - #stat
|
142
|
-
# - #lstat
|
143
|
-
# - #make_symlink(old)
|
144
|
-
# - #truncate(length)
|
145
|
-
# - #utime(atime, mtime)
|
146
|
-
# - #basename(*args)
|
147
|
-
# - #dirname
|
148
|
-
# - #extname
|
149
|
-
# - #expand_path(*args)
|
150
|
-
# - #split
|
151
|
-
#
|
152
|
-
# === Directory methods
|
153
|
-
#
|
154
|
-
# These methods are a facade for Dir:
|
155
|
-
# - Pathname.glob(*args)
|
156
|
-
# - Pathname.getwd / Pathname.pwd
|
157
|
-
# - #rmdir
|
158
|
-
# - #entries
|
159
|
-
# - #each_entry(&block)
|
160
|
-
# - #mkdir(*args)
|
161
|
-
# - #opendir(*args)
|
162
|
-
#
|
163
|
-
# === IO
|
164
|
-
#
|
165
|
-
# These methods are a facade for IO:
|
166
|
-
# - #each_line(*args, &block)
|
167
|
-
# - #read(*args)
|
168
|
-
# - #readlines(*args)
|
169
|
-
# - #sysopen(*args)
|
170
|
-
#
|
171
|
-
# === Utilities
|
172
|
-
#
|
173
|
-
# These methods are a mixture of Find, FileUtils, and others:
|
174
|
-
# - #find(&block)
|
175
|
-
# - #mkpath
|
176
|
-
# - #rmtree
|
177
|
-
# - #unlink / #delete
|
178
|
-
#
|
179
|
-
#
|
180
|
-
# == Method documentation
|
181
|
-
#
|
182
|
-
# As the above section shows, most of the methods in Pathname are facades. The
|
183
|
-
# documentation for these methods generally just says, for instance, "See
|
184
|
-
# FileTest.writable?", as you should be familiar with the original method
|
185
|
-
# anyway, and its documentation (e.g. through +ri+) will contain more
|
186
|
-
# information. In some cases, a brief description will follow.
|
187
|
-
#
|
188
|
-
class Pathname
|
189
|
-
|
190
|
-
# :stopdoc:
|
191
|
-
if RUBY_VERSION < "1.9"
|
192
|
-
TO_PATH = :to_str
|
193
|
-
else
|
194
|
-
# to_path is implemented so Pathname objects are usable with File.open, etc.
|
195
|
-
TO_PATH = :to_path
|
196
|
-
end
|
197
|
-
|
198
|
-
SAME_PATHS = if File::FNM_SYSCASE
|
199
|
-
proc {|a, b| a.casecmp(b).zero?}
|
200
|
-
else
|
201
|
-
proc {|a, b| a == b}
|
202
|
-
end
|
203
|
-
|
204
|
-
# :startdoc:
|
205
|
-
|
206
|
-
#
|
207
|
-
# Create a Pathname object from the given String (or String-like object).
|
208
|
-
# If +path+ contains a NUL character (<tt>\0</tt>), an ArgumentError is raised.
|
209
|
-
#
|
210
|
-
def initialize(path)
|
211
|
-
path = path.__send__(TO_PATH) if path.respond_to? TO_PATH
|
212
|
-
@path = path.dup
|
213
|
-
|
214
|
-
if /\0/ =~ @path
|
215
|
-
raise ArgumentError, "pathname contains \\0: #{@path.inspect}"
|
216
|
-
end
|
217
|
-
|
218
|
-
self.taint if @path.tainted?
|
219
|
-
end
|
220
|
-
|
221
|
-
def freeze() super; @path.freeze; self end
|
222
|
-
def taint() super; @path.taint; self end
|
223
|
-
def untaint() super; @path.untaint; self end
|
224
|
-
|
225
|
-
#
|
226
|
-
# Compare this pathname with +other+. The comparison is string-based.
|
227
|
-
# Be aware that two different paths (<tt>foo.txt</tt> and <tt>./foo.txt</tt>)
|
228
|
-
# can refer to the same file.
|
229
|
-
#
|
230
|
-
def ==(other)
|
231
|
-
return false unless Pathname === other
|
232
|
-
other.to_s == @path
|
233
|
-
end
|
234
|
-
alias === ==
|
235
|
-
alias eql? ==
|
236
|
-
|
237
|
-
# Provides for comparing pathnames, case-sensitively.
|
238
|
-
def <=>(other)
|
239
|
-
return nil unless Pathname === other
|
240
|
-
@path.tr('/', "\0") <=> other.to_s.tr('/', "\0")
|
241
|
-
end
|
242
|
-
|
243
|
-
def hash # :nodoc:
|
244
|
-
@path.hash
|
245
|
-
end
|
246
|
-
|
247
|
-
# Return the path as a String.
|
248
|
-
def to_s
|
249
|
-
@path.dup
|
250
|
-
end
|
251
|
-
|
252
|
-
# to_path is implemented so Pathname objects are usable with File.open, etc.
|
253
|
-
alias_method TO_PATH, :to_s
|
254
|
-
|
255
|
-
def inspect # :nodoc:
|
256
|
-
"#<#{self.class}:#{@path}>"
|
257
|
-
end
|
258
|
-
|
259
|
-
# Return a pathname which is substituted by String#sub.
|
260
|
-
def sub(pattern, *rest, &block)
|
261
|
-
if block
|
262
|
-
path = @path.sub(pattern, *rest) {|*args|
|
263
|
-
begin
|
264
|
-
old = Thread.current[:pathname_sub_matchdata]
|
265
|
-
Thread.current[:pathname_sub_matchdata] = $~
|
266
|
-
eval("$~ = Thread.current[:pathname_sub_matchdata]", block.binding)
|
267
|
-
ensure
|
268
|
-
Thread.current[:pathname_sub_matchdata] = old
|
269
|
-
end
|
270
|
-
yield *args
|
271
|
-
}
|
272
|
-
else
|
273
|
-
path = @path.sub(pattern, *rest)
|
274
|
-
end
|
275
|
-
self.class.new(path)
|
276
|
-
end
|
277
|
-
|
278
|
-
if File::ALT_SEPARATOR
|
279
|
-
SEPARATOR_LIST = "#{Regexp.quote File::ALT_SEPARATOR}#{Regexp.quote File::SEPARATOR}"
|
280
|
-
SEPARATOR_PAT = /[#{SEPARATOR_LIST}]/
|
281
|
-
else
|
282
|
-
SEPARATOR_LIST = "#{Regexp.quote File::SEPARATOR}"
|
283
|
-
SEPARATOR_PAT = /#{Regexp.quote File::SEPARATOR}/
|
284
|
-
end
|
285
|
-
|
286
|
-
# Return a pathname which the extension of the basename is substituted by
|
287
|
-
# <i>repl</i>.
|
288
|
-
#
|
289
|
-
# If self has no extension part, <i>repl</i> is appended.
|
290
|
-
def sub_ext(repl)
|
291
|
-
ext = File.extname(@path)
|
292
|
-
self.class.new(@path.chomp(ext) + repl)
|
293
|
-
end
|
294
|
-
|
295
|
-
# chop_basename(path) -> [pre-basename, basename] or nil
|
296
|
-
def chop_basename(path)
|
297
|
-
base = File.basename(path)
|
298
|
-
if /\A#{SEPARATOR_PAT}?\z/ =~ base
|
299
|
-
return nil
|
300
|
-
else
|
301
|
-
return path[0, path.rindex(base)], base
|
302
|
-
end
|
303
|
-
end
|
304
|
-
private :chop_basename
|
305
|
-
|
306
|
-
# split_names(path) -> prefix, [name, ...]
|
307
|
-
def split_names(path)
|
308
|
-
names = []
|
309
|
-
while r = chop_basename(path)
|
310
|
-
path, basename = r
|
311
|
-
names.unshift basename
|
312
|
-
end
|
313
|
-
return path, names
|
314
|
-
end
|
315
|
-
private :split_names
|
316
|
-
|
317
|
-
def prepend_prefix(prefix, relpath)
|
318
|
-
if relpath.empty?
|
319
|
-
File.dirname(prefix)
|
320
|
-
elsif /#{SEPARATOR_PAT}/ =~ prefix
|
321
|
-
prefix = File.dirname(prefix)
|
322
|
-
prefix = File.join(prefix, "") if File.basename(prefix + 'a') != 'a'
|
323
|
-
prefix + relpath
|
324
|
-
else
|
325
|
-
prefix + relpath
|
326
|
-
end
|
327
|
-
end
|
328
|
-
private :prepend_prefix
|
329
|
-
|
330
|
-
# Returns clean pathname of +self+ with consecutive slashes and useless dots
|
331
|
-
# removed. The filesystem is not accessed.
|
332
|
-
#
|
333
|
-
# If +consider_symlink+ is +true+, then a more conservative algorithm is used
|
334
|
-
# to avoid breaking symbolic linkages. This may retain more <tt>..</tt>
|
335
|
-
# entries than absolutely necessary, but without accessing the filesystem,
|
336
|
-
# this can't be avoided. See #realpath.
|
337
|
-
#
|
338
|
-
def cleanpath(consider_symlink=false)
|
339
|
-
if consider_symlink
|
340
|
-
cleanpath_conservative
|
341
|
-
else
|
342
|
-
cleanpath_aggressive
|
343
|
-
end
|
344
|
-
end
|
345
|
-
|
346
|
-
#
|
347
|
-
# Clean the path simply by resolving and removing excess "." and ".." entries.
|
348
|
-
# Nothing more, nothing less.
|
349
|
-
#
|
350
|
-
def cleanpath_aggressive
|
351
|
-
path = @path
|
352
|
-
names = []
|
353
|
-
pre = path
|
354
|
-
while r = chop_basename(pre)
|
355
|
-
pre, base = r
|
356
|
-
case base
|
357
|
-
when '.'
|
358
|
-
when '..'
|
359
|
-
names.unshift base
|
360
|
-
else
|
361
|
-
if names[0] == '..'
|
362
|
-
names.shift
|
363
|
-
else
|
364
|
-
names.unshift base
|
365
|
-
end
|
366
|
-
end
|
367
|
-
end
|
368
|
-
if /#{SEPARATOR_PAT}/o =~ File.basename(pre)
|
369
|
-
names.shift while names[0] == '..'
|
370
|
-
end
|
371
|
-
self.class.new(prepend_prefix(pre, File.join(*names)))
|
372
|
-
end
|
373
|
-
private :cleanpath_aggressive
|
374
|
-
|
375
|
-
# has_trailing_separator?(path) -> bool
|
376
|
-
def has_trailing_separator?(path)
|
377
|
-
if r = chop_basename(path)
|
378
|
-
pre, basename = r
|
379
|
-
pre.length + basename.length < path.length
|
380
|
-
else
|
381
|
-
false
|
382
|
-
end
|
383
|
-
end
|
384
|
-
private :has_trailing_separator?
|
385
|
-
|
386
|
-
# add_trailing_separator(path) -> path
|
387
|
-
def add_trailing_separator(path)
|
388
|
-
if File.basename(path + 'a') == 'a'
|
389
|
-
path
|
390
|
-
else
|
391
|
-
File.join(path, "") # xxx: Is File.join is appropriate to add separator?
|
392
|
-
end
|
393
|
-
end
|
394
|
-
private :add_trailing_separator
|
395
|
-
|
396
|
-
def del_trailing_separator(path)
|
397
|
-
if r = chop_basename(path)
|
398
|
-
pre, basename = r
|
399
|
-
pre + basename
|
400
|
-
elsif /#{SEPARATOR_PAT}+\z/o =~ path
|
401
|
-
$` + File.dirname(path)[/#{SEPARATOR_PAT}*\z/o]
|
402
|
-
else
|
403
|
-
path
|
404
|
-
end
|
405
|
-
end
|
406
|
-
private :del_trailing_separator
|
407
|
-
|
408
|
-
def cleanpath_conservative
|
409
|
-
path = @path
|
410
|
-
names = []
|
411
|
-
pre = path
|
412
|
-
while r = chop_basename(pre)
|
413
|
-
pre, base = r
|
414
|
-
names.unshift base if base != '.'
|
415
|
-
end
|
416
|
-
if /#{SEPARATOR_PAT}/o =~ File.basename(pre)
|
417
|
-
names.shift while names[0] == '..'
|
418
|
-
end
|
419
|
-
if names.empty?
|
420
|
-
self.class.new(File.dirname(pre))
|
421
|
-
else
|
422
|
-
if names.last != '..' && File.basename(path) == '.'
|
423
|
-
names << '.'
|
424
|
-
end
|
425
|
-
result = prepend_prefix(pre, File.join(*names))
|
426
|
-
if /\A(?:\.|\.\.)\z/ !~ names.last && has_trailing_separator?(path)
|
427
|
-
self.class.new(add_trailing_separator(result))
|
428
|
-
else
|
429
|
-
self.class.new(result)
|
430
|
-
end
|
431
|
-
end
|
432
|
-
end
|
433
|
-
private :cleanpath_conservative
|
434
|
-
|
435
|
-
def realpath_rec(prefix, unresolved, h)
|
436
|
-
resolved = []
|
437
|
-
until unresolved.empty?
|
438
|
-
n = unresolved.shift
|
439
|
-
if n == '.'
|
440
|
-
next
|
441
|
-
elsif n == '..'
|
442
|
-
resolved.pop
|
443
|
-
else
|
444
|
-
path = prepend_prefix(prefix, File.join(*(resolved + [n])))
|
445
|
-
if h.include? path
|
446
|
-
if h[path] == :resolving
|
447
|
-
raise Errno::ELOOP.new(path)
|
448
|
-
else
|
449
|
-
prefix, *resolved = h[path]
|
450
|
-
end
|
451
|
-
else
|
452
|
-
s = File.lstat(path)
|
453
|
-
if s.symlink?
|
454
|
-
h[path] = :resolving
|
455
|
-
link_prefix, link_names = split_names(File.readlink(path))
|
456
|
-
if link_prefix == ''
|
457
|
-
prefix, *resolved = h[path] = realpath_rec(prefix, resolved + link_names, h)
|
458
|
-
else
|
459
|
-
prefix, *resolved = h[path] = realpath_rec(link_prefix, link_names, h)
|
460
|
-
end
|
461
|
-
else
|
462
|
-
resolved << n
|
463
|
-
h[path] = [prefix, *resolved]
|
464
|
-
end
|
465
|
-
end
|
466
|
-
end
|
467
|
-
end
|
468
|
-
return prefix, *resolved
|
469
|
-
end
|
470
|
-
private :realpath_rec
|
471
|
-
|
472
|
-
#
|
473
|
-
# Returns a real (absolute) pathname of +self+ in the actual filesystem.
|
474
|
-
# The real pathname doesn't contain symlinks or useless dots.
|
475
|
-
#
|
476
|
-
# No arguments should be given; the old behaviour is *obsoleted*.
|
477
|
-
#
|
478
|
-
def realpath
|
479
|
-
path = @path
|
480
|
-
prefix, names = split_names(path)
|
481
|
-
if prefix == ''
|
482
|
-
prefix, names2 = split_names(Dir.pwd)
|
483
|
-
names = names2 + names
|
484
|
-
end
|
485
|
-
prefix, *names = realpath_rec(prefix, names, {})
|
486
|
-
self.class.new(prepend_prefix(prefix, File.join(*names)))
|
487
|
-
end
|
488
|
-
|
489
|
-
# #parent returns the parent directory.
|
490
|
-
#
|
491
|
-
# This is same as <tt>self + '..'</tt>.
|
492
|
-
def parent
|
493
|
-
self + '..'
|
494
|
-
end
|
495
|
-
|
496
|
-
# #mountpoint? returns +true+ if <tt>self</tt> points to a mountpoint.
|
497
|
-
def mountpoint?
|
498
|
-
begin
|
499
|
-
stat1 = self.lstat
|
500
|
-
stat2 = self.parent.lstat
|
501
|
-
stat1.dev == stat2.dev && stat1.ino == stat2.ino ||
|
502
|
-
stat1.dev != stat2.dev
|
503
|
-
rescue Errno::ENOENT
|
504
|
-
false
|
505
|
-
end
|
506
|
-
end
|
507
|
-
|
508
|
-
#
|
509
|
-
# #root? is a predicate for root directories. I.e. it returns +true+ if the
|
510
|
-
# pathname consists of consecutive slashes.
|
511
|
-
#
|
512
|
-
# It doesn't access actual filesystem. So it may return +false+ for some
|
513
|
-
# pathnames which points to roots such as <tt>/usr/..</tt>.
|
514
|
-
#
|
515
|
-
def root?
|
516
|
-
!!(chop_basename(@path) == nil && /#{SEPARATOR_PAT}/o =~ @path)
|
517
|
-
end
|
518
|
-
|
519
|
-
# Predicate method for testing whether a path is absolute.
|
520
|
-
# It returns +true+ if the pathname begins with a slash.
|
521
|
-
def absolute?
|
522
|
-
!relative?
|
523
|
-
end
|
524
|
-
|
525
|
-
# The opposite of #absolute?
|
526
|
-
def relative?
|
527
|
-
path = @path
|
528
|
-
while r = chop_basename(path)
|
529
|
-
path, basename = r
|
530
|
-
end
|
531
|
-
path == ''
|
532
|
-
end
|
533
|
-
|
534
|
-
#
|
535
|
-
# Iterates over each component of the path.
|
536
|
-
#
|
537
|
-
# Pathname.new("/usr/bin/ruby").each_filename {|filename| ... }
|
538
|
-
# # yields "usr", "bin", and "ruby".
|
539
|
-
#
|
540
|
-
def each_filename # :yield: filename
|
541
|
-
return to_enum(__method__) unless block_given?
|
542
|
-
prefix, names = split_names(@path)
|
543
|
-
names.each {|filename| yield filename }
|
544
|
-
nil
|
545
|
-
end
|
546
|
-
|
547
|
-
# Iterates over and yields a new Pathname object
|
548
|
-
# for each element in the given path in descending order.
|
549
|
-
#
|
550
|
-
# Pathname.new('/path/to/some/file.rb').descend {|v| p v}
|
551
|
-
# #<Pathname:/>
|
552
|
-
# #<Pathname:/path>
|
553
|
-
# #<Pathname:/path/to>
|
554
|
-
# #<Pathname:/path/to/some>
|
555
|
-
# #<Pathname:/path/to/some/file.rb>
|
556
|
-
#
|
557
|
-
# Pathname.new('path/to/some/file.rb').descend {|v| p v}
|
558
|
-
# #<Pathname:path>
|
559
|
-
# #<Pathname:path/to>
|
560
|
-
# #<Pathname:path/to/some>
|
561
|
-
# #<Pathname:path/to/some/file.rb>
|
562
|
-
#
|
563
|
-
# It doesn't access actual filesystem.
|
564
|
-
#
|
565
|
-
# This method is available since 1.8.5.
|
566
|
-
#
|
567
|
-
def descend
|
568
|
-
vs = []
|
569
|
-
ascend {|v| vs << v }
|
570
|
-
vs.reverse_each {|v| yield v }
|
571
|
-
nil
|
572
|
-
end
|
573
|
-
|
574
|
-
# Iterates over and yields a new Pathname object
|
575
|
-
# for each element in the given path in ascending order.
|
576
|
-
#
|
577
|
-
# Pathname.new('/path/to/some/file.rb').ascend {|v| p v}
|
578
|
-
# #<Pathname:/path/to/some/file.rb>
|
579
|
-
# #<Pathname:/path/to/some>
|
580
|
-
# #<Pathname:/path/to>
|
581
|
-
# #<Pathname:/path>
|
582
|
-
# #<Pathname:/>
|
583
|
-
#
|
584
|
-
# Pathname.new('path/to/some/file.rb').ascend {|v| p v}
|
585
|
-
# #<Pathname:path/to/some/file.rb>
|
586
|
-
# #<Pathname:path/to/some>
|
587
|
-
# #<Pathname:path/to>
|
588
|
-
# #<Pathname:path>
|
589
|
-
#
|
590
|
-
# It doesn't access actual filesystem.
|
591
|
-
#
|
592
|
-
# This method is available since 1.8.5.
|
593
|
-
#
|
594
|
-
def ascend
|
595
|
-
path = @path
|
596
|
-
yield self
|
597
|
-
while r = chop_basename(path)
|
598
|
-
path, name = r
|
599
|
-
break if path.empty?
|
600
|
-
yield self.class.new(del_trailing_separator(path))
|
601
|
-
end
|
602
|
-
end
|
603
|
-
|
604
|
-
#
|
605
|
-
# Pathname#+ appends a pathname fragment to this one to produce a new Pathname
|
606
|
-
# object.
|
607
|
-
#
|
608
|
-
# p1 = Pathname.new("/usr") # Pathname:/usr
|
609
|
-
# p2 = p1 + "bin/ruby" # Pathname:/usr/bin/ruby
|
610
|
-
# p3 = p1 + "/etc/passwd" # Pathname:/etc/passwd
|
611
|
-
#
|
612
|
-
# This method doesn't access the file system; it is pure string manipulation.
|
613
|
-
#
|
614
|
-
def +(other)
|
615
|
-
other = Pathname.new(other) unless Pathname === other
|
616
|
-
Pathname.new(plus(@path, other.to_s))
|
617
|
-
end
|
618
|
-
|
619
|
-
def plus(path1, path2) # -> path
|
620
|
-
prefix2 = path2
|
621
|
-
index_list2 = []
|
622
|
-
basename_list2 = []
|
623
|
-
while r2 = chop_basename(prefix2)
|
624
|
-
prefix2, basename2 = r2
|
625
|
-
index_list2.unshift prefix2.length
|
626
|
-
basename_list2.unshift basename2
|
627
|
-
end
|
628
|
-
return path2 if prefix2 != ''
|
629
|
-
prefix1 = path1
|
630
|
-
while true
|
631
|
-
while !basename_list2.empty? && basename_list2.first == '.'
|
632
|
-
index_list2.shift
|
633
|
-
basename_list2.shift
|
634
|
-
end
|
635
|
-
break unless r1 = chop_basename(prefix1)
|
636
|
-
prefix1, basename1 = r1
|
637
|
-
next if basename1 == '.'
|
638
|
-
if basename1 == '..' || basename_list2.empty? || basename_list2.first != '..'
|
639
|
-
prefix1 = prefix1 + basename1
|
640
|
-
break
|
641
|
-
end
|
642
|
-
index_list2.shift
|
643
|
-
basename_list2.shift
|
644
|
-
end
|
645
|
-
r1 = chop_basename(prefix1)
|
646
|
-
if !r1 && /#{SEPARATOR_PAT}/o =~ File.basename(prefix1)
|
647
|
-
while !basename_list2.empty? && basename_list2.first == '..'
|
648
|
-
index_list2.shift
|
649
|
-
basename_list2.shift
|
650
|
-
end
|
651
|
-
end
|
652
|
-
if !basename_list2.empty?
|
653
|
-
suffix2 = path2[index_list2.first..-1]
|
654
|
-
r1 ? File.join(prefix1, suffix2) : prefix1 + suffix2
|
655
|
-
else
|
656
|
-
r1 ? prefix1 : File.dirname(prefix1)
|
657
|
-
end
|
658
|
-
end
|
659
|
-
private :plus
|
660
|
-
|
661
|
-
#
|
662
|
-
# Pathname#join joins pathnames.
|
663
|
-
#
|
664
|
-
# <tt>path0.join(path1, ..., pathN)</tt> is the same as
|
665
|
-
# <tt>path0 + path1 + ... + pathN</tt>.
|
666
|
-
#
|
667
|
-
def join(*args)
|
668
|
-
args.unshift self
|
669
|
-
result = args.pop
|
670
|
-
result = Pathname.new(result) unless Pathname === result
|
671
|
-
return result if result.absolute?
|
672
|
-
args.reverse_each {|arg|
|
673
|
-
arg = Pathname.new(arg) unless Pathname === arg
|
674
|
-
result = arg + result
|
675
|
-
return result if result.absolute?
|
676
|
-
}
|
677
|
-
result
|
678
|
-
end
|
679
|
-
|
680
|
-
#
|
681
|
-
# Returns the children of the directory (files and subdirectories, not
|
682
|
-
# recursive) as an array of Pathname objects. By default, the returned
|
683
|
-
# pathnames will have enough information to access the files. If you set
|
684
|
-
# +with_directory+ to +false+, then the returned pathnames will contain the
|
685
|
-
# filename only.
|
686
|
-
#
|
687
|
-
# For example:
|
688
|
-
# p = Pathname("/usr/lib/ruby/1.8")
|
689
|
-
# p.children
|
690
|
-
# # -> [ Pathname:/usr/lib/ruby/1.8/English.rb,
|
691
|
-
# Pathname:/usr/lib/ruby/1.8/Env.rb,
|
692
|
-
# Pathname:/usr/lib/ruby/1.8/abbrev.rb, ... ]
|
693
|
-
# p.children(false)
|
694
|
-
# # -> [ Pathname:English.rb, Pathname:Env.rb, Pathname:abbrev.rb, ... ]
|
695
|
-
#
|
696
|
-
# Note that the result never contain the entries <tt>.</tt> and <tt>..</tt> in
|
697
|
-
# the directory because they are not children.
|
698
|
-
#
|
699
|
-
# This method has existed since 1.8.1.
|
700
|
-
#
|
701
|
-
def children(with_directory=true)
|
702
|
-
with_directory = false if @path == '.'
|
703
|
-
result = []
|
704
|
-
Dir.foreach(@path) {|e|
|
705
|
-
next if e == '.' || e == '..'
|
706
|
-
if with_directory
|
707
|
-
result << self.class.new(File.join(@path, e))
|
708
|
-
else
|
709
|
-
result << self.class.new(e)
|
710
|
-
end
|
711
|
-
}
|
712
|
-
result
|
713
|
-
end
|
714
|
-
|
715
|
-
#
|
716
|
-
# #relative_path_from returns a relative path from the argument to the
|
717
|
-
# receiver. If +self+ is absolute, the argument must be absolute too. If
|
718
|
-
# +self+ is relative, the argument must be relative too.
|
719
|
-
#
|
720
|
-
# #relative_path_from doesn't access the filesystem. It assumes no symlinks.
|
721
|
-
#
|
722
|
-
# ArgumentError is raised when it cannot find a relative path.
|
723
|
-
#
|
724
|
-
# This method has existed since 1.8.1.
|
725
|
-
#
|
726
|
-
def relative_path_from(base_directory)
|
727
|
-
dest_directory = self.cleanpath.to_s
|
728
|
-
base_directory = base_directory.cleanpath.to_s
|
729
|
-
dest_prefix = dest_directory
|
730
|
-
dest_names = []
|
731
|
-
while r = chop_basename(dest_prefix)
|
732
|
-
dest_prefix, basename = r
|
733
|
-
dest_names.unshift basename if basename != '.'
|
734
|
-
end
|
735
|
-
base_prefix = base_directory
|
736
|
-
base_names = []
|
737
|
-
while r = chop_basename(base_prefix)
|
738
|
-
base_prefix, basename = r
|
739
|
-
base_names.unshift basename if basename != '.'
|
740
|
-
end
|
741
|
-
unless SAME_PATHS[dest_prefix, base_prefix]
|
742
|
-
raise ArgumentError, "different prefix: #{dest_prefix.inspect} and #{base_directory.inspect}"
|
743
|
-
end
|
744
|
-
while !dest_names.empty? &&
|
745
|
-
!base_names.empty? &&
|
746
|
-
SAME_PATHS[dest_names.first, base_names.first]
|
747
|
-
dest_names.shift
|
748
|
-
base_names.shift
|
749
|
-
end
|
750
|
-
if base_names.include? '..'
|
751
|
-
raise ArgumentError, "base_directory has ..: #{base_directory.inspect}"
|
752
|
-
end
|
753
|
-
base_names.fill('..')
|
754
|
-
relpath_names = base_names + dest_names
|
755
|
-
if relpath_names.empty?
|
756
|
-
Pathname.new('.')
|
757
|
-
else
|
758
|
-
Pathname.new(File.join(*relpath_names))
|
759
|
-
end
|
760
|
-
end
|
761
|
-
end
|
762
|
-
|
763
|
-
class Pathname # * IO *
|
764
|
-
#
|
765
|
-
# #each_line iterates over the line in the file. It yields a String object
|
766
|
-
# for each line.
|
767
|
-
#
|
768
|
-
# This method has existed since 1.8.1.
|
769
|
-
#
|
770
|
-
def each_line(*args, &block) # :yield: line
|
771
|
-
IO.foreach(@path, *args, &block)
|
772
|
-
end
|
773
|
-
|
774
|
-
# Pathname#foreachline is *obsoleted* at 1.8.1. Use #each_line.
|
775
|
-
def foreachline(*args, &block)
|
776
|
-
warn "Pathname#foreachline is obsoleted. Use Pathname#each_line."
|
777
|
-
each_line(*args, &block)
|
778
|
-
end
|
779
|
-
|
780
|
-
# See <tt>IO.read</tt>. Returns all the bytes from the file, or the first +N+
|
781
|
-
# if specified.
|
782
|
-
def read(*args) IO.read(@path, *args) end
|
783
|
-
|
784
|
-
# See <tt>IO.readlines</tt>. Returns all the lines from the file.
|
785
|
-
def readlines(*args) IO.readlines(@path, *args) end
|
786
|
-
|
787
|
-
# See <tt>IO.sysopen</tt>.
|
788
|
-
def sysopen(*args) IO.sysopen(@path, *args) end
|
789
|
-
end
|
790
|
-
|
791
|
-
|
792
|
-
class Pathname # * File *
|
793
|
-
|
794
|
-
# See <tt>File.atime</tt>. Returns last access time.
|
795
|
-
def atime() File.atime(@path) end
|
796
|
-
|
797
|
-
# See <tt>File.ctime</tt>. Returns last (directory entry, not file) change time.
|
798
|
-
def ctime() File.ctime(@path) end
|
799
|
-
|
800
|
-
# See <tt>File.mtime</tt>. Returns last modification time.
|
801
|
-
def mtime() File.mtime(@path) end
|
802
|
-
|
803
|
-
# See <tt>File.chmod</tt>. Changes permissions.
|
804
|
-
def chmod(mode) File.chmod(mode, @path) end
|
805
|
-
|
806
|
-
# See <tt>File.lchmod</tt>.
|
807
|
-
def lchmod(mode) File.lchmod(mode, @path) end
|
808
|
-
|
809
|
-
# See <tt>File.chown</tt>. Change owner and group of file.
|
810
|
-
def chown(owner, group) File.chown(owner, group, @path) end
|
811
|
-
|
812
|
-
# See <tt>File.lchown</tt>.
|
813
|
-
def lchown(owner, group) File.lchown(owner, group, @path) end
|
814
|
-
|
815
|
-
# See <tt>File.fnmatch</tt>. Return +true+ if the receiver matches the given
|
816
|
-
# pattern.
|
817
|
-
def fnmatch(pattern, *args) File.fnmatch(pattern, @path, *args) end
|
818
|
-
|
819
|
-
# See <tt>File.fnmatch?</tt> (same as #fnmatch).
|
820
|
-
def fnmatch?(pattern, *args) File.fnmatch?(pattern, @path, *args) end
|
821
|
-
|
822
|
-
# See <tt>File.ftype</tt>. Returns "type" of file ("file", "directory",
|
823
|
-
# etc).
|
824
|
-
def ftype() File.ftype(@path) end
|
825
|
-
|
826
|
-
# See <tt>File.link</tt>. Creates a hard link.
|
827
|
-
def make_link(old) File.link(old, @path) end
|
828
|
-
|
829
|
-
# See <tt>File.open</tt>. Opens the file for reading or writing.
|
830
|
-
def open(*args, &block) # :yield: file
|
831
|
-
File.open(@path, *args, &block)
|
832
|
-
end
|
833
|
-
|
834
|
-
# See <tt>File.readlink</tt>. Read symbolic link.
|
835
|
-
def readlink() self.class.new(File.readlink(@path)) end
|
836
|
-
|
837
|
-
# See <tt>File.rename</tt>. Rename the file.
|
838
|
-
def rename(to) File.rename(@path, to) end
|
839
|
-
|
840
|
-
# See <tt>File.stat</tt>. Returns a <tt>File::Stat</tt> object.
|
841
|
-
def stat() File.stat(@path) end
|
842
|
-
|
843
|
-
# See <tt>File.lstat</tt>.
|
844
|
-
def lstat() File.lstat(@path) end
|
845
|
-
|
846
|
-
# See <tt>File.symlink</tt>. Creates a symbolic link.
|
847
|
-
def make_symlink(old) File.symlink(old, @path) end
|
848
|
-
|
849
|
-
# See <tt>File.truncate</tt>. Truncate the file to +length+ bytes.
|
850
|
-
def truncate(length) File.truncate(@path, length) end
|
851
|
-
|
852
|
-
# See <tt>File.utime</tt>. Update the access and modification times.
|
853
|
-
def utime(atime, mtime) File.utime(atime, mtime, @path) end
|
854
|
-
|
855
|
-
# See <tt>File.basename</tt>. Returns the last component of the path.
|
856
|
-
def basename(*args) self.class.new(File.basename(@path, *args)) end
|
857
|
-
|
858
|
-
# See <tt>File.dirname</tt>. Returns all but the last component of the path.
|
859
|
-
def dirname() self.class.new(File.dirname(@path)) end
|
860
|
-
|
861
|
-
# See <tt>File.extname</tt>. Returns the file's extension.
|
862
|
-
def extname() File.extname(@path) end
|
863
|
-
|
864
|
-
# See <tt>File.expand_path</tt>.
|
865
|
-
def expand_path(*args) self.class.new(File.expand_path(@path, *args)) end
|
866
|
-
|
867
|
-
# See <tt>File.split</tt>. Returns the #dirname and the #basename in an
|
868
|
-
# Array.
|
869
|
-
def split() File.split(@path).map {|f| self.class.new(f) } end
|
870
|
-
|
871
|
-
# Pathname#link is confusing and *obsoleted* because the receiver/argument
|
872
|
-
# order is inverted to corresponding system call.
|
873
|
-
def link(old)
|
874
|
-
warn 'Pathname#link is obsoleted. Use Pathname#make_link.'
|
875
|
-
File.link(old, @path)
|
876
|
-
end
|
877
|
-
|
878
|
-
# Pathname#symlink is confusing and *obsoleted* because the receiver/argument
|
879
|
-
# order is inverted to corresponding system call.
|
880
|
-
def symlink(old)
|
881
|
-
warn 'Pathname#symlink is obsoleted. Use Pathname#make_symlink.'
|
882
|
-
File.symlink(old, @path)
|
883
|
-
end
|
884
|
-
end
|
885
|
-
|
886
|
-
|
887
|
-
class Pathname # * FileTest *
|
888
|
-
|
889
|
-
# See <tt>FileTest.blockdev?</tt>.
|
890
|
-
def blockdev?() FileTest.blockdev?(@path) end
|
891
|
-
|
892
|
-
# See <tt>FileTest.chardev?</tt>.
|
893
|
-
def chardev?() FileTest.chardev?(@path) end
|
894
|
-
|
895
|
-
# See <tt>FileTest.executable?</tt>.
|
896
|
-
def executable?() FileTest.executable?(@path) end
|
897
|
-
|
898
|
-
# See <tt>FileTest.executable_real?</tt>.
|
899
|
-
def executable_real?() FileTest.executable_real?(@path) end
|
900
|
-
|
901
|
-
# See <tt>FileTest.exist?</tt>.
|
902
|
-
def exist?() FileTest.exist?(@path) end
|
903
|
-
|
904
|
-
# See <tt>FileTest.grpowned?</tt>.
|
905
|
-
def grpowned?() FileTest.grpowned?(@path) end
|
906
|
-
|
907
|
-
# See <tt>FileTest.directory?</tt>.
|
908
|
-
def directory?() FileTest.directory?(@path) end
|
909
|
-
|
910
|
-
# See <tt>FileTest.file?</tt>.
|
911
|
-
def file?() FileTest.file?(@path) end
|
912
|
-
|
913
|
-
# See <tt>FileTest.pipe?</tt>.
|
914
|
-
def pipe?() FileTest.pipe?(@path) end
|
915
|
-
|
916
|
-
# See <tt>FileTest.socket?</tt>.
|
917
|
-
def socket?() FileTest.socket?(@path) end
|
918
|
-
|
919
|
-
# See <tt>FileTest.owned?</tt>.
|
920
|
-
def owned?() FileTest.owned?(@path) end
|
921
|
-
|
922
|
-
# See <tt>FileTest.readable?</tt>.
|
923
|
-
def readable?() FileTest.readable?(@path) end
|
924
|
-
|
925
|
-
# See <tt>FileTest.world_readable?</tt>.
|
926
|
-
def world_readable?() FileTest.world_readable?(@path) end
|
927
|
-
|
928
|
-
# See <tt>FileTest.readable_real?</tt>.
|
929
|
-
def readable_real?() FileTest.readable_real?(@path) end
|
930
|
-
|
931
|
-
# See <tt>FileTest.setuid?</tt>.
|
932
|
-
def setuid?() FileTest.setuid?(@path) end
|
933
|
-
|
934
|
-
# See <tt>FileTest.setgid?</tt>.
|
935
|
-
def setgid?() FileTest.setgid?(@path) end
|
936
|
-
|
937
|
-
# See <tt>FileTest.size</tt>.
|
938
|
-
def size() FileTest.size(@path) end
|
939
|
-
|
940
|
-
# See <tt>FileTest.size?</tt>.
|
941
|
-
def size?() FileTest.size?(@path) end
|
942
|
-
|
943
|
-
# See <tt>FileTest.sticky?</tt>.
|
944
|
-
def sticky?() FileTest.sticky?(@path) end
|
945
|
-
|
946
|
-
# See <tt>FileTest.symlink?</tt>.
|
947
|
-
def symlink?() FileTest.symlink?(@path) end
|
948
|
-
|
949
|
-
# See <tt>FileTest.writable?</tt>.
|
950
|
-
def writable?() FileTest.writable?(@path) end
|
951
|
-
|
952
|
-
# See <tt>FileTest.world_writable?</tt>.
|
953
|
-
def world_writable?() FileTest.world_writable?(@path) end
|
954
|
-
|
955
|
-
# See <tt>FileTest.writable_real?</tt>.
|
956
|
-
def writable_real?() FileTest.writable_real?(@path) end
|
957
|
-
|
958
|
-
# See <tt>FileTest.zero?</tt>.
|
959
|
-
def zero?() FileTest.zero?(@path) end
|
960
|
-
end
|
961
|
-
|
962
|
-
|
963
|
-
class Pathname # * Dir *
|
964
|
-
# See <tt>Dir.glob</tt>. Returns or yields Pathname objects.
|
965
|
-
def Pathname.glob(*args) # :yield: p
|
966
|
-
if block_given?
|
967
|
-
Dir.glob(*args) {|f| yield self.new(f) }
|
968
|
-
else
|
969
|
-
Dir.glob(*args).map {|f| self.new(f) }
|
970
|
-
end
|
971
|
-
end
|
972
|
-
|
973
|
-
# See <tt>Dir.getwd</tt>. Returns the current working directory as a Pathname.
|
974
|
-
def Pathname.getwd() self.new(Dir.getwd) end
|
975
|
-
class << self; alias pwd getwd end
|
976
|
-
|
977
|
-
# Pathname#chdir is *obsoleted* at 1.8.1.
|
978
|
-
def chdir(&block)
|
979
|
-
warn "Pathname#chdir is obsoleted. Use Dir.chdir."
|
980
|
-
Dir.chdir(@path, &block)
|
981
|
-
end
|
982
|
-
|
983
|
-
# Pathname#chroot is *obsoleted* at 1.8.1.
|
984
|
-
def chroot
|
985
|
-
warn "Pathname#chroot is obsoleted. Use Dir.chroot."
|
986
|
-
Dir.chroot(@path)
|
987
|
-
end
|
988
|
-
|
989
|
-
# Return the entries (files and subdirectories) in the directory, each as a
|
990
|
-
# Pathname object.
|
991
|
-
def entries() Dir.entries(@path).map {|f| self.class.new(f) } end
|
992
|
-
|
993
|
-
# Iterates over the entries (files and subdirectories) in the directory. It
|
994
|
-
# yields a Pathname object for each entry.
|
995
|
-
#
|
996
|
-
# This method has existed since 1.8.1.
|
997
|
-
def each_entry(&block) # :yield: p
|
998
|
-
Dir.foreach(@path) {|f| yield self.class.new(f) }
|
999
|
-
end
|
1000
|
-
|
1001
|
-
# Pathname#dir_foreach is *obsoleted* at 1.8.1.
|
1002
|
-
def dir_foreach(*args, &block)
|
1003
|
-
warn "Pathname#dir_foreach is obsoleted. Use Pathname#each_entry."
|
1004
|
-
each_entry(*args, &block)
|
1005
|
-
end
|
1006
|
-
|
1007
|
-
# See <tt>Dir.mkdir</tt>. Create the referenced directory.
|
1008
|
-
def mkdir(*args) Dir.mkdir(@path, *args) end
|
1009
|
-
|
1010
|
-
# See <tt>Dir.rmdir</tt>. Remove the referenced directory.
|
1011
|
-
def rmdir() Dir.rmdir(@path) end
|
1012
|
-
|
1013
|
-
# See <tt>Dir.open</tt>.
|
1014
|
-
def opendir(&block) # :yield: dir
|
1015
|
-
Dir.open(@path, &block)
|
1016
|
-
end
|
1017
|
-
end
|
1018
|
-
|
1019
|
-
|
1020
|
-
class Pathname # * Find *
|
1021
|
-
#
|
1022
|
-
# Pathname#find is an iterator to traverse a directory tree in a depth first
|
1023
|
-
# manner. It yields a Pathname for each file under "this" directory.
|
1024
|
-
#
|
1025
|
-
# Since it is implemented by <tt>find.rb</tt>, <tt>Find.prune</tt> can be used
|
1026
|
-
# to control the traverse.
|
1027
|
-
#
|
1028
|
-
# If +self+ is <tt>.</tt>, yielded pathnames begin with a filename in the
|
1029
|
-
# current directory, not <tt>./</tt>.
|
1030
|
-
#
|
1031
|
-
def find(&block) # :yield: p
|
1032
|
-
require 'find'
|
1033
|
-
if @path == '.'
|
1034
|
-
Find.find(@path) {|f| yield self.class.new(f.sub(%r{\A\./}, '')) }
|
1035
|
-
else
|
1036
|
-
Find.find(@path) {|f| yield self.class.new(f) }
|
1037
|
-
end
|
1038
|
-
end
|
1039
|
-
end
|
1040
|
-
|
1041
|
-
|
1042
|
-
class Pathname # * FileUtils *
|
1043
|
-
# See <tt>FileUtils.mkpath</tt>. Creates a full path, including any
|
1044
|
-
# intermediate directories that don't yet exist.
|
1045
|
-
def mkpath
|
1046
|
-
require 'fileutils'
|
1047
|
-
FileUtils.mkpath(@path)
|
1048
|
-
nil
|
1049
|
-
end
|
1050
|
-
|
1051
|
-
# See <tt>FileUtils.rm_r</tt>. Deletes a directory and all beneath it.
|
1052
|
-
def rmtree
|
1053
|
-
# The name "rmtree" is borrowed from File::Path of Perl.
|
1054
|
-
# File::Path provides "mkpath" and "rmtree".
|
1055
|
-
require 'fileutils'
|
1056
|
-
FileUtils.rm_r(@path)
|
1057
|
-
nil
|
1058
|
-
end
|
1059
|
-
end
|
1060
|
-
|
1061
|
-
|
1062
|
-
class Pathname # * mixed *
|
1063
|
-
# Removes a file or directory, using <tt>File.unlink</tt> or
|
1064
|
-
# <tt>Dir.unlink</tt> as necessary.
|
1065
|
-
def unlink()
|
1066
|
-
begin
|
1067
|
-
Dir.unlink @path
|
1068
|
-
rescue Errno::ENOTDIR
|
1069
|
-
File.unlink @path
|
1070
|
-
end
|
1071
|
-
end
|
1072
|
-
alias delete unlink
|
1073
|
-
|
1074
|
-
# This method is *obsoleted* at 1.8.1. Use #each_line or #each_entry.
|
1075
|
-
def foreach(*args, &block)
|
1076
|
-
warn "Pathname#foreach is obsoleted. Use each_line or each_entry."
|
1077
|
-
if FileTest.directory? @path
|
1078
|
-
# For polymorphism between Dir.foreach and IO.foreach,
|
1079
|
-
# Pathname#foreach doesn't yield Pathname object.
|
1080
|
-
Dir.foreach(@path, *args, &block)
|
1081
|
-
else
|
1082
|
-
IO.foreach(@path, *args, &block)
|
1083
|
-
end
|
1084
|
-
end
|
1085
|
-
end
|
1086
|
-
|
1087
|
-
module Kernel
|
1088
|
-
# create a pathname object.
|
1089
|
-
#
|
1090
|
-
# This method is available since 1.8.5.
|
1091
|
-
def Pathname(path) # :doc:
|
1092
|
-
Pathname.new(path)
|
1093
|
-
end
|
1094
|
-
private :Pathname
|
1095
|
-
end
|