mister_bin 0.6.3 → 0.7.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 96c54bf11d15090b8bdbde7d3540e768ce4b5ffab47cd30765b4f742b88a3746
4
- data.tar.gz: 8915b5fa7b0222d5c09b39e9a530047277b56243b236d8af04a9f0cd36014caf
3
+ metadata.gz: a3079a8599aeffba78c30871ca736ab6c48dfac513400be8319c493ae24fd576
4
+ data.tar.gz: 8b1a58023370dffafe99362ad4cddf211d1ea8f3ee5a1a88ca282ed8c68b94ea
5
5
  SHA512:
6
- metadata.gz: 7529459ac47101bfc86b56569ebf0b680e684f0b94b044db6c39f9194539d4969f5cf244eb44e6f76a75f88cd72f06177898b2c4125ea696536a11182ee392b8
7
- data.tar.gz: c6a34bc12c75edabb45fcc0a9c104f1df40d38079c69cfdf5d561768340a9bd2ba05a1b0e4891fa76cee272d4fbeccc9faf75b7e8cb66dbcf9bf8feb3d5d57a5
6
+ metadata.gz: 8d62bc3efbe561981755ec5b90ffdfb9a3ab6efafbabc5281eb81e9aabbffbeec2c0601e658384aba05c401e5a396f9b0beabd265d36f6d9b1e5ddcdcf6423ea
7
+ data.tar.gz: 317ea1137fdd923f27995fe933f7a4660579f8ca1e91a301701d5eaae44b54d3f9d2e1984fcc2738d5040d322bbffcb056b8f90f958997f7b939d85e128a3c4a
data/README.md CHANGED
@@ -4,7 +4,6 @@ Mister Bin
4
4
  [![Gem Version](https://badge.fury.io/rb/mister_bin.svg)](https://badge.fury.io/rb/mister_bin)
5
5
  [![Build Status](https://travis-ci.com/DannyBen/mister_bin.svg?branch=master)](https://travis-ci.com/DannyBen/mister_bin)
6
6
  [![Maintainability](https://api.codeclimate.com/v1/badges/ae82443a99c2839d8ba8/maintainability)](https://codeclimate.com/github/DannyBen/mister_bin/maintainability)
7
- [![Test Coverage](https://api.codeclimate.com/v1/badges/ae82443a99c2839d8ba8/test_coverage)](https://codeclimate.com/github/DannyBen/mister_bin/test_coverage)
8
7
 
9
8
  ---
10
9
 
@@ -25,6 +24,9 @@ Contents
25
24
  * [Runner Routes](#runner-routes)
26
25
  * [Creating Commands](#creating-commands)
27
26
  * [Command DSL](#command-dsl)
27
+ * [Interactive Terminal](#interactive-terminal)
28
+ * [Terminal features](#terminal-features)
29
+ * [Terminal options](#terminal-options)
28
30
  * [In the Wild](#in-the-wild)
29
31
 
30
32
 
@@ -74,6 +76,7 @@ if you have a `server` command, you can execute it with `yourapp s` if it
74
76
  is the only command that starts with an `s`.
75
77
 
76
78
 
79
+
77
80
  Creating the Main Executable
78
81
  --------------------------------------------------
79
82
 
@@ -164,6 +167,7 @@ runner.route_all to: GlobalCommand
164
167
  ```
165
168
 
166
169
 
170
+
167
171
  Creating Commands
168
172
  --------------------------------------------------
169
173
 
@@ -237,6 +241,88 @@ example "app ls --all"
237
241
  ```
238
242
 
239
243
 
244
+
245
+ Interactive Terminal
246
+ --------------------------------------------------
247
+ Mister Bin comes with an interactive terminal thaht allows you to set up a
248
+ console that sends all commands to your runner.
249
+
250
+ ![Demo](https://raw.githubusercontent.com/DannyBen/mister_bin/master/demo/terminal.gif)
251
+
252
+ See the [terminal example](/examples/06-terminal) folder.
253
+
254
+ In order to start a terminal, you need to provide it with a
255
+ `MisterBin::Runner` object:
256
+
257
+ ```ruby
258
+ runner = MisterBin::Runner.new
259
+ runner.route 'greet', to: GreetCommand
260
+ terminal = MisterBin::Terminal.new runner
261
+ terminal.start
262
+ ```
263
+
264
+ ### Terminal features
265
+
266
+ - All commands will be routed to the runner.
267
+ - Customizable autocomplete.
268
+ - Command history (up/down arrows).
269
+ - Start a command with a `/` in order to run a system (shell) command.
270
+ - Type `exit` to quit (or Ctrl+D or Ctrl+C).
271
+ - Customizable header, exit message, exit command and prompt.
272
+
273
+
274
+ ### Terminal options
275
+
276
+ The `MisterBin::Terminal.new` command accepts an optional second argument. If
277
+ provided, it should be a options hash:
278
+
279
+ ```
280
+ terminal = MisterBin::Terminal.new runner, {
281
+ header: "Welcome",
282
+ autocomplete: %w[--help greet]
283
+ }
284
+ ```
285
+
286
+ These are the available options. All string options are displayed with
287
+ the [Colsole][5] `say` command so they support color markers.
288
+
289
+ #### `header`
290
+
291
+ Message to show when starting the terminal.
292
+ Default: blank.
293
+
294
+ #### `show_usage`
295
+
296
+ If true, the runner will be executed on startup to show its usage patterns.
297
+ Default: `false`.
298
+
299
+ #### `prompt`
300
+
301
+ The string for the prompt. Default: `"\n> "`.
302
+
303
+ #### `autocomplete`
304
+
305
+ An array of words to autocomplete by pressing Tab.
306
+ Default: none.
307
+
308
+ #### `exit_message`
309
+
310
+ The message to show on exit.
311
+ Default: blank.
312
+
313
+ #### `exit_commands`
314
+
315
+ An array of commands that if typed, will exit the terminal.
316
+ Default: `["exit", "q"]`.
317
+
318
+ #### `system_character`
319
+
320
+ The prefix character that if typed at the beginning of a command, will avoid
321
+ executing the runner, and instead execute a system (shell) command.
322
+ Default: `"/"`.
323
+
324
+
325
+
240
326
  In the Wild
241
327
  --------------------------------------------------
242
328
 
@@ -247,9 +333,14 @@ Several examples of real world use of Mister Bin in the wild (well,
247
333
  - [Madman][3] - The Markdown Swiss Army Knife
248
334
  - [Kojo][2] - Command line utility for generating config files from templates
249
335
  and definition files
336
+ - [Jobly][6] - Compact job server with API, CLI and Web UI
337
+ - [Slacktail][7] - Command line utility for following your Slack chat from the terminal
250
338
 
251
339
 
252
340
  [1]: http://docopt.org/
253
341
  [2]: https://github.com/DannyBen/kojo
254
342
  [3]: https://github.com/DannyBen/madman
255
343
  [4]: https://github.com/DannyBen/audio_addict
344
+ [5]: https://github.com/dannyben/colsole
345
+ [6]: https://github.com/dannyben/jobly
346
+ [7]: https://github.com/dannyben/slacktail
@@ -1,5 +1,6 @@
1
1
  require 'mister_bin/command'
2
2
  require 'mister_bin/command_meta'
3
3
  require 'mister_bin/runner'
4
+ require 'mister_bin/terminal'
4
5
 
5
6
  require 'byebug' if ENV['BYEBUG']
@@ -0,0 +1,107 @@
1
+ require 'readline'
2
+ require 'colsole'
3
+ require 'shellwords'
4
+
5
+ module MisterBin
6
+ class Terminal
7
+ include Colsole
8
+
9
+ attr_reader :runner, :options
10
+
11
+ def initialize(runner, options=nil)
12
+ @runner = runner
13
+ @options = options || {}
14
+ end
15
+
16
+ def start
17
+ Readline.completion_append_character = " "
18
+ Readline.completion_proc = autocomplete_handler if autocomplete
19
+
20
+ welcome_messages
21
+ loop { break unless safe_input_loop }
22
+ end
23
+
24
+ private
25
+
26
+ def safe_input_loop
27
+ input_loop
28
+ # :nocov:
29
+ rescue Interrupt
30
+ say exit_message if exit_message
31
+ false
32
+ rescue => e
33
+ puts e.backtrace.reverse if ENV['DEBUG']
34
+ say! "!txtred!#{e.class}: #{e.message}"
35
+ true
36
+ # :nocov:
37
+ end
38
+
39
+ def welcome_messages
40
+ say header if header
41
+ runner.run if show_usage
42
+ end
43
+
44
+ def input_loop
45
+ while input = Readline.readline(prompt, true) do
46
+ break unless execute input
47
+ end
48
+ end
49
+
50
+ def execute(input)
51
+ if exit_commands.include? input
52
+ say exit_message if exit_message
53
+ false
54
+ else
55
+ execute_command input
56
+ true
57
+ end
58
+ end
59
+
60
+ def execute_command(input)
61
+ command = Shellwords.shellwords input
62
+
63
+ if command.first&.start_with? system_character
64
+ system input[1..-1]
65
+ else
66
+ runner.run command
67
+ end
68
+ end
69
+
70
+ def header
71
+ @header ||= options[:header]
72
+ end
73
+
74
+ def show_usage
75
+ options[:show_usage]
76
+ end
77
+
78
+ def prompt
79
+ @prompt ||= options[:prompt] || "\n> "
80
+ end
81
+
82
+ def autocomplete
83
+ @autocomplete ||= options[:autocomplete]&.sort
84
+ end
85
+
86
+ def exit_message
87
+ @exit_message ||= options[:exit_message]
88
+ end
89
+
90
+ def exit_commands
91
+ @exit_commands ||= options[:exit_commands] || ['exit', 'q']
92
+ end
93
+
94
+ def system_character
95
+ @system_character ||= options[:system_character] || '/'
96
+ end
97
+
98
+ def autocomplete_handler
99
+ @autocomplete_handler ||= proc do |s|
100
+ # :nocov:
101
+ autocomplete.grep(/#{Regexp.escape(s)}/)
102
+ # :nocov:
103
+ end
104
+ end
105
+
106
+ end
107
+ end
@@ -1,3 +1,3 @@
1
1
  module MisterBin
2
- VERSION = "0.6.3"
2
+ VERSION = "0.7.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mister_bin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.3
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Danny Ben Shitrit
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-03-20 00:00:00.000000000 Z
11
+ date: 2019-09-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colsole
@@ -49,6 +49,7 @@ files:
49
49
  - lib/mister_bin/command.rb
50
50
  - lib/mister_bin/command_meta.rb
51
51
  - lib/mister_bin/runner.rb
52
+ - lib/mister_bin/terminal.rb
52
53
  - lib/mister_bin/version.rb
53
54
  homepage: https://github.com/dannyben/mister_bin
54
55
  licenses:
@@ -69,7 +70,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
69
70
  - !ruby/object:Gem::Version
70
71
  version: '0'
71
72
  requirements: []
72
- rubygems_version: 3.0.3
73
+ rubygems_version: 3.0.4
73
74
  signing_key:
74
75
  specification_version: 4
75
76
  summary: Command line interface for your gems