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.
- checksums.yaml +7 -0
- data/bin/mkdata +37 -0
- data/lib/make_data.rb +177 -0
- data/lib/runner.rb +0 -0
- metadata +71 -0
checksums.yaml
ADDED
@@ -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
|
data/bin/mkdata
ADDED
@@ -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
|
data/lib/make_data.rb
ADDED
@@ -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
|
data/lib/runner.rb
ADDED
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: []
|