dsl_evaluator 0.1.1 → 0.2.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: c93e3439b6133c0d201856d61afcfe5360d0c6f8a821a00c2eb551612553a969
4
- data.tar.gz: 6d074772c6075e1aea243072fcf83e2deb1e2de69bb7d3341177f1458fe417f8
3
+ metadata.gz: dd75a6a48ce5a9eb6858f470264eaf01af1039d93e4be1d5f609f8bc381ba297
4
+ data.tar.gz: d21493fb8aa7d9c78c7e873374a8037c1c40fd3991f4002c379ac0926c0e0e45
5
5
  SHA512:
6
- metadata.gz: 687b819d01e035f8c5e32048776af5048932283415e9f49c08193c98f58e058e346a39c6af1f18167fc49a0f7aaa41e06db64ffcc2a89592f9e2e667cab937e3
7
- data.tar.gz: 7cf6d15da7ac2debb4a04ab0dd4ca8236f97e1670a597127bcf471554bf59d72b027ed1c03a4850f1557a831a71b473cb76926f48acfcacdd5e1078028337c6c
6
+ metadata.gz: fa1913f87e7c7285bf3266097742353fbbb1817dface02543513798aba3d6b284b9231a8702199d3229accf57b6480f620490e15b23d92b25c9f0c03432bf742
7
+ data.tar.gz: 995507941a52c9b0ad3691346268ed5a30d852fb116cc7cd8132692343760411ed213f0b9815a43f20926e35b22d502d9bc3d37d4dd1062fd7d6037d86324305
data/.gitignore CHANGED
@@ -6,6 +6,7 @@
6
6
  /pkg/
7
7
  /spec/reports/
8
8
  /tmp/
9
+ /Gemfile.lock
9
10
 
10
11
  # rspec failure tracking
11
12
  .rspec_status
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.0] - 2022-02-24
7
+ - [#3](https://github.com/tongueroo/dsl_evaluator/pull/3) major improvements: configure ability
8
+
9
+ ## [0.1.3]
10
+ - #2 fix current line number printed
11
+
12
+ ## [0.1.2]
13
+ - #1 get line info from error message also
14
+
6
15
  ## [0.1.1]
7
16
  - make module methods availables
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")
@@ -21,4 +21,8 @@ Gem::Specification.new do |spec|
21
21
  spec.bindir = "exe"
22
22
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
23
  spec.require_paths = ["lib"]
24
+
25
+ spec.add_dependency "activesupport"
26
+ spec.add_dependency "memoist"
27
+ spec.add_dependency "rainbow"
24
28
  end
@@ -0,0 +1,37 @@
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
+
25
+ config
26
+ end
27
+
28
+ def default_logger
29
+ Logger.new(ENV['DSL_EVALUATOR_LOG_PATH'] || $stderr)
30
+ end
31
+ memoize :default_logger
32
+
33
+ def configure
34
+ yield(@config)
35
+ end
36
+ end
37
+ 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
@@ -0,0 +1,96 @@
1
+ module DslEvaluator
2
+ class Printer
3
+ def initialize(error)
4
+ @error = error
5
+ end
6
+
7
+ # Prints out a user friendly task_definition error message
8
+ def print
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']
31
+ end
32
+
33
+ def error_info
34
+ @error.message.include?("syntax") ? info_from_message : info_from_backtrace
35
+ end
36
+
37
+ def info_from_message
38
+ error_info = @error.message
39
+ path, line_number, _ = error_info.split(':')
40
+ {path: path, line_number: line_number}
41
+ end
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
+ #
50
+ def info_from_backtrace
51
+ lines = @error.backtrace
52
+ if ENV['FULL_BACKTRACE']
53
+ logger.error @error.message.color(:red)
54
+ logger.error lines.join("\n")
55
+ end
56
+
57
+ # Keep DslEvaluator.backtrace_reject for backwards compatibility
58
+ backtrace_reject = config.backtrace.reject_pattern || DslEvaluator.backtrace_reject
59
+ if backtrace_reject
60
+ lines = lines.reject do |l|
61
+ if backtrace_reject.is_a?(String)
62
+ l.include?(backtrace_reject)
63
+ else
64
+ l.match(backtrace_reject)
65
+ end
66
+ end
67
+ end
68
+ lines = lines.reject { |l| l.include?("lib/dsl_evaluator") } # ignore internal lib/dsl_evaluator backtrace lines
69
+
70
+ error_info = lines.first
71
+ parts = error_info.split(':')
72
+ windows = error_info.match(/^[a-zA-Z]:/)
73
+ path = windows ? parts[1] : parts[0]
74
+ line_number = windows ? parts[2] : parts[1]
75
+ line_number = line_number.to_i
76
+
77
+ {path: path, line_number: line_number}
78
+ end
79
+
80
+ def pretty_path(path)
81
+ path.sub("#{config.root}/",'')
82
+ end
83
+
84
+ def logger
85
+ config.logger
86
+ end
87
+
88
+ def config
89
+ DslEvaluator.config
90
+ end
91
+
92
+ def message
93
+ @error.message
94
+ end
95
+ end
96
+ end
@@ -1,3 +1,3 @@
1
1
  module DslEvaluator
2
- VERSION = "0.1.1"
2
+ VERSION = "0.2.0"
3
3
  end
data/lib/dsl_evaluator.rb CHANGED
@@ -1,51 +1,48 @@
1
- require "dsl_evaluator/version"
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
2
11
 
3
12
  module DslEvaluator
13
+ extend Memoist
14
+
4
15
  class Error < StandardError; end
5
16
 
6
17
  def evaluate_file(path)
7
18
  return unless path && File.file?(path)
8
19
  instance_eval(IO.read(path), path)
9
20
  rescue Exception => e
10
- evaluation_error(e)
11
- puts "\nFull error:"
12
- raise
21
+ Printer.new(e).print
22
+ case config.on_exception
23
+ when :rescue
24
+ # do nothing
25
+ when :exit
26
+ exit 1
27
+ else # :raise
28
+ raise
29
+ end
13
30
  end
14
31
 
15
- @@backtrace_reject = nil
16
- def backtrace_reject
17
- @@backtrace_reject
32
+ mattr_accessor :backtrace_reject
33
+
34
+ def logger
35
+ config.logger
18
36
  end
19
37
 
20
- def backtrace_reject=(v)
21
- @@backtrace_reject = v
38
+ def configure(&block)
39
+ App.instance.configure(&block)
22
40
  end
23
41
 
24
- # Prints out a user friendly task_definition error message
25
- def evaluation_error(e)
26
- lines = e.backtrace
27
- lines = lines.reject { |l| l.include?(backtrace_reject) } if backtrace_reject
28
- error_info = lines.first
29
- path, line_no, _ = error_info.split(':')
30
- line_no = line_no.to_i
31
- puts "Error evaluating #{path}:".color(:red)
32
- puts e.message
33
- puts "Here's the line in #{path} with the error:\n\n"
34
-
35
- contents = IO.read(path)
36
- content_lines = contents.split("\n")
37
- context = 5 # lines of context
38
- top, bottom = [line_no-context-1, 0].max, line_no+context-1
39
- spacing = content_lines.size.to_s.size
40
- content_lines[top..bottom].each_with_index do |line_content, index|
41
- line_number = top+index+1
42
- if line_number == line_no
43
- printf("%#{spacing}d %s\n".color(:red), line_number, line_content)
44
- else
45
- printf("%#{spacing}d %s\n", line_number, line_content)
46
- end
47
- end
42
+ def config
43
+ App.instance.config
48
44
  end
45
+ memoize :config
49
46
 
50
47
  extend self
51
48
  end
metadata CHANGED
@@ -1,15 +1,57 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dsl_evaluator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
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-12 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2022-02-24 00:00:00.000000000 Z
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'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rainbow
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
13
55
  description:
14
56
  email:
15
57
  - tongueroo@gmail.com
@@ -29,6 +71,10 @@ files:
29
71
  - bin/setup
30
72
  - dsl_evaluator.gemspec
31
73
  - lib/dsl_evaluator.rb
74
+ - lib/dsl_evaluator/app.rb
75
+ - lib/dsl_evaluator/autoloader.rb
76
+ - lib/dsl_evaluator/logger.rb
77
+ - lib/dsl_evaluator/printer.rb
32
78
  - lib/dsl_evaluator/version.rb
33
79
  homepage: https://github.com/tongueroo/dsl_evaluator
34
80
  licenses:
@@ -50,9 +96,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
50
96
  - !ruby/object:Gem::Version
51
97
  version: '0'
52
98
  requirements: []
53
- rubygems_version: 3.1.2
99
+ rubygems_version: 3.2.32
54
100
  signing_key:
55
101
  specification_version: 4
56
- summary: Small module to help with DSL evaluation. It produces a human-friendly backtrace
57
- error
102
+ summary: DSL evaluation library. It produces a human-friendly backtrace error
58
103
  test_files: []