Module: Scripto::FileCommands

Included in:
Scripto, Main
Defined in:
lib/scripto/file_commands.rb

Instance Method Summary collapse

Instance Method Details

#atomic_write(path) ⇒ Object

Atomically write to path. An open temp file is yielded.



133
134
135
136
137
138
139
140
141
# File 'lib/scripto/file_commands.rb', line 133

def atomic_write(path)
  tmp = Tempfile.new(File.basename(path))
  yield(tmp)
  tmp.close
  chmod(tmp.path, 0o644)
  mv(tmp.path, path)
ensure
  rm_if_necessary(tmp.path)
end

#chmod(file, mode) ⇒ Object

Like chmod mode file. Like all file commands, the operation will be printed out if verbose?.



109
110
111
112
113
# File 'lib/scripto/file_commands.rb', line 109

def chmod(file, mode)
  return if File.stat(file).mode == mode

  FileUtils.chmod(mode, file, verbose: verbose?)
end

#chown(file, user) ⇒ Object

Like chown user:user file. Like all file commands, the operation will be printed out if verbose?.



97
98
99
100
101
102
103
104
105
# File 'lib/scripto/file_commands.rb', line 97

def chown(file, user)
  # who is the current owner?
  @scripto_uids ||= {}
  @scripto_uids[user] ||= Etc.getpwnam(user).uid
  uid = @scripto_uids[user]
  return if File.stat(file).uid == uid

  FileUtils.chown(uid, uid, file, verbose: verbose?)
end

#copy_metadata(src, dst) ⇒ Object

Copy mode, atime and mtime from src to dst. This one is rarely used and doesn’t echo.



126
127
128
129
130
# File 'lib/scripto/file_commands.rb', line 126

def (src, dst)
  stat = File.stat(src)
  File.chmod(stat.mode, dst)
  File.utime(stat.atime, stat.mtime, dst)
end

#cp(src, dst, mkdir: false, owner: nil, mode: nil) ⇒ Object

Like cp -pr src +dst. If mkdir is true, the dst directoy will be created if necessary before the copy. If owner is specified, the directory will be chowned to owner. If mode is specified, the directory will be chmodded to mode. Like all file commands, the operation will be printed out if verbose?.



21
22
23
24
25
26
# File 'lib/scripto/file_commands.rb', line 21

def cp(src, dst, mkdir: false, owner: nil, mode: nil)
  mkdir_if_necessary(File.dirname(dst)) if mkdir
  FileUtils.cp_r(src, dst, preserve: true, verbose: verbose?)
  chown(dst, owner) if owner && !File.symlink?(dst)
  chmod(dst, mode) if mode
end

#cp_if_necessary(src, dst, mkdir: false, owner: nil, mode: nil) ⇒ Object

Runs #cp, but ONLY if dst doesn’t exist or differs from src. Returns true if the file had to be copied. This is useful with verbose?, to get an exact changelog.



65
66
67
68
69
70
# File 'lib/scripto/file_commands.rb', line 65

def cp_if_necessary(src, dst, mkdir: false, owner: nil, mode: nil)
  return if File.exist?(dst) && FileUtils.compare_file(src, dst)

  cp(src, dst, mkdir: mkdir, owner: owner, mode: mode)
  true
end

#ln(src, dst) ⇒ Object

Like ln -sf src +dst. The command will be printed out if verbose?.



38
39
40
41
42
43
44
# File 'lib/scripto/file_commands.rb', line 38

def ln(src, dst)
  FileUtils.ln_sf(src, dst, verbose: verbose?)
rescue Errno::EEXIST => e
  # It's a race - this can occur because ln_sf removes the old
  # dst, then creates the symlink. Raise if they don't match.
  raise e if !(File.symlink?(dst) && src == File.readlink(dst))
end

#ln_if_necessary(src, dst) ⇒ Object

Runs #ln, but ONLY if dst isn’t a symlink or differs from src. Returns true if the file had to be symlinked. This is useful with verbose?, to get an exact changelog.



75
76
77
78
79
80
81
82
83
84
# File 'lib/scripto/file_commands.rb', line 75

def ln_if_necessary(src, dst)
  if File.symlink?(dst)
    return if src == File.readlink(dst)

    rm(dst)
  end

  ln(src, dst)
  true
end

#mkdir(dir, owner: nil, mode: nil) ⇒ Object

Like mkdir -p dir. If owner is specified, the directory will be chowned to owner. If mode is specified, the directory will be chmodded to mode. Like all file commands, the operation will be printed out if verbose?.



10
11
12
13
14
# File 'lib/scripto/file_commands.rb', line 10

def mkdir(dir, owner: nil, mode: nil)
  FileUtils.mkdir_p(dir, verbose: verbose?)
  chown(dir, owner) if owner
  chmod(dir, mode) if mode
end

#mkdir_if_necessary(dir, owner: nil, mode: nil) ⇒ Object

Runs #mkdir, but ONLY if dir doesn’t already exist. Returns true if directory had to be created. This is useful with verbose?, to get an exact changelog.



55
56
57
58
59
60
# File 'lib/scripto/file_commands.rb', line 55

def mkdir_if_necessary(dir, owner: nil, mode: nil)
  return if File.exist?(dir) || File.symlink?(dir)

  mkdir(dir, owner: owner, mode: mode)
  true
end

#mv(src, dst, mkdir: false) ⇒ Object

Like mv src +dst. If mkdir is true, the dst directoy will be created if necessary before the copy. Like all file commands, the operation will be printed out if verbose?.



31
32
33
34
# File 'lib/scripto/file_commands.rb', line 31

def mv(src, dst, mkdir: false)
  mkdir_if_necessary(File.dirname(dst)) if mkdir
  FileUtils.mv(src, dst, verbose: verbose?)
end

#rm(file) ⇒ Object

Like rm -f file. Like all file commands, the operation will be printed out if verbose?.



48
49
50
# File 'lib/scripto/file_commands.rb', line 48

def rm(file)
  FileUtils.rm_f(file, verbose: verbose?)
end

#rm_and_mkdir(dir) ⇒ Object

Like rm -rf && mkdir -p. Like all file commands, the operation will be printed out if verbose?.



117
118
119
120
121
122
# File 'lib/scripto/file_commands.rb', line 117

def rm_and_mkdir(dir)
  raise "don't do this" if dir == ''

  FileUtils.rm_rf(dir, verbose: verbose?)
  mkdir(dir)
end

#rm_if_necessary(file) ⇒ Object

Runs #rm, but ONLY if file exists. Return true if the file had to be removed. This is useful with verbose?, to get an exact changelog.



88
89
90
91
92
93
# File 'lib/scripto/file_commands.rb', line 88

def rm_if_necessary(file)
  return if !File.exist?(file)

  rm(file)
  true
end