honey_format 0.16.0 → 0.17.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/.hound.yml +3 -0
- data/.rubocop.yml +7 -0
- data/.ruby-style-guide.yml +264 -0
- data/CHANGELOG.md +15 -0
- data/Gemfile +2 -0
- data/README.md +63 -15
- data/Rakefile +2 -0
- data/bin/benchmark +2 -0
- data/bin/console +1 -0
- data/exe/honey_format +1 -0
- data/honey_format.gemspec +5 -4
- data/lib/honey_format/cli/benchmark_cli.rb +15 -13
- data/lib/honey_format/cli/cli.rb +17 -12
- data/lib/honey_format/cli/result_writer.rb +2 -0
- data/lib/honey_format/configuration.rb +114 -11
- data/lib/honey_format/converters/convert_boolean.rb +24 -0
- data/lib/honey_format/converters/convert_date_and_time.rb +30 -0
- data/lib/honey_format/converters/convert_number.rb +33 -0
- data/lib/honey_format/converters/convert_string.rb +42 -0
- data/lib/honey_format/converters/converters.rb +12 -0
- data/lib/honey_format/converters/header_column_converter.rb +57 -0
- data/lib/honey_format/csv.rb +22 -14
- data/lib/honey_format/errors.rb +8 -2
- data/lib/honey_format/helpers/helpers.rb +41 -0
- data/lib/honey_format/{header.rb → matrix/header.rb} +48 -12
- data/lib/honey_format/matrix/matrix.rb +104 -0
- data/lib/honey_format/{row.rb → matrix/row.rb} +6 -3
- data/lib/honey_format/{row_builder.rb → matrix/row_builder.rb} +5 -4
- data/lib/honey_format/{rows.rb → matrix/rows.rb} +7 -4
- data/lib/honey_format/matrix.rb +6 -89
- data/lib/honey_format/registry.rb +99 -0
- data/lib/honey_format/version.rb +4 -2
- data/lib/honey_format.rb +14 -6
- metadata +34 -24
- data/lib/honey_format/header_column_converter.rb +0 -40
- data/lib/honey_format/value_converter.rb +0 -117
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 997883e33f720a7dc6c0d3f2a552b4dcd68cfa1bac8be23d5a36332c83bf0e32
|
4
|
+
data.tar.gz: dd522a2171b7befc1e41e80022dade22d18d3d9228c8b40eb6b7d3f8d032005b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c6e15af7156b78f97f02e1e42f9c961116ad7e09428ccaa6eb7b0651d93f162f2417381d034b82eaefa843d0b5aceab1cfb824347db1701ed5186d575c6d88eb
|
7
|
+
data.tar.gz: dfa13256a8446d9b7f6bedf4505e9c275268999098befd62a81174ef5d682185ea4e379e07b870e3554ecdb983714bac31b1175422dd750dc07d6997b52233b9
|
data/.hound.yml
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,264 @@
|
|
1
|
+
Rails:
|
2
|
+
Enabled: false
|
3
|
+
AllCops:
|
4
|
+
TargetRubyVersion: 2.3
|
5
|
+
Exclude:
|
6
|
+
- "vendor/**/*"
|
7
|
+
UseCache: true
|
8
|
+
Style/CollectionMethods:
|
9
|
+
Description: Preferred collection methods.
|
10
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#map-find-select-reduce-size
|
11
|
+
Enabled: true
|
12
|
+
PreferredMethods:
|
13
|
+
collect: map
|
14
|
+
collect!: map!
|
15
|
+
find: detect
|
16
|
+
find_all: select
|
17
|
+
reduce: inject
|
18
|
+
Style/RedundantFreeze:
|
19
|
+
Description: "Checks usages of Object#freeze on immutable objects."
|
20
|
+
Enabled: false
|
21
|
+
Layout/DotPosition:
|
22
|
+
Description: Checks the position of the dot in multi-line method calls.
|
23
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#consistent-multi-line-chains
|
24
|
+
Enabled: true
|
25
|
+
EnforcedStyle: trailing
|
26
|
+
SupportedStyles:
|
27
|
+
- leading
|
28
|
+
- trailing
|
29
|
+
Naming/FileName:
|
30
|
+
Description: Use snake_case for source file names.
|
31
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#snake-case-files
|
32
|
+
Enabled: false
|
33
|
+
Exclude: []
|
34
|
+
Naming/MemoizedInstanceVariableName:
|
35
|
+
Description: Memoized method name should match memo instance variable name.
|
36
|
+
Enabled: false
|
37
|
+
Naming/UncommunicativeMethodParamName:
|
38
|
+
Description: >-
|
39
|
+
Checks for method parameter names that contain capital letters,
|
40
|
+
end in numbers, or do not meet a minimal length.
|
41
|
+
Enabled: false
|
42
|
+
Style/GuardClause:
|
43
|
+
Description: Check for conditionals that can be replaced with guard clauses
|
44
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-nested-conditionals
|
45
|
+
Enabled: true
|
46
|
+
MinBodyLength: 3
|
47
|
+
Style/IfUnlessModifier:
|
48
|
+
Description: Favor modifier if/unless usage when you have a single-line body.
|
49
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#if-as-a-modifier
|
50
|
+
Enabled: false
|
51
|
+
Style/OptionHash:
|
52
|
+
Description: Don't use option hashes when you can use keyword arguments.
|
53
|
+
Enabled: false
|
54
|
+
Style/PercentLiteralDelimiters:
|
55
|
+
Description: Use `%`-literal delimiters consistently
|
56
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#percent-literal-braces
|
57
|
+
Enabled: false
|
58
|
+
PreferredDelimiters:
|
59
|
+
"%": "()"
|
60
|
+
"%i": "()"
|
61
|
+
"%q": "()"
|
62
|
+
"%Q": "()"
|
63
|
+
"%r": "{}"
|
64
|
+
"%s": "()"
|
65
|
+
"%w": "()"
|
66
|
+
"%W": "()"
|
67
|
+
"%x": "()"
|
68
|
+
Naming/PredicateName:
|
69
|
+
Description: Check the names of predicate methods.
|
70
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#bool-methods-qmark
|
71
|
+
Enabled: true
|
72
|
+
NamePrefix:
|
73
|
+
- is_
|
74
|
+
- has_
|
75
|
+
- have_
|
76
|
+
NamePrefixBlacklist:
|
77
|
+
- is_
|
78
|
+
Exclude:
|
79
|
+
- spec/**/*
|
80
|
+
Style/RaiseArgs:
|
81
|
+
Description: Checks the arguments passed to raise/fail.
|
82
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#exception-class-messages
|
83
|
+
Enabled: false
|
84
|
+
EnforcedStyle: exploded
|
85
|
+
SupportedStyles:
|
86
|
+
- compact
|
87
|
+
- exploded
|
88
|
+
Style/SignalException:
|
89
|
+
Description: Checks for proper usage of fail and raise.
|
90
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#fail-method
|
91
|
+
Enabled: false
|
92
|
+
EnforcedStyle: semantic
|
93
|
+
SupportedStyles:
|
94
|
+
- only_raise
|
95
|
+
- only_fail
|
96
|
+
- semantic
|
97
|
+
Style/SingleLineBlockParams:
|
98
|
+
Description: Enforces the names of some block params.
|
99
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#reduce-blocks
|
100
|
+
Enabled: false
|
101
|
+
Methods:
|
102
|
+
- reduce:
|
103
|
+
- a
|
104
|
+
- e
|
105
|
+
- inject:
|
106
|
+
- a
|
107
|
+
- e
|
108
|
+
Style/TrivialAccessors:
|
109
|
+
Enabled: false
|
110
|
+
Style/SingleLineMethods:
|
111
|
+
Description: Avoid single-line methods.
|
112
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-single-line-methods
|
113
|
+
Enabled: false
|
114
|
+
AllowIfMethodIsEmpty: true
|
115
|
+
Style/StringLiterals:
|
116
|
+
Description: Checks if uses of quotes match the configured preference.
|
117
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#consistent-string-literals
|
118
|
+
Enabled: true
|
119
|
+
EnforcedStyle: single_quotes
|
120
|
+
SupportedStyles:
|
121
|
+
- single_quotes
|
122
|
+
- double_quotes
|
123
|
+
Style/MixinUsage:
|
124
|
+
Enabled: true
|
125
|
+
Exclude:
|
126
|
+
- exe/*
|
127
|
+
Style/StringLiteralsInInterpolation:
|
128
|
+
Description: Checks if uses of quotes inside expressions in interpolated strings
|
129
|
+
match the configured preference.
|
130
|
+
Enabled: true
|
131
|
+
EnforcedStyle: single_quotes
|
132
|
+
SupportedStyles:
|
133
|
+
- single_quotes
|
134
|
+
- double_quotes
|
135
|
+
Style/TrailingCommaInArrayLiteral:
|
136
|
+
Description: Checks for trailing comma in parameter lists and literals.
|
137
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-trailing-array-commas
|
138
|
+
Enabled: true
|
139
|
+
EnforcedStyleForMultiline: comma
|
140
|
+
Style/TrailingCommaInHashLiteral:
|
141
|
+
Description: Checks for trailing comma in parameter lists and literals.
|
142
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-trailing-array-commas
|
143
|
+
Enabled: true
|
144
|
+
EnforcedStyleForMultiline: comma
|
145
|
+
Metrics/AbcSize:
|
146
|
+
Description: A calculated magnitude based on number of assignments, branches, and
|
147
|
+
conditions.
|
148
|
+
Enabled: false
|
149
|
+
Max: 15
|
150
|
+
Metrics/ClassLength:
|
151
|
+
Description: Avoid classes longer than 100 lines of code.
|
152
|
+
Enabled: false
|
153
|
+
CountComments: false
|
154
|
+
Max: 100
|
155
|
+
Metrics/ModuleLength:
|
156
|
+
CountComments: false
|
157
|
+
Max: 100
|
158
|
+
Description: Avoid modules longer than 100 lines of code.
|
159
|
+
Enabled: false
|
160
|
+
Metrics/CyclomaticComplexity:
|
161
|
+
Description: A complexity metric that is strongly correlated to the number of test
|
162
|
+
cases needed to validate a method.
|
163
|
+
Enabled: false
|
164
|
+
Max: 6
|
165
|
+
Metrics/MethodLength:
|
166
|
+
Description: Avoid methods longer than 10 lines of code.
|
167
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#short-methods
|
168
|
+
Enabled: false
|
169
|
+
CountComments: false
|
170
|
+
Max: 10
|
171
|
+
Metrics/ParameterLists:
|
172
|
+
Description: Avoid parameter lists longer than three or four parameters.
|
173
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#too-many-params
|
174
|
+
Enabled: false
|
175
|
+
Max: 5
|
176
|
+
CountKeywordArgs: true
|
177
|
+
Metrics/PerceivedComplexity:
|
178
|
+
Description: A complexity metric geared towards measuring complexity for a human
|
179
|
+
reader.
|
180
|
+
Enabled: false
|
181
|
+
Max: 7
|
182
|
+
Metrics/LineLength:
|
183
|
+
Description: Maximum line length
|
184
|
+
Enabled: true
|
185
|
+
Max: 95
|
186
|
+
Exclude:
|
187
|
+
- lib/honey_format/cli/*
|
188
|
+
- Gemfile
|
189
|
+
- honey_format.gemspec
|
190
|
+
- spec/**/*
|
191
|
+
Metrics/BlockLength:
|
192
|
+
Enabled: true
|
193
|
+
Exclude:
|
194
|
+
- lib/honey_format/cli/*
|
195
|
+
- spec/**/*
|
196
|
+
Lint/AssignmentInCondition:
|
197
|
+
Description: Don't use assignment in conditions.
|
198
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#safe-assignment-in-condition
|
199
|
+
Enabled: false
|
200
|
+
AllowSafeAssignment: true
|
201
|
+
Style/InlineComment:
|
202
|
+
Description: Avoid inline comments.
|
203
|
+
Enabled: false
|
204
|
+
Naming/AccessorMethodName:
|
205
|
+
Description: Check the naming of accessor methods for get_/set_.
|
206
|
+
Enabled: false
|
207
|
+
Style/Alias:
|
208
|
+
Description: Use alias_method instead of alias.
|
209
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#alias-method
|
210
|
+
Enabled: false
|
211
|
+
Style/Documentation:
|
212
|
+
Description: Document classes and non-namespace modules.
|
213
|
+
Enabled: false
|
214
|
+
Style/DoubleNegation:
|
215
|
+
Description: Checks for uses of double negation (!!).
|
216
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-bang-bang
|
217
|
+
Enabled: false
|
218
|
+
Style/EachWithObject:
|
219
|
+
Description: Prefer `each_with_object` over `inject` or `reduce`.
|
220
|
+
Enabled: false
|
221
|
+
Style/EmptyLiteral:
|
222
|
+
Description: Prefer literals to Array.new/Hash.new/String.new.
|
223
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#literal-array-hash
|
224
|
+
Enabled: false
|
225
|
+
Style/ModuleFunction:
|
226
|
+
Description: Checks for usage of `extend self` in modules.
|
227
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#module-function
|
228
|
+
Enabled: false
|
229
|
+
Style/OneLineConditional:
|
230
|
+
Description: Favor the ternary operator(?:) over if/then/else/end constructs.
|
231
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#ternary-operator
|
232
|
+
Enabled: false
|
233
|
+
Style/PerlBackrefs:
|
234
|
+
Description: Avoid Perl-style regex back references.
|
235
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-perl-regexp-last-matchers
|
236
|
+
Enabled: false
|
237
|
+
Style/Send:
|
238
|
+
Description: Prefer `Object#__send__` or `Object#public_send` to `send`, as `send`
|
239
|
+
may overlap with existing methods.
|
240
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#prefer-public-send
|
241
|
+
Enabled: false
|
242
|
+
Style/SpecialGlobalVars:
|
243
|
+
Description: Avoid Perl-style global variables.
|
244
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-cryptic-perlisms
|
245
|
+
Enabled: false
|
246
|
+
Style/VariableInterpolation:
|
247
|
+
Description: Don't interpolate global, instance and class variables directly in
|
248
|
+
strings.
|
249
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#curlies-interpolate
|
250
|
+
Enabled: false
|
251
|
+
Style/WhenThen:
|
252
|
+
Description: Use when x then ... for one-line cases.
|
253
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#one-line-cases
|
254
|
+
Enabled: false
|
255
|
+
Lint/EachWithObjectArgument:
|
256
|
+
Description: Check for immutable argument given to each_with_object.
|
257
|
+
Enabled: true
|
258
|
+
Lint/HandleExceptions:
|
259
|
+
Description: Don't suppress exception.
|
260
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#dont-hide-exceptions
|
261
|
+
Enabled: false
|
262
|
+
Lint/LiteralInInterpolation:
|
263
|
+
Description: Checks for literals used in interpolation.
|
264
|
+
Enabled: false
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,20 @@
|
|
1
1
|
# HEAD
|
2
2
|
|
3
|
+
## v0.17.0
|
4
|
+
|
5
|
+
:warning: This release contains some backwards compatible changes.
|
6
|
+
|
7
|
+
* Add global config for CSV `delimiter`, `row_delimiter`, `quote_character` and `skip_lines`
|
8
|
+
* Add `header_deduplicator` support to Matrix & CSV
|
9
|
+
* Make `HeaderColumnConverter` normalization even more aggressive [PR#32](https://github.com/buren/honey_format/pull/32)
|
10
|
+
- :warning: Backwards incompatible
|
11
|
+
* Add `blank` type [PR#34](https://github.com/buren/honey_format/pull/34)
|
12
|
+
* Rename `ValueConverter` => `Registry` and generalize implementation
|
13
|
+
* Rename `UnknownValueTypeError` => `UnknownTypeError`
|
14
|
+
- :warning: Backwards incompatible
|
15
|
+
* Allow unregister of existing value converters
|
16
|
+
* Add `hex` and `blank` converters to registry
|
17
|
+
|
3
18
|
## v0.16.0
|
4
19
|
|
5
20
|
* Add `--type-map` option to CLI
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -7,10 +7,10 @@ Proper objects for CSV headers and rows, convert column values, filter columns a
|
|
7
7
|
## Features
|
8
8
|
|
9
9
|
- Proper objects for CSV header and rows
|
10
|
-
- Convert column values
|
10
|
+
- Convert row and header column values
|
11
11
|
- Pass your own custom row builder
|
12
|
-
- Convert header column names
|
13
12
|
- Filter what columns and rows are included in CSV output
|
13
|
+
- Gracefully handle missing and duplicated header columns
|
14
14
|
- [CLI](#cli) - Simple command line interface
|
15
15
|
- Only ~5-10% overhead from using Ruby CSV, see [benchmarks](#benchmark)
|
16
16
|
- Has no dependencies other than Ruby stdlib
|
@@ -20,7 +20,6 @@ Read the [usage section](#usage), [RubyDoc](https://www.rubydoc.info/gems/honey
|
|
20
20
|
|
21
21
|
## Quick use
|
22
22
|
|
23
|
-
|
24
23
|
```ruby
|
25
24
|
csv_string = <<-CSV
|
26
25
|
Id,Username,Email
|
@@ -29,7 +28,7 @@ Id,Username,Email
|
|
29
28
|
CSV
|
30
29
|
csv = HoneyFormat::CSV.new(csv_string, type_map: { id: :integer })
|
31
30
|
csv.columns # => [:id, :username]
|
32
|
-
user = csv.rows # => [#<Row id=
|
31
|
+
user = csv.rows # => [#<Row id=1, username="buren">]
|
33
32
|
user.id # => 1
|
34
33
|
user.username # => "buren"
|
35
34
|
|
@@ -66,7 +65,7 @@ csv = HoneyFormat::CSV.new(csv_string)
|
|
66
65
|
# Header
|
67
66
|
header = csv.header
|
68
67
|
header.original # => ["Id", "Username"]
|
69
|
-
header.columns
|
68
|
+
header.columns # => [:id, :username]
|
70
69
|
|
71
70
|
|
72
71
|
# Rows
|
@@ -102,7 +101,7 @@ csv.rows.first.id # => 1
|
|
102
101
|
Add your own converter
|
103
102
|
```ruby
|
104
103
|
HoneyFormat.configure do |config|
|
105
|
-
config.
|
104
|
+
config.converter_registry.register :upcased, proc { |v| v.upcase }
|
106
105
|
end
|
107
106
|
|
108
107
|
csv_string = "Id,Username\n1,buren"
|
@@ -111,13 +110,22 @@ csv = HoneyFormat::CSV.new(csv_string, type_map: type_map)
|
|
111
110
|
csv.rows.first.username # => "BUREN"
|
112
111
|
```
|
113
112
|
|
113
|
+
Remove registered converter
|
114
|
+
```ruby
|
115
|
+
HoneyFormat.configure do |config|
|
116
|
+
config.converter_registry.unregister :upcase
|
117
|
+
# now you're free to register your own
|
118
|
+
config.converter_registry.register :upcase, proc { |v| v.upcase if v }
|
119
|
+
end
|
120
|
+
```
|
121
|
+
|
114
122
|
Access registered converters
|
115
123
|
```ruby
|
116
|
-
decimal_converter = HoneyFormat.
|
124
|
+
decimal_converter = HoneyFormat.converter_registry[:decimal]
|
117
125
|
decimal_converter.call('1.1') # => 1.1
|
118
126
|
```
|
119
127
|
|
120
|
-
See [`
|
128
|
+
See [`Configuration#default_converters`](https://github.com/buren/honey_format/tree/master/lib/honey_format/configuration.rb#L38) for a complete list of the default ones.
|
121
129
|
|
122
130
|
__Row builder__
|
123
131
|
|
@@ -196,7 +204,7 @@ csv = HoneyFormat::CSV.new(csv_string)
|
|
196
204
|
# Header
|
197
205
|
header = csv.header
|
198
206
|
header.original # => ["Id", "Username"]
|
199
|
-
header.columns
|
207
|
+
header.columns # => [:id, :username]
|
200
208
|
```
|
201
209
|
|
202
210
|
Define header
|
@@ -213,11 +221,11 @@ HoneyFormat.configure do |config|
|
|
213
221
|
end
|
214
222
|
|
215
223
|
# you can get the default one with
|
216
|
-
header_converter = HoneyFormat.
|
224
|
+
header_converter = HoneyFormat.converter_registry[:header_column]
|
217
225
|
header_converter.call('First name') # => "first_name"
|
218
226
|
```
|
219
227
|
|
220
|
-
Use any
|
228
|
+
Use any converter registry as the header converter
|
221
229
|
```ruby
|
222
230
|
csv_string = "Id,Username\n1,buren"
|
223
231
|
csv = HoneyFormat::CSV.new(csv_string, header_converter: :upcase)
|
@@ -232,7 +240,7 @@ converter = ->(column) { map.fetch(column, column.downcase) }
|
|
232
240
|
csv_string = "ID,First^Name\n1,Jacob"
|
233
241
|
user = HoneyFormat::CSV.new(csv_string, header_converter: converter).rows.first
|
234
242
|
user.first_name # => "Jacob"
|
235
|
-
user.id
|
243
|
+
user.id # => "1"
|
236
244
|
```
|
237
245
|
|
238
246
|
Missing header values
|
@@ -243,6 +251,23 @@ user = csv.rows.first
|
|
243
251
|
user.column1 # => "val1"
|
244
252
|
```
|
245
253
|
|
254
|
+
Duplicated header values
|
255
|
+
```ruby
|
256
|
+
csv_string = <<~CSV
|
257
|
+
email,email,name
|
258
|
+
john@example.com,jane@example.com,John
|
259
|
+
CSV
|
260
|
+
# :deduplicate is the default value
|
261
|
+
csv = HoneyFormat::CSV.new(csv_string, header_deduplicator: :deduplicate)
|
262
|
+
user = csv.rows.first
|
263
|
+
user.email # => john@example.com
|
264
|
+
user.email1 # => jane@example.com
|
265
|
+
|
266
|
+
# you can also choose to raise an error instead
|
267
|
+
HoneyFormat::CSV.new(csv_string, header_deduplicator: :raise)
|
268
|
+
# => HoneyFormat::DuplicateHeaderColumnError
|
269
|
+
```
|
270
|
+
|
246
271
|
If your header contains special chars and/or chars that can't be part of Ruby method names,
|
247
272
|
things can get a little awkward..
|
248
273
|
```ruby
|
@@ -280,8 +305,6 @@ end
|
|
280
305
|
|
281
306
|
You can see all [available errors here](https://www.rubydoc.info/gems/honey_format/HoneyFormat/Errors).
|
282
307
|
|
283
|
-
If you want to see more usage examples check out the [`examples/`](https://github.com/buren/honey_format/tree/master/examples) and [`spec/`](https://github.com/buren/honey_format/tree/master/spec) directories.
|
284
|
-
|
285
308
|
__Skip lines__
|
286
309
|
|
287
310
|
> Skip comments and/or other unwanted lines from being parsed.
|
@@ -298,6 +321,31 @@ csv = HoneyFormat::CSV.new(csv_string, skip_lines: regexp)
|
|
298
321
|
csv.rows.length # => 2
|
299
322
|
```
|
300
323
|
|
324
|
+
__Matrix__
|
325
|
+
|
326
|
+
> Use whats under the hood.
|
327
|
+
|
328
|
+
Actually `HoneyFormat::CSV` is a very thin wrapper around `HoneyFormat::Matrix`.
|
329
|
+
You can use `Matrix` directly it support all options that aren't specifically tied to parsing a CSV.
|
330
|
+
|
331
|
+
Example
|
332
|
+
```ruby
|
333
|
+
data = [
|
334
|
+
%w[name id],
|
335
|
+
%w[jacob 1]
|
336
|
+
]
|
337
|
+
type_map = {
|
338
|
+
id: :integer,
|
339
|
+
name: :upcase
|
340
|
+
}
|
341
|
+
|
342
|
+
matrix = HoneyFormat::Matrix.new(data, type_map: { id: :integer, name: :upcase })
|
343
|
+
matrix.columns # => [:name, :id]
|
344
|
+
matrix.rows.to_a # => [#<Row name="JACOB", id=1>]
|
345
|
+
matrix.to_csv # => "name,id\nJACOB,1\n"
|
346
|
+
```
|
347
|
+
|
348
|
+
If you want to see more usage examples check out the [`examples/`](https://github.com/buren/honey_format/tree/master/examples) and [`spec/`](https://github.com/buren/honey_format/tree/master/spec) directories and of course [on RubyDoc](https://www.rubydoc.info/gems/honey_format/).
|
301
349
|
|
302
350
|
## CLI
|
303
351
|
|
@@ -330,7 +378,7 @@ $ honey_format input.csv --columns=id,username > output.csv
|
|
330
378
|
|
331
379
|
## Benchmark
|
332
380
|
|
333
|
-
_Note_: This gem, adds some overhead to parsing a CSV string, typically ~5-10%. I've included some benchmarks below, your mileage may vary..
|
381
|
+
_Note_: This gem, adds some overhead to parsing a CSV string, typically ~5-10%. I've included some benchmarks below, your mileage may vary.. The benchmarks have been run with Ruby 2.5.
|
334
382
|
|
335
383
|
204KB (1k lines)
|
336
384
|
|
data/Rakefile
CHANGED
data/bin/benchmark
CHANGED
data/bin/console
CHANGED
data/exe/honey_format
CHANGED
data/honey_format.gemspec
CHANGED
@@ -1,5 +1,6 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
5
|
require 'honey_format/version'
|
5
6
|
|
@@ -21,10 +22,10 @@ Gem::Specification.new do |spec|
|
|
21
22
|
|
22
23
|
spec.required_ruby_version = '>= 2.3.0'
|
23
24
|
|
25
|
+
spec.add_development_dependency 'benchmark-ips'
|
24
26
|
spec.add_development_dependency 'bundler', '~> 1.10'
|
27
|
+
spec.add_development_dependency 'byebug'
|
25
28
|
spec.add_development_dependency 'rake', '~> 10.0'
|
26
|
-
spec.add_development_dependency 'benchmark-ips'
|
27
29
|
spec.add_development_dependency 'rspec'
|
28
30
|
spec.add_development_dependency 'simplecov'
|
29
|
-
spec.add_development_dependency 'byebug'
|
30
31
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'optparse'
|
2
4
|
require 'honey_format/cli/result_writer'
|
3
5
|
|
@@ -7,9 +9,9 @@ module HoneyFormat
|
|
7
9
|
# @attr_reader [CLIResultWriter] writer the CLI result writer
|
8
10
|
class BenchmarkCLI
|
9
11
|
# CSV default test data location
|
10
|
-
CSV_TEST_DATA_URL = 'https://gist.github.com/buren/b669dd82fa37e37672da2cab33c8a830/raw/54ba14a698941ff61f3b854b66df0a7782c79c85/csv_1000_rows.csv'
|
12
|
+
CSV_TEST_DATA_URL = 'https://gist.github.com/buren/b669dd82fa37e37672da2cab33c8a830/raw/54ba14a698941ff61f3b854b66df0a7782c79c85/csv_1000_rows.csv'.freeze
|
11
13
|
# CSV default test data cache location
|
12
|
-
CSV_TEST_DATA_CACHE_PATH = '/tmp/honey-format-benchmark-test.csv'
|
14
|
+
CSV_TEST_DATA_CACHE_PATH = '/tmp/honey-format-benchmark-test.csv'.freeze
|
13
15
|
|
14
16
|
attr_reader :writer, :options
|
15
17
|
|
@@ -44,7 +46,7 @@ module HoneyFormat
|
|
44
46
|
def fetch_default_benchmark_csv
|
45
47
|
cache_path = CSV_TEST_DATA_CACHE_PATH
|
46
48
|
|
47
|
-
if File.
|
49
|
+
if File.exist?(cache_path)
|
48
50
|
writer.puts "Cache file found at #{cache_path}.", verbose: true
|
49
51
|
@used_input_path = cache_path
|
50
52
|
return File.read(cache_path)
|
@@ -52,7 +54,7 @@ module HoneyFormat
|
|
52
54
|
|
53
55
|
writer.print 'Downloading test data file from GitHub..', verbose: true
|
54
56
|
require 'open-uri'
|
55
|
-
open(CSV_TEST_DATA_URL).read.tap do |csv|
|
57
|
+
open(CSV_TEST_DATA_URL).read.tap do |csv| # rubocop:disable Security/Open
|
56
58
|
@used_input_path = CSV_TEST_DATA_URL
|
57
59
|
writer.puts 'done!', verbose: true
|
58
60
|
File.write(cache_path, csv)
|
@@ -71,18 +73,18 @@ module HoneyFormat
|
|
71
73
|
verbose = false
|
72
74
|
|
73
75
|
OptionParser.new do |parser|
|
74
|
-
parser.banner =
|
75
|
-
parser.default_argv =
|
76
|
+
parser.banner = 'Usage: bin/benchmark [file.csv] [options]'
|
77
|
+
parser.default_argv = argv
|
76
78
|
|
77
|
-
parser.on(
|
79
|
+
parser.on('--csv=[file1.csv]', String, 'CSV file(s)') do |value|
|
78
80
|
input_path = value
|
79
81
|
end
|
80
82
|
|
81
|
-
parser.on(
|
83
|
+
parser.on('--[no-]verbose', 'Verbose output') do |value|
|
82
84
|
verbose = value
|
83
85
|
end
|
84
86
|
|
85
|
-
parser.on(
|
87
|
+
parser.on('--lines-multipliers=[1,10,50]', Array, 'Multiply the rows in the CSV file (default: 1)') do |value|
|
86
88
|
lines_multipliers = value.map do |v|
|
87
89
|
Integer(v).tap do |int|
|
88
90
|
unless int >= 1
|
@@ -92,21 +94,21 @@ module HoneyFormat
|
|
92
94
|
end
|
93
95
|
end
|
94
96
|
|
95
|
-
parser.on(
|
97
|
+
parser.on('--time=[30]', String, 'Benchmark time (default: 30)') do |value|
|
96
98
|
benchmark_time = Integer(value)
|
97
99
|
end
|
98
100
|
|
99
|
-
parser.on(
|
101
|
+
parser.on('--warmup=[30]', String, 'Benchmark warmup (default: 30)') do |value|
|
100
102
|
benchmark_warmup = Integer(value)
|
101
103
|
end
|
102
104
|
|
103
|
-
parser.on(
|
105
|
+
parser.on('-h', '--help', 'How to use') do
|
104
106
|
puts parser
|
105
107
|
exit
|
106
108
|
end
|
107
109
|
|
108
110
|
# No argument, shows at tail. This will print an options summary.
|
109
|
-
parser.on_tail(
|
111
|
+
parser.on_tail('-h', '--help', 'Show this message') do
|
110
112
|
puts parser
|
111
113
|
exit
|
112
114
|
end
|