cinch-commands 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,3 @@
1
+ -
2
+ ChangeLog.*
3
+ LICENSE.txt
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ doc/
2
+ pkg/
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --colour --format documentation
data/.yardopts ADDED
@@ -0,0 +1 @@
1
+ --markup markdown --title "cinch-commands Documentation" --protected
data/ChangeLog.md ADDED
@@ -0,0 +1,9 @@
1
+ ### 0.1.0 / 2013-06-02
2
+
3
+ * Initial release:
4
+ * Argument types.
5
+ * `!help` command with detailed output:
6
+ * Usages
7
+ * Summaries
8
+ * Descriptions
9
+
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012-2013 Hal Brodigan
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,59 @@
1
+ # cinch-commands
2
+
3
+ * [Source](https://github.com/postmodern/cinch-commands)
4
+ * [Issues](https://github.com/postmodern/cinch-commands/issues)
5
+ * [Documentation](http://rubydoc.info/gems/cinch-commands/frames)
6
+
7
+ ## Description
8
+
9
+ Allows defining multiple commands within a Cinch Plugin.
10
+
11
+ ## Features
12
+
13
+ * Argument types.
14
+ * `!help` command with detailed output:
15
+ * Usages
16
+ * Summaries
17
+ * Descriptions
18
+
19
+ ## Examples
20
+
21
+ require 'cinch/commands'
22
+
23
+ class MyPlugin
24
+
25
+ include Cinch::Plugin
26
+ include Cinch::Commands
27
+
28
+ command :foo, {arg1: :string, arg2: :integer},
29
+ summary: "Does foo",
30
+ description: %{
31
+ ...
32
+ }
33
+
34
+ command :bar, {name: :string},
35
+ aliases: [:b]
36
+
37
+ def foo(m,arg1,arg2)
38
+ end
39
+
40
+ def bar(m,name)
41
+ end
42
+
43
+ end
44
+
45
+ ## Requirements
46
+
47
+ * [cinch][1] ~> 2.0
48
+
49
+ ## Install
50
+
51
+ $ gem install cinch-commands
52
+
53
+ ## Copyright
54
+
55
+ Copyright (c) 2012-2013 Hal Brodigan
56
+
57
+ See {file:LICENSE.txt} for details.
58
+
59
+ [1]: https://github.com/cinchrb/cinch#readme
data/Rakefile ADDED
@@ -0,0 +1,40 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'rake'
5
+
6
+ begin
7
+ gem 'rubygems-tasks', '~> 0.1'
8
+ require 'rubygems/tasks'
9
+
10
+ Gem::Tasks.new
11
+ rescue LoadError => e
12
+ warn e.message
13
+ warn "Run `gem install rubygems-tasks` to install 'rubygems/tasks'."
14
+ end
15
+
16
+ begin
17
+ gem 'rspec', '~> 2.4'
18
+ require 'rspec/core/rake_task'
19
+
20
+ RSpec::Core::RakeTask.new
21
+ rescue LoadError => e
22
+ task :spec do
23
+ abort "Please run `gem install rspec` to install RSpec."
24
+ end
25
+ end
26
+
27
+ task :test => :spec
28
+ task :default => :spec
29
+
30
+ begin
31
+ gem 'yard', '~> 0.7'
32
+ require 'yard'
33
+
34
+ YARD::Rake::YardocTask.new
35
+ rescue LoadError => e
36
+ task :yard do
37
+ abort "Please run `gem install yard` to install YARD."
38
+ end
39
+ end
40
+ task :doc => :yard
@@ -0,0 +1,60 @@
1
+ # encoding: utf-8
2
+
3
+ require 'yaml'
4
+
5
+ Gem::Specification.new do |gem|
6
+ gemspec = YAML.load_file('gemspec.yml')
7
+
8
+ gem.name = gemspec.fetch('name')
9
+ gem.version = gemspec.fetch('version') do
10
+ lib_dir = File.join(File.dirname(__FILE__),'lib')
11
+ $LOAD_PATH << lib_dir unless $LOAD_PATH.include?(lib_dir)
12
+
13
+ require 'cinch/commands/version'
14
+ Cinch::Commands::VERSION
15
+ end
16
+
17
+ gem.summary = gemspec['summary']
18
+ gem.description = gemspec['description']
19
+ gem.licenses = Array(gemspec['license'])
20
+ gem.authors = Array(gemspec['authors'])
21
+ gem.email = gemspec['email']
22
+ gem.homepage = gemspec['homepage']
23
+
24
+ glob = lambda { |patterns| gem.files & Dir[*patterns] }
25
+
26
+ gem.files = `git ls-files`.split($/)
27
+ gem.files = glob[gemspec['files']] if gemspec['files']
28
+
29
+ gem.executables = gemspec.fetch('executables') do
30
+ glob['bin/*'].map { |path| File.basename(path) }
31
+ end
32
+ gem.default_executable = gem.executables.first if Gem::VERSION < '1.7.'
33
+
34
+ gem.extensions = glob[gemspec['extensions'] || 'ext/**/extconf.rb']
35
+ gem.test_files = glob[gemspec['test_files'] || '{test/{**/}*_test.rb']
36
+ gem.extra_rdoc_files = glob[gemspec['extra_doc_files'] || '*.{txt,md}']
37
+
38
+ gem.require_paths = Array(gemspec.fetch('require_paths') {
39
+ %w[ext lib].select { |dir| File.directory?(dir) }
40
+ })
41
+
42
+ gem.requirements = gemspec['requirements']
43
+ gem.required_ruby_version = gemspec['required_ruby_version']
44
+ gem.required_rubygems_version = gemspec['required_rubygems_version']
45
+ gem.post_install_message = gemspec['post_install_message']
46
+
47
+ split = lambda { |string| string.split(/,\s*/) }
48
+
49
+ if gemspec['dependencies']
50
+ gemspec['dependencies'].each do |name,versions|
51
+ gem.add_dependency(name,split[versions])
52
+ end
53
+ end
54
+
55
+ if gemspec['development_dependencies']
56
+ gemspec['development_dependencies'].each do |name,versions|
57
+ gem.add_development_dependency(name,split[versions])
58
+ end
59
+ end
60
+ end
data/gemspec.yml ADDED
@@ -0,0 +1,18 @@
1
+ name: cinch-commands
2
+ summary: Define multiple commands within a Cinch Plugin
3
+ description: |
4
+ Allows defining multiple commands within a Cinch Plugin.
5
+ Also provides a !help command with detailed output.
6
+
7
+ license: MIT
8
+ authors: Postmodern
9
+ email: postmodern.mod3@gmail.com
10
+ homepage: https://github.com/postmodern/cinch-commands#readme
11
+
12
+ dependencies:
13
+ cinch: ~> 2.0
14
+
15
+ development_dependencies:
16
+ rubygems-tasks: ~> 0.2
17
+ rspec: ~> 2.4
18
+ yard: ~> 0.7
@@ -0,0 +1,3 @@
1
+ require 'cinch/commands/commands'
2
+ require 'cinch/commands/help'
3
+ require 'cinch/commands/version'
@@ -0,0 +1,118 @@
1
+ module Cinch
2
+ module Commands
3
+ #
4
+ # @api semipublic
5
+ #
6
+ class Command
7
+
8
+ # Argument formats
9
+ ARG_FORMATS = {
10
+ string: /\S+/,
11
+ integer: /\d+/,
12
+ float: /\d*\.\d+/,
13
+ text: /.+/
14
+ }
15
+
16
+ # Name of the command
17
+ attr_reader :name
18
+
19
+ # Argument names/formats
20
+ attr_reader :arguments
21
+
22
+ # Short summary of the command
23
+ attr_reader :summary
24
+
25
+ # Long description of the command
26
+ attr_reader :description
27
+
28
+ #
29
+ # Creates a new command.
30
+ #
31
+ # @param [Symbol] name
32
+ # Name of the command.
33
+ #
34
+ # @param [Hash{Symbol => Symbol,Regexp,String,Array}] arguments
35
+ # Arguments names and their formats or possible values.
36
+ #
37
+ # @param [Hash] options
38
+ # Additional options.
39
+ #
40
+ # @option options [Array] :aliases
41
+ # Additiona aliases for the command.
42
+ #
43
+ # @option options [String] :summary
44
+ # Short summary of the command.
45
+ #
46
+ # @option options [String] :description
47
+ # Long description of the command.
48
+ #
49
+ def initialize(name,arguments,options={})
50
+ @name = name.to_s
51
+ @arguments = arguments
52
+ @aliases = options.fetch(:aliases,[]).map(&:to_s)
53
+
54
+ @summary = options[:summary]
55
+ @description = options[:description]
56
+ end
57
+
58
+ #
59
+ # The names for the command.
60
+ #
61
+ # @return [Array<String>]
62
+ # Command names.
63
+ #
64
+ def names
65
+ [@name] + @aliases
66
+ end
67
+
68
+ #
69
+ # Creates a Regular Expression that matches invocations of the command.
70
+ #
71
+ # @return [Regexp]
72
+ # A Regular Expression that matches the command and captures it's
73
+ # arguments.
74
+ #
75
+ def regexp
76
+ pattern = '(?:' + Regexp.union([@name] + @aliases).source + ')'
77
+
78
+ @arguments.each_value do |format|
79
+ arg_regexp = case format
80
+ when Array then Regexp.union(format)
81
+ when Regexp then format
82
+ when Symbol then ARG_FORMATS.fetch(format)
83
+ else Regexp.escape(format.to_s)
84
+ end
85
+
86
+ pattern << ' (' << arg_regexp.source << ')'
87
+ end
88
+
89
+ # match the full message
90
+ pattern << '$'
91
+
92
+ return Regexp.new(pattern)
93
+ end
94
+
95
+ #
96
+ # The usage string for the command.
97
+ #
98
+ # @return [String]
99
+ # The usage string for the command and it's arguments.
100
+ #
101
+ def usage
102
+ usage = "#{@name}"
103
+
104
+ @arguments.each do |arg,format|
105
+ usage << ' ' << case format
106
+ when Array then "[#{format.join('|')}]"
107
+ when Regexp then format.source
108
+ when Symbol then arg.to_s.upcase
109
+ else format.to_s
110
+ end
111
+ end
112
+
113
+ return usage
114
+ end
115
+
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,66 @@
1
+ require 'cinch/commands/command'
2
+
3
+ require 'cinch/helpers'
4
+ require 'cinch/plugin'
5
+
6
+ module Cinch
7
+ module Commands
8
+
9
+ def self.included(base)
10
+ base.send :include, Cinch::Plugin
11
+ base.send :extend, ClassMethods
12
+ end
13
+
14
+ module ClassMethods
15
+ #
16
+ # All registered commands.
17
+ #
18
+ # @return [Array<Command>]
19
+ # The registered commands.
20
+ #
21
+ # @api semipublic
22
+ #
23
+ def commands
24
+ @commands ||= []
25
+ end
26
+
27
+ protected
28
+
29
+ #
30
+ # Registers a command.
31
+ #
32
+ # @param [Symbol] name
33
+ #
34
+ # @param [Hash{Symbol => Symbol,Regexp}] arguments
35
+ #
36
+ # @param [Hash] options
37
+ # Additional options.
38
+ #
39
+ # @option options [String] :summary
40
+ # The short summary for the command.
41
+ #
42
+ # @option options [String] :description
43
+ # The long description for the command.
44
+ #
45
+ # @return [Command]
46
+ # The new command.
47
+ #
48
+ # @example
49
+ # command :grant, {name: :string, :level: :integer},
50
+ # summary: "Grants access",
51
+ # description: %{
52
+ # Grants a certain level of access to the user
53
+ # }
54
+ #
55
+ def command(name,arguments={},options={})
56
+ new_command = Command.new(name,arguments,options)
57
+
58
+ match(new_command.regexp, method: name)
59
+
60
+ commands << new_command
61
+ return new_command
62
+ end
63
+ end
64
+
65
+ end
66
+ end
@@ -0,0 +1,95 @@
1
+ require 'cinch/commands/commands'
2
+
3
+ module Cinch
4
+ module Commands
5
+ #
6
+ # Generic `!help` command that lists all commands.
7
+ #
8
+ class Help
9
+
10
+ include Cinch::Commands
11
+
12
+ command :help, {command: :string},
13
+ summary: %{Displays help information for the COMMAND},
14
+ description: %{
15
+ Finds the COMMAND and prints the usage and description for the
16
+ COMMAND.
17
+ }
18
+
19
+ command :help, {},
20
+ summary: "Lists available commands",
21
+ description: %{
22
+ If no COMMAND argument is given, then all commands will be listed.
23
+ }
24
+
25
+ #
26
+ # Displays a list of commands or the help information for a specific
27
+ # command.
28
+ #
29
+ # @param [Cinch::Message]
30
+ # The message that invoked `!help`.
31
+ #
32
+ # @param [String] command
33
+ # The specific command to list help information for.
34
+ #
35
+ def help(m,command=nil)
36
+ if command
37
+ found = commands_named(command)
38
+
39
+ if found.empty?
40
+ m.reply "help: Unknown command #{command.dump}"
41
+ else
42
+ # print all usages
43
+ found.each { |cmd| m.reply cmd.usage }
44
+
45
+ # print the description of the first command
46
+ m.reply ''
47
+ m.reply found.first.description
48
+ end
49
+ else
50
+ each_command do |cmd|
51
+ m.reply "#{cmd.usage} - #{cmd.summary}"
52
+ end
53
+ end
54
+ end
55
+
56
+ protected
57
+
58
+ #
59
+ # Enumerates over every command.
60
+ #
61
+ # @yield [command]
62
+ # The given block will be passed every command.
63
+ #
64
+ # @yieldparam [Command] command
65
+ # A command.
66
+ #
67
+ # @return [Enumerator]
68
+ # If no block is given, an Enumerator will be returned.
69
+ #
70
+ def each_command(&block)
71
+ return enum_for(__method__) unless block_given?
72
+
73
+ bot.config.plugins.plugins.each do |plugin|
74
+ if plugin < Cinch::Commands
75
+ plugin.commands.each(&block)
76
+ end
77
+ end
78
+ end
79
+
80
+ #
81
+ # Finds all commands with a similar name.
82
+ #
83
+ # @param [String] name
84
+ # The name to search for.
85
+ #
86
+ # @return [Array<Command>]
87
+ # The commands with the matching name.
88
+ #
89
+ def commands_named(name)
90
+ each_command.select { |command| command.name == name }
91
+ end
92
+
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,6 @@
1
+ module Cinch
2
+ module Commands
3
+ # cinch-commands version
4
+ VERSION = "0.1.0"
5
+ end
6
+ end
@@ -0,0 +1,73 @@
1
+ require 'spec_helper'
2
+ require 'cinch/commands/command'
3
+
4
+ describe Cinch::Commands::Command do
5
+ let(:command_name) { 'foo' }
6
+ let(:arguments) { {name: :string, level: :integer, flag: %w[a o v]} }
7
+
8
+ let(:summary) { 'Foo command' }
9
+ let(:description) { 'This is the foo command' }
10
+
11
+ describe "#regexp" do
12
+ let(:command_alias) { :fu }
13
+
14
+ let(:command) do
15
+ described_class.new(
16
+ command_name, arguments,
17
+ summary: summary,
18
+ description: description,
19
+ aliases: [command_alias]
20
+ )
21
+ end
22
+
23
+ let(:name_arg) { 'bob' }
24
+ let(:level_arg) { '20' }
25
+ let(:flag_arg) { 'o' }
26
+ let(:args) { "#{name_arg} #{level_arg} #{flag_arg}" }
27
+
28
+ subject { command.regexp }
29
+
30
+ it { should be_kind_of(Regexp) }
31
+
32
+ it "should match the primary command-name" do
33
+ "#{command_name} #{args}".should =~ subject
34
+ end
35
+
36
+ it "should match the command-name aliases" do
37
+ "#{command_alias} #{args}".should =~ subject
38
+ end
39
+
40
+ it "should capture the arguments" do
41
+ match = "#{command_name} #{args}".match(subject)
42
+
43
+ match[1].should == name_arg
44
+ match[2].should == level_arg
45
+ match[3].should == flag_arg
46
+ end
47
+
48
+ it "should match the formats of the arguments" do
49
+ "#{command_name} xxxxx xxxx xxxxx".should_not =~ subject
50
+ end
51
+ end
52
+
53
+ describe "#usage" do
54
+ let(:command) do
55
+ described_class.new(
56
+ command_name, arguments,
57
+ summary: summary,
58
+ description: description
59
+
60
+ )
61
+ end
62
+
63
+ subject { command.usage }
64
+
65
+ it "should include the command name" do
66
+ subject.start_with?(command_name).should be_true
67
+ end
68
+
69
+ it "should include the upper-case argument names" do
70
+ subject.should include("NAME LEVEL")
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,8 @@
1
+ require 'spec_helper'
2
+ require 'cinch/commands'
3
+
4
+ describe Cinch::Commands do
5
+ it "should have a VERSION constant" do
6
+ subject.const_get('VERSION').should_not be_empty
7
+ end
8
+ end
@@ -0,0 +1,5 @@
1
+ gem 'rspec', '~> 2.4'
2
+ require 'rspec'
3
+ require 'cinch/commands/version'
4
+
5
+ include Cinch::Commands
metadata ADDED
@@ -0,0 +1,134 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cinch-commands
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Postmodern
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-06-03 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: cinch
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '2.0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '2.0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rubygems-tasks
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '0.2'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '0.2'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rspec
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: '2.4'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '2.4'
62
+ - !ruby/object:Gem::Dependency
63
+ name: yard
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: '0.7'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: '0.7'
78
+ description: ! 'Allows defining multiple commands within a Cinch Plugin.
79
+
80
+ Also provides a !help command with detailed output.
81
+
82
+ '
83
+ email: postmodern.mod3@gmail.com
84
+ executables: []
85
+ extensions: []
86
+ extra_rdoc_files:
87
+ - ChangeLog.md
88
+ - LICENSE.txt
89
+ - README.md
90
+ files:
91
+ - .document
92
+ - .gitignore
93
+ - .rspec
94
+ - .yardopts
95
+ - ChangeLog.md
96
+ - LICENSE.txt
97
+ - README.md
98
+ - Rakefile
99
+ - cinch-commands.gemspec
100
+ - gemspec.yml
101
+ - lib/cinch/commands.rb
102
+ - lib/cinch/commands/command.rb
103
+ - lib/cinch/commands/commands.rb
104
+ - lib/cinch/commands/help.rb
105
+ - lib/cinch/commands/version.rb
106
+ - spec/command_spec.rb
107
+ - spec/commands_spec.rb
108
+ - spec/spec_helper.rb
109
+ homepage: https://github.com/postmodern/cinch-commands#readme
110
+ licenses:
111
+ - MIT
112
+ post_install_message:
113
+ rdoc_options: []
114
+ require_paths:
115
+ - lib
116
+ required_ruby_version: !ruby/object:Gem::Requirement
117
+ none: false
118
+ requirements:
119
+ - - ! '>='
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ required_rubygems_version: !ruby/object:Gem::Requirement
123
+ none: false
124
+ requirements:
125
+ - - ! '>='
126
+ - !ruby/object:Gem::Version
127
+ version: '0'
128
+ requirements: []
129
+ rubyforge_project:
130
+ rubygems_version: 1.8.25
131
+ signing_key:
132
+ specification_version: 3
133
+ summary: Define multiple commands within a Cinch Plugin
134
+ test_files: []