rubypath 0.3.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,161 +0,0 @@
1
- class Path::Backend
2
-
3
- #
4
- class Sys
5
-
6
- def initialize(root = nil)
7
- @root = ::File.expand_path root if root
8
- @umask = File.umask
9
- end
10
-
11
- def quit
12
- File.umask @umask
13
- end
14
-
15
- def home(user)
16
- ::File.expand_path "~#{user}"
17
- end
18
-
19
- def getwd
20
- ::Dir.getwd
21
- end
22
-
23
- def user
24
- require 'etc'
25
-
26
- Etc.getlogin
27
- end
28
-
29
- def r(path)
30
- return path unless @root
31
- ::File.expand_path("#{@root}/#{::File.expand_path(path)}")
32
- end
33
-
34
- def ur(path)
35
- return path unless @root
36
-
37
- if path.slice(0, @root.length) == @root
38
- path.slice(@root.length, path.length - @root.length)
39
- else
40
- path
41
- end
42
- end
43
-
44
- def fs(path, obj, method, *args)
45
- # puts "[FS] #{obj} #{method} #{args.inspect}"
46
- obj.send method, *args
47
- rescue Errno::ENOENT
48
- raise Errno::ENOENT.new path
49
- rescue Errno::EISDIR
50
- raise Errno::EISDIR.new path
51
- rescue Errno::ENOTDIR
52
- raise Errno::ENOTDIR.new path
53
- rescue Errno::EACCES
54
- raise Errno::EACCES.new path
55
- end
56
-
57
- ## OPERATIONS
58
-
59
- def expand_path(path, base)
60
- ::File.expand_path path, base
61
- end
62
-
63
- def exists?(path)
64
- fs path, ::File, :exists?, r(path)
65
- end
66
-
67
- def mkdir(path)
68
- fs path, ::Dir, :mkdir, r(path)
69
- end
70
-
71
- def mkpath(path)
72
- fs path, ::FileUtils, :mkdir_p, r(path)
73
- end
74
-
75
- def directory?(path)
76
- fs path, ::File, :directory?, r(path)
77
- end
78
-
79
- def file?(path)
80
- fs path, ::File, :file?, r(path)
81
- end
82
-
83
- def touch(path)
84
- fs path, ::FileUtils, :touch, r(path)
85
- end
86
-
87
- def write(path, content, *args)
88
- fs path, ::IO, :write, r(path), content, *args
89
- end
90
-
91
- def read(path, *args)
92
- fs path, ::IO, :read, r(path), *args
93
- end
94
-
95
- def mtime(path)
96
- fs path, ::File, :mtime, r(path)
97
- end
98
-
99
- def mtime=(path, time)
100
- fs path, ::File, :utime, atime(path), time, r(path)
101
- end
102
-
103
- def atime(path)
104
- fs path, ::File, :atime, r(path)
105
- end
106
-
107
- def atime=(path, time)
108
- fs path, ::File, :utime, time, mtime(path), r(path)
109
- end
110
-
111
- def entries(path)
112
- fs path, ::Dir, :entries, r(path)
113
- end
114
-
115
- def glob(pattern, flags = 0, &block)
116
- if block_given?
117
- fs pattern, ::Dir, :glob, r(pattern), flags do |path|
118
- yield ur(path)
119
- end
120
- else
121
- fs(pattern, ::Dir, :glob, r(pattern), flags).map{|path| ur path }
122
- end
123
- end
124
-
125
- def get_umask
126
- File.umask
127
- end
128
-
129
- def set_umask(mask)
130
- File.umask mask
131
- end
132
-
133
- def mode(path)
134
- fs(path, ::File, :stat, r(path)).mode & 0777
135
- end
136
-
137
- def chmod(path, mode)
138
- fs path, ::File, :chmod, mode, r(path)
139
- end
140
-
141
- def unlink(path)
142
- fs path, ::File, :unlink, r(path)
143
- end
144
-
145
- def rmtree(path)
146
- fs path, ::FileUtils, :rm_r, r(path), force: true
147
- end
148
-
149
- def rmtree!(path)
150
- fs path, ::FileUtils, :rm_r, r(path)
151
- end
152
-
153
- def safe_rmtree(path)
154
- fs path, ::FileUtils, :rm_r, r(path), force: true, secure: true
155
- end
156
-
157
- def safe_rmtree!(path)
158
- fs path, ::FileUtils, :rm_r, r(path), secure: true
159
- end
160
- end
161
- end
@@ -1,19 +0,0 @@
1
- class Path
2
- # @!group Comparison
3
-
4
- # Compare path to given object. If object is a string, Path or #{Path.like?}
5
- # they will be compared using the string paths. Otherwise they are assumed
6
- # as not equal.
7
- #
8
- # @param other [Object] Object to compare path with.
9
- # @return [Boolean] True if object represents same path.
10
- #
11
- def eql?(other)
12
- if other.is_a?(Path)
13
- cleanpath.internal_path == other.cleanpath.internal_path
14
- else
15
- Path.new(other).eql?(self) if Path.like?(other)
16
- end
17
- end
18
- alias_method :==, :eql?
19
- end
@@ -1,109 +0,0 @@
1
- class Path
2
-
3
- class << self
4
- # @!group Construction
5
-
6
- # Create new {Path}.
7
- #
8
- # If single argument is a path object it will be returned and no new one
9
- # will be created. If not arguments are given {Path::EMPTY} will be
10
- # returned.
11
- #
12
- # @see #initialize
13
- #
14
- def new(*args)
15
- args.flatten!
16
- return Path::EMPTY if args.empty?
17
- return args.first if args.size == 1 && args.first.is_a?(self)
18
- super
19
- end
20
-
21
- # Check if given object is like a path.
22
- #
23
- # An object is like a path if
24
- # 1. It is a {Path} object.
25
- # 2. It is a string.
26
- # 3. It responds to {#to_path} and {#to_path} returns a string.
27
- # 4. It responds to {#path} and {#path} returns a string.
28
- #
29
- # If no rule matches it is not considered to be like a path.
30
- #
31
- # @return [Boolean] True if object is path like, false otherwise.
32
- #
33
- def like?(obj)
34
- return true if obj.is_a?(self)
35
- return true if obj.is_a?(String)
36
- return true if obj.respond_to?(:to_path) && obj.to_path.is_a?(String)
37
- return true if obj.respond_to?(:path) && obj.path.is_a?(String)
38
- false
39
- end
40
-
41
- # Convert given object to path string using {::Path.like?} rules.
42
- #
43
- # @note Should not be used directly.
44
- #
45
- # @return [String]
46
- # @raise [ArgumentError] If given object is not {::Path.like?}.
47
- # @see ::Path.like?
48
- #
49
- def like_path(obj)
50
- case obj
51
- when String
52
- return obj
53
- else
54
- [:to_path, :path, :to_str, :to_s].each do |mth|
55
- if obj.respond_to?(mth) && obj.send(mth).is_a?(String)
56
- return obj.send(mth)
57
- end
58
- end
59
- end
60
-
61
- raise ArgumentError.new \
62
- "Argument #{obj.inspect} cannot be converted to path string."
63
- end
64
-
65
- # Return system file path separator.
66
- #
67
- # @return [String] File separator.
68
- # @see ::File::SEPARATOR
69
- #
70
- def separator
71
- ::File::SEPARATOR
72
- end
73
-
74
- # Allow class object to be used as a bock.
75
- #
76
- # @example
77
- # %w(path/to/fileA path/to/fileB).map(&Path)
78
- #
79
- def to_proc
80
- proc {|*args| Path.new(*args) }
81
- end
82
- end
83
-
84
- # @!group Construction
85
-
86
- # Initialize new {Path} object.
87
- #
88
- # Given arguments will be converted to String using `#to_path`, `#path` or
89
- # `#to_s` in this order if they return a String object.
90
- #
91
- # @overload initialize([[String, #to_path, #path, #to_s], ...]
92
- #
93
- def initialize(*args)
94
- parts = args.flatten
95
- @path = if parts.size > 1
96
- ::File.join(*parts.map{|p| Path.like_path p })
97
- elsif parts.size == 1
98
- Path.like_path(parts.first).dup
99
- else
100
- ''
101
- end
102
- end
103
-
104
- # Empty path.
105
- #
106
- # @return [Path] Empty path.
107
- #
108
- EMPTY = Path.new('')
109
- end
@@ -1,160 +0,0 @@
1
- class Path
2
- class << self
3
-
4
- # Returns the current working directory.
5
- #
6
- # @return [Path] Current working directory.
7
- # @see ::Dir.getwd
8
- #
9
- def getwd
10
- new Backend.instance.getwd
11
- end
12
-
13
- def glob(pattern, flags = nil)
14
- flags = default_glob_flags(flags)
15
-
16
- if block_given?
17
- Backend.instance.glob(pattern, flags) {|path| yield Path path }
18
- else
19
- Backend.instance.glob(pattern, flags).map(&Path)
20
- end
21
- end
22
-
23
- # @!visibility private
24
- #
25
- def default_glob_flags(flags)
26
- if flags.nil? && defined?(::File::FNM_EXTGLOB)
27
- ::File::FNM_EXTGLOB
28
- else
29
- flags.to_i
30
- end
31
- end
32
- end
33
-
34
- # @!group Directory Operations
35
-
36
- # Create directory.
37
- #
38
- # Given arguments will be joined with current path before directory is
39
- # created.
40
- #
41
- # @raise [Errno::ENOENT] If parent directory could not created.
42
- # @return [Path] Path to created directory.
43
- # @see #mkpath
44
- #
45
- def mkdir(*args)
46
- with_path(*args) do |path|
47
- Backend.instance.mkdir path
48
- Path path
49
- end
50
- end
51
-
52
- # Create directory and all missing parent directories.
53
- #
54
- # Given arguments will be joined with current path before directories
55
- # are created.
56
- #
57
- # @return [Path] Path to created directory.
58
- # @see #mkdir
59
- # @see ::FileUtils.mkdir_p
60
- #
61
- def mkpath(*args)
62
- with_path(*args) do |path|
63
- Backend.instance.mkpath path
64
- Path path
65
- end
66
- end
67
- alias_method :mkdir_p, :mkpath
68
-
69
- # Return list of entries in directory. That includes special directories
70
- # (`.`, `..`).
71
- #
72
- # Given arguments will be joined before children are listed for directory.
73
- #
74
- # @return [Array<Path>] Entries in directory.
75
- #
76
- def entries(*args)
77
- invoke_backend(:entries, internal_path).map(&Path)
78
- end
79
-
80
- #
81
- def glob(pattern, flags = nil, &block)
82
- Path.glob(::File.join(escaped_glob_path, pattern), flags, &block)
83
- end
84
-
85
- # Removes file or directory. If it's a directory it will be removed
86
- # recursively.
87
- #
88
- # WARNING: This method causes local vulnerability if one of parent
89
- # directories or removing directory tree are world writable (including
90
- # `/tmp`, whose permission is 1777), and the current process has strong
91
- # privilege such as Unix super user (root), and the system has symbolic link.
92
- # For secure removing see {#safe_rmtree}.
93
- #
94
- # @return [Path] Path to removed file or directory.
95
- #
96
- def rmtree(*args)
97
- with_path(*args) do |path|
98
- invoke_backend :rmtree, internal_path
99
- Path path
100
- end
101
- end
102
- alias_method :rm_rf, :rmtree
103
-
104
- # Removes file or directory. If it's a directory it will be removed
105
- # recursively.
106
- #
107
- # This method uses #{FileUtils#remove_entry_secure} to avoid TOCTTOU
108
- # (time-of-check-to-time-of-use) local security vulnerability of {#rmtree}.
109
- # {#rmtree} causes security hole when:
110
- #
111
- # * Parent directory is world writable (including `/tmp`).
112
- # * Removing directory tree includes world writable directory.
113
- # * The system has symbolic link.
114
- #
115
- # @return [Path] Path to removed file or directory.
116
- #
117
- def safe_rmtree(*args)
118
- with_path(*args) do |path|
119
- invoke_backend :safe_rmtree, internal_path
120
- Path path
121
- end
122
- end
123
-
124
- # Removes file or directory. If it's a directory it will be removed
125
- # recursively.
126
- #
127
- # This method behaves exactly like {#rmtree} but will raise exceptions
128
- # e.g. when file does not exist.
129
- #
130
- # @return [Path] Path to removed file or directory.
131
- #
132
- def rmtree!(*args)
133
- with_path(*args) do |path|
134
- invoke_backend :rmtree!, internal_path
135
- Path path
136
- end
137
- end
138
- alias_method :rm_r, :rmtree!
139
-
140
- # Removes file or directory. If it's a directory it will be removed
141
- # recursively.
142
- #
143
- # This method behaves exactly like {#safe_rmtree} but will raise exceptions
144
- # e.g. when file does not exist.
145
- #
146
- # @return [Path] Path to removed file or directory.
147
- #
148
- def safe_rmtree!(*args)
149
- with_path(*args) do |path|
150
- invoke_backend :safe_rmtree!, internal_path
151
- Path path
152
- end
153
- end
154
-
155
- private
156
-
157
- def escaped_glob_path
158
- internal_path.gsub(/[\[\]\*\?\{\}]/, '\\\\\0')
159
- end
160
- end