make-data 0.0.2

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.
Files changed (5) hide show
  1. checksums.yaml +7 -0
  2. data/bin/mkdata +37 -0
  3. data/lib/make_data.rb +177 -0
  4. data/lib/runner.rb +0 -0
  5. metadata +71 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 822b436591938dd3af1a73598e7be2c8d0589ca2b25c3a2b73174413cc331a15
4
+ data.tar.gz: db99bcc728248066077b74a5998130a9ab7afcf257f7396888c0752ce5293650
5
+ SHA512:
6
+ metadata.gz: df86472bfe58e747a6b7d7be25e197d1dc7a1b03a79a59bce7d4ae7bc9a1d44f0cd16e6d2bdde51f738b723bead12a272228dc0475123bc05ea677d21e501eb5
7
+ data.tar.gz: 07707f19b71282bcc3e98e72260ae6675c6f03c8f615988804927358f026bec72e0e24727365a35f482cb70cf25ee4d0e8d2974e762b7d5afcf663b5268b9090
@@ -0,0 +1,37 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+ require 'json'
5
+ require_relative '../lib/make_data.rb'
6
+
7
+ options = {}
8
+
9
+ OptionParser.new do |parser|
10
+ parser.on("-n", "--count [COUNT]", OptionParser::DecimalInteger,
11
+ "How many records to generate") do |count|
12
+ options[:count] = count
13
+ end
14
+
15
+ parser.on("-f [FORMAT]", "--format [FORMAT]", MakeData::ResultsFormatter.valid_formats,
16
+ "Format for the generated records") do |format|
17
+ options[:format] = format
18
+ end
19
+
20
+ parser.on("-d", "--dry", "--dry-run", "Generate a shape, but don't actually generate the samples") do
21
+ options[:dry] = true
22
+ end
23
+
24
+ parser.on("--ids", "include an auto-incrementing id column") do
25
+ options[:ids] = true
26
+ end
27
+
28
+ parser.on("--no-ids", "do not include ids") do
29
+ options[:ids] = false
30
+ end
31
+
32
+ parser.on("-s [FILENAME]", "--shape [FILENAME]", "File path to a json specification for the shape of records to generate") do |filename|
33
+ options[:shape] = JSON.parse(File.read(filename))
34
+ end
35
+ end.parse!
36
+
37
+ MakeData::CLI.new(options).run
@@ -0,0 +1,177 @@
1
+ #! /usr/bin/env ruby
2
+ require 'faker'
3
+ require 'json'
4
+ require 'csv'
5
+ require 'yaml'
6
+
7
+ module MakeData
8
+ class FakerFinder
9
+ attr_accessor :category
10
+
11
+ def initialize(category)
12
+ @category = category
13
+ raise ArgumentError.new("Invalid Category") unless Faker.const_get(@category)
14
+ end
15
+
16
+ def self.available_categories
17
+ Faker.constants - [:Config, :VERSION, :Base, :UniqueGenerator]
18
+ end
19
+
20
+ def klass
21
+ Faker.const_get(@category)
22
+ end
23
+
24
+ def available_methods
25
+ klass.methods - klass.superclass.methods
26
+ end
27
+ end
28
+
29
+ class SampleGenerator
30
+ attr_accessor :shape
31
+
32
+ # shape is a mapping from names to [category, method] pairs
33
+ # so, { name => ['FunnyName', 'name'], location => ['GameOfThrones', 'location'] }
34
+ def initialize(shape, ids)
35
+ @shape = shape
36
+ @ids = ids
37
+ end
38
+
39
+ def self.generate(category_name, method_name)
40
+ Faker.const_get(category_name).send(method_name.to_sym)
41
+ end
42
+
43
+ def make_one_from_shape
44
+ @shape.map do |category, (faker_class, method)|
45
+ [category, self.class.generate(faker_class, method)]
46
+ end.to_h
47
+ end
48
+
49
+ def generate(count)
50
+ count.times.map do |id|
51
+ make_one_from_shape.tap do |sample|
52
+ # start ids at 1
53
+ sample[:id] = id + 1 if @ids
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ class ResultsFormatter
60
+ def initialize(results, format)
61
+ @results = results
62
+ @format = format
63
+ end
64
+
65
+ def format_results
66
+ send(@format.to_sym)
67
+ end
68
+
69
+ def self.valid_formats
70
+ %w(json csv yaml)
71
+ end
72
+
73
+ def json
74
+ JSON.generate(@results)
75
+ end
76
+
77
+ def csv
78
+ CSV.generate do |csv|
79
+ csv << @results[0].keys # column headers
80
+ @results.map(&:values).each { |row| csv << row }
81
+ end
82
+ end
83
+
84
+ def yaml
85
+ @results.to_yaml
86
+ end
87
+ end
88
+
89
+ class CLI
90
+ class InvalidFormatError < StandardError; end
91
+
92
+ def initialize(format: nil, ids: true, count: nil, shape: nil, dry: false)
93
+ @dry = dry
94
+ @ids = ids
95
+ @format = @dry ? :json : format
96
+ @count = count
97
+ @shape = shape
98
+ end
99
+
100
+ def run
101
+ @shape ||= get_shape
102
+ @format ||= get_format
103
+ @count ||= get_count unless @dry
104
+ @results = @dry ? @shape : SampleGenerator.new(@shape, @ids).generate(@count)
105
+ print_results(@results)
106
+ end
107
+
108
+ def print_results(results, format = @format)
109
+ print ResultsFormatter.new(results, format).format_results
110
+ end
111
+
112
+ def get_format
113
+ prompt = "What kind of data do you want to generate?"
114
+ format = choose_among(prompt, ResultsFormatter.valid_formats)
115
+ unless ResultsFormatter.valid_formats.include?(format)
116
+ raise InvalidFormatError.new("File needs to be one of #{ResultsFormatter.valid_formats.join(', ')}")
117
+ end
118
+ format
119
+ end
120
+
121
+ def puts_in_columns(strings)
122
+ col_count = `tput cols`.chomp.to_i
123
+ col_width = strings.max_by { |s| s.length }.length + 2
124
+ cols = col_count / col_width
125
+ strings.each_slice(cols) do |row|
126
+ row.each { |s| print s.to_s.ljust(col_width) }
127
+ puts
128
+ end
129
+ end
130
+
131
+ def choose_among(prompt, strings)
132
+ `echo "#{strings.join("\n")}" | peco --prompt="#{prompt}>"`.chomp
133
+ end
134
+
135
+ def get_category
136
+ prompt = "What faker category?"
137
+ choose_among(prompt, FakerFinder.available_categories.map(&:to_s))
138
+ end
139
+
140
+ def get_method(category)
141
+ prompt = "What method?"
142
+ choose_among(prompt, FakerFinder.new(category).available_methods.map(&:to_s))
143
+ end
144
+
145
+ def get_shape(shape = {})
146
+ puts "---"
147
+ print_results(shape, 'json')
148
+ puts "\n---"
149
+ action = choose_among("What do you want to do?", ["Add a key", "Done"])
150
+ case action
151
+ when "Done"
152
+ return shape
153
+ when "Add a key"
154
+ updated = add_key(shape)
155
+ get_shape(updated)
156
+ end
157
+ end
158
+
159
+ def get_key
160
+ puts "What key do you want to add?"
161
+ gets.chomp
162
+ end
163
+
164
+ def add_key(shape)
165
+ key = get_key
166
+ cat = get_category
167
+ method = get_method(cat)
168
+ shape[key] = [cat, method]
169
+ shape
170
+ end
171
+
172
+ def get_count
173
+ puts "How many records?"
174
+ gets.chomp.to_i
175
+ end
176
+ end
177
+ end
File without changes
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: make-data
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Rob Cobb
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-03-15 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: |2+
14
+ # MakeData
15
+ A CLI for generating fake json, csv, or yaml data.
16
+
17
+ Uses Faker to produce fake data in whatever category you choose.
18
+
19
+ ## Quick Start
20
+ Requires `peco`, so `brew install peco` (or however you get packages)
21
+
22
+ ```
23
+ mkdata
24
+ ```
25
+
26
+ Follow the prompts to select the category, keys, count, and format.
27
+
28
+ ## Options
29
+
30
+ `-h --help` Shows the help menu
31
+
32
+ `-c --category [CATEGORY]` choose a category from Faker. (I can never remember these, so I use the interactive mode. Mostly here so that this could be used without interaction, like in a script)
33
+
34
+ `-f --format [FORMAT]` json, csv, or yaml. What format to generate the data in.
35
+
36
+ `-a --all` use all the keys from that Faker category.
37
+
38
+ email: rwcobbjr@gmail.com
39
+ executables:
40
+ - mkdata
41
+ extensions: []
42
+ extra_rdoc_files: []
43
+ files:
44
+ - bin/mkdata
45
+ - lib/make_data.rb
46
+ - lib/runner.rb
47
+ homepage: http://rubygems.org/gems/make_data
48
+ licenses:
49
+ - MIT
50
+ metadata: {}
51
+ post_install_message:
52
+ rdoc_options: []
53
+ require_paths:
54
+ - lib
55
+ required_ruby_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: '0'
65
+ requirements: []
66
+ rubyforge_project:
67
+ rubygems_version: 2.7.6
68
+ signing_key:
69
+ specification_version: 4
70
+ summary: Generate fake data interactively!
71
+ test_files: []