startor 0.6.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 998bba49132f5d6805135b181e5ce13cbc00555318f7c3e164c949527dc103df
4
+ data.tar.gz: 58b182ce0395000d88a10ee09bbe251f9be5af668f8ed1f905e5a147d74066ee
5
+ SHA512:
6
+ metadata.gz: 68e883397b9a44f78a1b8ab0717652b3a686767a8ce5473dfb1e0f2fabd33bba7749862516402db8215feb9f7ad00cdb98db4bff5f8b521feb5e1004e1aee387
7
+ data.tar.gz: 7c9ed15bfa22c96dd580bd6420836a0a7b41f5fac1dbaef41ae37835c25745a6642f2950df8394bfdc8a0321ed915d9977c485ff3af5e2cbc8f9a57324ca620d
data/bin/startor ADDED
@@ -0,0 +1,173 @@
1
+ #!/usr/bin/env ruby
2
+ # startor
3
+
4
+ # 20181106
5
+ # 0.6.0
6
+
7
+ # History: Derived from https://kremalicious.com/simple-tor-setup-on-mac-os-x/...
8
+
9
+ # Prerequisites:
10
+ # 1. tor binary is installed.
11
+ # 2. Ruby is installed, which it should be already!
12
+
13
+ # Installation:
14
+ # 1. Press the <cmd> and <space> keys on the keyboard simultaneously.
15
+ # 2. Type: "Terminal.app" and press the <return> key.
16
+ # 3. Type: "gem install startor"
17
+
18
+ # How to use:
19
+ # 1. Press the <cmd> and <space> keys on the keyboard simultaneously.
20
+ # 2. Type: "Terminal.app" and press the <return> key.
21
+ # 3. Type: "startor setup" and press the <return> key.
22
+ # 4. Type: "startor" and press the <return> key.
23
+ # 5. If prompted, enter the password you use to login to your computer.
24
+ # 6. When wanting stop tor, go to the same window as the commands immediately above were entered and press the <ctrl> and <c> keys on the keyboard simultaneously.
25
+ # 7. If prompted, enter the password you use to login to your computer.
26
+
27
+ # Notes:
28
+ # 1. The hardware ports can be any of: 'Thunderbolt Ethernet', 'Thunderbolt Bridge', 'Wi-Fi', 'Ethernet', 'Bluetooth PAN', or 'Display Ethernet'.
29
+ # 2. See `networksetup -listallnetworkservices` for the complete list of hardware ports on your machine.
30
+
31
+ # Todo: (one or more of the following, in no particular order)
32
+ # 1. Turn this into a gem. Done as of 0.6.0.
33
+ # 2. Turn this into a brew formula.
34
+ # 3. Remove some of the comments here and put those into a README or INSTALL or other files as appropriate.
35
+ # 4. Create a(n) .app out of this by using some simple wrapper code.
36
+ # 5. Make it cross-platform: OSX, Linux, and Windows, at least.
37
+ # 6. Clean up the required libraries so that they are either gemified and/or reduced in number.
38
+
39
+ # Changes:
40
+ # Gemification and further tidying...
41
+ # 1. + startor.gemspec
42
+ # 2. Added to the section of comments entitled "Installation", which includes making use of the startor gem.
43
+
44
+ require 'FileUtils/which'
45
+ require 'Kernel/run'
46
+ require 'OSX/HardwarePort'
47
+ require 'OSX/IfConfig'
48
+
49
+ def install_homebrew
50
+ if FileUtils.which('brew')
51
+ puts 'Homebrew is already installed!'
52
+ else
53
+ run('/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"', show: true)
54
+ end
55
+ end
56
+
57
+ def install_tor
58
+ if FileUtils.which('tor')
59
+ puts 'tor is already installed!'
60
+ else
61
+ run('brew install tor', show: true)
62
+ end
63
+ end
64
+
65
+ def setup
66
+ install_homebrew
67
+ install_tor
68
+ end
69
+
70
+ def tor_installed?
71
+ FileUtils.which('tor')
72
+ end
73
+
74
+ def check_for_tor_program
75
+ unless tor_installed?
76
+ puts "tor was not found. You must install tor first."
77
+ puts "The easist way to install it is by running `startor setup`."
78
+ exit
79
+ end
80
+ end
81
+
82
+ def enter_admin_password
83
+ system('sudo -v')
84
+ end
85
+
86
+ def active_network_interfaces
87
+ OSX::IfConfig.new.active_interfaces
88
+ end
89
+
90
+ def active_network_ports
91
+ active_network_interfaces.collect do |active_network_interface|
92
+ if hardware_port = OSX::HardwarePort.find_by_device(active_network_interface)
93
+ hardware_port.name
94
+ end
95
+ end.compact
96
+ end
97
+
98
+ def setup_interfaces
99
+ active_network_ports.each do |active_network_port|
100
+ run("sudo networksetup -setsocksfirewallproxy '#{active_network_port}' 127.0.0.1 9050 off", show: true)
101
+ end
102
+ end
103
+
104
+ def puts_with_colour(string, colour)
105
+ system("echo \"$(tput setaf #{colour})\"")
106
+ puts string
107
+ system('echo "$(tput sgr0)"') # color reset
108
+ end
109
+
110
+ def puts_green(string)
111
+ puts_with_colour(string, 64) # Set console text colour to green(ish).
112
+ end
113
+
114
+ def puts_orange(string)
115
+ puts_with_colour(string, 136) # Set console text colour to orange.
116
+ end
117
+
118
+ def enable_proxy
119
+ active_network_ports.each do |active_network_port|
120
+ run("sudo networksetup -setsocksfirewallproxystate '#{active_network_port}' on", show: true)
121
+ puts_green('SOCKS proxy 127.0.0.1:9050 enabled.')
122
+ puts_orange('Starting Tor...')
123
+ end
124
+ end
125
+
126
+ def system_tor
127
+ system('tor')
128
+ end
129
+
130
+ def exec_tor
131
+ exec('tor')
132
+ end
133
+
134
+ def disable_proxy
135
+ active_network_ports.each do |active_network_port|
136
+ run("sudo networksetup -setsocksfirewallproxystate '#{active_network_port}' off", show: true)
137
+ puts_green('SOCKS proxy disabled.')
138
+ end
139
+ end
140
+
141
+ def common_up
142
+ check_for_tor_program
143
+ enter_admin_password
144
+ setup_interfaces
145
+ enable_proxy
146
+ end
147
+
148
+ def explicit_up
149
+ common_up
150
+ exec_tor
151
+ end
152
+
153
+ def implicit_up
154
+ common_up
155
+ system_tor
156
+ end
157
+
158
+ def down
159
+ disable_proxy
160
+ end
161
+
162
+ def main
163
+ case ARGV[0]
164
+ when 'up'; explicit_up
165
+ when 'down'; down
166
+ when 'setup'; setup
167
+ else; implicit_up
168
+ end
169
+ rescue SystemExit, Interrupt
170
+ down if tor_installed?
171
+ end
172
+
173
+ main
@@ -0,0 +1,24 @@
1
+ # Array#all_but_last
2
+
3
+ # 20080831
4
+ # 0.1.0
5
+
6
+ # Description: This returns a copy of the receiving array with the last element removed.
7
+
8
+ # Changes since 0.0:
9
+ # 1. I've added require 'Array/lastX', since I think it is reasonable that each file should load its own dependencies.
10
+
11
+ # Todo:
12
+ # 1. Conditionally do the require depending on whether the method already exists on Array and/or on whether rubylib has been defined elsewhere, since the require will fail in either case; and if rubylib is available, but this method isn't.
13
+
14
+ require 'Array/lastX'
15
+
16
+ class Array
17
+
18
+ def all_but_last
19
+ d = self.dup
20
+ d.last!
21
+ d
22
+ end
23
+
24
+ end
@@ -0,0 +1,21 @@
1
+ # Array/extract_optionsX.rb
2
+ # Array#extract_options!
3
+
4
+ # 20140402
5
+ # 0.1.1
6
+
7
+ # History: Stolen wholesale from ActiveSupport.
8
+
9
+ # Changes:
10
+ # 1. + #extract_options (no exclamation). Whereas I had previously had #extract_options mean the same as what I now call #peek_options, I decided that Array has some precedents for method names which do not have a bang method, but which do modify the receiver in place; #shift, #unshift, #push, and #pop come to mind...
11
+ # 0/1
12
+ # 2. Some minor tidying.
13
+
14
+ class Array
15
+
16
+ def extract_options!
17
+ last.is_a?(::Hash) ? pop : {}
18
+ end
19
+ alias_method :extract_options, :extract_options!
20
+
21
+ end
@@ -0,0 +1,10 @@
1
+ # Array#last!
2
+ # 20060630
3
+ #
4
+ # Description: Sometimes it makes more sense to treat arrays this way.
5
+ #
6
+ # Discussion: This and first! were taken from Skink2Quick from a few months ago.
7
+
8
+ class Array
9
+ alias_method :last!, :pop
10
+ end
@@ -0,0 +1,17 @@
1
+ # File#basename_without_extname
2
+ # File/basename_without_extname
3
+
4
+ # 2010.06.05
5
+ # 0.0.0
6
+
7
+ # Description: This returns the basename without the extension for a given File instance without the need to specify what the extension is because it makes use of File.extension which works that out.
8
+
9
+ require 'File/extname'
10
+
11
+ class File
12
+
13
+ def basename_without_extname
14
+ File.basename(path, extname)
15
+ end
16
+
17
+ end
@@ -0,0 +1,18 @@
1
+ # File/extname.rb
2
+ # File#extname
3
+
4
+ # 20140412
5
+ # 0.2.0
6
+
7
+ # Description: This is the instance method version of the class method on File by the same name.
8
+
9
+ # Changes since 0.1:
10
+ # 1. Using the built-in class-method now.
11
+
12
+ class File
13
+
14
+ def extname
15
+ File.extname(path)
16
+ end
17
+
18
+ end
@@ -0,0 +1,54 @@
1
+ # File/self.gsubX
2
+ # File.gsub!
3
+
4
+ # 20111122
5
+ # 0.0.1
6
+
7
+ # Description: This takes a file and replaces any text it finds according to a regular expression with a supplied string.
8
+
9
+ # History:
10
+ # 1. Separated class and instance methods to their own files at File#gsubX 0.3.6/0.4.
11
+
12
+ # Changes:
13
+ # 1. /File.gsubX/File\/self.gsubX/.
14
+
15
+ class File
16
+
17
+ def self.gsub!(filename, replacement_pattern, replacement_text, selection_pattern = nil)
18
+ replacement_pattern = (
19
+ case replacement_pattern
20
+ when String; Regexp.new(Regexp.escape(replacement_pattern))
21
+ when Regexp; replacement_pattern
22
+ else; raise
23
+ end
24
+ )
25
+ selection_pattern = replacement_pattern unless selection_pattern
26
+ selection_pattern = (
27
+ case selection_pattern
28
+ when String; Regexp.new(Regexp.escape(selection_pattern))
29
+ when Regexp; selection_pattern
30
+ else; raise
31
+ end
32
+ )
33
+ file_handle = self.open(filename, 'r')
34
+ tmp_file_handle = self.new(filename + '.tmp', 'w')
35
+ modified = false
36
+ file_handle.each do |line|
37
+ if line =~ Regexp.new(selection_pattern)
38
+ tmp_file_handle.print line.gsub(Regexp.new(replacement_pattern), replacement_text)
39
+ modified = true
40
+ else
41
+ tmp_file_handle.print line
42
+ end
43
+ end
44
+ file_handle.close
45
+ tmp_file_handle.close
46
+ if modified
47
+ self.delete(filename)
48
+ self.rename(filename + '.tmp', filename)
49
+ else
50
+ self.delete(filename + '.tmp')
51
+ end
52
+ end
53
+
54
+ end
@@ -0,0 +1,37 @@
1
+ # FileUtils/where.rb
2
+ # FileUtils#where
3
+
4
+ # 20140912
5
+ # 0.0.2
6
+
7
+ # History: Derived from where 0.2.3---the original command version I wrote in Ruby.
8
+
9
+ # Changes:
10
+ # 1. Removed trailing spaces.
11
+ # 2. - require 'File/extension', since it doesn't seem to be being used.
12
+ # 3. /require 'File/basename_without_extension'/require 'File/basename_without_extname'/, and uses thereof.
13
+ # 4. /require 'Platform/windowsQ'/require 'Platform/OS', and use thereof.
14
+
15
+ require 'File/basename_without_extname'
16
+ require 'Platform/OS'
17
+
18
+ module FileUtils
19
+
20
+ def where(executable_sought)
21
+ paths = ENV['PATH'].split(/:/)
22
+ sought_paths = []
23
+ paths.uniq.each do |path|
24
+ Dir["#{path}/*"].each do |executable|
25
+ if Platform::OS.windows?
26
+ sought_paths << executable if File.basename_without_extname(executable) == File.basename_without_extname(executable_sought)
27
+ else
28
+ sought_paths << executable if File.basename(executable) == executable_sought
29
+ end
30
+ end
31
+ end
32
+ sought_paths.empty? ? nil : sought_paths
33
+ end
34
+
35
+ module_function :where
36
+
37
+ end
@@ -0,0 +1,20 @@
1
+ # FileUtils#which
2
+
3
+ # 20100320
4
+ # 0.0.0
5
+
6
+ require 'FileUtils/where'
7
+
8
+ module FileUtils
9
+
10
+ def which(executable_sought)
11
+ if where_results = FileUtils.where(executable_sought)
12
+ where_results[0]
13
+ else
14
+ nil
15
+ end
16
+ end
17
+
18
+ module_function :which
19
+
20
+ end
data/lib/Files.rb ADDED
@@ -0,0 +1,249 @@
1
+ # Files.rb
2
+ # Files
3
+
4
+ # 20140508
5
+ # 0.8.3
6
+
7
+ # Changes since 0.7: (Switched from using Files to OpenStructs for @files instance variable because Ruby can't open more than some hundreds of files and nil was being returned after that limit had been reached.)
8
+ # 1. - Files.files_for().
9
+ # 2. + Files.with_attributes().
10
+ # 3. /return_files_object/return_ostruct_object/.
11
+ # 4. ~ Files.in_path___with_pattern___(), so as to make reference to Files.with_attributes().
12
+ # 5. ~ Files#absolute_paths(), to not rely upon an extension to File.
13
+ # 6. ~ Files#dirnames(), to not rely upon an extension to File.
14
+ # 7. ~ Files#absolute_dirnames(), to not rely upon an extension to File.
15
+ # 8 - require_relative './File'.
16
+ # 0/1
17
+ # 9. Even though MacRuby is supposed to be an MRI 1.9.2 analogue, it doesn't know Kernel#require_relative, so I've added a 'backport' for it in Ruby.
18
+ # 1/2
19
+ # 10. I don't need require_relative if I am altering the path and wrapping this up as a gem does that automatically for me.
20
+ # 11. However, perhaps I can't assume that someone will be using RubyGems, so I've got some $LOAD_PATH manipulation stuff there instead. It also means that I don't have to change any of the test code, else I'd have to it in there. Perhaps it doesn't matter terribly which of these ways I do this?
21
+ # 12. - ruby '1.9.3' from the Gemfile, since I had merely copied and pasted that from another project.
22
+ # 2/3
23
+ # 13. /MiniTest::Unit::TestCase/MiniTest::Test/.
24
+ # 14. + gem 'minitest' to all children test files and to the Gemfile so as to silence the warnings.
25
+ # 15. Moved test/all.rb to test/Files.rb.
26
+ # 16. Moved all children tests to test/Files/ as was forshadowed by the first line of the test files prior to 8.3.
27
+ # 17. ~ TC_Files_instance_methods_performing_operations#test_gsub! and #test_move, so that they were actually testing the instance methods and not the class methods as they were, thereby helping improve test coverage to 99.07%.
28
+ # 18. + TC_Files_instance_methods#test_initialize_with_no_filenames_and_no_path_or_pattern, so as to achieve 100% test coverage finally.
29
+ # 19. /TC_Files_instance_methods#test_initialize_with_no_path_or_pattern/TC_Files_instance_methods#test_initialize_with_a_filename/, so as to make the name more accurate.
30
+ # 20. /TC_Files_instance_methods#test_initialize_and_a_path/TC_Files_instance_methods#test_initialize_with_a_path/, so as to make the name more accurate.
31
+ # 21. /TC_Files_instance_methods#test_initialize_and_a_pattern/TC_Files_instance_methods#test_initialize_with_a_pattern/, so as to make the name more accurate.
32
+ # 22. /TC_Files_instance_methods#test_initialize_and_a_path_and_pattern/TC_Files_instance_methods#test_initialize_with_a_path_and_pattern/, so as to make the name more accurate.
33
+ # 23. Updated lib/Array/extract_optionsX.rb to the latest version.
34
+ # 24. Added lib/Array/all_but_last.rb, since it was a missing dependency.
35
+ # 25. Added lib/Array/lastX.rb, since it too was a missing dependency.
36
+ # 26. ~ Files#sort_method_macro, #sorter_macro, and #reverse_sort_method_macro, so as to make use of instance_eval rather than eval.
37
+ # 27. Added Kernel/require_relative.rb back, since I should be able to run the specs with MacRuby as well.
38
+ # 28. Updated the gemspec with latest version number.
39
+
40
+ # Todo:
41
+ # 1. Ensure that the interface is sufficiently usable that it will be reading for a 1.0 release after some more tinkering through the remainder of 0.8 and 0.9.
42
+
43
+ $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__))) unless
44
+ $LOAD_PATH.include?(File.dirname(__FILE__)) || $LOAD_PATH.include?(File.expand_path(File.dirname(__FILE__)))
45
+
46
+ require 'Array/extract_optionsX'
47
+ require 'File/self.gsubX'
48
+ require 'fileutils'
49
+ require 'Module/alias_methods'
50
+ require 'ostruct'
51
+
52
+ class Files
53
+
54
+ class << self
55
+
56
+ def find(options = {})
57
+ path, pattern, return_ostruct_object = options[:path], options[:pattern], options[:return_ostruct_object]
58
+ case
59
+ when path && pattern
60
+ in_path___with_pattern___(path, pattern, return_ostruct_object)
61
+ when path && !pattern
62
+ in_path___(path, return_ostruct_object)
63
+ when !path && pattern
64
+ with_pattern___(pattern, return_ostruct_object)
65
+ when !path && !pattern
66
+ here(return_ostruct_object)
67
+ end
68
+ end
69
+ alias_methods :all, :find
70
+
71
+ def in_path___with_pattern___(path, pattern, return_ostruct_object = true)
72
+ files = with_attributes(Dir["#{path}/#{pattern}"])
73
+ if return_ostruct_object
74
+ files_object = Files.new
75
+ files_object.files = files
76
+ files_object
77
+ else
78
+ files
79
+ end
80
+ end
81
+ alias_methods :in_path_matching, :in_path___matching___,
82
+ :in_path_with_pattern, :in_path___with_pattern___
83
+
84
+ def in_path___(path, return_ostruct_object = true)
85
+ in_path___matching___(path, '*', return_ostruct_object)
86
+ end
87
+ alias_methods :in, :in_path, :in_path___
88
+
89
+ def with_pattern___(pattern, return_ostruct_object = true)
90
+ in_path___matching___('./', pattern, return_ostruct_object)
91
+ end
92
+ alias_methods :with_pattern, :with_pattern___
93
+
94
+ def here(return_ostruct_object = true)
95
+ in_path___matching___('./', '*', return_ostruct_object)
96
+ end
97
+
98
+ def with_attributes(paths)
99
+ paths.collect do |path|
100
+ begin
101
+ f = {}
102
+ f[:path] = path
103
+ f[:size] = File.stat(path).size
104
+ f[:ftype] = File.stat(path).ftype
105
+ f[:mode] = File.stat(path).mode
106
+ f[:gid] = File.stat(path).gid
107
+ f[:uid] = File.stat(path).uid
108
+ f[:ctime] = File.stat(path).ctime
109
+ f[:mtime] = File.stat(path).mtime
110
+ f[:atime] = File.stat(path).atime
111
+ OpenStruct.new(f)
112
+ rescue
113
+ end
114
+ end
115
+ end
116
+
117
+ def gsub!(filenames, replacement_pattern, replacement_text, selection_pattern = nil)
118
+ filenames.each do |filename|
119
+ File.gsub!(filename, replacement_pattern, replacement_text, selection_pattern)
120
+ end
121
+ end
122
+
123
+ def move(filenames, replacement_pattern, replacement_text)
124
+ filenames.each do |filename|
125
+ new_filename = filename.gsub(/#{replacement_pattern}/, replacement_text)
126
+ FileUtils.mv(filename, new_filename)
127
+ end
128
+ end
129
+ alias_methods :ren, :rename, :mv, :move
130
+
131
+ end # class << self
132
+
133
+ include Enumerable
134
+
135
+ attr_writer :files
136
+ attr_reader :path
137
+ attr_reader :pattern
138
+
139
+ def initialize(*args)
140
+ options = args.extract_options!
141
+ @args, @path, @pattern = args, options[:path], options[:pattern]
142
+ load_metaprogrammed_methods
143
+ end
144
+
145
+ def files
146
+ @files ||= (
147
+ if !@args.empty?
148
+ Files.with_attributes(@args.flatten)
149
+ elsif path && pattern
150
+ Files.find(path: path, pattern: pattern, return_ostruct_object: false)
151
+ elsif path
152
+ Files.find(path: path, return_ostruct_object: false)
153
+ elsif pattern
154
+ Files.find(pattern: pattern, return_ostruct_object: false)
155
+ else
156
+ []
157
+ end
158
+ )
159
+ end
160
+
161
+ def each
162
+ files.each{|f| yield f}
163
+ end
164
+
165
+ def paths
166
+ files.collect{|f| f.path}
167
+ end
168
+
169
+ def absolute_paths
170
+ files.collect{|f| File.expand_path(f.path)}
171
+ end
172
+
173
+ def dirnames
174
+ files.collect{|f| File.dirname(f.path)}
175
+ end
176
+
177
+ def absolute_dirnames
178
+ files.collect{|f| File.dirname(File.absolute_path(f.path))}
179
+ end
180
+
181
+ def gsub!(replacement_pattern, replacement_text)
182
+ Files.gsub!(paths, replacement_pattern, replacement_text)
183
+ end
184
+
185
+ def move(replacement_pattern, replacement_text)
186
+ Files.move(paths, replacement_pattern, replacement_text)
187
+ end
188
+ alias_methods :ren, :rename, :mv, :move
189
+
190
+ def path=(new_path)
191
+ @path = new_path
192
+ set_files
193
+ end
194
+
195
+ def pattern=(new_pattern)
196
+ @pattern = new_pattern
197
+ set_files
198
+ end
199
+
200
+ private
201
+
202
+ def set_files
203
+ @files = nil
204
+ files
205
+ end
206
+
207
+ def load_metaprogrammed_methods
208
+ sort_method_macro
209
+ reverse_sort_method_macro
210
+ sorter_macro
211
+ end
212
+
213
+ def sort_method_macro
214
+ %w(atime ctime mtime size ftype mode gid uid filename).each do |method|
215
+ instance_eval("
216
+ def sort_by_#{method}
217
+ files.sort! do |a,b|
218
+ by_#{method}(a,b)
219
+ end
220
+ self
221
+ end
222
+ ")
223
+ end
224
+ end
225
+
226
+ def sorter_macro
227
+ %w(atime ctime mtime size ftype mode gid uid filename).each do |method|
228
+ instance_eval("
229
+ def by_#{method}(a,b)
230
+ a.#{method} <=> b.#{method}
231
+ end
232
+ ")
233
+ end
234
+ end
235
+
236
+ def reverse_sort_method_macro
237
+ %w(atime ctime mtime size ftype mode gid uid filename).each do |method|
238
+ instance_eval("
239
+ def reverse_sort_by_#{method}
240
+ files.sort! do |a,b|
241
+ by_#{method}(a,b)
242
+ end.reverse!
243
+ self
244
+ end
245
+ ")
246
+ end
247
+ end
248
+
249
+ end
data/lib/Kernel/run.rb ADDED
@@ -0,0 +1,43 @@
1
+ # Kernel/run.rb
2
+ # Kernel#run
3
+
4
+ # 20170613
5
+ # 0.1.5
6
+
7
+ # Changes:
8
+ # 1. Make use of a number of options, substituting ENV['DRY_RUN'] for options[:dry_run], and adding :show and :dont_raise.
9
+ # 0/1
10
+ # 2. When showing the output make it clear that it is a dry run.
11
+ # 1/2
12
+ # 3. If the :dry_run option is specified, then it makes no sense to test $? for success, so group all that code in the unless.
13
+ # 2/3
14
+ # 4. The logic was reversed for whether to raise or not.
15
+ # 3/4
16
+ # 5. Really fixed the raise logic finally, I think.
17
+ # 4/5
18
+ # 6. Yet another attempt at fixing the raise logic.
19
+
20
+ # Todo:
21
+ # 1. Even though this is a small method it might be good idea to add some automated tests.
22
+
23
+ require 'Array/extract_optionsX'
24
+
25
+ module Kernel
26
+
27
+ def run(*args)
28
+ options = args.extract_options!
29
+ command = args
30
+ if options[:show] && !options[:dry_run]
31
+ puts command.join(' ')
32
+ elsif options[:show] && options[:dry_run]
33
+ puts "DRY RUN *** #{command.join(' ')} *** DRY RUN"
34
+ end
35
+ unless options[:dry_run]
36
+ system(*command)
37
+ if !$?.success? && !options[:dont_raise]
38
+ raise "#{command.inspect} failed to exit cleanly."
39
+ end
40
+ end
41
+ end
42
+
43
+ end
@@ -0,0 +1,16 @@
1
+ # Module#alias_methods
2
+
3
+ # 20080831
4
+ # 0.0.0
5
+
6
+ # Description: I have a penchance for having multiple method names and having line after line of alias_method calls is kinda ugly.
7
+
8
+ require 'Array/all_but_last'
9
+
10
+ class Module
11
+
12
+ def alias_methods(*args)
13
+ args.all_but_last.each{|e| alias_method e.to_sym, args.last.to_sym}
14
+ end
15
+
16
+ end