console_runner 0.1.8 → 0.1.9

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: 46251b514ee3ff2c6fe6d1805b58bb7bc8740ebb
4
- data.tar.gz: 7781c2c0188af33e49ab7bec3e99be229bb756ac
3
+ metadata.gz: 1c16db9e220aea79fb56dcfedbefaf35822d5759
4
+ data.tar.gz: 04a996f93da398cc7b3cf78054d4cbc0410d2572
5
5
  SHA512:
6
- metadata.gz: 1ca1cf2617736897556652cfa6de3c7a894349359d3ab2472f759c7a8def9a0b617e77138e48dbab8e9c77c805451b52ff4aef38fca6ffb8187b9ddc2d62c4cc
7
- data.tar.gz: 64c9e1747574c79f5ee1b863a7e26ba4a2dd9f98ecd10d8f4cfbab133b02350c34354ef73b5bf451487ea69c7b0dbb875cd597a857d7dae68bb5b68a7705e1f8
6
+ metadata.gz: b250ca7da42c8f2c2940577d0706a8ebc800af3463aef7f94b75c2a6aa626e809262b2e37b5c12dce3f515855bfe39ef0bd0fcf1a67683b8338f6c51458b9f93
7
+ data.tar.gz: 9e0c76daa906eb6cb2224caa38d86ad0e9df4adf374c79979a3ed15186625326161f5e7bb596049c3c9fa6d101ee26987befba7298460ee3830c5b7f1bca172a
data/README.md CHANGED
@@ -5,9 +5,47 @@
5
5
  [![Code Climate][CC img]][Code Climate]
6
6
  [![Coverage Status][CS img]][Coverage Status]
7
7
 
8
- This gem provides you an ability to run any Ruby method from command-line (no any code modifications required!!!).
8
+ This gem provides you an ability to run any Ruby method from command-line. No special code modifications required!.
9
+ `console_runner` is a smart mix of [YARD](http://yardoc.org/) and [Trollop](http://manageiq.github.io/trollop/) gems.
10
+ > 1. it parses [YARD](http://yardoc.org/) annotations of classes and methods to 'understand' your code
11
+ > 2. it generates friendly unix-like help menu for your tool (using [Trollop](http://manageiq.github.io/trollop/) gem)
12
+ > 3. it parses command-line input and run your Ruby code in a proper way
13
+
14
+ Just 4 simple steps to make your code runnable from terminal:
15
+ 1. Just add `@runnable` tag in
16
+
9
17
  One thing you need to do is to add an [YARD](http://yardoc.org/) tag annotation `@runnable`.
10
18
 
19
+ ## Usage
20
+ `console_runner` extends [YARD](http://yardoc.org/) with a new tag: `@runnable`. You need to set this tag in a Class and Method annotation. After that it will be possible to call this method from command-line.
21
+ Usage instructions are as simple as one, two, three:
22
+ 1. Add `@runnable` tag
23
+ 2. Now you can run your tool from terminal by `c_run /path/to/class.rb_file` command
24
+ 3. PROFIT! (:
25
+
26
+ ### Example
27
+ 1. Install `console_runner` gem
28
+ 2. Put some code to `/home/user/project/my_class.rb`
29
+ ```ruby
30
+ # @runnable
31
+ class MyClass
32
+
33
+ # @runnable
34
+ def say_hello
35
+ puts 'Hello!'
36
+ end
37
+
38
+ end
39
+ ```
40
+ 3. Run terminal command to run `say_hello` method
41
+ ```bash
42
+ c_run /home/user/project/my_class.rb say_hello
43
+
44
+ -> Hello!
45
+ ```
46
+
47
+ Read FAQ for more examples.
48
+
11
49
  ## Installation
12
50
 
13
51
  Add this line to your application's Gemfile:
@@ -24,84 +62,40 @@ Or install it yourself as:
24
62
 
25
63
  $ gem install console_runner
26
64
 
27
- ## Usage
28
- Usage is simple. First of all you need to add `gem 'console_runner'` in your `Gemfile`.
29
- Then you need to specify `@runnable` tag in your class and method annotations. For example,
30
-
65
+ ## FAQ
66
+ ##### **Can I add documentation for my tool and customize help page content?**
67
+ Yes. Any text placed after `@runnable` tag will be displayed on the help page. You can add any additional information about how to use your tool there.
68
+ > **Tip**: You can use multi-line text as well
69
+
70
+ **Example:**
31
71
  ```ruby
32
- # This is basic Ruby class with YARD annotation.
33
- # Nothing special here except @runnable tag. This is a `console_runner` tag that
34
- # shows that this class can be runnable via bash command line.
35
- #
36
- # You can mark any method (class method or instance method) with @runnable tag to show you want the method to be executable.
37
- # We name class method as *class action* and instance method as *instance action* or just *action*.
38
- # Instance action requires #initialize method to be executed first. `console_runner` tool invokes #initialize
39
- # method automatically.
40
- #
41
- # @author Yuri Karpovich
42
- #
43
- # @runnable This is your "smart" assistant tool.
44
- # NOTE: This message will be shown in your tool in --help menu.
45
- #
46
- # @since 0.1.0
47
- class SimpleSiri
48
-
49
- def initialize
50
- @name = 'Siri'
51
- @age = Random.rand 100
52
- end
53
-
54
- # Say something
55
- #
56
- # @runnable
57
- # @return [String]
58
- # @param [String] what_to_say ask name or age of Siri
59
- def say(what_to_say)
60
- case what_to_say.downcase
61
- when 'name'
62
- puts 'My name is ' + @name
63
- when 'age'
64
- puts "I'm #{@age} years old"
65
- else
66
- puts "I don't know".green
67
- end
68
- end
72
+ # @runnable This tool can talk to you. Run it when you are lonely.
73
+ class MyClass
69
74
 
75
+ def initialize
76
+ @hello_msg = 'Hello!'
77
+ @bye_msg = 'Good Bye!'
78
+ end
79
+
80
+ # @runnable Say 'Hello' to you.
81
+ def say_hello
82
+ puts @hello_msg
83
+ end
84
+
85
+ # @runnable Say 'Good Bye' to you.
86
+ def say_bye
87
+ puts @bye_msg
88
+ end
89
+
70
90
  end
71
91
  ```
72
92
 
73
- Then you can run the tool in your console:
74
- ```bash
75
- c_run ruby_class.rb say --help
76
-
77
- This is your "smart" assistant tool.
78
- NOTE: This message will be shown in your tool in --help menu.
79
- -h, --help Show this message
80
- -w, --what-to-say=<s> (Ruby class: String) ask name or age of Siri
81
- ```
82
-
83
93
  ```bash
84
- c_run ruby_class.rb say -w age
85
-
86
- =======================================================
87
- Global options:
88
- help = false
89
- INIT: initialize
90
- INIT options:
91
-
92
- Subcommand: say
93
- Subcommand options:
94
- what_to_say = age
95
- =======================================================
96
- Start Time: 2017-04-11 21:39:40 +0300
97
- I'm 78 years old
98
- Finish Time: 2017-04-11 21:39:40 +0300 (Duration: 0.0 minutes)
99
-
94
+ TODO example
100
95
  ```
101
96
 
102
97
  ## ToDo
103
98
  - fix help menu for action: action help text should be displayed, list of available actions should be displayed
104
- - write good readme
105
99
 
106
100
  ## Development
107
101
 
@@ -1,77 +1,62 @@
1
1
  require 'file_parser'
2
- require 'cmd_parser'
2
+ require 'trollop_configurator'
3
3
  require 'runner'
4
4
  require 'console_runner/version'
5
5
 
6
-
6
+ # console_runner logic is here
7
7
  module ConsoleRunner
8
8
  file_from_arg = ARGV.shift
9
9
  raise ConsoleRunnerError, 'Specify file to be executed' unless file_from_arg
10
10
  file_path = File.realpath file_from_arg
11
11
  file_parser = FileParser.new(file_path)
12
-
13
-
14
- runnable_classes = file_parser.list_classes(:runnable)
15
- if runnable_classes.count != 1
16
- raise ConsoleRunnerError, "One runnable Class should be specified in file.
17
- Runnable class should be marked with @#{FileParser::RUNNABLE_TAG} tag"
18
- end
19
-
20
- clazz = runnable_classes.first
21
- all_methods = file_parser.list_methods(:all, clazz)
22
- runnable_methods = file_parser.list_methods(:runnable, clazz)
23
- initialize_method = all_methods.find { |m| m.name == :initialize }
24
- run_method = all_methods.find { |m| m.name == :run }
25
-
26
-
27
- cmd = ARGV[0]
28
- action_methods = runnable_methods.select { |m| m.name.to_s == cmd }
29
- if action_methods.count > 1
12
+ cmd = ARGV[0]
13
+ actions = file_parser.runnable_methods.select { |m| m.name.to_s == cmd }
14
+ if actions.count > 1
30
15
  raise(
31
16
  ConsoleRunnerError,
32
- "Class and Instance methods have the same name (#{cmd}). Action name should be unique"
17
+ "Class and Instance methods have the same name (#{cmd}). Actions names should be unique"
33
18
  )
34
19
  end
35
- action_method = action_methods.first
36
- action_method ||= run_method
37
- cmd_parser = CmdParser.new(runnable_methods, initialize_method)
38
- raise ConsoleRunnerError, "Cannot run! You haven't specify any method to run." unless action_method
39
- cmd_parser.parse_method action_method
20
+ action = actions.first
21
+ action ||= file_parser.run_method
22
+ trol_config = TrollopConfigurator.new(file_parser)
23
+ raise ConsoleRunnerError, "Cannot run! You haven't specify any method to run." unless action
24
+ trol_config.parse_method action
40
25
 
41
26
 
42
27
  puts '======================================================='
43
28
  puts 'Global options:'
44
- puts cmd_parser.global_opts.map { |k, v| " #{k} = #{v}" }.join("\n")
45
- if initialize_method
46
- puts "INIT: #{initialize_method.name}"
29
+ puts trol_config.global_opts.map { |k, v| " #{k} = #{v}" }.join("\n")
30
+ if file_parser.initialize_method
31
+ puts "INIT: #{file_parser.initialize_method.name}"
47
32
  puts 'INIT options:'
48
- puts cmd_parser.init_method.cmd_opts.map { |k, v| " #{k} = #{v}" }.join("\n")
33
+ puts trol_config.init_method.cmd_opts.map { |k, v| " #{k} = #{v}" }.join("\n")
49
34
  end
50
- puts "Subcommand: #{action_method.name}"
35
+ puts "Subcommand: #{action.name}"
51
36
  puts 'Subcommand options:'
52
- puts cmd_parser.method.cmd_opts.map { |k, v| " #{k} = #{v}" }.join("\n")
37
+ puts trol_config.method.cmd_opts.map { |k, v| " #{k} = #{v}" }.join("\n")
53
38
  puts "Remaining arguments: #{ARGV.inspect}" if ARGV != []
54
39
  puts '======================================================='
55
40
 
56
41
 
57
42
  Runner.run {
58
43
  require file_path
59
- class_full_name = clazz.title
44
+ class_full_name = file_parser.clazz.title
60
45
  raise ConsoleRunnerError, "#{class_full_name} is not defined" unless Module.const_defined?(class_full_name)
61
46
  klass_obj = Module.const_get(class_full_name)
62
- method_type = action_method.scope
63
- method_params = cmd_parser.method.params_array
47
+ method_type = action.scope
48
+ method_params = trol_config.method.params_array
64
49
 
65
50
  case method_type
66
51
  when :class
67
- klass_obj.send(action_method.name, *method_params)
52
+ klass_obj.send(action.name, *method_params)
68
53
  when :instance
69
- init_method = cmd_parser.init_method
54
+ init_method = trol_config.init_method
70
55
  init_params = []
71
56
  init_params = init_method.params_array if init_method
72
57
  # TODO catch errors
73
58
  obj = klass_obj.new(*init_params)
74
- obj.send(action_method.name, *method_params)
59
+ obj.send(action.name, *method_params)
75
60
  else
76
61
  raise ConsoleRunnerError, "Unknown method type: #{method_type}"
77
62
  end
@@ -1,3 +1,3 @@
1
1
  module ConsoleRunner
2
- VERSION = '0.1.8'
2
+ VERSION = '0.1.9'
3
3
  end
data/lib/file_parser.rb CHANGED
@@ -5,8 +5,10 @@ require 'console_runner_error'
5
5
  class FileParser
6
6
  RUNNABLE_TAG = :runnable
7
7
 
8
- # array of #YARD::CodeObjects
9
- attr_reader :all_objects
8
+ attr_reader :clazz,
9
+ :runnable_methods,
10
+ :initialize_method,
11
+ :run_method
10
12
 
11
13
  # Parse file with #YARD::CLI::Stats
12
14
  #
@@ -15,9 +17,18 @@ class FileParser
15
17
  raise ConsoleRunnerError "Cannot find file #{file_path}" unless File.exist?(file_path)
16
18
  code = YARD::CLI::Stats.new
17
19
  code.run(file_path)
18
- @all_objects = code.all_objects
20
+ @all_objects = code.all_objects
21
+ runnable_classes = list_classes(:runnable)
22
+ raise ConsoleRunnerError, 'At least one runnable Class should be specified in file' if runnable_classes.count != 1
23
+ @clazz = runnable_classes.first
24
+ all_methods = list_methods(:all, clazz)
25
+ @runnable_methods = list_methods(:runnable, clazz)
26
+ @initialize_method = all_methods.find { |m| m.name == :initialize }
27
+ @run_method = all_methods.find { |m| m.name == :run }
19
28
  end
20
29
 
30
+ private
31
+
21
32
  # List of methods
22
33
  # @param [Symbol] scope :all - list all methods, :runnable - list only runnable methods
23
34
  # @param [YARD::CodeObjects::ClassObject, nil] clazz list methods of specified class only
@@ -93,9 +104,11 @@ YARD::Tags::Library.define_tag 'Console Tool Description', FileParser::RUNNABLE_
93
104
  module YARD
94
105
  module CLI
95
106
  class Stats < Yardoc
96
- def print_statistics; end
107
+ def print_statistics;
108
+ end
97
109
 
98
- def print_undocumented_objects; end
110
+ def print_undocumented_objects;
111
+ end
99
112
  end
100
113
  end
101
114
  end
data/lib/method_parser.rb CHANGED
@@ -2,8 +2,8 @@
2
2
  class MethodParser
3
3
  attr_reader :method,
4
4
  :name,
5
- :param_tags, # All method parameters tags
6
- :option_tags # Only options tags
5
+ :param_tags, # All method parameters tags
6
+ :option_tags # Only options tags
7
7
 
8
8
  attr_accessor :cmd_opts
9
9
 
@@ -15,6 +15,14 @@ class MethodParser
15
15
  @param_tags = FileParser.select_param_tags @method
16
16
  @option_tags = FileParser.select_option_tags @method
17
17
  @cmd_opts = nil
18
+ same_params = param_tags_names & option_tags_names
19
+ if same_params.count > 0
20
+ raise(
21
+ ConsoleRunnerError,
22
+ "You have the same name for @param and @option attribute(s): #{same_params.join(', ')}.
23
+ Use different names to `console_runner` be able to run #{@name} method."
24
+ )
25
+ end
18
26
  end
19
27
 
20
28
  # Prepare
@@ -2,7 +2,7 @@ require 'trollop'
2
2
  require 'method_parser'
3
3
 
4
4
  # Parses command line and configure #Trollop
5
- class CmdParser
5
+ class TrollopConfigurator
6
6
  attr_reader :global_opts, :method, :init_method
7
7
  TYPES_MAPPINGS = {
8
8
  'String' => :string,
@@ -16,8 +16,12 @@ class CmdParser
16
16
  'Array(Float)' => :floats,
17
17
  'Array(Boolean)' => :booleans
18
18
  }.freeze
19
- # Should be executed before ARGV.shift
20
- def initialize(runnable_methods, init_method= nil)
19
+
20
+ # Generate tool help menu.
21
+ # IMPORTANT! Should be executed before ARGV.shift
22
+ def initialize(file_parser)
23
+ runnable_methods = file_parser.runnable_methods
24
+ init_method = file_parser.initialize_method
21
25
  clazz = runnable_methods.first.parent
22
26
  sub_commands = runnable_methods.map { |m| m.name.to_s }
23
27
  @parser = Trollop::Parser.new
@@ -26,16 +30,6 @@ class CmdParser
26
30
 
27
31
  if init_method
28
32
  @init_method = MethodParser.new init_method
29
- same_params = @init_method.param_tags_names & @init_method.option_tags_names
30
- if same_params.count > 0
31
- raise(
32
- ConsoleRunnerError,
33
- "You have the same name for @param and @option attribute(s): #{same_params.join(', ')}.
34
- Use different names to `console_runner` be able to run #{@init_method.name} method."
35
- )
36
- end
37
-
38
-
39
33
  @init_method.param_tags.each do |tag|
40
34
  tag_name = tag.name
41
35
  tag_text = tag.text
@@ -47,13 +41,13 @@ Use different names to `console_runner` be able to run #{@init_method.name} meth
47
41
  option_name = option.pair.name.delete(':')
48
42
  option_text = option.pair.text
49
43
  option_type = option.pair.type
50
- @parser.opt(option_name.to_sym, "(Ruby class: #{option_type}) " + option_text.to_s, type: CmdParser.parse_type(option_type))
44
+ @parser.opt(option_name.to_sym, "(Ruby class: #{option_type}) " + option_text.to_s, type: TrollopConfigurator.parse_type(option_type))
51
45
  end
52
46
  else
53
- @parser.opt(tag_name.to_sym, "(Ruby class: #{tag_type}) " + tag_text.to_s, type: CmdParser.parse_type(tag_type))
47
+ @parser.opt(tag_name.to_sym, "(Ruby class: #{tag_type}) " + tag_text.to_s, type: TrollopConfigurator.parse_type(tag_type))
54
48
  end
55
49
  else
56
- @parser.opt(tag_name.to_sym, "(Ruby class: #{tag_type}) " + tag_text.to_s, type: CmdParser.parse_type(tag_type))
50
+ @parser.opt(tag_name.to_sym, "(Ruby class: #{tag_type}) " + tag_text.to_s, type: TrollopConfigurator.parse_type(tag_type))
57
51
  end
58
52
  end
59
53
  end
@@ -76,15 +70,7 @@ Use different names to `console_runner` be able to run #{@init_method.name} meth
76
70
  # Parse method and configure #Trollop
77
71
  def parse_method(method)
78
72
  ARGV.shift
79
- @method = MethodParser.new method
80
- same_params = @method.param_tags_names & @method.option_tags_names
81
- if same_params.count > 0
82
- raise(
83
- ConsoleRunnerError,
84
- "You have the same name for @param and @option attribute(s): #{same_params.join(', ')}.
85
- Use different names to `console_runner` be able to run #{@method.name} method."
86
- )
87
- end
73
+ @method = MethodParser.new method
88
74
  method_params_tags = @method.param_tags
89
75
 
90
76
  method_params_tags.each do |tag|
@@ -98,13 +84,13 @@ Use different names to `console_runner` be able to run #{@method.name} method."
98
84
  option_name = option.pair.name.delete(':')
99
85
  option_text = option.pair.text
100
86
  option_type = option.pair.type
101
- @parser.opt(option_name.to_sym, "(Ruby class: #{option_type}) " + option_text.to_s, type: CmdParser.parse_type(option_type))
87
+ @parser.opt(option_name.to_sym, "(Ruby class: #{option_type}) " + option_text.to_s, type: TrollopConfigurator.parse_type(option_type))
102
88
  end
103
89
  else
104
- @parser.opt(tag_name.to_sym, "(Ruby class: #{tag_type}) " + tag_text.to_s, type: CmdParser.parse_type(tag_type))
90
+ @parser.opt(tag_name.to_sym, "(Ruby class: #{tag_type}) " + tag_text.to_s, type: TrollopConfigurator.parse_type(tag_type))
105
91
  end
106
92
  else
107
- @parser.opt(tag_name.to_sym, "(Ruby class: #{tag_type}) " + tag_text.to_s, type: CmdParser.parse_type(tag_type))
93
+ @parser.opt(tag_name.to_sym, "(Ruby class: #{tag_type}) " + tag_text.to_s, type: TrollopConfigurator.parse_type(tag_type))
108
94
  end
109
95
  end
110
96
  cmd_opts = Trollop::with_standard_exception_handling @parser do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: console_runner
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.8
4
+ version: 0.1.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yury Karpovich
@@ -157,13 +157,13 @@ files:
157
157
  - bin/setup
158
158
  - console_runner.gemspec
159
159
  - exe/c_run
160
- - lib/cmd_parser.rb
161
160
  - lib/console_runner.rb
162
161
  - lib/console_runner/version.rb
163
162
  - lib/console_runner_error.rb
164
163
  - lib/file_parser.rb
165
164
  - lib/method_parser.rb
166
165
  - lib/runner.rb
166
+ - lib/trollop_configurator.rb
167
167
  homepage: https://github.com/yuri-karpovich/console_runner
168
168
  licenses:
169
169
  - MIT