csv2schema 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- NTA1OWRiNjIxMmQ2YjdiZmMxM2M0MzkzOTI5OWNiNjE5Y2NmNGQzZA==
4
+ NTRjMDQyMjU2NmY1YTYzOTc4MGMzMjkxMjE4MDk3MjUyYjQzMThmZA==
5
5
  data.tar.gz: !binary |-
6
- Nzk0MGUxODRlMTVlZmY4Y2VlNDY2ZmQ2MGQ3ZGI1ZWY4ZDQzMjEyOA==
6
+ OWMwYjAyNzUwMDAwNjRmZjNhZTAxNDMwMjgyMjhmNjVlZGU2ZWQ5ZA==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- NjE1YjMzZDIxZGQyMDllZjMyNWU2MDBhZmVmMmZjMDE3ODA0YmMzMDk1YzY5
10
- MGQ5YzFiOWEwOWU3MTYwYTJkYzdlN2YzYWE4OTY1MjFhZGI0MDdlMGNmYTNh
11
- Mzk1MGU2N2EyMDNmYjZlMDVhMGE1MTg2N2IwYzJkNTVkMmNmYWI=
9
+ Y2VlOWMzZGM1OWQyYjA3YzdhMzM5MDBmNjcwNmZkZjFmNzk0MTFhZDhmNzll
10
+ ZTdjYmE3ZTQ4NDBhNDkzMDFkYjY1NzgyYTgwNWE2NjgwM2YxN2NmYzM1MTM5
11
+ MTg0MjM5OTcxMTk3OTg1MTdhZTFjYjVjNzNkYjU3NWI5ZmZiZWY=
12
12
  data.tar.gz: !binary |-
13
- NmUwNTQ5ZTU0MjNhNTY5MmQ4ZWNmMWUyNGFkZDk1M2M2YTYyYzgxZGVhNGI0
14
- ZTViNzY3NGZmMzA2NmI3ZTBkNGVkNDc1MjQ5ZTJkMTU4NDZhNDJhOGQzYzU1
15
- N2RhZmIzZjdlNWJlY2YzMWUzNDM0MWI2NzcxMTdmMDEzMDdmM2E=
13
+ YzA3MzRhYjY0ODJkOTRmMWZjOTQ5NzhkYjY3NTA5NzFmNzVjOWIyYWJjOThi
14
+ ZDcxMmQ3MWExOGE4ZmM1YzQyMWUxYTBiYWExYTMzOTVmOWMxYmZlOGMzNDZi
15
+ OGY0ZWUyN2ViZGVkZDllZDk1NzRjZGM5YWJkZTg4NWFmYjM1Zjc=
@@ -1,3 +1,4 @@
1
+ ---
1
2
  language: ruby
2
3
  rvm:
3
4
  - 2.3.1
@@ -10,3 +11,8 @@ deploy:
10
11
  on:
11
12
  tags: true
12
13
  repo: theodi/csv2schema
14
+ env:
15
+ global:
16
+ secure: jNfyOFHHWsNoOnpZeeB64rfpgBy1qn4h7pltuSwvW5LwuHBaQQU2d2vqi7ypqN7AfCvxU2ZGOmiGlhX7TjsIFhqs0LBpUuzde7xgMMrHuDr7fp3aNfKXjljdg0ltUsXjcgyoPMsaWJt9KqhIY3YFGcz+PeOFGmUVLDHUNjM2nyDIlmPxn5iCt/UzSOXWW3iHdjwfJyiUNLvRP+AxCfL0bR7d0LleitAk75ITcsKgbasekg51uFC/wvdZnPB88Er3Sr4y2/YXQDjQuyCj+cOZitNgHjFQ3lRz7CBHko5uA7NcQeFxLmV3oaOTmbwDGiI9fHjzWXDkWAc2jnf98B1UizFJDkGpftXBRrtoFqf6huIegJf+0bP4zKoEOfINHm50QGVLmbXDqN0Oc3WNJo/ULXm80W28yf7cuQBHSJ8ze+3Bllg8NHQwlCws2teHappkOG842Nzzx9qNs/ATleiHtvIo6iUtv5QXHkqD7OET6ubJVyGWw5guCRo/tpsFV1djEc3O9Dpc2aQs2hhz0gMvHVrb1V1mGGKwC37KEJCzRuPJypkTvSsylTLezq4eQ24E/jMpVMi97vceXbXpj+mxL1aaOwtDoN5QR6MCvC3w7dvODEG/mJ5wDtEhPp35zK3iwI26g/gxWrW9iy9cLz2jqBPY1EZJDOPvlD4OyB+XNSc=
17
+ after_success:
18
+ - bundle exec henry deploy
@@ -0,0 +1,9 @@
1
+ # Change Log
2
+
3
+ ## [0.1.0](https://github.com/theodi/csv2schema/tree/0.1.0) (2016-09-02)
4
+ [Full Changelog](https://github.com/theodi/csv2schema/compare/0.0.1...0.1.0)
5
+
6
+ ## [0.0.1](https://github.com/theodi/csv2schema/tree/0.0.1) (2016-09-02)
7
+
8
+
9
+ \* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
data/README.md CHANGED
@@ -26,6 +26,32 @@ Or install it yourself as:
26
26
 
27
27
  ## Usage
28
28
 
29
+ You can either use the gem on the command line, or in your own Ruby code
30
+
31
+ ### On the command line
32
+
33
+ After installing the gem, you can generate a schema file on the command line like so:
34
+
35
+ ```
36
+ csv2schema generate myfile.csv
37
+ ```
38
+
39
+ This will generate a JSON table schema file at `schema.json`.
40
+
41
+ You can also specify a filename and extension like so:
42
+
43
+ ```
44
+ csv2schema generate myfile.csv --filename=myschema.json
45
+ ```
46
+
47
+ If you want to dump the JSON to the command line (to pipe somewhere else for example) we can handle that too:
48
+
49
+ ```
50
+ csv2schema generate myfile.csv --dump
51
+ ```
52
+
53
+ ### In your own Ruby code
54
+
29
55
  Require the gem (if you haven't already):
30
56
 
31
57
  ```ruby
@@ -27,9 +27,12 @@ Gem::Specification.new do |spec|
27
27
  spec.require_paths = ["lib"]
28
28
 
29
29
  spec.add_dependency "csvlint", "~> 0.3.2"
30
+ spec.add_dependency "thor", "~> 0.19.1"
31
+ spec.add_dependency "colorize", "~> 0.8.1"
30
32
 
31
33
  spec.add_development_dependency "bundler", "~> 1.11"
32
34
  spec.add_development_dependency "rake", "~> 10.0"
33
35
  spec.add_development_dependency "rspec", "~> 3.0"
34
36
  spec.add_development_dependency "pry", "~> 0.10.4"
37
+ spec.add_development_dependency "henry", "~> 0.1.3"
35
38
  end
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "csv2schema"
5
+ require "thor"
6
+ require "colorize"
7
+
8
+ module Csv2schema
9
+ class Cli < Thor
10
+
11
+ desc "csv2schema /path/to/file.csv OR csv2schema http://example.org/file.csv", "Generate schema from CSV"
12
+ option :dump, type: :boolean
13
+ option :filename
14
+ def generate(source)
15
+ source = read_source(source)
16
+ csv = Csv2schema::CSV.new(source)
17
+ if options[:dump]
18
+ puts csv.schema
19
+ else
20
+ filename = options[:filename].nil? ? 'schema.json' : options[:filename]
21
+ File.open(filename, 'w') {|f| f.write(csv.schema) }
22
+ puts "Schema created at #{filename}!".colorize(:green)
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ def read_source(source)
29
+ if source.nil?
30
+ # If no source is present, try reading from stdin
31
+ if !$stdin.tty?
32
+ source = StringIO.new(STDIN.read) rescue nil
33
+ return_error "No CSV data to validate" if !options[:schema] && source.nil?
34
+ end
35
+ else
36
+ # If the source isn't a URL, it's a file
37
+ unless source =~ /^http(s)?/
38
+ begin
39
+ source = File.new( source )
40
+ rescue Errno::ENOENT
41
+ return_error "#{source} not found"
42
+ end
43
+ end
44
+ end
45
+ source
46
+ end
47
+
48
+ end
49
+ end
50
+
51
+ Csv2schema::Cli.start(ARGV)
@@ -3,6 +3,7 @@ require "json"
3
3
 
4
4
  require "csv2schema/version"
5
5
 
6
+ require "csv2schema/format_builder"
6
7
  require "csv2schema/formats"
7
8
  require "csv2schema/required"
8
9
  require "csv2schema/schema"
@@ -5,7 +5,7 @@ module Csv2schema
5
5
  include Csv2schema::Schema
6
6
 
7
7
  def initialize(io)
8
- @validator = Csvlint::Validator.new(io)
8
+ @validator = Csv2schema::Validator.new(io)
9
9
  @column_headers = get_column_headers
10
10
  apply_formats
11
11
  apply_required
@@ -0,0 +1,84 @@
1
+ module Csv2schema
2
+ class Validator < Csvlint::Validator
3
+
4
+ def build_formats(row)
5
+ row.each_with_index do |col, i|
6
+ next if col.nil? || col.empty?
7
+ @formats[i] ||= Hash.new(0)
8
+
9
+ # require "pry" ; binding.pry
10
+
11
+ format =
12
+ if float?(col)
13
+ :float
14
+ elsif col.strip[FORMATS[:boolean]]
15
+ :boolean
16
+ elsif uri?(col)
17
+ :uri
18
+ elsif possible_date?(col)
19
+ date_formats(col)
20
+ elsif col.strip[FORMATS[:numeric]]
21
+ :numeric
22
+ else
23
+ :string
24
+ end
25
+
26
+ @formats[i][format] += 1
27
+ end
28
+ end
29
+
30
+ def float?(col)
31
+ Float(col).to_s == col rescue false
32
+ end
33
+
34
+ def date_formats(col)
35
+ if col[FORMATS[:date_db]] && date_format?(Date, col, '%Y-%m-%d')
36
+ :date_db
37
+ elsif col[FORMATS[:date_short]] && date_format?(Date, col, '%e %b')
38
+ :date_short
39
+ elsif col[FORMATS[:date_rfc822]] && date_format?(Date, col, '%e %b %Y')
40
+ :date_rfc822
41
+ elsif col[FORMATS[:date_long]] && date_format?(Date, col, '%B %e, %Y')
42
+ :date_long
43
+ elsif col[FORMATS[:dateTime_time]] && date_format?(Time, col, '%H:%M')
44
+ :dateTime_time
45
+ elsif col[FORMATS[:dateTime_hms]] && date_format?(Time, col, '%H:%M:%S')
46
+ :dateTime_hms
47
+ elsif col[FORMATS[:dateTime_db]] && date_format?(Time, col, '%Y-%m-%d %H:%M:%S')
48
+ :dateTime_db
49
+ elsif col[FORMATS[:dateTime_iso8601]] && date_format?(Time, col, '%Y-%m-%dT%H:%M:%SZ')
50
+ :dateTime_iso8601
51
+ elsif col[FORMATS[:dateTime_short]] && date_format?(Time, col, '%d %b %H:%M')
52
+ :dateTime_short
53
+ elsif col[FORMATS[:dateTime_long]] && date_format?(Time, col, '%B %d, %Y %H:%M')
54
+ :dateTime_long
55
+ elsif col[FORMATS[:date_month]] && date_format?(Date, col, '%Y-%m')
56
+ :date_month
57
+ elsif col.strip[FORMATS[:numeric]]
58
+ :numeric
59
+ else
60
+ :string
61
+ end
62
+ end
63
+
64
+ FORMATS = {
65
+ :string => nil,
66
+ :numeric => /\A[-+]?\d*\.?\d+(?:[eE][-+]?\d+)?\z/,
67
+ :uri => /\Ahttps?:/,
68
+ :boolean => /\Atrue\z|\Afalse\z|\Ay\z|\An\z|\Ayes\z|\Ano\z|\A1\z|\A0\z/i,
69
+ :date_year => /\A\d{4,}\z/, # 12345
70
+ :date_month => /\A\d{4,}-\d{2,}\z/, # 12345-02
71
+ :date_db => /\A\d{4,}-\d\d-\d\d\z/, # "12345-01-01"
72
+ :date_long => /\A(?:#{Date::MONTHNAMES.join('|')}) [ \d]\d, \d{4,}\z/, # "January 1, 12345"
73
+ :date_rfc822 => /\A[ \d]\d (?:#{Date::ABBR_MONTHNAMES.join('|')}) \d{4,}\z/, # " 1 Jan 12345"
74
+ :date_short => /\A[ \d]\d (?:#{Date::ABBR_MONTHNAMES.join('|')})\z/, # "1 Jan"
75
+ :dateTime_db => /\A\d{4,}-\d\d-\d\d \d\d:\d\d:\d\d\z/, # "12345-01-01 00:00:00"
76
+ :dateTime_hms => /\A\d\d:\d\d:\d\d\z/, # "00:00:00"
77
+ :dateTime_iso8601 => /\A\d{4,}-\d\d-\d\dT\d\d:\d\d:\d\dZ\z/, # "12345-01-01T00:00:00Z"
78
+ :dateTime_long => /\A(?:#{Date::MONTHNAMES.join('|')}) \d\d, \d{4,} \d\d:\d\d\z/, # "January 01, 12345 00:00"
79
+ :dateTime_short => /\A\d\d (?:#{Date::ABBR_MONTHNAMES.join('|')}) \d\d:\d\d\z/, # "01 Jan 00:00"
80
+ :dateTime_time => /\A\d\d:\d\d\z/, # "00:00"
81
+ }.freeze
82
+
83
+ end
84
+ end
@@ -21,7 +21,14 @@ module Csv2schema
21
21
  def get_type(format)
22
22
  {
23
23
  string: 'http://www.w3.org/2001/XMLSchema#string',
24
- numeric: 'http://www.w3.org/2001/XMLSchema#int'
24
+ numeric: 'http://www.w3.org/2001/XMLSchema#int',
25
+ float: 'http://www.w3.org/2001/XMLSchema#float',
26
+ uri: 'http://www.w3.org/2001/XMLSchema#anyURI',
27
+ boolean: 'http://www.w3.org/2001/XMLSchema#boolean',
28
+ date_db: 'http://www.w3.org/2001/XMLSchema#date',
29
+ dateTime_iso8601: 'http://www.w3.org/2001/XMLSchema#dateTime',
30
+ date_month: 'http://www.w3.org/2001/XMLSchema#gYearMonth',
31
+ dateTime_hms: 'http://www.w3.org/2001/XMLSchema#time'
25
32
  }[format]
26
33
  end
27
34
 
@@ -1,3 +1,3 @@
1
1
  module Csv2schema
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: csv2schema
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - pezholio
@@ -24,6 +24,34 @@ dependencies:
24
24
  - - ~>
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.3.2
27
+ - !ruby/object:Gem::Dependency
28
+ name: thor
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: 0.19.1
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: 0.19.1
41
+ - !ruby/object:Gem::Dependency
42
+ name: colorize
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: 0.8.1
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 0.8.1
27
55
  - !ruby/object:Gem::Dependency
28
56
  name: bundler
29
57
  requirement: !ruby/object:Gem::Requirement
@@ -80,10 +108,25 @@ dependencies:
80
108
  - - ~>
81
109
  - !ruby/object:Gem::Version
82
110
  version: 0.10.4
111
+ - !ruby/object:Gem::Dependency
112
+ name: henry
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ~>
116
+ - !ruby/object:Gem::Version
117
+ version: 0.1.3
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ~>
123
+ - !ruby/object:Gem::Version
124
+ version: 0.1.3
83
125
  description:
84
126
  email:
85
127
  - pezholio@gmail.com
86
- executables: []
128
+ executables:
129
+ - csv2schema
87
130
  extensions: []
88
131
  extra_rdoc_files: []
89
132
  files:
@@ -91,6 +134,7 @@ files:
91
134
  - .rspec
92
135
  - .ruby-version
93
136
  - .travis.yml
137
+ - CHANGELOG.md
94
138
  - CODE_OF_CONDUCT.md
95
139
  - Gemfile
96
140
  - LICENSE.txt
@@ -99,8 +143,10 @@ files:
99
143
  - bin/console
100
144
  - bin/setup
101
145
  - csv2schema.gemspec
146
+ - exe/csv2schema
102
147
  - lib/csv2schema.rb
103
148
  - lib/csv2schema/csv.rb
149
+ - lib/csv2schema/format_builder.rb
104
150
  - lib/csv2schema/formats.rb
105
151
  - lib/csv2schema/required.rb
106
152
  - lib/csv2schema/schema.rb