mac-wifi 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 75c730b3171f9dba37b683b40cde3c4d40765001
4
- data.tar.gz: 5660a6f765152ad8ac23a09f5f88084a4ec83d3b
3
+ metadata.gz: 24a41565844a201ee4416a7a5452d8859526ed7c
4
+ data.tar.gz: 8cfe9206c6164351d4b98b825a89543e98932719
5
5
  SHA512:
6
- metadata.gz: 237050e6744bb80ae8c2f36053731db4a03c78cc1402b82a12479848ac6d20b16a032a48d8944e038fe026799f5c28b0991523108958182c083bde7c9e65bb4a
7
- data.tar.gz: 57d380bc2392e40e2b78bc856b22be6c83ec388e70a365cc098b0b76084f1e5427dcd6fac64172dad7d300cf11b39f9883f4e67c894ad1430ca851ffaca926ba
6
+ metadata.gz: 41ba590f1fe37986621d1fee3f5c8d93af431de56b24bedf8988f2f740f20ed8e1a49ad7aeab8b2ed412e068b39ee0b9da3e0372a7821260279e6af988a61f35
7
+ data.tar.gz: 7e8cb0afeb5f413ff444cf1602170671976ef1a464624c58846ec6b7dc86bf09b349caa0cb889d973790d0d818d92b6a61ebbba360bbcd57f24c1ce073b9c17e
data/.gitignore CHANGED
@@ -16,4 +16,4 @@ test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
18
  .idea/
19
-
19
+ mac-wifi-error-stack-trace.txt
data/README.md CHANGED
@@ -17,34 +17,38 @@ Available commands can be seen by using the `h` (or `help`) option. Here is its
17
17
  output at the time of this writing:
18
18
 
19
19
  ```
20
- ➜ mac-wifi git:(master) ✗  ./mac-wifi h
21
-
22
- mac-wifi version 1.1.0 -- Available commands are:
23
-
24
- ci - connected to Internet (not just wifi on)?
25
- co[nnect] network-name - turns wifi on, connects to network-name
26
- cy[cle] - turns wifi off, then on, preserving network selection
27
- d[isconnect] - disconnects from current network, does not turn off wifi
28
- h[elp] - prints this help
29
- i[nfo] - prints wifi-related information
30
- lsp[referred] - lists preferred (not necessarily available) networks
31
- lsa[vailable] - lists available networks
32
- n[etwork_name] - name (SSID) of currently connected network
33
- on - turns wifi on
34
- of[f] - turns wifi off
35
- pa[ssword] network-name - shows password for preferred network-name
36
- q[uit] - exits this program (interactive shell mode only)
37
- r[m] network-name - removes network-name from the preferred networks list
38
- s[hell] - opens an interactive pry shell (command line only)
39
- t[ill] - returns when the desired Internet connection state is true. Options:
40
- 'on'/:on or 'off'/:off
41
- wait interval, in seconds (optional, defaults to 0.5 seconds)
42
- w[ifion] - is the wifi on?
43
- x[it] - exits this program (interactive shell mode only)
20
+ $ mac-wifi h
21
+
22
+
23
+ mac-wifi version 1.3.0 -- Available commands are:
24
+
25
+ a[vailnets] - array of names of the available networks
26
+ ci - connected to Internet (not just wifi on)?
27
+ co[nnect] network-name - turns wifi on, connects to network-name
28
+ cy[cle] - turns wifi off, then on, preserving network selection
29
+ d[isconnect] - disconnects from current network, does not turn off wifi
30
+ h[elp] - prints this help
31
+ i[nfo] - a hash of wifi-related information
32
+ l[savailnets] - details about available networks
33
+ n[etwork_name] - name (SSID) of currently connected network
34
+ on - turns wifi on
35
+ of[f] - turns wifi off
36
+ pa[ssword] network-name - password for preferred network-name
37
+ pr[efnets] - preferred (not necessarily available) networks
38
+ q[uit] - exits this program (interactive shell mode only) (see also 'x')
39
+ r[mprefnets] network-name - removes network-name from the preferred networks list
40
+ (can provide multiple names separated by spaces)
41
+ s[hell] - opens an interactive pry shell (command line only)
42
+ t[ill] - returns when the desired Internet connection state is true. Options:
43
+ 1) 'on'/:on, 'off'/:off, 'conn'/:conn, or 'disc'/:disc
44
+ 2) wait interval, in seconds (optional, defaults to 0.5 seconds)
45
+ w[ifion] - is the wifi on?
46
+ x[it] - exits this program (interactive shell mode only) (see also 'q')
44
47
 
45
48
  When in interactive shell mode:
46
49
  * use quotes for string parameters such as method names.
47
50
  * for pry commands, use prefix `%`.
51
+
48
52
  ```
49
53
 
50
54
  Internally, it uses several Mac command line utilities. This is not ideal,
@@ -63,6 +67,25 @@ This is accomplished by the following command:
63
67
  `gem install awesome_print`
64
68
 
65
69
 
70
+ ### JSON and YAML Output
71
+
72
+ For now, JSON and YAML processing are only available in the interactive mode shell, in the way
73
+ you would usually use them in Ruby code. Their respective libraries are automatically
74
+ `require`d for your convenience. If you want them in non-interactive mode,
75
+ you can work around this limitation by redirecting the shell's input, e.g.:
76
+
77
+ ```
78
+ echo "File.write('available_networks.json', availnets.pretty_inspect)" | mac-wifi s
79
+ ```
80
+
81
+ This will create a file `available_networks.json` with content looking something like this:
82
+
83
+ ```bash
84
+ ["....MMobile 2.4G",
85
+ ".@ 3BB_WiFi",
86
+ ".@ AIS SUPER WiFi"]
87
+ ```
88
+
66
89
  ### Seeing the Underlying OS Commands and Output
67
90
 
68
91
  If you would like to see the Mac OS commands and their output, you can do so by setting the
@@ -119,7 +142,7 @@ session. It can be useful when:
119
142
 
120
143
  There are a couple of things (that may be surprising) to keep in mind
121
144
  when using the shell. They relate to the fact that local variables
122
- and method calls use the same notation in Ruby (use of parentheses
145
+ and method calls use the same notation in Ruby (since use of parentheses
123
146
  in a method call is optional):
124
147
 
125
148
  1) In Ruby, when both a method and a local variable have the same name,
@@ -187,8 +210,9 @@ constants or instance variables if you want to create variables in your shell.
187
210
 
188
211
  ```
189
212
  mac-wifi i # prints out wifi info
190
- mac-wifi lsa # prints available networks
191
- mac-wifi lsp # prints preferred networks
213
+ mac-wifi a # prints out names of available networks
214
+ mac-wifi lsa # prints available networks detailed information
215
+ mac-wifi pr # prints preferred networks
192
216
  mac-wifi cy # cycles the wifi off and on
193
217
  mac-wifi co a-network a-password # connects to a network requiring a password
194
218
  mac-wifi co a-network # connects to a network _not_ requiring a password
@@ -197,6 +221,36 @@ mac-wifi t on && say "Internet connected" # Play audible message when Internet b
197
221
 
198
222
  #### Interactive Shell Commands
199
223
 
224
+ When in shell mode, commands generally return the target object (e.g. the array of
225
+ available networks) rather than outputting a nicely formatted string. This may result
226
+ in the shell outputting that returned value in an ugly way.
227
+
228
+ If you don't need the return value but just want to display the value nicely,
229
+ you can use the `fancy_puts` method to output it nicely. An alias `fp` has been
230
+ provided for your convenience. You're welcome! For example:
231
+
232
+ ```
233
+ [5] pry(#<MacWifi::CommandLineInterface>)> fp pr.first(3)
234
+ [
235
+ [0] " AIS SMART Login",
236
+ [1] " BubblesLive",
237
+ [2] "#HKAirport Free WiFi"
238
+ ]
239
+ ```
240
+
241
+ If you want to surpress output altogether (e.g. if you are using the value in an
242
+ expression and don't need to print it out, you can simply append `;nil` to the expression
243
+ and that will be value output to the console. For example:
244
+
245
+ ```
246
+ [10] pry(#<MacWifi::CommandLineInterface>)> available_networks = availnets; nil
247
+ => nil
248
+ [11] pry(#<MacWifi::CommandLineInterface>)> availnets.size
249
+ => 32
250
+ ```
251
+
252
+ **More Examples**
253
+
200
254
  (For brevity, semicolons are used here to put multiple commands on one line,
201
255
  but these commands could also each be specified on a line of its own.)
202
256
 
@@ -216,15 +270,15 @@ i
216
270
  > @i = i; puts "You are connected on port #{@i[:port]} to #{@i[:network]} on IP address #{@i[:ip_address]}."
217
271
  You are connected on port en0 to .@ AIS SUPER WiFi on IP address 172.27.145.225.
218
272
 
219
- > puts "There are #{lsp.size} preferred networks."
273
+ > puts "There are #{pr.size} preferred networks."
220
274
  There are 341 preferred networks.
221
275
 
222
276
  # Delete all preferred networks whose names begin with "TOTTGUEST", the hard way:
223
- > lsp.grep(/^TOTTGUEST/).each { |n| rm(n) }
277
+ > pr.grep(/^TOTTGUEST/).each { |n| rm(n) }
224
278
 
225
279
  # Delete all preferred networks whose names begin with "TOTTGUEST", the easy way.
226
280
  # rm can take multiple network names, but they must be specified as separate parameters; thus the '*'.
227
- > rm(*lsp.grep(/^TOTTGUEST/))
281
+ > rm(*pr.grep(/^TOTTGUEST/))
228
282
 
229
283
  # Define a method to wait for the Internet connection to be active.
230
284
  # (This functionality is included in the `till` command.)
data/RELEASE_NOTES.md CHANGED
@@ -1,9 +1,19 @@
1
+ ## v1.3.0
2
+
3
+ * Add partial JSON and YAML support.
4
+ * Script moved from bin to exe directory.
5
+ * Provide `fp` fancy print alias for convenience in shell.
6
+ * Command renames: 'lsp' -> 'prefnets', 'rm' -> 'rmprefnets'
7
+ * Add 'availnets' command for list of unique available network names.
8
+
9
+
1
10
  ## v1.2.0
2
11
 
3
12
  * Fix: protect against using command strings shorter than minimum length
4
13
  (e.g. 'c', when more chars are necessary to disambiguate multiple commands).
5
14
  * Improvements in help text and readme.
6
15
 
16
+
7
17
  ## v1.1.0
8
18
 
9
19
  * Sort available networks alphabetically, left justify ssid's.
@@ -19,14 +19,13 @@
19
19
  # License: MIT License
20
20
 
21
21
 
22
-
23
22
  require 'shellwords'
24
23
  require 'tempfile'
25
24
 
26
25
  module MacWifi
27
26
 
28
27
  # This version must be kept in sync with the version in the gemspec file.
29
- VERSION = '1.2.0'
28
+ VERSION = '1.3.0'
30
29
 
31
30
 
32
31
  class BaseModel
@@ -184,11 +183,16 @@ class BaseModel
184
183
 
185
184
 
186
185
  # Waits for the Internet connection to be in the desired state.
187
- # @param status must be in [:conn, :disc, :off, :on]; waits for that state
188
- # @param wait_interval_in_secs sleeps this interval between retries
186
+ # @param target_status must be in [:conn, :disc, :off, :on]; waits for that state
187
+ # @param wait_interval_in_secs sleeps this interval between retries; if nil or absent,
188
+ # a default will be provided
189
189
  #
190
- def till(status, wait_interval_in_secs = nil)
190
+ def till(target_status, wait_interval_in_secs = nil)
191
191
 
192
+ # One might ask, why not just put the 0.5 up there as the default argument.
193
+ # We could do that, but we'd still need the line below in case nil
194
+ # was explicitly specified. The default argument of nil above emphasizes that
195
+ # the absence of an argument and a specification of nil will behave identically.
192
196
  wait_interval_in_secs ||= 0.5
193
197
 
194
198
  finished_predicates = {
@@ -198,10 +202,11 @@ class BaseModel
198
202
  off: -> { ! wifi_on? }
199
203
  }
200
204
 
201
- finished_predicate = finished_predicates[status]
205
+ finished_predicate = finished_predicates[target_status]
202
206
 
203
207
  if finished_predicate.nil?
204
- raise ArgumentError.new("Option must be one of #{finished_predicates.keys.inspect}. Was: #{status.inspect}")
208
+ raise ArgumentError.new(
209
+ "Option must be one of #{finished_predicates.keys.inspect}. Was: #{target_status.inspect}")
205
210
  end
206
211
 
207
212
  loop do
@@ -280,10 +285,21 @@ class MacOsModel < BaseModel
280
285
  return [reformat_line.(header_line)] + data_lines
281
286
  end
282
287
  end
288
+
289
+
283
290
  raise "Unable to get available network information after #{max_attempts} attempts."
284
291
  end
285
292
 
286
293
 
294
+ # @return an array of unique available network names only, sorted alphabetically
295
+ def available_network_names
296
+ available_network_info[1..-1] \
297
+ .map { |line| line[0..32].rstrip } \
298
+ .uniq \
299
+ .sort { |s1, s2| s1.casecmp(s2) }
300
+ end
301
+
302
+
287
303
  # Returns data pertaining to "preferred" networks, many/most of which will probably not be available.
288
304
  def preferred_networks
289
305
  lines = run_os_command("networksetup -listpreferredwirelessnetworks #{wifi_hardware_port}").split("\n")
@@ -445,7 +461,7 @@ end
445
461
 
446
462
  class CommandLineInterface
447
463
 
448
- attr_reader :model
464
+ attr_reader :model, :interactive_mode
449
465
 
450
466
  class Command < Struct.new(:min_string, :max_string, :action); end
451
467
 
@@ -461,26 +477,28 @@ class CommandLineInterface
461
477
  HELP_TEXT = "
462
478
  mac-wifi version #{VERSION} -- Available commands are:
463
479
 
464
- ci - connected to Internet (not just wifi on)?
465
- co[nnect] network-name - turns wifi on, connects to network-name
466
- cy[cle] - turns wifi off, then on, preserving network selection
467
- d[isconnect] - disconnects from current network, does not turn off wifi
468
- h[elp] - prints this help
469
- i[nfo] - prints wifi-related information
470
- lsp[referred] - lists preferred (not necessarily available) networks
471
- lsa[vailable] - lists available networks
472
- n[etwork_name] - name (SSID) of currently connected network
473
- on - turns wifi on
474
- of[f] - turns wifi off
475
- pa[ssword] network-name - shows password for preferred network-name
476
- q[uit] - exits this program (interactive shell mode only)
477
- r[m] network-name - removes network-name from the preferred networks list
478
- s[hell] - opens an interactive pry shell (command line only)
479
- t[ill] - returns when the desired Internet connection state is true. Options:
480
- 1) 'on'/:on, 'off'/:off, 'conn'/:conn, or 'disc'/:disc
481
- 2) wait interval, in seconds (optional, defaults to 0.5 seconds)
482
- w[ifion] - is the wifi on?
483
- x[it] - exits this program (interactive shell mode only)
480
+ a[vailnets] - array of names of the available networks
481
+ ci - connected to Internet (not just wifi on)?
482
+ co[nnect] network-name - turns wifi on, connects to network-name
483
+ cy[cle] - turns wifi off, then on, preserving network selection
484
+ d[isconnect] - disconnects from current network, does not turn off wifi
485
+ h[elp] - prints this help
486
+ i[nfo] - a hash of wifi-related information
487
+ l[savailnets] - details about available networks
488
+ n[etwork_name] - name (SSID) of currently connected network
489
+ on - turns wifi on
490
+ of[f] - turns wifi off
491
+ pa[ssword] network-name - password for preferred network-name
492
+ pr[efnets] - preferred (not necessarily available) networks
493
+ q[uit] - exits this program (interactive shell mode only) (see also 'x')
494
+ r[mprefnets] network-name - removes network-name from the preferred networks list
495
+ (can provide multiple names separated by spaces)
496
+ s[hell] - opens an interactive pry shell (command line only)
497
+ t[ill] - returns when the desired Internet connection state is true. Options:
498
+ 1) 'on'/:on, 'off'/:off, 'conn'/:conn, or 'disc'/:disc
499
+ 2) wait interval, in seconds (optional, defaults to 0.5 seconds)
500
+ w[ifion] - is the wifi on?
501
+ x[it] - exits this program (interactive shell mode only) (see also 'q')
484
502
 
485
503
  When in interactive shell mode:
486
504
  * use quotes for string parameters such as method names.
@@ -495,6 +513,8 @@ When in interactive shell mode:
495
513
  end
496
514
 
497
515
 
516
+ # Until command line option parsing is added, the only way to specify
517
+ # verbose mode is in the environment variable MAC_WIFI_OPTS.
498
518
  def verbose_mode
499
519
  /-v/.match(ENV['MAC_WIFI_OPTS'])
500
520
  end
@@ -505,9 +525,10 @@ When in interactive shell mode:
505
525
  end
506
526
 
507
527
 
528
+ # @return true if awesome_print is available (after requiring it), else false after requiring 'pp'.
508
529
  # We'd like to use awesome_print if it is available, but not require it.
509
- # So, we try to require it, but if that fails, we fall back to using pp (pretty print).
510
- # Returns true if awesome_print is available (after requiring it), else false after requiring 'pp'.
530
+ # So, we try to require it, but if that fails, we fall back to using pp (pretty print),
531
+ # which is included in Ruby distributions without the need to install a gem.
511
532
  def awesome_print_available?
512
533
  if @awesome_print_available.nil? # first time here
513
534
  begin
@@ -523,8 +544,19 @@ When in interactive shell mode:
523
544
  end
524
545
 
525
546
 
547
+ def fancy_string(object)
548
+ awesome_print_available? ? object.ai : object.pretty_inspect
549
+ end
550
+
551
+
526
552
  def fancy_puts(object)
527
- awesome_print_available? ? ap(object) : pp(object)
553
+ puts fancy_string(object)
554
+ end
555
+ alias_method :fp, :fancy_puts
556
+
557
+
558
+ def puts_unless_interactive(string)
559
+ puts(string) unless interactive_mode
528
560
  end
529
561
 
530
562
 
@@ -549,13 +581,17 @@ When in interactive shell mode:
549
581
  # Runs a pry session in the context of this object.
550
582
  # Commands and options specified on the command line can also be specified in the shell.
551
583
  def run_shell
552
- if @interactive_mode
584
+ if interactive_mode
553
585
  puts "Already in shell."
554
586
  return
555
587
  end
556
588
 
557
589
  @interactive_mode = true
558
590
 
591
+ # For conveniently calling to_json or to_yaml on an object:
592
+ require 'json'
593
+ require 'yaml'
594
+
559
595
  begin
560
596
  require 'pry'
561
597
  rescue LoadError
@@ -579,22 +615,14 @@ When in interactive shell mode:
579
615
  end
580
616
 
581
617
 
582
- def output_network_password(network_name, password)
583
- output = %Q{Preferred network "#{network_name}" }
584
- output << (password ? %Q{stored password is: "#{password}".} : "has no stored password.")
585
- puts output
586
- password
587
- end
588
-
589
-
590
618
  # For use by the shell; when typing a command and options, it is passed to process_command_line
591
619
  def method_missing(method_name, *options)
592
620
  method_name = method_name.to_s
593
- method_valid = !! find_command_action(method_name)
594
- if method_valid
621
+ method_exists = !! find_command_action(method_name)
622
+ if method_exists
595
623
  process_command_line(method_name, options)
596
624
  else
597
- puts(%Q{"#{method_name}" is not a valid command or option. If you intend for this to be a string literal, use quotes.})
625
+ puts(%Q{"#{method_name}" is not a valid command or option. If you intend for this to be a string literal, use quotes or %q/Q{}.})
598
626
  end
599
627
  end
600
628
 
@@ -602,9 +630,9 @@ When in interactive shell mode:
602
630
  # Processes the command (ARGV[0]) and any relevant options (ARGV[1..-1]).
603
631
  #
604
632
  # CAUTION! In interactive mode, any strings entered (e.g. a network name) MUST
605
- # be in a form that Ruby will recognize as a string, i.e. single or double quotes,
606
- # %q, %Q, etc. Otherwise Ruby will assume it's a method name and pass it to
607
- # method_missing!
633
+ # be in a form that the Ruby interpreter will recognize as a string,
634
+ # i.e. single or double quotes, %q, %Q, etc.
635
+ # Otherwise it will assume it's a method name and pass it to method_missing!
608
636
  def process_command_line(command, options)
609
637
  action = find_command_action(command)
610
638
  if action
@@ -618,7 +646,7 @@ When in interactive shell mode:
618
646
 
619
647
 
620
648
  def quit
621
- if @interactive_mode
649
+ if interactive_mode
622
650
  exit(0)
623
651
  else
624
652
  puts "This command can only be run in shell mode."
@@ -626,9 +654,16 @@ When in interactive shell mode:
626
654
  end
627
655
 
628
656
 
657
+ def cmd_a
658
+ info = model.available_network_names
659
+ puts_unless_interactive(fancy_string(info))
660
+ info
661
+ end
662
+
663
+
629
664
  def cmd_ci
630
665
  connected = model.connected_to_internet?
631
- puts "Connected to Internet: #{connected}" unless @interactive_mode
666
+ puts_unless_interactive("Connected to Internet: #{connected}")
632
667
  connected
633
668
  end
634
669
 
@@ -655,30 +690,21 @@ When in interactive shell mode:
655
690
 
656
691
  def cmd_i
657
692
  info = model.wifi_info
658
- fancy_puts(info) unless @interactive_mode
693
+ puts_unless_interactive(fancy_string(info))
659
694
  info
660
695
  end
661
696
 
662
697
 
663
698
  def cmd_lsa
664
699
  info = model.available_network_info
665
- puts info unless @interactive_mode
700
+ puts_unless_interactive(fancy_string(info))
666
701
  info
667
702
  end
668
703
 
669
704
 
670
- def cmd_lsp
671
- networks = model.preferred_networks
672
- puts networks unless @interactive_mode
673
- networks
674
- end
675
-
676
-
677
705
  def cmd_n
678
706
  name = model.connected_network_name
679
- unless @interactive_mode
680
- puts "Network (SSID) name: #{name ? name : '[none]'}"
681
- end
707
+ puts_unless_interactive("Network (SSID) name: #{name ? name : '[none]'}")
682
708
  name
683
709
  end
684
710
 
@@ -695,11 +721,24 @@ When in interactive shell mode:
695
721
 
696
722
  def cmd_pa(network)
697
723
  password = model.preferred_network_password(network)
698
- output_network_password(network, password) unless @interactive_mode
724
+
725
+ unless interactive_mode
726
+ output = %Q{Preferred network "#{network_name}" }
727
+ output << (password ? %Q{stored password is: "#{password}".} : "has no stored password.")
728
+ puts output
729
+ end
730
+
699
731
  password
700
732
  end
701
733
 
702
734
 
735
+ def cmd_pr
736
+ networks = model.preferred_networks
737
+ puts_unless_interactive(fancy_string(networks))
738
+ networks
739
+ end
740
+
741
+
703
742
  def cmd_q
704
743
  quit
705
744
  end
@@ -724,7 +763,7 @@ When in interactive shell mode:
724
763
 
725
764
  def cmd_w
726
765
  on = model.wifi_on?
727
- puts "Wifi on: #{on}" unless @interactive_mode
766
+ puts_unless_interactive("Wifi on: #{on}")
728
767
  on
729
768
  end
730
769
 
@@ -736,20 +775,21 @@ When in interactive shell mode:
736
775
 
737
776
  def commands
738
777
  @commands_ ||= [
778
+ Command.new('a', 'availnets', -> (*_options) { cmd_a }),
739
779
  Command.new('ci', 'ci', -> (*_options) { cmd_ci }),
740
780
  Command.new('co', 'connect', -> (*options) { cmd_co(*options) }),
741
781
  Command.new('cy', 'cycle', -> (*_options) { cmd_cy }),
742
782
  Command.new('d', 'disconnect', -> (*_options) { cmd_d }),
743
783
  Command.new('h', 'help', -> (*_options) { cmd_h }),
744
784
  Command.new('i', 'info', -> (*_options) { cmd_i }),
745
- Command.new('lsa', 'lsavailable', -> (*_options) { cmd_lsa }),
746
- Command.new('lsp', 'lspreferred', -> (*_options) { cmd_lsp }),
785
+ Command.new('l', 'lsavailnets', -> (*_options) { cmd_lsa }),
747
786
  Command.new('n', 'network_name', -> (*_options) { cmd_n }),
748
787
  Command.new('of', 'off', -> (*_options) { cmd_of }),
749
788
  Command.new('on', 'on', -> (*_options) { cmd_on }),
750
789
  Command.new('pa', 'password', -> (*options) { cmd_pa(*options) }),
790
+ Command.new('pr', 'prefnets', -> (*_options) { cmd_pr }),
751
791
  Command.new('q', 'quit', -> (*_options) { cmd_q }),
752
- Command.new('r', 'rm', -> (*options) { cmd_r(*options) }),
792
+ Command.new('r', 'rmprefnets', -> (*options) { cmd_r(*options) }),
753
793
  Command.new('s', 'shell', -> (*_options) { cmd_s }),
754
794
  Command.new('t', 'till', -> (*options) { cmd_t(*options) }),
755
795
  Command.new('w', 'wifion', -> (*_options) { cmd_w }),
@@ -774,65 +814,86 @@ When in interactive shell mode:
774
814
  begin
775
815
  process_command_line(ARGV[0], ARGV[1..-1])
776
816
  rescue BadCommandError => error
777
- separator_line = "#{'!' * 79}\n"
817
+ separator_line = "! #{'-' * 75} !\n"
778
818
  puts '' << separator_line << error.to_s << "\n" << separator_line
779
819
  exit(-1)
780
820
  end
781
821
  end
782
822
  end
783
- end
784
823
 
785
824
 
825
+ class Main
786
826
 
787
- # @return true if this file is being run as a script, else false
788
- #
789
- # This file could be called as a script in either of these two ways:
790
- #
791
- # 1) by loading this file directly, or
792
- # 2) by running as a gem executable's binstub, in (relatively) '../../../bin'
793
- #
794
- # For example, I get this when running this file as a gem:
795
- # __FILE__ = /Users/kbennett/.rvm/gems/ruby-2.4.0/gems/mac-wifi-1.0.0/bin/mac-wifi
796
- # $0 = /Users/kbennett/.rvm/gems/ruby-2.4.0/bin/mac-wifi
797
- # GEM_PATH = /Users/kbennett/.rvm/gems/ruby-2.4.0:/Users/kbennett/.rvm/gems/ruby-2.4.0@global
827
+ # @return true if this file is being run as a script, else false
828
+ #
829
+ # This file could be called as a script in either of these two ways:
830
+ #
831
+ # 1) by loading this file directly, or
832
+ # 2) by running as a gem executable's binstub, in (relatively) '../../../exe'
833
+ #
834
+ # For example, I get this when running this file as a gem and running:
835
+ #
836
+ # puts "$0: #{$0}"
837
+ # puts "__FILE__: #{__FILE__}"
838
+ # puts "GEM_PATH: #{ENV['GEM_PATH']}"
839
+ #
840
+ # $0: /Users/kbennett/.rvm/gems/ruby-2.4.1/bin/mac-wifi
841
+ # __FILE__: /Users/kbennett/.rvm/gems/ruby-2.4.1/gems/mac-wifi-1.2.0/exe/mac-wifi
842
+ # GEM_PATH: /Users/kbennett/.rvm/gems/ruby-2.4.1:/Users/kbennett/.rvm/gems/ruby-2.4.1@global
798
843
 
799
- def running_as_script?
800
844
 
801
- this_file = File.expand_path(__FILE__)
802
- main_file = File.expand_path($0)
845
+ def running_as_script?
803
846
 
804
- this_file_basename = File.basename(this_file)
805
- main_file_basename = File.basename(main_file)
847
+ this_source_file = File.expand_path(__FILE__)
848
+ called_file = File.expand_path($0)
849
+ return true if called_file == this_source_file
806
850
 
807
- # Please enable this code and report its output if you report any issues with this method:
808
- # puts "__FILE__ = #{this_file}"
809
- # puts "$0 = #{main_file}"
810
- # puts "GEM_PATH = #{ENV['GEM_PATH']}"
851
+ this_source_file_basename = File.basename(this_source_file)
852
+ called_file_basename = File.basename(called_file)
853
+ return false if called_file_basename != this_source_file_basename
811
854
 
812
- return true if main_file == this_file
813
- return false if main_file_basename != this_file_basename
855
+ # If here, then filespecs are different but have the same basename.
856
+ gem_roots = ENV['GEM_PATH'].split(File::PATH_SEPARATOR)
857
+ as_script = gem_roots.any? do |gem_root|
858
+ binstub_candidate_name = File.join(gem_root, 'bin', called_file_basename)
859
+ up_4_from_this_source_file = File.expand_path(File.join(this_source_file, '..', '..', '..', '..'))
860
+ found = ($0 == binstub_candidate_name) && (gem_root == up_4_from_this_source_file)
861
+ found
862
+ end
814
863
 
815
- # If here, then filespecs are different but have the same basename.
816
- gem_paths = ENV['GEM_PATH'].split(File::PATH_SEPARATOR)
817
- gem_paths.any? do |path|
818
- path_plus_basename = File.join(path, 'bin', main_file_basename)
819
- __file__up_4 = File.expand_path(File.join(this_file, '..', '..', '..', '..'))
820
- ($0 == path_plus_basename) && (path == __file__up_4)
864
+ as_script
821
865
  end
822
- end
823
866
 
824
867
 
825
- def assert_os_is_mac_os
826
- unless /darwin/ === RbConfig::CONFIG["host_os"] # e.g. "darwin16.4.0"
827
- raise "This program currently works only on Mac OS. Platform is '#{RbConfig::CONFIG["host_os"]}'."
868
+ def assert_os_is_mac_os
869
+ host_os = RbConfig::CONFIG["host_os"]
870
+ unless /darwin/.match(host_os) # e.g. "darwin16.4.0"
871
+ raise "This program currently works only on Mac OS. Platform is '#{host_os}'."
872
+ end
828
873
  end
829
- end
830
874
 
831
- assert_os_is_mac_os
832
875
 
833
- # If this file is being called as a script, run it.
834
- # Else, it may be loaded to use the model in a different way.
835
- if running_as_script?
836
- MacWifi::CommandLineInterface.new.call
876
+ def call
877
+ assert_os_is_mac_os
878
+
879
+ # If this file is being called as a script, run it.
880
+ # Else, it may be loaded to use the model in a different way.
881
+ if running_as_script?
882
+ begin
883
+ MacWifi::CommandLineInterface.new.call
884
+ rescue => error
885
+ puts error
886
+ stack_trace_filename = './mac-wifi-error-stack-trace.txt'
887
+ File.write(stack_trace_filename, caller.join("\n"))
888
+ puts "Exiting. Stack trace written to '#{File.expand_path(stack_trace_filename)}'."
889
+ exit(-1)
890
+ end
891
+ end
892
+ end
837
893
  end
838
894
 
895
+
896
+ end # module MacWifi
897
+
898
+
899
+ MacWifi::Main.new.call
data/mac-wifi.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  # coding: utf-8
2
2
  # When changing the version, also change the version and the help text in the README.
3
- VERSION = '1.2.0'
3
+ VERSION = '1.3.0'
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "mac-wifi"
@@ -13,13 +13,14 @@ Gem::Specification.new do |spec|
13
13
  spec.license = "MIT"
14
14
 
15
15
  spec.files = `git ls-files`.split($/)
16
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
- spec.require_paths = ['lib']
16
+ spec.bindir = 'exe'
17
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
18
+ # spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ # spec.require_paths = ['lib']
19
20
 
20
- # spec.add_development_dependency "bundler", "~> 1.3"
21
- # spec.add_development_dependency "rake", '~> 10.1'
22
- # spec.add_development_dependency "rspec", '~> 3.0'
21
+ spec.add_development_dependency "bundler", "~> 1.16"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ spec.add_development_dependency "rspec", "~> 3.0"
23
24
 
24
25
  end
25
26
 
metadata CHANGED
@@ -1,15 +1,57 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mac-wifi
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Keith Bennett
8
8
  autorequire:
9
- bindir: bin
9
+ bindir: exe
10
10
  cert_chain: []
11
- date: 2017-10-28 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2017-12-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.16'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.16'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
13
55
  description: A command line interface for managing wifi on a Mac.
14
56
  email:
15
57
  - keithrbennett@gmail.com
@@ -23,7 +65,7 @@ files:
23
65
  - LICENSE.txt
24
66
  - README.md
25
67
  - RELEASE_NOTES.md
26
- - bin/mac-wifi
68
+ - exe/mac-wifi
27
69
  - mac-wifi.gemspec
28
70
  - spec/mac-wifi_spec.rb
29
71
  homepage: https://github.com/keithrbennett/mac-wifi
@@ -46,9 +88,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
46
88
  version: '0'
47
89
  requirements: []
48
90
  rubyforge_project:
49
- rubygems_version: 2.6.13
91
+ rubygems_version: 2.6.14
50
92
  signing_key:
51
93
  specification_version: 4
52
94
  summary: Mac wifi utility
53
- test_files:
54
- - spec/mac-wifi_spec.rb
95
+ test_files: []