friends 0.28 → 0.29

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 (53) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +4 -4
  3. data/.ruby-version +1 -1
  4. data/.travis.yml +2 -0
  5. data/CHANGELOG.md +13 -0
  6. data/README.md +35 -5
  7. data/Rakefile +1 -1
  8. data/bin/friends +7 -379
  9. data/friends.gemspec +3 -1
  10. data/lib/friends/activity.rb +4 -4
  11. data/lib/friends/commands/add.rb +64 -0
  12. data/lib/friends/commands/clean.rb +9 -0
  13. data/lib/friends/commands/edit.rb +12 -0
  14. data/lib/friends/commands/graph.rb +56 -0
  15. data/lib/friends/commands/list.rb +143 -0
  16. data/lib/friends/commands/remove.rb +27 -0
  17. data/lib/friends/commands/rename.rb +30 -0
  18. data/lib/friends/commands/set.rb +14 -0
  19. data/lib/friends/commands/stats.rb +11 -0
  20. data/lib/friends/commands/suggest.rb +20 -0
  21. data/lib/friends/commands/update.rb +29 -0
  22. data/lib/friends/graph.rb +7 -7
  23. data/lib/friends/introvert.rb +23 -18
  24. data/lib/friends/version.rb +1 -1
  25. data/test/commands/add/activity_spec.rb +379 -0
  26. data/test/commands/add/friend_spec.rb +30 -0
  27. data/test/commands/add/location_spec.rb +30 -0
  28. data/test/commands/add/nickname_spec.rb +50 -0
  29. data/test/commands/add/tag_spec.rb +65 -0
  30. data/test/commands/clean_spec.rb +39 -0
  31. data/test/commands/graph_spec.rb +147 -0
  32. data/test/commands/help_spec.rb +45 -0
  33. data/test/commands/list/activities_spec.rb +136 -0
  34. data/test/commands/list/favorite/friends_spec.rb +77 -0
  35. data/test/commands/list/favorite/locations_spec.rb +82 -0
  36. data/test/commands/list/friends_spec.rb +76 -0
  37. data/test/commands/list/locations_spec.rb +35 -0
  38. data/test/commands/list/tags_spec.rb +58 -0
  39. data/test/commands/remove/nickname_spec.rb +63 -0
  40. data/test/commands/remove/tag_spec.rb +64 -0
  41. data/test/commands/rename/friend_spec.rb +55 -0
  42. data/test/commands/rename/location_spec.rb +43 -0
  43. data/test/commands/set/location_spec.rb +54 -0
  44. data/test/commands/stats_spec.rb +41 -0
  45. data/test/commands/suggest_spec.rb +86 -0
  46. data/test/commands/update_spec.rb +13 -0
  47. data/test/helper.rb +114 -0
  48. metadata +89 -15
  49. data/test/activity_spec.rb +0 -597
  50. data/test/friend_spec.rb +0 -241
  51. data/test/graph_spec.rb +0 -92
  52. data/test/introvert_spec.rb +0 -969
  53. data/test/location_spec.rb +0 -60
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 31ada45e644c5d8473d57a70508d64f360dd3541
4
- data.tar.gz: dc6d98844de09d8bfd8110dbe1fd0b2b468a6711
3
+ metadata.gz: 266cfedd5b0654ca5ebd434c11ead3d8c21d4e9e
4
+ data.tar.gz: 76d290e42cc9babe0dcfe3dd9419dded6ca4825d
5
5
  SHA512:
6
- metadata.gz: fd6409785d7d579a2ba0106757572970a28b5e23eb52c2e7c1dd227fbeeed92f7107c75f8780c3d6f397332b3ce41d23d0af3394f812d993e17147724814ed87
7
- data.tar.gz: 3a9d5fa932b44adc0a27d4d73044d5eefb060cd6a363e4934d19d0274668d171eaab2f08914732bbcbd9da467ab1b31d65a3e82ac551e532191dc8e832f5ca4b
6
+ metadata.gz: 41e311c6cd3f8dc4a0c9e86d5268badad683731307626f6f50ef33eaf15edfc930754adce617f2934262b6915caa87b3167b138741b3e6b99025d0c4cc542a06
7
+ data.tar.gz: e838474558ec1a065cd7d72a828fb6073adafac32a6aec23b4bc6e930063f5838e55129d9a6d82d01bf0236a79777db936a31a32b15104fce83cdd3c146e1c5c
data/.rubocop.yml CHANGED
@@ -74,9 +74,6 @@ Delegate:
74
74
  DeprecatedClassMethods:
75
75
  Enabled: false
76
76
 
77
- DeprecatedHashMethods:
78
- Enabled: false
79
-
80
77
  Documentation:
81
78
  Enabled: false
82
79
 
@@ -132,7 +129,7 @@ LineEndConcatenation:
132
129
  Enabled: false
133
130
 
134
131
  LineLength:
135
- Max: 80
132
+ Max: 100
136
133
 
137
134
  LiteralInCondition:
138
135
  Enabled: false
@@ -146,6 +143,9 @@ Loop:
146
143
  MethodLength:
147
144
  Enabled: false
148
145
 
146
+ Metrics/BlockLength:
147
+ Enabled: false
148
+
149
149
  ModuleFunction:
150
150
  Enabled: false
151
151
 
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.3.0
1
+ 2.4.0
data/.travis.yml CHANGED
@@ -1,7 +1,9 @@
1
1
  language: ruby
2
2
  rvm:
3
3
  - 2.1.0
4
+ - 2.2.0
4
5
  - 2.3.0
6
+ - 2.4.0
5
7
  script:
6
8
  - bundle exec rake test
7
9
  - bundle exec rubocop
data/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # Change Log
2
2
 
3
+ ## [v0.29](https://github.com/JacobEvelyn/friends/tree/v0.29) (2017-03-18)
4
+ [Full Changelog](https://github.com/JacobEvelyn/friends/compare/v0.28...v0.29)
5
+
6
+ **Implemented enhancements:**
7
+
8
+ - Add `--since \<date\>` and `--until \<date\>` flags, and remove extraneous months from `graph` [\#153](https://github.com/JacobEvelyn/friends/issues/153)
9
+ - Add integration tests for bin/friends? [\#127](https://github.com/JacobEvelyn/friends/issues/127)
10
+
11
+ **Merged pull requests:**
12
+
13
+ - Add --since and --until flags to `graph` and `list activities` [\#157](https://github.com/JacobEvelyn/friends/pull/157) ([JacobEvelyn](https://github.com/JacobEvelyn))
14
+ - Restructuring [\#155](https://github.com/JacobEvelyn/friends/pull/155) ([JacobEvelyn](https://github.com/JacobEvelyn))
15
+
3
16
  ## [v0.28](https://github.com/JacobEvelyn/friends/tree/v0.28) (2016-06-25)
4
17
  [Full Changelog](https://github.com/JacobEvelyn/friends/compare/v0.27...v0.28)
5
18
 
data/README.md CHANGED
@@ -42,7 +42,7 @@ lots of help), and give feedback!**
42
42
  - `rename`
43
43
  - [`rename friend`](#rename-friend)
44
44
  - [`rename location`](#rename-location)
45
- - [`set location`](#set)
45
+ - [`set location`](#set-location)
46
46
  - [`stats`](#stats)
47
47
  - [`suggest`](#suggest)
48
48
  - [`update`](#update)
@@ -55,9 +55,8 @@ lots of help), and give feedback!**
55
55
 
56
56
  ## Overview
57
57
 
58
- `friends` is both a Ruby library and a command-line interface that
59
- allows you to keep track of your relationships with the people you
60
- care about.
58
+ `friends` is a command-line program that helps you to keep track of your relationships with the
59
+ people you care about.
61
60
 
62
61
  `friends` gives you:
63
62
  - More organization around staying in touch with friends and
@@ -364,10 +363,27 @@ Jan 2015 |
364
363
  Feb 2015 |█
365
364
  ```
366
365
 
366
+ Or graph only activities on or after a certain date:
367
+
368
+ ```bash
369
+ $ friends graph --since 'January 1st 2015'
370
+ Jan 2015 |███████
371
+ Feb 2015 |█████
372
+ ```
373
+
374
+ Or graph only activities before or on a certain date:
375
+
376
+ ```bash
377
+ $ friends graph --until 'January 1st 2015'
378
+ Nov 2014 |███
379
+ Dec 2014 |██
380
+ Jan 2015 |███████
381
+ ```
382
+
367
383
  And you can use multiple of these flags together:
368
384
 
369
385
  ```bash
370
- $ friends graph --in Paris --tagged food --with George
386
+ $ friends graph --in Paris --tagged food --with George --after 'September 2014'
371
387
  Nov 2014 |█
372
388
  ```
373
389
 
@@ -441,6 +457,20 @@ $ friends list activities --tagged food
441
457
  2015-01-04: Got lunch with Grace Hopper and George Washington Carver. @food
442
458
  ```
443
459
 
460
+ Or by date:
461
+
462
+ ```bash
463
+ $ friends graph --since 'December 31st 2014'
464
+ 2015-01-04: Got lunch with Grace Hopper and George Washington Carver. @food
465
+ 2014-12-31: Celebrated the new year with Marie Curie in New York City. @partying
466
+ ```
467
+
468
+ ```bash
469
+ $ friends graph --until 'December 31st 2014'
470
+ 2014-12-31: Celebrated the new year with Marie Curie in New York City. @partying
471
+ 2014-11-15: Talked to George Washington Carver on the phone for an hour.
472
+ ```
473
+
444
474
  And you can mix and match these options to your heart's content:
445
475
 
446
476
  ```bash
data/Rakefile CHANGED
@@ -4,7 +4,7 @@ require "bundler/gem_tasks"
4
4
  require "rake/testtask"
5
5
 
6
6
  Rake::TestTask.new do |t|
7
- t.test_files = FileList["test/*_spec.rb"]
7
+ t.test_files = FileList["test/**/*_spec.rb"]
8
8
  end
9
9
 
10
10
  task default: :test
data/bin/friends CHANGED
@@ -39,6 +39,12 @@ end
39
39
  class Stripped; end
40
40
  accept(Stripped, &:strip)
41
41
 
42
+ class InputDate; end
43
+ accept(InputDate) do |value|
44
+ time = Chronic.parse(value)
45
+ time && time.to_date
46
+ end
47
+
42
48
  switch [:quiet],
43
49
  negatable: false,
44
50
  desc: "Quiet output messages"
@@ -56,385 +62,7 @@ switch [:colorless],
56
62
  negatable: false,
57
63
  desc: "Disable output colorization and other effects"
58
64
 
59
- desc "Updates the `friends` program"
60
- command :update do |update|
61
- update.action do
62
- # rubocop:disable Lint/AssignmentInCondition
63
- if match = `gem search friends`.match(/^friends\s\(([^\)]+)\)$/)
64
- # rubocop:enable Lint/AssignmentInCondition
65
- remote_version = match[1]
66
- if Semverse::Version.coerce(remote_version) >
67
- Semverse::Version.coerce(Friends::VERSION)
68
- `gem update friends && gem cleanup friends`
69
- if $?.success?
70
- @message = Paint[
71
- "Updated to friends #{remote_version}", :bold, :green
72
- ]
73
- else
74
- @message = Paint[
75
- "Error updating to friends version #{remote_version}", :bold, :red
76
- ]
77
- end
78
- else
79
- @message = Paint[
80
- "Already up-to-date (#{Friends::VERSION})", :bold, :green
81
- ]
82
- end
83
- end
84
- end
85
- end
86
-
87
- desc "Opens the `friends.md` file in $EDITOR for manual editing"
88
- command :edit do |edit|
89
- edit.action do |global_options|
90
- editor = ENV["EDITOR"] || "vim"
91
- filename = global_options[:filename]
92
-
93
- puts "Opening \"#{filename}\" in #{editor}" unless global_options[:quiet]
94
- Kernel.exec "#{editor} #{filename}"
95
- end
96
- end
97
-
98
- desc "Lists friends, activities, and locations"
99
- command :list do |list|
100
- list.desc "List all friends"
101
- list.command :friends do |list_friends|
102
- list_friends.flag [:in],
103
- arg_name: "LOCATION",
104
- desc: "List only friends in the given location",
105
- type: Stripped
106
-
107
- list_friends.flag [:tagged],
108
- arg_name: "@TAG",
109
- desc: "List only friends with the given tag",
110
- type: Tag
111
-
112
- list_friends.switch [:verbose],
113
- negatable: false,
114
- desc: "Output friend nicknames, locations, and tags"
115
-
116
- list_friends.action do |_, options|
117
- puts @introvert.list_friends(
118
- location_name: options[:in],
119
- tagged: options[:tagged],
120
- verbose: options[:verbose]
121
- )
122
- end
123
- end
124
-
125
- list.desc "Lists all activities"
126
- list.command :activities do |list_activities|
127
- list_activities.flag [:limit],
128
- arg_name: "NUMBER",
129
- desc: "The number of activities to return",
130
- default_value: 10,
131
- type: Integer
132
-
133
- list_activities.flag [:with],
134
- arg_name: "NAME",
135
- desc: "List only activities with the given friend",
136
- type: Stripped
137
-
138
- list_activities.flag [:in],
139
- arg_name: "LOCATION",
140
- desc: "List only activities in the given location",
141
- type: Stripped
142
-
143
- list_activities.flag [:tagged],
144
- arg_name: "@TAG",
145
- desc: "List only activities with the given tag",
146
- type: Tag
147
-
148
- list_activities.action do |_, options|
149
- puts @introvert.list_activities(
150
- limit: options[:limit],
151
- with: options[:with],
152
- location_name: options[:in],
153
- tagged: options[:tagged]
154
- )
155
- end
156
- end
157
-
158
- list.desc "List all locations"
159
- list.command :locations do |list_locations|
160
- list_locations.action do
161
- puts @introvert.list_locations
162
- end
163
- end
164
-
165
- list.desc "List all tags used"
166
- list.command :tags do |list_tags|
167
- list_tags.flag [:from],
168
- arg_name: '"activities" or "friends" (default: both)',
169
- desc: "List only tags from activities or friends instead of"\
170
- "both"
171
- list_tags.action do |_, options|
172
- puts @introvert.list_tags(from: options[:from])
173
- end
174
- end
175
-
176
- list.desc "List favorite friends and locations"
177
- list.command :favorite do |list_favorite|
178
- list_favorite.desc "List favorite friends"
179
- list_favorite.command :friends do |list_favorite_friends|
180
- list_favorite_friends.flag [:limit],
181
- arg_name: "NUMBER",
182
- desc: "The number of friends to return",
183
- default_value: 10,
184
- type: Integer
185
-
186
- list_favorite_friends.action do |_, options|
187
- favorites = @introvert.list_favorite_friends(limit: options[:limit])
188
-
189
- if options[:limit] == 1
190
- puts "Your best friend is #{favorites.first}"
191
- else
192
- puts "Your favorite friends:"
193
-
194
- num_str_size = favorites.size.to_s.size + 1
195
- favorites.each.with_index(1) do |name, rank|
196
- puts "#{"#{rank}.".ljust(num_str_size)} #{name}"
197
- end
198
- end
199
- end
200
- end
201
-
202
- list_favorite.desc "List favorite locations"
203
- list_favorite.command :locations do |list_favorite_locations|
204
- list_favorite_locations.flag [:limit],
205
- arg_name: "NUMBER",
206
- desc: "The number of locations to return",
207
- default_value: 10,
208
- type: Integer
209
-
210
- list_favorite_locations.action do |_, options|
211
- favorites = @introvert.list_favorite_locations(limit: options[:limit])
212
-
213
- if options[:limit] == 1
214
- puts "Your favorite location is #{favorites.first}"
215
- else
216
- puts "Your favorite locations:"
217
-
218
- num_str_size = favorites.size.to_s.size + 1
219
- favorites.each.with_index(1) do |name, rank|
220
- puts "#{"#{rank}.".ljust(num_str_size)} #{name}"
221
- end
222
- end
223
- end
224
- end
225
- end
226
- end
227
-
228
- desc "Adds a friend (or nickname), activity, or location"
229
- command :add do |add|
230
- add.desc "Adds a friend"
231
- add.arg_name "NAME"
232
- add.command :friend do |add_friend|
233
- add_friend.action do |_, _, args|
234
- friend = @introvert.add_friend(name: args.join(" "))
235
- @message = "Friend added: \"#{friend.name}\""
236
- @dirty = true # Mark the file for cleaning.
237
- end
238
- end
239
-
240
- add.desc "Adds an activity"
241
- add.arg_name "DESCRIPTION"
242
- add.command :activity do |add_activity|
243
- add_activity.action do |_, _, args|
244
- activity = @introvert.add_activity(serialization: args.join(" "))
245
-
246
- # If there's no description, prompt the user for one.
247
- if activity.description.nil? || activity.description.empty?
248
- activity.description = Readline.readline(activity.to_s)
249
- activity.highlight_description(introvert: @introvert)
250
- end
251
-
252
- @message = "Activity added: \"#{activity}\""
253
- @dirty = true # Mark the file for cleaning.
254
- end
255
- end
256
-
257
- add.desc "Adds a location"
258
- add.arg_name "LOCATION"
259
- add.command :location do |add_location|
260
- add_location.action do |_, _, args|
261
- location = @introvert.add_location(name: args.join(" "))
262
- @message = "Location added: \"#{location.name}\""
263
- @dirty = true # Mark the file for cleaning.
264
- end
265
- end
266
-
267
- add.desc "Adds a nickname to a friend"
268
- add.arg_name "NAME NICKNAME"
269
- add.command :nickname do |add_nickname|
270
- add_nickname.action do |_, _, args|
271
- friend = @introvert.add_nickname(name: args.first, nickname: args[1])
272
- @message = "Nickname added: \"#{friend}\""
273
- @dirty = true # Mark the file for cleaning.
274
- end
275
- end
276
-
277
- add.desc "Adds a tag to a friend"
278
- add.arg_name "NAME @TAG"
279
- add.command :tag do |add_tag|
280
- add_tag.action do |_, _, args|
281
- friend = @introvert.add_tag(
282
- name: args[0..-2].join(" "),
283
- tag: Tag.convert_to_tag(args.last)
284
- )
285
- @message = "Tag added to friend: \"#{friend}\""
286
- @dirty = true # Mark the file for cleaning.
287
- end
288
- end
289
- end
290
-
291
- desc "Set data about friends"
292
- command :set do |set|
293
- set.desc "Set a friend's location"
294
- set.arg_name "NAME LOCATION"
295
- set.command :location do |set_location|
296
- set_location.action do |_, _, args|
297
- friend = @introvert.set_location(name: args.first, location_name: args[1])
298
- @message = "#{friend.name}'s location set to: #{friend.location_name}"
299
- @dirty = true # Mark the file for cleaning.
300
- end
301
- end
302
- end
303
-
304
- desc "Remove a nickname"
305
- command :remove do |remove|
306
- remove.desc "Removes a nickname from a friend"
307
- remove.arg_name "NAME NICKNAME"
308
- remove.command :nickname do |remove_nickname|
309
- remove_nickname.action do |_, _, args|
310
- friend = @introvert.remove_nickname(name: args.first, nickname: args[1])
311
- @message = "Nickname removed: \"#{friend}\""
312
- @dirty = true # Mark the file for cleaning.
313
- end
314
- end
315
-
316
- remove.desc "Removes a tag from a friend"
317
- remove.arg_name "NAME @TAG"
318
- remove.command :tag do |remove_tag|
319
- remove_tag.action do |_, _, args|
320
- friend = @introvert.remove_tag(
321
- name: args[0..-2].join(" "),
322
- tag: Tag.convert_to_tag(args.last)
323
- )
324
- @message = "Tag removed from friend: \"#{friend}\""
325
- @dirty = true # Mark the file for cleaning.
326
- end
327
- end
328
- end
329
-
330
- desc "Graph activities over time"
331
- command :graph do |graph|
332
- graph.flag [:with],
333
- arg_name: "NAME",
334
- desc: "Graph activities with the given friend",
335
- type: Stripped
336
-
337
- graph.flag [:in],
338
- arg_name: "LOCATION",
339
- desc: "Graph activities in the given location",
340
- type: Stripped
341
-
342
- graph.flag [:tagged],
343
- arg_name: "@TAG",
344
- desc: "Graph activities with the given tag",
345
- type: Tag
346
-
347
- graph.action do |_, options|
348
- # This math is taken from Minitest's Pride plugin (the PrideLOL class).
349
- PI_3 = Math::PI / 3
350
-
351
- colors = (0...(6 * 7)).map do |n|
352
- n *= 1.0 / 6
353
- r = (3 * Math.sin(n) + 3).to_i
354
- g = (3 * Math.sin(n + 2 * PI_3) + 3).to_i
355
- b = (3 * Math.sin(n + 4 * PI_3) + 3).to_i
356
-
357
- [r, g, b].map { |c| c * 51 }
358
- end
359
-
360
- data = @introvert.graph(
361
- with: options[:with],
362
- location_name: options[:in],
363
- tagged: options[:tagged]
364
- )
365
-
366
- data.each do |month, count|
367
- print "#{month} |"
368
- puts colors.take(count).map { |rgb| Paint["█", rgb] }.join
369
- end
370
- end
371
- end
372
-
373
- desc "Suggest friends to do activities with"
374
- command :suggest do |suggest|
375
- suggest.flag [:in],
376
- arg_name: "LOCATION",
377
- desc: "Suggest only friends in the given location",
378
- type: Stripped
379
-
380
- suggest.action do |_, options|
381
- suggestions = @introvert.suggest(location_name: options[:in])
382
-
383
- puts "Distant friend: "\
384
- "#{Paint[suggestions[:distant].sample || 'None found', :bold, :magenta]}"
385
- puts "Moderate friend: "\
386
- "#{Paint[suggestions[:moderate].sample || 'None found', :bold, :magenta]}"
387
- puts "Close friend: "\
388
- "#{Paint[suggestions[:close].sample || 'None found', :bold, :magenta]}"
389
- end
390
- end
391
-
392
- desc "Cleans your friends.md file"
393
- command :clean do |clean|
394
- clean.action do
395
- @clean_command = true
396
- @dirty = true # Mark the file for cleaning.
397
- end
398
- end
399
-
400
- desc "List all stats"
401
- command :stats do |stats|
402
- stats.action do
403
- puts "Total activities: #{@introvert.total_activities}"
404
- puts "Total friends: #{@introvert.total_friends}"
405
- days = @introvert.elapsed_days
406
- puts "Total time elapsed: #{days} day#{'s' if days != 1}"
407
- end
408
- end
409
-
410
- desc "Renames a friend or location"
411
- command :rename do |rename|
412
- rename.desc "Renames a friend"
413
- rename.arg_name "NAME NEW_NAME"
414
- rename.command :friend do |rename_friend|
415
- rename_friend.action do |_, _, args|
416
- friend = @introvert.rename_friend(
417
- old_name: args.first,
418
- new_name: args[1]
419
- )
420
- @message = "Name changed: \"#{friend}\""
421
- @dirty = true # Mark the file for cleaning.
422
- end
423
- end
424
-
425
- rename.desc "Renames a location"
426
- rename.arg_name "NAME NEW_NAME"
427
- rename.command :location do |rename_location|
428
- rename_location.action do |_, _, args|
429
- location = @introvert.rename_location(
430
- old_name: args.first,
431
- new_name: args[1]
432
- )
433
- @message = "Location renamed: \"#{location.name}\""
434
- @dirty = true # Mark the file for cleaning.
435
- end
436
- end
437
- end
65
+ commands_from "friends/commands"
438
66
 
439
67
  # Before each command, clean up all arguments and create the global Introvert.
440
68
  pre do |global_options, cmd, options|