run_loop_tcc 2.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/bin/run-loop +19 -0
  4. data/lib/run_loop/abstract.rb +18 -0
  5. data/lib/run_loop/app.rb +372 -0
  6. data/lib/run_loop/cache/cache.rb +68 -0
  7. data/lib/run_loop/cli/cli.rb +48 -0
  8. data/lib/run_loop/cli/codesign.rb +24 -0
  9. data/lib/run_loop/cli/errors.rb +11 -0
  10. data/lib/run_loop/cli/instruments.rb +160 -0
  11. data/lib/run_loop/cli/locale.rb +31 -0
  12. data/lib/run_loop/cli/simctl.rb +257 -0
  13. data/lib/run_loop/cli/tcc.rb +139 -0
  14. data/lib/run_loop/codesign.rb +76 -0
  15. data/lib/run_loop/core.rb +902 -0
  16. data/lib/run_loop/core_simulator.rb +960 -0
  17. data/lib/run_loop/detect_aut/detect.rb +185 -0
  18. data/lib/run_loop/detect_aut/errors.rb +126 -0
  19. data/lib/run_loop/detect_aut/xamarin_studio.rb +46 -0
  20. data/lib/run_loop/detect_aut/xcode.rb +157 -0
  21. data/lib/run_loop/device.rb +722 -0
  22. data/lib/run_loop/device_agent/app/CBX-Runner.app.zip +0 -0
  23. data/lib/run_loop/device_agent/bin/xctestctl +0 -0
  24. data/lib/run_loop/device_agent/cbxrunner.rb +156 -0
  25. data/lib/run_loop/device_agent/frameworks/Frameworks.zip +0 -0
  26. data/lib/run_loop/device_agent/frameworks.rb +65 -0
  27. data/lib/run_loop/device_agent/ipa/CBX-Runner.app.zip +0 -0
  28. data/lib/run_loop/device_agent/launcher.rb +51 -0
  29. data/lib/run_loop/device_agent/xcodebuild.rb +91 -0
  30. data/lib/run_loop/device_agent/xctestctl.rb +109 -0
  31. data/lib/run_loop/directory.rb +179 -0
  32. data/lib/run_loop/dnssd.rb +148 -0
  33. data/lib/run_loop/dot_dir.rb +87 -0
  34. data/lib/run_loop/dylib_injector.rb +145 -0
  35. data/lib/run_loop/encoding.rb +56 -0
  36. data/lib/run_loop/environment.rb +361 -0
  37. data/lib/run_loop/fifo.rb +40 -0
  38. data/lib/run_loop/host_cache.rb +128 -0
  39. data/lib/run_loop/http/error.rb +15 -0
  40. data/lib/run_loop/http/request.rb +44 -0
  41. data/lib/run_loop/http/retriable_client.rb +166 -0
  42. data/lib/run_loop/http/server.rb +17 -0
  43. data/lib/run_loop/instruments.rb +436 -0
  44. data/lib/run_loop/ipa.rb +142 -0
  45. data/lib/run_loop/l10n.rb +93 -0
  46. data/lib/run_loop/language.rb +63 -0
  47. data/lib/run_loop/lipo.rb +132 -0
  48. data/lib/run_loop/lldb.rb +52 -0
  49. data/lib/run_loop/locale.rb +101 -0
  50. data/lib/run_loop/logging.rb +111 -0
  51. data/lib/run_loop/otool.rb +76 -0
  52. data/lib/run_loop/patches/awesome_print.rb +17 -0
  53. data/lib/run_loop/physical_device/life_cycle.rb +268 -0
  54. data/lib/run_loop/plist_buddy.rb +189 -0
  55. data/lib/run_loop/process_terminator.rb +128 -0
  56. data/lib/run_loop/process_waiter.rb +117 -0
  57. data/lib/run_loop/regex.rb +19 -0
  58. data/lib/run_loop/shell.rb +103 -0
  59. data/lib/run_loop/sim_control.rb +1264 -0
  60. data/lib/run_loop/simctl.rb +275 -0
  61. data/lib/run_loop/sqlite.rb +61 -0
  62. data/lib/run_loop/strings.rb +88 -0
  63. data/lib/run_loop/tcc/TCC.db +0 -0
  64. data/lib/run_loop/tcc/tcc.rb +240 -0
  65. data/lib/run_loop/template.rb +61 -0
  66. data/lib/run_loop/version.rb +182 -0
  67. data/lib/run_loop/xcode.rb +318 -0
  68. data/lib/run_loop/xcrun.rb +107 -0
  69. data/lib/run_loop/xcuitest.rb +550 -0
  70. data/lib/run_loop.rb +230 -0
  71. data/plists/simctl/com.apple.UIAutomation.plist +0 -0
  72. data/plists/simctl/com.apple.UIAutomationPlugIn.plist +0 -0
  73. data/scripts/calabash_script_uia.js +28184 -0
  74. data/scripts/lib/json2.min.js +26 -0
  75. data/scripts/lib/log.js +26 -0
  76. data/scripts/lib/on_alert.js +224 -0
  77. data/scripts/read-cmd.sh +2 -0
  78. data/scripts/run_dismiss_location.js +89 -0
  79. data/scripts/run_loop_basic.js +34 -0
  80. data/scripts/run_loop_fast_uia.js +188 -0
  81. data/scripts/run_loop_host.js +117 -0
  82. data/scripts/run_loop_shared_element.js +125 -0
  83. data/scripts/timeout3 +23 -0
  84. data/scripts/udidetect +0 -0
  85. data/vendor-licenses/FBSimulatorControl.LICENSE +30 -0
  86. data/vendor-licenses/xctestctl.LICENSE +32 -0
  87. metadata +443 -0
@@ -0,0 +1,156 @@
1
+
2
+ module RunLoop
3
+ # @!visibility private
4
+ module DeviceAgent
5
+ # @!visibility private
6
+ class CBXRunner
7
+
8
+
9
+ # @!visibility private
10
+ @@cbxdevice = nil
11
+
12
+ # @!visibility private
13
+ @@cbxsim = nil
14
+
15
+ # @!visibility private
16
+ def self.device_agent_dir
17
+ @@device_agent_dir ||= File.expand_path(File.dirname(__FILE__))
18
+ end
19
+
20
+ # @!visibility private
21
+ def self.detect_cbxsim
22
+ @@cbxsim ||= lambda do
23
+ from_env = RunLoop::Environment.cbxsim
24
+
25
+ if from_env
26
+ if File.exist?(from_env)
27
+ from_env
28
+ else
29
+ raise RuntimeError, %Q[
30
+ CBXSIM environment variable defined:
31
+
32
+ #{from_env}
33
+
34
+ but runner does not exist at that path.
35
+ ]
36
+ end
37
+ else
38
+ self.default_cbxsim
39
+ end
40
+ end.call
41
+ end
42
+
43
+ # @!visibility private
44
+ def self.detect_cbxdevice
45
+ @@cbxdevice ||= lambda do
46
+ from_env = RunLoop::Environment.cbxdevice
47
+
48
+ if from_env
49
+ if File.exist?(from_env)
50
+ from_env
51
+ else
52
+ raise RuntimeError, %Q[
53
+ CBXDEVICE environment variable defined:
54
+
55
+ #{from_env}
56
+
57
+ but runner does not exist at that path.
58
+ ]
59
+ end
60
+ else
61
+ self.default_cbxdevice
62
+ end
63
+ end.call
64
+ end
65
+
66
+ # @!visibility private
67
+ def self.default_cbxdevice
68
+ cbx = File.join(self.device_agent_dir, "ipa", "CBX-Runner.app")
69
+
70
+ if !File.exist?(cbx)
71
+ self.expand_runner_archive("#{cbx}.zip")
72
+ else
73
+ cbx
74
+ end
75
+ end
76
+
77
+ # @!visibility private
78
+ def self.default_cbxsim
79
+ cbx = File.join(self.device_agent_dir, "app", "CBX-Runner.app")
80
+
81
+ if !File.exist?(cbx)
82
+ self.expand_runner_archive("#{cbx}.zip")
83
+ else
84
+ cbx
85
+ end
86
+ end
87
+
88
+ # @!visibility private
89
+ # TODO move this behavior to shell.rb - should be able to call Shell.run_unix_command
90
+ def self.expand_runner_archive(archive)
91
+ shell = Class.new do
92
+ require "run_loop/shell"
93
+ include RunLoop::Shell
94
+ def to_s; "#<CBXRunner Shell>"; end
95
+ def inspect; to_s; end
96
+ end.new
97
+
98
+ dir = File.dirname(archive)
99
+ options = { :log_cmd => true }
100
+ Dir.chdir(dir) do
101
+ RunLoop.log_unix_cmd("cd #{dir}")
102
+ shell.run_unix_command(["unzip", File.basename(archive)], options)
103
+ end
104
+ File.join(dir, "CBX-Runner.app")
105
+ end
106
+
107
+ # @!visibility private
108
+ attr_reader :device
109
+
110
+ # @!visibility private
111
+ # @param [RunLoop::Device] device the target device
112
+ def initialize(device)
113
+ @device = device
114
+ end
115
+
116
+ # @!visibility private
117
+ def runner
118
+ @runner ||= lambda do
119
+ if device.physical_device?
120
+ RunLoop::DeviceAgent::CBXRunner.detect_cbxdevice
121
+ else
122
+ RunLoop::DeviceAgent::CBXRunner.detect_cbxsim
123
+ end
124
+ end.call
125
+ end
126
+
127
+ # @!visibility private
128
+ def tester
129
+ @tester ||= File.join(runner, "PlugIns", "CBX.xctest")
130
+ end
131
+
132
+ # @!visibility private
133
+ def version
134
+ @version ||= lambda do
135
+ short = pbuddy.plist_read("CFBundleShortVersionString", info_plist)
136
+ build = pbuddy.plist_read("CFBundleVersion", info_plist)
137
+ str = "#{short}.pre#{build}"
138
+ RunLoop::Version.new(str)
139
+ end.call
140
+ end
141
+
142
+ private
143
+
144
+ # @!visibility private
145
+ def info_plist
146
+ @info_plist ||= File.join(runner, "PlugIns", "CBX.xctest", "Info.plist")
147
+ end
148
+
149
+ # @!visibility private
150
+ def pbuddy
151
+ @pbuddy ||= RunLoop::PlistBuddy.new
152
+ end
153
+ end
154
+ end
155
+ end
156
+
@@ -0,0 +1,65 @@
1
+
2
+ module RunLoop
3
+ # @!visibility private
4
+ module DeviceAgent
5
+ # @!visibility private
6
+ class Frameworks
7
+ require "singleton"
8
+ include Singleton
9
+
10
+ # @!visibility private
11
+ def install
12
+ if File.exist?(frameworks)
13
+ RunLoop.log_debug("#{frameworks} already exists; skipping install")
14
+ return true
15
+ end
16
+
17
+ RunLoop.log_debug("Installing Frameworks to #{target}")
18
+
19
+ options = { :log_cmd => true }
20
+
21
+ Dir.chdir(rootdir) do
22
+ RunLoop.log_unix_cmd("cd #{rootdir}")
23
+ shell.run_shell_command(["unzip", File.basename(zip)], options)
24
+ end
25
+
26
+ shell.run_shell_command(["cp", "-r", "#{frameworks}/*.framework", target], options)
27
+ shell.run_shell_command(["cp", "#{frameworks}/*LICENSE", target], options)
28
+ RunLoop.log_debug("Installed frameworks to #{target}")
29
+ end
30
+
31
+ private
32
+
33
+ # @!visibility private
34
+ # TODO replace with include Shell
35
+ def shell
36
+ require "run_loop/shell"
37
+ Class.new do
38
+ include RunLoop::Shell
39
+ def to_s; "#<Frameworks Shell>"; end
40
+ def inspect; to_s; end
41
+ end.new
42
+ end
43
+
44
+ # @!visibility private
45
+ def target
46
+ @target ||= File.join(RunLoop::DotDir.directory, "Frameworks")
47
+ end
48
+
49
+ # @!visibility private
50
+ def frameworks
51
+ @frameworks ||= File.join(rootdir, "Frameworks")
52
+ end
53
+
54
+ # @!visibility private
55
+ def zip
56
+ @zip ||= File.join(rootdir, "Frameworks.zip")
57
+ end
58
+
59
+ # @!visibility private
60
+ def rootdir
61
+ @rootdir ||= File.expand_path(File.join(File.dirname(__FILE__), "frameworks"))
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,51 @@
1
+
2
+ module RunLoop
3
+ # @!visibility private
4
+ module DeviceAgent
5
+ # @!visibility private
6
+ #
7
+ # An abstract base class for something that can launch the CBXRunner on a
8
+ # device. The CBXRunner is AKA the DeviceAgent.
9
+ class Launcher
10
+ require "run_loop/abstract"
11
+ include RunLoop::Abstract
12
+
13
+ # @!visibility private
14
+ attr_reader :device
15
+
16
+ # @!visibility private
17
+ # @param [RunLoop::Device] device where to launch the CBX-Runner
18
+ def initialize(device)
19
+ @device = device
20
+
21
+ if device.version < RunLoop::Version.new("9.0")
22
+ raise ArgumentError, %Q[
23
+ Invalid device:
24
+
25
+ #{device}
26
+
27
+ XCUITest is only available for iOS >= 9.0
28
+ ]
29
+ end
30
+ end
31
+
32
+ # @!visibility private
33
+ #
34
+ # Does whatever it takes to launch the CBX-Runner on the device.
35
+ def launch
36
+ abstract_method!
37
+ end
38
+
39
+ # @!visibility private
40
+ def self.dot_dir
41
+ path = File.join(RunLoop::DotDir.directory, "xcuitest")
42
+
43
+ if !File.exist?(path)
44
+ FileUtils.mkdir_p(path)
45
+ end
46
+
47
+ path
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,91 @@
1
+
2
+ module RunLoop
3
+
4
+ # @!visibility private
5
+ module DeviceAgent
6
+
7
+ # @!visibility private
8
+ class Xcodebuild < RunLoop::DeviceAgent::Launcher
9
+
10
+ # @!visibility private
11
+ def self.log_file
12
+ path = File.join(Xcodebuild.dot_dir, "xcodebuild.log")
13
+ FileUtils.touch(path) if !File.exist?(path)
14
+ path
15
+ end
16
+
17
+ # @!visibility private
18
+ def to_s
19
+ "#<Xcodebuild #{workspace}>"
20
+ end
21
+
22
+ # @!visibility private
23
+ def inspect
24
+ to_s
25
+ end
26
+
27
+ # @!visibility private
28
+ def launch
29
+ workspace
30
+
31
+ if device.simulator?
32
+ # quits the simulator
33
+ sim = CoreSimulator.new(device, "")
34
+ sim.launch_simulator
35
+ end
36
+
37
+ start = Time.now
38
+ RunLoop.log_debug("Waiting for CBX-Runner to build...")
39
+ pid = xcodebuild
40
+ RunLoop.log_debug("Took #{Time.now - start} seconds to build and launch CBX-Runner")
41
+ pid
42
+ end
43
+
44
+ # @!visibility private
45
+ def workspace
46
+ @workspace ||= lambda do
47
+ path = RunLoop::Environment.send(:cbxws)
48
+ if path
49
+ path
50
+ else
51
+ raise "The CBXWS env var is undefined. Are you a maintainer?"
52
+ end
53
+ end.call
54
+ end
55
+
56
+ # @!visibility private
57
+ def xcodebuild
58
+ env = {
59
+ "COMMAND_LINE_BUILD" => "1"
60
+ }
61
+
62
+ args = [
63
+ "xcrun",
64
+ "xcodebuild",
65
+ "-scheme", "CBXAppStub",
66
+ "-workspace", workspace,
67
+ "-config", "Debug",
68
+ "-destination",
69
+ "id=#{device.udid}",
70
+ "clean",
71
+ "test"
72
+ ]
73
+
74
+ log_file = Xcodebuild.log_file
75
+
76
+ options = {
77
+ :out => log_file,
78
+ :err => log_file
79
+ }
80
+
81
+ command = "#{env.map.each { |k, v| "#{k}=#{v}" }.join(" ")} #{args.join(" ")}"
82
+ RunLoop.log_unix_cmd("#{command} >& #{log_file}")
83
+
84
+ pid = Process.spawn(env, *args, options)
85
+ Process.detach(pid)
86
+ pid.to_i
87
+ end
88
+ end
89
+ end
90
+ end
91
+
@@ -0,0 +1,109 @@
1
+
2
+ module RunLoop
3
+ # @!visibility private
4
+ module DeviceAgent
5
+ # @!visibility private
6
+ #
7
+ # A wrapper around the test-control binary.
8
+ class XCTestctl < RunLoop::DeviceAgent::Launcher
9
+
10
+ # @!visibility private
11
+ @@xctestctl = nil
12
+
13
+ # @!visibility private
14
+ def self.device_agent_dir
15
+ @@device_agent_dir ||= File.expand_path(File.dirname(__FILE__))
16
+ end
17
+
18
+ # @!visibility private
19
+ def self.xctestctl
20
+ @@xctestctl ||= lambda do
21
+ from_env = RunLoop::Environment.xctestctl
22
+ if from_env
23
+ if File.exist?(from_env)
24
+ RunLoop.log_debug("Using XCTESTCTL=#{from_env}")
25
+ from_env
26
+ else
27
+ raise RuntimeError, %Q[
28
+ XCTESTCTL environment variable defined:
29
+
30
+ #{from_env}
31
+
32
+ but binary does not exist at that path.
33
+ ]
34
+ end
35
+
36
+ else
37
+ File.join(self.device_agent_dir, "bin", "xctestctl")
38
+ end
39
+ end.call
40
+ end
41
+
42
+ # @!visibility private
43
+ def to_s
44
+ "#<Testctl: #{XCTestctl.xctestctl}>"
45
+ end
46
+
47
+ # @!visibility private
48
+ def inspect
49
+ to_s
50
+ end
51
+
52
+ # @!visibility private
53
+ def runner
54
+ @runner ||= RunLoop::DeviceAgent::CBXRunner.new(device)
55
+ end
56
+
57
+ # @!visibility private
58
+ def self.log_file
59
+ path = File.join(Launcher.dot_dir, "xctestctl.log")
60
+ FileUtils.touch(path) if !File.exist?(path)
61
+ path
62
+ end
63
+
64
+ # @!visibility private
65
+ def launch
66
+ RunLoop::DeviceAgent::Frameworks.instance.install
67
+
68
+ if device.simulator?
69
+ cbxapp = RunLoop::App.new(runner.runner)
70
+
71
+ # quits the simulator
72
+ sim = CoreSimulator.new(device, cbxapp)
73
+ sim.install
74
+ end
75
+
76
+ cmd = RunLoop::DeviceAgent::XCTestctl.xctestctl
77
+
78
+ args = ["-r", runner.runner,
79
+ "-t", runner.tester,
80
+ "-d", device.udid]
81
+
82
+ if device.physical_device?
83
+ args << "-c"
84
+ args << RunLoop::Environment.codesign_identity
85
+ end
86
+
87
+ log_file = XCTestctl.log_file
88
+ FileUtils.rm_rf(log_file)
89
+ FileUtils.touch(log_file)
90
+
91
+ options = {:out => log_file, :err => log_file}
92
+ RunLoop.log_unix_cmd("#{cmd} #{args.join(" ")} >& #{log_file}")
93
+
94
+ # Gotta keep the xctestctl process alive or the connection
95
+ # to testmanagerd will fail.
96
+ pid = Process.spawn(cmd, *args, options)
97
+ Process.detach(pid)
98
+
99
+ if device.simulator?
100
+ device.simulator_wait_for_stable_state
101
+ end
102
+
103
+ pid.to_i
104
+ end
105
+ end
106
+ end
107
+ end
108
+
109
+
@@ -0,0 +1,179 @@
1
+ module RunLoop
2
+
3
+ # Class for performing operations on directories.
4
+ class Directory
5
+ require 'digest'
6
+ require 'openssl'
7
+ require 'pathname'
8
+
9
+ # Dir.glob ignores files that start with '.', but we often need to find
10
+ # dotted files and directories.
11
+ #
12
+ # Ruby 2.* does the right thing by ignoring '..' and '.'.
13
+ #
14
+ # Ruby < 2.0 includes '..' and '.' in results which causes problems for some
15
+ # of run-loop's internal methods. In particular `reset_app_sandbox`.
16
+ def self.recursive_glob_for_entries(base_dir)
17
+ Dir.glob("#{base_dir}/{**/.*,**/*}").select do |entry|
18
+ !(entry.end_with?('..') || entry.end_with?('.'))
19
+ end
20
+ end
21
+
22
+ # Computes the digest of directory.
23
+ #
24
+ # @param path A path to a directory.
25
+ # @param options Control the behavior of the method.
26
+ # @option options :handle_errors_by (:raising) Controls what to do when
27
+ # File.read causes an error. The default behavior is to raise. Other
28
+ # options are: :logging and :ignoring. Logging will only happen if
29
+ # running in debug mode.
30
+ #
31
+ # @raise ArgumentError When `path` is not a directory or path does not exist.
32
+ # @raise ArgumentError When options[:handle_errors_by] has n unsupported value.
33
+ def self.directory_digest(path, options={})
34
+ default_options = {
35
+ :handle_errors_by => :raising
36
+ }
37
+
38
+ merged_options = default_options.merge(options)
39
+ handle_errors_by = merged_options[:handle_errors_by]
40
+ unless [:raising, :logging, :ignoring].include?(handle_errors_by)
41
+ raise ArgumentError,
42
+ %Q{Expected :handle_errors_by to be :raising, :logging, or :ignoring;
43
+ found '#{handle_errors_by}'
44
+ }
45
+ end
46
+
47
+ unless File.exist?(path)
48
+ raise ArgumentError, "Expected '#{path}' to exist"
49
+ end
50
+
51
+ unless File.directory?(path)
52
+ raise ArgumentError, "Expected '#{path}' to be a directory"
53
+ end
54
+
55
+ entries = self.recursive_glob_for_entries(path)
56
+
57
+ if entries.empty?
58
+ raise ArgumentError, "Expected a non-empty dir at '#{path}' found '#{entries}'"
59
+ end
60
+
61
+ debug = RunLoop::Environment.debug?
62
+
63
+ sha = OpenSSL::Digest::SHA256.new
64
+ entries.each do |file|
65
+ unless self.skip_file?(file, 'SHA1', debug)
66
+ begin
67
+ sha << File.read(file)
68
+ rescue => e
69
+ case handle_errors_by
70
+ when :logging
71
+ message =
72
+ %Q{RunLoop::Directory.directory_digest raised an error:
73
+
74
+ #{e}
75
+
76
+ while trying to find the SHA of this file:
77
+
78
+ #{file}
79
+
80
+ This is not a fatal error; it can be ignored.
81
+ }
82
+ RunLoop.log_debug(message)
83
+ when :raising
84
+ raise e.class, e.message
85
+ when :ignoring
86
+ # nop
87
+ else
88
+ # nop
89
+ end
90
+ end
91
+ end
92
+ end
93
+ sha.hexdigest
94
+ end
95
+
96
+ def self.size(path, format)
97
+
98
+ allowed_formats = [:bytes, :kb, :mb, :gb]
99
+ unless allowed_formats.include?(format)
100
+ raise ArgumentError, "Expected '#{format}' to be one of #{allowed_formats.join(', ')}"
101
+ end
102
+
103
+ unless File.exist?(path)
104
+ raise ArgumentError, "Expected '#{path}' to exist"
105
+ end
106
+
107
+ unless File.directory?(path)
108
+ raise ArgumentError, "Expected '#{path}' to be a directory"
109
+ end
110
+
111
+ entries = self.recursive_glob_for_entries(path)
112
+
113
+ if entries.empty?
114
+ raise ArgumentError, "Expected a non-empty dir at '#{path}' found '#{entries}'"
115
+ end
116
+
117
+ size = self.iterate_for_size(entries)
118
+
119
+ case format
120
+ when :bytes
121
+ size
122
+ when :kb
123
+ size/1000.0
124
+ when :mb
125
+ size/1000.0/1000.0
126
+ when :gb
127
+ size/1000.0/1000.0/1000.0
128
+ else
129
+ # Not expected to reach this.
130
+ size
131
+ end
132
+ end
133
+
134
+ private
135
+
136
+ def self.skip_file?(file, task, debug)
137
+ skip = false
138
+ if File.directory?(file)
139
+ # Skip directories
140
+ skip = true
141
+ elsif !Pathname.new(file).exist?
142
+ # Skip broken symlinks
143
+ skip = true
144
+ elsif !File.exist?(file)
145
+ # Skip files that don't exist
146
+ skip = true
147
+ else
148
+ case File.ftype(file)
149
+ when 'fifo'
150
+ RunLoop.log_warn("#{task} IS SKIPPING FIFO #{file}") if debug
151
+ skip = true
152
+ when 'socket'
153
+ RunLoop.log_warn("#{task} IS SKIPPING SOCKET #{file}") if debug
154
+ skip = true
155
+ when 'characterSpecial'
156
+ RunLoop.log_warn("#{task} IS SKIPPING CHAR SPECIAL #{file}") if debug
157
+ skip = true
158
+ when 'blockSpecial'
159
+ skip = true
160
+ RunLoop.log_warn("#{task} SKIPPING BLOCK SPECIAL #{file}") if debug
161
+ else
162
+
163
+ end
164
+ end
165
+ skip
166
+ end
167
+
168
+ def self.iterate_for_size(entries)
169
+ debug = RunLoop::Environment.debug?
170
+ size = 0
171
+ entries.each do |file|
172
+ unless self.skip_file?(file, "SIZE", debug)
173
+ size = size + File.size(file)
174
+ end
175
+ end
176
+ size
177
+ end
178
+ end
179
+ end