cinch-commands 0.1.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.
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: []