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 +4 -4
- data/.gitignore +1 -0
- data/CHANGELOG.md +9 -0
- data/README.md +12 -4
- data/dsl_evaluator.gemspec +5 -1
- data/lib/dsl_evaluator/app.rb +37 -0
- data/lib/dsl_evaluator/autoloader.rb +20 -0
- data/lib/dsl_evaluator/logger.rb +30 -0
- data/lib/dsl_evaluator/printer.rb +96 -0
- data/lib/dsl_evaluator/version.rb +1 -1
- data/lib/dsl_evaluator.rb +30 -33
- metadata +51 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dd75a6a48ce5a9eb6858f470264eaf01af1039d93e4be1d5f609f8bc381ba297
|
4
|
+
data.tar.gz: d21493fb8aa7d9c78c7e873374a8037c1c40fd3991f4002c379ac0926c0e0e45
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fa1913f87e7c7285bf3266097742353fbbb1817dface02543513798aba3d6b284b9231a8702199d3229accf57b6480f620490e15b23d92b25c9f0c03432bf742
|
7
|
+
data.tar.gz: 995507941a52c9b0ad3691346268ed5a30d852fb116cc7cd8132692343760411ed213f0b9815a43f20926e35b22d502d9bc3d37d4dd1062fd7d6037d86324305
|
data/.gitignore
CHANGED
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
|
-
|
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")
|
@@ -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
|
data/lib/dsl_evaluator.rb
CHANGED
@@ -1,51 +1,48 @@
|
|
1
|
-
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
|
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
|
-
|
11
|
-
|
12
|
-
|
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
|
-
|
16
|
-
|
17
|
-
|
32
|
+
mattr_accessor :backtrace_reject
|
33
|
+
|
34
|
+
def logger
|
35
|
+
config.logger
|
18
36
|
end
|
19
37
|
|
20
|
-
def
|
21
|
-
|
38
|
+
def configure(&block)
|
39
|
+
App.instance.configure(&block)
|
22
40
|
end
|
23
41
|
|
24
|
-
|
25
|
-
|
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.
|
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:
|
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.
|
99
|
+
rubygems_version: 3.2.32
|
54
100
|
signing_key:
|
55
101
|
specification_version: 4
|
56
|
-
summary:
|
57
|
-
error
|
102
|
+
summary: DSL evaluation library. It produces a human-friendly backtrace error
|
58
103
|
test_files: []
|