resme 2.0.0 → 2.0.1
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 +4 -4
- data/CHANGELOG.org +2 -2
- data/TAGS +48 -50
- data/exe/resme +0 -0
- data/lib/resme/cli.rb +5 -7
- data/lib/resme/document.rb +5 -17
- data/lib/resme/document_validator.rb +165 -209
- data/lib/resme/executor.rb +9 -4
- data/lib/resme/helper.rb +7 -8
- data/lib/resme/json_resume.rb +91 -87
- data/lib/resme/version.rb +1 -1
- data/lib/resme.rb +0 -2
- metadata +4 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 75fc73b4333ce4f6b51a02625a846fa6a7bdb16b0c53e0dc97bbcd0a1011f681
|
|
4
|
+
data.tar.gz: 38b29db1c99a03d07d29036985291f5181e4f0e92225824bf131b5e006faaa92
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 83f7f01cdd3c00932b7cdcb6cbe4e169c8f3a5129c06163582dfe6ecbfdd541b951c6812fa87836b26f30ecd4c8789dcea12f6fa8b212b7ef486b9b95cc1906e
|
|
7
|
+
data.tar.gz: d148e71395e5abf9b3ab39d4770cbed5da1f66a17ec35c061b194ceabce7f94021d8ac37af678394a4c0bad94329147f761d89b1a52409b96a5a77a0ee0c0450
|
data/CHANGELOG.org
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#+TITLE: CHANGELOG
|
|
2
2
|
#+AUTHOR: Adolfo Villafiorita
|
|
3
3
|
|
|
4
|
-
* Version 2.0.0
|
|
4
|
+
* Version 2.0.1 and 2.0.0
|
|
5
5
|
|
|
6
|
-
- Fully rewritten code
|
|
6
|
+
- Fully rewritten code (and rubocopped for most part)
|
|
7
7
|
- Removed export to Markdown (which can be gotten from Org Mode)
|
|
8
8
|
- Fixed JSON Resume export
|
|
9
9
|
- Added new keys and renamed some existing keys to make them closer to JSON Resume.
|
data/TAGS
CHANGED
|
@@ -1,14 +1,4 @@
|
|
|
1
1
|
|
|
2
|
-
/home/adolfo/Sources/ruby/resme/lib/resme/document.rb,292
|
|
3
|
-
module ResmeResme3,31
|
|
4
|
-
class DocumentDocument7,88
|
|
5
|
-
attr_reader :filename, :datafilename8,105
|
|
6
|
-
attr_reader :filename, :datadata8,105
|
|
7
|
-
def initialize(filename)initialize10,139
|
|
8
|
-
def dig(*keys)dig16,292
|
|
9
|
-
def fetch(*keys, default)fetch21,422
|
|
10
|
-
def loadload27,502
|
|
11
|
-
|
|
12
2
|
/home/adolfo/Sources/ruby/resme/test/test_helper.rb,0
|
|
13
3
|
|
|
14
4
|
/home/adolfo/Sources/ruby/resme/test/test_resme.rb,200
|
|
@@ -18,51 +8,54 @@ class TestResme < Minitest::TestTestResme5,54
|
|
|
18
8
|
|
|
19
9
|
/home/adolfo/Sources/ruby/resme/templates/org.erb,0
|
|
20
10
|
|
|
21
|
-
/home/adolfo/Sources/ruby/resme/lib/resme.rb,0
|
|
22
|
-
|
|
23
11
|
/home/adolfo/Sources/ruby/resme/templates/json.erb,0
|
|
24
12
|
|
|
25
|
-
/home/adolfo/Sources/ruby/resme/lib/resme
|
|
13
|
+
/home/adolfo/Sources/ruby/resme/lib/resme.rb,0
|
|
14
|
+
|
|
15
|
+
/home/adolfo/Sources/ruby/resme/lib/resme/json_resume.rb,196
|
|
26
16
|
module ResmeResme3,31
|
|
27
|
-
class
|
|
28
|
-
def initialize(document)initialize
|
|
29
|
-
def
|
|
30
|
-
|
|
31
|
-
OPTIONAL_PARTIAL_DATE = [:optional, Date, String, Integer, NilClass]OPTIONAL_PARTIAL_DATE33,678
|
|
32
|
-
PARTIAL_DATE = [Date, String, Integer]PARTIAL_DATE34,751
|
|
33
|
-
SCHEMA = {SCHEMA40,891
|
|
17
|
+
class JsonResumeJsonResume7,78
|
|
18
|
+
def initialize(document)initialize10,117
|
|
19
|
+
def buildbuild16,307
|
|
20
|
+
def split_highlights(highlights)split_highlights154,4638
|
|
34
21
|
|
|
35
22
|
/home/adolfo/Sources/ruby/resme/lib/resme/helper.rb,990
|
|
36
23
|
module ResmeResme3,31
|
|
37
24
|
module HelperHelper7,87
|
|
38
25
|
def clean(string)clean9,178
|
|
39
26
|
def full_name(data)full_name13,250
|
|
40
|
-
def reflow_a(string, line_break: 78)reflow_a
|
|
41
|
-
def blank?(char)blank?
|
|
42
|
-
def reflow_s(string, line_break: 75, delimiter: "\n", indent: 3)reflow_s
|
|
43
|
-
def period(entry, date: :date, from: :start_date, to: :end_date, separator: "--")period
|
|
44
|
-
def itemize(entry, header: %i[role who address], summary_key: :summary)itemize
|
|
45
|
-
def propertify(entry, except: %i[summary details], indent: 3)propertify
|
|
46
|
-
def select(contacts, label: :email)select
|
|
47
|
-
def format_date(date, format: "%Y-%m-%d")format_date
|
|
48
|
-
def complete_date(incomplete_date, format: "%Y-%m-%d")complete_date
|
|
49
|
-
def year(input)year181,
|
|
50
|
-
def month(input)month186,
|
|
51
|
-
def day(input)day191,
|
|
52
|
-
def y?(input)y?196,
|
|
53
|
-
def ym?(input)ym?201,
|
|
54
|
-
def ymd?(input)ymd?206,
|
|
27
|
+
def reflow_a(string, line_break: 78)reflow_a34,893
|
|
28
|
+
def blank?(char)blank?70,2086
|
|
29
|
+
def reflow_s(string, line_break: 75, delimiter: "\n", indent: 3)reflow_s77,2312
|
|
30
|
+
def period(entry, date: :date, from: :start_date, to: :end_date, separator: "--")period102,3285
|
|
31
|
+
def itemize(entry, header: %i[role who address], summary_key: :summary)itemize127,4040
|
|
32
|
+
def propertify(entry, except: %i[summary details], indent: 3)propertify138,4486
|
|
33
|
+
def select(contacts, label: :email)select148,4787
|
|
34
|
+
def format_date(date, format: "%Y-%m-%d")format_date164,5314
|
|
35
|
+
def complete_date(incomplete_date, format: "%Y-%m-%d")complete_date168,5428
|
|
36
|
+
def year(input)year181,5813
|
|
37
|
+
def month(input)month186,5931
|
|
38
|
+
def day(input)day191,6048
|
|
39
|
+
def y?(input)y?196,6186
|
|
40
|
+
def ym?(input)ym?201,6305
|
|
41
|
+
def ymd?(input)ymd?206,6423
|
|
55
42
|
|
|
56
|
-
/home/adolfo/Sources/ruby/resme/lib/resme/
|
|
43
|
+
/home/adolfo/Sources/ruby/resme/lib/resme/document.rb,219
|
|
57
44
|
module ResmeResme3,31
|
|
58
|
-
class
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
def
|
|
45
|
+
class DocumentDocument7,88
|
|
46
|
+
attr_reader :filename, :datafilename8,105
|
|
47
|
+
attr_reader :filename, :datadata8,105
|
|
48
|
+
def initialize(filename)initialize10,139
|
|
49
|
+
def loadload17,236
|
|
62
50
|
|
|
63
|
-
/home/adolfo/Sources/ruby/resme/lib/resme/
|
|
51
|
+
/home/adolfo/Sources/ruby/resme/lib/resme/executor.rb,295
|
|
64
52
|
module ResmeResme3,31
|
|
65
|
-
|
|
53
|
+
class ExecutorExecutor7,66
|
|
54
|
+
def initialize(input)initialize11,146
|
|
55
|
+
def executeexecute18,286
|
|
56
|
+
def output_filename(format)output_filename81,2240
|
|
57
|
+
def backup(filename)backup85,2328
|
|
58
|
+
def backup_and_write(filename, content)backup_and_write90,2469
|
|
66
59
|
|
|
67
60
|
/home/adolfo/Sources/ruby/resme/lib/resme/cli.rb,218
|
|
68
61
|
module ResmeResme3,31
|
|
@@ -71,13 +64,18 @@ module ResmeResme3,31
|
|
|
71
64
|
def initialize(arguments)initialize10,113
|
|
72
65
|
def parseparse15,257
|
|
73
66
|
def commandcommand20,332
|
|
74
|
-
def parserparser
|
|
67
|
+
def parserparser27,421
|
|
75
68
|
|
|
76
|
-
/home/adolfo/Sources/ruby/resme/lib/resme/
|
|
69
|
+
/home/adolfo/Sources/ruby/resme/lib/resme/document_validator.rb,442
|
|
70
|
+
module ResmeResme3,31
|
|
71
|
+
class DocumentValidatorDocumentValidator7,76
|
|
72
|
+
def initialize(document)initialize8,102
|
|
73
|
+
def validatevalidate12,167
|
|
74
|
+
OPTIONAL_STRING = [:optional, String, NilClass].freezeOPTIONAL_STRING30,576
|
|
75
|
+
OPTIONAL_PARTIAL_DATE = [:optional, Date, String, Integer, NilClass].freezeOPTIONAL_PARTIAL_DATE31,635
|
|
76
|
+
PARTIAL_DATE = [Date, String, Integer].freezePARTIAL_DATE32,715
|
|
77
|
+
SCHEMA = {SCHEMA38,862
|
|
78
|
+
|
|
79
|
+
/home/adolfo/Sources/ruby/resme/lib/resme/version.rb,57
|
|
77
80
|
module ResmeResme3,31
|
|
78
|
-
|
|
79
|
-
def initialize(input)initialize8,124
|
|
80
|
-
def executeexecute14,234
|
|
81
|
-
def output_filename(format)output_filename76,2176
|
|
82
|
-
def backup(filename)backup80,2264
|
|
83
|
-
def backup_and_write(filename, content)backup_and_write85,2405
|
|
81
|
+
VERSION = "2.0.1"VERSION4,44
|
data/exe/resme
CHANGED
|
File without changes
|
data/lib/resme/cli.rb
CHANGED
|
@@ -23,19 +23,16 @@ module Resme
|
|
|
23
23
|
|
|
24
24
|
private
|
|
25
25
|
|
|
26
|
+
# rubocop:disable Metrics
|
|
26
27
|
def parser
|
|
27
28
|
OptionParser.new do |parser|
|
|
28
29
|
parser.banner = "resme [options] - Format and manage a resume in YAML"
|
|
29
30
|
|
|
30
|
-
# parser.on("-o", "--output FILENAME", String, "Output filename") do |v|
|
|
31
|
-
# @options[:output] = v
|
|
32
|
-
# end
|
|
33
|
-
|
|
34
31
|
parser.on("--format FORMAT", String, "Output format") do |v|
|
|
35
32
|
@options[:format] = v
|
|
36
33
|
end
|
|
37
34
|
|
|
38
|
-
parser.on("--init", "Init a new resume") do |
|
|
35
|
+
parser.on("--init", "Init a new resume") do |_|
|
|
39
36
|
@options[:cmd] = :init
|
|
40
37
|
end
|
|
41
38
|
|
|
@@ -54,12 +51,12 @@ module Resme
|
|
|
54
51
|
@options[:filename] = v
|
|
55
52
|
end
|
|
56
53
|
|
|
57
|
-
parser.on("--list", "List available templates") do |
|
|
54
|
+
parser.on("--list", "List available templates") do |_|
|
|
58
55
|
@options[:cmd] = :list
|
|
59
56
|
end
|
|
60
57
|
|
|
61
58
|
parser.on("--except x,y,z", Array, "Excluded section") do |v|
|
|
62
|
-
@options[:except] = v.map
|
|
59
|
+
@options[:except] = v.map(&:to_sym)
|
|
63
60
|
end
|
|
64
61
|
|
|
65
62
|
parser.on("--cat TEMPLATE", "View a template") do |v|
|
|
@@ -76,5 +73,6 @@ module Resme
|
|
|
76
73
|
end
|
|
77
74
|
end
|
|
78
75
|
end
|
|
76
|
+
# rubocop:enable Metrics
|
|
79
77
|
end
|
|
80
78
|
end
|
data/lib/resme/document.rb
CHANGED
|
@@ -12,26 +12,14 @@ module Resme
|
|
|
12
12
|
@data = load
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
# Access values references by *keys. Keys are Symbols or Strings
|
|
16
|
-
def dig(*keys)
|
|
17
|
-
@data.dig keys.map { |x| x.to_s }
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
# Access values references by *keys. Default to "default"
|
|
21
|
-
def fetch(*keys, default)
|
|
22
|
-
dig(*keys) || default
|
|
23
|
-
end
|
|
24
|
-
|
|
25
15
|
private
|
|
26
16
|
|
|
27
17
|
def load
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
exit 1
|
|
34
|
-
end
|
|
18
|
+
YAML.load_file @filename, permitted_classes: [Date], symbolize_names: true
|
|
19
|
+
rescue Psych::SyntaxError => e
|
|
20
|
+
puts "#{@filename} has an invalid structure."
|
|
21
|
+
puts e.message
|
|
22
|
+
exit 1
|
|
35
23
|
end
|
|
36
24
|
end
|
|
37
25
|
end
|
|
@@ -10,28 +10,26 @@ module Resme
|
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
def validate
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
puts "- #{error[:full_path]}: #{error[:message]}"
|
|
28
|
-
end
|
|
13
|
+
errors = []
|
|
14
|
+
ClassyHash.validate(
|
|
15
|
+
@document.data,
|
|
16
|
+
SCHEMA,
|
|
17
|
+
errors: errors,
|
|
18
|
+
strict: true,
|
|
19
|
+
raise_errors: true,
|
|
20
|
+
full: true
|
|
21
|
+
)
|
|
22
|
+
errors
|
|
23
|
+
rescue StandardError => e
|
|
24
|
+
puts "#{@document.filename} does not validate:"
|
|
25
|
+
e.entries.each do |error|
|
|
26
|
+
puts "- #{error[:full_path]}: #{error[:message]}"
|
|
29
27
|
end
|
|
30
28
|
end
|
|
31
29
|
|
|
32
|
-
OPTIONAL_STRING = [:optional, String, NilClass]
|
|
33
|
-
OPTIONAL_PARTIAL_DATE = [:optional, Date, String, Integer, NilClass]
|
|
34
|
-
PARTIAL_DATE = [Date, String, Integer]
|
|
30
|
+
OPTIONAL_STRING = [:optional, String, NilClass].freeze
|
|
31
|
+
OPTIONAL_PARTIAL_DATE = [:optional, Date, String, Integer, NilClass].freeze
|
|
32
|
+
PARTIAL_DATE = [Date, String, Integer].freeze
|
|
35
33
|
|
|
36
34
|
#
|
|
37
35
|
# This defines the structure of resume.yml
|
|
@@ -49,260 +47,218 @@ module Resme
|
|
|
49
47
|
marital_status: OPTIONAL_STRING,
|
|
50
48
|
gender: OPTIONAL_STRING
|
|
51
49
|
},
|
|
52
|
-
contacts: [[
|
|
53
|
-
addresses: [[
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
}
|
|
63
|
-
]],
|
|
50
|
+
contacts: [[{ label: String, value: String }]],
|
|
51
|
+
addresses: [[{
|
|
52
|
+
label: String,
|
|
53
|
+
street: OPTIONAL_STRING,
|
|
54
|
+
postal_code: [:optional, String, Integer, NilClass],
|
|
55
|
+
city: OPTIONAL_STRING,
|
|
56
|
+
region: OPTIONAL_STRING,
|
|
57
|
+
country_code: OPTIONAL_STRING,
|
|
58
|
+
country: OPTIONAL_STRING
|
|
59
|
+
}]],
|
|
64
60
|
web_presence: [:optional,
|
|
65
|
-
[[
|
|
66
|
-
{
|
|
67
|
-
label: String,
|
|
68
|
-
value: String
|
|
69
|
-
},
|
|
70
|
-
]],
|
|
61
|
+
[[{ label: String, value: String }]],
|
|
71
62
|
NilClass
|
|
72
63
|
],
|
|
73
64
|
summary: OPTIONAL_STRING,
|
|
74
65
|
work: [:optional,
|
|
75
|
-
[[
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
},
|
|
86
|
-
]],
|
|
66
|
+
[[{
|
|
67
|
+
name: OPTIONAL_STRING,
|
|
68
|
+
url: OPTIONAL_STRING,
|
|
69
|
+
address: OPTIONAL_STRING,
|
|
70
|
+
end_date: OPTIONAL_PARTIAL_DATE,
|
|
71
|
+
start_date: OPTIONAL_PARTIAL_DATE,
|
|
72
|
+
position: String,
|
|
73
|
+
summary: String,
|
|
74
|
+
details: OPTIONAL_STRING
|
|
75
|
+
}]],
|
|
87
76
|
NilClass
|
|
88
77
|
],
|
|
89
78
|
teaching: [:optional,
|
|
90
|
-
[[
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
}
|
|
102
|
-
]],
|
|
79
|
+
[[{
|
|
80
|
+
name: String,
|
|
81
|
+
school: OPTIONAL_STRING,
|
|
82
|
+
address: OPTIONAL_STRING,
|
|
83
|
+
end_date: OPTIONAL_PARTIAL_DATE,
|
|
84
|
+
start_date: OPTIONAL_PARTIAL_DATE,
|
|
85
|
+
position: String,
|
|
86
|
+
subject: String,
|
|
87
|
+
summary: OPTIONAL_STRING,
|
|
88
|
+
details: OPTIONAL_STRING
|
|
89
|
+
}]],
|
|
103
90
|
NilClass
|
|
104
91
|
],
|
|
105
92
|
projects: [:optional,
|
|
106
|
-
[[
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
}
|
|
116
|
-
]],
|
|
93
|
+
[[{
|
|
94
|
+
name: String,
|
|
95
|
+
size: OPTIONAL_STRING,
|
|
96
|
+
stakeholder: OPTIONAL_STRING,
|
|
97
|
+
end_date: OPTIONAL_PARTIAL_DATE,
|
|
98
|
+
start_date: OPTIONAL_PARTIAL_DATE,
|
|
99
|
+
position: String,
|
|
100
|
+
summary: OPTIONAL_STRING
|
|
101
|
+
}]],
|
|
117
102
|
NilClass
|
|
118
103
|
],
|
|
119
104
|
other: [:optional,
|
|
120
|
-
[[
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
}
|
|
128
|
-
]],
|
|
105
|
+
[[{
|
|
106
|
+
name: OPTIONAL_STRING,
|
|
107
|
+
end_date: OPTIONAL_PARTIAL_DATE,
|
|
108
|
+
start_date: OPTIONAL_PARTIAL_DATE,
|
|
109
|
+
position: String,
|
|
110
|
+
summary: OPTIONAL_STRING
|
|
111
|
+
}]],
|
|
129
112
|
NilClass
|
|
130
113
|
],
|
|
131
114
|
committees: [:optional,
|
|
132
|
-
[[
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
}
|
|
139
|
-
]],
|
|
115
|
+
[[{
|
|
116
|
+
name: String,
|
|
117
|
+
position: String,
|
|
118
|
+
editions: [String, Integer],
|
|
119
|
+
url: OPTIONAL_STRING
|
|
120
|
+
}]],
|
|
140
121
|
NilClass
|
|
141
122
|
],
|
|
142
123
|
volunteer: [:optional,
|
|
143
|
-
[[
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
}
|
|
153
|
-
]],
|
|
124
|
+
[[{
|
|
125
|
+
name: String,
|
|
126
|
+
where: OPTIONAL_STRING,
|
|
127
|
+
date: OPTIONAL_PARTIAL_DATE,
|
|
128
|
+
end_date: OPTIONAL_PARTIAL_DATE,
|
|
129
|
+
start_date: OPTIONAL_PARTIAL_DATE,
|
|
130
|
+
position: String,
|
|
131
|
+
summary: OPTIONAL_STRING
|
|
132
|
+
}]],
|
|
154
133
|
NilClass
|
|
155
134
|
],
|
|
156
135
|
visits: [:optional,
|
|
157
|
-
[[
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
}
|
|
166
|
-
]],
|
|
136
|
+
[[{
|
|
137
|
+
name: String,
|
|
138
|
+
address: OPTIONAL_STRING,
|
|
139
|
+
end_date: OPTIONAL_PARTIAL_DATE,
|
|
140
|
+
start_date: OPTIONAL_PARTIAL_DATE,
|
|
141
|
+
position: String,
|
|
142
|
+
summary: OPTIONAL_STRING
|
|
143
|
+
}]],
|
|
167
144
|
NilClass
|
|
168
145
|
],
|
|
169
146
|
education: [:optional,
|
|
170
|
-
[[
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
}
|
|
183
|
-
]],
|
|
147
|
+
[[{
|
|
148
|
+
degree: OPTIONAL_STRING,
|
|
149
|
+
topic: OPTIONAL_STRING,
|
|
150
|
+
school: String,
|
|
151
|
+
address: OPTIONAL_STRING,
|
|
152
|
+
date: OPTIONAL_PARTIAL_DATE,
|
|
153
|
+
end_date: OPTIONAL_PARTIAL_DATE,
|
|
154
|
+
start_date: OPTIONAL_PARTIAL_DATE,
|
|
155
|
+
url: OPTIONAL_STRING,
|
|
156
|
+
publish: TrueClass,
|
|
157
|
+
score: [:optional, String, Integer, NilClass]
|
|
158
|
+
}]],
|
|
184
159
|
NilClass
|
|
185
160
|
],
|
|
186
161
|
publications: [:optional,
|
|
187
|
-
[[
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
}
|
|
195
|
-
]],
|
|
162
|
+
[[{
|
|
163
|
+
title: String,
|
|
164
|
+
authors: String,
|
|
165
|
+
publisher: String,
|
|
166
|
+
date: PARTIAL_DATE,
|
|
167
|
+
url: OPTIONAL_STRING
|
|
168
|
+
}]],
|
|
196
169
|
NilClass
|
|
197
170
|
],
|
|
198
171
|
talks: [:optional,
|
|
199
|
-
[[
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
}
|
|
206
|
-
]],
|
|
172
|
+
[[{
|
|
173
|
+
title: String,
|
|
174
|
+
venue: String,
|
|
175
|
+
date: PARTIAL_DATE,
|
|
176
|
+
url: OPTIONAL_STRING
|
|
177
|
+
}]],
|
|
207
178
|
NilClass
|
|
208
179
|
],
|
|
209
180
|
awards: [:optional,
|
|
210
|
-
[[
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
}
|
|
218
|
-
]],
|
|
181
|
+
[[{
|
|
182
|
+
name: String,
|
|
183
|
+
address: OPTIONAL_STRING,
|
|
184
|
+
date: PARTIAL_DATE,
|
|
185
|
+
title: String,
|
|
186
|
+
summary: OPTIONAL_STRING
|
|
187
|
+
}]],
|
|
219
188
|
NilClass
|
|
220
189
|
],
|
|
221
190
|
achievements: [:optional,
|
|
222
|
-
[[
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
}
|
|
230
|
-
]],
|
|
191
|
+
[[{
|
|
192
|
+
name: String,
|
|
193
|
+
address: OPTIONAL_STRING,
|
|
194
|
+
date: OPTIONAL_PARTIAL_DATE,
|
|
195
|
+
title: String,
|
|
196
|
+
summary: OPTIONAL_STRING
|
|
197
|
+
}]],
|
|
231
198
|
NilClass
|
|
232
199
|
],
|
|
233
200
|
software: [:optional,
|
|
234
|
-
[[
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
}
|
|
243
|
-
]],
|
|
201
|
+
[[{
|
|
202
|
+
title: String,
|
|
203
|
+
url: OPTIONAL_STRING,
|
|
204
|
+
programming_language: OPTIONAL_STRING,
|
|
205
|
+
license: OPTIONAL_STRING,
|
|
206
|
+
position: OPTIONAL_STRING,
|
|
207
|
+
summary: OPTIONAL_STRING
|
|
208
|
+
}]],
|
|
244
209
|
NilClass
|
|
245
210
|
],
|
|
246
211
|
skills: [:optional,
|
|
247
|
-
[[
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
}
|
|
253
|
-
]],
|
|
212
|
+
[[{
|
|
213
|
+
name: String,
|
|
214
|
+
level: OPTIONAL_STRING,
|
|
215
|
+
summary: OPTIONAL_STRING
|
|
216
|
+
}]],
|
|
254
217
|
NilClass
|
|
255
218
|
],
|
|
256
219
|
driving: [:optional,
|
|
257
|
-
[[
|
|
220
|
+
[[{ license: String }]],
|
|
258
221
|
NilClass
|
|
259
222
|
],
|
|
260
223
|
languages: [:optional,
|
|
261
224
|
{
|
|
262
|
-
mother_tongues: [[
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
language: String,
|
|
225
|
+
mother_tongues: [[{
|
|
226
|
+
code: OPTIONAL_STRING,
|
|
227
|
+
language: String,
|
|
266
228
|
}
|
|
267
229
|
]],
|
|
268
230
|
foreign: [:optional,
|
|
269
|
-
[[
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
}
|
|
280
|
-
]],
|
|
231
|
+
[[{
|
|
232
|
+
code: OPTIONAL_STRING,
|
|
233
|
+
language: String,
|
|
234
|
+
level: OPTIONAL_STRING,
|
|
235
|
+
listening: OPTIONAL_STRING,
|
|
236
|
+
reading: OPTIONAL_STRING,
|
|
237
|
+
spoken_interaction: OPTIONAL_STRING,
|
|
238
|
+
spoken_production: OPTIONAL_STRING,
|
|
239
|
+
writing: OPTIONAL_STRING
|
|
240
|
+
}]],
|
|
281
241
|
NilClass
|
|
282
242
|
]
|
|
283
243
|
},
|
|
284
244
|
NilClass
|
|
285
245
|
],
|
|
286
246
|
interests: [:optional,
|
|
287
|
-
[[
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
}
|
|
293
|
-
]],
|
|
247
|
+
[[{
|
|
248
|
+
name: String,
|
|
249
|
+
level: OPTIONAL_STRING,
|
|
250
|
+
summary: OPTIONAL_STRING
|
|
251
|
+
}]],
|
|
294
252
|
NilClass
|
|
295
253
|
],
|
|
296
254
|
references: [:optional,
|
|
297
|
-
[[
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
}
|
|
303
|
-
]],
|
|
255
|
+
[[{
|
|
256
|
+
name: String,
|
|
257
|
+
reference: String,
|
|
258
|
+
contacts: [[{ label: String, value: String }]]
|
|
259
|
+
}]],
|
|
304
260
|
NilClass
|
|
305
261
|
]
|
|
306
|
-
}
|
|
262
|
+
}.freeze
|
|
307
263
|
end
|
|
308
264
|
end
|
data/lib/resme/executor.rb
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Resme
|
|
4
|
+
#
|
|
5
|
+
# Execute!
|
|
6
|
+
#
|
|
4
7
|
class Executor
|
|
5
8
|
# include all formatter helpers
|
|
6
9
|
include Resme::Helper
|
|
@@ -11,12 +14,13 @@ module Resme
|
|
|
11
14
|
@options.parse
|
|
12
15
|
end
|
|
13
16
|
|
|
17
|
+
# rubocop:disable Metrics
|
|
14
18
|
def execute
|
|
15
19
|
case @options.command
|
|
16
20
|
when :init
|
|
17
21
|
resume_template = File.join __dir__, "../../templates/resume.yml"
|
|
18
22
|
puts File.read resume_template
|
|
19
|
-
|
|
23
|
+
|
|
20
24
|
when :validate
|
|
21
25
|
filename = @options.options[:filename]
|
|
22
26
|
document = Document.new(filename)
|
|
@@ -26,7 +30,7 @@ module Resme
|
|
|
26
30
|
when :sections
|
|
27
31
|
filename = @options.options[:filename]
|
|
28
32
|
keys = Document.new(filename).data.keys
|
|
29
|
-
puts keys
|
|
33
|
+
puts keys
|
|
30
34
|
|
|
31
35
|
when :build
|
|
32
36
|
filename = @options.options[:filename]
|
|
@@ -44,7 +48,7 @@ module Resme
|
|
|
44
48
|
js = JsonResume.new Document.new(filename)
|
|
45
49
|
@json_resume = js.build
|
|
46
50
|
end
|
|
47
|
-
|
|
51
|
+
|
|
48
52
|
output = ERB.new(template, trim_mode: "-").result(binding)
|
|
49
53
|
|
|
50
54
|
# it is difficult to write readable ERBs with no empty lines... we use
|
|
@@ -70,6 +74,7 @@ module Resme
|
|
|
70
74
|
|
|
71
75
|
end
|
|
72
76
|
end
|
|
77
|
+
# rubocop:enable Metrics
|
|
73
78
|
|
|
74
79
|
private
|
|
75
80
|
|
|
@@ -78,7 +83,7 @@ module Resme
|
|
|
78
83
|
end
|
|
79
84
|
|
|
80
85
|
def backup(filename)
|
|
81
|
-
FileUtils
|
|
86
|
+
FileUtils.cp "filename, "#{filename}~"
|
|
82
87
|
puts "Backup copy #{filename} created in #{filename}~."
|
|
83
88
|
end
|
|
84
89
|
|
data/lib/resme/helper.rb
CHANGED
|
@@ -30,6 +30,7 @@ module Resme
|
|
|
30
30
|
# Special cases: if one line is longer than chars characters, then break at
|
|
31
31
|
# the first space after chars
|
|
32
32
|
#
|
|
33
|
+
# rubocop:disable Metrics/AbcSize
|
|
33
34
|
def reflow_a(string, line_break: 78)
|
|
34
35
|
# if the string is less than line_break chars, we are done
|
|
35
36
|
return [clean(string)] if string.length < line_break
|
|
@@ -45,7 +46,7 @@ module Resme
|
|
|
45
46
|
reflow_a(string[(index + 1)..], line_break:)
|
|
46
47
|
end
|
|
47
48
|
end
|
|
48
|
-
|
|
49
|
+
|
|
49
50
|
# here the string does not have a space between 0 and line_break
|
|
50
51
|
#
|
|
51
52
|
# In this case we try to break at the first blank after the string and
|
|
@@ -57,18 +58,19 @@ module Resme
|
|
|
57
58
|
reflow_a(string[(index + 1)..], line_break:)
|
|
58
59
|
end
|
|
59
60
|
end
|
|
60
|
-
|
|
61
|
+
|
|
61
62
|
# here string is longer than line_break and it does not have spaces
|
|
62
63
|
#
|
|
63
64
|
# The only thing left to do is returning the string as it is
|
|
64
65
|
#
|
|
65
66
|
[clean(string)]
|
|
66
67
|
end
|
|
68
|
+
# rubocop:enable Metrics/AbcSize
|
|
67
69
|
|
|
68
70
|
def blank?(char)
|
|
69
71
|
[" ", "\t", "\n"].include?(char)
|
|
70
72
|
end
|
|
71
|
-
|
|
73
|
+
|
|
72
74
|
# Reflow at +line_break+, returning a string with each line delimited by
|
|
73
75
|
# +delimiter+ (by default newline) and indented with +indent+ spaces.
|
|
74
76
|
#
|
|
@@ -152,7 +154,7 @@ module Resme
|
|
|
152
154
|
# Utility functions for managing dates in the form 2015-01-01 and partial
|
|
153
155
|
# dates (e.g., 2015-05, 2015)
|
|
154
156
|
#
|
|
155
|
-
|
|
157
|
+
|
|
156
158
|
# Format the input as a date, according to format. If the input is not
|
|
157
159
|
# a date, return it as it (assuming it represents a partial date (e.g.,
|
|
158
160
|
# 2012-01, 2012
|
|
@@ -172,8 +174,6 @@ module Resme
|
|
|
172
174
|
"#{incomplete_date}-01"
|
|
173
175
|
elsif y?(incomplete_date.to_s)
|
|
174
176
|
"#{incomplete_date}-01-01"
|
|
175
|
-
else
|
|
176
|
-
nil
|
|
177
177
|
end
|
|
178
178
|
end
|
|
179
179
|
|
|
@@ -191,7 +191,7 @@ module Resme
|
|
|
191
191
|
def day(input)
|
|
192
192
|
input.is_a?(Date) ? input.strftime("%d") : input.to_s[8..9]
|
|
193
193
|
end
|
|
194
|
-
|
|
194
|
+
|
|
195
195
|
# Is the input in the form YYYY-MM(-..)
|
|
196
196
|
def y?(input)
|
|
197
197
|
input.is_a?(Date) || input.to_s.size == 4
|
|
@@ -208,4 +208,3 @@ module Resme
|
|
|
208
208
|
end
|
|
209
209
|
end
|
|
210
210
|
end
|
|
211
|
-
|
data/lib/resme/json_resume.rb
CHANGED
|
@@ -6,151 +6,155 @@ module Resme
|
|
|
6
6
|
#
|
|
7
7
|
class JsonResume
|
|
8
8
|
include Helper
|
|
9
|
-
|
|
9
|
+
|
|
10
10
|
def initialize(document)
|
|
11
11
|
@document = document
|
|
12
12
|
@data = document.data
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
+
# rubocop:disable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity, Metrics/AbcSize
|
|
15
16
|
def build
|
|
16
17
|
address = @data[:addresses]&.first || {}
|
|
17
|
-
|
|
18
|
+
education = @data[:education].select { |x| x[:publish] } || []
|
|
19
|
+
|
|
18
20
|
{
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
21
|
+
basics: {
|
|
22
|
+
name: full_name(@data),
|
|
23
|
+
label: @data[:basics][:title],
|
|
24
|
+
image: "",
|
|
25
|
+
email: select(@data[:contacts], label: :email),
|
|
26
|
+
phone: select(@data[:contacts], label: :phone),
|
|
27
|
+
url: select(@data[:web_presence], label: :url),
|
|
28
|
+
summary: @data[:summary],
|
|
29
|
+
location: {
|
|
30
|
+
address: address[:street],
|
|
31
|
+
postalCode: address[:postal_code].to_s,
|
|
32
|
+
city: address[:city],
|
|
33
|
+
countryCode: address[:country_code],
|
|
34
|
+
region: address[:region]
|
|
33
35
|
}.compact,
|
|
34
|
-
|
|
36
|
+
profiles: @data[:web_presence].map do |kv|
|
|
35
37
|
{
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
#
|
|
38
|
+
network: kv[:label],
|
|
39
|
+
username: kv[:value]
|
|
40
|
+
# url:
|
|
39
41
|
}
|
|
40
42
|
end.compact
|
|
41
43
|
}.compact,
|
|
42
44
|
|
|
43
|
-
|
|
45
|
+
work: @data[:work].map do |elem|
|
|
44
46
|
{
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
47
|
+
name: elem[:name],
|
|
48
|
+
position: elem[:position],
|
|
49
|
+
url: elem[:url],
|
|
50
|
+
startDate: complete_date(elem[:date] || elem[:start_date]),
|
|
51
|
+
endDate: complete_date(elem[:date] || elem[:end_date]),
|
|
52
|
+
summary: elem[:summary],
|
|
53
|
+
highlights: split_highlights(elem[:details])
|
|
52
54
|
}.compact
|
|
53
55
|
end,
|
|
54
56
|
|
|
55
|
-
|
|
57
|
+
volunteer: (@data[:volunteer] || []).map do |elem|
|
|
56
58
|
{
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
59
|
+
organization: elem[:name],
|
|
60
|
+
position: elem[:position],
|
|
61
|
+
startDate: complete_date(elem[:date] || elem[:start_date]),
|
|
62
|
+
endDate: complete_date(elem[:date] || elem[:end_date]),
|
|
63
|
+
summary: elem[:summary],
|
|
64
|
+
highlights: split_highlights(elem[:details])
|
|
63
65
|
}.compact
|
|
64
66
|
end,
|
|
65
67
|
|
|
66
|
-
|
|
68
|
+
education: education.map do |elem|
|
|
67
69
|
{
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
70
|
+
institution: elem[:school],
|
|
71
|
+
url: elem[:url],
|
|
72
|
+
area: elem[:topic],
|
|
73
|
+
studyType: elem[:degree],
|
|
74
|
+
startDate: complete_date(elem[:date] || elem[:start_date]),
|
|
75
|
+
endDate: complete_date(elem[:date] || elem[:end_date]),
|
|
76
|
+
score: elem[:score],
|
|
77
|
+
courses: []
|
|
76
78
|
}.compact
|
|
77
79
|
end,
|
|
78
80
|
|
|
79
|
-
|
|
81
|
+
awards: (@data[:awards] || []).map do |elem|
|
|
80
82
|
{
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
83
|
+
title: elem[:title],
|
|
84
|
+
date: complete_date(elem[:date]),
|
|
85
|
+
awarder: elem[:name],
|
|
86
|
+
summary: elem[:summary]
|
|
85
87
|
}.compact
|
|
86
88
|
end,
|
|
87
89
|
|
|
88
|
-
|
|
90
|
+
certificates: [],
|
|
89
91
|
|
|
90
|
-
|
|
92
|
+
publications: (@data[:publications] || []).map do |elem|
|
|
91
93
|
{
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
94
|
+
name: [elem[:title], elem[:authors]].compact.join(", "),
|
|
95
|
+
publisher: elem[:publisher],
|
|
96
|
+
releaseDate: complete_date(elem[:date]),
|
|
97
|
+
url: elem[:url],
|
|
98
|
+
summary: ""
|
|
97
99
|
}.compact
|
|
98
100
|
end,
|
|
99
|
-
|
|
100
|
-
|
|
101
|
+
|
|
102
|
+
skills: (@data[:skills] || []).map do |elem|
|
|
101
103
|
{
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
104
|
+
name: elem[:name],
|
|
105
|
+
level: elem[:level],
|
|
106
|
+
keywords: split_highlights(elem[:summary])
|
|
105
107
|
}.compact
|
|
106
108
|
end,
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
{
|
|
110
|
-
|
|
111
|
-
|
|
109
|
+
|
|
110
|
+
languages: (@data.dig(:languages, :mother_tongues) || []).map do |elem|
|
|
111
|
+
{
|
|
112
|
+
language: elem[:language],
|
|
113
|
+
fluency: "Native speaker"
|
|
112
114
|
}.compact
|
|
113
|
-
end + (@data.dig(:languages, :foreign) || []).map do |
|
|
114
|
-
{
|
|
115
|
-
|
|
116
|
-
|
|
115
|
+
end + (@data.dig(:languages, :foreign) || []).map do |elem|
|
|
116
|
+
{
|
|
117
|
+
language: elem[:language],
|
|
118
|
+
fluency: elem[:level]
|
|
117
119
|
}.compact
|
|
118
120
|
end,
|
|
119
121
|
|
|
120
|
-
|
|
122
|
+
interests: (@data[:interests] || []).map do |elem|
|
|
121
123
|
{
|
|
122
|
-
|
|
123
|
-
|
|
124
|
+
name: elem[:name],
|
|
125
|
+
keywords: split_highlights(elem[:summary])
|
|
124
126
|
}.compact
|
|
125
127
|
end,
|
|
126
|
-
|
|
127
|
-
|
|
128
|
+
|
|
129
|
+
references: (@data[:references] || []).map do |elem|
|
|
128
130
|
{
|
|
129
|
-
|
|
130
|
-
|
|
131
|
+
name: elem[:name],
|
|
132
|
+
reference: elem[:reference]
|
|
131
133
|
}.compact
|
|
132
134
|
end,
|
|
133
|
-
|
|
134
|
-
|
|
135
|
+
|
|
136
|
+
projects: (@data[:projects] || []).map do |elem|
|
|
135
137
|
{
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
138
|
+
name: elem[:name],
|
|
139
|
+
url: elem[:url],
|
|
140
|
+
startDate: complete_date(elem[:date] || elem[:start_date]),
|
|
141
|
+
endDate: complete_date(elem[:date] || elem[:end_date]),
|
|
142
|
+
description: elem[:summary],
|
|
143
|
+
highlights: []
|
|
142
144
|
}.compact
|
|
143
145
|
end
|
|
144
146
|
}.compact
|
|
145
147
|
end
|
|
148
|
+
# rubocop:enable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity, Metrics/AbcSize
|
|
149
|
+
|
|
146
150
|
|
|
147
151
|
private
|
|
148
152
|
|
|
149
153
|
# make a string with an itemized list into an array of the items
|
|
150
154
|
def split_highlights(highlights)
|
|
151
155
|
(highlights || "").split(/^ *- /)
|
|
152
|
-
|
|
153
|
-
|
|
156
|
+
.map { |x| x.gsub("\n", "") }
|
|
157
|
+
.reject { |x| x == "" }
|
|
154
158
|
end
|
|
155
159
|
end
|
|
156
160
|
end
|
data/lib/resme/version.rb
CHANGED
data/lib/resme.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: resme
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.0.
|
|
4
|
+
version: 2.0.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Adolfo Villafiorita
|
|
@@ -23,9 +23,9 @@ dependencies:
|
|
|
23
23
|
- - ">="
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
25
|
version: '0'
|
|
26
|
-
description:
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
description: Manage your resume in YAML and publish with Org Mode or JSON resume.Org
|
|
27
|
+
Mode provides HTML, TXT, LaTeX, Markdown exports.JSON Resume comes with many ready-made
|
|
28
|
+
templates.
|
|
29
29
|
email:
|
|
30
30
|
- adolfo@shair.tech
|
|
31
31
|
executables:
|