macos.rb 0.50.0

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 (70) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG +572 -0
  3. data/Gemfile +3 -0
  4. data/LICENSE +21 -0
  5. data/README.md +129 -0
  6. data/Rakefile +9 -0
  7. data/lib/Array/all_but_last.rb +7 -0
  8. data/lib/MacOS/Apple80211.rb +68 -0
  9. data/lib/MacOS/Applications.rb +73 -0
  10. data/lib/MacOS/Defaults/ComAppleDock.rb +153 -0
  11. data/lib/MacOS/Defaults/NSGlobalDomain/NSUserKeyEquivalents.rb +109 -0
  12. data/lib/MacOS/Defaults.rb +126 -0
  13. data/lib/MacOS/DiskUtil.rb +63 -0
  14. data/lib/MacOS/Dmg.rb +99 -0
  15. data/lib/MacOS/HardwarePort.rb +79 -0
  16. data/lib/MacOS/IfConfig.rb +183 -0
  17. data/lib/MacOS/Keychain.rb +26 -0
  18. data/lib/MacOS/LaunchControl.rb +36 -0
  19. data/lib/MacOS/SystemProfiler.rb +119 -0
  20. data/lib/MacOS/USBFlashDrive.rb +26 -0
  21. data/lib/MacOS/Users.rb +16 -0
  22. data/lib/MacOS/VERSION.rb +6 -0
  23. data/lib/MacOS/VPN.rb +13 -0
  24. data/lib/MacOS/Voice.rb +40 -0
  25. data/lib/MacOS.rb +27 -0
  26. data/lib/Module/alias_methods.rb +7 -0
  27. data/lib/Ordinal/Array.rb +8 -0
  28. data/lib/Ordinal.rb +157 -0
  29. data/lib/Thoran/Array/AllButLast/all_but_last.rb +28 -0
  30. data/lib/Thoran/Array/LastX/lastX.rb +33 -0
  31. data/lib/Thoran/Module/AliasMethods/alias_methods.rb +23 -0
  32. data/lib/Thoran/String/Capture/capture.rb +28 -0
  33. data/lib/Version.rb +381 -0
  34. data/macos.rb.gemspec +59 -0
  35. data/test/MacOS/Apple80211_test.rb +80 -0
  36. data/test/MacOS/Applications_test.rb +82 -0
  37. data/test/MacOS/Defaults/ComAppleDock_test.rb +66 -0
  38. data/test/MacOS/Defaults/NSGlobalDomain/NSUserKeyEquivalents_test.rb +67 -0
  39. data/test/MacOS/Defaults_test.rb +144 -0
  40. data/test/MacOS/DiskUtil_test.rb +48 -0
  41. data/test/MacOS/Dmg_test.rb +69 -0
  42. data/test/MacOS/HardwarePort_test.rb +46 -0
  43. data/test/MacOS/IfConfig_test.rb +144 -0
  44. data/test/MacOS/Keychain_test.rb +22 -0
  45. data/test/MacOS/LaunchControl_test.rb +40 -0
  46. data/test/MacOS/SystemProfiler_test.rb +69 -0
  47. data/test/MacOS/USBFlashDrive_test.rb +20 -0
  48. data/test/MacOS/Users_test.rb +10 -0
  49. data/test/MacOS/VPN_test.rb +18 -0
  50. data/test/MacOS/Voice_test.rb +46 -0
  51. data/test/MacOS_test.rb +17 -0
  52. data/test/VERSION_test.rb +19 -0
  53. data/test/commands_test.rb +50 -0
  54. data/test/fixtures/airport-I-deprecated.txt +2 -0
  55. data/test/fixtures/airport-I.txt +17 -0
  56. data/test/fixtures/defaults-domains.txt +1 -0
  57. data/test/fixtures/defaults-export-com.apple.dock.xml +47 -0
  58. data/test/fixtures/defaults-read-NSUserKeyEquivalents.txt +4 -0
  59. data/test/fixtures/df-k.txt +6 -0
  60. data/test/fixtures/diskutil-list-plist.xml +104 -0
  61. data/test/fixtures/dscl-list-users.txt +8 -0
  62. data/test/fixtures/ifconfig-a.txt +53 -0
  63. data/test/fixtures/networksetup-listallhardwareports.txt +39 -0
  64. data/test/fixtures/say-v.txt +8 -0
  65. data/test/fixtures/system_profiler-SPAirPortDataType.txt +44 -0
  66. data/test/fixtures/system_profiler-SPSoftwareDataType.txt +14 -0
  67. data/test/fixtures/system_profiler-SPUSBDataType.txt +58 -0
  68. data/test/gemspec_test.rb +50 -0
  69. data/test/helper.rb +18 -0
  70. metadata +183 -0
@@ -0,0 +1,63 @@
1
+ # MacOS/DiskUtil.rb
2
+ # MacOS::DiskUtil
3
+
4
+ require 'plist'
5
+
6
+ module MacOS
7
+ class DiskUtil
8
+
9
+ class << self
10
+ def xml_volume_plist
11
+ `diskutil list -plist`
12
+ end
13
+
14
+ def volume_plist
15
+ Plist.parse_xml(xml_volume_plist)
16
+ end
17
+
18
+ def volumes_and_partitions
19
+ volume_plist["AllDisksAndPartitions"].select do |dp|
20
+ !dp["Partitions"].empty?
21
+ end
22
+ end
23
+
24
+ def volume_partitions(volume)
25
+ volume["Partitions"]
26
+ end
27
+
28
+ def volumes
29
+ volumes_and_partitions.collect do |volume|
30
+ volume_partitions(volume).collect do |partition|
31
+ {
32
+ device_id: partition["DeviceIdentifier"],
33
+ mount_point: partition["MountPoint"],
34
+ name: partition["VolumeName"],
35
+ size: partition["Size"],
36
+ }
37
+ end
38
+ end.flatten.compact
39
+ end
40
+
41
+ def external_volumes
42
+ volumes.reject{|v| v[:mount_point].nil?}
43
+ end
44
+
45
+ def free_bytes_for_device_id(device_id)
46
+ `df -k`.split("\n").detect do |partition_data|
47
+ if partition_data.split.first.match(device_id)
48
+ return partition_data.split[3].to_i * 1024
49
+ end
50
+ end
51
+ end
52
+
53
+ def free_bytes_for_volume_name(volume_name)
54
+ `df -k`.split("\n").detect do |partition_data|
55
+ if partition_data.split.last.match(volume_name)
56
+ return partition_data.split[3].to_i * 1024
57
+ end
58
+ end
59
+ end
60
+ end # class << self
61
+
62
+ end
63
+ end
data/lib/MacOS/Dmg.rb ADDED
@@ -0,0 +1,99 @@
1
+ # MacOS/Dmg.rb
2
+ # MacOS::Dmg
3
+
4
+ # History: Extracted the methods from install_macports to be used in install_homebrew, but didn't finish this and just placed the methods (with some modification) directly into install_homebrew.
5
+
6
+ require 'shellwords'
7
+
8
+ module MacOS
9
+ class Dmg
10
+
11
+ class << self
12
+ attr_accessor :verbose
13
+
14
+ def mount(path_to_dmg)
15
+ puts "hdiutil attach #{Shellwords.escape(path_to_dmg)}" if verbose
16
+ system "hdiutil attach #{Shellwords.escape(path_to_dmg)}"
17
+ end
18
+ alias_method :attach, :mount
19
+
20
+ def run_installer(mount_point:, pkg_name:)
21
+ starting_working_directory = Dir.pwd
22
+ puts "cd #{full_path_to_mount_point(mount_point)}" if verbose
23
+ Dir.chdir(full_path_to_mount_point(mount_point))
24
+ puts "sudo installer -pkg #{Shellwords.escape(pkg_name)} -target '/'" if verbose
25
+ system "sudo installer -pkg #{Shellwords.escape(pkg_name)} -target '/'"
26
+ Dir.chdir(starting_working_directory)
27
+ end
28
+
29
+ def unmount(mount_point)
30
+ puts "hdiutil detach -Force #{Shellwords.escape(full_path_to_mount_point(mount_point))}" if verbose
31
+ system "hdiutil detach -Force #{Shellwords.escape(full_path_to_mount_point(mount_point))}"
32
+ end
33
+ alias_method :detach, :unmount
34
+
35
+ def install(path_to_dmg:, disk_image_name:, mount_point: nil, package: nil)
36
+ dmg = new(path_to_dmg: path_to_dmg, disk_image_name: disk_image_name, mount_point: mount_point, package: package)
37
+ dmg.mount
38
+ dmg.run_installer
39
+ dmg.unmount
40
+ end
41
+
42
+ private
43
+
44
+ def full_path_to_mount_point(mount_point)
45
+ File.join('/', 'Volumes', mount_point)
46
+ end
47
+ end # class << self
48
+
49
+ attr_accessor :disk_image_name
50
+ attr_accessor :package
51
+ attr_accessor :path_to_dmg
52
+
53
+ attr_writer :mount_point
54
+ attr_writer :pkg_name
55
+
56
+ def initialize(path_to_dmg:, disk_image_name: nil, mount_point: nil, package: nil)
57
+ @path_to_dmg = path_to_dmg
58
+ @disk_image_name = disk_image_name
59
+ @mount_point = mount_point
60
+ @package = package
61
+ end
62
+
63
+ alias_method :filename, :disk_image_name
64
+ alias_method :dmg_filename, :disk_image_name
65
+ alias_method :image_name, :disk_image_name
66
+ alias_method :filename=, :disk_image_name=
67
+ alias_method :dmg_filename=, :disk_image_name=
68
+ alias_method :image_name=, :disk_image_name=
69
+
70
+ def pkg_name
71
+ @pkg_name || (@package + '.pkg')
72
+ end
73
+
74
+ def mount_point
75
+ @mount_point || @disk_image_name.split('.').first
76
+ end
77
+
78
+ def mount
79
+ MacOS::Dmg.mount(@path_to_dmg)
80
+ end
81
+ alias_method :attach, :mount
82
+
83
+ def run_installer
84
+ MacOS::Dmg.run_installer(pkg_name: pkg_name, mount_point: mount_point)
85
+ end
86
+
87
+ def unmount
88
+ MacOS::Dmg.unmount(mount_point)
89
+ end
90
+ alias_method :detach, :unmount
91
+
92
+ def install
93
+ mount
94
+ run_installer
95
+ unmount
96
+ end
97
+
98
+ end
99
+ end
@@ -0,0 +1,79 @@
1
+ # MacOS/HardwarePort.rb
2
+ # MacOS::HardwarePort
3
+
4
+ module MacOS
5
+ class HardwarePort
6
+
7
+ class << self
8
+
9
+ def parse(output = nil)
10
+ output ||= self.output
11
+ hardware_ports = []
12
+ hardware_port = nil
13
+ output.each_line do |line|
14
+ # p line
15
+ if line == "\n" || line == ""
16
+ hardware_ports << hardware_port if hardware_port
17
+ hardware_port = new
18
+ else
19
+ label, value = line.match(/^(.+): (.+)/)&.captures
20
+ case label
21
+ when 'Hardware Port'; hardware_port.hardware_port = value
22
+ when 'Device'; hardware_port.device = value
23
+ when 'Ethernet Address'; hardware_port.ethernet_address = value
24
+ end
25
+ end
26
+ end
27
+ hardware_ports
28
+ end
29
+ alias_method :all, :parse
30
+ alias_method :hardware_ports, :parse
31
+ alias_method :ports, :parse
32
+
33
+ def find_by_interface(interface)
34
+ all.detect{|hardware_port| hardware_port.interface == interface}
35
+ end
36
+ alias_method :find_by_device, :find_by_interface
37
+
38
+ def find_by_name(name)
39
+ all.detect{|hardware_port| hardware_port.name == name}
40
+ end
41
+ alias_method :find_by_hardware_port, :find_by_name
42
+
43
+ def find_by_mac_address(mac_address)
44
+ all.detect{|hardware_port| hardware_port.ethernet_address == mac_address}
45
+ end
46
+ alias_method :find_by_ethernet_address, :find_by_mac_address
47
+
48
+ private
49
+
50
+ def output
51
+ `networksetup -listallhardwareports`
52
+ end
53
+
54
+ end # class << self
55
+
56
+ attr_accessor :hardware_port
57
+ attr_accessor :device
58
+ attr_accessor :ethernet_address
59
+
60
+ def initialize(hardware_port: nil, device: nil, ethernet_address: nil)
61
+ @hardware_port = hardware_port
62
+ @device = device
63
+ @ethernet_address = ethernet_address
64
+ end
65
+
66
+ def name
67
+ @hardware_port
68
+ end
69
+
70
+ def mac_address
71
+ @ethernet_address
72
+ end
73
+
74
+ def interface
75
+ @device
76
+ end
77
+
78
+ end
79
+ end
@@ -0,0 +1,183 @@
1
+ # MacOS/IfConfig.rb
2
+ # MacOS::IfConfig
3
+
4
+ module MacOS
5
+ class IfConfig
6
+ class << self
7
+ def parse(output = nil)
8
+ output ||= self.output
9
+ ifconfigs = []
10
+ ifconfig = nil
11
+ output.each_line do |line|
12
+ if line =~ /^\t/
13
+ case line
14
+ when /ether/
15
+ ifconfig.mac_address = line[/ *ether (.+?) ?$/, 1]
16
+ when /inet /
17
+ if line.match(/broadcast/)
18
+ ifconfig.ipv4_address, ifconfig.netmask, ifconfig.broadcast_address = line.match(/ *inet (\d+(?:\.\d+){3}) netmask (.+) broadcast (.+)$/)&.captures
19
+ elsif line.match(/-->/)
20
+ ipv4_address_from, ipv4_address_to, ifconfig.netmask = line.match(/inet (.+) --> (.+) netmask (.+)$/)&.captures
21
+ ifconfig.ipv4_address = ipv4_address_from
22
+ else
23
+ ifconfig.ipv4_address, ifconfig.netmask = line.match(/ *inet (\d+(?:\.\d+){3}) netmask (.+?) ?$/)&.captures
24
+ end
25
+ when /status\:/
26
+ ifconfig.status = line[/ *status: (.+)$/, 1]
27
+ end
28
+ else
29
+ ifconfigs << ifconfig if ifconfig
30
+ ifconfig = new
31
+ ifconfig.interface, rest_of_line = line.match(/^(.+?): (.+)$/)&.captures
32
+ if rest_of_line =~ /flags=\w+<([^>]+)>/
33
+ ifconfig.flags = $1.split(',')
34
+ end
35
+ end
36
+ end
37
+ ifconfigs << ifconfig if ifconfig
38
+ ifconfigs
39
+ end
40
+ alias_method :all, :parse
41
+ alias_method :interfaces, :parse
42
+ alias_method :all_interfaces, :parse
43
+
44
+ def interface_names
45
+ all.collect(&:interface_name)
46
+ end
47
+
48
+ def active_interfaces
49
+ all.select(&:active?)
50
+ end
51
+ alias_method :active, :active_interfaces
52
+
53
+ def active_interfaces_names
54
+ all.select(&:active?).collect(&:interface_name)
55
+ end
56
+
57
+ def inactive_interfaces
58
+ all.select(&:inactive?)
59
+ end
60
+ alias_method :inactive, :inactive_interfaces
61
+
62
+ def inactive_interfaces_names
63
+ all.select(&:inactive?).collect(&:interface_name)
64
+ end
65
+
66
+ def up_interfaces
67
+ all.select(&:up?)
68
+ end
69
+ alias_method :up, :up_interfaces
70
+
71
+ def up_interfaces_names
72
+ all.select(&:up?).collect(&:interface_name)
73
+ end
74
+
75
+ def mac_addresses
76
+ all.collect(&:mac_address).compact
77
+ end
78
+ alias_method :ethernet_addresses, :mac_addresses
79
+
80
+ def ipv4_addresses
81
+ all.collect(&:ipv4_address).compact
82
+ end
83
+
84
+ def find_by_interface(interface)
85
+ all.find{|ifconfig| ifconfig.interface == interface}
86
+ end
87
+
88
+ def find_by_mac_address(mac_address)
89
+ all.find{|ifconfig| ifconfig.mac_address == mac_address}
90
+ end
91
+
92
+ def find_by_ipv4_address(ipv4_address)
93
+ all.find{|ifconfig| ifconfig.ipv4_address == ipv4_address}
94
+ end
95
+
96
+ def all_matching(pattern)
97
+ pattern = Regexp.union(pattern)
98
+ all.select{|ifconfig| ifconfig.name =~ pattern}
99
+ end
100
+
101
+ def bring_down_interface(interface_name)
102
+ system('sudo', 'ifconfig', interface_name, 'down', exception: true)
103
+ end
104
+
105
+ def bring_down_matching_interfaces(pattern)
106
+ matching_interfaces = all_matching(pattern).select(&:up?)
107
+ matching_interfaces.each do |ifconfig|
108
+ bring_down_interface(ifconfig.name)
109
+ end
110
+ matching_interfaces.map(&:name)
111
+ end
112
+
113
+ def destroy_interface(interface_name)
114
+ system('sudo', 'ifconfig', interface_name, 'destroy', exception: true)
115
+ end
116
+
117
+ private
118
+
119
+ def output
120
+ `ifconfig -a`
121
+ end
122
+ end # class << self
123
+
124
+ attr_accessor(
125
+ :broadcast_address,
126
+ :flags,
127
+ :interface,
128
+ :ipv4_address,
129
+ :mac_address,
130
+ :netmask,
131
+ :status
132
+ )
133
+
134
+ def initialize(
135
+ broadcast_address: nil,
136
+ flags: nil,
137
+ interface: nil,
138
+ ipv4_address: nil,
139
+ mac_address: nil,
140
+ netmask: nil,
141
+ status: nil
142
+ )
143
+ @broadcast_address = broadcast_address
144
+ @flags = flags
145
+ @interface = interface
146
+ @ipv4_address = ipv4_address
147
+ @mac_address = mac_address
148
+ @netmask = netmask
149
+ @status = status
150
+ end
151
+
152
+ def interface_name
153
+ @interface
154
+ end
155
+ alias_method :name, :interface_name
156
+
157
+ def ethernet_address
158
+ @mac_address
159
+ end
160
+
161
+ def active?
162
+ @status == 'active'
163
+ end
164
+
165
+ def inactive?
166
+ @status == 'inactive'
167
+ end
168
+
169
+ # For interfaces with status field (physical), check active status and IP address.
170
+ # For interfaces with flags only (virtual), check UP flag and IP address.
171
+ def up?
172
+ if @status
173
+ active? && @ipv4_address
174
+ else
175
+ (@flags && @flags.include?('UP')) && @ipv4_address
176
+ end
177
+ end
178
+
179
+ def virtual?
180
+ @interface =~ /^(utun|awdl|llw|lo|bridge|gif|stf)\d*/
181
+ end
182
+ end
183
+ end
@@ -0,0 +1,26 @@
1
+ # MacOS/Keychain.rb
2
+ # MacOS::Keychain
3
+
4
+ require 'open3'
5
+ require 'shellwords'
6
+
7
+ module MacOS
8
+ class Keychain
9
+ class << self
10
+
11
+ def find_generic_password_command(key)
12
+ "security find-generic-password -ga #{Shellwords.escape(key)}"
13
+ end
14
+
15
+ def find_generic_password(key)
16
+ Open3.capture3(find_generic_password_command(key))
17
+ end
18
+
19
+ def wifi_password(wifi_ssid)
20
+ stdout, stderr, status = find_generic_password(wifi_ssid)
21
+ stderr[/password: "(.+)"/, 1]
22
+ end
23
+
24
+ end # class << self
25
+ end
26
+ end
@@ -0,0 +1,36 @@
1
+ # MacOS/LaunchControl.rb
2
+ # MacOS::LaunchControl
3
+
4
+ require 'shellwords'
5
+
6
+ module MacOS
7
+ class LaunchControl
8
+
9
+ class << self
10
+
11
+ def load(path_to_plist)
12
+ system("launchctl load -w #{Shellwords.escape(path_to_plist)}")
13
+ end
14
+
15
+ def unload(path_to_plist)
16
+ system("launchctl unload -w #{Shellwords.escape(path_to_plist)}")
17
+ end
18
+
19
+ end # class << self
20
+
21
+ attr_accessor :path_to_plist
22
+
23
+ def initialize(path_to_plist = nil)
24
+ @path_to_plist = path_to_plist
25
+ end
26
+
27
+ def load
28
+ MacOS::LaunchControl.load(path_to_plist)
29
+ end
30
+
31
+ def unload(path_to_plist = @path_to_plist)
32
+ MacOS::LaunchControl.unload(path_to_plist)
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,119 @@
1
+ # MacOS/SystemProfiler.rb
2
+ # MacOS::SystemProfiler
3
+
4
+ # Description: This uses the built-in system_profiler command on MacOS to get access to the version numbers on any
5
+ # version of MacOS which has a system_profiler command and which returns results in a known format.
6
+
7
+ require 'Version'
8
+
9
+ module MacOS
10
+ module SystemProfiler
11
+
12
+ module_function
13
+
14
+ def system_profiler_output
15
+ `system_profiler SPSoftwareDataType`.force_encoding('UTF-8')
16
+ end
17
+
18
+ # The value system_profiler gives for a field, such as 'Boot Volume'.
19
+ def field(name)
20
+ system_profiler_output[/#{Regexp.escape(name)}: (?<value>.+)$/, :value]
21
+ end
22
+ private_class_method :field
23
+
24
+ def system_version_data
25
+ field('System Version')
26
+ end
27
+
28
+ def system_version_string
29
+ earlier_versions = system_version_data.split[3] # OSX 10.4 to 10.9 at least
30
+ later_versions = system_version_data.split[1] # MacOS 10.14 at least
31
+ earlier_versions || later_versions
32
+ end
33
+
34
+ def system_version
35
+ Version.new(system_version_string)
36
+ end
37
+
38
+ def major_system_version
39
+ system_version.major
40
+ end
41
+
42
+ def minor_system_version
43
+ system_version.minor
44
+ end
45
+
46
+ def tiny_system_version
47
+ system_version.tiny
48
+ end
49
+
50
+ def kernel_version_data
51
+ field('Kernel Version')
52
+ end
53
+
54
+ def kernel_name
55
+ kernel_version_data.split.first
56
+ end
57
+
58
+ def kernel_version_string
59
+ kernel_version_data.split.last
60
+ end
61
+
62
+ def kernel_version
63
+ Version.new(kernel_version_string)
64
+ end
65
+
66
+ def boot_volume_data
67
+ field('Boot Volume')
68
+ end
69
+ alias_method :boot_volume_string, :boot_volume_data
70
+
71
+ def boot_mode_data
72
+ field('Boot Mode')
73
+ end
74
+ alias_method :boot_mode_string, :boot_mode_data
75
+ alias_method :boot_mode, :boot_mode_data
76
+
77
+ def computer_name_data
78
+ field('Computer Name')
79
+ end
80
+ alias_method :computer_name_string, :computer_name_data
81
+ alias_method :computer_name, :computer_name_data
82
+
83
+ def username_data
84
+ field('User Name')
85
+ end
86
+ alias_method :username_string, :username_data
87
+ alias_method :username, :username_data
88
+
89
+ def secure_virtual_memory_data
90
+ field('Secure Virtual Memory')
91
+ end
92
+ alias_method :secure_virtual_memory_string, :secure_virtual_memory_data
93
+ alias_method :secure_virtual_memory, :secure_virtual_memory_data
94
+
95
+ def system_integrity_protection_data
96
+ field('System Integrity Protection')
97
+ end
98
+ alias_method :system_integrity_protection_string, :system_integrity_protection_data
99
+ alias_method :system_integrity_protection, :system_integrity_protection_data
100
+
101
+ def time_since_boot_data
102
+ field('Time since boot')
103
+ end
104
+ alias_method :time_since_boot_string, :time_since_boot_data
105
+ alias_method :time_since_boot, :time_since_boot_data
106
+
107
+ # The aliases as module functions too, alias_method making instance methods alone.
108
+ module_function(
109
+ :boot_volume_string,
110
+ :boot_mode_string, :boot_mode,
111
+ :computer_name_string, :computer_name,
112
+ :username_string, :username,
113
+ :secure_virtual_memory_string, :secure_virtual_memory,
114
+ :system_integrity_protection_string, :system_integrity_protection,
115
+ :time_since_boot_string, :time_since_boot
116
+ )
117
+
118
+ end
119
+ end
@@ -0,0 +1,26 @@
1
+ # MacOS/USBFlashDrive.rb
2
+ # MacOS::USBFlashDrive
3
+
4
+ require 'open3'
5
+ require 'shellwords'
6
+
7
+ module MacOS
8
+ class USBFlashDrive
9
+ class << self
10
+
11
+ def system_profiler_usb_data_type_command
12
+ "system_profiler SPUSBDataType"
13
+ end
14
+
15
+ def raw_system_profiler_output
16
+ Open3.capture3(system_profiler_usb_data_type_command)
17
+ end
18
+
19
+ def all_mount_points
20
+ stdout, stderr, status = raw_system_profiler_output
21
+ stdout.scan(/Mount Point: (.+)$/).flatten
22
+ end
23
+
24
+ end # class << self
25
+ end
26
+ end
@@ -0,0 +1,16 @@
1
+ # MacOS/Users.rb
2
+ # MacOS::Users
3
+
4
+ # Description: Lists the real (human) user accounts on the system, excluding system and service accounts.
5
+
6
+ module MacOS
7
+ module Users
8
+ module_function
9
+
10
+ def all
11
+ `dscl . list /users`.split("\n")
12
+ .reject{|username| username =~ /^_/}
13
+ .reject{|username| %w{daemon nobody root}.include?(username)}
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,6 @@
1
+ # MacOS/VERSION.rb
2
+ # MacOS::VERSION
3
+
4
+ module MacOS
5
+ VERSION = '0.50.0'
6
+ end
data/lib/MacOS/VPN.rb ADDED
@@ -0,0 +1,13 @@
1
+ # MacOS/VPN.rb
2
+ # MacOS::VPN
3
+
4
+ # Notes:
5
+ # 1. Taken from mercurial-0.4.3.
6
+
7
+ module MacOS
8
+ module VPN
9
+ def self.up?
10
+ MacOS::IfConfig.up_interfaces.detect{|ifconfig| ifconfig.interface.match(/utun/)}
11
+ end
12
+ end
13
+ end