dsl_evaluator 0.1.2 → 0.2.1

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: 38416a5462223f8c1b87c303e81c02d7410e76c371fde03eb03de37a9f455a90
4
- data.tar.gz: 264bb6cc47c4c02a047dea7812810b741be48eca5f6298bce98510a568b3be26
3
+ metadata.gz: 5d712162a49ab0151d9acb686bc7613b11f242a0187f95628b5617a2fe88de58
4
+ data.tar.gz: 481d6aea0a1800ad8efc46af97771b99925d69bc81231ff4673c02f01d3e0d52
5
5
  SHA512:
6
- metadata.gz: 76d9c1b745ce57961e5d8458e0037c16709617e821f43ce6ee6b4072b54cae60e117ea6a9540ee1fde97fca86276b7498a184a77fefc5cab9b8a603103e80042
7
- data.tar.gz: bc0e3ec881d84a2ef80b16b05dbbed1c3f63877a394e9027bb409372501a557af5c08b352631ece2d49e262cde1733f7b69637bb2ca1fefce29291626501b84c
6
+ metadata.gz: '0854ffb84d518b498c2c32ddc16cfa0f6306645be452574cf22e878a002959be6792bd4f7dd0ef4e1af20460ea5443f74164bdf5cbef58a8f0a6fd48429d0062'
7
+ data.tar.gz: d66dd8eaf3d9317e74227d9fef78cdfae27f6db990587b7c80a0be29ab1b2f47c2f87c83a408fccb9b59728ca55887121798473ffcefef92af2bffead1df6e38
data/CHANGELOG.md CHANGED
@@ -3,6 +3,15 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  This project *loosely tries* to adhere to [Semantic Versioning](http://semver.org/).
5
5
 
6
+ ## [0.2.1] - 2022-02-25
7
+ - [#4](https://github.com/tongueroo/dsl_evaluator/pull/4) add config.select_pattern option
8
+
9
+ ## [0.2.0] - 2022-02-24
10
+ - [#3](https://github.com/tongueroo/dsl_evaluator/pull/3) major improvements: configure ability
11
+
12
+ ## [0.1.3]
13
+ - #2 fix current line number printed
14
+
6
15
  ## [0.1.2]
7
16
  - #1 get line info from error message also
8
17
 
data/README.md CHANGED
@@ -4,14 +4,22 @@ Small module to help with DSL evaluation. Notably, it produces a human-friendly
4
4
 
5
5
  ## Usage
6
6
 
7
+ Example usage:
8
+
7
9
  ```ruby
8
- require "dsl_evaluator"
9
- DslEvaluator.backtrace_reject = "lib/my_gem" # optional
10
+ DslEvaluator.configure do |config|
11
+ config.backtrace.reject_pattern = "/lib/lono"
12
+ config.logger = Lono.logger
13
+ config.on_exception = :exit
14
+ config.root = Lono.root
15
+ end
16
+
10
17
 
11
- class DslBuilder
18
+ class Dsl
19
+ include DslEvaluator
12
20
  def build
13
21
  path = "/path/to/user/provided/dsl/file.rb"
14
- evaluate_file(path)
22
+ evaluate_file(path) # from DslEvaluator module
15
23
  end
16
24
  end
17
25
  ```
@@ -6,7 +6,7 @@ Gem::Specification.new do |spec|
6
6
  spec.authors = ["Tung Nguyen"]
7
7
  spec.email = ["tongueroo@gmail.com"]
8
8
 
9
- spec.summary = "Small module to help with DSL evaluation. It produces a human-friendly backtrace error"
9
+ spec.summary = "DSL evaluation library. It produces a human-friendly backtrace error"
10
10
  spec.homepage = "https://github.com/tongueroo/dsl_evaluator"
11
11
  spec.license = "MIT"
12
12
  spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
@@ -22,5 +22,7 @@ Gem::Specification.new do |spec|
22
22
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
23
  spec.require_paths = ["lib"]
24
24
 
25
+ spec.add_dependency "activesupport"
26
+ spec.add_dependency "memoist"
25
27
  spec.add_dependency "rainbow"
26
28
  end
@@ -0,0 +1,38 @@
1
+ module DslEvaluator
2
+ class App
3
+ extend Memoist
4
+ include Singleton
5
+
6
+ attr_reader :config
7
+ def initialize
8
+ @config = defaults
9
+ end
10
+
11
+ def defaults
12
+ config = ActiveSupport::OrderedOptions.new
13
+
14
+ config.logger = default_logger
15
+ config.logger.formatter = Logger::Formatter.new
16
+ config.logger.level = ENV['DSL_EVALUATOR_LOG_LEVEL'] || :info
17
+
18
+ config.on_exception = :raise
19
+
20
+ config.root = Dir.pwd
21
+
22
+ config.backtrace = ActiveSupport::OrderedOptions.new
23
+ config.backtrace.reject_pattern = nil # dont use .reject. Seems its used internally by ActiveSupport::OrderedOptions
24
+ config.backtrace.select_pattern = nil
25
+
26
+ config
27
+ end
28
+
29
+ def default_logger
30
+ Logger.new(ENV['DSL_EVALUATOR_LOG_PATH'] || $stderr)
31
+ end
32
+ memoize :default_logger
33
+
34
+ def configure
35
+ yield(@config)
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,20 @@
1
+ module DslEvaluator
2
+ class Autoloader
3
+ class Inflector < Zeitwerk::Inflector
4
+ def camelize(basename, _abspath)
5
+ map = { cli: "CLI", version: "VERSION" }
6
+ map[basename.to_sym] || super
7
+ end
8
+ end
9
+
10
+ class << self
11
+ def setup
12
+ loader = Zeitwerk::Loader.new
13
+ loader.inflector = Inflector.new
14
+ loader.push_dir(File.dirname(__dir__)) # lib
15
+ loader.log! if ENV["DSL_EVALUATOR_AUTOLOAD_LOG"]
16
+ loader.setup
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,30 @@
1
+ module DslEvaluator
2
+ class Logger < ::Logger
3
+ def initialize(*args)
4
+ super
5
+ self.formatter = Formatter.new
6
+ self.level = ENV['DSL_EVALUATOR_LOG_LEVEL'] || :info # note: only respected when config.logger not set in config/app.rb
7
+ end
8
+
9
+ def format_message(severity, datetime, progname, msg)
10
+ line = if @logdev.dev == $stdout || @logdev.dev == $stderr || @logdev.dev.is_a?(StringIO)
11
+ msg # super simple format if stdout
12
+ else
13
+ super # use the configured formatter
14
+ end
15
+ line =~ /\n$/ ? line : "#{line}\n"
16
+ end
17
+
18
+ # Used to allow output to always go to stdout
19
+ def stdout(msg, newline: true)
20
+ if newline
21
+ puts msg
22
+ else
23
+ print msg
24
+ end
25
+ end
26
+
27
+ public :print
28
+ public :printf
29
+ end
30
+ end
@@ -4,16 +4,33 @@ module DslEvaluator
4
4
  @error = error
5
5
  end
6
6
 
7
- def message
8
- @error.message
9
- end
10
-
11
7
  # Prints out a user friendly task_definition error message
12
8
  def print
13
- print_source(info)
9
+ info = error_info
10
+ path = info[:path]
11
+ line_number = info[:line_number].to_i
12
+
13
+ logger.error "Error evaluating #{pretty_path(path)}".color(:red)
14
+ logger.error "Here's the line with the error:\n\n"
15
+
16
+ contents = IO.read(path)
17
+ content_lines = contents.split("\n")
18
+ context = 5 # lines of context
19
+ top, bottom = [line_number-context-1, 0].max, line_number+context-1
20
+ lpad = content_lines.size.to_s.size
21
+ content_lines[top..bottom].each_with_index do |line_content, index|
22
+ current_line = top+index+1
23
+ if current_line == line_number
24
+ printf("%#{lpad}d %s\n".color(:red), current_line, line_content)
25
+ else
26
+ printf("%#{lpad}d %s\n", current_line, line_content)
27
+ end
28
+ end
29
+
30
+ logger.info "Rerun with FULL_BACKTRACE=1 to see full backtrace" unless ENV['FULL_BACKTRACE']
14
31
  end
15
32
 
16
- def info
33
+ def error_info
17
34
  @error.message.include?("syntax") ? info_from_message : info_from_backtrace
18
35
  end
19
36
 
@@ -23,39 +40,76 @@ module DslEvaluator
23
40
  {path: path, line_number: line_number}
24
41
  end
25
42
 
43
+ # Grab info so can print out user friendly error message
44
+ #
45
+ # Backtrace lines are different for OSes:
46
+ #
47
+ # windows: "C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/terraspace-1.1.1/lib/terraspace/builder.rb:34:in `build'"
48
+ # linux: "/home/ec2-user/.rvm/gems/ruby-3.0.3/gems/terraspace-1.1.1/lib/terraspace/compiler/dsl/syntax/mod.rb:4:in `<module:Mod>'"
49
+ #
26
50
  def info_from_backtrace
27
51
  lines = @error.backtrace
52
+ if ENV['FULL_BACKTRACE']
53
+ logger.error @error.message.color(:red)
54
+ logger.error lines.join("\n")
55
+ end
28
56
 
29
- backtrace_reject = DslEvaluator.backtrace_reject
30
- lines = lines.reject { |l| l.include?(backtrace_reject) } if backtrace_reject
31
- lines = lines.reject { |l| l.include?("lib/dsl_evaluator") } # ignore internal lib/dsl_evaluator backtrace lines
57
+ lines = reject(lines)
58
+ lines = select(lines)
32
59
 
33
60
  error_info = lines.first
34
- path, line_number, _ = error_info.split(':')
61
+ parts = error_info.split(':')
62
+ windows = error_info.match(/^[a-zA-Z]:/)
63
+ path = windows ? parts[1] : parts[0]
64
+ line_number = windows ? parts[2] : parts[1]
65
+ line_number = line_number.to_i
66
+
35
67
  {path: path, line_number: line_number}
36
68
  end
37
69
 
38
- def print_source(info={})
39
- path = info[:path]
40
- line_number = info[:line_number].to_i
70
+ def reject(lines)
71
+ # Keep DslEvaluator.backtrace_reject for backwards compatibility
72
+ pattern = config.backtrace.reject_pattern || DslEvaluator.backtrace_reject
73
+ return lines unless pattern
41
74
 
42
- puts "Error evaluating #{path}:".color(:red)
43
- puts @error.message
44
- puts "Here's the line in #{path} with the error:\n\n"
75
+ lines.reject! do |l|
76
+ if pattern.is_a?(String)
77
+ l.include?(pattern)
78
+ else
79
+ l.match(pattern)
80
+ end
81
+ end
82
+ # Always ignore internal lib/dsl_evaluator backtrace lines
83
+ lines.reject { |l| l.include?("lib/dsl_evaluator") }
84
+ end
45
85
 
46
- contents = IO.read(path)
47
- content_lines = contents.split("\n")
48
- context = 5 # lines of context
49
- top, bottom = [line_number-context-1, 0].max, line_number+context-1
50
- lpad = content_lines.size.to_s.size
51
- content_lines[top..bottom].each_with_index do |line_content, index|
52
- current_line = top+index+1
53
- if current_line == line_number
54
- printf("%#{lpad}d %s\n".color(:red), line_number, line_content)
86
+ def select(lines)
87
+ pattern = config.backtrace.select_pattern
88
+ return unless pattern
89
+
90
+ lines.select do |l|
91
+ if pattern.is_a?(String)
92
+ l.include?(pattern)
55
93
  else
56
- printf("%#{lpad}d %s\n", line_number, line_content)
94
+ l.match(pattern)
57
95
  end
58
96
  end
59
97
  end
98
+
99
+ def pretty_path(path)
100
+ path.sub("#{config.root}/",'')
101
+ end
102
+
103
+ def logger
104
+ config.logger
105
+ end
106
+
107
+ def config
108
+ DslEvaluator.config
109
+ end
110
+
111
+ def message
112
+ @error.message
113
+ end
60
114
  end
61
115
  end
@@ -1,3 +1,3 @@
1
1
  module DslEvaluator
2
- VERSION = "0.1.2"
2
+ VERSION = "0.2.1"
3
3
  end
data/lib/dsl_evaluator.rb CHANGED
@@ -1,8 +1,16 @@
1
- require "dsl_evaluator/version"
2
- require "rainbow/ext/string"
1
+ require 'active_support'
2
+ require 'active_support/core_ext/class'
3
+ require 'active_support/core_ext/hash'
4
+ require 'active_support/core_ext/string'
5
+ require 'dsl_evaluator/version'
6
+ require 'memoist'
7
+ require 'rainbow/ext/string'
8
+
9
+ require "dsl_evaluator/autoloader"
10
+ DslEvaluator::Autoloader.setup
3
11
 
4
12
  module DslEvaluator
5
- autoload :Printer, "dsl_evaluator/printer"
13
+ extend Memoist
6
14
 
7
15
  class Error < StandardError; end
8
16
 
@@ -11,18 +19,30 @@ module DslEvaluator
11
19
  instance_eval(IO.read(path), path)
12
20
  rescue Exception => e
13
21
  Printer.new(e).print
14
- puts "\nFull error:"
15
- raise
22
+ case config.on_exception
23
+ when :rescue
24
+ # do nothing
25
+ when :exit
26
+ exit 1
27
+ else # :raise
28
+ raise
29
+ end
30
+ end
31
+
32
+ mattr_accessor :backtrace_reject
33
+
34
+ def logger
35
+ config.logger
16
36
  end
17
37
 
18
- @@backtrace_reject = nil
19
- def backtrace_reject
20
- @@backtrace_reject
38
+ def configure(&block)
39
+ App.instance.configure(&block)
21
40
  end
22
41
 
23
- def backtrace_reject=(v)
24
- @@backtrace_reject = v
42
+ def config
43
+ App.instance.config
25
44
  end
45
+ memoize :config
26
46
 
27
47
  extend self
28
48
  end
metadata CHANGED
@@ -1,15 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dsl_evaluator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tung Nguyen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-05-30 00:00:00.000000000 Z
11
+ date: 2022-02-25 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: memoist
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
13
41
  - !ruby/object:Gem::Dependency
14
42
  name: rainbow
15
43
  requirement: !ruby/object:Gem::Requirement
@@ -43,6 +71,9 @@ files:
43
71
  - bin/setup
44
72
  - dsl_evaluator.gemspec
45
73
  - lib/dsl_evaluator.rb
74
+ - lib/dsl_evaluator/app.rb
75
+ - lib/dsl_evaluator/autoloader.rb
76
+ - lib/dsl_evaluator/logger.rb
46
77
  - lib/dsl_evaluator/printer.rb
47
78
  - lib/dsl_evaluator/version.rb
48
79
  homepage: https://github.com/tongueroo/dsl_evaluator
@@ -65,9 +96,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
65
96
  - !ruby/object:Gem::Version
66
97
  version: '0'
67
98
  requirements: []
68
- rubygems_version: 3.1.2
99
+ rubygems_version: 3.2.32
69
100
  signing_key:
70
101
  specification_version: 4
71
- summary: Small module to help with DSL evaluation. It produces a human-friendly backtrace
72
- error
102
+ summary: DSL evaluation library. It produces a human-friendly backtrace error
73
103
  test_files: []