nin 0.0.0 → 0.7.0
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 +4 -4
- data/.gitignore +2 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +29 -0
- data/LICENSE +21 -0
- data/README.md +67 -0
- data/Rakefile +9 -0
- data/bin/nin +11 -0
- data/demo.gif +0 -0
- data/lib/nin.rb +16 -59
- data/lib/nin/command.rb +76 -0
- data/lib/nin/error.rb +4 -0
- data/lib/nin/item.rb +60 -0
- data/lib/nin/item_presenter.rb +49 -0
- data/lib/nin/parser.rb +41 -0
- data/lib/nin/todo.rb +130 -0
- data/lib/nin/toml_store.rb +31 -0
- data/lib/nin/version.rb +3 -0
- data/lib/nin/yaml_store.rb +31 -0
- data/nin.gemspec +27 -0
- metadata +97 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e69e3a795983376ba5be5fd6bd9b639dcb8856cf11585e52cb2493b701e98ab4
|
4
|
+
data.tar.gz: 4e3662bb0d5e87243eb78d20619e5a33904c586e158a3e4fa067ebd098e6e0d1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 72afcf6252cd03732ebd9b1e03d9eb0fc209aaf22edc1de4760be1a0d5e89ee2cf01210dd915cd0cb01d3d23700552e45e7de9738ebcd76b86b196d432a416e7
|
7
|
+
data.tar.gz: f6850697bc332effae708dcee96ef0b1f0812e8e254c8a9f7ad5bb3da57f35db6188c0d739dfb386be4dc03e1529d5ff7538051f69044210f9bf09cf0f311c8a
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
nin (0.6.0)
|
5
|
+
chronic
|
6
|
+
colored2
|
7
|
+
toml-rb
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: https://rubygems.org/
|
11
|
+
specs:
|
12
|
+
byebug (10.0.2)
|
13
|
+
chronic (0.10.2)
|
14
|
+
citrus (3.0.2)
|
15
|
+
colored2 (3.1.2)
|
16
|
+
minitest (5.11.3)
|
17
|
+
toml-rb (1.1.2)
|
18
|
+
citrus (~> 3.0, > 3.0)
|
19
|
+
|
20
|
+
PLATFORMS
|
21
|
+
ruby
|
22
|
+
|
23
|
+
DEPENDENCIES
|
24
|
+
byebug
|
25
|
+
minitest
|
26
|
+
nin!
|
27
|
+
|
28
|
+
BUNDLED WITH
|
29
|
+
1.17.1
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2018 Ahmed Saleh
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
nin
|
2
|
+
---
|
3
|
+
|
4
|
+
A simple, full-featured command line todo app
|
5
|
+
|
6
|
+

|
7
|
+
|
8
|
+
## Features
|
9
|
+
|
10
|
+
- Simple, easy-to-use CLI
|
11
|
+
- Currently supports: listing, adding, editing, deleting, completing,
|
12
|
+
archiving, and deleting archived todo items
|
13
|
+
- Smart colored output
|
14
|
+
- Modular code covered by unit tests
|
15
|
+
- Uses YAML for storage by default
|
16
|
+
|
17
|
+
## Installation
|
18
|
+
|
19
|
+
```bash
|
20
|
+
gem install nin
|
21
|
+
```
|
22
|
+
|
23
|
+
To run the tests:
|
24
|
+
|
25
|
+
```console
|
26
|
+
rake
|
27
|
+
```
|
28
|
+
|
29
|
+
## Usage
|
30
|
+
|
31
|
+
```console
|
32
|
+
NAME:
|
33
|
+
nin - a simple, full-featured command line todo app
|
34
|
+
|
35
|
+
USAGE:
|
36
|
+
nin COMMAND [arguments...]
|
37
|
+
|
38
|
+
COMMANDS:
|
39
|
+
l [a] List all unarchived todos. Pass optional argument `a` to list all todos
|
40
|
+
a desc Add a todo. Prepend due date by an @. Prepend tag by a \#
|
41
|
+
e id desc Edit a todo. Prepend due date by an @. Prepend tag by a \#
|
42
|
+
c id(s) Un/complete todo(s)
|
43
|
+
ac id(s) Un/archive todo(s)
|
44
|
+
d id(s) Delete todo(s)
|
45
|
+
gc Delete all archived todos. Resets item ids as a side effect
|
46
|
+
o Open todo file in $EDITOR
|
47
|
+
```
|
48
|
+
|
49
|
+
## Why
|
50
|
+
|
51
|
+
Why write another todo app? I like to use the terminal for everything and I've
|
52
|
+
been using a markdown file to manage my todo list. I looked for something
|
53
|
+
simple and I found [Todo.rb](https://gist.github.com/mattsears/1259080) which
|
54
|
+
`nin` started as a spinoff from. However, I needed to add some more features. I
|
55
|
+
then found [Todolist](http://todolist.site/) which I took some inspiration from
|
56
|
+
but kept the CLI as simple as it is in Todo.rb. I also didn't like that
|
57
|
+
todolist uses JSON to store the todo items because I wanted to view the file on
|
58
|
+
my phone and I needed something more readable.
|
59
|
+
|
60
|
+
## Contribution
|
61
|
+
|
62
|
+
Contributions are welcome. If you found a bug or want to add a new feature,
|
63
|
+
open an issue or send a pull request.
|
64
|
+
|
65
|
+
## License
|
66
|
+
|
67
|
+
See [LICENSE](https://github.com/aonemd/nin/blob/master/LICENSE).
|
data/Rakefile
ADDED
data/bin/nin
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require_relative '../lib/nin'
|
4
|
+
|
5
|
+
begin
|
6
|
+
Nin::Command.new(ARGV[0], ARGV[1..-1]).call
|
7
|
+
rescue Nin::ItemNotFoundError
|
8
|
+
puts "Todo item does not exist"
|
9
|
+
rescue Nin::EmptyCommandArgumentError
|
10
|
+
puts "Command argument cannot be empty\nRun nin to view the USAGE message"
|
11
|
+
end
|
data/demo.gif
ADDED
Binary file
|
data/lib/nin.rb
CHANGED
@@ -1,59 +1,16 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
def initialize()
|
18
|
-
@items = load_items
|
19
|
-
end
|
20
|
-
|
21
|
-
def list
|
22
|
-
end
|
23
|
-
|
24
|
-
def add(todo)
|
25
|
-
end
|
26
|
-
|
27
|
-
def edit(id)
|
28
|
-
end
|
29
|
-
|
30
|
-
def delete(id)
|
31
|
-
end
|
32
|
-
|
33
|
-
private
|
34
|
-
|
35
|
-
def load_items
|
36
|
-
[]
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
if __FILE__ == $0
|
42
|
-
case ARGV[0]
|
43
|
-
when 'l'
|
44
|
-
Nin::Todo.new.list
|
45
|
-
when 'a'
|
46
|
-
Nin::Todo.new.add(ARGV[1])
|
47
|
-
when 'e'
|
48
|
-
Nin::Todo.new.edit(ARGV[1])
|
49
|
-
when 'd'
|
50
|
-
Nin::Todo.new.delete(ARGV[1])
|
51
|
-
else
|
52
|
-
puts "\nUSAGE: nin COMMAND [arguments...]\n\n"
|
53
|
-
puts "COMMANDS:"
|
54
|
-
puts " l List all todos"
|
55
|
-
puts " a desc Add a todo"
|
56
|
-
puts " e id Edit a todo"
|
57
|
-
puts " d id Remove a todo"
|
58
|
-
end
|
59
|
-
end
|
1
|
+
require 'psych'
|
2
|
+
require 'toml-rb'
|
3
|
+
require 'chronic'
|
4
|
+
require 'colored2'
|
5
|
+
require 'date'
|
6
|
+
require 'readline'
|
7
|
+
|
8
|
+
require_relative 'nin/version'
|
9
|
+
require_relative 'nin/error'
|
10
|
+
require_relative 'nin/yaml_store'
|
11
|
+
require_relative 'nin/toml_store'
|
12
|
+
require_relative 'nin/parser'
|
13
|
+
require_relative 'nin/item_presenter'
|
14
|
+
require_relative 'nin/item'
|
15
|
+
require_relative 'nin/todo'
|
16
|
+
require_relative 'nin/command'
|
data/lib/nin/command.rb
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
module Nin
|
2
|
+
class Command
|
3
|
+
COMMANDS_WITH_ARGS = %w(a e c ac d)
|
4
|
+
|
5
|
+
def initialize(command, args)
|
6
|
+
@command = command
|
7
|
+
@args = args
|
8
|
+
@todo = Todo.new(YamlStore.new, collect_options)
|
9
|
+
|
10
|
+
validate_args
|
11
|
+
end
|
12
|
+
|
13
|
+
def call
|
14
|
+
case @command
|
15
|
+
when 'l'
|
16
|
+
@todo.list
|
17
|
+
when 'a'
|
18
|
+
desc, date, tags = Parser.new(@args.join(' ')).call
|
19
|
+
@todo.add(desc, date, tags)
|
20
|
+
when 'e'
|
21
|
+
desc, date, tags = Parser.new(@args[1..-1].join(' ')).call
|
22
|
+
@todo.edit(@args[0].to_i, desc, date, tags)
|
23
|
+
when 'c'
|
24
|
+
@todo.complete(*@args)
|
25
|
+
when 'ac'
|
26
|
+
@todo.archive(*@args)
|
27
|
+
when 'd'
|
28
|
+
@todo.delete(*@args)
|
29
|
+
when 'gc'
|
30
|
+
@todo.delete_archived
|
31
|
+
when 'o'
|
32
|
+
system("`echo $EDITOR` #{@todo.store.file}")
|
33
|
+
when 'i'
|
34
|
+
run_interactive_mode
|
35
|
+
else
|
36
|
+
puts "NAME:\n\tnin - a simple, full-featured command line todo app"
|
37
|
+
puts "\nUSAGE:\n\tnin COMMAND [arguments...]"
|
38
|
+
puts "\nCOMMANDS:"
|
39
|
+
puts "\tl [a] List all unarchived todos. Pass optional argument `a` to list all todos"
|
40
|
+
puts "\ta desc Add a todo. Prepend due date by a @. Prepend each tag by a \\#"
|
41
|
+
puts "\te id desc Edit a todo. Prepend due date by a @. Prepend each tag by a \\#"
|
42
|
+
puts "\tc id(s) Un/complete todo(s)"
|
43
|
+
puts "\tac id(s) Un/archive todo(s)"
|
44
|
+
puts "\td id(s) Delete todo(s)"
|
45
|
+
puts "\tgc Delete all archived todos. Resets item ids as a side effect"
|
46
|
+
puts "\to Open todo file in $EDITOR"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def collect_options
|
53
|
+
options = { archived: false }
|
54
|
+
|
55
|
+
if @command == 'l' && @args[0] == 'a'
|
56
|
+
options[:archived] = true
|
57
|
+
end
|
58
|
+
|
59
|
+
options
|
60
|
+
end
|
61
|
+
|
62
|
+
def validate_args
|
63
|
+
COMMANDS_WITH_ARGS.each do |command|
|
64
|
+
raise EmptyCommandArgumentError if @command == command && @args.empty?
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def run_interactive_mode
|
69
|
+
while line = Readline.readline("nin> ", true)
|
70
|
+
line = line.split(' ')
|
71
|
+
|
72
|
+
Command.new(line[0], line[1..-1]).call
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
data/lib/nin/error.rb
ADDED
data/lib/nin/item.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
module Nin
|
2
|
+
class Item
|
3
|
+
attr_accessor :id, :desc, :date, :tags, :completed, :archived
|
4
|
+
|
5
|
+
def initialize(id,
|
6
|
+
desc,
|
7
|
+
date = nil,
|
8
|
+
tags = [],
|
9
|
+
completed = false,
|
10
|
+
archived = false,
|
11
|
+
formatter = ItemPresenter)
|
12
|
+
|
13
|
+
@id = id
|
14
|
+
@desc = desc
|
15
|
+
self.date = date # this looks ugly
|
16
|
+
@tags = tags
|
17
|
+
@completed = completed
|
18
|
+
@archived = archived
|
19
|
+
@formatter = formatter.new(self)
|
20
|
+
end
|
21
|
+
|
22
|
+
def date=(date = nil)
|
23
|
+
@date = date || Date.today.to_s
|
24
|
+
end
|
25
|
+
|
26
|
+
def toggle_completed!
|
27
|
+
@completed = !@completed
|
28
|
+
end
|
29
|
+
|
30
|
+
def toggle_archived!
|
31
|
+
@archived = !@archived
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_s
|
35
|
+
@formatter.call
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_h
|
39
|
+
{
|
40
|
+
'id' => id,
|
41
|
+
'desc' => desc,
|
42
|
+
'tags' => tags,
|
43
|
+
'completed' => completed,
|
44
|
+
'archived' => archived
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
def completed?
|
49
|
+
@completed
|
50
|
+
end
|
51
|
+
|
52
|
+
def archived?
|
53
|
+
@archived
|
54
|
+
end
|
55
|
+
|
56
|
+
def due?
|
57
|
+
@date < Date.today.to_s
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Nin
|
2
|
+
class ItemPresenter < SimpleDelegator
|
3
|
+
def call
|
4
|
+
sprintf("%d\t%s\t%s \t%s %s",
|
5
|
+
id, completed, date, desc, tags).gsub(' ', ' ')
|
6
|
+
end
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def desc
|
11
|
+
if self.archived?
|
12
|
+
self.desc.yellow
|
13
|
+
elsif self.completed?
|
14
|
+
self.desc.white
|
15
|
+
else
|
16
|
+
self.desc
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def completed
|
21
|
+
if self.completed?
|
22
|
+
'[x]'.green
|
23
|
+
else
|
24
|
+
'[ ]'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def date
|
29
|
+
case self.date
|
30
|
+
when Date.today.to_s
|
31
|
+
'@today'.bold
|
32
|
+
when Date.today.succ.to_s
|
33
|
+
'@tomorrow'
|
34
|
+
when Date.today.prev_day.to_s
|
35
|
+
'@yesterday'.magenta
|
36
|
+
else
|
37
|
+
if self.due?
|
38
|
+
('@' << self.date).magenta
|
39
|
+
else
|
40
|
+
'@' << self.date
|
41
|
+
end
|
42
|
+
end.cyan
|
43
|
+
end
|
44
|
+
|
45
|
+
def tags
|
46
|
+
self.tags.map { |tag| tag.dup.prepend('#') }.join(' ').blue
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/lib/nin/parser.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
module Nin
|
2
|
+
class Parser
|
3
|
+
def initialize(desc)
|
4
|
+
@desc = desc
|
5
|
+
@date = extract_date
|
6
|
+
@tags = extract_tags
|
7
|
+
end
|
8
|
+
|
9
|
+
def call
|
10
|
+
[@desc, @date, @tags]
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def extract_date
|
16
|
+
date_pattern = /@[A-Z0-9.,-]+/i
|
17
|
+
date = @desc.scan(date_pattern).last
|
18
|
+
|
19
|
+
return nil if date.nil?
|
20
|
+
|
21
|
+
date.gsub!('@', '')
|
22
|
+
strip_tags(date_pattern)
|
23
|
+
|
24
|
+
Chronic.parse(date).strftime('%Y-%m-%d')
|
25
|
+
end
|
26
|
+
|
27
|
+
def extract_tags
|
28
|
+
tag_pattern = /#[A-Z0-9_]+/i
|
29
|
+
tags = @desc.scan(tag_pattern).map { |tag| tag.gsub!('#', '') }
|
30
|
+
|
31
|
+
strip_tags(tag_pattern)
|
32
|
+
|
33
|
+
tags
|
34
|
+
end
|
35
|
+
|
36
|
+
def strip_tags(pattern)
|
37
|
+
@desc.gsub!(pattern, '')
|
38
|
+
@desc.strip!
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/nin/todo.rb
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
module Nin
|
2
|
+
class Todo
|
3
|
+
attr_accessor :items
|
4
|
+
attr_reader :store
|
5
|
+
|
6
|
+
def initialize(store = YamlStore.new, options = {})
|
7
|
+
@store = store
|
8
|
+
@options = options
|
9
|
+
@items = load_items.sort_by(&:date)
|
10
|
+
end
|
11
|
+
|
12
|
+
def list
|
13
|
+
if @options[:archived]
|
14
|
+
@items
|
15
|
+
else
|
16
|
+
unarchived_items
|
17
|
+
end.each do |item|
|
18
|
+
puts item
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def add(desc, date, tags)
|
23
|
+
@items << Item.new(next_id, desc, date, tags)
|
24
|
+
@store.write(to_hash)
|
25
|
+
end
|
26
|
+
|
27
|
+
def edit(id, desc, date, tags)
|
28
|
+
item = find_by_id(id)
|
29
|
+
item.desc = desc
|
30
|
+
item.date = date
|
31
|
+
item.tags = tags
|
32
|
+
@store.write(to_hash)
|
33
|
+
end
|
34
|
+
|
35
|
+
def complete(*ids)
|
36
|
+
ids.each do |id|
|
37
|
+
item = find_by_id(id.to_i)
|
38
|
+
item.toggle_completed!
|
39
|
+
end
|
40
|
+
|
41
|
+
@store.write(to_hash)
|
42
|
+
end
|
43
|
+
|
44
|
+
def archive(*ids)
|
45
|
+
ids.each do |id|
|
46
|
+
item = find_by_id(id.to_i)
|
47
|
+
item.toggle_archived!
|
48
|
+
end
|
49
|
+
|
50
|
+
@store.write(to_hash)
|
51
|
+
end
|
52
|
+
|
53
|
+
def delete_archived
|
54
|
+
delete(*archived_items.map(&:id))
|
55
|
+
reset_item_indices!
|
56
|
+
end
|
57
|
+
|
58
|
+
def delete(*ids)
|
59
|
+
ids.each do |id|
|
60
|
+
item = find_by_id(id.to_i)
|
61
|
+
@items.delete(item)
|
62
|
+
end
|
63
|
+
|
64
|
+
reset_item_indices!
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def load_items
|
70
|
+
items = []
|
71
|
+
@store.read.map do |key, values|
|
72
|
+
date = key.dup
|
73
|
+
values.map do |item|
|
74
|
+
items << Item.new(item.fetch('id').to_i,
|
75
|
+
item.fetch('desc'),
|
76
|
+
date,
|
77
|
+
item.fetch('tags'),
|
78
|
+
item.fetch('completed'),
|
79
|
+
item.fetch('archived')
|
80
|
+
)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
items
|
85
|
+
end
|
86
|
+
|
87
|
+
def to_hash
|
88
|
+
@items.group_by(&:date).reduce({}) do |hash, (key, values)|
|
89
|
+
hash[key] = values.map(&:to_h)
|
90
|
+
hash
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def next_id
|
95
|
+
last_id + 1
|
96
|
+
end
|
97
|
+
|
98
|
+
def last_id
|
99
|
+
begin
|
100
|
+
@items.sort_by(&:id).last.id
|
101
|
+
rescue NoMethodError
|
102
|
+
0
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def find_by_id(id)
|
107
|
+
found_item = @items.find { |item| item.id == id }
|
108
|
+
|
109
|
+
raise ItemNotFoundError unless found_item
|
110
|
+
|
111
|
+
found_item
|
112
|
+
end
|
113
|
+
|
114
|
+
def archived_items
|
115
|
+
@items.select { |item| item.archived? }
|
116
|
+
end
|
117
|
+
|
118
|
+
def unarchived_items
|
119
|
+
@items.select { |item| !item.archived? }
|
120
|
+
end
|
121
|
+
|
122
|
+
def reset_item_indices!
|
123
|
+
@items.each.with_index(1) do |item, index|
|
124
|
+
item.id = index
|
125
|
+
end
|
126
|
+
|
127
|
+
@store.write(to_hash)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Nin
|
2
|
+
class TomlStore
|
3
|
+
DEFAULT_FILE = "#{ENV['HOME']}/.todos.toml"
|
4
|
+
|
5
|
+
attr_reader :file
|
6
|
+
|
7
|
+
def initialize(file = DEFAULT_FILE)
|
8
|
+
@file = file
|
9
|
+
|
10
|
+
init_store
|
11
|
+
end
|
12
|
+
|
13
|
+
def read
|
14
|
+
TomlRB.load_file(@file)
|
15
|
+
end
|
16
|
+
|
17
|
+
def write(hash)
|
18
|
+
File.open(@file, 'w') do |file|
|
19
|
+
file.write(TomlRB.dump(hash))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def init_store
|
26
|
+
return if File.exist?(@file)
|
27
|
+
|
28
|
+
File.open(@file, "w")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/nin/version.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
module Nin
|
2
|
+
class YamlStore
|
3
|
+
DEFAULT_FILE = "#{ENV['HOME']}/.todos.yaml"
|
4
|
+
|
5
|
+
attr_reader :file
|
6
|
+
|
7
|
+
def initialize(file = DEFAULT_FILE)
|
8
|
+
@file = file
|
9
|
+
|
10
|
+
init_store
|
11
|
+
end
|
12
|
+
|
13
|
+
def read
|
14
|
+
Psych.load_file(@file) || {} # Psych returns false if the file is empty
|
15
|
+
end
|
16
|
+
|
17
|
+
def write(hash)
|
18
|
+
File.open(@file, 'w') do |file|
|
19
|
+
file.write(Psych.dump(hash))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def init_store
|
26
|
+
return if File.exist?(@file)
|
27
|
+
|
28
|
+
File.open(@file, "w")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/nin.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require File.expand_path('../lib/nin/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Ahmed Saleh"]
|
6
|
+
gem.email = 'aonemdsaleh@gmail.com'
|
7
|
+
gem.description = "A simple, full-featured command line todo app"
|
8
|
+
gem.summary = "A command line todo app that provides an easy to use CLI for everyday todo management"
|
9
|
+
gem.homepage = 'https://github.com/aonemd/nin'
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\).reject do |f|
|
12
|
+
f.match(%r{^(test|spec|features)/})
|
13
|
+
end
|
14
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
15
|
+
gem.executables = ["nin"]
|
16
|
+
|
17
|
+
gem.name = 'nin'
|
18
|
+
gem.version = Nin::VERSION
|
19
|
+
gem.license = 'MIT'
|
20
|
+
|
21
|
+
gem.add_dependency 'toml-rb'
|
22
|
+
gem.add_dependency 'chronic'
|
23
|
+
gem.add_dependency 'colored2'
|
24
|
+
|
25
|
+
gem.add_development_dependency 'byebug'
|
26
|
+
gem.add_development_dependency 'minitest'
|
27
|
+
end
|
metadata
CHANGED
@@ -1,23 +1,112 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ahmed Saleh
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-12-
|
12
|
-
dependencies:
|
13
|
-
|
11
|
+
date: 2018-12-24 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: toml-rb
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: chronic
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: colored2
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: byebug
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: minitest
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description: A simple, full-featured command line todo app
|
14
84
|
email: aonemdsaleh@gmail.com
|
15
|
-
executables:
|
85
|
+
executables:
|
86
|
+
- nin
|
16
87
|
extensions: []
|
17
88
|
extra_rdoc_files: []
|
18
89
|
files:
|
90
|
+
- ".gitignore"
|
91
|
+
- Gemfile
|
92
|
+
- Gemfile.lock
|
93
|
+
- LICENSE
|
94
|
+
- README.md
|
95
|
+
- Rakefile
|
96
|
+
- bin/nin
|
97
|
+
- demo.gif
|
19
98
|
- lib/nin.rb
|
20
|
-
|
99
|
+
- lib/nin/command.rb
|
100
|
+
- lib/nin/error.rb
|
101
|
+
- lib/nin/item.rb
|
102
|
+
- lib/nin/item_presenter.rb
|
103
|
+
- lib/nin/parser.rb
|
104
|
+
- lib/nin/todo.rb
|
105
|
+
- lib/nin/toml_store.rb
|
106
|
+
- lib/nin/version.rb
|
107
|
+
- lib/nin/yaml_store.rb
|
108
|
+
- nin.gemspec
|
109
|
+
homepage: https://github.com/aonemd/nin
|
21
110
|
licenses:
|
22
111
|
- MIT
|
23
112
|
metadata: {}
|
@@ -40,5 +129,6 @@ rubyforge_project:
|
|
40
129
|
rubygems_version: 2.7.6
|
41
130
|
signing_key:
|
42
131
|
specification_version: 4
|
43
|
-
summary:
|
132
|
+
summary: A command line todo app that provides an easy to use CLI for everyday todo
|
133
|
+
management
|
44
134
|
test_files: []
|