dsl_evaluator 0.1.1 → 0.2.0

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: 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: []