friends 0.12 → 0.13

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b6fbeed1512a5fb14b7a89e5afebe885e48817ea
4
- data.tar.gz: e4fa97ba906eb037fc70da65704aa33a456e0a99
3
+ metadata.gz: 844eb360bcc04aed352a8b3c3371117afb18f564
4
+ data.tar.gz: db2feb8fbf5a15232b6b5923218dc8d7cff4ded1
5
5
  SHA512:
6
- metadata.gz: 883ef235fc6d26aec8bc03ac5a72794e643f1d7d501944a5e5c587bf0451ed55320562b1188161616cd88e1c952ddfccce746d8a369cf05a080d0bd6cda5b2d3
7
- data.tar.gz: 51557fe1705cf9d812087c5b7b3d5397517f48232a56668267ce8000d94301b7208b430dbf9f97c67694a50ce09f4d079b6f57e9033b084f6f10a0fe928c788b
6
+ metadata.gz: c3eb0061ba85b5dcc7eb1fa9f7d0dc1c711834b4b128b37d789252b5293b290e95de4553f55cb57a585dee1cf077e87c7b2d8fa6e5806f7ed8520227287e3e9a
7
+ data.tar.gz: cac077cacd2c4a0309b5614e1952dd65b55f0c22b7d23ed619cda4c6637f282284c0c236ff1a16ed83a4fd9ecc3bcfe434755f3c46f87c241fd8073990deda7d
@@ -8,7 +8,7 @@ Alias:
8
8
  Enabled: false
9
9
 
10
10
  AllCops:
11
- RunRailsCops: false
11
+ TargetRubyVersion: 2.3
12
12
 
13
13
  AmbiguousOperator:
14
14
  Enabled: false
@@ -149,6 +149,9 @@ MethodLength:
149
149
  ModuleFunction:
150
150
  Enabled: false
151
151
 
152
+ MutableConstant:
153
+ Enabled: true
154
+
152
155
  NegatedIf:
153
156
  Enabled: false
154
157
 
@@ -196,6 +199,9 @@ PredicateName:
196
199
  Proc:
197
200
  Enabled: false
198
201
 
202
+ Rails:
203
+ Enabled: false
204
+
199
205
  RaiseArgs:
200
206
  Enabled: false
201
207
 
@@ -232,8 +238,11 @@ Style/MultilineBlockChain:
232
238
  VariableInterpolation:
233
239
  Enabled: false
234
240
 
235
- TrailingComma:
236
- Enabled: false
241
+ TrailingCommaInArguments:
242
+ Enabled: true
243
+
244
+ TrailingCommaInLiteral:
245
+ Enabled: true
237
246
 
238
247
  TrivialAccessors:
239
248
  Enabled: false
@@ -1,5 +1,21 @@
1
1
  # Change Log
2
2
 
3
+ ## [v0.13](https://github.com/JacobEvelyn/friends/tree/v0.13) (2016-01-21)
4
+ [Full Changelog](https://github.com/JacobEvelyn/friends/compare/v0.12...v0.13)
5
+
6
+ **Fixed bugs:**
7
+
8
+ - Treat double names as a single name [\#80](https://github.com/JacobEvelyn/friends/issues/80)
9
+
10
+ **Closed issues:**
11
+
12
+ - 4 RuboCop errors prevent git commit [\#78](https://github.com/JacobEvelyn/friends/issues/78)
13
+
14
+ **Merged pull requests:**
15
+
16
+ - Improve handling of double-names and names within names [\#81](https://github.com/JacobEvelyn/friends/pull/81) ([JacobEvelyn](https://github.com/JacobEvelyn))
17
+ - Update RuboCop and fix many offenses [\#79](https://github.com/JacobEvelyn/friends/pull/79) ([bloomyminded](https://github.com/bloomyminded))
18
+
3
19
  ## [v0.12](https://github.com/JacobEvelyn/friends/tree/v0.12) (2016-01-16)
4
20
  [Full Changelog](https://github.com/JacobEvelyn/friends/compare/v0.11...v0.12)
5
21
 
@@ -24,23 +24,25 @@ subcommand_option_handling :normal
24
24
  arguments :strict
25
25
 
26
26
  switch [:quiet],
27
- negatable: false,
28
- desc: "Quiet output messages"
27
+ negatable: false,
28
+ desc: "Quiet output messages"
29
29
 
30
30
  flag [:filename],
31
- arg_name: "FILENAME",
32
- default_value: "./friends.md",
33
- desc: "Set the location of the friends file"
31
+ arg_name: "FILENAME",
32
+ default_value: "./friends.md",
33
+ desc: "Set the location of the friends file"
34
34
 
35
35
  switch [:debug],
36
- negatable: false,
37
- desc: "Debug error messages with a full backtrace"
36
+ negatable: false,
37
+ desc: "Debug error messages with a full backtrace"
38
38
 
39
39
  desc "Updates the `friends` program"
40
40
  command :update do |update|
41
41
  update.action do
42
42
  search = `gem search friends`
43
+ # rubocop:disable Lint/AssignmentInCondition
43
44
  if match = search.match(/^friends\s\(([^\)]+)\)$/)
45
+ # rubocop:enable Lint/AssignmentInCondition
44
46
  remote_version = match[1]
45
47
  if Semverse::Version.coerce(remote_version) >
46
48
  Semverse::Version.coerce(Friends::VERSION)
@@ -71,9 +73,9 @@ command :list do |list|
71
73
  list.desc "List favorite friends"
72
74
  list.command :favorites do |list_favorites|
73
75
  list_favorites.flag [:limit],
74
- arg_name: "NUMBER",
75
- default_value: 10,
76
- desc: "The number of friends to return"
76
+ arg_name: "NUMBER",
77
+ default_value: 10,
78
+ desc: "The number of friends to return"
77
79
 
78
80
  list_favorites.action do |_, options|
79
81
  limit = options[:limit].to_i
@@ -95,13 +97,13 @@ command :list do |list|
95
97
  list.desc "Lists all activities"
96
98
  list.command :activities do |list_activities|
97
99
  list_activities.flag [:limit],
98
- arg_name: "NUMBER",
99
- default_value: 10,
100
- desc: "The number of activities to return"
100
+ arg_name: "NUMBER",
101
+ default_value: 10,
102
+ desc: "The number of activities to return"
101
103
 
102
104
  list_activities.flag [:with],
103
- arg_name: "NAME",
104
- desc: "List only activities involving the given friend"
105
+ arg_name: "NAME",
106
+ desc: "List only activities involving the given friend"
105
107
 
106
108
  list_activities.action do |_, options|
107
109
  limit = options[:limit].to_i
@@ -172,7 +174,7 @@ command :graph do |graph|
172
174
 
173
175
  colors = (0...(6 * 7)).map do |n|
174
176
  n *= 1.0 / 6
175
- r = (3 * Math.sin(n ) + 3).to_i
177
+ r = (3 * Math.sin(n) + 3).to_i
176
178
  g = (3 * Math.sin(n + 2 * PI_3) + 3).to_i
177
179
  b = (3 * Math.sin(n + 4 * PI_3) + 3).to_i
178
180
 
@@ -9,7 +9,8 @@ Gem::Specification.new do |spec|
9
9
  spec.authors = ["Jacob Evelyn"]
10
10
  spec.email = ["jacobevelyn@gmail.com"]
11
11
  spec.summary = "Spend time with the people you care about."
12
- spec.description = "Spend time with the people you care about. Introvert-tested. Extrovert-approved."
12
+ spec.description = "Spend time with the people you care about. "\
13
+ "Introvert-tested. Extrovert-approved."
13
14
  spec.homepage = "https://github.com/JacobEvelyn/friends"
14
15
  spec.license = "MIT"
15
16
 
@@ -31,5 +32,5 @@ Gem::Specification.new do |spec|
31
32
  spec.add_development_dependency "minitest", "~> 5.5"
32
33
  spec.add_development_dependency "overcommit", "~> 0.30"
33
34
  spec.add_development_dependency "rake", "~> 10.0"
34
- spec.add_development_dependency "rubocop", "~> 0.35"
35
+ spec.add_development_dependency "rubocop", "~> 0.36"
35
36
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  # Activity represents an activity you've done with one or more Friends.
2
3
 
3
4
  require "memoist"
@@ -10,11 +11,14 @@ module Friends
10
11
  extend Serializable
11
12
  extend Memoist
12
13
 
13
- SERIALIZATION_PREFIX = "- "
14
+ SERIALIZATION_PREFIX = "- ".freeze
14
15
 
15
16
  # @return [Regexp] the regex for capturing groups in deserialization
16
17
  def self.deserialization_regex
18
+ # Note: this regex must be on one line because whitespace is important
19
+ # rubocop:disable Metrics/LineLength
17
20
  /(#{SERIALIZATION_PREFIX})?((?<date_s>\d{4}-\d\d-\d\d)(:\s)?)?(?<description>.+)?/
21
+ # rubocop:enable Metrics/LineLength
18
22
  end
19
23
 
20
24
  # @return [Regexp] the string of what we expected during deserialization
@@ -37,7 +41,9 @@ module Friends
37
41
  def display_text
38
42
  date_s = Paint[date, :bold]
39
43
  description_s = description.to_s
44
+ # rubocop:disable Lint/AssignmentInCondition
40
45
  while match = description_s.match(/(\*\*)([^\*]+)(\*\*)/)
46
+ # rubocop:enable Lint/AssignmentInCondition
41
47
  description_s = "#{match.pre_match}"\
42
48
  "#{Paint[match[2], :bold, :magenta]}"\
43
49
  "#{match.post_match}"
@@ -61,41 +67,31 @@ module Friends
61
67
  # more information see the comments below and the
62
68
  # introvert#set_likelihood_score! method.
63
69
  def highlight_friends(introvert:)
64
- friend_regexes = introvert.friend_regex_map
65
-
66
- # Create hash mapping regex to friend. Note that because two friends may
67
- # have the same regex (e.g. /John/), we need to store the names in an
68
- # array since there may be more than one. We also iterate through the
69
- # regexes to add the most important regexes to the hash first, so
70
- # "Jacob Evelyn" takes precedence over all instances of "Jacob" (since
71
- # Ruby hashes are ordered).
72
- regex_map = Hash.new { |h, k| h[k] = [] }
73
- while !friend_regexes.empty?
74
- friend_regexes.each do |friend, regex_list|
75
- regex_map[regex_list.shift] << friend
76
- friend_regexes.delete(friend) if regex_list.empty?
77
- end
78
- end
70
+ # Split the regex friend map into two maps: one for names with only one
71
+ # friend match and another for ambiguous names
72
+ definite_map, ambiguous_map =
73
+ introvert.regex_friend_map.partition { |_, arr| arr.size == 1 }
79
74
 
80
75
  matched_friends = []
81
76
 
82
- # First, we find all of the regex matches with only one possibility, and
83
- # make those substitutions.
84
- regex_map.
85
- select { |_, arr| arr.size == 1 }.each do |regex, friend_list|
86
- if @description.match(regex)
77
+ # First, we find all of the unambiguous matches, and make those
78
+ # substitutions.
79
+ definite_map.each do |regex, friend_list|
80
+ # If we find a match, add the friend to the matched list and replace all
81
+ # instances of the matching text with the friend's name.
82
+ description_matches(regex: regex, replace: true) do
87
83
  friend = friend_list.first # There's only one friend in the list.
88
84
  matched_friends << friend
89
- @description.gsub!(regex, "**#{friend.name}**")
85
+ friend.name
90
86
  end
91
87
  end
92
88
 
93
89
  possible_matched_friends = []
94
90
 
95
91
  # Now, we look at regex matches that are ambiguous.
96
- regex_map.
97
- reject { |_, arr| arr.size == 1 }.each do |regex, friend_list|
98
- if @description.match(regex)
92
+ ambiguous_map.each do |regex, friend_list|
93
+ # If we find a match, add the friend to the possible-match list.
94
+ description_matches(regex: regex, replace: false) do
99
95
  possible_matched_friends << friend_list
100
96
  end
101
97
  end
@@ -107,21 +103,20 @@ module Friends
107
103
  possible_matches: possible_matched_friends
108
104
  )
109
105
 
110
- # Now we go through and replace all of the ambiguous matches with our best
111
- # guess.
112
- regex_map.
113
- reject { |_, arr| arr.size == 1 }.each do |regex, friend_list|
114
- if @description.match(regex)
115
- guessed_friend = friend_list.sort_by do |friend|
106
+ # Now we replace all of the ambiguous matches with our best guesses.
107
+ ambiguous_map.each do |regex, friend_list|
108
+ # If we find a match, take the most likely and replace all instances of
109
+ # the matching text with that friend's name.
110
+ description_matches(regex: regex, replace: true) do
111
+ friend_list.sort_by do |friend|
116
112
  [-friend.likelihood_score, -friend.n_activities]
117
- end.first
118
- @description.gsub!(regex, "**#{guessed_friend.name}**")
113
+ end.first.name
119
114
  end
120
115
  end
121
116
 
122
117
  # Lastly, we remove any backslashes, as these are used to escape friends'
123
118
  # names that we don't want to match.
124
- @description.delete!("\\")
119
+ @description = @description.delete("\\")
125
120
  end
126
121
 
127
122
  # Updates a friend's old_name to their new_name
@@ -150,6 +145,45 @@ module Friends
150
145
 
151
146
  private
152
147
 
148
+ # This method accepts a block, and tests a regex on the @description
149
+ # instance variable.
150
+ # - If the regex does not match, the block is not executed.
151
+ # - If the regex matches, the block is executed exactly once, and:
152
+ # - If `replace` is true, all of the regex's matches are replaced by the
153
+ # return value of the block, EXCEPT when the matched text is between a
154
+ # set of double-asterisks ("**") indicating it is already part of
155
+ # another friend's matched name.
156
+ # - If `replace` is not true, we do not modify @description.
157
+ # @param regex [Regexp] the regex to test against @description
158
+ # @param replace [Boolean] true iff we should replace regex matches with the
159
+ # yielded block's result in @description
160
+ def description_matches(regex:, replace:)
161
+ # rubocop:disable Lint/AssignmentInCondition
162
+ return unless match = @description.match(regex) # Abort if no match.
163
+ # rubocop:enable Lint/AssignmentInCondition
164
+ str = yield # It's important to execute the block even if not replacing.
165
+ return unless replace # Only continue if we want to replace text.
166
+
167
+ position = 0 # Prevent infinite looping by tracking last match position.
168
+ loop do
169
+ # Only make a replacement if we're not between a set of "**"s.
170
+ if match.pre_match.scan("**").size % 2 == 0 &&
171
+ match.post_match.scan("**").size % 2 == 0
172
+ @description = "#{match.pre_match}**#{str}**#{match.post_match}"
173
+ else
174
+ # If we're between double-asterisks we're already part of a name, so
175
+ # we don't make a substitution. We update `position` to avoid infinite
176
+ # looping.
177
+ position = match.end(0)
178
+ end
179
+
180
+ # Exit when there are no more matches.
181
+ # rubocop:disable Lint/AssignmentInCondition
182
+ break unless match = @description.match(regex, position)
183
+ # rubocop:enable Lint/AssignmentInCondition
184
+ end
185
+ end
186
+
153
187
  # Default sorting for an array of activities is reverse-date.
154
188
  def <=>(other)
155
189
  other.date <=> date
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  # Friend represents a friend. You know, a real-life friend!
2
3
 
3
4
  require "friends/serializable"
@@ -6,12 +7,15 @@ module Friends
6
7
  class Friend
7
8
  extend Serializable
8
9
 
9
- SERIALIZATION_PREFIX = "- "
10
- NICKNAME_PREFIX = "a.k.a. "
10
+ SERIALIZATION_PREFIX = "- ".freeze
11
+ NICKNAME_PREFIX = "a.k.a. ".freeze
11
12
 
12
13
  # @return [Regexp] the regex for capturing groups in deserialization
13
14
  def self.deserialization_regex
15
+ # Note: this regex must be on one line because whitespace is important
16
+ # rubocop:disable Metrics/LineLength
14
17
  /(#{SERIALIZATION_PREFIX})?(?<name>[^\(]+)(\((?<nickname_str>#{NICKNAME_PREFIX}.+)\))?/
18
+ # rubocop:enable Metrics/LineLength
15
19
  end
16
20
 
17
21
  # @return [Regexp] the string of what we expected during deserialization
@@ -31,7 +35,7 @@ module Friends
31
35
 
32
36
  # @return [String] the file serialization text for the friend
33
37
  def serialize
34
- "#{SERIALIZATION_PREFIX}#{to_s}"
38
+ "#{SERIALIZATION_PREFIX}#{self}"
35
39
  end
36
40
 
37
41
  # @return [String] a string representing the friend's name and nicknames
@@ -83,13 +87,12 @@ module Friends
83
87
  @likelihood_score || 0
84
88
  end
85
89
 
86
- # @return [Array] a list of all regexes to match the name in a string, with
87
- # longer regexes first
88
- # Note: for now we only match on full names or first names
90
+ # @return [Array] a list of all regexes to match the name in a string
89
91
  # Example: [
90
92
  # /Jacob\s+Morris\s+Evelyn/,
91
93
  # /Jacob/
92
94
  # ]
95
+ # NOTE: For now we only match on full names or first names.
93
96
  def regexes_for_name
94
97
  # We generously allow any amount of whitespace between parts of a name.
95
98
  splitter = "\\s+"
@@ -100,6 +103,10 @@ module Friends
100
103
 
101
104
  # We don't want to match names that are directly touching double asterisks
102
105
  # as these are treated as sacred by our program.
106
+ # NOTE: Technically we don't need this check here, since we perform a more
107
+ # complex asterisk check in the Activity#description_matches method, but
108
+ # this class shouldn't need to know about the internal implementation of
109
+ # another class.
103
110
  no_leading_asterisks = "(?<!\\*\\*)"
104
111
  no_ending_asterisks = "(?!\\*\\*)"
105
112
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  # Introvert is the internal handler for the friends script. It is designed to be
2
3
  # able to be used directly within another Ruby program, without needing to call
3
4
  # the command-line script explicitly.
@@ -8,10 +9,10 @@ require "friends/friends_error"
8
9
 
9
10
  module Friends
10
11
  class Introvert
11
- DEFAULT_FILENAME = "./friends.md"
12
- ACTIVITIES_HEADER = "### Activities:"
13
- FRIENDS_HEADER = "### Friends:"
14
- GRAPH_DATE_FORMAT = "%b %Y" # Used as the param for date.strftime().
12
+ DEFAULT_FILENAME = "./friends.md".freeze
13
+ ACTIVITIES_HEADER = "### Activities:".freeze
14
+ FRIENDS_HEADER = "### Friends:".freeze
15
+ GRAPH_DATE_FORMAT = "%b %Y".freeze # Used as the param for date.strftime().
15
16
 
16
17
  # @param filename [String] the name of the friends Markdown file
17
18
  def initialize(filename: DEFAULT_FILENAME)
@@ -250,12 +251,15 @@ module Friends
250
251
  end
251
252
  end
252
253
 
253
- # @return [Hash] mapping each friend to a list of all possible regexes for
254
- # that friend's name
255
- def friend_regex_map
256
- @friends.each_with_object({}) do |friend, hash|
257
- hash[friend] = friend.regexes_for_name
258
- end
254
+ # @return [Hash] of the form { /regex/ => [list of friends matching regex] }
255
+ # This hash is sorted (because Ruby's hashes are ordered) by decreasing
256
+ # regex key length, so the key /Jacob Evelyn/ appears before /Jacob/.
257
+ def regex_friend_map
258
+ @friends.each_with_object(Hash.new { |h, k| h[k] = [] }) do |friend, hash|
259
+ friend.regexes_for_name.each do |regex|
260
+ hash[regex] << friend
261
+ end
262
+ end.sort_by { |k, _| -k.to_s.size }.to_h
259
263
  end
260
264
 
261
265
  # Sets the likelihood_score field on each friend in `possible_matches`. This
@@ -274,13 +278,13 @@ module Friends
274
278
  # description, for instance, is "John Deere" vs. "John Doe"
275
279
  def set_likelihood_score!(matches:, possible_matches:)
276
280
  combinations = (matches + possible_matches.flatten).
277
- combination(2).
278
- reject do |friend1, friend2|
279
- (matches & [friend1, friend2]).size == 2 ||
280
- possible_matches.any? do |group|
281
- (group & [friend1, friend2]).size == 2
282
- end
283
- end
281
+ combination(2).
282
+ reject do |friend1, friend2|
283
+ (matches & [friend1, friend2]).size == 2 ||
284
+ possible_matches.any? do |group|
285
+ (group & [friend1, friend2]).size == 2
286
+ end
287
+ end
284
288
 
285
289
  @activities.each do |activity|
286
290
  names = activity.friend_names
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Friends
2
- VERSION = "0.12"
3
+ VERSION = "0.13".freeze
3
4
  end
@@ -135,6 +135,54 @@ describe Friends::Activity do
135
135
  end
136
136
  end
137
137
 
138
+ describe "when one name ends another after a hyphen" do
139
+ let(:friend1) { Friends::Friend.new(name: "Mary-Kate Olsen") }
140
+ let(:friend2) { Friends::Friend.new(name: "Kate Winslet") }
141
+ let(:description) { "Shopping with Mary-Kate." }
142
+
143
+ it "gives precedence to the larger name" do
144
+ # Make sure "Kate" is a closer friend than "Mary-Kate" so we know our
145
+ # test result isn't due to chance.
146
+ friend1.n_activities = 0
147
+ friend2.n_activities = 10
148
+
149
+ subject
150
+ activity.description.must_equal "Shopping with **Mary-Kate Olsen**."
151
+ end
152
+ end
153
+
154
+ describe "when one name preceeds another before a hyphen" do
155
+ let(:friend1) { Friends::Friend.new(name: "Mary-Kate Olsen") }
156
+ let(:friend2) { Friends::Friend.new(name: "Mary Poppins") }
157
+ let(:description) { "Shopping with Mary-Kate." }
158
+
159
+ it "gives precedence to the larger name" do
160
+ # Make sure "Kate" is a closer friend than "Mary-Kate" so we know our
161
+ # test result isn't due to chance.
162
+ friend1.n_activities = 0
163
+ friend2.n_activities = 10
164
+
165
+ subject
166
+ activity.description.must_equal "Shopping with **Mary-Kate Olsen**."
167
+ end
168
+ end
169
+
170
+ describe "when one name is contained within another via a hyphen" do
171
+ let(:friend1) { Friends::Friend.new(name: "Mary-Jo-Kate Olsen") }
172
+ let(:friend2) { Friends::Friend.new(name: "Jo Stafford") }
173
+ let(:description) { "Shopping with Mary-Jo-Kate." }
174
+
175
+ it "gives precedence to the larger name" do
176
+ # Make sure "Kate" is a closer friend than "Mary-Kate" so we know our
177
+ # test result isn't due to chance.
178
+ friend1.n_activities = 0
179
+ friend2.n_activities = 10
180
+
181
+ subject
182
+ activity.description.must_equal "Shopping with **Mary-Jo-Kate Olsen**."
183
+ end
184
+ end
185
+
138
186
  describe "when name is at end of word" do
139
187
  let(:description) { "Field trip to the JimJohn Co." }
140
188
  it "does not match a friend" do
@@ -2,8 +2,10 @@ require "./test/helper"
2
2
 
3
3
  describe Friends::Introvert do
4
4
  # Add readers to make internal state easier to test.
5
- class Friends::Introvert
6
- attr_reader :filename, :activities, :friends
5
+ module Friends
6
+ class Introvert
7
+ attr_reader :filename, :activities, :friends
8
+ end
7
9
  end
8
10
 
9
11
  # Add helpers to set internal states for friends and activities.
@@ -318,7 +320,8 @@ describe Friends::Introvert do
318
320
  after { File.delete(filename) if File.exists?(filename) }
319
321
 
320
322
  it "returns the modified friend" do
321
- friend = Friends::Friend.new(name: "Jeff", nickname_str: "a.k.a. The Dude")
323
+ friend = Friends::Friend.new(name: "Jeff",
324
+ nickname_str: "a.k.a. The Dude")
322
325
  stub_friends([friend]) do
323
326
  subject.must_equal friend
324
327
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: friends
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.12'
4
+ version: '0.13'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jacob Evelyn
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-16 00:00:00.000000000 Z
11
+ date: 2016-01-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: gli
@@ -142,14 +142,14 @@ dependencies:
142
142
  requirements:
143
143
  - - "~>"
144
144
  - !ruby/object:Gem::Version
145
- version: '0.35'
145
+ version: '0.36'
146
146
  type: :development
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
150
  - - "~>"
151
151
  - !ruby/object:Gem::Version
152
- version: '0.35'
152
+ version: '0.36'
153
153
  description: Spend time with the people you care about. Introvert-tested. Extrovert-approved.
154
154
  email:
155
155
  - jacobevelyn@gmail.com