gm-notepad 0.0.10 → 0.0.11

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
  SHA256:
3
- metadata.gz: 8a9f77aeaa803fe169c27b96242f16fcfe1ebaaf0db7c61aae75a2be0f9ba1c7
4
- data.tar.gz: 3a3728f49177fb88631f9e2c08df8ca9ca7148e7405b0df37986a861a80d950e
3
+ metadata.gz: 72cbb20c02dd2fa334bf57d7d88c40e7772d05ccf03bee599ddbf651e416c645
4
+ data.tar.gz: 1e474a0b888297ae5655e68710f5d40efcfbb59030aac36dab60e4fc765043de
5
5
  SHA512:
6
- metadata.gz: a89494760fa29c73d63381a6737e2b0e540fc88a82cb8abaf2c71c902af2ec2cc8c5d297b20824b50bd96d6cc42ca5c9fcf0432b35a16476a581ed775a2332bc
7
- data.tar.gz: a380d0f07547ff3c3e4f552033e97569e1539c6d82d441f913f4a906625c69e26e63a36479a78f7d6185745ccc68ae33af75c4d99b38f2d7b5777c2f0e94dcb2
6
+ metadata.gz: 49a06ad0a6f85eddaefa70f9f05dd358f39f163cc3c7555f0116d2c645436260910ef8f4ec4b955e26bbf8d332a0957a6dfa401c39b3a7664a44c6f787f6be60
7
+ data.tar.gz: a0f8bd008eb2220a4f8c68726aa96fcd68b110f50725b01091dc7ef5c57096e41d908674d4fa1bd46c0a552f61f01e68dddac3c508a499674d305361845363b4
data/README.md CHANGED
@@ -4,6 +4,10 @@ A command-line tool to help with your GM-ing.
4
4
 
5
5
  ## To install
6
6
 
7
+ First, you will need a working copy of Ruby. I recommend following the [instructions over at rbenv's Github page](https://github.com/rbenv/rbenv#installation).
8
+
9
+ Next, you'll want to install the `gm-notepad` gem.
10
+
7
11
  `$ gem install gm-notepad`
8
12
 
9
13
  ## Background
@@ -61,7 +65,6 @@ Options:
61
65
  -f, --filesystem_directory=DIR Path to dump tables (Default: ".")
62
66
  -x, --table_extension=EXT Extension to use for selecting tables (Default: ".txt")
63
67
  -t, --timestamp Append a timestamp to the note (Default: false)
64
- -d, --defer_output Defer output until system close (Default: false)
65
68
 
66
69
  Color options:
67
70
  -i, --skip-interactive-color Disable color rendering for interactive buffer (Default: false)
@@ -79,7 +82,6 @@ Which writes the following to the `interactive` buffer (eg. `$stderr`)::
79
82
  ```console
80
83
  # Configuration Parameters:
81
84
  # config[:report_config] = true
82
- # config[:defer_output] = false
83
85
  # config[:filesystem_directory] = "."
84
86
  # config[:interactive_buffer] = #<IO:<STDERR>>
85
87
  # config[:interactive_color] = true
@@ -227,15 +229,17 @@ columns. _I am still working on retrieving by column names as well as rendering
227
229
  - [ ] Gracefully handle loading a malformed data file (maybe?)
228
230
  - [X] Add concept of history
229
231
  - [X] When expanding tables account for line expansion (via \n and \t)
230
- - [ ] Separate the InputHandler into pre-amble (e.g. allow overrides to where we are writing, determine what command we are writing)
232
+ - [X] Separate the InputHandler into pre-amble (e.g. allow overrides to where we are writing, determine what command we are writing)
231
233
  - [X] Create a configuration object that captures the initial input (reduce passing around parameters and persisting copies of the config)
232
234
  - [ ] Add concept of "journal entry"; its not a table (perhaps) but something that you could capture notes.
233
235
  - [X] Add column handling `{table[][]}`
234
- - [ ] Gracefully handle cell lookup when named cell for entry is not found
236
+ - [X] Gracefully handle cell lookup when named cell for entry is not found
235
237
  - [X] Support `\{\{table}-name}` You should be able to do `\{\{culture}-name}` and first evaluate to `{arabic-name}` and then get a value from the `arabic-name` table
236
238
  - [X] Ensure index names are lower-case
237
239
  - [ ] Hit 100% spec coverage
238
240
  - [ ] Create a "To Render Object"; When you parse the input, you push relevant lines to that "To Render Object". When you look at a table, you want to know what the column names are.
241
+ - [X] Remove "defer" printing concept
242
+ - [ ] Add ability to shell out; I would love to leverage the [swnt](https://github.com/nboughton/swnt) command line tool
239
243
 
240
244
  ### Stretch TODO
241
245
 
data/Rakefile CHANGED
@@ -17,7 +17,7 @@ namespace :commitment do
17
17
  lastrun_filename = File.expand_path('../coverage/.last_run.json', __FILE__)
18
18
  if File.exist?(lastrun_filename)
19
19
  coverage_percentage = JSON.parse(File.read(lastrun_filename)).fetch('result').fetch('covered_percent').to_i
20
- EXPECTED_COVERAGE_GOAL = 98
20
+ EXPECTED_COVERAGE_GOAL = 97
21
21
  if coverage_percentage < EXPECTED_COVERAGE_GOAL
22
22
  abort("ERROR: Code Coverage Goal Not Met:\n\t#{coverage_percentage}%\tExpected\n\t#{EXPECTED_COVERAGE_GOAL}%\tActual")
23
23
  else
data/exe/gm-notepad CHANGED
@@ -2,7 +2,8 @@
2
2
  require 'gm/notepad'
3
3
 
4
4
  require 'optparse'
5
- config = Gm::Notepad::Configuration::CLI_CONFIG_DEFAULTS.clone
5
+ defaults = Gm::Notepad::Config
6
+ config = {}
6
7
 
7
8
  command_name = File.basename(__FILE__)
8
9
 
@@ -16,50 +17,47 @@ OptionParser.new do |options|
16
17
  "\t$ echo '{name}' | #{command_name}\n\n" \
17
18
  "Options:\n"
18
19
 
19
- options.on_head("-l", "--list_tables", "List tables loaded and exit (Default: #{config[:list_tables].inspect})") do |list_tables|
20
+ options.on_head("-l", "--list_tables", "List tables loaded and exit (Default: #{defaults.list_tables.inspect})") do |list_tables|
20
21
  config[:list_tables] = list_tables
21
22
  end
22
23
 
23
- options.on("-r", "--report_config", "Dump the configuration data (Default: #{config[:report_config].inspect})") do |report_config|
24
+ options.on("-r", "--report_config", "Dump the configuration data (Default: #{defaults.report_config.inspect})") do |report_config|
24
25
  config[:report_config] = report_config
25
26
  end
26
27
 
27
- options.on("-pPATH", "--path=PATH", String, "Path(s) for {table_name}.<config.table_extension> files (Default: [\".\"])") do |path|
28
+ options.on("-pPATH", "--path=PATH", String, "Path(s) for {table_name}.<config.table_extension> files (Default: #{defaults.paths.inspect})") do |path|
29
+ config[:paths] ||= []
28
30
  config[:paths] << path
29
31
  end
30
32
 
31
- options.on("-fDIR", "--filesystem_directory=DIR", String, "Path to dump tables (Default: #{config[:filesystem_directory].inspect})") do |filesystem_directory|
33
+ options.on("-fDIR", "--filesystem_directory=DIR", String, "Path to dump tables (Default: #{defaults.filesystem_directory.inspect})") do |filesystem_directory|
32
34
  # Should we guard that this exists?
33
35
  config[:filesystem_directory] = filesystem_directory
34
36
  end
35
37
 
36
- options.on("-xEXT", "--table_extension=EXT", String, "Extension to use for selecting tables (Default: #{config[:table_extension].inspect})") do |table_extension|
38
+ options.on("-xEXT", "--table_extension=EXT", String, "Extension to use for selecting tables (Default: #{defaults.table_extension.inspect})") do |table_extension|
37
39
  config[:table_extension] = table_extension
38
40
  end
39
41
 
40
- options.on("-dDELIM", "--delimiter=DELIM", String, "Default column delimiter for tables (Default: #{config[:column_delimiter].inspect})") do |column_delimiter|
42
+ options.on("-dDELIM", "--delimiter=DELIM", String, "Default column delimiter for tables (Default: #{defaults.column_delimiter.inspect})") do |column_delimiter|
41
43
  map = { "t" => "\t" }
42
44
  config[:column_delimiter] = map.fetch(column_delimiter) { column_delimiter }
43
45
  end
44
46
 
45
47
  options.separator("")
46
48
  options.separator("Output options:")
47
- options.on("-t", "--timestamp", "Append a timestamp to the note (Default: #{config[:with_timestamp].inspect})") do |timestamp|
49
+ options.on("-t", "--timestamp", "Append a timestamp to the note (Default: #{defaults.with_timestamp.inspect})") do |timestamp|
48
50
  config[:with_timestamp] = timestamp
49
51
  end
50
52
 
51
- options.on("--defer_output", "Defer output until system close (Default: #{config[:defer_output].inspect})") do |defer_output|
52
- config[:defer_output] = defer_output
53
- end
54
-
55
53
  options.separator("")
56
54
  options.separator("Color options:")
57
55
 
58
- options.on("-i", "--skip-interactive-color", "Disable color rendering for interactive buffer (Default: #{!config[:interactive_color].inspect})") do |interactive_color|
56
+ options.on("-i", "--skip-interactive-color", "Disable color rendering for interactive buffer (Default: #{(!defaults.interactive_color).inspect})") do |interactive_color|
59
57
  config[:interactive_color] = !interactive_color
60
58
  end
61
59
 
62
- options.on("-o", "--with-output-color", "Enable color rendering for output buffer (Default: #{!config[:output_color].inspect})") do |output_color|
60
+ options.on("-o", "--with-output-color", "Enable color rendering for output buffer (Default: #{(!defaults.output_color).inspect})") do |output_color|
63
61
  config[:output_color] = output_color
64
62
  end
65
63
 
@@ -72,14 +70,14 @@ OptionParser.new do |options|
72
70
  end.parse!
73
71
 
74
72
  if config[:list_tables]
75
- notepad = Gm::Notepad.new(config.merge(report_config: true))
76
- notepad.process(input: "+")
73
+ notepad = Gm::Notepad.new(finalize: true, **config.merge(report_config: true))
74
+ notepad.process(text: "+")
77
75
  exit(1)
78
76
  end
79
77
 
80
78
  begin
81
- @notepad = Gm::Notepad.new(**config)
82
- if config.fetch(:skip_readlines)
79
+ @notepad = Gm::Notepad.new(finalize: true, **config)
80
+ if Gm::Notepad::Config.skip_readlines
83
81
  input_getter = ARGF.method(:gets)
84
82
  else
85
83
  require 'gm/notepad/readline'
@@ -87,9 +85,9 @@ begin
87
85
  end
88
86
  while input = input_getter.call
89
87
  # # Keep reading lines of input as long as they're coming.
90
- input.each_line do |input|
88
+ input.each_line do |text|
91
89
  begin
92
- @notepad.process(input: input)
90
+ @notepad.process(text: text)
93
91
  rescue Errno::EPIPE
94
92
  @notepad.close!
95
93
 
data/gm-notepad.gemspec CHANGED
@@ -22,6 +22,9 @@ Gem::Specification.new do |spec|
22
22
  spec.require_paths = ["lib"]
23
23
 
24
24
  spec.add_dependency "dice_parser"
25
+ spec.add_dependency "dry-configurable"
26
+ spec.add_dependency "dry-container"
27
+ spec.add_dependency "dry-initializer"
25
28
  spec.add_dependency "term-ansicolor"
26
29
  spec.add_development_dependency "bundler"
27
30
  spec.add_development_dependency "rake"
data/lib/gm/notepad.rb CHANGED
@@ -1,12 +1,14 @@
1
1
  require "gm/notepad/version"
2
- require "gm/notepad/defaults"
3
- require "gm/notepad/pad"
4
- require "gm/notepad/configuration"
2
+ require 'gm/notepad/config'
3
+ require "gm/notepad/app"
5
4
  module Gm
6
5
  module Notepad
7
- def self.new(*args)
8
- config = Configuration.new(*args)
9
- Pad.new(config: config)
6
+ def self.new(finalize: false, **config_parameters)
7
+ config_parameters.each_pair do |key, value|
8
+ Config.config.public_send("#{key}=", value)
9
+ end
10
+ Config.finalize! if finalize
11
+ App.new
10
12
  end
11
13
  end
12
14
  end
@@ -0,0 +1,45 @@
1
+ require 'dry-initializer'
2
+ require 'gm/notepad/container'
3
+ require 'gm/notepad/throughput_text'
4
+
5
+ module Gm
6
+ module Notepad
7
+ # Responsible for recording entries and then dumping them accordingly.
8
+ class App
9
+ extend Dry::Initializer
10
+ option :renderer, default: -> { Container.resolve(:renderer) }
11
+ option :input_processor, default: -> { Container.resolve(:input_processor) }
12
+ option :report_config, default: -> { Container.resolve(:config).report_config }, reader: :private
13
+ option :list_tables, default: -> { Container.resolve(:config).list_tables }, reader: :private
14
+
15
+ def initialize(*args)
16
+ super
17
+ open!
18
+ end
19
+
20
+ def process(text:)
21
+ output = input_processor.convert_to_output(input: text)
22
+ renderer.render(output: output)
23
+ end
24
+
25
+ def close!
26
+ renderer.close!
27
+ end
28
+
29
+ private
30
+
31
+ def open!
32
+ renderer.call("Welcome to gm-notepad. type \"?\" for help.", to_interactive: true, to_output: false)
33
+ return unless report_config
34
+ lines = ["# Configuration Parameters:"]
35
+ Config.settings.each do |setting|
36
+ lines << "# config[#{setting.inspect}] = #{Config.public_send(setting).inspect}"
37
+ end
38
+ # When running :list_tables by default I don't want to report
39
+ # that to the output buffer.
40
+ to_output = !list_tables
41
+ renderer.call(lines, to_interactive: true, to_output: to_output)
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,47 @@
1
+ require 'dry-initializer'
2
+ require 'term/ansicolor'
3
+ require 'gm/notepad/container'
4
+
5
+ module Gm
6
+ module Notepad
7
+ # To provide a means for colorizing the output and defering output
8
+ class BufferWrapper
9
+ def self.for_interactive(buffer:)
10
+ new(buffer: buffer, color: Container[:config].interactive_color, append_new_line_on_close: true)
11
+ end
12
+
13
+ def self.for_output(buffer:)
14
+ new(buffer: buffer, color: Container[:config].output_color, append_new_line_on_close: false)
15
+ end
16
+ private_class_method :new
17
+
18
+ extend Dry::Initializer
19
+ option :buffer
20
+ option :color, default: -> { false }
21
+ option :append_new_line_on_close, default: -> { false }
22
+ option :lines, default: -> { [] }
23
+
24
+ def initialize(*args)
25
+ super
26
+ if color
27
+ buffer.extend(Term::ANSIColor)
28
+ end
29
+ end
30
+
31
+ def puts(text)
32
+ if color
33
+ buffer.puts("#{buffer.public_send(color)}#{text}#{buffer.reset}")
34
+ else
35
+ buffer.puts("#{text}")
36
+ end
37
+ end
38
+
39
+ def close!
40
+ self.lines.each do |line|
41
+ puts(line)
42
+ end
43
+ buffer.print("\n") if append_new_line_on_close
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,31 @@
1
+ require 'dry-container'
2
+ module Gm
3
+ module Notepad
4
+ class Config
5
+ extend Dry::Configurable
6
+
7
+ setting :report_config, false, reader: true
8
+ setting :filesystem_directory, '.', reader: true
9
+ setting :index_entry_prefix, "index", reader: true
10
+ setting :interactive_buffer, $stderr, reader: true
11
+ setting :interactive_color, :faint, reader: true
12
+ setting :output_color, false, reader: true
13
+ setting :list_tables, false, reader: true
14
+ setting :output_buffer, $stdout, reader: true
15
+ setting :paths, ['.'], reader: true
16
+ setting :column_delimiter, "|", reader: true
17
+ setting :skip_readlines, false, reader: true
18
+ setting :include_original_command_as_comment, true, reader: true
19
+ setting :table_extension, '.txt', reader: true
20
+ setting :with_timestamp, false, reader: true
21
+
22
+ def self.index_entry_prefix_regexp
23
+ %r{^#{Regexp.escape(index_entry_prefix)} *#{Regexp.escape(column_delimiter)}}i
24
+ end
25
+
26
+ def index_entry_prefix_regexp
27
+ %r{^#{Regexp.escape(index_entry_prefix)} *#{Regexp.escape(column_delimiter)}}i
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,50 @@
1
+ require 'dry-container'
2
+
3
+ module Gm
4
+ module Notepad
5
+ # A container for dependency injection
6
+ class Container
7
+ extend Dry::Container::Mixin
8
+
9
+ register "input_processor" do
10
+ require 'gm/notepad/input_processor'
11
+ InputProcessor.new
12
+ end
13
+
14
+ register "config" do
15
+ require 'gm/notepad/config'
16
+ Config
17
+ end
18
+
19
+ register "table_registry" do
20
+ require 'gm/notepad/table_registry'
21
+ TableRegistry.build_and_load
22
+ end
23
+
24
+ register "renderer" do
25
+ require 'gm/notepad/line_renderer'
26
+ LineRenderer.new
27
+ end
28
+
29
+ register "input_handler_registry" do
30
+ # Order matters. The first registered will be the first to
31
+ # answer "Can you handle the input?"
32
+ require "gm/notepad/input_handler_registry"
33
+ require "gm/notepad/input_handlers/help_handler"
34
+ require "gm/notepad/input_handlers/comment_handler"
35
+ require "gm/notepad/input_handlers/query_table_handler"
36
+ require "gm/notepad/input_handlers/query_table_names_handler"
37
+ require "gm/notepad/input_handlers/write_to_table_handler"
38
+ require "gm/notepad/input_handlers/write_line_handler"
39
+ InputHandlerRegistry.new do |registry|
40
+ registry.register(handler: InputHandlers::HelpHandler)
41
+ registry.register(handler: InputHandlers::CommentHandler)
42
+ registry.register(handler: InputHandlers::QueryTableHandler)
43
+ registry.register(handler: InputHandlers::QueryTableNamesHandler)
44
+ registry.register(handler: InputHandlers::WriteToTableHandler)
45
+ registry.register(handler: InputHandlers::WriteLineHandler)
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -10,7 +10,7 @@ module Gm
10
10
  class MissingTableError < RuntimeError
11
11
  def initialize(name:)
12
12
  @name = name
13
- super(%(Missing table "#{name}"))
13
+ super(%((Missing table "#{name}")))
14
14
  end
15
15
  alias to_buffer_message to_s
16
16
  end
@@ -8,16 +8,16 @@ module Gm
8
8
  yield(self) if block_given?
9
9
  end
10
10
 
11
- def handler_for(input:, skip_default: false)
11
+ def handler_for(input:, skip_default: false, table_registry: Container.resolve(:table_registry))
12
12
  handler = nil
13
13
  @registry.each do |handler_builder|
14
- if handler = handler_builder.build_if_handled(input: input)
14
+ if handler = handler_builder.build_if_handled(input: input, table_registry: table_registry)
15
15
  break
16
16
  end
17
17
  end
18
18
  return handler if handler
19
19
  return nil if skip_default
20
- default_handler_builder.build_if_handled(input: input)
20
+ default_handler_builder.build_if_handled(input: input, table_registry: table_registry)
21
21
  end
22
22
 
23
23
  def register(handler:)
@@ -6,18 +6,16 @@ module Gm
6
6
  COMMENT_PREFIX = '#'.freeze
7
7
 
8
8
  def self.handles?(input:)
9
- return false unless input[0] == COMMENT_PREFIX
9
+ return false unless input.match(/^#/)
10
10
  true
11
11
  end
12
12
 
13
13
  def after_initialize!
14
- self.to_interactive = true
15
- self.to_output = false
16
- self.expand_line = false
17
- end
18
-
19
- def lines
20
- [input]
14
+ input.render_current_text(
15
+ to_interactive: true,
16
+ to_output: false,
17
+ expand_line: false
18
+ )
21
19
  end
22
20
  end
23
21
  end
@@ -1,41 +1,33 @@
1
+ require 'gm/notepad/throughput_text'
2
+ require 'dry-initializer'
1
3
  module Gm
2
4
  module Notepad
3
5
  module InputHandlers
4
6
  class DefaultHandler
5
- def self.build_if_handled(input:)
7
+ def self.build_if_handled(input:, table_registry: Container.resolve(:table_registry))
6
8
  return false unless handles?(input: input)
7
- new(input: input)
9
+ new(input: input, table_registry: table_registry)
8
10
  end
9
11
 
10
12
  def self.handles?(input:)
11
13
  true
12
14
  end
13
15
 
14
- def initialize(input:, table_registry: nil)
15
- self.to_interactive = false
16
- self.to_output = false
17
- self.to_filesystem = false
18
- self.expand_line = false
19
- self.input = input
20
- self.table_registry = table_registry
16
+ extend Dry::Initializer
17
+ option :input
18
+ option :table_registry, default: -> { Container.resolve(:table_registry) }
19
+ def initialize(*args)
20
+ super
21
21
  after_initialize!
22
22
  end
23
- attr_accessor :table_registry, :to_interactive, :to_output, :expand_line, :input, :to_filesystem
24
-
25
- def after_initialize!
26
- end
27
23
 
28
24
  def lines
29
- []
25
+ input.lines
30
26
  end
31
27
 
32
- alias expand_line? expand_line
28
+ private
33
29
 
34
- def each_line_with_parameters
35
- lines.each do |line|
36
- line = table_registry.evaluate(line: line.to_s.strip) if expand_line?
37
- yield(line, to_output: to_output, to_interactive: to_interactive)
38
- end
30
+ def after_initialize!
39
31
  end
40
32
  end
41
33
  end