raka 0.2.3
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 +7 -0
- data/LICENSE +21 -0
- data/README.md +261 -0
- data/VERSION +1 -0
- data/lib/compile.rb +173 -0
- data/lib/interface.rbs +23 -0
- data/lib/lang/psql/impl.rb +59 -0
- data/lib/lang/python/impl.rb +32 -0
- data/lib/lang/r/impl.rb +38 -0
- data/lib/lang/r/io.R +113 -0
- data/lib/lang/shell/impl.rb +17 -0
- data/lib/output_type.rb +36 -0
- data/lib/protocol.rb +122 -0
- data/lib/raka.rb +70 -0
- data/lib/temp.json +9167 -0
- data/lib/token.rb +165 -0
- metadata +158 -0
data/lib/token.rb
ADDED
@@ -0,0 +1,165 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# convenient patterns for matching
|
4
|
+
module Pattern
|
5
|
+
WORD = '[^\s_]'
|
6
|
+
TOKEN = '(?!.*__)\w+'
|
7
|
+
ANY = '\w+'
|
8
|
+
end
|
9
|
+
|
10
|
+
# Context to preserve during the token chaining
|
11
|
+
class Context
|
12
|
+
attr_reader :ext
|
13
|
+
attr_reader :scopes
|
14
|
+
|
15
|
+
def initialize(ext, scopes = [])
|
16
|
+
@ext = ext
|
17
|
+
@scopes = scopes
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# methods like _xx_ are preserved for token
|
22
|
+
def internal(name)
|
23
|
+
name.length > 1 && name.to_s.start_with?('_') && name.to_s.end_with?('_')
|
24
|
+
end
|
25
|
+
|
26
|
+
# A raka expression is a list of linked tokens. The Token
|
27
|
+
# class store current token, info of previous tokens, and context.
|
28
|
+
# It plays rule of both token and expr
|
29
|
+
class Token
|
30
|
+
attr_reader :chain
|
31
|
+
|
32
|
+
def initialize(compiler, context, chain, inline_scope)
|
33
|
+
@compiler = compiler
|
34
|
+
@context = context
|
35
|
+
@chain = chain
|
36
|
+
@inline_scope = inline_scope
|
37
|
+
end
|
38
|
+
|
39
|
+
def _captures_(target)
|
40
|
+
matched = _pattern_.match(target)
|
41
|
+
keys = matched.names.map(&:to_sym)
|
42
|
+
Hash[keys.zip(matched.captures)]
|
43
|
+
end
|
44
|
+
|
45
|
+
# rubocop:disable Style/MethodLength # long but straightforward
|
46
|
+
def _parse_output_(output)
|
47
|
+
# xxx? is for minimal match
|
48
|
+
out_pattern = %r{^((?<scope>\S+)/)?}.source
|
49
|
+
out_pattern += %r{(?<target_scope>#{@inline_scope})/}.source unless @inline_scope.nil?
|
50
|
+
out_pattern += /(?<stem>(\S+))(?<ext>\.[^\.]+)$/.source
|
51
|
+
info = Regexp.new(out_pattern).match(output)
|
52
|
+
res = Hash[info.names.zip(info.captures)]
|
53
|
+
unless info[:scope].nil?
|
54
|
+
rule_scopes = Regexp.new(_scope_pattern_).match(info[:scope]).captures
|
55
|
+
res[:rule_scopes] = rule_scopes[1..-1].reverse
|
56
|
+
end
|
57
|
+
if !@inline_scope.nil? && !info[:target_scope].nil?
|
58
|
+
segs = Regexp.new(@inline_scope).match(info[:target_scope]).captures
|
59
|
+
res[:target_scope_captures] = segs
|
60
|
+
end
|
61
|
+
name_details = /^(\S+?)__(\S+)$/.match(info[:stem])
|
62
|
+
res = if name_details
|
63
|
+
res.merge(func: name_details[1], input_stem: name_details[2])
|
64
|
+
else
|
65
|
+
res.merge(func: nil, input_stem: nil)
|
66
|
+
end
|
67
|
+
res = res.merge(captures: OpenStruct.new(_captures_(output)))
|
68
|
+
res[:name] = output
|
69
|
+
res[:output] = output
|
70
|
+
res[:output_stem] = info[:stem]
|
71
|
+
OpenStruct.new res
|
72
|
+
end
|
73
|
+
# rubocop:enable Style/MethodLength
|
74
|
+
|
75
|
+
# attach a new item to the chain
|
76
|
+
def _attach_(item)
|
77
|
+
Token.new(@compiler, @context, @chain + [item], @inline_scope)
|
78
|
+
end
|
79
|
+
|
80
|
+
# rubocop:disable Style/MissingRespondToMissing # for DSL not essential
|
81
|
+
def method_missing(sym, *args)
|
82
|
+
# if ends with '=' then is to compile;
|
83
|
+
# if not but has a arg then it is template token, push template;
|
84
|
+
# else is inconclusive so just push symbol
|
85
|
+
super if internal(sym)
|
86
|
+
|
87
|
+
if sym.to_s.end_with? '='
|
88
|
+
@compiler.compile(_attach_(sym.to_s.chomp('=')), args.first)
|
89
|
+
elsif !args.empty?
|
90
|
+
_attach_ args.first.to_s
|
91
|
+
else
|
92
|
+
_attach_ sym.to_s
|
93
|
+
end
|
94
|
+
end
|
95
|
+
# rubocop:enable Style/MissingRespondToMissing
|
96
|
+
|
97
|
+
# non capture matching anything
|
98
|
+
def _(*args)
|
99
|
+
if !args.empty?
|
100
|
+
_attach_ args.first.to_s
|
101
|
+
else
|
102
|
+
_attach_ Pattern::ANY
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def _=(rhs)
|
107
|
+
@compiler.compile(_attach_(Pattern::ANY), rhs)
|
108
|
+
end
|
109
|
+
|
110
|
+
def _input_?
|
111
|
+
@chain.length > 1
|
112
|
+
end
|
113
|
+
|
114
|
+
def _inputs_(output, ext)
|
115
|
+
# no input
|
116
|
+
return [] if @chain.length == 1
|
117
|
+
|
118
|
+
# match the body part besides the scope (if not scoped), leading xxx__ and .ext of output
|
119
|
+
info = _parse_output_(output)
|
120
|
+
input_stem = /^\S+?__(\S+)$/.match(info.stem)[1]
|
121
|
+
auto_input = "#{input_stem}.#{ext}"
|
122
|
+
auto_input = "#{info.target_scope}/" + auto_input if info.target_scope
|
123
|
+
auto_input = "#{info.scope}/" + auto_input if info.scope
|
124
|
+
[auto_input]
|
125
|
+
end
|
126
|
+
|
127
|
+
def _scope_pattern_
|
128
|
+
'((?:(\S+)/)?' + (@context.scopes.map { |layer| "(#{layer.join('|')})" }).join('/') + ')'
|
129
|
+
end
|
130
|
+
|
131
|
+
def _pattern_
|
132
|
+
# scopes as leading
|
133
|
+
leading = !@context.scopes.empty? ? _scope_pattern_ + '/' : _scope_pattern_
|
134
|
+
leading += "(#{@inline_scope})/" unless @inline_scope.nil?
|
135
|
+
body = @chain.reverse.map { |s| "(#{s})" }.join('__')
|
136
|
+
Regexp.new('^' + leading + body + '\.' + @context.ext.to_s + '$')
|
137
|
+
end
|
138
|
+
|
139
|
+
def _template_(scope = nil)
|
140
|
+
(scope.nil? ? '' : scope + '/') + (@inline_scope.nil? ? '' : @inline_scope + '/') +
|
141
|
+
@chain.reverse.join('__') + '.' +
|
142
|
+
@context.ext.to_s
|
143
|
+
end
|
144
|
+
|
145
|
+
# These two methods indicate that this is a pattern token
|
146
|
+
def [](pattern)
|
147
|
+
symbol = @chain.pop.to_s
|
148
|
+
# if the pattern contains child pattern like percent_(\d+), we change the capture to
|
149
|
+
# named capture so that it can be captured later. The name is symbol with the index, like func0
|
150
|
+
pattern = pattern.gsub(/\(\S+?\)/).with_index { |m, i| "(?<#{symbol}#{i}>#{m})" }
|
151
|
+
|
152
|
+
# if the symbol is _, \S+ will be put in chain, it indicates not to capture,
|
153
|
+
# so just replace it with the refined pattern
|
154
|
+
if symbol == Pattern::ANY # match-everything and not bound
|
155
|
+
@chain.push pattern.to_s
|
156
|
+
else
|
157
|
+
@chain.push "(?<#{symbol}>(#{pattern}\\w*))"
|
158
|
+
end
|
159
|
+
self
|
160
|
+
end
|
161
|
+
|
162
|
+
def []=(pattern, value)
|
163
|
+
@compiler.compile(self[pattern], value)
|
164
|
+
end
|
165
|
+
end
|
metadata
ADDED
@@ -0,0 +1,158 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: raka
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.3
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- yarray
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2022-02-02 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 13.0.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 13.0.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rdoc
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 6.3.1
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 6.3.1
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 2.1.0
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 2.1.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: juwelier
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 2.1.0
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 2.1.0
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: test-unit
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 3.3.0
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 3.3.0
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rubocop
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 0.80.0
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 0.80.0
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: reek
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '6.0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '6.0'
|
111
|
+
description: An extensible, concise and light weight DSL on Rake to automate data
|
112
|
+
processing tasks
|
113
|
+
email: '08to09@gmail.com'
|
114
|
+
executables: []
|
115
|
+
extensions: []
|
116
|
+
extra_rdoc_files:
|
117
|
+
- LICENSE
|
118
|
+
- README.md
|
119
|
+
files:
|
120
|
+
- LICENSE
|
121
|
+
- README.md
|
122
|
+
- VERSION
|
123
|
+
- lib/compile.rb
|
124
|
+
- lib/interface.rbs
|
125
|
+
- lib/lang/psql/impl.rb
|
126
|
+
- lib/lang/python/impl.rb
|
127
|
+
- lib/lang/r/impl.rb
|
128
|
+
- lib/lang/r/io.R
|
129
|
+
- lib/lang/shell/impl.rb
|
130
|
+
- lib/output_type.rb
|
131
|
+
- lib/protocol.rb
|
132
|
+
- lib/raka.rb
|
133
|
+
- lib/temp.json
|
134
|
+
- lib/token.rb
|
135
|
+
homepage: http://github.com/yarray/raka
|
136
|
+
licenses:
|
137
|
+
- MIT
|
138
|
+
metadata: {}
|
139
|
+
post_install_message:
|
140
|
+
rdoc_options: []
|
141
|
+
require_paths:
|
142
|
+
- lib
|
143
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
144
|
+
requirements:
|
145
|
+
- - ">="
|
146
|
+
- !ruby/object:Gem::Version
|
147
|
+
version: '0'
|
148
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
requirements: []
|
154
|
+
rubygems_version: 3.1.2
|
155
|
+
signing_key:
|
156
|
+
specification_version: 4
|
157
|
+
summary: Rake for data
|
158
|
+
test_files: []
|