path 1.3.3 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE +1 -1
- data/README.md +35 -37
- data/lib/path.rb +2 -6
- data/lib/path/dir.rb +23 -3
- data/lib/path/file.rb +6 -5
- data/lib/path/find.rb +7 -5
- data/lib/path/identity.rb +7 -10
- data/lib/path/implementation.rb +18 -37
- data/lib/path/load.rb +1 -1
- data/lib/path/parts.rb +27 -15
- data/lib/path/predicates.rb +3 -3
- data/lib/path/version.rb +1 -1
- data/path.gemspec +1 -2
- metadata +11 -24
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dc79568913620a232363ac1c8337e5b163a1a910
|
4
|
+
data.tar.gz: 3b1e928062bba5999f0ffd1afd6ac8895b7838a0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 81762a43a917e1b34e483753bdb72bfe5256a4eb777c07f32a5ae108b166ef67da09bef20af735b4c3e3154bdb606fffd7cc5134c99e9e474d4bb1d5ed99927e
|
7
|
+
data.tar.gz: 8456c2c9eda72afbe858e5a22cf6648297acd75a3101d5b5abc7a4d4a117dcae2e86b807f0ec585367295a2b2354f4ce3272917ef6e0a7c16d3f9ce7d7530b0f
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
# Path - a Path manipulation library
|
2
2
|
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/path.png)](https://rubygems.org/gems/path)
|
4
|
+
[![Build Status](https://travis-ci.org/eregon/path.svg?branch=master)](https://travis-ci.org/eregon/path)
|
5
|
+
[![Build Status](https://ci.appveyor.com/api/projects/status/jg6fx1692mw8mu58/branch/master?svg=true)](https://ci.appveyor.com/project/eregon/path/branch/master)
|
6
|
+
|
3
7
|
[Path](http://rubydoc.info/github/eregon/path/master/Path) is a library to manage paths.
|
4
8
|
It is similar to Pathname, but has some extra goodness.
|
5
9
|
The method names are intended to be short and explicit, and avoid too much duplication like having 'name' or 'path' in the method name.
|
@@ -7,7 +11,13 @@ The method names are intended to be short and explicit, and avoid too much dupli
|
|
7
11
|
I believe the object-oriented approach to manipulate paths is very elegant and useful.
|
8
12
|
Paths are naturally the subject of their methods and even if they are simple Strings behind, they carry way much more information and deserve a first-class status.
|
9
13
|
|
10
|
-
|
14
|
+
With `Path`, there is no need to remember in which class the functionality is implemented, everything is in one place (if not, please open an issue!).
|
15
|
+
|
16
|
+
## Version 2
|
17
|
+
|
18
|
+
This is the second version of Path, which tries to respect even more
|
19
|
+
the standard library names and the principle of least surprise.
|
20
|
+
For the first version, see the branch [1.3.x](https://github.com/eregon/path/tree/1.3.x).
|
11
21
|
|
12
22
|
## Installation
|
13
23
|
|
@@ -31,7 +41,7 @@ Most methods of `FileUtils` should be there too.
|
|
31
41
|
``` ruby
|
32
42
|
Path.new('/usr/bin')
|
33
43
|
Path['/usr/bin']
|
34
|
-
Path('/usr/bin')
|
44
|
+
Path('/usr/bin')
|
35
45
|
|
36
46
|
Path.new('~myuser/path') # expanded if it begins with ~
|
37
47
|
|
@@ -50,7 +60,7 @@ Path.home or Path.~ # == Path(File.expand_path('~'))
|
|
50
60
|
Path.~(user) # == Path(File.expand_path("~#{user}"))
|
51
61
|
```
|
52
62
|
|
53
|
-
### temporary
|
63
|
+
### temporary paths
|
54
64
|
|
55
65
|
``` ruby
|
56
66
|
Path.tmpfile
|
@@ -62,37 +72,25 @@ Path.tmpdir
|
|
62
72
|
* expand => expand\_path
|
63
73
|
* relative\_to => relative\_path\_from
|
64
74
|
|
65
|
-
### parts
|
66
|
-
|
67
|
-
Path can split a path in two ways:
|
68
|
-
|
69
|
-
The first way is the one done by File methods (dirname, basename, extname).
|
70
|
-
|
71
|
-
The second is Path's own way in which the base is given without the extension and the extension is given without the leading dot.
|
72
|
-
The rationale behind this is to have a true three-components path, splitting on the / and the . (See [this issue](https://github.com/eregon/path/pull/8#issuecomment-3499030) for details)
|
73
|
-
|
74
|
-
dirname basename
|
75
|
-
____________ ______
|
76
|
-
/ \ / \
|
77
|
-
/some/path/dir/file.ext
|
78
|
-
\____________/ \__/ \_/
|
79
|
-
dir base ext
|
75
|
+
### parts and decomposition
|
80
76
|
|
81
|
-
|
82
|
-
path = dirname / basename(extname) extname
|
83
|
-
path = dir / base [. ext]
|
77
|
+
A path can be split in two or three parts:
|
84
78
|
|
85
|
-
|
86
|
-
|
87
|
-
|
79
|
+
dir base
|
80
|
+
_______ ______
|
81
|
+
/ \ / \
|
82
|
+
/some/dir/file.ext
|
83
|
+
\_______/ \__/\__/
|
84
|
+
dir stem ext
|
88
85
|
|
89
|
-
|
86
|
+
path = dir "/" base = dir "/" stem ext
|
90
87
|
|
91
|
-
|
92
|
-
* base: basename(extname), the basename without the extension: "file"
|
93
|
-
* ext: extname without the leading dot: "ext"
|
88
|
+
All of these are methods of Path:
|
94
89
|
|
95
|
-
|
90
|
+
* dir: "/some/dir"
|
91
|
+
* base: "file.ext"
|
92
|
+
* ext: ".ext"
|
93
|
+
* stem: "file"
|
96
94
|
|
97
95
|
### join
|
98
96
|
|
@@ -103,18 +101,18 @@ The rationale behind this is to have a true three-components path, splitting on
|
|
103
101
|
Path('/usr')/'bin'
|
104
102
|
```
|
105
103
|
|
106
|
-
### extensions
|
104
|
+
### file extensions
|
107
105
|
|
108
106
|
* add\_ext / add\_extension
|
109
107
|
* rm\_ext / without\_extension
|
110
108
|
* sub\_ext(new\_ext) / replace\_extension(new\_ext)
|
111
109
|
|
112
|
-
###
|
110
|
+
### globbing
|
113
111
|
|
114
112
|
* children: files under self, without . and ..
|
115
113
|
* glob: relative glob to self, yield absolute paths
|
116
114
|
|
117
|
-
### structure
|
115
|
+
### navigating the structure
|
118
116
|
|
119
117
|
* parent: parent directory (don't use #dirname more than once, use #parent instead)
|
120
118
|
* ascend, ancestors: self and all the parent directories
|
@@ -122,7 +120,7 @@ Path('/usr')/'bin'
|
|
122
120
|
* backfind: ascends the parents until it finds the given path
|
123
121
|
|
124
122
|
``` ruby
|
125
|
-
# Path.backfind is Path.
|
123
|
+
# Path.backfind is Path.dir.backfind
|
126
124
|
Path.backfind('lib') # => Path's lib folder
|
127
125
|
|
128
126
|
# It accepts XPath-like context
|
@@ -135,7 +133,7 @@ Path.backfind('.[.git]') # => the root of this repository
|
|
135
133
|
* write(contents)
|
136
134
|
* append(contents)
|
137
135
|
|
138
|
-
### management
|
136
|
+
### directory management
|
139
137
|
|
140
138
|
* mkdir
|
141
139
|
* mkdir\_p
|
@@ -161,12 +159,12 @@ earth.relocate(from, to, '.png') { |rel| "#{rel}-200" }
|
|
161
159
|
One aim of Path is to help the user make the transition coming from
|
162
160
|
String (not using a path library), Pathname, or another library.
|
163
161
|
|
164
|
-
To this
|
162
|
+
To this intent, [`Path.configure`](http://rubydoc.info/github/eregon/path/master/Path#configure-class_method) allows to configure the behavior of `Path#+`.
|
165
163
|
|
166
|
-
Coming from String, one should use `Path
|
164
|
+
Coming from String, one should use `Path.configure(:+ => :string)`, and run ruby with the verbose option (`-w`),
|
167
165
|
which will show where `+` is used as String concatenation.
|
168
166
|
|
169
|
-
Coming from a path library using `+` as #join, one should just use the default (`Path
|
167
|
+
Coming from a path library using `+` as #join, one should just use the default (`Path.configure(:+ => :warning)`),
|
170
168
|
which will show where `+` is used.
|
171
169
|
|
172
170
|
## Status
|
data/lib/path.rb
CHANGED
@@ -14,7 +14,6 @@ class Path
|
|
14
14
|
# v This : is there to define a group without capturing
|
15
15
|
new(from.first.rpartition(/:\d+(?:$|:in )/).first).expand
|
16
16
|
end
|
17
|
-
alias :here :file
|
18
17
|
|
19
18
|
# {Path} to the directory of this file: +Path(__FILE__).dir+.
|
20
19
|
def dir(from = nil)
|
@@ -146,9 +145,9 @@ class Path
|
|
146
145
|
def relocate(from, to, new_ext = ext, &updater)
|
147
146
|
updater ||= lambda { |path| path }
|
148
147
|
renamer = lambda { |rel|
|
149
|
-
Path(updater.call(rel.rm_ext)).add_ext(new_ext)
|
148
|
+
Path.new(updater.call(rel.rm_ext)).add_ext(new_ext)
|
150
149
|
}
|
151
|
-
to / renamer.call(self % from)
|
150
|
+
Path.new(to) / renamer.call(self % from)
|
152
151
|
end
|
153
152
|
|
154
153
|
# Setup
|
@@ -166,6 +165,3 @@ class Path
|
|
166
165
|
eval path.read
|
167
166
|
end
|
168
167
|
end
|
169
|
-
|
170
|
-
# to meet everyone's expectations and for compatibility with old gem name
|
171
|
-
EPath = Path
|
data/lib/path/dir.rb
CHANGED
@@ -2,6 +2,12 @@ class Path
|
|
2
2
|
class << self
|
3
3
|
# @!group Directory
|
4
4
|
|
5
|
+
# Escape the path to be suitable for globbing
|
6
|
+
# (so it contains no globbing special characters)
|
7
|
+
def glob_escape(path)
|
8
|
+
path.gsub(/\[|\]|\*|\?|\{|\}/, '\\\\' + '\0')
|
9
|
+
end
|
10
|
+
|
5
11
|
# Returns or yields Path objects. See +Dir.glob+.
|
6
12
|
# @yieldparam [Path] path
|
7
13
|
def glob(pattern, flags = 0)
|
@@ -56,13 +62,16 @@ class Path
|
|
56
62
|
Dir.open(@path, &block)
|
57
63
|
end
|
58
64
|
|
59
|
-
# Returns or yields Path objects.
|
65
|
+
# Returns or yields Path objects.
|
66
|
+
# Prepends the (escaped for globbing) +path+ to the pattern.
|
67
|
+
# See +Dir.glob+.
|
60
68
|
# @yieldparam [Path] path
|
61
69
|
def glob(pattern, flags = 0)
|
70
|
+
pattern = "#{Path.glob_escape(@path)}/#{pattern}"
|
62
71
|
if block_given?
|
63
|
-
Dir.glob(
|
72
|
+
Dir.glob(pattern, flags) { |f| yield Path.new(f) }
|
64
73
|
else
|
65
|
-
Dir.glob(
|
74
|
+
Dir.glob(pattern, flags).map(&Path)
|
66
75
|
end
|
67
76
|
end
|
68
77
|
|
@@ -145,4 +154,15 @@ class Path
|
|
145
154
|
def each_child(with_directory=true, &b)
|
146
155
|
children(with_directory).each(&b)
|
147
156
|
end
|
157
|
+
|
158
|
+
# Equivalent of +parent.children - [self]+.
|
159
|
+
# Returns the siblings, the files in the same directory as the current +path+.
|
160
|
+
# Returns only the root if +path+ is the root.
|
161
|
+
def siblings(with_directory = true)
|
162
|
+
if root?
|
163
|
+
[self]
|
164
|
+
else
|
165
|
+
parent.children(with_directory) - [(with_directory ? self : basename)]
|
166
|
+
end
|
167
|
+
end
|
148
168
|
end
|
data/lib/path/file.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
class Path
|
2
2
|
# @!group File
|
3
3
|
|
4
|
-
# Returns last access time. See +File.atime+.
|
4
|
+
# Returns the last access time. See +File.atime+.
|
5
5
|
def atime
|
6
6
|
File.atime(@path)
|
7
7
|
end
|
8
8
|
|
9
|
-
# Returns last change time (of the directory entry, not the file itself).
|
9
|
+
# Returns the last change time (of the directory entry, not the file itself).
|
10
10
|
# See +File.ctime+.
|
11
11
|
def ctime
|
12
12
|
File.ctime(@path)
|
@@ -27,7 +27,7 @@ class Path
|
|
27
27
|
File.lchmod(mode, @path)
|
28
28
|
end
|
29
29
|
|
30
|
-
# Changes the owner and group of
|
30
|
+
# Changes the owner and group of +path+. See +File.chown+.
|
31
31
|
def chown(owner, group)
|
32
32
|
File.chown(owner, group, @path)
|
33
33
|
end
|
@@ -60,7 +60,7 @@ class Path
|
|
60
60
|
# Renames the file and returns the new Path. See +File.rename+.
|
61
61
|
def rename(to)
|
62
62
|
File.rename(@path, to)
|
63
|
-
Path(to)
|
63
|
+
Path.new(to)
|
64
64
|
end
|
65
65
|
|
66
66
|
# Returns the stat of +path+ as a +File::Stat+ object. See +File.stat+.
|
@@ -114,13 +114,14 @@ class Path
|
|
114
114
|
end
|
115
115
|
alias :expand_path :expand
|
116
116
|
|
117
|
-
# Returns the real (absolute) path
|
117
|
+
# Returns the real (absolute) path for +self+ in the actual
|
118
118
|
# filesystem not containing symlinks or useless dots.
|
119
119
|
#
|
120
120
|
# All components of the path must exist when this method is called.
|
121
121
|
def realpath(basedir=nil)
|
122
122
|
Path.new(real_path_internal(true, basedir))
|
123
123
|
end
|
124
|
+
alias :real :realpath
|
124
125
|
|
125
126
|
# Returns the real (absolute) path of +self+ in the actual filesystem.
|
126
127
|
# The real path doesn't contain symlinks or useless dots.
|
data/lib/path/find.rb
CHANGED
@@ -1,15 +1,17 @@
|
|
1
1
|
class Path
|
2
|
-
#
|
3
|
-
# manner
|
2
|
+
# Iterates over the directory tree in a depth first
|
3
|
+
# manner, yielding a Path for each file under "this" directory.
|
4
4
|
#
|
5
|
-
# Returns an
|
5
|
+
# Returns an Enumerator if no block is given.
|
6
6
|
#
|
7
|
-
# Since it is implemented by
|
8
|
-
# to control the traversal.
|
7
|
+
# Since it is implemented by the standard library module Find, +Find.prune+
|
8
|
+
# can be used to control the traversal.
|
9
9
|
#
|
10
10
|
# If +self+ is +.+, yielded paths begin with a filename in the
|
11
11
|
# current directory, not +./+.
|
12
12
|
#
|
13
|
+
# See +Find.find+.
|
14
|
+
#
|
13
15
|
# @yieldparam [Path] path
|
14
16
|
def find
|
15
17
|
return to_enum(__method__) unless block_given?
|
data/lib/path/identity.rb
CHANGED
@@ -80,11 +80,9 @@ class Path
|
|
80
80
|
# Returns the +path+ as a String.
|
81
81
|
# {#path} is implemented for better readability (+file.path+ instead of +file.to_s+) and as an accessor.
|
82
82
|
# {#to_path} is implemented so Path objects are usable with +open+, etc.
|
83
|
-
# {#to_str} is implemented so Path objects are usable with +open+, etc with Ruby 1.8 (it is not defined in Ruby 1.9).
|
84
83
|
attr_reader :path
|
85
84
|
alias :to_s :path
|
86
85
|
alias :to_path :path
|
87
|
-
alias :to_str :path if RUBY_VERSION < '1.9'
|
88
86
|
|
89
87
|
# Compare this path with +other+. The comparison is string-based.
|
90
88
|
# Be aware that two different paths (+foo.txt+ and +./foo.txt+)
|
@@ -94,7 +92,7 @@ class Path
|
|
94
92
|
end
|
95
93
|
alias :eql? :==
|
96
94
|
|
97
|
-
# Provides for
|
95
|
+
# Provides a case-sensitive comparison operator for paths.
|
98
96
|
def <=>(other)
|
99
97
|
return nil unless Path === other
|
100
98
|
@path.tr('/', "\0") <=> other.path.tr('/', "\0")
|
@@ -151,12 +149,11 @@ class Path
|
|
151
149
|
end
|
152
150
|
end
|
153
151
|
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
end
|
160
|
-
private :Path
|
152
|
+
# @private The extension to define the global method Path()
|
153
|
+
module Kernel
|
154
|
+
# A shorthand method to create a {Path}. Same as {Path.new}.
|
155
|
+
def Path(*args)
|
156
|
+
Path.new(*args)
|
161
157
|
end
|
158
|
+
private :Path
|
162
159
|
end
|
data/lib/path/implementation.rb
CHANGED
@@ -20,13 +20,13 @@ class Path
|
|
20
20
|
end
|
21
21
|
alias :cleanpath :clean
|
22
22
|
|
23
|
-
#
|
23
|
+
# Returns the parent directory.
|
24
24
|
# This can be chained.
|
25
25
|
def parent
|
26
26
|
self / '..'
|
27
27
|
end
|
28
28
|
|
29
|
-
# Path#/ appends a path fragment to
|
29
|
+
# Path#/ appends a path fragment to +self+ to produce a new Path.
|
30
30
|
#
|
31
31
|
# p = Path.new("/usr") # => #<Path /usr>
|
32
32
|
# p / "bin/ruby" # => #<Path /usr/bin/ruby>
|
@@ -39,18 +39,19 @@ class Path
|
|
39
39
|
|
40
40
|
# Configures the behavior of {Path#+}. The default is +:warning+.
|
41
41
|
#
|
42
|
-
# Path
|
43
|
-
# Path
|
44
|
-
# Path
|
45
|
-
# Path
|
42
|
+
# Path.configure(:+ => :defined) # aliased to Path#/
|
43
|
+
# Path.configure(:+ => :warning) # calls Path#/ but warns
|
44
|
+
# Path.configure(:+ => :error) # not defined
|
45
|
+
# Path.configure(:+ => :string) # like String#+. Warns if $VERBOSE (-w)
|
46
46
|
#
|
47
|
-
# @
|
48
|
-
def Path
|
47
|
+
# @option config [:defined, :warning, :error, :string] :+ the configuration value
|
48
|
+
def Path.configure(config)
|
49
|
+
config = config[:+]
|
49
50
|
unless [:defined, :warning, :error, :string].include? config
|
50
51
|
raise ArgumentError, "Invalid configuration: #{config.inspect}"
|
51
52
|
end
|
52
53
|
if @plus_configured
|
53
|
-
raise "Path
|
54
|
+
raise "Path.configure(:+ => ...) has already been called: #{@plus_configured}"
|
54
55
|
end
|
55
56
|
remove_method :+ if method_defined? :+
|
56
57
|
case config
|
@@ -68,21 +69,18 @@ class Path
|
|
68
69
|
def +(other)
|
69
70
|
warn 'Warning: use of deprecated Path#+ as String#+: ' <<
|
70
71
|
"#{inspect} + #{other.inspect}\n#{caller.first}" if $VERBOSE
|
71
|
-
Path(to_s + other.to_s)
|
72
|
+
Path.new(to_s + other.to_s)
|
72
73
|
end
|
73
74
|
end
|
74
75
|
@plus_configured = caller.first
|
75
76
|
end
|
76
|
-
class << self
|
77
|
-
alias :configure_plus :+
|
78
|
-
end
|
79
77
|
|
80
78
|
@plus_configured = nil # Initialization
|
81
|
-
Path.
|
79
|
+
Path.configure(:+ => :warning)
|
82
80
|
@plus_configured = nil # Let the user overrides this default configuration
|
83
81
|
|
84
82
|
# @!method +(other)
|
85
|
-
# The behavior depends on the configuration with Path.
|
83
|
+
# The behavior depends on the configuration with {Path.configure}.
|
86
84
|
# It might behave as {Path#/}, String#+, give warnings,
|
87
85
|
# or not be defined at all.
|
88
86
|
|
@@ -100,10 +98,10 @@ class Path
|
|
100
98
|
self / result
|
101
99
|
end
|
102
100
|
|
103
|
-
# #relative_path_from returns a relative path from the
|
104
|
-
# receiver. They must be both relative or both absolute.
|
101
|
+
# #relative_path_from returns a relative path from the given +base_directory+
|
102
|
+
# to the receiver. They must be both relative or both absolute.
|
105
103
|
#
|
106
|
-
#
|
104
|
+
# It doesn't access the filesystem and assumes no symlinks.
|
107
105
|
#
|
108
106
|
# @raise [ArgumentError] if it cannot find a relative path:
|
109
107
|
# Either the base is relative and contains '..' (in that case you can expand
|
@@ -130,24 +128,6 @@ class Path
|
|
130
128
|
alias :relative_to :relative_path_from
|
131
129
|
alias :% :relative_path_from
|
132
130
|
|
133
|
-
# @private
|
134
|
-
module Helpers
|
135
|
-
private
|
136
|
-
|
137
|
-
# remove the leading . of +ext+ if present.
|
138
|
-
def pure_ext(ext)
|
139
|
-
ext = ext.to_s and ext.start_with?('.') ? ext[1..-1] : ext
|
140
|
-
end
|
141
|
-
|
142
|
-
# add a leading . to +ext+ if missing. Returns '' if +ext+ is empty.
|
143
|
-
def dotted_ext(ext)
|
144
|
-
ext = ext.to_s and (ext.empty? or ext.start_with?('.')) ? ext : ".#{ext}"
|
145
|
-
end
|
146
|
-
end
|
147
|
-
|
148
|
-
include Helpers
|
149
|
-
extend Helpers
|
150
|
-
|
151
131
|
private
|
152
132
|
|
153
133
|
def init
|
@@ -161,6 +141,7 @@ class Path
|
|
161
141
|
def validate(path)
|
162
142
|
raise ArgumentError, "path contains a null byte: #{path.inspect}" if path.include? "\0"
|
163
143
|
path.gsub!(File::ALT_SEPARATOR, '/') if File::ALT_SEPARATOR
|
144
|
+
path = del_trailing_separator(path)
|
164
145
|
path = File.expand_path(path) if path.start_with? '~'
|
165
146
|
path
|
166
147
|
end
|
@@ -230,7 +211,7 @@ class Path
|
|
230
211
|
names.shift while names.first == '..' if is_root?(prefix)
|
231
212
|
end
|
232
213
|
|
233
|
-
# Clean the path simply by resolving and removing excess
|
214
|
+
# Clean the path simply by resolving and removing excess +.+ and +..+ entries.
|
234
215
|
# Nothing more, nothing less.
|
235
216
|
def cleanpath_aggressive
|
236
217
|
pre = @path
|
data/lib/path/load.rb
CHANGED
data/lib/path/parts.rb
CHANGED
@@ -1,14 +1,25 @@
|
|
1
1
|
class Path
|
2
2
|
# @!group Path parts
|
3
3
|
|
4
|
+
# remove the leading . of +ext+ if present.
|
5
|
+
def self.pure_ext(ext)
|
6
|
+
ext = ext.to_s and ext.start_with?('.') ? ext[1..-1] : ext
|
7
|
+
end
|
8
|
+
|
9
|
+
# add a leading . to +ext+ if missing. Returns '' if +ext+ is empty.
|
10
|
+
def self.dotted_ext(ext)
|
11
|
+
ext = ext.to_s and (ext.empty? or ext.start_with?('.')) ? ext : ".#{ext}"
|
12
|
+
end
|
13
|
+
|
4
14
|
# Returns the last component of the path. See +File.basename+.
|
5
|
-
def
|
15
|
+
def base(*args)
|
6
16
|
Path.new(File.basename(@path, *args))
|
7
17
|
end
|
18
|
+
alias :basename :base
|
8
19
|
|
9
|
-
#
|
10
|
-
def
|
11
|
-
|
20
|
+
# Returns the last component of the path, without the extension: base(ext)
|
21
|
+
def stem
|
22
|
+
base(ext)
|
12
23
|
end
|
13
24
|
|
14
25
|
# Returns all but the last component of the path.
|
@@ -17,20 +28,20 @@ class Path
|
|
17
28
|
# Path('.').dir # => #<Path .>
|
18
29
|
# Use #parent instead.
|
19
30
|
# See +File.dirname+.
|
20
|
-
def
|
31
|
+
def dir
|
21
32
|
Path.new(File.dirname(@path))
|
22
33
|
end
|
23
|
-
alias :
|
34
|
+
alias :dirname :dir
|
24
35
|
|
25
36
|
# Returns the extension, with a leading dot. See +File.extname+.
|
26
|
-
def
|
37
|
+
def ext
|
27
38
|
File.extname(@path)
|
28
39
|
end
|
40
|
+
alias :extname :ext
|
29
41
|
|
30
|
-
# {#
|
31
|
-
def
|
32
|
-
|
33
|
-
ext.empty? ? ext : ext[1..-1]
|
42
|
+
# {#ext} without leading dot.
|
43
|
+
def pure_ext
|
44
|
+
Path.pure_ext(extname)
|
34
45
|
end
|
35
46
|
|
36
47
|
# Returns the #dirname and the #basename in an Array. See +File.split+.
|
@@ -45,7 +56,7 @@ class Path
|
|
45
56
|
# Path('file').add_extension('txt') # => #<Path file.txt>
|
46
57
|
def add_extension(ext)
|
47
58
|
return self if ext.to_s.empty?
|
48
|
-
Path.new @path+dotted_ext(ext)
|
59
|
+
Path.new @path + Path.dotted_ext(ext)
|
49
60
|
end
|
50
61
|
alias :add_ext :add_extension
|
51
62
|
|
@@ -65,7 +76,7 @@ class Path
|
|
65
76
|
# Path('main.c++').replace_extension('cc') # => #<Path main.cc>
|
66
77
|
def replace_extension(ext)
|
67
78
|
return without_extension if ext.to_s.empty?
|
68
|
-
Path.new(@path[0..-extname.size-1] << dotted_ext(ext))
|
79
|
+
Path.new(@path[0..-extname.size-1] << Path.dotted_ext(ext))
|
69
80
|
end
|
70
81
|
alias :sub_ext :replace_extension
|
71
82
|
|
@@ -74,6 +85,7 @@ class Path
|
|
74
85
|
# Path.new("/usr/bin/ruby").each_filename { |filename| ... }
|
75
86
|
# # yields "usr", "bin", and "ruby".
|
76
87
|
#
|
88
|
+
# Returns an Enumerator if no block was given.
|
77
89
|
# @yieldparam [String] filename
|
78
90
|
def each_filename
|
79
91
|
return to_enum(__method__) unless block_given?
|
@@ -97,7 +109,7 @@ class Path
|
|
97
109
|
# #<Path path/to/some>
|
98
110
|
# #<Path path/to/some/file.rb>
|
99
111
|
#
|
100
|
-
# It doesn't access
|
112
|
+
# It doesn't access the filesystem.
|
101
113
|
# @yieldparam [Path] path
|
102
114
|
def descend
|
103
115
|
return to_enum(:descend) unless block_given?
|
@@ -120,7 +132,7 @@ class Path
|
|
120
132
|
# #<Path path/to>
|
121
133
|
# #<Path path>
|
122
134
|
#
|
123
|
-
# It doesn't access
|
135
|
+
# It doesn't access the filesystem.
|
124
136
|
# @yieldparam [Path] path
|
125
137
|
def ascend
|
126
138
|
return to_enum(:ascend) unless block_given?
|
data/lib/path/predicates.rb
CHANGED
@@ -11,16 +11,16 @@ class Path
|
|
11
11
|
not absolute?
|
12
12
|
end
|
13
13
|
|
14
|
-
#
|
14
|
+
# Predicate for root directories. Returns +true+ if the
|
15
15
|
# path consists of consecutive slashes.
|
16
16
|
#
|
17
|
-
# It doesn't access
|
17
|
+
# It doesn't access the filesystem. So it may return +false+ for some
|
18
18
|
# paths which points to roots such as +/usr/..+.
|
19
19
|
def root?
|
20
20
|
is_root?(@path)
|
21
21
|
end
|
22
22
|
|
23
|
-
#
|
23
|
+
# Returns +true+ if +self+ points to a mountpoint.
|
24
24
|
def mountpoint?
|
25
25
|
begin
|
26
26
|
stat1 = lstat
|
data/lib/path/version.rb
CHANGED
data/path.gemspec
CHANGED
@@ -8,7 +8,6 @@ Gem::Specification.new do |s|
|
|
8
8
|
s.email = 'eregontp@gmail.com'
|
9
9
|
s.homepage = 'https://github.com/eregon/path'
|
10
10
|
s.files = Dir['lib/**/*.rb'] + %w[README.md LICENSE path.gemspec]
|
11
|
+
s.licenses = ['MIT']
|
11
12
|
s.version = Path::VERSION
|
12
|
-
|
13
|
-
s.add_development_dependency 'rspec'
|
14
13
|
end
|
metadata
CHANGED
@@ -1,35 +1,24 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: path
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- eregon
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
12
|
-
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: rspec
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - '>='
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '0'
|
20
|
-
type: :development
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - '>='
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '0'
|
11
|
+
date: 2016-11-13 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
27
13
|
description: Path is a library to easily manage paths and with a lot of extra goodness.
|
28
14
|
email: eregontp@gmail.com
|
29
15
|
executables: []
|
30
16
|
extensions: []
|
31
17
|
extra_rdoc_files: []
|
32
18
|
files:
|
19
|
+
- LICENSE
|
20
|
+
- README.md
|
21
|
+
- lib/path.rb
|
33
22
|
- lib/path/compatibility.rb
|
34
23
|
- lib/path/dir.rb
|
35
24
|
- lib/path/file.rb
|
@@ -44,12 +33,10 @@ files:
|
|
44
33
|
- lib/path/predicates.rb
|
45
34
|
- lib/path/require_tree.rb
|
46
35
|
- lib/path/version.rb
|
47
|
-
- lib/path.rb
|
48
|
-
- README.md
|
49
|
-
- LICENSE
|
50
36
|
- path.gemspec
|
51
37
|
homepage: https://github.com/eregon/path
|
52
|
-
licenses:
|
38
|
+
licenses:
|
39
|
+
- MIT
|
53
40
|
metadata: {}
|
54
41
|
post_install_message:
|
55
42
|
rdoc_options: []
|
@@ -57,17 +44,17 @@ require_paths:
|
|
57
44
|
- lib
|
58
45
|
required_ruby_version: !ruby/object:Gem::Requirement
|
59
46
|
requirements:
|
60
|
-
- -
|
47
|
+
- - ">="
|
61
48
|
- !ruby/object:Gem::Version
|
62
49
|
version: '0'
|
63
50
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
64
51
|
requirements:
|
65
|
-
- -
|
52
|
+
- - ">="
|
66
53
|
- !ruby/object:Gem::Version
|
67
54
|
version: '0'
|
68
55
|
requirements: []
|
69
56
|
rubyforge_project:
|
70
|
-
rubygems_version: 2.
|
57
|
+
rubygems_version: 2.5.1
|
71
58
|
signing_key:
|
72
59
|
specification_version: 4
|
73
60
|
summary: The Path manipulation library
|