honey_format 0.14.0 → 0.15.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 94ea71ae5f48d46c64294767a6e52f2b47971e7cb578418e8947a7abfbd188a0
4
- data.tar.gz: df93394a4afd2cf7e7cff2d9c25f185febfb57b7b400d28cc7b2d703e6a2d0c6
3
+ metadata.gz: 857b7d39a88dc2a08a7fe2e3659e4e35e0b5deec1d13b3507ec74849ed55a105
4
+ data.tar.gz: cc1bd4d205e225a9767d96cd7f49d89374b55c6221de42f28210666bb505193c
5
5
  SHA512:
6
- metadata.gz: 5c95d38ebe74e9f1ace21c9ac8cb3e60dfbcd102996d8151a0dfc0c37e927a52ae9396a8b6f291160b69167bd4e6c2254a9f6290ef3e59b3a04d035dff06c124
7
- data.tar.gz: f15d755c122826a0c20de5918e248a1e100b89d4b933569614a2732d2aed5300fbb4c252ce51a67d8f0a27cc2c4064383b246e3fe59b67ddab7e6ccec4f5568c
6
+ metadata.gz: 13e3ac4d6e10d6e416b21ef909e42960a9aa33b5d09fbb231f5703390d9b9440e2271fb3bc7842a8d233ec89652051de44c4bc7c542a06fd78853d8185ed5104
7
+ data.tar.gz: 66b176f2f89999eb80c4e2688fde3db94c92dc7a3d25f2520f838dfbbc38f61c8711ee0f266d282d5930a4eb65ba8cebcb44bc81b1cbd0fc6381515487f62e98
data/CHANGELOG.md CHANGED
@@ -1,12 +1,21 @@
1
1
  # HEAD
2
2
 
3
- # v0.14.0
3
+ ## v0.15.0
4
+
5
+ :warning: This release contains some backwards compatible changes.
6
+
7
+ * Add `--skip-lines` argument to CLI [PR#22](https://github.com/buren/honey_format/pull/22)
8
+ * Add support for CSV skip lines [PR#22](https://github.com/buren/honey_format/pull/22)
9
+ * CLI have input file argument on tail instead of head [PR #21](https://github.com/buren/honey_format/pull/21)
10
+ - :warning: Backwards incompatible
11
+
12
+ ## v0.14.0
4
13
 
5
14
  * Additional converters
6
15
  + `integer_or_zero`
7
16
  + `decimal_or_zero`
8
17
 
9
- # v0.13.0
18
+ ## v0.13.0
10
19
 
11
20
  :warning: This release contains some backwards compatible changes.
12
21
 
@@ -20,21 +29,21 @@
20
29
  * Add `--[no-]rows-only` CLI option
21
30
  * Rename `--[no-]only-header` CLI option to `--[no-]header-only`
22
31
 
23
- # v0.12.0
32
+ ## v0.12.0
24
33
 
25
34
  * Add `--[no-]only-header` option to CLI
26
35
  * _[Bugfix]_: Handle missing --columns argument in CLI
27
36
 
28
- # v0.11.0
37
+ ## v0.11.0
29
38
 
30
39
  * Add CLI: `honey_format` executable
31
40
  * Swap `RowBuilder` <> `Row` class names [[#PR12](https://github.com/buren/honey_format/pull/12)]
32
41
 
33
- # v0.10.0
42
+ ## v0.10.0
34
43
 
35
44
  * Add support for filtering what rows are included in `#to_csv` [[#PR11](https://github.com/buren/honey_format/pull/11)]
36
45
 
37
- # v0.9.0
46
+ ## v0.9.0
38
47
 
39
48
  :warning: This release contains some backwards compatible changes.
40
49
 
@@ -45,41 +54,41 @@
45
54
  - There are now two super classes for errors `HeaderError` and `RowError`
46
55
  - All errors are under an `Errors` namespace, which `HoneyFormat` includes
47
56
 
48
- # v0.8.2
57
+ ## v0.8.2
49
58
 
50
59
  * _[Bugfix]_ `#to_csv` now outputs nil values as empty string instead of `""`
51
60
 
52
- # v0.8.1
61
+ ## v0.8.1
53
62
 
54
63
  * _[Bugfix]_ Properly quote cells with special CSV-characters in them. ([PR#7](https://github.com/buren/honey_format/pull/7))
55
64
 
56
- # v0.8.0
65
+ ## v0.8.0
57
66
 
58
67
  * _[Feature]_ Add `#size` and `#length` methods to `Header` and `Rows` objects
59
68
  * _[Bugfix]_ Improved Row error handling for when row size differs from header column
60
69
 
61
70
 
62
- # v0.7.0
71
+ ## v0.7.0
63
72
 
64
73
  * Don't sanitize each row :rocket: (improves performance from ~1.4x times slower than raw CSV to ~1.1)
65
74
  * Fold `Columns` class into `Header`
66
75
  * Remove `Sanitize` class
67
76
 
68
- # v0.6.0
77
+ ## v0.6.0
69
78
 
70
79
  * Add `CSV#to_csv` ([PR#2](https://github.com/buren/honey_format/pull/2))
71
80
  * `csv#rows` returns an instance of `Rows` instead of `Array`
72
81
 
73
- # v0.3.0 - v0.5.0
82
+ ## v0.3.0 - v0.5.0
74
83
 
75
84
  * Add CSV `row_builder` option
76
85
  * ...
77
86
 
78
- # v0.2.0
87
+ ## v0.2.0
79
88
 
80
89
  * More explicit exception classes
81
90
  * Restructured internals
82
91
 
83
- ## v0.1.0
92
+ ### v0.1.0
84
93
 
85
94
  Initial release
data/README.md CHANGED
@@ -29,7 +29,7 @@ Id,Username,Email
29
29
  CSV
30
30
  csv = HoneyFormat::CSV.new(csv_string, type_map: { id: :integer })
31
31
  csv.columns # => [:id, :username]
32
- user = csv.rows # => [#<struct id="1", username="buren">]
32
+ user = csv.rows # => [#<Row id="1", username="buren">]
33
33
  user.id # => 1
34
34
  user.username # => "buren"
35
35
 
@@ -70,7 +70,7 @@ header.columns # => [:id, :username]
70
70
 
71
71
 
72
72
  # Rows
73
- rows = csv.rows # => [#<struct id="1", username="buren">]
73
+ rows = csv.rows # => [#<Row id="1", username="buren">]
74
74
  user = rows.first
75
75
  user.id # => "1"
76
76
  user.username # => "buren"
@@ -128,7 +128,7 @@ Custom row builder
128
128
  csv_string = "Id,Username\n1,buren"
129
129
  upcaser = ->(row) { row.tap { |r| r.username.upcase! } }
130
130
  csv = HoneyFormat::CSV.new(csv_string, row_builder: upcaser)
131
- csv.rows # => [#<struct id="1", username="BUREN">]
131
+ csv.rows # => [#<Row id="1", username="BUREN">]
132
132
  ```
133
133
 
134
134
  As long as the row builder responds to `#call` you can pass anything you like
@@ -282,18 +282,36 @@ You can see all [available errors here](https://www.rubydoc.info/gems/honey_form
282
282
 
283
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
284
 
285
+ __Skip lines__
286
+
287
+ > Skip comments and/or other unwanted lines from being parsed.
288
+
289
+ ```ruby
290
+ csv_string = <<~CSV
291
+ Id,Username
292
+ 1,buren
293
+ # comment
294
+ 2,jacob
295
+ CSV
296
+ regexp = %r{\A#} # Match all lines that start with "#"
297
+ csv = HoneyFormat::CSV.new(csv_string, skip_lines: regexp)
298
+ csv.rows.length # => 2
299
+ ```
300
+
301
+
285
302
  ## CLI
286
303
 
287
304
  > Perfect when you want to get something simple done quickly.
288
305
 
289
306
  ```
290
- Usage: honey_format [file.csv] [options]
307
+ Usage: honey_format [options] <file.csv>
291
308
  --csv=input.csv CSV file
292
- --[no-]header-only Print only the header
293
- --[no-]rows-only Print only the rows
294
- --columns=id,name Select columns.
309
+ --columns=id,name Select columns
295
310
  --output=output.csv CSV output (STDOUT otherwise)
296
311
  --delimiter=, CSV delimiter (default: ,)
312
+ --skip-lines=, Skip lines that match this pattern
313
+ --[no-]header-only Print only the header
314
+ --[no-]rows-only Print only the rows
297
315
  -h, --help How to use
298
316
  --version Show version
299
317
  ```
data/exe/honey_format CHANGED
@@ -11,7 +11,11 @@ options = cli.options
11
11
 
12
12
  input_path = options[:input_path] || raise(ArgumentError, 'input path required')
13
13
  csv_input = File.read(input_path)
14
- csv = HoneyFormat::CSV.new(csv_input, delimiter: options[:delimiter])
14
+ csv = HoneyFormat::CSV.new(
15
+ csv_input,
16
+ delimiter: options[:delimiter],
17
+ skip_lines: options[:skip_lines]
18
+ )
15
19
 
16
20
  csv_part = if options[:header_only]
17
21
  csv.header
@@ -8,24 +8,32 @@ module HoneyFormat
8
8
 
9
9
  # Instantiate the CLI
10
10
  # @return [CLI] the CLI
11
- def initialize
12
- @options = parse_options(argv: ARGV)
11
+ def initialize(argv: ARGV, io: STDOUT)
12
+ @io = io
13
+ @options = parse_options(argv: argv.dup)
14
+ end
15
+
16
+ private
17
+
18
+ def puts(*args)
19
+ @io.puts(*args)
13
20
  end
14
21
 
15
22
  # Parse command line arguments and return options
16
23
  # @param [Array<String>] argv the command lines arguments
17
24
  # @return [Hash] the command line options
18
25
  def parse_options(argv:)
19
- input_path = argv.first
26
+ input_path = nil
20
27
  columns = nil
21
28
  output_path = nil
22
29
  delimiter = ','
23
30
  header_only = false
24
31
  rows_only = false
32
+ skip_lines = nil
25
33
 
26
34
  OptionParser.new do |parser|
27
- parser.banner = "Usage: honey_format [file.csv] [options]"
28
- parser.default_argv = ARGV
35
+ parser.banner = "Usage: honey_format [options] <file.csv>"
36
+ parser.default_argv = argv
29
37
 
30
38
  parser.on("--csv=input.csv", String, "CSV file") do |value|
31
39
  input_path = value
@@ -43,6 +51,10 @@ module HoneyFormat
43
51
  delimiter = value
44
52
  end
45
53
 
54
+ parser.on("--skip-lines=,", String, "Skip lines that match this pattern") do |value|
55
+ skip_lines = value
56
+ end
57
+
46
58
  parser.on("--[no-]header-only", "Print only the header") do |value|
47
59
  header_only = value
48
60
  end
@@ -60,14 +72,17 @@ module HoneyFormat
60
72
  puts "HoneyFormat version #{HoneyFormat::VERSION}"
61
73
  exit
62
74
  end
63
-
64
- # No argument, shows at tail. This will print an options summary.
65
- parser.on_tail("-h", "--help", "Show this message") do
66
- puts parser
67
- exit
68
- end
69
75
  end.parse!
70
76
 
77
+ if header_only && rows_only
78
+ raise(ArgumentError, "you can't provide both --header-only and --rows-only")
79
+ end
80
+
81
+ if input_path && argv.last
82
+ raise(ArgumentError, "you can't provide both --csv and <path>")
83
+ end
84
+ input_path ||= argv.last
85
+
71
86
  {
72
87
  input_path: input_path,
73
88
  columns: columns,
@@ -75,6 +90,7 @@ module HoneyFormat
75
90
  delimiter: delimiter,
76
91
  header_only: header_only,
77
92
  rows_only: rows_only,
93
+ skip_lines: skip_lines
78
94
  }
79
95
  end
80
96
  end
@@ -17,6 +17,7 @@ module HoneyFormat
17
17
  # @param [#call] header_converter converts header columns.
18
18
  # @param [#call] row_builder will be called for each parsed row.
19
19
  # @param type_map [Hash] map of column_name => type conversion to perform.
20
+ # @param skip_lines [Regexp, String] Regexp for determining wheter a line is a comment. See CSV skip_lines option.
20
21
  # @raise [HeaderError] super class of errors raised when there is a CSV header error.
21
22
  # @raise [MissingHeaderError] raised when header is missing (empty or nil).
22
23
  # @raise [MissingHeaderColumnError] raised when header column is missing.
@@ -48,14 +49,16 @@ module HoneyFormat
48
49
  header: nil,
49
50
  header_converter: HoneyFormat.header_converter,
50
51
  row_builder: nil,
51
- type_map: {}
52
+ type_map: {},
53
+ skip_lines: nil
52
54
  )
53
55
  csv = ::CSV.parse(
54
56
  csv,
55
57
  col_sep: delimiter,
56
58
  row_sep: row_delimiter,
57
59
  quote_char: quote_character,
58
- skip_blanks: true
60
+ skip_blanks: true,
61
+ skip_lines: skip_lines
59
62
  )
60
63
  super(
61
64
  csv,
@@ -23,6 +23,20 @@ module HoneyFormat
23
23
  ::CSV.generate_line(row)
24
24
  end
25
25
 
26
+ # Describe the contents of this row in a string.
27
+ # @return [String] content of this row
28
+ def inspect
29
+ attributes = members.map do |field|
30
+ value = self[field]
31
+ value = "\"#{value}\"" if value.is_a?(String)
32
+
33
+ [field, value].join("=")
34
+ end.join(", ")
35
+
36
+ "#<Row #{attributes}>"
37
+ end
38
+ alias_method :to_s, :inspect
39
+
26
40
  private
27
41
 
28
42
  # Returns the column in CSV format
@@ -8,9 +8,12 @@ require 'honey_format/header_column_converter'
8
8
  module HoneyFormat
9
9
  # Converts values
10
10
  class ValueConverter
11
+ # String values considered truthy
11
12
  TRUTHY = Set.new(%w[t T 1 y Y true TRUE]).freeze
13
+ # String values considered falsy
12
14
  FALSY = Set.new(%w[f F 0 n N false FALSE]).freeze
13
15
 
16
+ # Tries to convert value boolean to, returns nil if it can't convert
14
17
  CONVERT_BOOLEAN = lambda { |v|
15
18
  value = v&.downcase
16
19
  if TRUTHY.include?(value)
@@ -1,4 +1,8 @@
1
1
  module HoneyFormat
2
2
  # Gem version
3
- VERSION = '0.14.0'
3
+ VERSION = [
4
+ MAJOR_VERSION = 0,
5
+ MINOR_VERSION = 15,
6
+ PATCH_VERSION = 0
7
+ ].join('.')
4
8
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: honey_format
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.14.0
4
+ version: 0.15.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jacob Burenstam
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-06-26 00:00:00.000000000 Z
11
+ date: 2018-06-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler