friends 0.33 → 0.34
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +16 -246
- data/.travis.yml +1 -0
- data/CHANGELOG.md +12 -1
- data/README.md +102 -80
- data/bin/friends +4 -6
- data/lib/friends/activity.rb +2 -2
- data/lib/friends/friend.rb +4 -8
- data/lib/friends/graph.rb +6 -5
- data/lib/friends/introvert.rb +12 -6
- data/lib/friends/location.rb +1 -1
- data/lib/friends/regex_builder.rb +8 -8
- data/lib/friends/version.rb +1 -1
- data/test/commands/add/activity_spec.rb +8 -3
- data/test/commands/help_spec.rb +1 -1
- data/test/helper.rb +2 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c8288b02c441d46ce2481d4a39f8ea457519a6e7
|
4
|
+
data.tar.gz: 551632c785ec6d2447adf65d56ab4fa0aac16a49
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9fc27186b237b3a244d88e5c85cc019bfce8ae51a1b74becae9c103d33fa777429c247ae3070b3da288104299856475ab1e67e376a5b4bdb719f62f9550f6b8d
|
7
|
+
data.tar.gz: 3206d0662d64b42f8c8ce5e2fb5bc8ad9a95dda27b4d07541798fc27a177f0d7d5c343bfbf540357f891a6bf954e2b09acf38aa8a09d71988b84d480a92d8944
|
data/.rubocop.yml
CHANGED
@@ -1,280 +1,50 @@
|
|
1
|
-
AbcSize:
|
2
|
-
Enabled: false
|
3
|
-
|
4
|
-
AccessorMethodName:
|
5
|
-
Enabled: false
|
6
|
-
|
7
|
-
Alias:
|
8
|
-
Enabled: false
|
9
|
-
|
10
1
|
AllCops:
|
11
|
-
TargetRubyVersion: 2.
|
12
|
-
|
13
|
-
AmbiguousOperator:
|
14
|
-
Enabled: false
|
15
|
-
|
16
|
-
AmbiguousRegexpLiteral:
|
17
|
-
Enabled: false
|
18
|
-
|
19
|
-
ArrayJoin:
|
20
|
-
Enabled: false
|
21
|
-
|
22
|
-
AsciiComments:
|
23
|
-
Enabled: false
|
24
|
-
|
25
|
-
AsciiIdentifiers:
|
26
|
-
Enabled: false
|
27
|
-
|
28
|
-
AssignmentInCondition:
|
29
|
-
Enabled: true
|
30
|
-
|
31
|
-
Attr:
|
32
|
-
Enabled: false
|
33
|
-
|
34
|
-
BlockNesting:
|
35
|
-
Enabled: false
|
36
|
-
|
37
|
-
BracesAroundHashParameters:
|
38
|
-
Enabled: false
|
39
|
-
|
40
|
-
CaseEquality:
|
41
|
-
Enabled: false
|
42
|
-
|
43
|
-
CharacterLiteral:
|
44
|
-
Enabled: false
|
45
|
-
|
46
|
-
ClassLength:
|
47
|
-
Enabled: false
|
48
|
-
|
49
|
-
ClassVars:
|
50
|
-
Enabled: false
|
51
|
-
|
52
|
-
CollectionMethods:
|
53
|
-
PreferredMethods:
|
54
|
-
find: detect
|
55
|
-
reduce: inject
|
56
|
-
collect: map
|
57
|
-
find_all: select
|
58
|
-
|
59
|
-
ColonMethodCall:
|
60
|
-
Enabled: false
|
61
|
-
|
62
|
-
CommentAnnotation:
|
63
|
-
Enabled: false
|
2
|
+
TargetRubyVersion: 2.1
|
64
3
|
|
65
|
-
|
66
|
-
Enabled: false
|
67
|
-
|
68
|
-
CyclomaticComplexity:
|
69
|
-
Enabled: false
|
70
|
-
|
71
|
-
Delegate:
|
72
|
-
Enabled: false
|
73
|
-
|
74
|
-
DeprecatedClassMethods:
|
75
|
-
Enabled: false
|
76
|
-
|
77
|
-
Documentation:
|
78
|
-
Enabled: false
|
79
|
-
|
80
|
-
DotPosition:
|
4
|
+
Layout/DotPosition:
|
81
5
|
EnforcedStyle: trailing
|
82
6
|
|
83
|
-
DoubleNegation:
|
84
|
-
Enabled: false
|
85
|
-
|
86
|
-
ElseLayout:
|
87
|
-
Enabled: false
|
88
|
-
|
89
|
-
EmptyLiteral:
|
90
|
-
Enabled: false
|
91
|
-
|
92
|
-
Encoding:
|
93
|
-
Enabled: false
|
94
|
-
|
95
|
-
EvenOdd:
|
96
|
-
Enabled: false
|
97
|
-
|
98
|
-
FileName:
|
99
|
-
Enabled: false
|
100
|
-
|
101
|
-
FlipFlop:
|
102
|
-
Enabled: false
|
103
|
-
|
104
|
-
FormatString:
|
105
|
-
Enabled: false
|
106
|
-
|
107
|
-
GlobalVars:
|
108
|
-
Enabled: false
|
109
|
-
|
110
|
-
HandleExceptions:
|
111
|
-
Enabled: false
|
112
|
-
|
113
|
-
IfUnlessModifier:
|
114
|
-
Enabled: false
|
115
|
-
|
116
|
-
IfWithSemicolon:
|
117
|
-
Enabled: false
|
118
|
-
|
119
|
-
InvalidCharacterLiteral:
|
120
|
-
Enabled: false
|
121
|
-
|
122
|
-
Lambda:
|
123
|
-
Enabled: false
|
124
|
-
|
125
|
-
LambdaCall:
|
126
|
-
Enabled: false
|
127
|
-
|
128
7
|
Layout/IndentHeredoc:
|
129
8
|
Enabled: false
|
130
9
|
|
131
|
-
|
132
|
-
Enabled: false
|
133
|
-
|
134
|
-
LineLength:
|
135
|
-
Max: 100
|
136
|
-
|
137
|
-
LiteralInCondition:
|
138
|
-
Enabled: false
|
139
|
-
|
140
|
-
LiteralInInterpolation:
|
141
|
-
Enabled: false
|
142
|
-
|
143
|
-
Loop:
|
144
|
-
Enabled: false
|
145
|
-
|
146
|
-
MethodLength:
|
10
|
+
Metrics/AbcSize:
|
147
11
|
Enabled: false
|
148
12
|
|
149
13
|
Metrics/BlockLength:
|
150
14
|
Enabled: false
|
151
15
|
|
152
|
-
|
153
|
-
Enabled: false
|
154
|
-
|
155
|
-
MutableConstant:
|
156
|
-
Enabled: true
|
157
|
-
|
158
|
-
NegatedIf:
|
159
|
-
Enabled: false
|
160
|
-
|
161
|
-
NegatedWhile:
|
162
|
-
Enabled: false
|
163
|
-
|
164
|
-
Next:
|
165
|
-
Enabled: false
|
166
|
-
|
167
|
-
NilComparison:
|
168
|
-
Enabled: false
|
169
|
-
|
170
|
-
Not:
|
171
|
-
Enabled: false
|
172
|
-
|
173
|
-
NumericLiterals:
|
16
|
+
Metrics/ClassLength:
|
174
17
|
Enabled: false
|
175
18
|
|
176
|
-
|
19
|
+
Metrics/CyclomaticComplexity:
|
177
20
|
Enabled: false
|
178
21
|
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
ParameterLists:
|
183
|
-
Enabled: false
|
184
|
-
|
185
|
-
ParenthesesAsGroupedExpression:
|
186
|
-
Enabled: false
|
187
|
-
|
188
|
-
PerceivedComplexity:
|
189
|
-
Enabled: false
|
190
|
-
|
191
|
-
PercentLiteralDelimiters:
|
192
|
-
PreferredDelimiters:
|
193
|
-
'%': '{}'
|
194
|
-
|
195
|
-
PerlBackrefs:
|
196
|
-
Enabled: false
|
197
|
-
|
198
|
-
PredicateName:
|
199
|
-
NamePrefixBlacklist:
|
200
|
-
- is_
|
201
|
-
|
202
|
-
Proc:
|
203
|
-
Enabled: false
|
204
|
-
|
205
|
-
Rails:
|
206
|
-
Enabled: false
|
22
|
+
Metrics/LineLength:
|
23
|
+
Max: 100
|
207
24
|
|
208
|
-
|
25
|
+
Metrics/MethodLength:
|
209
26
|
Enabled: false
|
210
27
|
|
211
|
-
|
212
|
-
AllowMultipleReturnValues: true
|
213
|
-
|
214
|
-
RegexpLiteral:
|
28
|
+
Metrics/ParameterLists:
|
215
29
|
Enabled: false
|
216
30
|
|
217
|
-
|
31
|
+
Metrics/PerceivedComplexity:
|
218
32
|
Enabled: false
|
219
33
|
|
220
|
-
|
34
|
+
Naming/AccessorMethodName:
|
221
35
|
Enabled: false
|
222
36
|
|
223
|
-
|
224
|
-
EnforcedStyle: only_raise
|
225
|
-
|
226
|
-
SingleLineBlockParams:
|
37
|
+
Style/Documentation:
|
227
38
|
Enabled: false
|
228
39
|
|
229
|
-
|
40
|
+
Style/MultilineBlockChain:
|
230
41
|
Enabled: false
|
231
42
|
|
232
|
-
SpecialGlobalVars:
|
43
|
+
Style/SpecialGlobalVars:
|
233
44
|
Enabled: false
|
234
45
|
|
235
|
-
StringLiterals:
|
46
|
+
Style/StringLiterals:
|
236
47
|
EnforcedStyle: double_quotes
|
237
48
|
|
238
|
-
Style/MultilineBlockChain:
|
239
|
-
Enabled: false
|
240
|
-
|
241
49
|
Style/SymbolArray:
|
242
|
-
EnforcedStyle: brackets
|
243
|
-
|
244
|
-
VariableInterpolation:
|
245
|
-
Enabled: false
|
246
|
-
|
247
|
-
TrailingCommaInArguments:
|
248
|
-
Enabled: true
|
249
|
-
|
250
|
-
TrailingCommaInLiteral:
|
251
|
-
Enabled: true
|
252
|
-
|
253
|
-
TrivialAccessors:
|
254
|
-
Enabled: false
|
255
|
-
|
256
|
-
UnderscorePrefixedVariableName:
|
257
|
-
Enabled: false
|
258
|
-
|
259
|
-
VariableInterpolation:
|
260
|
-
Enabled: false
|
261
|
-
|
262
|
-
Void:
|
263
|
-
Enabled: false
|
264
|
-
|
265
|
-
WhenThen:
|
266
|
-
Enabled: false
|
267
|
-
|
268
|
-
WhileUntilModifier:
|
269
|
-
Enabled: false
|
270
|
-
|
271
|
-
WordArray:
|
272
|
-
Enabled: false
|
273
|
-
|
274
|
-
GuardClause:
|
275
|
-
Enabled: false
|
276
|
-
|
277
|
-
# Renaming `has_something?` to `something?` obfuscates whether it is a "is-a" or
|
278
|
-
# # a "has-a" relationship.
|
279
|
-
PredicateName:
|
280
|
-
Enabled: false
|
50
|
+
EnforcedStyle: brackets
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,9 +1,20 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## [v0.34](https://github.com/JacobEvelyn/friends/tree/v0.34) (2018-01-10)
|
4
|
+
[Full Changelog](https://github.com/JacobEvelyn/friends/compare/v0.33...v0.34)
|
5
|
+
|
6
|
+
**Implemented enhancements:**
|
7
|
+
|
8
|
+
- Newer activities should always appear above older activities on the same date [\#184](https://github.com/JacobEvelyn/friends/issues/184)
|
9
|
+
|
10
|
+
**Merged pull requests:**
|
11
|
+
|
12
|
+
- Always sort activities stably within a date [\#185](https://github.com/JacobEvelyn/friends/pull/185) ([JacobEvelyn](https://github.com/JacobEvelyn))
|
13
|
+
|
3
14
|
## [v0.33](https://github.com/JacobEvelyn/friends/tree/v0.33) (2017-08-22)
|
4
15
|
[Full Changelog](https://github.com/JacobEvelyn/friends/compare/v0.32...v0.33)
|
5
16
|
|
6
|
-
**
|
17
|
+
**Implemented enhancements:**
|
7
18
|
|
8
19
|
- Prevent dates without years from being in the future [\#181](https://github.com/JacobEvelyn/friends/pull/181) ([JacobEvelyn](https://github.com/JacobEvelyn))
|
9
20
|
|
data/README.md
CHANGED
@@ -1,5 +1,20 @@
|
|
1
|
-
[![Gem Version](https://badge.fury.io/rb/friends.svg)](https://badge.fury.io/rb/friends)
|
2
|
-
|
1
|
+
[![Gem Version](https://badge.fury.io/rb/friends.svg)](https://badge.fury.io/rb/friends)
|
2
|
+
[![Dependency Status](https://gemnasium.com/badges/github.com/JacobEvelyn/friends.svg)](https://gemnasium.com/github.com/JacobEvelyn/friends)
|
3
|
+
[![Coverage Status](https://coveralls.io/repos/github/JacobEvelyn/friends/badge.svg)](https://coveralls.io/github/JacobEvelyn/friends)
|
4
|
+
[![Build Status](https://travis-ci.org/JacobEvelyn/friends.svg?branch=master)](https://travis-ci.org/JacobEvelyn/friends)
|
5
|
+
[![Readme Score](http://readme-score-api.herokuapp.com/score.svg?url=JacobEvelyn/friends&bust=1)](http://clayallsopp.github.io/readme-score?url=JacobEvelyn/friends)
|
6
|
+
[![Inline docs](http://inch-ci.org/github/JacobEvelyn/friends.png)](http://inch-ci.org/github/JacobEvelyn/friends)
|
7
|
+
[![Gem](https://img.shields.io/gem/dt/friends.svg)](https://rubygems.org/gems/friends)
|
8
|
+
|
9
|
+
`friends` is a volunteer project. If you find it useful, please consider
|
10
|
+
making a small donation to show me you appreciate its continued development.
|
11
|
+
|
12
|
+
[![Donate via OpenCollective](https://opencollective.com/friends/contributors/badge.svg)](https://opencollective.com/friends)
|
13
|
+
[![Support via Patreon](https://img.shields.io/badge/patreon-donate-yellow.svg)](https://www.patreon.com/jacobevelyn)
|
14
|
+
[![Donate via Liberapay](https://liberapay.com/assets/widgets/donate.svg)](https://liberapay.com/jacobevelyn/donate)
|
15
|
+
[![Donate via PayPal](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=jacobevelyn%40gmail%2ecom&lc=US&item_name=Development%20of%20JacobEvelyn%2ffriends%20%28GitHub%20repository%29&no_note=0¤cy_code=USD&bn=PP%2dDonationsBF%3abtn_donate_SM%2egif%3aNonHostedGuest)
|
16
|
+
[![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)
|
17
|
+
[![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)
|
3
18
|
|
4
19
|
# `friends`
|
5
20
|
|
@@ -12,47 +27,47 @@ lots of help), and give feedback!**
|
|
12
27
|
|
13
28
|
## Table of Contents
|
14
29
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
30
|
+
* [Overview](#overview)
|
31
|
+
* [Installation](#installation)
|
32
|
+
* [Usage](#usage)
|
33
|
+
* [Core concepts](#core-concepts)
|
34
|
+
* [Global flags](#global-flags)
|
35
|
+
* [Syncing across multiple machines](#syncing-across-multiple-machines)
|
36
|
+
* [Setting reminders](#setting-reminders)
|
37
|
+
* [Command reference](#command-reference)
|
38
|
+
* `add`
|
39
|
+
* [`add activity`](#add-activity)
|
40
|
+
* [`add friend`](#add-friend)
|
41
|
+
* [`add tag`](#add-tag)
|
42
|
+
* [`add location`](#add-location)
|
43
|
+
* [`add nickname`](#add-nickname)
|
44
|
+
* [`clean`](#clean)
|
45
|
+
* [`graph`](#graph)
|
46
|
+
* [`help`](#help)
|
47
|
+
* `list`
|
48
|
+
* [`list activities`](#list-activities)
|
49
|
+
* `list favorite`
|
50
|
+
* [`list favorite friends`](#list-favorite-friends)
|
51
|
+
* [`list favorite locations`](#list-favorite-locations)
|
52
|
+
* [`list friends`](#list-friends)
|
53
|
+
* [`list tags`](#list-tags)
|
54
|
+
* [`list locations`](#list-locations)
|
55
|
+
* `remove`
|
56
|
+
* [`remove tag`](#remove-tag)
|
57
|
+
* [`remove nickname`](#remove-nickname)
|
58
|
+
* `rename`
|
59
|
+
* [`rename friend`](#rename-friend)
|
60
|
+
* [`rename location`](#rename-location)
|
61
|
+
* [`set location`](#set-location)
|
62
|
+
* [`stats`](#stats)
|
63
|
+
* [`suggest`](#suggest)
|
64
|
+
* [`update`](#update)
|
65
|
+
* [Other documentation](#other-documentation)
|
66
|
+
* [Contributing (it's encouraged!)](#contributing-its-encouraged)
|
67
|
+
* [Code of Conduct](#code-of-conduct)
|
68
|
+
* [License](#license)
|
69
|
+
|
70
|
+
---
|
56
71
|
|
57
72
|
## Overview
|
58
73
|
|
@@ -60,21 +75,22 @@ lots of help), and give feedback!**
|
|
60
75
|
people you care about.
|
61
76
|
|
62
77
|
`friends` gives you:
|
63
|
-
|
78
|
+
|
79
|
+
* More organization around staying in touch with friends and
|
64
80
|
family.
|
65
|
-
|
81
|
+
* A way to track the ebbs and flows of your relationships over
|
66
82
|
time.
|
67
|
-
|
83
|
+
* Suggestions for who to call or hang out with when you have free
|
68
84
|
time, whether it's fifteen minutes or an entire weekend.
|
69
|
-
|
85
|
+
* A low-cost way to record and remember big moments in your life.
|
70
86
|
|
71
87
|
Its philosophy emphasizes:
|
72
88
|
|
73
|
-
|
74
|
-
|
89
|
+
* **Simplicity**—it should be quick and easy to use.
|
90
|
+
* **Transparency**—all data is stored in a human-readable Markdown file. No
|
75
91
|
proprietary formats here! And in addition to being open-source, `friends` is
|
76
92
|
very much open to new ideas. Contribute!
|
77
|
-
|
93
|
+
* **Intelligence**—specify dates with English phrases like "yesterday." Specify
|
78
94
|
friends with their first names, even when you're friends with many *Joanne*s. `friends` will figure it out.
|
79
95
|
|
80
96
|
## Installation
|
@@ -91,44 +107,47 @@ Easy, huh?
|
|
91
107
|
|
92
108
|
`friends` is structured around several different types of things:
|
93
109
|
|
94
|
-
|
95
|
-
it. Activities may optionally contain any number of
|
96
|
-
and
|
97
|
-
|
110
|
+
* **Activities**: The things you do. Each activity has a date associated with
|
111
|
+
it. Activities may optionally contain any number of _friends_, _locations_,
|
112
|
+
and _tags_.
|
113
|
+
* **Friends**: The people you do _activities_ with. Each friend has a name and,
|
98
114
|
optionally, one or several nicknames. (Examples: `John`, `Grace Hopper`)
|
99
|
-
|
115
|
+
* **Locations**: The places in which _activities_ happen. (Examples: `Paris`,
|
100
116
|
`Marie's Diner`)
|
101
|
-
|
117
|
+
* **Tags**: A way to categorize your _activities_ with tags of your
|
102
118
|
choosing. (Examples: `@exercise`, `@school`)
|
103
119
|
|
104
120
|
The `friends.md` Markdown file that stores all of your data contains:
|
105
121
|
|
106
|
-
|
122
|
+
* an alphabetical list of all locations:
|
107
123
|
|
108
124
|
```markdown
|
109
125
|
### Locations:
|
110
|
-
|
111
|
-
|
112
|
-
|
126
|
+
|
127
|
+
* Atlantis
|
128
|
+
* Marie's Diner
|
129
|
+
* Paris
|
113
130
|
```
|
114
131
|
|
115
|
-
|
132
|
+
* an alphabetical list of all friends and their nicknames and locations:
|
116
133
|
|
117
134
|
```markdown
|
118
135
|
### Friends:
|
119
|
-
|
120
|
-
|
121
|
-
|
136
|
+
|
137
|
+
* George Washington Carver
|
138
|
+
* Grace Hopper (a.k.a. The Admiral a.k.a. Amazing Grace) [Paris]
|
139
|
+
* Marie Curie [Atlantis]
|
122
140
|
```
|
123
141
|
|
124
|
-
|
142
|
+
* and an ordered list of all activities:
|
125
143
|
|
126
144
|
```markdown
|
127
145
|
### Activities:
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
146
|
+
|
147
|
+
* 2018-11-01: **Grace Hopper** and I went to _Marie's Diner_. George had to cancel at the last minute.
|
148
|
+
* 2018-01-04: Got lunch with **Grace Hopper** and **George Washington Carver**.
|
149
|
+
* 2017-12-31: Celebrated the new year in _Paris_ with **Marie Curie**.
|
150
|
+
* 2017-11-15: Talked to **George Washington Carver** on the phone for an hour.
|
132
151
|
```
|
133
152
|
|
134
153
|
See the example
|
@@ -142,16 +161,16 @@ specified before the name of the command, like: `friends [flags] [command]`.
|
|
142
161
|
|
143
162
|
These flags are:
|
144
163
|
|
145
|
-
|
146
|
-
|
147
|
-
|
164
|
+
* `--colorless`: Disable output colorization and other effects.
|
165
|
+
* `--debug`: Debug error messages with a full backtrace.
|
166
|
+
* `--filename`: Set the location of the friends file to use (default: ./friends.md).
|
148
167
|
|
149
168
|
```bash
|
150
169
|
$ friends --filename ./test/tmp/friends.md clean
|
151
170
|
File cleaned: "./test/tmp/friends.md"
|
152
171
|
```
|
153
172
|
|
154
|
-
|
173
|
+
* `--quiet`: Quiet output messages.
|
155
174
|
|
156
175
|
```bash
|
157
176
|
$ friends --quiet add activity Went rollerskating with George.
|
@@ -160,8 +179,8 @@ $ # No output!
|
|
160
179
|
|
161
180
|
In addition, these flags may be used without any command:
|
162
181
|
|
163
|
-
|
164
|
-
Help menus are available for all levels of commands:
|
182
|
+
* `--help`: Show the help menu. This is equivalent to `friends help`.
|
183
|
+
Help menus are available for all levels of commands:
|
165
184
|
|
166
185
|
```bash
|
167
186
|
$ friends --help
|
@@ -175,7 +194,7 @@ $ friends list --help
|
|
175
194
|
$ friends list activities --help
|
176
195
|
```
|
177
196
|
|
178
|
-
|
197
|
+
* `--version`: Show the `friends` program version.
|
179
198
|
|
180
199
|
### Syncing across multiple machines
|
181
200
|
|
@@ -212,9 +231,9 @@ hang out with every Saturday morning:
|
|
212
231
|
|
213
232
|
(If you use other tools, please share and we'll add to these examples!)
|
214
233
|
|
215
|
-
### Command reference
|
234
|
+
### Command reference\*
|
216
235
|
|
217
|
-
|
236
|
+
\*Note that the command-line output is colored, which this README cannot show.
|
218
237
|
|
219
238
|
#### `add activity`
|
220
239
|
|
@@ -223,7 +242,7 @@ $ friends add activity Got lunch with Grace and George.
|
|
223
242
|
Activity added: "2018-01-04: Got lunch with Grace Hopper and George Washington Carver."
|
224
243
|
```
|
225
244
|
|
226
|
-
`friends` will **automatically** figure out which "Grace" and "George" you're referring to,
|
245
|
+
`friends` will **automatically** figure out which "Grace" and "George" you're referring to, _even if you're friends with lots of different Graces and Georges_.
|
227
246
|
|
228
247
|
Nicknames will be used to match friends in activities,
|
229
248
|
just like formal names:
|
@@ -746,7 +765,7 @@ Updated to friends 0.17
|
|
746
765
|
|
747
766
|
## Other documentation
|
748
767
|
|
749
|
-
In case you're
|
768
|
+
In case you're _really_ interested, we have documentation on
|
750
769
|
[RubyDoc](http://www.rubydoc.info/github/JacobEvelyn/friends).
|
751
770
|
|
752
771
|
## Contributing (it's encouraged!)
|
@@ -760,6 +779,9 @@ quickly. And if you'd like to do the implementing yourself, see the
|
|
760
779
|
A big big thanks to all of this project's lovely
|
761
780
|
[contributors](https://github.com/JacobEvelyn/friends/graphs/contributors)!
|
762
781
|
|
782
|
+
Another way to contribute is to make a donation (see the buttons at the top
|
783
|
+
of this `README`!
|
784
|
+
|
763
785
|
## Code of Conduct
|
764
786
|
|
765
787
|
Note that this project follows a [Code of Conduct](https://github.com/JacobEvelyn/friends/blob/master/CODE_OF_CONDUCT.md).
|
data/bin/friends
CHANGED
@@ -16,7 +16,7 @@ require "semverse"
|
|
16
16
|
require "friends/introvert"
|
17
17
|
require "friends/version"
|
18
18
|
|
19
|
-
include GLI::App
|
19
|
+
include GLI::App # rubocop:disable Style/MixinUsage
|
20
20
|
|
21
21
|
program_desc "Spend time with the people you care about. Introvert-tested. "\
|
22
22
|
"Extrovert-approved."
|
@@ -104,11 +104,9 @@ end
|
|
104
104
|
|
105
105
|
# If an error is raised, print the message to STDERR and exit the program.
|
106
106
|
on_error do |error|
|
107
|
-
if @debug_mode
|
108
|
-
|
109
|
-
|
110
|
-
abort "Error: #{error}"
|
111
|
-
end
|
107
|
+
raise error if @debug_mode
|
108
|
+
|
109
|
+
abort "Error: #{error}"
|
112
110
|
end
|
113
111
|
|
114
112
|
# Run the program and return the exit code corresponding to its success.
|
data/lib/friends/activity.rb
CHANGED
@@ -12,8 +12,8 @@ module Friends
|
|
12
12
|
class Activity
|
13
13
|
extend Serializable
|
14
14
|
|
15
|
-
SERIALIZATION_PREFIX = "- "
|
16
|
-
DATE_PARTITION = ": "
|
15
|
+
SERIALIZATION_PREFIX = "- ".freeze
|
16
|
+
DATE_PARTITION = ": ".freeze
|
17
17
|
|
18
18
|
# @return [Regexp] the regex for capturing groups in deserialization
|
19
19
|
def self.deserialization_regex
|
data/lib/friends/friend.rb
CHANGED
@@ -10,8 +10,8 @@ module Friends
|
|
10
10
|
class Friend
|
11
11
|
extend Serializable
|
12
12
|
|
13
|
-
SERIALIZATION_PREFIX = "- "
|
14
|
-
NICKNAME_PREFIX = "a.k.a. "
|
13
|
+
SERIALIZATION_PREFIX = "- ".freeze
|
14
|
+
NICKNAME_PREFIX = "a.k.a. ".freeze
|
15
15
|
|
16
16
|
# @return [Regexp] the regex for capturing groups in deserialization
|
17
17
|
def self.deserialization_regex
|
@@ -60,9 +60,7 @@ module Friends
|
|
60
60
|
end.join(" ") + ")"
|
61
61
|
end
|
62
62
|
|
63
|
-
unless @location_name.nil?
|
64
|
-
location_str = " [#{Paint[@location_name, :bold, :yellow]}]"
|
65
|
-
end
|
63
|
+
location_str = " [#{Paint[@location_name, :bold, :yellow]}]" unless @location_name.nil?
|
66
64
|
|
67
65
|
tag_str = " #{Paint[@tags.join(' '), :bold, :cyan]}" unless @tags.empty?
|
68
66
|
|
@@ -78,9 +76,7 @@ module Friends
|
|
78
76
|
|
79
77
|
# @param tag [String] the tag to remove, of the format: "@tag"
|
80
78
|
def remove_tag(tag)
|
81
|
-
unless @tags.include? tag
|
82
|
-
raise FriendsError, "Tag \"#{tag}\" not found for \"#{name}\""
|
83
|
-
end
|
79
|
+
raise FriendsError, "Tag \"#{tag}\" not found for \"#{name}\"" unless @tags.include? tag
|
84
80
|
|
85
81
|
@tags.delete(tag)
|
86
82
|
end
|
data/lib/friends/graph.rb
CHANGED
@@ -4,16 +4,17 @@
|
|
4
4
|
|
5
5
|
module Friends
|
6
6
|
class Graph
|
7
|
-
DATE_FORMAT = "%b %Y"
|
7
|
+
DATE_FORMAT = "%b %Y".freeze # rubocop:disable Style/FormatStringToken
|
8
8
|
|
9
9
|
# @param activities [Array<Friends::Activity>] a list of activities to graph
|
10
10
|
def initialize(filtered_activities:, all_activities:)
|
11
11
|
@filtered_activities = filtered_activities
|
12
12
|
@all_activities = all_activities
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
13
|
+
|
14
|
+
return if @all_activities.empty?
|
15
|
+
|
16
|
+
@start_date = @all_activities.last.date
|
17
|
+
@end_date = @all_activities.first.date
|
17
18
|
end
|
18
19
|
|
19
20
|
# Prints the graph to STDOUT, with colors.
|
data/lib/friends/introvert.rb
CHANGED
@@ -14,10 +14,10 @@ require "friends/friends_error"
|
|
14
14
|
|
15
15
|
module Friends
|
16
16
|
class Introvert
|
17
|
-
DEFAULT_FILENAME = "./friends.md"
|
18
|
-
ACTIVITIES_HEADER = "### Activities:"
|
19
|
-
FRIENDS_HEADER = "### Friends:"
|
20
|
-
LOCATIONS_HEADER = "### Locations:"
|
17
|
+
DEFAULT_FILENAME = "./friends.md".freeze
|
18
|
+
ACTIVITIES_HEADER = "### Activities:".freeze
|
19
|
+
FRIENDS_HEADER = "### Friends:".freeze
|
20
|
+
LOCATIONS_HEADER = "### Locations:".freeze
|
21
21
|
|
22
22
|
# @param filename [String] the name of the friends Markdown file
|
23
23
|
def initialize(filename: DEFAULT_FILENAME)
|
@@ -32,7 +32,7 @@ module Friends
|
|
32
32
|
def clean
|
33
33
|
File.open(@filename, "w") do |file|
|
34
34
|
file.puts(ACTIVITIES_HEADER)
|
35
|
-
@activities.
|
35
|
+
stable_sort(@activities).each { |act| file.puts(act.serialize) }
|
36
36
|
file.puts # Blank line separating activities from friends.
|
37
37
|
file.puts(FRIENDS_HEADER)
|
38
38
|
@friends.sort.each { |friend| file.puts(friend.serialize) }
|
@@ -471,6 +471,12 @@ module Friends
|
|
471
471
|
|
472
472
|
private
|
473
473
|
|
474
|
+
# @param arr [Array] an unsorted array
|
475
|
+
# @return [Array] a stably-sorted array
|
476
|
+
def stable_sort(arr)
|
477
|
+
arr.sort_by.with_index { |x, idx| [x, idx] }
|
478
|
+
end
|
479
|
+
|
474
480
|
# Filter activities by friend, location and tag
|
475
481
|
# @param with [Array<String>] the names of friends to filter by, or empty for
|
476
482
|
# unfiltered
|
@@ -652,7 +658,7 @@ module Friends
|
|
652
658
|
|
653
659
|
begin
|
654
660
|
instance_variable_get("@#{stage.id}") << stage.klass.deserialize(line)
|
655
|
-
rescue => e
|
661
|
+
rescue => e # rubocop:disable Style/RescueStandardError
|
656
662
|
bad_line(e, line_num)
|
657
663
|
end
|
658
664
|
|
data/lib/friends/location.rb
CHANGED
@@ -6,26 +6,26 @@ module Friends
|
|
6
6
|
class RegexBuilder
|
7
7
|
# We don't want to match strings that are "escaped" with a leading
|
8
8
|
# backslash.
|
9
|
-
NO_LEADING_BACKSLASH = "(?<!\\\\)"
|
9
|
+
NO_LEADING_BACKSLASH = "(?<!\\\\)".freeze
|
10
10
|
|
11
11
|
# We don't want to match strings that are directly touching double asterisks
|
12
12
|
# as these are treated as sacred by our program.
|
13
|
-
NO_LEADING_ASTERISKS = "(?<!\\*\\*)"
|
14
|
-
NO_TRAILING_ASTERISKS = "(?!\\*\\*)"
|
13
|
+
NO_LEADING_ASTERISKS = "(?<!\\*\\*)".freeze
|
14
|
+
NO_TRAILING_ASTERISKS = "(?!\\*\\*)".freeze
|
15
15
|
|
16
16
|
# We don't want to match strings that are directly touching underscores
|
17
17
|
# as these are treated as sacred by our program.
|
18
|
-
NO_LEADING_UNDERSCORES = "(?<!_)"
|
19
|
-
NO_TRAILING_UNDERSCORES = "(?!_)"
|
18
|
+
NO_LEADING_UNDERSCORES = "(?<!_)".freeze
|
19
|
+
NO_TRAILING_UNDERSCORES = "(?!_)".freeze
|
20
20
|
|
21
21
|
# We don't want to match strings that are part of other words.
|
22
|
-
NO_LEADING_ALPHABETICALS = "(?<![A-z])"
|
23
|
-
NO_TRAILING_ALPHABETICALS = "(?![A-z])"
|
22
|
+
NO_LEADING_ALPHABETICALS = "(?<![A-z])".freeze
|
23
|
+
NO_TRAILING_ALPHABETICALS = "(?![A-z])".freeze
|
24
24
|
|
25
25
|
# We ignore case within the regex as opposed to globally to allow consumers
|
26
26
|
# of this API the ability to pass in strings that turn off this modifier
|
27
27
|
# with the "(?-i)" string.
|
28
|
-
IGNORE_CASE = "(?i)"
|
28
|
+
IGNORE_CASE = "(?i)".freeze
|
29
29
|
|
30
30
|
def self.regex(str)
|
31
31
|
Regexp.new(
|
data/lib/friends/version.rb
CHANGED
@@ -328,7 +328,9 @@ clean_describe "add activity" do
|
|
328
328
|
let(:content) do
|
329
329
|
<<-FILE
|
330
330
|
### Activities:
|
331
|
+
- 2018-01-01: Activity one year later.
|
331
332
|
- 2017-01-01: Activity 1.
|
333
|
+
- 2016-01-01: Activity one year earlier.
|
332
334
|
|
333
335
|
### Friends:
|
334
336
|
|
@@ -337,19 +339,22 @@ FILE
|
|
337
339
|
end
|
338
340
|
|
339
341
|
subject do
|
340
|
-
|
341
|
-
|
342
|
-
|
342
|
+
4.times do |i|
|
343
|
+
run_cmd("add activity 2017-01-01: Activity #{i + 2}.")
|
344
|
+
end
|
343
345
|
end
|
344
346
|
|
345
347
|
it "orders dates by insertion time" do
|
346
348
|
subject
|
347
349
|
File.read(filename).must_equal <<-FILE
|
348
350
|
### Activities:
|
351
|
+
- 2018-01-01: Activity one year later.
|
352
|
+
- 2017-01-01: Activity 5.
|
349
353
|
- 2017-01-01: Activity 4.
|
350
354
|
- 2017-01-01: Activity 3.
|
351
355
|
- 2017-01-01: Activity 2.
|
352
356
|
- 2017-01-01: Activity 1.
|
357
|
+
- 2016-01-01: Activity one year earlier.
|
353
358
|
|
354
359
|
### Friends:
|
355
360
|
|
data/test/commands/help_spec.rb
CHANGED
@@ -37,7 +37,7 @@ clean_describe "help" do
|
|
37
37
|
describe "with an invalid subcommand passed" do
|
38
38
|
subject { run_cmd("help garbage") }
|
39
39
|
|
40
|
-
# FIXME uncomment!!!
|
40
|
+
# FIXME: uncomment!!!
|
41
41
|
# Waiting for: https://github.com/davetron5000/gli/issues/255
|
42
42
|
# it "prints an error message" do
|
43
43
|
# stderr_only "error: Unknown command 'garbage'. Use 'friends help' for a list of commands."
|
data/test/helper.rb
CHANGED
@@ -24,7 +24,7 @@ require "securerandom"
|
|
24
24
|
|
25
25
|
require "friends"
|
26
26
|
|
27
|
-
CONTENT = <<-FILE
|
27
|
+
CONTENT = <<-FILE.freeze
|
28
28
|
### Activities:
|
29
29
|
- 2015-11-01: **Grace Hopper** and I went to _Marie's Diner_. George had to cancel at the last minute. @food
|
30
30
|
- 2015-01-04: Got lunch with **Grace Hopper** and **George Washington Carver**. @food
|
@@ -43,7 +43,7 @@ CONTENT = <<-FILE
|
|
43
43
|
FILE
|
44
44
|
|
45
45
|
# This is CONTENT but with activities, friends, and locations unsorted.
|
46
|
-
SCRAMBLED_CONTENT = <<-FILE
|
46
|
+
SCRAMBLED_CONTENT = <<-FILE.freeze
|
47
47
|
### Activities:
|
48
48
|
- 2015-01-04: Got lunch with **Grace Hopper** and **George Washington Carver**. @food
|
49
49
|
- 2015-11-01: **Grace Hopper** and I went to _Marie's Diner_. George had to cancel at the last minute. @food
|
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.
|
4
|
+
version: '0.34'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jacob Evelyn
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-01-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: chronic
|