module Autoproj::Ops
Public Class Methods
Source
# File lib/autoproj/ops/atomic_write.rb, line 25 def self.atomic_write(file_name, temp_dir = File.dirname(file_name)) Tempfile.open(".#{File.basename(file_name)}", temp_dir) do |temp_file| temp_file.binmode yield temp_file temp_file.close old_stat = begin # Get original file permissions File.stat(file_name) rescue Errno::ENOENT # If not possible, probe which are the default permissions in the # destination directory. probe_stat_in(File.dirname(file_name)) end if old_stat # Set correct permissions on new file begin File.chown(old_stat.uid, old_stat.gid, temp_file.path) # This operation will affect filesystem ACL's File.chmod(old_stat.mode, temp_file.path) rescue Errno::EPERM, Errno::EACCES # Changing file ownership failed, moving on. end end # Overwrite original file with temp file File.rename(temp_file.path, file_name) end end
Write to a file atomically. Useful for situations where you don’t want other processes or threads to see half-written files.
File.atomic_write('important.file') do |file| file.write('hello') end
This method needs to create a temporary file. By default it will create it in the same directory as the destination file. If you don’t like this behavior you can provide a different directory but it must be on the same physical filesystem as the file you’re trying to write.
File.atomic_write('/data/something.important', '/data/tmp') do |file| file.write('hello') end
Shamelessly stolen from ActiveSupport
Source
# File lib/autoproj/ops/cached_env.rb, line 5 def self.cached_env_path(root_dir) File.join(root_dir, ".autoproj", "env.yml") end
Source
# File lib/autoproj/ops/cached_env.rb, line 9 def self.load_cached_env(root_dir) path = cached_env_path(root_dir) if File.file?(path) env = YAML.safe_load(File.read(path)) Autobuild::Environment::ExportedEnvironment.new( env["set"], env["unset"], env["update"] ) end end
Source
# File lib/autoproj/ops/loader.rb, line 107 def self.loader Autoproj.workspace end
@deprecated use Autoproj.workspace
, or better make sure all ops classes
get their own workspace object as argument
Source
# File lib/autoproj/ops/cached_env.rb, line 19 def self.save_cached_env(root_dir, env) env = env.exported_environment path = cached_env_path(root_dir) existing = begin YAML.safe_load(File.read(path)) rescue Exception end env = Hash["set" => env.set, "unset" => env.unset, "update" => env.update] if env != existing Ops.atomic_write(path) do |io| io.write YAML.dump(env) end true end end
Source
# File lib/autoproj/ops/watch.rb, line 32 def self.watch_cleanup_marker(io) FileUtils.rm_f io.path io.close end
Source
# File lib/autoproj/ops/watch.rb, line 18 def self.watch_create_marker(root_dir) io = File.open(watch_marker_path(root_dir), "a+") unless io.flock(File::LOCK_EX | File::LOCK_NB) raise WatchAlreadyRunning, "autoproj watch is already running as PID #{io.read.strip}" end io.truncate(0) io.puts Process.pid io.flush rescue Exception io&.close raise end
Source
# File lib/autoproj/ops/watch.rb, line 3 def self.watch_marker_path(root_dir) File.join(root_dir, ".autoproj", "watch") end
Source
# File lib/autoproj/ops/watch.rb, line 7 def self.watch_running?(root_dir) io = File.open(watch_marker_path(root_dir)) !io.flock(File::LOCK_EX | File::LOCK_NB) rescue Errno::ENOENT false ensure io&.close end
Source
# File lib/autoproj/ops/which.rb, line 19 def self.which(cmd, path_entries: nil) path = Pathname.new(cmd) if path.absolute? if path.file? && path.executable? cmd elsif path.exist? raise ExecutableNotFound.new(cmd), "given command `#{cmd}` exists but is not an executable file" else raise ExecutableNotFound.new(cmd), "given command `#{cmd}` does not exist, "\ "an executable file was expected" end else path_entries = path_entries.call if path_entries.respond_to?(:call) absolute = Autobuild::Environment.find_executable_in_path(cmd, path_entries) if absolute absolute elsif (file = Autobuild::Environment.find_in_path(cmd, path_entries)) raise ExecutableNotFound.new(cmd), "`#{cmd}` resolves to #{file} which is not executable" else raise ExecutableNotFound.new(cmd), "cannot resolve `#{cmd}` to an executable in the workspace" end end end
Find the given executable file in PATH
If ‘cmd` is an absolute path, it will either return it or raise if `cmd` is not executable. Otherwise, looks for an executable named `cmd` in PATH and returns it, or raises if it cannot be found. The exception contains a more detailed reason for failure
@param [String] cmd @return [String] the resolved program @raise [ExecutableNotFound] if an executable file named ‘cmd` cannot
be found