rubypath 0.3.2 → 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.
- checksums.yaml +4 -4
- metadata +5 -55
- data/CHANGELOG.md +0 -24
- data/LICENSE.txt +0 -165
- data/README.md +0 -102
- data/doc/file.README.html +0 -175
- data/lib/rubypath.rb +0 -29
- data/lib/rubypath/backend.rb +0 -92
- data/lib/rubypath/backend/mock.rb +0 -356
- data/lib/rubypath/backend/sys.rb +0 -161
- data/lib/rubypath/comparison.rb +0 -19
- data/lib/rubypath/construction.rb +0 -109
- data/lib/rubypath/dir_operations.rb +0 -160
- data/lib/rubypath/extensions.rb +0 -157
- data/lib/rubypath/file_operations.rb +0 -192
- data/lib/rubypath/file_predicates.rb +0 -32
- data/lib/rubypath/identity.rb +0 -59
- data/lib/rubypath/io_operations.rb +0 -82
- data/lib/rubypath/mock.rb +0 -42
- data/lib/rubypath/path_operations.rb +0 -311
- data/lib/rubypath/path_predicates.rb +0 -61
- data/lib/rubypath/version.rb +0 -11
- data/rubypath.gemspec +0 -22
- data/spec/README_spec.rb +0 -27
- data/spec/rubypath/comparison_spec.rb +0 -77
- data/spec/rubypath/construction_spec.rb +0 -101
- data/spec/rubypath/dir_operations_spec.rb +0 -225
- data/spec/rubypath/extensions_spec.rb +0 -270
- data/spec/rubypath/file_operations_spec.rb +0 -428
- data/spec/rubypath/file_predicates_spec.rb +0 -66
- data/spec/rubypath/identity_spec.rb +0 -21
- data/spec/rubypath/io_operations_spec.rb +0 -128
- data/spec/rubypath/path_operations_spec.rb +0 -483
- data/spec/rubypath/path_predicates_spec.rb +0 -75
- data/spec/spec_helper.rb +0 -42
- data/spec/support/describe_method.rb +0 -18
- data/spec/support/with_backend.rb +0 -37
data/lib/rubypath/extensions.rb
DELETED
@@ -1,157 +0,0 @@
|
|
1
|
-
class Path
|
2
|
-
# @!group File Extensions
|
3
|
-
|
4
|
-
# Return list of all file extensions.
|
5
|
-
#
|
6
|
-
# @example
|
7
|
-
# Path.new('/path/to/template.de.html.erb').extensions
|
8
|
-
# #=> ['de', 'html', 'erb']
|
9
|
-
#
|
10
|
-
# @return [Array<String>] List of file extensions.
|
11
|
-
#
|
12
|
-
def extensions
|
13
|
-
if dotfile?
|
14
|
-
name.split('.')[2..-1]
|
15
|
-
else
|
16
|
-
name.split('.')[1..-1]
|
17
|
-
end
|
18
|
-
end
|
19
|
-
alias_method :exts, :extensions
|
20
|
-
|
21
|
-
# Return last file extension.
|
22
|
-
#
|
23
|
-
# @example
|
24
|
-
# Path.new('/path/to/template.de.html.erb').extension
|
25
|
-
# #=> 'erb'
|
26
|
-
#
|
27
|
-
# @return [String] Last file extensions.
|
28
|
-
#
|
29
|
-
def extension
|
30
|
-
extensions.last
|
31
|
-
end
|
32
|
-
alias_method :ext, :extension
|
33
|
-
|
34
|
-
# Return last file extension include dot character.
|
35
|
-
#
|
36
|
-
# @return [String] Ext name.
|
37
|
-
# @see ::File.extname
|
38
|
-
#
|
39
|
-
def extname
|
40
|
-
::File.extname name
|
41
|
-
end
|
42
|
-
|
43
|
-
# Return the file name without any extensions.
|
44
|
-
#
|
45
|
-
# @example
|
46
|
-
# Path("template.de.html.slim").pure_name
|
47
|
-
# #=> "template"
|
48
|
-
#
|
49
|
-
# @example
|
50
|
-
# Path("~/.gitconfig").pure_name
|
51
|
-
# #=> ".gitconfig"
|
52
|
-
#
|
53
|
-
# @return [String] File name without extensions.
|
54
|
-
#
|
55
|
-
def pure_name
|
56
|
-
if dotfile?
|
57
|
-
name.split('.', 3)[0..1].join('.')
|
58
|
-
else
|
59
|
-
name.split('.', 2)[0]
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
# Replace file extensions with given new ones or by a given
|
64
|
-
# translation map.
|
65
|
-
#
|
66
|
-
# @overload replace_extensions(exts)
|
67
|
-
# Replace all extensions with given new ones. Number of given extensions
|
68
|
-
# does not need to match number of existing extensions.
|
69
|
-
#
|
70
|
-
# @example
|
71
|
-
# Path('file.de.txt').replace_extensions(%w(en html))
|
72
|
-
# #=> <Path "file.en.html">
|
73
|
-
#
|
74
|
-
# @example
|
75
|
-
# Path('file.de.mobile.html.haml').replace_extensions(%w(int txt))
|
76
|
-
# #=> <Path "file.int.txt">
|
77
|
-
#
|
78
|
-
# @param exts [Array<String>] New extensions.
|
79
|
-
#
|
80
|
-
# @overload replace_extensions(ext, [ext, [..]])
|
81
|
-
# Replace all extensions with given new ones. Number of given extensions
|
82
|
-
# does not need to match number of existing extensions.
|
83
|
-
#
|
84
|
-
# @example
|
85
|
-
# Path('file.de.txt').replace_extensions('en', 'html')
|
86
|
-
# #=> <Path "file.en.html">
|
87
|
-
#
|
88
|
-
# @example
|
89
|
-
# Path('file.de.mobile.html.haml').replace_extensions('en', 'html')
|
90
|
-
# #=> <Path "file.en.html">
|
91
|
-
#
|
92
|
-
# @example
|
93
|
-
# Path('file.de.txt').replace_extensions('html')
|
94
|
-
# #=> <Path "file.html">
|
95
|
-
#
|
96
|
-
# @param ext [String] New extensions.
|
97
|
-
#
|
98
|
-
# @overload replace_extensions(map)
|
99
|
-
# Replace all matching extensions.
|
100
|
-
#
|
101
|
-
# @example
|
102
|
-
# Path('file.de.html.haml').replace_extensions('de' => 'en', 'haml' => 'slim')
|
103
|
-
# #=> <Path "file.en.html.slim">
|
104
|
-
#
|
105
|
-
# @param map [Hash<String, String>] Translation map as hash.
|
106
|
-
#
|
107
|
-
# @return [Path] Path to new filename.
|
108
|
-
#
|
109
|
-
def replace_extensions(*args)
|
110
|
-
args.flatten!
|
111
|
-
extensions = self.extensions
|
112
|
-
|
113
|
-
if (replace = (args.last.is_a?(Hash) ? args.pop : nil))
|
114
|
-
if args.empty?
|
115
|
-
extensions.map! do |ext|
|
116
|
-
replace[ext] ? replace[ext].to_s : ext
|
117
|
-
end
|
118
|
-
else
|
119
|
-
raise ArgumentError.new 'Cannot replace extensions with array ' \
|
120
|
-
'and hash at the same time.'
|
121
|
-
end
|
122
|
-
else
|
123
|
-
extensions = args.map(&:to_s)
|
124
|
-
end
|
125
|
-
|
126
|
-
if extensions == self.extensions
|
127
|
-
self
|
128
|
-
else
|
129
|
-
if only_filename?
|
130
|
-
Path "#{pure_name}.#{extensions.join('.')}"
|
131
|
-
else
|
132
|
-
dirname.join "#{pure_name}.#{extensions.join('.')}"
|
133
|
-
end
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
# Replace last extension with one or multiple new extensions.
|
138
|
-
#
|
139
|
-
# @example
|
140
|
-
# Path('file.de.txt').replace_extension('html')
|
141
|
-
# #=> <Path "file.de.html">
|
142
|
-
#
|
143
|
-
# @example
|
144
|
-
# Path('file.de.txt').replace_extension('html', 'erb')
|
145
|
-
# #=> <Path "file.de.html.erb">
|
146
|
-
#
|
147
|
-
# @return [Path] Path to new filename.
|
148
|
-
#
|
149
|
-
def replace_extension(*args)
|
150
|
-
extensions = self.extensions
|
151
|
-
extensions.pop
|
152
|
-
extensions += args.flatten
|
153
|
-
|
154
|
-
replace_extensions extensions
|
155
|
-
end
|
156
|
-
|
157
|
-
end
|
@@ -1,192 +0,0 @@
|
|
1
|
-
class Path
|
2
|
-
# @!group File Operations
|
3
|
-
|
4
|
-
# Return base name without path.
|
5
|
-
#
|
6
|
-
# @return [String] Base name.
|
7
|
-
#
|
8
|
-
def name
|
9
|
-
::File.basename internal_path
|
10
|
-
end
|
11
|
-
alias_method :basename, :name
|
12
|
-
|
13
|
-
# Create new file at pointed location or update modification time if file
|
14
|
-
# exists.
|
15
|
-
#
|
16
|
-
# @example
|
17
|
-
# Path('/path/to/file.txt').touch
|
18
|
-
# #=> <Path:"/path/to/file.txt">
|
19
|
-
#
|
20
|
-
# @example
|
21
|
-
# Path('/path/to').touch('file.txt')
|
22
|
-
# #=> <Path:"/path/to/file.txt">
|
23
|
-
#
|
24
|
-
# @return [Path] Path to touched file.
|
25
|
-
#
|
26
|
-
def touch(*args)
|
27
|
-
with_path(*args) do |path|
|
28
|
-
invoke_backend :touch, path
|
29
|
-
Path path
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
# Removes file at current path.
|
34
|
-
#
|
35
|
-
# Raise an error if file does not exists or is a directory.
|
36
|
-
#
|
37
|
-
# @example
|
38
|
-
# Path('/file.txt').touch.unlink
|
39
|
-
# #=> <Path /file.txt>
|
40
|
-
#
|
41
|
-
# @example
|
42
|
-
# Path('/file.txt').touch
|
43
|
-
# Path('/').unlink('file.txt')
|
44
|
-
# #=> <Path /file.txt>
|
45
|
-
#
|
46
|
-
# @return [Path] Unlinked path.
|
47
|
-
#
|
48
|
-
def unlink(*args)
|
49
|
-
with_path(*args) do |path|
|
50
|
-
invoke_backend :unlink, path
|
51
|
-
Path path
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
# Create a file at pointed location and all missing parent directories.
|
56
|
-
#
|
57
|
-
# Given arguments will be joined with current path before directories and
|
58
|
-
# file is created.
|
59
|
-
#
|
60
|
-
# If file already exists nothing will be done.
|
61
|
-
#
|
62
|
-
# @example
|
63
|
-
# Path('/path/to/file.txt').mkfile
|
64
|
-
# #=> <Path:"/path/to/file.txt">
|
65
|
-
#
|
66
|
-
# @example
|
67
|
-
# Path('/').mkfile('path', 'to', 'file.txt')
|
68
|
-
# #=> <Path:"/path/to/file.txt">
|
69
|
-
#
|
70
|
-
# @return [Path] Path to created or existent file.
|
71
|
-
#
|
72
|
-
def mkfile(*args)
|
73
|
-
with_path(*args) do |path|
|
74
|
-
if !path.exists? && path.parent && !path.parent.exists?
|
75
|
-
path.parent.mkpath
|
76
|
-
end
|
77
|
-
|
78
|
-
if path.exists?
|
79
|
-
raise Errno::ENOENT.new path.to_s unless path.file?
|
80
|
-
else
|
81
|
-
path.touch
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
# Search for a file in current directory or parent directories.
|
87
|
-
#
|
88
|
-
# Given search pattern can either be a regular expression or a shell glob
|
89
|
-
# expression.
|
90
|
-
#
|
91
|
-
# @example
|
92
|
-
# Path.cwd.lookup('project.{yml,yaml}')
|
93
|
-
# #=> <Path:"/path/config.yml">
|
94
|
-
#
|
95
|
-
# @example
|
96
|
-
# Path.cwd.lookup(/config(_\d+).ya?ml/)
|
97
|
-
# #=> <Path:"/path/config_354.yaml">
|
98
|
-
#
|
99
|
-
# @example
|
100
|
-
# Path('~').lookup('*config', ::File::FNM_DOTMATCH)
|
101
|
-
# #=> <Path:"/gome/user/.gitconfig">
|
102
|
-
#
|
103
|
-
# @param pattern [String|RegExp] Expression file name must match.
|
104
|
-
# @param flags [Integer] Additional flags. See {::File.fnmatch}.
|
105
|
-
# Defaults to `File::FNM_EXTGLOB`.
|
106
|
-
# @return [Path] Path to found file or nil.
|
107
|
-
#
|
108
|
-
def lookup(pattern, flags = nil)
|
109
|
-
flags = self.class.default_glob_flags(flags)
|
110
|
-
|
111
|
-
expand.ascend do |path|
|
112
|
-
case pattern
|
113
|
-
when String
|
114
|
-
path.entries.each do |c|
|
115
|
-
return path.join(c) if ::File.fnmatch?(pattern, c.name, flags)
|
116
|
-
end
|
117
|
-
when Regexp
|
118
|
-
path.entries.each do |c|
|
119
|
-
return path.join(c) if pattern =~ c.name
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
nil
|
125
|
-
end
|
126
|
-
|
127
|
-
# Return file modification time.
|
128
|
-
#
|
129
|
-
# @return [Time] Time of last modification.
|
130
|
-
#
|
131
|
-
def mtime
|
132
|
-
invoke_backend :mtime
|
133
|
-
end
|
134
|
-
|
135
|
-
# Set last modification time.
|
136
|
-
#
|
137
|
-
# @param [Time] Time of last modification.
|
138
|
-
#
|
139
|
-
def mtime=(time)
|
140
|
-
invoke_backend :mtime=, internal_path, time
|
141
|
-
end
|
142
|
-
|
143
|
-
# Return file access time.
|
144
|
-
#
|
145
|
-
# @return [Time] Time of last access.
|
146
|
-
#
|
147
|
-
def atime
|
148
|
-
invoke_backend :atime
|
149
|
-
end
|
150
|
-
|
151
|
-
# Set last access time.
|
152
|
-
#
|
153
|
-
# @param [Time] Time of last access.
|
154
|
-
#
|
155
|
-
def atime=(time)
|
156
|
-
invoke_backend :atime=, internal_path, time
|
157
|
-
end
|
158
|
-
|
159
|
-
def mode
|
160
|
-
invoke_backend :mode
|
161
|
-
end
|
162
|
-
|
163
|
-
def chmod(mode)
|
164
|
-
invoke_backend :chmod, internal_path, mode
|
165
|
-
end
|
166
|
-
|
167
|
-
class << self
|
168
|
-
|
169
|
-
# Read or set process umask.
|
170
|
-
#
|
171
|
-
# @overload umask
|
172
|
-
# Read process umask.
|
173
|
-
#
|
174
|
-
# @return [Integer] Process umask.
|
175
|
-
#
|
176
|
-
# @overload umask(mask)
|
177
|
-
# Set process umask.
|
178
|
-
#
|
179
|
-
# @param mask [Integer] New process umask.
|
180
|
-
#
|
181
|
-
# @see File.umask
|
182
|
-
#
|
183
|
-
def umask(mask = nil)
|
184
|
-
if mask
|
185
|
-
invoke_backend :set_umask, mask
|
186
|
-
else
|
187
|
-
invoke_backend :get_umask
|
188
|
-
end
|
189
|
-
end
|
190
|
-
alias_method :umask=, :umask
|
191
|
-
end
|
192
|
-
end
|
@@ -1,32 +0,0 @@
|
|
1
|
-
class Path
|
2
|
-
# @!group File Predicates
|
3
|
-
|
4
|
-
# Check if path points to file.
|
5
|
-
#
|
6
|
-
# @return [Boolean] True if path is a file.
|
7
|
-
# @see ::File.file?
|
8
|
-
#
|
9
|
-
def file?
|
10
|
-
invoke_backend :file?
|
11
|
-
end
|
12
|
-
|
13
|
-
# Check if path points to an existing location.
|
14
|
-
#
|
15
|
-
# @return [Boolean] True if path exists.
|
16
|
-
# @see ::File.exists?
|
17
|
-
#
|
18
|
-
def exists?
|
19
|
-
invoke_backend :exists?
|
20
|
-
end
|
21
|
-
alias_method :exist?, :exists?
|
22
|
-
alias_method :existent?, :exists?
|
23
|
-
|
24
|
-
# Check if path points to a directory.
|
25
|
-
#
|
26
|
-
# @return [Boolean] True if path is a directory.
|
27
|
-
# @see ::File.directory?
|
28
|
-
#
|
29
|
-
def directory?
|
30
|
-
invoke_backend :directory?
|
31
|
-
end
|
32
|
-
end
|
data/lib/rubypath/identity.rb
DELETED
@@ -1,59 +0,0 @@
|
|
1
|
-
class Path
|
2
|
-
# @!group Identity
|
3
|
-
|
4
|
-
# Return path as string. String will be duped before it gets returned and
|
5
|
-
# cannot be used to modify the path object.
|
6
|
-
#
|
7
|
-
# @return [String] Path as string.
|
8
|
-
def path
|
9
|
-
internal_path.dup
|
10
|
-
end
|
11
|
-
alias_method :to_path, :path
|
12
|
-
alias_method :to_str, :path
|
13
|
-
alias_method :to_s, :path
|
14
|
-
|
15
|
-
# Return a useful object string representation.
|
16
|
-
#
|
17
|
-
# @return [String] Useful object representation
|
18
|
-
def inspect
|
19
|
-
"<#{self.class.name}:#{internal_path}>"
|
20
|
-
end
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
protected
|
25
|
-
|
26
|
-
# Return internal path object without duping.
|
27
|
-
#
|
28
|
-
# Must not be modified to not change internal state.
|
29
|
-
#
|
30
|
-
# @return [String] Internal path.
|
31
|
-
# @see #path
|
32
|
-
#
|
33
|
-
def internal_path
|
34
|
-
@path
|
35
|
-
end
|
36
|
-
|
37
|
-
# If arguments are provided the current path will be joined with given
|
38
|
-
# arguments to the result will be yielded. If no arguments are given the
|
39
|
-
# current path will be yielded.
|
40
|
-
#
|
41
|
-
# Internal helper method.
|
42
|
-
#
|
43
|
-
# @example
|
44
|
-
# def handle_both(*args)
|
45
|
-
# with_path(*args) do |path|
|
46
|
-
# # do something
|
47
|
-
# end
|
48
|
-
# end
|
49
|
-
#
|
50
|
-
# Returns whatever the block returns.
|
51
|
-
#
|
52
|
-
def with_path(*args)
|
53
|
-
if args.any?
|
54
|
-
yield join(*args)
|
55
|
-
else
|
56
|
-
yield self
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
@@ -1,82 +0,0 @@
|
|
1
|
-
class Path
|
2
|
-
# @!group IO Operations
|
3
|
-
|
4
|
-
# Write given content to file.
|
5
|
-
#
|
6
|
-
# @overload write(content, [..])
|
7
|
-
# Write given content to file. An existing file will be truncated otherwise
|
8
|
-
# a file will be created.
|
9
|
-
#
|
10
|
-
# Additional arguments will be passed to {::IO.write}.
|
11
|
-
#
|
12
|
-
# @example
|
13
|
-
# Path('/path/to/file.txt').write('CONTENT')
|
14
|
-
# #=> 7
|
15
|
-
#
|
16
|
-
# @param content [String] Content to write to file.
|
17
|
-
#
|
18
|
-
# @overload write(content, offset, [..])
|
19
|
-
# Write content at specific position in file. Content will be replaced
|
20
|
-
# starting at given offset.
|
21
|
-
#
|
22
|
-
# Additional arguments will be passed to {::IO.write}.
|
23
|
-
#
|
24
|
-
# @example
|
25
|
-
# path.write('CONTENT', 4)
|
26
|
-
# #=> 7
|
27
|
-
# path.read
|
28
|
-
# #=> "1234CONTENT2345678"
|
29
|
-
#
|
30
|
-
# @param content [String] Content to write to file.
|
31
|
-
# @param offset [Integer] Offset where to start writing. If nil file will
|
32
|
-
# be truncated.
|
33
|
-
#
|
34
|
-
# @see IO.write
|
35
|
-
# @return [Path] Self.
|
36
|
-
#
|
37
|
-
def write(content, *args)
|
38
|
-
invoke_backend :write, self, content, *args
|
39
|
-
self
|
40
|
-
end
|
41
|
-
|
42
|
-
# Read file content from disk.
|
43
|
-
#
|
44
|
-
# @overload read([..])
|
45
|
-
# Read all content from file.
|
46
|
-
#
|
47
|
-
# Additional arguments will be passed to {::IO.read}.
|
48
|
-
#
|
49
|
-
# @example
|
50
|
-
# Path('file.txt').read
|
51
|
-
# #=> "CONTENT"
|
52
|
-
#
|
53
|
-
# @overload read(length, [..])
|
54
|
-
# Read given amount of bytes from file.
|
55
|
-
#
|
56
|
-
# Additional arguments will be passed to {::IO.read}.
|
57
|
-
#
|
58
|
-
# @example
|
59
|
-
# Path('file.txt').read(4)
|
60
|
-
# #=> "CONT"
|
61
|
-
#
|
62
|
-
# @param length [Integer] Number of bytes to read.
|
63
|
-
#
|
64
|
-
# @overload read(length, offset, [..])
|
65
|
-
# Read given amount of bytes from file starting at given offset.
|
66
|
-
#
|
67
|
-
# Additional arguments will be passed to {::IO.read}.
|
68
|
-
#
|
69
|
-
# @example
|
70
|
-
# Path('file.txt').read(4, 2)
|
71
|
-
# #=> "NTEN"
|
72
|
-
#
|
73
|
-
# @param length [Integer] Number of bytes to read.
|
74
|
-
# @param offset [Integer] Where to start reading.
|
75
|
-
#
|
76
|
-
# @see IO.read
|
77
|
-
# @return [String] Read content.
|
78
|
-
#
|
79
|
-
def read(*args)
|
80
|
-
invoke_backend :read, self, *args
|
81
|
-
end
|
82
|
-
end
|