cinch-bot_template 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.
- checksums.yaml +7 -0
- data/.gitignore +28 -0
- data/Gemfile +3 -0
- data/LICENSE +21 -0
- data/README.md +38 -0
- data/Rakefile +11 -0
- data/bin/cinch-mktpl +4 -0
- data/cinch-bot_template.gemspec +33 -0
- data/lib/cinch/bot_template.rb +1 -0
- data/lib/cinch/bot_template/cinch-bot_template.rb +60 -0
- data/lib/cinch/bot_template/classes/bot.rb +73 -0
- data/lib/cinch/bot_template/classes/config.rb +86 -0
- data/lib/cinch/bot_template/classes/exceptions.rb +8 -0
- data/lib/cinch/bot_template/classes/gen_init.rb +69 -0
- data/lib/cinch/bot_template/classes/hello.rb +60 -0
- data/lib/cinch/bot_template/classes/plugin.rb +51 -0
- data/lib/cinch/bot_template/desc/bot.rb +22 -0
- data/lib/cinch/bot_template/desc/gen.rb +27 -0
- data/lib/cinch/bot_template/desc/hello.rb +17 -0
- data/lib/cinch/bot_template/desc/plugin.rb +22 -0
- data/lib/cinch/bot_template/main/bot.rb +19 -0
- data/lib/cinch/bot_template/main/cli.rb +51 -0
- data/lib/cinch/bot_template/main/config.rb +20 -0
- data/lib/cinch/bot_template/main/desc.rb +10 -0
- data/lib/cinch/bot_template/main/plugin.rb +15 -0
- data/lib/cinch/bot_template/main/spinner.rb +22 -0
- data/lib/cinch/bot_template/main/thor.rb +102 -0
- data/lib/cinch/bot_template/templates/bot.rb +157 -0
- data/lib/cinch/bot_template/templates/config.rb +58 -0
- data/lib/cinch/bot_template/templates/hello.rb +32 -0
- data/lib/cinch/bot_template/templates/plugin.rb +30 -0
- data/lib/cinch/bot_template/version.rb +5 -0
- metadata +189 -0
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'highline'
|
3
|
+
|
4
|
+
require 'cinch/bot_template/templates/hello'
|
5
|
+
module Cinch
|
6
|
+
module BotTemplate
|
7
|
+
module Classes
|
8
|
+
class Hello
|
9
|
+
def initialize(directory: Pathname('.'), shell:, options: {})
|
10
|
+
@hl = HighLine.new($stdin, $stderr, 80)
|
11
|
+
@opts = Hash.new { |hash, key| hash[key] = {} }
|
12
|
+
@directory = directory
|
13
|
+
@shell = shell
|
14
|
+
@options = options
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
def get_001_bot_name
|
19
|
+
@hl.say "What's the bot's name"
|
20
|
+
@opts['bot']['nick'] = @hl.ask " > ", String
|
21
|
+
end
|
22
|
+
|
23
|
+
# @note What the executable file will be named + .rb
|
24
|
+
def get_002_bot_file
|
25
|
+
@hl.say "What should the executable file be named."
|
26
|
+
@hl.say "Use a hyphen by itself '-' to output to stdout "
|
27
|
+
@hl.say "instead of a file."
|
28
|
+
@hl.say "The generator will add .rb automatically."
|
29
|
+
filename = @hl.ask " > ", String
|
30
|
+
if filename == '-'
|
31
|
+
@opts['stdout'] = true
|
32
|
+
return
|
33
|
+
end
|
34
|
+
@opts['bot']['file'] = filename.include?('.rb') ? filename : filename + '.rb'
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
def generate
|
39
|
+
meths = self.methods.select { |x| x =~ /^get_[0-9]+_.*/ }
|
40
|
+
meths.sort! { |m, n| m.to_s.gsub(/^get_([0-9]+)_.*/, '\1').to_i <=> n.to_s.gsub(/^get_([0-9]+)_.*/, '\1').to_i }
|
41
|
+
meths.each do |m|
|
42
|
+
self.send(m)
|
43
|
+
end
|
44
|
+
@hl.say "Generating..."
|
45
|
+
tpl = Cinch::BotTemplate::Templates::Hello.new.generate(nick: @opts['bot']['nick'])
|
46
|
+
Cinch::BotTemplate.show_wait_spinner(5) do
|
47
|
+
if @opts.fetch('stdout', nil)
|
48
|
+
puts tpl
|
49
|
+
else
|
50
|
+
filename = @opts.dig('bot', 'file')
|
51
|
+
open filename, 'a+' do |fd|
|
52
|
+
fd.puts tpl
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'highline'
|
3
|
+
|
4
|
+
require 'cinch/bot_template/templates/plugin'
|
5
|
+
module Cinch
|
6
|
+
module BotTemplate
|
7
|
+
module Classes
|
8
|
+
class Plugin
|
9
|
+
def initialize(directory: Pathname('.').to_s, shell:, options:, all: false)
|
10
|
+
@hl = HighLine.new($stdin, $stderr, 80)
|
11
|
+
@opts = Hash.new { |hash, key| hash[key] = {} }
|
12
|
+
@all = all
|
13
|
+
@shell = shell
|
14
|
+
@directory = directory
|
15
|
+
@options = options
|
16
|
+
end
|
17
|
+
|
18
|
+
# @param [String] file_path File path to config as string to parse
|
19
|
+
def parse_config_path(file_path)
|
20
|
+
path = Pathname(file_path)
|
21
|
+
path = File.expand_path(path)
|
22
|
+
path.to_s
|
23
|
+
end
|
24
|
+
|
25
|
+
def get_001_plugin_names
|
26
|
+
@hl.say "What's the plugin name(s)?"
|
27
|
+
@hl.say "Each name you put here will have 'Plugin' appended to it."
|
28
|
+
@hl.say "Each name will become a separate plugin file"
|
29
|
+
@opts['plugin_names'] = @hl.ask " > ", -> (str) { str.split(' ') }
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
def generate(directory:)
|
34
|
+
meths = self.methods.select { |x| x =~ /^get_[0-9]+_.*/ }
|
35
|
+
meths.sort! { |m, n| m.to_s.gsub(/^get_([0-9]+)_.*/, '\1').to_i <=> n.to_s.gsub(/^get_([0-9]+)_.*/, '\1').to_i }
|
36
|
+
meths.each do |m|
|
37
|
+
self.send(m)
|
38
|
+
end
|
39
|
+
@hl.say "Generating..."
|
40
|
+
plugins = Cinch::BotTemplate::Templates::Plugin.generate(plugin_names: @opts['plugin_names'])
|
41
|
+
FileUtils.mkpath(directory.join('plugins'))
|
42
|
+
plugins.each do |plugin, text|
|
43
|
+
open Pathname(directory).join('plugins', plugin), 'w' do |fd|
|
44
|
+
fd.puts text
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Cinch
|
2
|
+
module BotTemplate
|
3
|
+
module Descs
|
4
|
+
module Bot
|
5
|
+
def self.Gen
|
6
|
+
<<~GEN
|
7
|
+
'#{Pathname($PROGRAM_NAME).basename} bot gen' will generate a bot file,
|
8
|
+
a executable file that has the basics of a cinch bot inside.
|
9
|
+
\#$
|
10
|
+
If you're looking to generate a whole bot, config, plugins,
|
11
|
+
bot file, logs, then use '#{Pathname($PROGRAM_NAME).basename} gen' itself.
|
12
|
+
\#$
|
13
|
+
See the help on '#{Pathname($PROGRAM_NAME).basename} help gen'
|
14
|
+
for information on using having a bot connect to
|
15
|
+
multiple servers/networks.
|
16
|
+
|
17
|
+
GEN
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'paint'
|
2
|
+
module Cinch
|
3
|
+
module BotTemplate
|
4
|
+
module Descs
|
5
|
+
module Gen
|
6
|
+
module_function
|
7
|
+
|
8
|
+
def Gen
|
9
|
+
ERB.new(
|
10
|
+
<<~GEN
|
11
|
+
--'<%= Paint['#{Pathname($PROGRAM_NAME).basename} gen', 'orange', :bold ] %>' will prompt for information
|
12
|
+
--then will generate the following when given no other options.
|
13
|
+
--* executable bot file
|
14
|
+
--* config file
|
15
|
+
--* optimal directory structure
|
16
|
+
<%= Paint['MULTI SERVER USE', 'white', :bold] %>:
|
17
|
+
--If '--multi-server' or '-m' is used, the generator will
|
18
|
+
--output a config and/or bot file that is set in a way to
|
19
|
+
--allow multiple networks/servers.
|
20
|
+
GEN
|
21
|
+
).result
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Cinch
|
2
|
+
module BotTemplate
|
3
|
+
module Descs
|
4
|
+
module Hello
|
5
|
+
module_function
|
6
|
+
|
7
|
+
def Gen
|
8
|
+
<<~GEN
|
9
|
+
'#{Pathname($PROGRAM_NAME).basename} hello' generates a simple one file
|
10
|
+
--that allows you to start a bot up in seconds.
|
11
|
+
GEN
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'paint'
|
2
|
+
module Cinch
|
3
|
+
module BotTemplate
|
4
|
+
module Descs
|
5
|
+
module Plugin
|
6
|
+
module_function
|
7
|
+
|
8
|
+
def Gen
|
9
|
+
ERB.new(
|
10
|
+
<<~GEN
|
11
|
+
--'<%= Paint['#{Pathname($PROGRAM_NAME).basename} plugin gen', 'orange', :bold] %>'
|
12
|
+
--will prompt for information,
|
13
|
+
--then will start generating either one or multiple plugin files,
|
14
|
+
--based on how many plugin names it was given.
|
15
|
+
GEN
|
16
|
+
).result
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'cinch/bot_template/classes/bot'
|
2
|
+
require 'cinch/bot_template/main/desc'
|
3
|
+
require 'thor'
|
4
|
+
|
5
|
+
module Cinch
|
6
|
+
module BotTemplate
|
7
|
+
|
8
|
+
class Bot < Thor
|
9
|
+
|
10
|
+
method_option 'multi-server', type: :boolean, default: false, aliases: %w(-m), hide: true
|
11
|
+
long_desc Descs::Bot.Gen
|
12
|
+
desc 'gen [options]', 'Generate the executable for a bot'
|
13
|
+
def gen
|
14
|
+
generator = Cinch::BotTemplate::Classes::Bot.new(options)
|
15
|
+
generator.generate
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'highline'
|
3
|
+
require 'cinch/bot_template/classes/gen_init'
|
4
|
+
require 'cinch/bot_template/classes/bot'
|
5
|
+
require 'cinch/bot_template/classes/plugin'
|
6
|
+
require 'cinch/bot_template/classes/config'
|
7
|
+
module Cinch
|
8
|
+
module BotTemplate
|
9
|
+
module CLI
|
10
|
+
class Base
|
11
|
+
def initialize(shell:, options:)
|
12
|
+
@hl = HighLine.new($stdin, $stderr, 80)
|
13
|
+
@opts = Hash.new { |hash, key| hash[key] = {} }
|
14
|
+
@options = options
|
15
|
+
@shell = shell
|
16
|
+
end
|
17
|
+
|
18
|
+
def generate
|
19
|
+
init = Cinch::BotTemplate::Classes::Init.new(
|
20
|
+
options: @options,
|
21
|
+
shell: @shell,
|
22
|
+
all: true
|
23
|
+
)
|
24
|
+
init.generate
|
25
|
+
directory = init.directory
|
26
|
+
|
27
|
+
config = Cinch::BotTemplate::Classes::Config.new(
|
28
|
+
options: @options,
|
29
|
+
shell: @shell,
|
30
|
+
all: true
|
31
|
+
)
|
32
|
+
cfg_path = config.generate(directory)
|
33
|
+
|
34
|
+
bot = Cinch::BotTemplate::Classes::Bot.new(
|
35
|
+
options: @options,
|
36
|
+
shell: @shell,
|
37
|
+
all: true
|
38
|
+
)
|
39
|
+
bot.generate(directory: directory, config_file: cfg_path)
|
40
|
+
|
41
|
+
plugins = Cinch::BotTemplate::Classes::Plugin.new(
|
42
|
+
shell: @shell,
|
43
|
+
options: @options,
|
44
|
+
all: true
|
45
|
+
)
|
46
|
+
plugins.generate(directory: directory)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'cinch/bot_template/classes/bot'
|
2
|
+
require 'cinch/bot_template/main/desc'
|
3
|
+
require 'thor'
|
4
|
+
|
5
|
+
module Cinch
|
6
|
+
module BotTemplate
|
7
|
+
|
8
|
+
class Config < Thor
|
9
|
+
|
10
|
+
desc 'gen [options]', 'Generate the executable for a bot'
|
11
|
+
method_option 'multi-server', type: :boolean, default: false, aliases: %w(-m), required: false, hide: true
|
12
|
+
|
13
|
+
long_desc Cinch::BotTemplate::Descs::Plugin.Gen
|
14
|
+
def gen(dir)
|
15
|
+
generator = Cinch::BotTemplate::Classes::Config.new(options: options, shell: self.shell)
|
16
|
+
generator.generate(Pathname(dir))
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module Cinch
|
2
|
+
module BotTemplate
|
3
|
+
module Descs
|
4
|
+
autoload :Bot, 'cinch/bot_template/desc/bot'
|
5
|
+
autoload :Gen, 'cinch/bot_template/desc/gen'
|
6
|
+
autoload :Hello, 'cinch/bot_template/desc/hello'
|
7
|
+
autoload :Plugin, 'cinch/bot_template/desc/plugin'
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'cinch/bot_template/classes/plugin'
|
2
|
+
require 'thor'
|
3
|
+
|
4
|
+
module Cinch
|
5
|
+
module BotTemplate
|
6
|
+
class Plugin < Thor
|
7
|
+
long_desc Cinch::BotTemplate::Descs::Plugin.Gen
|
8
|
+
desc 'gen [options]', 'Generate a plugin'
|
9
|
+
def gen(dir)
|
10
|
+
generator = Cinch::BotTemplate::Classes::Plugin.new(directory: dir, options: options)
|
11
|
+
generator.generate
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Cinch
|
2
|
+
module BotTemplate
|
3
|
+
module_function
|
4
|
+
|
5
|
+
def show_wait_spinner(fps = 10)
|
6
|
+
chars = %w[| / - \\]
|
7
|
+
delay = 1.0 / fps
|
8
|
+
iter = 0
|
9
|
+
spinner = Thread.new do
|
10
|
+
while iter do # Keep spinning until told otherwise
|
11
|
+
print chars[(iter += 1) % chars.length]
|
12
|
+
sleep delay
|
13
|
+
print "\b"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
yield.tap {# After yielding to the block, save the return value
|
17
|
+
iter = false # Tell the thread to exit, cleaning up after itself…
|
18
|
+
spinner.join # …and wait for it to do so.
|
19
|
+
} # Use the block's return value as the method's
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'paint'
|
2
|
+
class Thor
|
3
|
+
class << self
|
4
|
+
def command_help(shell, command_name)
|
5
|
+
meth = normalize_command_name(command_name)
|
6
|
+
command = all_commands[meth]
|
7
|
+
handle_no_command_error(meth) unless command
|
8
|
+
|
9
|
+
shell.say "USAGE ", ['white', :bold]
|
10
|
+
shell.say "\b:"
|
11
|
+
shell.say " #{banner(command)}"
|
12
|
+
class_options_help(shell, nil => command.options.values)
|
13
|
+
if command.long_description
|
14
|
+
shell.say "DESCRIPTION ", ['white', :bold]
|
15
|
+
shell.say "\b:"
|
16
|
+
shell.print_wrapped(command.long_description)
|
17
|
+
else
|
18
|
+
shell.say command.description
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
alias_method :task_help, :command_help
|
23
|
+
end
|
24
|
+
module Base
|
25
|
+
module ClassMethods
|
26
|
+
def print_options(shell, options, group_name = nil)
|
27
|
+
return if options.empty?
|
28
|
+
|
29
|
+
list = []
|
30
|
+
padding = options.map { |o| o.aliases.size }.max.to_i * 4
|
31
|
+
|
32
|
+
options.each do |option|
|
33
|
+
next if option.hide
|
34
|
+
item = [option.usage(padding)]
|
35
|
+
item.push(option.description ? "# #{option.description}" : "")
|
36
|
+
|
37
|
+
list << item
|
38
|
+
list << ["", "# Default: #{option.default}"] if option.show_default?
|
39
|
+
list << ["", "# Possible values: #{option.enum.join(', ')}"] if option.enum
|
40
|
+
end
|
41
|
+
|
42
|
+
shell.say(group_name ? "#{group_name} options:" : "Options:") unless list.empty?
|
43
|
+
shell.print_table(list, :indent => 2) unless list.empty?
|
44
|
+
#shell.say ""
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
module Shell
|
50
|
+
class Basic
|
51
|
+
def prepare_message(message, *color, paint: true)
|
52
|
+
case paint
|
53
|
+
when true
|
54
|
+
spaces = " " * padding
|
55
|
+
spaces + Paint[message.to_s, *color]
|
56
|
+
when false
|
57
|
+
spaces = " " * padding
|
58
|
+
spaces + set_color(message.to_s, *color)
|
59
|
+
else
|
60
|
+
spaces = " " * padding
|
61
|
+
spaces + Paint[message.to_s, *color]
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
# Say (print) something to the user. If the sentence ends with a whitespace
|
67
|
+
# or tab character, a new line is not appended (print + flush). Otherwise
|
68
|
+
# are passed straight to puts (behavior got from Highline).
|
69
|
+
#
|
70
|
+
# ==== Example
|
71
|
+
# say("I know you knew that.")
|
72
|
+
#
|
73
|
+
def say(message = "", color = nil, force_new_line = (message.to_s !~ /( |\t)\Z/), paint: true)
|
74
|
+
buffer = prepare_message(message, *color, paint: paint)
|
75
|
+
buffer << "\n" if force_new_line && !message.to_s.end_with?("\n")
|
76
|
+
|
77
|
+
stdout.print(buffer)
|
78
|
+
stdout.flush
|
79
|
+
end
|
80
|
+
|
81
|
+
# @note Override Thor::Shell::Basic.print_wrapped
|
82
|
+
# @overload Thor::Shell::Basic.print_wrapped
|
83
|
+
# 1. Replace 6 - with 6 spaces
|
84
|
+
# 2. Replace 4 - with 4 spaces
|
85
|
+
# 3. Replace 2 - with 2 spaces
|
86
|
+
# 4. Replace #$ at the beginning of lines
|
87
|
+
# with '\n'
|
88
|
+
def print_wrapped(message, options = {})
|
89
|
+
message.lstrip!
|
90
|
+
message.gsub!(/\n\s+/, "\n")
|
91
|
+
message = message.split("\n")
|
92
|
+
message.each do |line|
|
93
|
+
line.gsub!(/^------/, ' ' * 6) if line[0..5] == '-' * 6
|
94
|
+
line.gsub!(/^----/, ' ' * 4) if line[0..3] == '-' * 4
|
95
|
+
line.gsub!(/^--/, ' ' * 2) if line[0..1] == '-' * 2
|
96
|
+
line.gsub!(/^#\$/, "\n")
|
97
|
+
stdout.puts line
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|