friends 0.35 → 0.36
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -0
- data/CHANGELOG.md +20 -0
- data/README.md +103 -6
- data/bin/friends +12 -16
- data/lib/friends/commands/add.rb +5 -17
- data/lib/friends/commands/edit.rb +13 -2
- data/lib/friends/commands/list.rb +4 -4
- data/lib/friends/commands/remove.rb +2 -4
- data/lib/friends/commands/rename.rb +2 -4
- data/lib/friends/commands/set.rb +1 -2
- data/lib/friends/commands/stats.rb +1 -7
- data/lib/friends/commands/suggest.rb +1 -8
- data/lib/friends/commands/update.rb +12 -13
- data/lib/friends/event.rb +2 -2
- data/lib/friends/introvert.rb +122 -110
- data/lib/friends/version.rb +1 -1
- data/test/commands/clean_spec.rb +88 -1
- data/test/commands/edit_spec.rb +125 -17
- data/test/commands/rename/friend_spec.rb +7 -0
- data/test/commands/rename/location_spec.rb +8 -0
- data/test/commands/set/location_spec.rb +2 -2
- data/test/editor +15 -0
- data/test/helper.rb +2 -2
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7c26333d51f189dc3c73e8619857ef1d18ebb85f
|
4
|
+
data.tar.gz: 1444055713076b43e7cc0cb20b9da27af110a1f4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ace38cd9bb2fa074acc3f320626f90720b9e21cadc424704f042621e662ffe785875189c0d5dd08632b7c6446bb3f8789a91697a00c0539a98a7a0e56b6fc5be
|
7
|
+
data.tar.gz: 6910fb55ba8ab0de491e7c083c2f70674fe4df76194a6f8b3cbfc77987ab1b935776f09ef61b26b29aa1cb5e0828f21a4ba2b0144cd3f6ff92ce14562eb04e44
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -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
|
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"
|
414
|
+
Opening "./friends.md" with "vim"
|
383
415
|
```
|
384
416
|
|
385
|
-
The file is opened with the command specified by the
|
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"
|
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:
|
data/bin/friends
CHANGED
@@ -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
|
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
|
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
|
96
|
+
post do
|
94
97
|
# After each command, clean the file if we have modifications to make.
|
95
|
-
|
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.
|
data/lib/friends/commands/add.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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}\"
|
10
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
data/lib/friends/commands/set.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|