Class: ShellHelpers::PathnameExt::Base
- Defined in:
- lib/shell_helpers/pathname.rb
Direct Known Subclasses
Class Method Summary collapse
-
./(path) ⇒ Object
Pathname / 'usr'.
-
.[](path) ⇒ Object
Pathname['/usr'].
- .cd(dir, &b) ⇒ Object
-
.current ⇒ Object
differ from Pathname.pwd in that this returns a relative path.
- .home ⇒ Object
- .hometilde ⇒ Object
- .null ⇒ Object
- .slash ⇒ Object
Instance Method Summary collapse
- #abs_path(base: self.class.pwd, mode: :clean) ⇒ Object
-
#append_name(*args, join: '') ⇒ Object
Pathname.new("foo")+"bar" return "foo/bar" Pathname.new("foo").append_name("bar") return "foobar".
- #backup(suffix: '.old', overwrite: true) ⇒ Object
- #bad_symlink? ⇒ Boolean
-
#binary? ⇒ Boolean
stolen from ptools (https://github.com/djberg96/ptools/blob/master/lib/ptools.rb).
-
#call(prog, *args, pos: :last, full: false, **opts) ⇒ Object
calls an external program.
- #chattr(*args, **opts) ⇒ Object
- #components ⇒ Object
-
#convert_path(base: self.class.pwd, mode: :clean, checkdir: false) ⇒ Object
call abs_path or rel_path according to :mode.
-
#copy_entry(dest, dereference: false, preserve: true) ⇒ Object
use the low level FileUtils feature to copy the metadata if passed a dir just copy the dir metadata, not the directory recursively Note this differs from FileUtils.copy_entry who copy directories recursively.
- #depth ⇒ Object
- #dereference(mode = true) ⇒ Object
- #entries(filter: true) ⇒ Object
- #filewrite(*args, mode: "w", perm: nil, mkpath: false, backup: false) ⇒ Object
- #find(*args, &b) ⇒ Object
-
#follow ⇒ Object
follow a symlink.
- #hidden? ⇒ Boolean
-
#may_exist? ⇒ Boolean
exist? returns false if called on a symlink pointing to a non existing file.
-
#new_name(cond) ⇒ Object
loop until we get a name satisfying cond.
-
#nonexisting_name ⇒ Object
find a non existing filename.
-
#orig_find ⇒ Object
overwrites Pathname#find.
-
#read! ⇒ Object
like read, but output nil rather than an exception if the file does not exist.
- #readbin(*args) ⇒ Object
-
#rel_glob(pattern, expand: false) ⇒ Object
We now have Pathname#glob.
- #rel_path(base: self.class.pwd, checkdir: false) ⇒ Object
-
#rel_path_to(target = self.class.pwd, base: self.class.pwd, mode: :rel, clean_mode: :abs_clean, inside: false, **opts) ⇒ Object
path from self to target (warning: we always assume that we are one level up self, except if inside is true) bar=SH::Pathname.new("foo/bar"); baz=SH::Pathname.new("foo/baz") bar.rel_path_to(baz) #ShellHelpers::Pathname:baz bar.rel_path_to(baz, inside: true) #ShellHelpers::Pathname:../baz note: there is no real sense to use mode: :rel here, but we don't prevent it.
- #rm_bad_symlinks(rm: false, hidden: false) ⇒ Object
-
#rm_empty_dirs(rm: true) ⇒ Object
remove all empty directories inside self this includes directories which only include empty directories.
-
#rm_r ⇒ Object
rmtree should be rm_rf, not rm_r!.
- #rmtree ⇒ Object (also: #rm_rf)
- #shellescape ⇒ Object
-
#split_all ⇒ Object
taken from facets/split_all.
- #sudo_mkdir ⇒ Object
- #sudo_mkpath ⇒ Object
-
#text? ⇒ Boolean
return true if the file is a text.
- #to_relative ⇒ Object
Methods inherited from Pathname
Class Method Details
./(path) ⇒ Object
Pathname / 'usr'
74 75 76 |
# File 'lib/shell_helpers/pathname.rb', line 74 def /(path) new(path) end |
.[](path) ⇒ Object
Pathname['/usr']
78 79 80 |
# File 'lib/shell_helpers/pathname.rb', line 78 def [](path) new(path) end |
.cd(dir, &b) ⇒ Object
82 83 84 |
# File 'lib/shell_helpers/pathname.rb', line 82 def cd(dir,&b) self.new(dir).cd(&b) end |
.current ⇒ Object
differ from Pathname.pwd in that this returns a relative path
66 67 68 |
# File 'lib/shell_helpers/pathname.rb', line 66 def current return Pathname.new(".") end |
.home ⇒ Object
56 57 58 |
# File 'lib/shell_helpers/pathname.rb', line 56 def home return Pathname.new(Dir.home) end |
.hometilde ⇒ Object
59 60 61 |
# File 'lib/shell_helpers/pathname.rb', line 59 def hometilde return Pathname.new('~') end |
.null ⇒ Object
69 70 71 |
# File 'lib/shell_helpers/pathname.rb', line 69 def null return Pathname.new('/dev/null') end |
.slash ⇒ Object
62 63 64 |
# File 'lib/shell_helpers/pathname.rb', line 62 def slash return Pathname.new("/") end |
Instance Method Details
#abs_path(base: self.class.pwd, mode: :clean) ⇒ Object
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 |
# File 'lib/shell_helpers/pathname.rb', line 205 def abs_path(base: self.class.pwd, mode: :clean) f= absolute? ? self : base+self case mode when :clean f.cleanpath when :clean_sym f.cleanpath(consider_symlink: true) when :real f.realpath when :realdir f.realdirpath else f end end |
#append_name(*args, join: '') ⇒ Object
Pathname.new("foo")+"bar" return "foo/bar" Pathname.new("foo").append_name("bar") return "foobar"
147 148 149 |
# File 'lib/shell_helpers/pathname.rb', line 147 def append_name(*args,join:'') Pathname.new(self.to_s+args.join(join)) end |
#backup(suffix: '.old', overwrite: true) ⇒ Object
196 197 198 199 200 201 202 203 |
# File 'lib/shell_helpers/pathname.rb', line 196 def backup(suffix: '.old', overwrite: true) if self.exist? filebk=self.append_name(suffix) filebk=nonexisting_name if filebk.exist? and !overwrite logger.debug "Backup #{self} -> #{filebk}" if respond_to?(:logger) FileUtils.mv(self,filebk) end end |
#bad_symlink? ⇒ Boolean
314 315 316 |
# File 'lib/shell_helpers/pathname.rb', line 314 def bad_symlink? symlink? and !dereference.exist? end |
#binary? ⇒ Boolean
stolen from ptools (https://github.com/djberg96/ptools/blob/master/lib/ptools.rb)
167 168 169 170 171 172 173 174 175 |
# File 'lib/shell_helpers/pathname.rb', line 167 def binary? return false if directory? bytes = stat.blksize bytes = 4096 if bytes > 4096 s = read(bytes, bytes) || "" #s = s.encode('US-ASCII', :undef => :replace).split(//) s=s.split(//) ((s.size - s.grep(" ".."~").size) / s.size.to_f) > 0.30 end |
#call(prog, *args, pos: :last, full: false, **opts) ⇒ Object
calls an external program
357 358 359 360 361 362 363 364 |
# File 'lib/shell_helpers/pathname.rb', line 357 def call(prog,*args,pos: :last,full:false,**opts) name=to_s name=(self.class.pwd+self).to_s if full and relative? sh_args=args pos=sh_args.length if pos==:last sh_args[pos,0]=name Sh.sh(prog,*sh_args,**opts) end |
#chattr(*args, **opts) ⇒ Object
366 367 368 |
# File 'lib/shell_helpers/pathname.rb', line 366 def chattr(*args,**opts) call("chattr",*args,**opts) end |
#components ⇒ Object
129 130 131 |
# File 'lib/shell_helpers/pathname.rb', line 129 def components each_filename.to_a end |
#convert_path(base: self.class.pwd, mode: :clean, checkdir: false) ⇒ Object
call abs_path or rel_path according to :mode
230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 |
# File 'lib/shell_helpers/pathname.rb', line 230 def convert_path(base: self.class.pwd, mode: :clean, checkdir: false) case mode when :clean cleanpath when :clean_sym cleanpath(consider_symlink: true) when :rel rel_path(base: base, checkdir: checkdir) when :relative rel_path(base: base, checkdir: checkdir) unless self.relative? when :absolute,:abs abs_path(base: base, mode: :abs) when :abs_clean abs_path(base: base, mode: :clean) when :abs_cleansym abs_path(base: base, mode: :cleansym) when :abs_real abs_path(base: base, mode: :real) when :abs_realdir abs_path(base: base, mode: :realdir) else self end end |
#copy_entry(dest, dereference: false, preserve: true) ⇒ Object
use the low level FileUtils feature to copy the metadata if passed a dir just copy the dir metadata, not the directory recursively Note this differs from FileUtils.copy_entry who copy directories recursively
48 49 50 51 52 53 |
# File 'lib/shell_helpers/pathname.rb', line 48 def copy_entry(dest, dereference: false, preserve: true) require 'fileutils' ent = FileUtils::Entry_.new(@path, nil, dereference) ent.copy dest.to_s ent. dest.to_s if preserve end |
#depth ⇒ Object
132 133 134 |
# File 'lib/shell_helpers/pathname.rb', line 132 def depth each_filename.count end |
#dereference(mode = true) ⇒ Object
303 304 305 306 307 308 309 310 311 312 |
# File 'lib/shell_helpers/pathname.rb', line 303 def dereference(mode=true) return self unless mode case mode when :simple return follow if symlink? else return follow.dereference(mode) if symlink? end self end |
#entries(filter: true) ⇒ Object
136 137 138 139 140 141 142 143 |
# File 'lib/shell_helpers/pathname.rb', line 136 def entries(filter: true) c=super() if filter c.reject {|c| c.to_s=="." or c.to_s==".."} else c end end |
#filewrite(*args, mode: "w", perm: nil, mkpath: false, backup: false) ⇒ Object
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/shell_helpers/pathname.rb', line 109 def filewrite(*args,mode:"w",perm: nil,mkpath: false,backup: false) logger.debug("Write to #{self}"+ (perm ? " (#{perm})" : "")) if respond_to?(:logger) self.dirname.mkpath if mkpath self.backup if backup and exist? if !exist? && symlink? logger.debug "Removing bad symlink #{self}" if respond_to?(:logger) self.unlink end self.open(mode: mode) do |fh| fh.chmod(perm) if perm #hack to pass an array to write and do the right thing if args.length == 1 && Array === args.first fh.puts(args.first) else fh.write(*args) end yield fh if block_given? end end |
#find(*args, &b) ⇒ Object
276 277 278 279 |
# File 'lib/shell_helpers/pathname.rb', line 276 def find(*args,&b) require 'shell_helpers/utils' Utils.find(self,*args,&b) end |
#follow ⇒ Object
follow a symlink
293 294 295 296 297 298 299 300 301 |
# File 'lib/shell_helpers/pathname.rb', line 293 def follow return self unless symlink? l=readlink if l.relative? self.dirname+l else l end end |
#hidden? ⇒ Boolean
318 319 320 321 |
# File 'lib/shell_helpers/pathname.rb', line 318 def hidden? #without abs_path '.' is considered as hidden abs_path.basename.to_s[0]=="." end |
#may_exist? ⇒ Boolean
exist? returns false if called on a symlink pointing to a non existing file
97 98 99 |
# File 'lib/shell_helpers/pathname.rb', line 97 def may_exist? exist? or symlink? end |
#new_name(cond) ⇒ Object
loop until we get a name satisfying cond
152 153 154 155 156 157 |
# File 'lib/shell_helpers/pathname.rb', line 152 def new_name(cond) loop.with_index do |_,ind| n=self.class.new(yield(self,ind)) return n if cond.call(n) end end |
#nonexisting_name ⇒ Object
find a non existing filename
159 160 161 162 163 164 |
# File 'lib/shell_helpers/pathname.rb', line 159 def nonexisting_name return self unless self.may_exist? new_name(Proc.new {|f| !f.may_exist?}) do |old_name, ind| old_name.append_name("%02d" % ind) end end |
#orig_find ⇒ Object
overwrites Pathname#find
275 |
# File 'lib/shell_helpers/pathname.rb', line 275 alias orig_find find |
#read! ⇒ Object
like read, but output nil rather than an exception if the file does not exist
103 104 105 106 107 |
# File 'lib/shell_helpers/pathname.rb', line 103 def read! read rescue nil end |
#readbin(*args) ⇒ Object
184 185 186 |
# File 'lib/shell_helpers/pathname.rb', line 184 def readbin(*args) open("rb").read(*args) end |
#rel_glob(pattern, expand: false) ⇒ Object
We now have Pathname#glob
282 283 284 285 286 287 288 289 290 |
# File 'lib/shell_helpers/pathname.rb', line 282 def rel_glob(pattern, expand: false) g=[] self.cd { g=Dir.glob(pattern) } if g.map {|f| self+f} else g.map {|f| Pathname.new(f)} end end |
#rel_path(base: self.class.pwd, checkdir: false) ⇒ Object
221 222 223 224 225 226 227 |
# File 'lib/shell_helpers/pathname.rb', line 221 def rel_path(base: self.class.pwd, checkdir: false) base=base.dirname unless base.directory? if checkdir relative_path_from(base) rescue ArgumentError => e warn "#{self}.relative_path_from(#{base}): #{e}" self end |
#rel_path_to(target = self.class.pwd, base: self.class.pwd, mode: :rel, clean_mode: :abs_clean, inside: false, **opts) ⇒ Object
path from self to target (warning: we always assume that we are one level up self, except if inside is true) bar=SH::Pathname.new("foo/bar"); baz=SH::Pathname.new("foo/baz") bar.rel_path_to(baz) #ShellHelpers::Pathname:baz bar.rel_path_to(baz, inside: true) #ShellHelpers::Pathname:../baz note: there is no real sense to use mode: :rel here, but we don't prevent it
262 263 264 265 266 267 268 269 270 271 272 |
# File 'lib/shell_helpers/pathname.rb', line 262 def rel_path_to(target=self.class.pwd, base: self.class.pwd, mode: :rel, clean_mode: :abs_clean, inside: false, **opts) target=self.class.new(target) unless target.is_a?(self.class) sbase=opts[:source_base]||base smode=opts[:source_mode]||clean_mode tbase=opts[:target_base]||base tmode=opts[:target_mode]||clean_mode source=self.convert_path(base: sbase, mode: smode) target=target.convert_path(base: tbase, mode: tmode) from=inside ? source : source.dirname target.convert_path(base: from, mode: mode) end |
#rm_bad_symlinks(rm: false, hidden: false) ⇒ Object
338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 |
# File 'lib/shell_helpers/pathname.rb', line 338 def rm_bad_symlinks(rm:false,hidden:false) r=[] if directory? filter=if hidden ->(x,_) {x.hidden?} else ->(*x) {false} end find(filter:filter) do |file| if file.bad_symlink? r<<file file.rm if rm end end end r end |
#rm_empty_dirs(rm: true) ⇒ Object
remove all empty directories inside self this includes directories which only include empty directories
325 326 327 328 329 330 331 332 333 334 335 336 |
# File 'lib/shell_helpers/pathname.rb', line 325 def rm_empty_dirs(rm:true) r=[] if directory? find(depth:true) do |file| if file.directory? and file.children(false).empty? r<<file file.rmdir if rm end end end r end |
#rm_r ⇒ Object
rmtree should be rm_rf, not rm_r!
27 |
# File 'lib/shell_helpers/pathname.rb', line 27 alias_method :rm_r, :rmtree |
#rmtree ⇒ Object Also known as: rm_rf
28 29 30 31 32 |
# File 'lib/shell_helpers/pathname.rb', line 28 def rmtree require 'fileutils' FileUtils.rm_rf(@path) nil end |
#shellescape ⇒ Object
35 36 37 38 |
# File 'lib/shell_helpers/pathname.rb', line 35 def shellescape require 'shellwords' to_s.shellescape end |
#split_all ⇒ Object
taken from facets/split_all
189 190 191 192 193 194 |
# File 'lib/shell_helpers/pathname.rb', line 189 def split_all head, tail = split return [tail] if head.to_s == '.' || tail.to_s == '/' return [head, tail] if head.to_s == '/' return head.split_all + [tail] end |
#sudo_mkdir ⇒ Object
370 371 372 |
# File 'lib/shell_helpers/pathname.rb', line 370 def sudo_mkdir Sh.sh("mkdir -p #{shellescape}", sudo: true) end |
#sudo_mkpath ⇒ Object
373 374 375 |
# File 'lib/shell_helpers/pathname.rb', line 373 def sudo_mkpath Sh.sh("mkdir -p #{shellescape}", sudo: true) end |
#text? ⇒ Boolean
return true if the file is a text
178 179 180 181 182 |
# File 'lib/shell_helpers/pathname.rb', line 178 def text? #!! %x/file #{self.to_s}/.match(/text/) return false if directory? !binary? end |