friends 0.35 → 0.36

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: 850118ba419db4de89e23cd279ea57d0e9c7305b
4
- data.tar.gz: a4440dc2489f1756eaaa22ff395909d85abbf471
3
+ metadata.gz: 7c26333d51f189dc3c73e8619857ef1d18ebb85f
4
+ data.tar.gz: 1444055713076b43e7cc0cb20b9da27af110a1f4
5
5
  SHA512:
6
- metadata.gz: 643172f6f2be216b21bbc47e43fb17ee712c3d2e9ba092cff0cec4657e29391739712c9d3bb6b6d6811fabf8a77626c91a43cba7bb7e86a1e33b3d6326183ffb
7
- data.tar.gz: a64b0fc7a57e929af581457a3eeb2be21184dd60da9056ad91aa72068274fa602d13613f1faae2b86125bfd8c1e43d0d536bd3d35a1232873b32b76d215fd631
6
+ metadata.gz: ace38cd9bb2fa074acc3f320626f90720b9e21cadc424704f042621e662ffe785875189c0d5dd08632b7c6446bb3f8789a91697a00c0539a98a7a0e56b6fc5be
7
+ data.tar.gz: 6910fb55ba8ab0de491e7c083c2f70674fe4df76194a6f8b3cbfc77987ab1b935776f09ef61b26b29aa1cb5e0828f21a4ba2b0144cd3f6ff92ce14562eb04e44
@@ -13,6 +13,9 @@ Metrics/AbcSize:
13
13
  Metrics/BlockLength:
14
14
  Enabled: false
15
15
 
16
+ Metrics/BlockNesting:
17
+ Enabled: false
18
+
16
19
  Metrics/ClassLength:
17
20
  Enabled: false
18
21
 
@@ -10,6 +10,26 @@ making a small donation to show me you appreciate its continued development.
10
10
  [![Flattr this](http://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/submit/auto?user_id=jacobevelyn&url=https://github.com/JacobEvelyn/friends&title=friends&tags=github&category=software)
11
11
  [![Donate bitcoin](https://img.shields.io/badge/donate-Bitcoin-green.svg)](https://nrobinson2000.github.io/donate-bitcoin?address=1CFu6gWpmS89EnitPPdYssZhFMRWx5qhW4&amount=10&name=support-friends-development)
12
12
 
13
+ ## [v0.36](https://github.com/JacobEvelyn/friends/tree/v0.36) (2018-01-17)
14
+ [Full Changelog](https://github.com/JacobEvelyn/friends/compare/v0.35...v0.36)
15
+
16
+ **Implemented enhancements:**
17
+
18
+ - Parse friends.md and generate lists of friends/locations from the activities [\#182](https://github.com/JacobEvelyn/friends/issues/182)
19
+
20
+ **Fixed bugs:**
21
+
22
+ - `rename friend` and `rename location` do not correctly update existing notes [\#189](https://github.com/JacobEvelyn/friends/issues/189)
23
+
24
+ **Closed issues:**
25
+
26
+ - Add `grep` examples to the README [\#183](https://github.com/JacobEvelyn/friends/issues/183)
27
+
28
+ **Merged pull requests:**
29
+
30
+ - Add ability to add new friends and locations from events [\#190](https://github.com/JacobEvelyn/friends/pull/190) ([JacobEvelyn](https://github.com/JacobEvelyn))
31
+ - Add advanced search \(grep\) examples to README [\#188](https://github.com/JacobEvelyn/friends/pull/188) ([JacobEvelyn](https://github.com/JacobEvelyn))
32
+
13
33
  ## [v0.35](https://github.com/JacobEvelyn/friends/tree/v0.35) (2018-01-14)
14
34
  [Full Changelog](https://github.com/JacobEvelyn/friends/compare/v0.34...v0.35)
15
35
 
data/README.md CHANGED
@@ -54,6 +54,7 @@ lots of help), and give feedback!**
54
54
  * [`list friends`](#list-friends)
55
55
  * [`list tags`](#list-tags)
56
56
  * [`list locations`](#list-locations)
57
+ * [Advanced searching](#advanced-searching)
57
58
  * `remove`
58
59
  * [`remove tag`](#remove-tag)
59
60
  * [`remove nickname`](#remove-nickname)
@@ -313,6 +314,22 @@ $ friends add activity "2018-11-01: Grace and I went to \Marie's Diner. \George
313
314
  Activity added: "2018-11-01: Grace Hopper and I went to Marie's Diner. George had to cancel at the last minute."
314
315
  ```
315
316
 
317
+ And if an activity contains friends or locations you haven't yet added, you can simply
318
+ denote them with the signifiers found in the `friends.md` file (`**`s around friends,
319
+ and `_`s around locations), and `friends` will automatically add the friends or locations
320
+ that are missing:
321
+
322
+ ```bash
323
+ $ friends add activity "2018-11-01: I got to meet **Oprah Winfrey** in _Chicago_ today."
324
+ Activity added: "2018-11-01: I got to meet Oprah Winfrey in Chicago today."
325
+ Friend added: "Oprah Winfrey"
326
+ Location added: "Chicago"
327
+ ```
328
+
329
+ This is really handy for when you have an activity involving a friend or location that
330
+ you can't remember if you've already added. Just use the signifiers and
331
+ they'll be added if necessary!
332
+
316
333
  #### `add note`
317
334
 
318
335
  Notes can be added exactly like activities, either on one line:
@@ -329,7 +346,20 @@ $ friends add note last Monday
329
346
  2017-03-07: <type description here>
330
347
  ```
331
348
 
332
- And just like with `add activity`, dates, friends, locations, nicknames, and tags will all be intelligently matched.
349
+ And just like with `add activity`, dates, friends, locations, nicknames, and tags will all be
350
+ intelligently matched. In addition, as with `add activity` you can use the `**`/`_` signifiers
351
+ around friend and location names and they'll be added if necessary:
352
+
353
+ ```bash
354
+ $ friends add note "2018-11-01: **Oprah Winfrey** grew up in _Chicago_."
355
+ Activity added: "2018-11-01: Oprah Winfrey grew up in Chicago."
356
+ Friend added: "Oprah Winfrey"
357
+ Location added: "Chicago"
358
+ ```
359
+
360
+ This is really handy for when you have a note involving a friend or location that
361
+ you can't remember if you've already added. Just use the signifiers and
362
+ they'll be added if necessary!
333
363
 
334
364
  #### `add friend`
335
365
 
@@ -371,7 +401,9 @@ File cleaned: "./friends.md"
371
401
  ```
372
402
 
373
403
  This command is useful after manual editing of the file, for re-ordering its
374
- contents.
404
+ contents and adding any missing friends or locations that are found in
405
+ activities or notes. Note that `friends clean` is automatically called after
406
+ the editor in `friends edit` is closed.
375
407
 
376
408
  #### `edit`
377
409
 
@@ -379,16 +411,42 @@ Allows you to manually edit the file:
379
411
 
380
412
  ```bash
381
413
  $ friends edit
382
- Opening "./friends.md" in vim
414
+ Opening "./friends.md" with "vim"
383
415
  ```
384
416
 
385
- The file is opened with the command specified by the `$EDITOR` environment
417
+ The file is opened with the command specified by the `EDITOR` environment
386
418
  variable, falling back to `vim` if it is not set:
387
419
 
388
420
  ```bash
389
- $ export EDITOR=atom
421
+ $ export EDITOR='atom --wait'
390
422
  $ friends edit
391
- Opening "./friends.md" in atom
423
+ Opening "./friends.md" with "atom --wait"
424
+ ```
425
+
426
+ Note that when setting your own `EDITOR` value, if you like to use
427
+ an editor like Atom, VS Code, or Sublime Text, you should first make
428
+ sure you have the command-line tool for your editor (`atom`, `code`,
429
+ or `subl`) installed correctly so you can open your editor from the
430
+ command line. Then, when setting `EDITOR`, make sure to use the
431
+ `--wait` flag (as in the example above), which will allow `friends`
432
+ to be able to run the `clean` command (see below).
433
+
434
+ After the editor has been closed, `friends` will automatically run the
435
+ `clean` command to re-organize the file and add any friends or locations
436
+ you've referenced in activities or notes that have not been added to the
437
+ file. This means that, similar to the `add activity` and `add note`
438
+ commands, you can add lines like:
439
+
440
+ ```markdown
441
+ - 2018-01-01: I just met **Oprah Winfrey** in _Chicago_!
442
+ ```
443
+
444
+ And if that friend or location isn't already present it'll be added:
445
+
446
+ ```bash
447
+ Friend added: "Oprah Winfrey"
448
+ Location added: "Chicago"
449
+ File cleaned: "./friends.md\"
392
450
  ```
393
451
 
394
452
  #### `graph`
@@ -739,6 +797,41 @@ New York City
739
797
  Paris
740
798
  ```
741
799
 
800
+ #### Advanced searching
801
+
802
+ Since `friends` is a command-line program, we can easily support
803
+ more complex searching by piping the output of a `list` command
804
+ through a command-line tool like `grep`.
805
+
806
+ For instance, to see all of the notes containing the string `PhD`:
807
+
808
+ ```bash
809
+ $ friends list notes | grep PhD
810
+ 2017-07-01: Marie Curie just got accepted into a PhD program.
811
+ 2017-06-10: John Doe is finishing his PhD.
812
+ 2013-06-10: John Doe is just starting his PhD.
813
+ ```
814
+
815
+ And you can combine this with the normal filter options provided
816
+ by `friends`, like this:
817
+
818
+ ```bash
819
+ $ friends list notes --with John --since 'January 1st 2015' | grep PhD
820
+ 2017-06-10: John Doe is finishing his PhD.
821
+ ```
822
+
823
+ Note that `grep` has some handy flags, like `--ignore-case`/`-i`, and
824
+ `--color=always`, to help customize your search:
825
+
826
+ ```bash
827
+ $ friends list notes --with John --since 'January 1st 2015' | grep -i PhD
828
+ 2017-06-10: John Doe is finishing his PhD.
829
+ 2016-06-01: I think John Doe is hoping to finish his phD about a year from now.
830
+ ```
831
+
832
+ These `grep` flags might be slightly different depending on which version of
833
+ `grep` you have installed.
834
+
742
835
  #### `remove tag`
743
836
 
744
837
  Removes a specific tag from a friend:
@@ -764,6 +857,8 @@ $ friends rename friend "Grace Hopper" "Grace Brewster Murray Hopper"
764
857
  Name changed: "Grace Brewster Murray Hopper (a.k.a. Amazing Grace)"
765
858
  ```
766
859
 
860
+ This will update that friend's name in all notes and activities.
861
+
767
862
  #### `rename location`
768
863
 
769
864
  ```bash
@@ -771,6 +866,8 @@ $ friends rename location Paris "Paris, France"
771
866
  Location renamed: "Paris, France"
772
867
  ```
773
868
 
869
+ This will update that location's name in all notes and activities.
870
+
774
871
  #### `set location`
775
872
 
776
873
  Sets a friend's location:
@@ -72,34 +72,30 @@ switch [:colorless],
72
72
  commands_from "friends/commands"
73
73
 
74
74
  # Before each command, clean up all arguments and create the global Introvert.
75
- pre do |global_options, cmd, options|
75
+ pre do |global_options, cmd|
76
76
  # If the --colorless flag is passed, don't do any fancy painting.
77
77
  Paint.mode = 0 if global_options[:colorless]
78
78
 
79
79
  @debug_mode = global_options[:debug]
80
80
 
81
- final_options = global_options.merge!(options).select do |key, _|
82
- [:filename].include? key
83
- end
84
-
85
81
  # If we're updating the friends program we don't need to read the friends file
86
82
  # but we don't skip this block entirely because we might still want to enable
87
- # debug mode.
88
- @introvert = Friends::Introvert.new(final_options) unless cmd.name == :update
83
+ # debug mode. If we're in a `friends edit` command we wait to initialize the
84
+ # @introvert until the command block when the system call has exited
85
+ # successfully.
86
+ unless [:update, :edit].include? cmd.name
87
+ @introvert = Friends::Introvert.new(
88
+ filename: global_options[:filename],
89
+ quiet: global_options[:quiet]
90
+ )
91
+ end
89
92
 
90
93
  true # Continue executing the command.
91
94
  end
92
95
 
93
- post do |global_options|
96
+ post do
94
97
  # After each command, clean the file if we have modifications to make.
95
- filename = @introvert.clean if @dirty
96
-
97
- # This is a special-case piece of code that lets us print a message that
98
- # includes the filename when `friends clean` is called.
99
- @message = "File cleaned: \"#{filename}\"" if @clean_command
100
-
101
- # Print the output message (if there is one) unless --quiet is passed.
102
- puts @message unless @message.nil? || global_options[:quiet]
98
+ @introvert.clean(clean_command: @clean_command) if @dirty
103
99
  end
104
100
 
105
101
  # If an error is raised, print the message to STDERR and exit the program.
@@ -6,8 +6,7 @@ command :add do |add|
6
6
  add.arg_name "NAME"
7
7
  add.command :friend do |add_friend|
8
8
  add_friend.action do |_, _, args|
9
- friend = @introvert.add_friend(name: args.join(" "))
10
- @message = "Friend added: \"#{friend.name}\""
9
+ @introvert.add_friend(name: args.join(" "))
11
10
  @dirty = true # Mark the file for cleaning.
12
11
  end
13
12
  end
@@ -17,15 +16,7 @@ command :add do |add|
17
16
  add.arg_name "DESCRIPTION"
18
17
  add.command event do |add_event|
19
18
  add_event.action do |_, _, args|
20
- event_obj = @introvert.send("add_#{event}", serialization: args.join(" "))
21
-
22
- # If there's no description, prompt the user for one.
23
- if event_obj.description.nil? || event_obj.description.empty?
24
- event_obj.description = Readline.readline(event_obj.to_s)
25
- event_obj.highlight_description(introvert: @introvert)
26
- end
27
-
28
- @message = "#{event.to_s.capitalize} added: \"#{event_obj}\""
19
+ @introvert.send("add_#{event}", serialization: args.join(" "))
29
20
  @dirty = true # Mark the file for cleaning.
30
21
  end
31
22
  end
@@ -35,8 +26,7 @@ command :add do |add|
35
26
  add.arg_name "LOCATION"
36
27
  add.command :location do |add_location|
37
28
  add_location.action do |_, _, args|
38
- location = @introvert.add_location(name: args.join(" "))
39
- @message = "Location added: \"#{location.name}\""
29
+ @introvert.add_location(name: args.join(" "))
40
30
  @dirty = true # Mark the file for cleaning.
41
31
  end
42
32
  end
@@ -45,8 +35,7 @@ command :add do |add|
45
35
  add.arg_name "NAME NICKNAME"
46
36
  add.command :nickname do |add_nickname|
47
37
  add_nickname.action do |_, _, args|
48
- friend = @introvert.add_nickname(name: args.first, nickname: args[1])
49
- @message = "Nickname added: \"#{friend}\""
38
+ @introvert.add_nickname(name: args.first, nickname: args[1])
50
39
  @dirty = true # Mark the file for cleaning.
51
40
  end
52
41
  end
@@ -55,11 +44,10 @@ command :add do |add|
55
44
  add.arg_name "NAME @TAG"
56
45
  add.command :tag do |add_tag|
57
46
  add_tag.action do |_, _, args|
58
- friend = @introvert.add_tag(
47
+ @introvert.add_tag(
59
48
  name: args[0..-2].join(" "),
60
49
  tag: Tag.convert_to_tag(args.last)
61
50
  )
62
- @message = "Tag added to friend: \"#{friend}\""
63
51
  @dirty = true # Mark the file for cleaning.
64
52
  end
65
53
  end
@@ -6,7 +6,18 @@ command :edit do |edit|
6
6
  editor = ENV["EDITOR"] || "vim"
7
7
  filename = global_options[:filename]
8
8
 
9
- puts "Opening \"#{filename}\" in #{editor}" unless global_options[:quiet]
10
- Kernel.exec "#{editor} #{filename}"
9
+ puts "Opening \"#{filename}\" with \"#{editor}\"" unless global_options[:quiet]
10
+
11
+ # Mark the file for cleaning once the editor was closed correctly.
12
+ if Kernel.system("#{editor} #{filename}")
13
+ @introvert = Friends::Introvert.new(
14
+ filename: global_options[:filename],
15
+ quiet: global_options[:quiet]
16
+ )
17
+ @clean_command = true
18
+ @dirty = true
19
+ elsif !global_options[:quiet]
20
+ puts "Not cleaning file: \"#{filename}\" (\"#{editor}\" did not exit successfully)"
21
+ end
11
22
  end
12
23
  end
@@ -20,7 +20,7 @@ command :list do |list|
20
20
  desc: "Output friend nicknames, locations, and tags"
21
21
 
22
22
  list_friends.action do |_, options|
23
- puts @introvert.list_friends(
23
+ @introvert.list_friends(
24
24
  location_name: options[:in],
25
25
  tagged: options[:tagged],
26
26
  verbose: options[:verbose]
@@ -65,7 +65,7 @@ command :list do |list|
65
65
  type: InputDate
66
66
 
67
67
  list_events.action do |_, options|
68
- puts @introvert.send(
68
+ @introvert.send(
69
69
  "list_#{events}",
70
70
  limit: options[:limit],
71
71
  with: options[:with],
@@ -81,7 +81,7 @@ command :list do |list|
81
81
  list.desc "List all locations"
82
82
  list.command :locations do |list_locations|
83
83
  list_locations.action do
84
- puts @introvert.list_locations
84
+ @introvert.list_locations
85
85
  end
86
86
  end
87
87
 
@@ -93,7 +93,7 @@ command :list do |list|
93
93
  "all three",
94
94
  multiple: true
95
95
  list_tags.action do |_, options|
96
- puts @introvert.list_tags(from: options[:from])
96
+ @introvert.list_tags(from: options[:from])
97
97
  end
98
98
  end
99
99
 
@@ -6,8 +6,7 @@ command :remove do |remove|
6
6
  remove.arg_name "NAME NICKNAME"
7
7
  remove.command :nickname do |remove_nickname|
8
8
  remove_nickname.action do |_, _, args|
9
- friend = @introvert.remove_nickname(name: args.first, nickname: args[1])
10
- @message = "Nickname removed: \"#{friend}\""
9
+ @introvert.remove_nickname(name: args.first, nickname: args[1])
11
10
  @dirty = true # Mark the file for cleaning.
12
11
  end
13
12
  end
@@ -16,11 +15,10 @@ command :remove do |remove|
16
15
  remove.arg_name "NAME @TAG"
17
16
  remove.command :tag do |remove_tag|
18
17
  remove_tag.action do |_, _, args|
19
- friend = @introvert.remove_tag(
18
+ @introvert.remove_tag(
20
19
  name: args[0..-2].join(" "),
21
20
  tag: Tag.convert_to_tag(args.last)
22
21
  )
23
- @message = "Tag removed from friend: \"#{friend}\""
24
22
  @dirty = true # Mark the file for cleaning.
25
23
  end
26
24
  end
@@ -6,11 +6,10 @@ command :rename do |rename|
6
6
  rename.arg_name "NAME NEW_NAME"
7
7
  rename.command :friend do |rename_friend|
8
8
  rename_friend.action do |_, _, args|
9
- friend = @introvert.rename_friend(
9
+ @introvert.rename_friend(
10
10
  old_name: args.first,
11
11
  new_name: args[1]
12
12
  )
13
- @message = "Name changed: \"#{friend}\""
14
13
  @dirty = true # Mark the file for cleaning.
15
14
  end
16
15
  end
@@ -19,11 +18,10 @@ command :rename do |rename|
19
18
  rename.arg_name "NAME NEW_NAME"
20
19
  rename.command :location do |rename_location|
21
20
  rename_location.action do |_, _, args|
22
- location = @introvert.rename_location(
21
+ @introvert.rename_location(
23
22
  old_name: args.first,
24
23
  new_name: args[1]
25
24
  )
26
- @message = "Location renamed: \"#{location.name}\""
27
25
  @dirty = true # Mark the file for cleaning.
28
26
  end
29
27
  end
@@ -6,8 +6,7 @@ command :set do |set|
6
6
  set.arg_name "NAME LOCATION"
7
7
  set.command :location do |set_location|
8
8
  set_location.action do |_, _, args|
9
- friend = @introvert.set_location(name: args.first, location_name: args[1])
10
- @message = "#{friend.name}'s location set to: #{friend.location_name}"
9
+ @introvert.set_location(name: args.first, location_name: args[1])
11
10
  @dirty = true # Mark the file for cleaning.
12
11
  end
13
12
  end
@@ -3,12 +3,6 @@
3
3
  desc "List all stats"
4
4
  command :stats do |stats|
5
5
  stats.action do
6
- puts "Total activities: #{@introvert.total_activities}"
7
- puts "Total friends: #{@introvert.total_friends}"
8
- puts "Total locations: #{@introvert.total_locations}"
9
- puts "Total notes: #{@introvert.total_notes}"
10
- puts "Total tags: #{@introvert.total_tags}"
11
- days = @introvert.elapsed_days
12
- puts "Total time elapsed: #{days} day#{'s' if days != 1}"
6
+ @introvert.stats
13
7
  end
14
8
  end