tw 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source :rubygems
2
+
3
+ gem 'hoe'
4
+ gem 'newgem'
5
+ gem 'oauth'
6
+ gem 'twitter'
7
+ gem 'rainbow'
8
+ gem 'args_parser'
data/Gemfile.lock ADDED
@@ -0,0 +1,40 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ RedCloth (4.2.9)
5
+ activesupport (2.3.14)
6
+ args_parser (0.1.0)
7
+ faraday (0.8.4)
8
+ multipart-post (~> 1.1)
9
+ hoe (3.1.0)
10
+ rake (~> 0.8)
11
+ multi_json (1.3.6)
12
+ multipart-post (1.1.5)
13
+ newgem (1.5.3)
14
+ RedCloth (>= 4.1.1)
15
+ activesupport (~> 2.3.4)
16
+ hoe (>= 2.4.0)
17
+ rubigen (>= 1.5.3)
18
+ syntax (>= 1.0.0)
19
+ oauth (0.4.7)
20
+ rainbow (1.1.4)
21
+ rake (0.9.2.2)
22
+ rubigen (1.5.8)
23
+ activesupport (>= 2.3.5, < 3.2.0)
24
+ simple_oauth (0.1.9)
25
+ syntax (1.0.0)
26
+ twitter (4.0.0)
27
+ faraday (~> 0.8)
28
+ multi_json (~> 1.3)
29
+ simple_oauth (~> 0.1.6)
30
+
31
+ PLATFORMS
32
+ ruby
33
+
34
+ DEPENDENCIES
35
+ args_parser
36
+ hoe
37
+ newgem
38
+ oauth
39
+ rainbow
40
+ twitter
data/History.txt CHANGED
@@ -1,3 +1,10 @@
1
- === 0.0.1 2011-04-22
1
+ === 0.0.2 2012-10-03
2
2
 
3
- * project start
3
+ * support multi user accounts : --user=NAME
4
+ * tweet from pipe : --pipe
5
+ * option : --search=WORD
6
+ * show version : --version
7
+
8
+ === 0.0.1 2012-09-15
9
+
10
+ * first release
data/Manifest.txt CHANGED
@@ -1,14 +1,19 @@
1
+ Gemfile
2
+ Gemfile.lock
1
3
  History.txt
2
4
  Manifest.txt
3
5
  README.rdoc
4
6
  Rakefile
7
+ bin/tw
5
8
  lib/tw.rb
6
- lib/tw/auth.rb
7
- lib/tw/client.rb
9
+ lib/tw/app/cmds.rb
10
+ lib/tw/app/main.rb
11
+ lib/tw/app/opt_parser.rb
12
+ lib/tw/app/render.rb
13
+ lib/tw/client/auth.rb
14
+ lib/tw/client/error.rb
15
+ lib/tw/client/request.rb
8
16
  lib/tw/conf.rb
9
- lib/tw/opts.rb
10
- lib/tw/render.rb
11
- bin/tw
12
17
  script/console
13
18
  script/destroy
14
19
  script/generate
data/Rakefile CHANGED
@@ -1,5 +1,5 @@
1
1
  require 'rubygems'
2
- gem 'hoe', '>= 2.1.0'
2
+ require 'bundler/setup'
3
3
  require 'hoe'
4
4
  require 'fileutils'
5
5
  require './lib/tw'
@@ -14,8 +14,9 @@ $hoe = Hoe.spec 'tw' do
14
14
  self.developer 'Sho Hashimoto', 'hashimoto@shokai.org'
15
15
  self.rubyforge_name = self.name # TODO this is default value
16
16
  self.extra_deps = [['oauth','>= 0.4.7', '< 1.0.0'],
17
- ['twitter', '>= 3.7.0', '< 4.0.0'],
18
- ['rainbow', '>= 1.1.4', '< 2.0.0']]
17
+ ['twitter', '>= 4.0.0', '< 5.0.0'],
18
+ ['args_parser', '>= 0.1.0'],
19
+ ['rainbow', '>= 1.1.4', '< 2.0.0']]
19
20
 
20
21
  end
21
22
 
data/bin/tw CHANGED
@@ -1,39 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
- require File.expand_path '../lib/tw', File.dirname(__FILE__)
2
+ $:.unshift File.expand_path '../lib', File.dirname(__FILE__)
3
+ require 'rubygems'
4
+ require 'tw'
5
+ require 'tw/app/main'
3
6
 
4
- c = Tw::Client.new
5
-
6
- if ARGV.size < 1
7
- Tw::Render.display c.mentions
8
- elsif Tw::Opts.all_cmds? ARGV
9
- Tw::Render.display ARGV.map{|arg|
10
- if word = Tw::Opts.search_word?(arg)
11
- res = c.search word
12
- elsif user = Tw::Opts.username?(arg)
13
- res = c.user_timeline user
14
- elsif (user, list = Tw::Opts.listname?(arg)) != false
15
- res = c.list_timeline(user, list)
16
- end
17
- res
18
- }
19
- else
20
- if ARGV.size == 1 and ARGV.first =~ /^-+$/
21
- ARGF.each do |line|
22
- line.split(/(.{140})/u).select{|m|m.size>0}.each do |message|
23
- c.tweet message
24
- end
25
- sleep 1
26
- end
27
- else
28
- message = ARGV.join(' ')
29
- if (len = message.split(//u).size) > 140
30
- puts "tweet too long (#{len} chars)"
31
- exit 1
32
- else
33
- puts "tweet \"#{message}\"? (#{len} chars)"
34
- puts '[Y/n]'
35
- exit if STDIN.gets.strip =~ /^n/i
36
- end
37
- c.tweet message
38
- end
39
- end
7
+ app = Tw::App.new
8
+ app.run ARGV
@@ -0,0 +1,80 @@
1
+
2
+ module Tw::App
3
+ class Main
4
+
5
+ private
6
+ def regist_cmds
7
+ cmd :user do |v|
8
+ if v == true
9
+ STDERR.puts 'e.g. tw "hello" --user=USERNAME'
10
+ on_error
11
+ end
12
+ end
13
+
14
+ cmd 'user:add' do |v|
15
+ client.add_user
16
+ on_exit
17
+ end
18
+
19
+ cmd 'user:list' do |v|
20
+ Tw::Conf['users'].keys.each do |name|
21
+ puts name == Tw::Conf['default_user'] ? "* #{name}" : " #{name}"
22
+ end
23
+ puts "(#{Tw::Conf['users'].size} users)"
24
+ on_exit
25
+ end
26
+
27
+ cmd 'user:default' do |v|
28
+ if v.class == String
29
+ Tw::Conf['default_user'] = v
30
+ Tw::Conf.save
31
+ puts "set default user \"@#{Tw::Conf['default_user']}\""
32
+ else
33
+ puts "@"+Tw::Conf['default_user'] if Tw::Conf['default_user']
34
+ puts "e.g. tw --user:default=USERNAME"
35
+ end
36
+ on_exit
37
+ end
38
+
39
+ cmd :search do |v|
40
+ if v.class == String
41
+ auth
42
+ Render.display client.search v
43
+ on_exit
44
+ else
45
+ STDERR.puts "e.g. tw --search=ruby"
46
+ on_error
47
+ end
48
+ end
49
+
50
+ cmd :pipe do |v|
51
+ auth
52
+ STDIN.read.split(/[\r\n]+/).each do |line|
53
+ line.split(/(.{140})/u).select{|m|m.size>0}.each do |message|
54
+ client.tweet message
55
+ end
56
+ sleep 1
57
+ end
58
+ on_exit
59
+ end
60
+
61
+ cmd :version do |v|
62
+ puts "tw version #{Tw::VERSION}"
63
+ on_exit
64
+ end
65
+ end
66
+
67
+ def cmd(name, &block)
68
+ if block_given?
69
+ cmds[name.to_sym] = block
70
+ else
71
+ return cmds[name.to_sym]
72
+ end
73
+ end
74
+
75
+ def cmds
76
+ @cmds ||= Hash.new
77
+ end
78
+
79
+ end
80
+ end
@@ -0,0 +1,101 @@
1
+
2
+ require File.expand_path 'opt_parser', File.dirname(__FILE__)
3
+ require File.expand_path 'cmds', File.dirname(__FILE__)
4
+ require File.expand_path 'render', File.dirname(__FILE__)
5
+
6
+ module Tw::App
7
+
8
+ def self.new
9
+ Main.new
10
+ end
11
+
12
+ class Main
13
+ def initialize
14
+ on_exit do
15
+ exit 0
16
+ end
17
+
18
+ on_error do
19
+ exit 1
20
+ end
21
+ end
22
+
23
+ def client
24
+ @client ||= Tw::Client.new
25
+ end
26
+
27
+ def on_exit(&block)
28
+ if block_given?
29
+ @on_exit = block
30
+ else
31
+ @on_exit.call if @on_exit
32
+ end
33
+ end
34
+
35
+ def on_error(&block)
36
+ if block_given?
37
+ @on_error = block
38
+ else
39
+ @on_error.call if @on_error
40
+ end
41
+ end
42
+
43
+ def run(argv)
44
+ @parser = ArgsParser.parse argv, :style => :equal do
45
+ arg :user, 'user account'
46
+ arg 'user:add', 'add user'
47
+ arg 'user:list', 'show user list'
48
+ arg 'user:default', 'set default user'
49
+ arg :timeline, 'show timeline'
50
+ arg :search, 'search public timeline'
51
+ arg :pipe, 'pipe tweet'
52
+ arg :version, 'show version', :alias => :v
53
+ arg :help, 'show help', :alias => :h
54
+ end
55
+
56
+ if @parser.has_option? :help
57
+ STDERR.puts @parser.help
58
+ on_exit
59
+ end
60
+
61
+ regist_cmds
62
+
63
+ cmds.each do |name, cmd|
64
+ next unless @parser[name]
65
+ cmd.call @parser[name]
66
+ end
67
+
68
+ auth
69
+ if @parser.argv.size < 1
70
+ Render.display client.mentions
71
+ elsif all_requests?(@parser.argv)
72
+ Render.display @parser.argv.map{|arg|
73
+ if user = username?(arg)
74
+ res = client.user_timeline user
75
+ elsif (user, list =listname?(arg)) != false
76
+ res = client.list_timeline(user, list)
77
+ end
78
+ res
79
+ }
80
+ else
81
+ message = @parser.argv.join(' ')
82
+ if (len = message.split(//u).size) > 140
83
+ puts "tweet too long (#{len} chars)"
84
+ on_error
85
+ else
86
+ puts "tweet \"#{message}\"? (#{len} chars)"
87
+ puts '[Y/n]'
88
+ on_exit if STDIN.gets.strip =~ /^n/i
89
+ end
90
+ client.tweet message
91
+ end
92
+ end
93
+
94
+ private
95
+ def auth
96
+ return unless @parser
97
+ client.auth @parser.has_param?(:user) ? @parser[:user] : nil
98
+ end
99
+
100
+ end
101
+ end
@@ -0,0 +1,20 @@
1
+
2
+ module Tw::App
3
+ class Main
4
+ def username?(arg)
5
+ arg =~ /^@[a-zA-Z0-9_]+$/ ? arg.scan(/^@([a-zA-Z0-9_]+)$/)[0][0] : false
6
+ end
7
+
8
+ def listname?(arg)
9
+ arg =~ /^@[a-zA-Z0-9_]+\/[a-zA-Z0-9_]+$/ ? arg.scan(/^@([a-zA-Z0-9_]+)\/([a-zA-Z0-9_]+)$/)[0] : false
10
+ end
11
+
12
+ def request?(arg)
13
+ username?(arg) or listname?(arg)
14
+ end
15
+
16
+ def all_requests?(args)
17
+ !args.map{|arg| request? arg}.include?(false)
18
+ end
19
+ end
20
+ end
@@ -1,5 +1,5 @@
1
1
 
2
- module Tw
2
+ module Tw::App
3
3
  class Render
4
4
  def self.color_code(str)
5
5
  colors = Sickill::Rainbow::TERM_COLORS.keys - [:default, :black, :white]
@@ -0,0 +1,50 @@
1
+
2
+ module Tw
3
+ class Client
4
+
5
+ def initialize
6
+ end
7
+
8
+ def auth(user=nil)
9
+ user = Conf['default_user'] unless user
10
+ if user == nil and Conf['users'].empty?
11
+ add_user
12
+ return
13
+ end
14
+ raise ArgumentError, "Argument must be instance of String or Hash." unless [Hash, String].include? user.class
15
+ if user.class == String
16
+ raise ArgumentError, "user \"#{user}\" not exists." unless Conf['users'].include? user
17
+ user = Conf['users'][user]
18
+ end
19
+ Twitter.configure do |c|
20
+ c.consumer_key = Conf['consumer_key']
21
+ c.consumer_secret = Conf['consumer_secret']
22
+ c.oauth_token = user['access_token']
23
+ c.oauth_token_secret = user['access_secret']
24
+ end
25
+ end
26
+
27
+ def add_user
28
+ consumer = OAuth::Consumer.new(Conf['consumer_key'], Conf['consumer_secret'],
29
+ :site => 'http://twitter.com')
30
+ request_token = consumer.get_request_token
31
+ puts cmd = "open #{request_token.authorize_url}"
32
+ system cmd
33
+ print 'input PIN Number: '
34
+ verifier = STDIN.gets.strip
35
+ access_token = request_token.get_access_token(:oauth_verifier => verifier)
36
+ self.auth('access_token' => access_token.token,
37
+ 'access_secret' => access_token.secret)
38
+ u = Twitter.user
39
+ Conf['users'][u.screen_name] = {
40
+ 'access_token' => access_token.token,
41
+ 'access_secret' => access_token.secret,
42
+ 'id' => u.id
43
+ }
44
+ Conf['default_user'] = u.screen_name unless Conf['default_user']
45
+ Conf.save
46
+ puts "add \"@#{u.screen_name}\""
47
+ end
48
+
49
+ end
50
+ end
@@ -0,0 +1,4 @@
1
+ module Tw
2
+ class Error < StandardError
3
+ end
4
+ end
File without changes
data/lib/tw/conf.rb CHANGED
@@ -4,8 +4,11 @@ module Tw
4
4
 
5
5
  def self.default
6
6
  {
7
+ 'version' => Tw::VERSION,
7
8
  'consumer_key' => 'AYhhkOC8H2yTZyelz3uw',
8
- 'consumer_secret' => '28Ba8YyFDSPgoCYAmH5ANqOmT6qVS8gIhKnUiDbIpU'
9
+ 'consumer_secret' => '28Ba8YyFDSPgoCYAmH5ANqOmT6qVS8gIhKnUiDbIpU',
10
+ 'default_user' => nil,
11
+ 'users' => {}
9
12
  }
10
13
  end
11
14
 
@@ -18,7 +21,7 @@ module Tw
18
21
  end
19
22
 
20
23
  def self.conf_file
21
- "#{ENV['HOME']}/.tw.conf"
24
+ "#{ENV['HOME']}/.tw.yml"
22
25
  end
23
26
 
24
27
  def self.conf
@@ -38,6 +41,17 @@ module Tw
38
41
  )
39
42
  end
40
43
 
44
+ def self.to_yaml
45
+ self.conf.to_yaml
46
+ end
47
+
48
+ def self.save
49
+ open_conf_file('w+') do |f|
50
+ f.write conf.to_yaml
51
+ end
52
+ end
53
+
54
+ private
41
55
  def self.open_conf_file(opt=nil, &block)
42
56
  if block_given?
43
57
  yield open(self.conf_file, opt)
@@ -45,10 +59,5 @@ module Tw
45
59
  return open(self.conf_file, opt)
46
60
  end
47
61
  end
48
-
49
- def self.to_yaml
50
- self.conf.to_yaml
51
- end
52
-
53
62
  end
54
63
  end
data/lib/tw.rb CHANGED
@@ -1,21 +1,17 @@
1
1
  $:.unshift(File.dirname(__FILE__)) unless
2
2
  $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
3
 
4
- require 'rubygems'
5
4
  require 'oauth'
6
5
  require 'twitter'
7
6
  require 'yaml'
8
7
  require 'time'
8
+ require 'args_parser'
9
9
  require 'rainbow'
10
- require 'tw/auth'
11
- require 'tw/client'
12
10
  require 'tw/conf'
13
- require 'tw/opts'
14
- require 'tw/render'
11
+ require 'tw/client/auth'
12
+ require 'tw/client/request'
13
+ require 'tw/client/error'
15
14
 
16
15
  module Tw
17
- VERSION = '0.0.1'
18
-
19
- class Error < StandardError
20
- end
16
+ VERSION = '0.0.2'
21
17
  end
data/test/test_helper.rb CHANGED
@@ -1,3 +1,4 @@
1
+ require 'bundler'
1
2
  require 'stringio'
2
3
  require 'test/unit'
3
4
  require File.dirname(__FILE__) + '/../lib/tw'
data/test/test_tw.rb CHANGED
@@ -3,9 +3,34 @@ require File.dirname(__FILE__) + '/test_helper.rb'
3
3
  class TestTw < Test::Unit::TestCase
4
4
 
5
5
  def setup
6
+ @client = Tw::Client.new
7
+ @client.auth
8
+ end
9
+
10
+ def response?(arr)
11
+ return false unless arr.kind_of? Array
12
+ arr.each do |i|
13
+ return false if !(i[:id].class == Fixnum and
14
+ i[:user] =~ /^[a-zA-Z0-9_]+$/ and
15
+ i[:text].kind_of? String and
16
+ i[:time].kind_of? Time)
17
+ end
18
+ return true
6
19
  end
7
20
 
8
- def test_truth
9
- assert true
21
+ def test_mentions
22
+ assert response? @client.mentions
23
+ end
24
+
25
+ def test_search
26
+ assert response? @client.search('ruby')
27
+ end
28
+
29
+ def test_user_timeline
30
+ assert response? @client.user_timeline 'shokai'
31
+ end
32
+
33
+ def test_list_timeline
34
+ assert response? @client.list_timeline('shokai', 'arr')
10
35
  end
11
36
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tw
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-09-15 00:00:00.000000000 Z
12
+ date: 2012-10-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: oauth
@@ -40,10 +40,10 @@ dependencies:
40
40
  requirements:
41
41
  - - ! '>='
42
42
  - !ruby/object:Gem::Version
43
- version: 3.7.0
43
+ version: 4.0.0
44
44
  - - <
45
45
  - !ruby/object:Gem::Version
46
- version: 4.0.0
46
+ version: 5.0.0
47
47
  type: :runtime
48
48
  prerelease: false
49
49
  version_requirements: !ruby/object:Gem::Requirement
@@ -51,10 +51,26 @@ dependencies:
51
51
  requirements:
52
52
  - - ! '>='
53
53
  - !ruby/object:Gem::Version
54
- version: 3.7.0
54
+ version: 4.0.0
55
55
  - - <
56
56
  - !ruby/object:Gem::Version
57
- version: 4.0.0
57
+ version: 5.0.0
58
+ - !ruby/object:Gem::Dependency
59
+ name: args_parser
60
+ requirement: !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: 0.1.0
66
+ type: :runtime
67
+ prerelease: false
68
+ version_requirements: !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ! '>='
72
+ - !ruby/object:Gem::Version
73
+ version: 0.1.0
58
74
  - !ruby/object:Gem::Dependency
59
75
  name: rainbow
60
76
  requirement: !ruby/object:Gem::Requirement
@@ -116,7 +132,7 @@ dependencies:
116
132
  requirements:
117
133
  - - ~>
118
134
  - !ruby/object:Gem::Version
119
- version: '3.0'
135
+ version: '3.1'
120
136
  type: :development
121
137
  prerelease: false
122
138
  version_requirements: !ruby/object:Gem::Requirement
@@ -124,7 +140,7 @@ dependencies:
124
140
  requirements:
125
141
  - - ~>
126
142
  - !ruby/object:Gem::Version
127
- version: '3.0'
143
+ version: '3.1'
128
144
  description: ! '* twitter client.'
129
145
  email:
130
146
  - hashimoto@shokai.org
@@ -136,17 +152,22 @@ extra_rdoc_files:
136
152
  - Manifest.txt
137
153
  - README.rdoc
138
154
  files:
155
+ - Gemfile
156
+ - Gemfile.lock
139
157
  - History.txt
140
158
  - Manifest.txt
141
159
  - README.rdoc
142
160
  - Rakefile
161
+ - bin/tw
143
162
  - lib/tw.rb
144
- - lib/tw/auth.rb
145
- - lib/tw/client.rb
163
+ - lib/tw/app/cmds.rb
164
+ - lib/tw/app/main.rb
165
+ - lib/tw/app/opt_parser.rb
166
+ - lib/tw/app/render.rb
167
+ - lib/tw/client/auth.rb
168
+ - lib/tw/client/error.rb
169
+ - lib/tw/client/request.rb
146
170
  - lib/tw/conf.rb
147
- - lib/tw/opts.rb
148
- - lib/tw/render.rb
149
- - bin/tw
150
171
  - script/console
151
172
  - script/destroy
152
173
  - script/generate
@@ -167,6 +188,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
167
188
  - - ! '>='
168
189
  - !ruby/object:Gem::Version
169
190
  version: '0'
191
+ segments:
192
+ - 0
193
+ hash: -4067215787574588106
170
194
  required_rubygems_version: !ruby/object:Gem::Requirement
171
195
  none: false
172
196
  requirements:
data/lib/tw/auth.rb DELETED
@@ -1,35 +0,0 @@
1
-
2
- module Tw
3
- class Client
4
-
5
- def initialize
6
- if !Conf['access_token'] or !Conf['access_secret']
7
- consumer = OAuth::Consumer.new(Conf['consumer_key'], Conf['consumer_secret'],
8
- :site => 'http://twitter.com')
9
- begin
10
- request_token = consumer.get_request_token
11
- puts "open #{request_token.authorize_url}"
12
- system "open #{request_token.authorize_url}"
13
- print 'input PIN Number: '
14
- oauth_verifier = gets.strip
15
- access_token = request_token.get_access_token(:oauth_verifier => oauth_verifier)
16
- Conf['access_token'] = access_token.token
17
- Conf['access_secret'] = access_token.secret
18
- rescue => e
19
- raise Error.new "#{e.to_s}\ncheck config file(#{Conf.conf_file}) and twitter.com status."
20
- end
21
- Conf.open_conf_file('w+'){|f|
22
- f.puts Conf.to_yaml
23
- }
24
- end
25
-
26
- Twitter.configure do |c|
27
- c.consumer_key = Conf['consumer_key']
28
- c.consumer_secret = Conf['consumer_secret']
29
- c.oauth_token = Conf['access_token']
30
- c.oauth_token_secret = Conf['access_secret']
31
- end
32
- end
33
-
34
- end
35
- end
data/lib/tw/opts.rb DELETED
@@ -1,27 +0,0 @@
1
-
2
- module Tw
3
- class Opts
4
- def self.search_word?(str)
5
- str =~ /^\?.+$/ ? str.scan(/^\?(.+)$/)[0][0] : false
6
- end
7
-
8
- def self.username?(str)
9
- str =~ /^@[a-zA-Z0-9_]+$/ ? str.scan(/^@([a-zA-Z0-9_]+)$/)[0][0] : false
10
- end
11
-
12
- def self.listname?(str)
13
- if str =~ /^@[a-zA-Z0-9_]+\/[a-zA-Z0-9_]+$/
14
- return str.scan(/^@([a-zA-Z0-9_]+)\/([a-zA-Z0-9_]+)$/).first
15
- end
16
- false
17
- end
18
-
19
- def self.cmd?(str)
20
- search_word?(str) || username?(str) || listname?(str)
21
- end
22
-
23
- def self.all_cmds?(argv)
24
- argv.map{|arg| cmd? arg}.count(false) < 1
25
- end
26
- end
27
- end