dsl_evaluator 0.1.2 → 0.2.1
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 +4 -4
- data/CHANGELOG.md +9 -0
- data/README.md +12 -4
- data/dsl_evaluator.gemspec +3 -1
- data/lib/dsl_evaluator/app.rb +38 -0
- data/lib/dsl_evaluator/autoloader.rb +20 -0
- data/lib/dsl_evaluator/logger.rb +30 -0
- data/lib/dsl_evaluator/printer.rb +80 -26
- data/lib/dsl_evaluator/version.rb +1 -1
- data/lib/dsl_evaluator.rb +30 -10
- metadata +35 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5d712162a49ab0151d9acb686bc7613b11f242a0187f95628b5617a2fe88de58
|
4
|
+
data.tar.gz: 481d6aea0a1800ad8efc46af97771b99925d69bc81231ff4673c02f01d3e0d52
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
9
|
-
|
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
|
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
|
```
|
data/dsl_evaluator.gemspec
CHANGED
@@ -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 = "
|
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
|
-
|
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
|
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
|
-
|
30
|
-
lines = lines
|
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
|
-
|
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
|
39
|
-
|
40
|
-
|
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
|
-
|
43
|
-
|
44
|
-
|
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
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
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
|
-
|
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
|
data/lib/dsl_evaluator.rb
CHANGED
@@ -1,8 +1,16 @@
|
|
1
|
-
require
|
2
|
-
require
|
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
|
-
|
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
|
-
|
15
|
-
|
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
|
-
|
19
|
-
|
20
|
-
@@backtrace_reject
|
38
|
+
def configure(&block)
|
39
|
+
App.instance.configure(&block)
|
21
40
|
end
|
22
41
|
|
23
|
-
def
|
24
|
-
|
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
|
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:
|
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.
|
99
|
+
rubygems_version: 3.2.32
|
69
100
|
signing_key:
|
70
101
|
specification_version: 4
|
71
|
-
summary:
|
72
|
-
error
|
102
|
+
summary: DSL evaluation library. It produces a human-friendly backtrace error
|
73
103
|
test_files: []
|