resme 1.0.1 → 2.0.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.
data/Gemfile DELETED
@@ -1,6 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- # Specify your gem's dependencies in resme.gemspec
4
- gemspec
5
-
6
- gem "rake", "~> 12.0"
data/Gemfile.lock DELETED
@@ -1,20 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- resme (0.5.0)
5
-
6
- GEM
7
- remote: https://rubygems.org/
8
- specs:
9
- rake (12.3.3)
10
-
11
- PLATFORMS
12
- x86_64-linux
13
-
14
- DEPENDENCIES
15
- bundler (~> 2.3.20)
16
- rake (~> 12.0)
17
- resme!
18
-
19
- BUNDLED WITH
20
- 2.3.20
data/bin/console DELETED
@@ -1,14 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require "bundler/setup"
4
- require "resme"
5
-
6
- # You can add fixtures and/or initialization code here to make experimenting
7
- # with your gem easier. You can also use a different console, if you like.
8
-
9
- # (If you use this, don't forget to add pry to your Gemfile!)
10
- # require "pry"
11
- # Pry.start
12
-
13
- require "irb"
14
- IRB.start(__FILE__)
data/bin/setup DELETED
@@ -1,8 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
- set -vx
5
-
6
- bundle install
7
-
8
- # Do any other automated setup that you need to do here
@@ -1,198 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "resme/version"
4
- require "readline"
5
- require "fileutils"
6
- require "date"
7
- require "yaml"
8
- require "erb"
9
- require "json"
10
-
11
- module Resme
12
- # Give e meaning to commands
13
- module CommandSemantics
14
- APPNAME = "resme"
15
- VERSION = Resme::VERSION
16
-
17
- #
18
- # Main App Starts Here!
19
- #
20
- def self.version(opts = nil, argv = [])
21
- puts "#{APPNAME} version #{VERSION}"
22
- end
23
-
24
- def self.man(opts = nil, argv = [])
25
- path = File.join(File.dirname(__FILE__), "/../../../README.org")
26
- file = File.open(path, "r")
27
- puts file.read
28
- end
29
-
30
- def self.help(opts = nil, argv = [])
31
- all_commands = CommandSyntax.commands
32
-
33
- if argv == []
34
- puts "#{APPNAME} command [options] [args]\n"
35
- puts "Available commands:\n"
36
- all_commands.each_key do |key|
37
- puts " #{all_commands[key][:options].banner}"
38
- end
39
- else
40
- argv.map do |x|
41
- puts all_commands[x.to_sym][:help]
42
- puts "\n\n"
43
- end
44
- end
45
- end
46
-
47
- def self.console(opts = nil, argv = [])
48
- all_commands = CommandSyntax.commands
49
- all_commands.delete(:console)
50
-
51
- i = 0
52
- loop do
53
- string = Readline.readline("#{APPNAME}:%03d> " % i, true)
54
- # as a courtesy, remove any leading appname string
55
- string.gsub!(/^#{APPNAME} /, "")
56
- exit 0 if %w[exit quit .].include? string
57
- execute all_commands, string.split(" ")
58
- i += 1
59
- end
60
- end
61
-
62
- # read-eval-print step
63
- # check if argv is in any of all_commands, parse options
64
- # according to the specification in all_commands and invoke
65
- # a function in this class to actually do the work
66
- def self.execute(all_commands, argv)
67
- if argv == [] or argv[0] == "--help" or argv[0] == "-h"
68
- help
69
- exit 0
70
- else
71
- command = argv[0]
72
- command_spec = all_commands[command.to_sym]
73
-
74
- if command_spec
75
- command_name = command_spec[:name]
76
- option_parser = command_spec[:options]
77
-
78
- begin
79
- argv.shift # remove command name from ARGV
80
- options = {}
81
- parser = option_parser.parse!(into: options)
82
- eval "CommandSemantics::#{command_name}(options, argv)"
83
- rescue Exception => e
84
- puts "#{APPNAME} error: #{e}"
85
- puts "Help with \"#{APPNAME} help #{command_name}\""
86
- end
87
- else
88
- puts "#{APPNAME} error: "#{command}" is not a valid command."
89
- puts "List commands with \"#{APPNAME} help\"."
90
- end
91
- end
92
- end
93
-
94
- #
95
- # APP SPECIFIC COMMANDS
96
- #
97
- def self.check(opts, argv)
98
- begin
99
- document = YAML.load_file(argv[0], permitted_classes: [Date])
100
- rescue Psych::SyntaxError => ex
101
- puts "The file #{argv[0]} has an invalid structure."
102
- puts ex.message
103
- exit 1
104
- end
105
-
106
- begin
107
- errors = ResumeStructureValidator.validate(document)
108
- rescue Exception => ex
109
- puts "The files #{argv[0]} does not validate"
110
- ex.entries.each do |error|
111
- puts "#{error[:full_path]}: #{error[:message]}"
112
- end
113
- exit 1
114
- end
115
- puts "The file #{argv[0]} has a valid structure."
116
- end
117
-
118
- def self.init(opts, argv)
119
- output = opts[:output] || "resume.yml"
120
- force = opts[:force]
121
- path = File.dirname(__FILE__), "/../templates/resume.yml"
122
- template = File.join(path)
123
-
124
- # avoid catastrophe
125
- if File.exist?(output) && !force
126
- puts "#{APPNAME} error: file #{output} already exists."
127
- puts "Use --force if you want to overwrite it."
128
- else
129
- content = File.read(template)
130
- backup_and_write output, content
131
- puts "YML resume template generated in #{output}"
132
- end
133
- end
134
-
135
- def self.list(opts, argv)
136
- data = {}
137
- argv.each do |file|
138
- data = data.merge(YAML.load_file(file, permitted_classes: [Date]))
139
- end
140
- puts "Sections included in #{argv.join(", ")}:"
141
- data.keys.each do |key|
142
- puts "- #{key}: #{(data[key] || []).size} entries"
143
- end
144
- end
145
-
146
- def self.view(opts, argv)
147
- format = opts[:to]
148
- template = File.join(File.dirname(__FILE__), "/../templates/resume.#{format}.erb")
149
- puts File.read template
150
- end
151
-
152
- def self.generate(opts, argv)
153
- format = opts[:to]
154
- output = opts[:output] || "resume-#{Date.today}.#{format}"
155
-
156
- if opts[:erb]
157
- template = opts[:erb]
158
- else
159
- template = File.join(File.dirname(__FILE__), "/../templates/resume.#{format}.erb")
160
- end
161
-
162
- skipped_sections = opts[:skip] || []
163
-
164
- if !File.exist?(template)
165
- puts "#{APPNAME} error: format #{format} is not understood."
166
- end
167
-
168
- render argv, template, output, skipped_sections
169
- puts "Resume generated in #{output}"
170
- end
171
-
172
- private_class_method def self.render(yml_files, template_name, output_name, skipped_sections)
173
- data = {}
174
- yml_files.each do |file|
175
- data = data.merge(YAML.load_file(file, permitted_classes: [Date]))
176
- end
177
- skipped_sections.each do |section|
178
- data.reject! { |k| k == section }
179
- end
180
- template = File.read(template_name)
181
- output = ERB.new(template, trim_mode: "-").result(binding)
182
- # it is difficult to write readable ERBs with no empty lines... we use
183
- # gsub to replace multiple empty lines with \n\n in the final output
184
- output.gsub!(/([\t ]*\n){3,}/, "\n\n")
185
- backup_and_write output_name, output
186
- end
187
-
188
- private_class_method def self.backup(filename)
189
- FileUtils::cp filename, filename + "~"
190
- puts "Backup copy #{filename} created in #{filename}~."
191
- end
192
-
193
- private_class_method def self.backup_and_write(filename, content)
194
- backup(filename) if File.exist?(filename)
195
- File.open(filename, "w") { |f| f.puts content }
196
- end
197
- end
198
- end
@@ -1,282 +0,0 @@
1
- require "optparse"
2
-
3
- module Resme
4
- module CommandSyntax
5
- # Return a hash of hashes. Each key is the name of a command and
6
- # includes useful information, such as an Option object to
7
- # parse options and a documentation string.
8
- def self.commands
9
- cmd_spec = {}
10
- methods.each do |method|
11
- cmd_spec = cmd_spec.merge eval(method.to_s) if method.to_s.include?("_opts")
12
- end
13
- cmd_spec
14
- end
15
-
16
- def self.version_opts
17
- opts = OptionParser.new do |opts|
18
- opts.banner = "version # print version information"
19
- end
20
-
21
- help = <<-EOS
22
- NAME
23
- #{opts.banner}
24
-
25
- SYNOPSYS
26
- #{opts.to_s}
27
-
28
- DESCRIPTION
29
- return version information
30
-
31
- EXAMPLES
32
- # resme version
33
- resme version #{VERSION}
34
- EOS
35
-
36
- {
37
- version: {
38
- name: :version,
39
- options: opts,
40
- help: help.gsub(" ", "")
41
- }
42
- }
43
- end
44
-
45
- def self.console_opts
46
- opts = OptionParser.new do |opts|
47
- opts.banner = "console # enter the console"
48
- end
49
-
50
- help = <<-EOS
51
- NAME
52
- #{opts.banner}
53
-
54
- SYNOPSYS
55
- #{opts.to_s}
56
-
57
- DESCRIPTION
58
- Invoke a console, from which you can more easily run
59
- resme commands.
60
-
61
- EXAMPLES
62
- resme console
63
- resme:000> check
64
- resme:001> generate -t md
65
- resme:002>
66
- EOS
67
-
68
- {
69
- console: {
70
- name: :console,
71
- options: opts,
72
- help: help.gsub(" ", "")
73
- }
74
- }
75
- end
76
-
77
- def self.man_opts
78
- opts = OptionParser.new do |opts|
79
- opts.banner = "man # print resme manual page"
80
- end
81
-
82
- help = <<-EOS
83
- NAME
84
- #{opts.banner}
85
-
86
- SYNOPSYS
87
- #{opts.to_s}
88
-
89
- DESCRIPTION
90
- Print the README file of this gem
91
-
92
- EXAMPLES
93
- resme man
94
- EOS
95
-
96
- {
97
- man: {
98
- name: :man,
99
- options: opts,
100
- help: help.gsub(" ", "")
101
- }
102
- }
103
- end
104
-
105
- def self.help_opts
106
- opts = OptionParser.new do |opts|
107
- opts.banner = "help [command] # print command usage"
108
- end
109
-
110
- help = <<-EOS
111
- NAME
112
- #{opts.banner}
113
-
114
- SYNOPSYS
115
- #{opts.to_s}
116
-
117
- DESCRIPTION
118
- Print help about a command
119
-
120
- EXAMPLES
121
- resme help
122
- resme help generate
123
- EOS
124
- {
125
- help: {
126
- name: :help,
127
- options: opts,
128
- help: help.gsub(" ", "")
129
- }
130
- }
131
- end
132
-
133
- def self.init_opts
134
- opts = OptionParser.new do |opts|
135
- opts.banner = "init [options] # generate an empty resume.yml file"
136
- opts.on("-o", "--output FILENAME", String, "Output filename")
137
- opts.on("-f", "--force", FalseClass, "Overwrite existing file (if present)")
138
- end
139
-
140
- help = <<-EOS
141
- NAME
142
- #{opts.banner}
143
-
144
- SYNOPSYS
145
- #{opts.to_s}
146
-
147
- DESCRIPTION
148
- Generate a YAML template for your resume in the current directory.
149
-
150
- EXAMPLES
151
- resme init
152
- resme init -o r.yml
153
- resme init -o r.yml --force
154
- EOS
155
- {
156
- init: {
157
- name: :init,
158
- options: opts,
159
- help: help.gsub(" ", "")
160
- }
161
- }
162
- end
163
-
164
- def self.check_opts
165
- opts = OptionParser.new do |opts|
166
- opts.banner = "check resume.yml # Check syntax of resume.yml"
167
- end
168
-
169
- help = <<-EOS
170
- NAME
171
- #{opts.banner}
172
-
173
- SYNOPSYS
174
- #{opts.to_s}
175
-
176
- DESCRIPTION
177
- Check whether a YAML file conforms with the RESME syntax.
178
-
179
- EXAMPLES
180
- resme check file.yml
181
- EOS
182
-
183
- {
184
- check: {
185
- name: :check,
186
- options: opts,
187
- help: help.gsub(" ", "")
188
- }
189
- }
190
- end
191
-
192
- def self.list_opts
193
- opts = OptionParser.new do |opts|
194
- opts.banner = "list resume.yml # List main sections in resume.yml"
195
- end
196
-
197
- help = <<-EOS
198
- NAME
199
- #{opts.banner}
200
-
201
- SYNOPSYS
202
- #{opts.to_s}
203
-
204
- DESCRIPTION
205
- List main sections in resume.yml.
206
-
207
- EXAMPLES
208
- resme list file.yml
209
- EOS
210
-
211
- {
212
- list: {
213
- name: :list,
214
- options: opts,
215
- help: help.gsub(" ", "")
216
- }
217
- }
218
- end
219
-
220
- def self.view_opts
221
- opts = OptionParser.new do |o|
222
- o.banner = "view --template FORMAT # Print template used for format"
223
- o.on("-t", "--template FORMAT", String, "View template for FORMAT")
224
- end
225
-
226
- help = <<-EOS
227
- NAME
228
- #{opts.banner}
229
-
230
- SYNOPSYS
231
- #{opts.to_s}
232
-
233
- DESCRIPTION
234
- Print template used for FORMAT
235
-
236
- EXAMPLES
237
- resme view --template md
238
- EOS
239
-
240
- {
241
- view: {
242
- name: :view,
243
- options: opts,
244
- help: help.gsub(" ", "")
245
- }
246
- }
247
- end
248
-
249
- def self.generate_opts
250
- opts = OptionParser.new do |o|
251
- o.banner = "generate [options] resume.yml ... # output resume"
252
- o.on("-e", "--erb FILENAME", String, "Template to use")
253
- o.on("-t", "--to FORMAT", String, "Output format")
254
- o.on("-o", "--output FILENAME", String, "Output filename")
255
- o.on("-s", "--skip SECTION,SECTION", Array, "Sections to skip")
256
- end
257
-
258
- help = <<-EOS
259
- NAME
260
- #{opts.banner}
261
-
262
- SYNOPSYS
263
- #{opts.to_s}
264
-
265
- DESCRIPTION
266
- Generate a resume from the YAML input files.
267
-
268
- EXAMPLES
269
- resme generate -t org resume.yml
270
- resme generate -t md -o r.md section-1.yml section-2.yml
271
- EOS
272
-
273
- {
274
- generate: {
275
- name: :generate,
276
- options: opts,
277
- help: help.gsub(" ", "")
278
- }
279
- }
280
- end
281
- end
282
- end