cocos 0.2.0 → 0.3.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/CHANGELOG.md +1 -0
- data/Manifest.txt +1 -0
- data/lib/cocos/env.rb +91 -0
- data/lib/cocos/version.rb +1 -1
- data/lib/cocos.rb +102 -21
- metadata +6 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 38e913cc7ec8d6951edd7bb59ac80626aadf3a3fbd7b13f82ccc123dffc6a7b1
|
|
4
|
+
data.tar.gz: 8883a9656f7aa48b6c778e9786966f507a80dbd13be670ca69ff9ed5b20656a8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1b9e85de98ce029a384d0ce1fa2e09905d3d7eeee956d59ab090c0eb9300b1de121ecc1bfeaaacdebdca7dd66227f7a9fefce1ef397d1d97fa5123cac32609c8
|
|
7
|
+
data.tar.gz: ba6fc944c1dc724c131c0f32390349140c3d658a4db80d876a421704eea1d13ac78ecedc3da6141ba7116367270e836d8aafcb420b12bd664ae604ac557af8a4
|
data/CHANGELOG.md
CHANGED
data/Manifest.txt
CHANGED
data/lib/cocos/env.rb
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
###
|
|
2
|
+
# simple read_env, load_env machinery
|
|
3
|
+
## inspired by
|
|
4
|
+
## dotenv gem -> https://github.com/bkeepers/dotenv
|
|
5
|
+
## figaro -> https://github.com/laserlemon/figaro
|
|
6
|
+
## and others
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
## todo/check:
|
|
10
|
+
## move to its own (standandaloen) envparser gem - why? why not?
|
|
11
|
+
|
|
12
|
+
module EnvParser
|
|
13
|
+
# returns a hash
|
|
14
|
+
# (compatible structure - works like YAML.load_file)
|
|
15
|
+
#
|
|
16
|
+
# change to .read(path) and parse( text) - why? why not?
|
|
17
|
+
def self.load_file( path )
|
|
18
|
+
text = File.open( path, 'r:utf-8' ) { |f| f.read }
|
|
19
|
+
parse( text )
|
|
20
|
+
end
|
|
21
|
+
def self.load( text ) parse( text ); end
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class Error < StandardError; end
|
|
25
|
+
|
|
26
|
+
## todo/check - what is JSON and YAML returning Parser/ParseError something else?
|
|
27
|
+
## YAML uses ParseError and JSON uses ParserError
|
|
28
|
+
class ParseError < Error; end
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
## todo/check - if support for empty values e.g. abc= is required/possible???
|
|
32
|
+
## todo/ addd support for quoted values - why? why not?
|
|
33
|
+
## add support for "inline" end of line comments - why? why not?
|
|
34
|
+
## add support for escapes and multi-line values - why? why not?
|
|
35
|
+
LINE_RX = /\A(?<key>[A-Za-z][A-Za-z0-9_-]*)
|
|
36
|
+
[ ]*
|
|
37
|
+
=
|
|
38
|
+
[ ]*
|
|
39
|
+
(?<value>.+?) ## non-greedy
|
|
40
|
+
\z
|
|
41
|
+
/x
|
|
42
|
+
|
|
43
|
+
## use a parser class - why? why not?
|
|
44
|
+
def self.parse( text )
|
|
45
|
+
h = {}
|
|
46
|
+
|
|
47
|
+
lineno = 0
|
|
48
|
+
text.each_line do |line|
|
|
49
|
+
lineno += 1 ## track line numbers for (parse) error reporting
|
|
50
|
+
|
|
51
|
+
line = line.strip ## check: use strip (or be more strict) - why? why not?
|
|
52
|
+
## skip empty and comment lines
|
|
53
|
+
next if line.empty? || line.start_with?( '#' )
|
|
54
|
+
|
|
55
|
+
if m=LINE_RX.match(line)
|
|
56
|
+
key = m[:key]
|
|
57
|
+
value = m[:value]
|
|
58
|
+
|
|
59
|
+
## todo/check - check/warn about duplicates - why? why not?
|
|
60
|
+
h[key] = value
|
|
61
|
+
else
|
|
62
|
+
raise ParseError, "line #{lineno} - unknown line type; cannot parse >#{line}<"
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
h
|
|
66
|
+
end # methdod self.parse
|
|
67
|
+
end # module EnvParser
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
__END__
|
|
72
|
+
|
|
73
|
+
# parser regex from dotenv
|
|
74
|
+
|
|
75
|
+
LINE = /
|
|
76
|
+
(?:^|\A) # beginning of line
|
|
77
|
+
\s* # leading whitespace
|
|
78
|
+
(?:export\s+)? # optional export
|
|
79
|
+
([\w.]+) # key
|
|
80
|
+
(?:\s*=\s*?|:\s+?) # separator
|
|
81
|
+
( # optional value begin
|
|
82
|
+
\s*'(?:\\'|[^'])*' # single quoted value
|
|
83
|
+
| # or
|
|
84
|
+
\s*"(?:\\"|[^"])*" # double quoted value
|
|
85
|
+
| # or
|
|
86
|
+
[^\#\r\n]+ # unquoted value
|
|
87
|
+
)? # value end
|
|
88
|
+
\s* # trailing whitespace
|
|
89
|
+
(?:\#.*)? # optional comment
|
|
90
|
+
(?:$|\z) # end of line
|
|
91
|
+
/x
|
data/lib/cocos/version.rb
CHANGED
data/lib/cocos.rb
CHANGED
|
@@ -30,7 +30,7 @@ require 'webclient'
|
|
|
30
30
|
#####################
|
|
31
31
|
# our own code
|
|
32
32
|
require 'cocos/version' # note: let version always go first
|
|
33
|
-
|
|
33
|
+
require 'cocos/env' ## e.g. EnvParser
|
|
34
34
|
|
|
35
35
|
###
|
|
36
36
|
## read/parse convenience/helper shortcuts
|
|
@@ -40,14 +40,35 @@ module Kernel
|
|
|
40
40
|
|
|
41
41
|
|
|
42
42
|
|
|
43
|
+
################
|
|
44
|
+
# private helpers - keep along here - why? why not?
|
|
45
|
+
|
|
46
|
+
##### check if path starts with http:// or https://
|
|
47
|
+
## if yes, assume it's a download
|
|
48
|
+
DOWNLOAD_RX = %r{^https?://}i
|
|
49
|
+
|
|
50
|
+
## note: hack - use !! to force nil (no match) to false
|
|
51
|
+
## and matchdata to true
|
|
52
|
+
def _download?( path )
|
|
53
|
+
!! DOWNLOAD_RX.match( path )
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
43
58
|
## todo: add symbolize options a la read_json
|
|
44
59
|
## add sep options
|
|
45
60
|
def read_csv( path, headers: true )
|
|
46
|
-
|
|
47
|
-
|
|
61
|
+
|
|
62
|
+
if _download?( path )
|
|
63
|
+
parse_csv( _wget!( path ).text,
|
|
64
|
+
headers: headers )
|
|
48
65
|
else
|
|
49
|
-
|
|
50
|
-
|
|
66
|
+
if headers
|
|
67
|
+
CsvHash.read( path )
|
|
68
|
+
else
|
|
69
|
+
Csv.read( path )
|
|
70
|
+
end
|
|
71
|
+
end
|
|
51
72
|
end
|
|
52
73
|
|
|
53
74
|
def parse_csv( str, headers: true )
|
|
@@ -63,7 +84,11 @@ end
|
|
|
63
84
|
## for alternate shortcut for read_csv / parse_csv w/ headers: false
|
|
64
85
|
## returning arrays of strings
|
|
65
86
|
def read_data( path )
|
|
66
|
-
|
|
87
|
+
if _download?( path )
|
|
88
|
+
read_data( _wget!( path ).text )
|
|
89
|
+
else
|
|
90
|
+
Csv.read( path )
|
|
91
|
+
end
|
|
67
92
|
end
|
|
68
93
|
|
|
69
94
|
def parse_data( str )
|
|
@@ -73,7 +98,11 @@ end
|
|
|
73
98
|
|
|
74
99
|
|
|
75
100
|
def read_tab( path )
|
|
76
|
-
|
|
101
|
+
if _download?( path )
|
|
102
|
+
parse_tab( _wget!( path ).text )
|
|
103
|
+
else
|
|
104
|
+
Tab.read( path )
|
|
105
|
+
end
|
|
77
106
|
end
|
|
78
107
|
|
|
79
108
|
def parse_tab( str )
|
|
@@ -83,16 +112,17 @@ end
|
|
|
83
112
|
|
|
84
113
|
## todo: add symbolize options ???
|
|
85
114
|
def read_json( path )
|
|
86
|
-
|
|
115
|
+
JSON.parse( read_text( path ))
|
|
87
116
|
end
|
|
88
117
|
|
|
89
118
|
def parse_json( str )
|
|
90
119
|
JSON.parse( str )
|
|
91
120
|
end
|
|
92
121
|
|
|
122
|
+
|
|
93
123
|
### todo/check: use parse_safeyaml or such? (is default anyway?) - why? why not?
|
|
94
124
|
def read_yaml( path )
|
|
95
|
-
|
|
125
|
+
YAML.load( read_text( path ))
|
|
96
126
|
end
|
|
97
127
|
|
|
98
128
|
def parse_yaml( str )
|
|
@@ -101,7 +131,7 @@ end
|
|
|
101
131
|
|
|
102
132
|
|
|
103
133
|
def read_ini( path )
|
|
104
|
-
|
|
134
|
+
INI.load( read_text( path ))
|
|
105
135
|
end
|
|
106
136
|
|
|
107
137
|
def parse_ini( str )
|
|
@@ -115,22 +145,32 @@ alias_method :parse_conf, :parse_ini
|
|
|
115
145
|
|
|
116
146
|
|
|
117
147
|
def read_text( path )
|
|
148
|
+
if _download?( path )
|
|
149
|
+
_wget!( path ).text
|
|
150
|
+
else
|
|
118
151
|
## todo/check: add universal newline mode or such?
|
|
119
152
|
## e.g. will always convert all
|
|
120
153
|
## newline variants (\n|\r|\n\r) to "universal" \n only
|
|
154
|
+
##
|
|
155
|
+
## add r:bom - why? why not?
|
|
121
156
|
txt = File.open( path, 'r:utf-8' ) do |f|
|
|
122
157
|
f.read
|
|
123
158
|
end
|
|
124
159
|
txt
|
|
160
|
+
end
|
|
125
161
|
end
|
|
126
162
|
alias_method :read_txt, :read_text
|
|
127
163
|
|
|
128
164
|
|
|
129
165
|
def read_blob( path )
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
166
|
+
if _download?( path )
|
|
167
|
+
_wget!( path ).blob
|
|
168
|
+
else
|
|
169
|
+
blob = File.open( path, 'rb' ) do |f|
|
|
170
|
+
f.read
|
|
171
|
+
end
|
|
172
|
+
blob
|
|
173
|
+
end
|
|
134
174
|
end
|
|
135
175
|
alias_method :read_binary, :read_blob
|
|
136
176
|
alias_method :read_bin, :read_blob
|
|
@@ -140,12 +180,42 @@ alias_method :read_bin, :read_blob
|
|
|
140
180
|
|
|
141
181
|
## todo/check: remove \n (or\r or \r\n) from line
|
|
142
182
|
## ruby (by default) keeps the newline - follow tradition? why? why not?
|
|
183
|
+
## add/offer chomp: true/false option or such - why? why not?
|
|
184
|
+
## see String.lines in rdoc
|
|
143
185
|
##
|
|
144
186
|
def read_lines( path )
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
187
|
+
read_text( path ).lines
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def parse_lines( str )
|
|
191
|
+
str.lines
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
def read_env( path )
|
|
197
|
+
EnvParser.load( read_text( path ))
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def parse_env( str )
|
|
201
|
+
EnvParser.load( str )
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
##
|
|
206
|
+
## todo/check - change path to *paths=['./.env']
|
|
207
|
+
## and support more files - why? why not?
|
|
208
|
+
def load_env( path='./.env' )
|
|
209
|
+
if File.exist?( path )
|
|
210
|
+
puts "==> loading .env settings..."
|
|
211
|
+
env = read_env( path )
|
|
212
|
+
puts " applying .env settings... (merging into ENV)"
|
|
213
|
+
pp env
|
|
214
|
+
## note: will only add .env setting if NOT present in ENV!!!
|
|
215
|
+
env.each do |k,v|
|
|
216
|
+
ENV[k] ||= v
|
|
217
|
+
end
|
|
218
|
+
end
|
|
149
219
|
end
|
|
150
220
|
|
|
151
221
|
|
|
@@ -163,7 +233,7 @@ def write_json( path, data )
|
|
|
163
233
|
FileUtils.mkdir_p( dirname ) unless Dir.exist?( dirname )
|
|
164
234
|
|
|
165
235
|
## note: pretty print/reformat json
|
|
166
|
-
File.open( path,
|
|
236
|
+
File.open( path, 'w:utf-8' ) do |f|
|
|
167
237
|
f.write( JSON.pretty_generate( data ))
|
|
168
238
|
end
|
|
169
239
|
end
|
|
@@ -177,7 +247,7 @@ def write_blob( path, blob )
|
|
|
177
247
|
dirname = File.dirname( path )
|
|
178
248
|
FileUtils.mkdir_p( dirname ) unless Dir.exist?( dirname )
|
|
179
249
|
|
|
180
|
-
File.open( path,
|
|
250
|
+
File.open( path, 'wb' ) do |f|
|
|
181
251
|
f.write( blob )
|
|
182
252
|
end
|
|
183
253
|
end
|
|
@@ -193,7 +263,7 @@ def write_text( path, text )
|
|
|
193
263
|
dirname = File.dirname( path )
|
|
194
264
|
FileUtils.mkdir_p( dirname ) unless Dir.exist?( dirname )
|
|
195
265
|
|
|
196
|
-
File.open( path,
|
|
266
|
+
File.open( path, 'w:utf-8' ) do |f|
|
|
197
267
|
f.write( text )
|
|
198
268
|
end
|
|
199
269
|
end
|
|
@@ -211,6 +281,17 @@ end
|
|
|
211
281
|
|
|
212
282
|
|
|
213
283
|
|
|
284
|
+
## private helper - make public -why? why not?
|
|
285
|
+
def _wget!( url, **kwargs )
|
|
286
|
+
res = Webclient.get( url, **kwargs )
|
|
287
|
+
|
|
288
|
+
## check/todo - use a different exception/error - keep RuntimeError - why? why not?
|
|
289
|
+
raise RuntimeError, "HTTP #{res.status.code} - #{res.status.message}" if res.status.nok?
|
|
290
|
+
|
|
291
|
+
res
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
|
|
214
295
|
end # module Kernel
|
|
215
296
|
|
|
216
297
|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: cocos
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Gerald Bauer
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2023-09-05 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: csvreader
|
|
@@ -92,14 +92,14 @@ dependencies:
|
|
|
92
92
|
requirements:
|
|
93
93
|
- - "~>"
|
|
94
94
|
- !ruby/object:Gem::Version
|
|
95
|
-
version: '
|
|
95
|
+
version: '4.0'
|
|
96
96
|
type: :development
|
|
97
97
|
prerelease: false
|
|
98
98
|
version_requirements: !ruby/object:Gem::Requirement
|
|
99
99
|
requirements:
|
|
100
100
|
- - "~>"
|
|
101
101
|
- !ruby/object:Gem::Version
|
|
102
|
-
version: '
|
|
102
|
+
version: '4.0'
|
|
103
103
|
description: cocos (code commons) - auto-include quick-starter prelude & prolog
|
|
104
104
|
email: opensport@googlegroups.com
|
|
105
105
|
executables: []
|
|
@@ -116,6 +116,7 @@ files:
|
|
|
116
116
|
- README.md
|
|
117
117
|
- Rakefile
|
|
118
118
|
- lib/cocos.rb
|
|
119
|
+
- lib/cocos/env.rb
|
|
119
120
|
- lib/cocos/version.rb
|
|
120
121
|
homepage: https://github.com/rubycocos/cocos
|
|
121
122
|
licenses:
|
|
@@ -138,7 +139,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
138
139
|
- !ruby/object:Gem::Version
|
|
139
140
|
version: '0'
|
|
140
141
|
requirements: []
|
|
141
|
-
rubygems_version: 3.
|
|
142
|
+
rubygems_version: 3.4.10
|
|
142
143
|
signing_key:
|
|
143
144
|
specification_version: 4
|
|
144
145
|
summary: cocos (code commons) - auto-include quick-starter prelude & prolog
|