Module: FileSystem

Defined in:
lib/atk/yaml_info_parser.rb,
lib/atk/file_sys.rb

Overview

duplicated for the sake of efficieny (so that the parser doesn’t need to import all of FileSystem)

Class Method Summary collapse

Class Method Details

.absolute_path(*args) ⇒ Object

inherit from File



273
274
275
# File 'lib/atk/file_sys.rb', line 273

def self.absolute_path(*args)
    File.absolute_path(*args)
end

.absolute_path?(path) ⇒ Boolean

Pathname aliases

Returns:

  • (Boolean)


186
187
188
# File 'lib/atk/file_sys.rb', line 186

def self.absolute_path?(path)
    Pathname.new(path).absolute?
end

.basename(*args) ⇒ Object



279
280
281
# File 'lib/atk/file_sys.rb', line 279

def self.basename(*args)
    File.basename(*args)
end

.cd(*args, verbose: false) ⇒ Object



237
238
239
240
241
242
# File 'lib/atk/file_sys.rb', line 237

def self.cd(*args, verbose: false)
    if args.size == 0
        args[0] = FS.home
    end
    FileUtils.cd(args[0], verbose: verbose)
end

.chdir(*args) ⇒ Object



243
244
245
# File 'lib/atk/file_sys.rb', line 243

def self.chdir(*args)
    FS.cd(*args)
end

.copy(from: nil, to: nil, new_name: "", force: true, preserve: false, dereference_root: false) ⇒ Object



135
136
137
138
139
140
141
142
143
144
145
# File 'lib/atk/file_sys.rb', line 135

def self.copy(from:nil, to:nil, new_name:"", force: true, preserve: false, dereference_root: false)
    if new_name == ""
        raise "\n\nFileSystem.copy() needs a new_name: argument\nset new_name:nil if you wish the file/folder to keep the same name\ne.g. FileSystem.copy(from:'place/thing', to:'place', new_name:nil)"
    elsif new_name == nil
        new_name = File.basename(from)
    end
    # make sure the "to" path exists
    FileSystem.touch_dir(to)
    # perform the copy
    FileUtils.copy_entry(from, to/new_name, preserve, dereference_root, force)
end

.delete(path) ⇒ Object



103
104
105
106
107
108
109
# File 'lib/atk/file_sys.rb', line 103

def self.delete(path)
    if File.file?(path)
        File.delete(path)
    elsif File.directory?(path)
        FileUtils.rm_rf(path)
    end
end

.dirname(*args) ⇒ Object



276
277
278
# File 'lib/atk/file_sys.rb', line 276

def self.dirname(*args)
    File.dirname(*args)
end

.download(input = nil, from: nil, url: nil, to: nil) ⇒ Object



380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
# File 'lib/atk/file_sys.rb', line 380

def self.download(input=nil, from:nil, url:nil, to:nil)
    require 'open-uri'
    # if only one argument, either input or url
    if ((input!=nil) != (url!=nil)) && (from==nil) && (to==nil)
        # this covers:
        #    download     'site.com/file'
        the_url = url || input
        file_name = the_url.match /(?<=\/)[^\/]+\z/ 
        file_name = file_name[0]
    elsif (to != nil) && ((input!=nil)!=(url!=nil))
        # this covers:
        #    download     'site.com/file' to:'file'
        #    download url:'site.com/file' to:'file'
        the_url = url || input
        file_name = to
    elsif ((from!=nil) != (url!=nil)) && input!=nil
        # this covers:
        #    download 'file' from:'site.com/file'
        #    download 'file'  url:'site.com/file'
        the_url = from || url
        file_name = input
    else
        raise <<-HEREDOC.remove_indent
            I'm not sure how you're using the download function.
            Please use one of the following methods:
                download     'site.com/file'
                download     'site.com/file', to:'file'
                download url:'site.com/file', to:'file'
                download 'file', from:'site.com/file'
                download 'file',  url:'site.com/file'
        HEREDOC
    end
    FileSystem.write(open(URI.encode(the_url)).read, to: file_name)
end

.empty?(*args) ⇒ Boolean

Returns:

  • (Boolean)


305
306
307
# File 'lib/atk/file_sys.rb', line 305

def self.empty?(*args)
    File.empty?(*args)
end

.executable?(*args) ⇒ Boolean

Returns:

  • (Boolean)


310
311
312
# File 'lib/atk/file_sys.rb', line 310

def self.executable?(*args)
    File.executable?(*args)
end

.exists?(*args) ⇒ Boolean

Returns:

  • (Boolean)


294
295
296
# File 'lib/atk/file_sys.rb', line 294

def self.exists?(*args)
    File.exist?(*args)
end

.expand_path(*args) ⇒ Object



370
371
372
# File 'lib/atk/file_sys.rb', line 370

def self.expand_path(*args)
    File.expand_path(*args)
end

.extname(*args) ⇒ Object



282
283
284
# File 'lib/atk/file_sys.rb', line 282

def self.extname(*args)
    File.extname(*args)
end

.file?(*args) ⇒ Boolean

Returns:

  • (Boolean)


300
301
302
# File 'lib/atk/file_sys.rb', line 300

def self.file?(*args)
    File.file?(*args)
end

.folder?(*args) ⇒ Boolean

Returns:

  • (Boolean)


285
286
287
# File 'lib/atk/file_sys.rb', line 285

def self.folder?(*args)
    File.directory?(*args)
end

.glob(path) ⇒ Object



222
223
224
# File 'lib/atk/file_sys.rb', line 222

def self.glob(path)
    Dir.glob(path, File::FNM_DOTMATCH) - %w[. ..]
end

.homeObject

dir aliases



219
220
221
# File 'lib/atk/file_sys.rb', line 219

def self.home
    HOME
end

.in_dir(path_to_somewhere) ⇒ Object



123
124
125
126
127
128
129
130
131
132
133
# File 'lib/atk/file_sys.rb', line 123

def self.in_dir(path_to_somewhere)
    # save the current working dir
    current_dir = Dir.pwd
    # switch dirs
    Dir.chdir(path_to_somewhere)
    # do the thing
    output = yield
    # switch back
    Dir.chdir(current_dir)
    return output
end

.join(*args) ⇒ Object



257
258
259
260
261
262
263
264
265
266
267
268
269
270
# File 'lib/atk/file_sys.rb', line 257

def self.join(*args)
    if OS.is?("windows")
        folders_without_leading_or_trailing_slashes = args.map do |each|
            # replace all forward slashes with backslashes
            backslashed_only = each.gsub(/\//,"\\")
            # remove leading/trailing backslashes
            backslashed_only.gsub(/(^\\|^\/|\\$|\/$)/,"")
        end
        # join all of them with backslashes
        folders_without_leading_or_trailing_slashes.join("\\")
    else
        File.join(*args)
    end
end

.list_files(path = ".") ⇒ Object



225
226
227
# File 'lib/atk/file_sys.rb', line 225

def self.list_files(path=".")
    Dir.children(path).map{|each| path/each }.select {|each| FileSystem.file?(each)}
end

.list_folders(path = ".") ⇒ Object



228
229
230
# File 'lib/atk/file_sys.rb', line 228

def self.list_folders(path=".")
    Dir.children(path).map{|each| path/each }.select {|each| FileSystem.directory?(each)}
end

.ls(path = ".") ⇒ Object



231
232
233
# File 'lib/atk/file_sys.rb', line 231

def self.ls(path=".")
    Dir.children(path)
end

.makedirs(path) ⇒ Object



119
120
121
# File 'lib/atk/file_sys.rb', line 119

def self.makedirs(path)
    FileUtils.makedirs(path)
end

.mkfifo(*args) ⇒ Object



373
374
375
# File 'lib/atk/file_sys.rb', line 373

def self.mkfifo(*args)
    File.mkfifo(*args)
end

.move(from: nil, to: nil, new_name: "", force: true, noop: nil, verbose: nil, secure: nil) ⇒ Object



147
148
149
150
151
152
153
154
155
156
157
# File 'lib/atk/file_sys.rb', line 147

def self.move(from:nil, to:nil, new_name:"", force: true, noop: nil, verbose: nil, secure: nil)
    if new_name == ""
        raise "\n\nFileSystem.move() needs a new_name: argument\nset new_name:nil if you wish the file/folder to keep the same name\ne.g. FileSystem.move(from:'place/thing', to:'place', new_name:nil)"
    elsif new_name == nil
        new_name = File.basename(from)
    end
    # make sure the "to" path exists
    FileSystem.touch_dir(to)
    # perform the move
    FileUtils.move(from, to/new_name, force: force, noop: noop, verbose: verbose, secure: secure)
end

.owned?(*args) ⇒ Boolean

Returns:

  • (Boolean)


320
321
322
# File 'lib/atk/file_sys.rb', line 320

def self.owned?(*args)
    File.owned?(*args)
end

.path_pieces(path) ⇒ Object



200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
# File 'lib/atk/file_sys.rb', line 200

def self.path_pieces(path)
    # use this function like this:
    # *path, filename, extension = FS.path_pieces('/Users/jeffhykin/Desktop/place1/file1.pdf')
    pieces = Pathname(path).each_filename.to_a
    extname = File.extname(pieces[-1])
    basebasename = pieces[-1][0...(pieces[-1].size - extname.size)]
    # add the root if the path is absolute
    if FileSystem.abs?(path)
        if not OS.is?("windows")
            pieces.unshift('/')
        else
            # TODO: eventually make this work for any drive, not just the current drive
            pieces.unshift('\\')
        end
    end
    return [ *pieces[0...-1], basebasename, extname ]
end

.pipe?(*args) ⇒ Boolean

Returns:

  • (Boolean)


325
326
327
# File 'lib/atk/file_sys.rb', line 325

def self.pipe?(*args)
    File.pipe?(*args)
end

.pwdObject



234
235
236
# File 'lib/atk/file_sys.rb', line 234

def self.pwd
    Dir.pwd
end

.read(filepath) ⇒ Object



95
96
97
98
99
100
101
# File 'lib/atk/file_sys.rb', line 95

def self.read(filepath)
    begin
        return IO.read(filepath)
    rescue Errno::ENOENT => exception
        return nil
    end
end

.readable?(*args) ⇒ Boolean

Returns:

  • (Boolean)


330
331
332
# File 'lib/atk/file_sys.rb', line 330

def self.readable?(*args)
    File.readable?(*args)
end

.relative_path?(path) ⇒ Boolean

Returns:

  • (Boolean)


193
194
195
# File 'lib/atk/file_sys.rb', line 193

def self.relative_path?(path)
    Pathname.new(path).relative?
end

.rename(from: nil, to: nil, force: true) ⇒ Object



159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/atk/file_sys.rb', line 159

def self.rename(from:nil, to:nil, force: true)
    # if the directories are different, then throw an error
    if not File.identical?(File.dirname(from), File.dirname(to))
        raise "\n\nFileSystem.rename() requires that the the file stay in the same place and only change names.\nIf you want to move a file, use FileSystem.move()"
    end
    # make sure the path is clear
    if force
        FileSystem.delete(to)
    end
    # perform the copy
    File.rename(from, to)
end

.save(value, to: nil, as: nil) ⇒ Object



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/atk/file_sys.rb', line 48

def self.save(value, to:nil, as:nil)
    # assume string if as was not given
    if as == nil
        as = :s
    end
    
    # add a special exception for csv files
    case as
    when :csv
        require 'csv'
        FS.write(value.map(&:to_csv).join, to: to)
    else
        require 'json'
        require 'yaml'
        conversion_method_name = "to_#{as}"
        if value.respond_to? conversion_method_name
            # this is like calling `value.to_json`, `value.to_yaml`, or `value.to_csv` but programatically
            string_value = value.public_send(conversion_method_name)
            if not string_value.is_a?(String)
                raise <<-HEREDOC.remove_indent
                
                
                    The FileSystem.save(value, to: #{to.inspect}, as: #{as.inspect}) had a problem.
                    The as: #{as}, gets converted into value.to_#{as}
                    Normally that returns a string that can be saved to a file
                    However, the value.to_#{as} did not return a string.
                    Value is of the #{value.class} class. Add a `to_#{as}` 
                    method to that class that returns a string to get FileSystem.save() working
                HEREDOC
            end
            FS.write(string_value, to:to)
        else
            raise <<-HEREDOC.remove_indent
            
            
                The FileSystem.save(value, to: #{to.inspect}, as: #{as.inspect}) had a problem.
                
                The as: #{as}, gets converted into value.to_#{as}
                Normally that returns a string that can be saved to a file
                However, the value.to_#{as} is not a method for value
                Value is of the #{value.class} class. Add a `to_#{as}` 
                method to that class that returns a string to get FileSystem.save() working
            HEREDOC
        end
    end
end

.size?(*args) ⇒ Boolean

Returns:

  • (Boolean)


335
336
337
338
339
340
341
342
# File 'lib/atk/file_sys.rb', line 335

def self.size?(*args)
    if File.directory?(args[0])
        # recursively get the size of the folder
        return Dir.glob(File.join(args[0], '**', '*')).map{ |f| File.size(f) }.inject(:+)
    else
        File.size?(*args)
    end
end

.socket?(*args) ⇒ Boolean

Returns:

  • (Boolean)


345
346
347
# File 'lib/atk/file_sys.rb', line 345

def self.socket?(*args)
    File.socket?(*args)
end

.stat(*args) ⇒ Object



376
377
378
# File 'lib/atk/file_sys.rb', line 376

def self.stat(*args)
    File.stat(*args)
end

.symlink?(*args) ⇒ Boolean

Returns:

  • (Boolean)


315
316
317
# File 'lib/atk/file_sys.rb', line 315

def self.symlink?(*args)
    File.symlink?(*args)
end

.time_access(*args) ⇒ Object

File aliases



248
249
250
# File 'lib/atk/file_sys.rb', line 248

def self.time_access(*args)
    File.atime(*args)
end

.time_created(*args) ⇒ Object



251
252
253
# File 'lib/atk/file_sys.rb', line 251

def self.time_created(*args)
    File.birthtime(*args)
end

.time_modified(*args) ⇒ Object



254
255
# File 'lib/atk/file_sys.rb', line 254

def self.time_modified(*args)
end

.touch(*args) ⇒ Object



172
173
174
# File 'lib/atk/file_sys.rb', line 172

def self.touch(*args)
    return FileUtils.touch(*args)
end

.touch_dir(path) ⇒ Object



178
179
180
181
182
# File 'lib/atk/file_sys.rb', line 178

def self.touch_dir(path)
    if not FileSystem.directory?(path)
        FileUtils.makedirs(path)
    end
end

.usernameObject



111
112
113
114
115
116
117
# File 'lib/atk/file_sys.rb', line 111

def self.username
    if OS.is?(:windows)
        return File.basename(ENV["userprofile"])
    else
        return Etc.getlogin
    end
end

.world_readable?(*args) ⇒ Boolean

Returns:

  • (Boolean)


350
351
352
# File 'lib/atk/file_sys.rb', line 350

def self.world_readable?(*args)
    File.world_readable?(*args)
end

.world_writable?(*args) ⇒ Boolean

Returns:

  • (Boolean)


355
356
357
# File 'lib/atk/file_sys.rb', line 355

def self.world_writable?(*args)
    File.world_writable?(*args)
end

.writable?(*args) ⇒ Boolean

Returns:

  • (Boolean)


360
361
362
# File 'lib/atk/file_sys.rb', line 360

def self.writable?(*args)
    File.writable?(*args)
end

.writable_real?(*args) ⇒ Boolean

Returns:

  • (Boolean)


365
366
367
# File 'lib/atk/file_sys.rb', line 365

def self.writable_real?(*args)
    File.writable_real?(*args)
end

.write(data, to: nil) ⇒ Object

change_owner set_permissions relative_path_between relative_path_to add a force: true option to most of the commands



41
42
43
44
45
46
# File 'lib/atk/file_sys.rb', line 41

def self.write(data, to:nil)
    # make sure the containing folder exists
    FileSystem.makedirs(File.dirname(to))
    # actually download the file
    IO.write(to, data)
end