my_todo 3.1.1 → 4.0.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +63 -50
- data/Rakefile +3 -0
- data/bin/{my_todo → mytodo} +1 -1
- data/{lib/db → db}/config.yml +3 -3
- data/{lib/db → db}/migrate/20160912172429_create_items.rb +2 -2
- data/{lib/db → db}/migrate/20160913134552_create_tags.rb +1 -1
- data/{lib/db → db}/migrate/20160913134610_create_stubs.rb +1 -1
- data/{lib/db → db}/migrate/20161003121448_create_notes.rb +1 -1
- data/{lib/db → db}/migrate/20161005133023_add_detailed_status_to_items.rb +1 -1
- data/db/migrate/20161220143613_add_default_to_item_done.rb +5 -0
- data/{lib/db → db}/schema.rb +6 -14
- data/lib/my_todo.rb +4 -114
- data/lib/my_todo/ar_base.rb +3 -2
- data/lib/my_todo/models/item.rb +4 -0
- data/lib/my_todo/modules/actions.rb +129 -0
- data/lib/my_todo/modules/finders.rb +5 -3
- data/lib/my_todo/modules/my_todo_actions.rb +7 -6
- data/lib/my_todo/modules/templates.rb +1 -0
- data/lib/my_todo/templates/item.erb +6 -2
- data/lib/my_todo/templates/list.erb +3 -1
- data/lib/my_todo/templates/notes.erb +8 -5
- data/lib/my_todo/templates/results.erb +7 -1
- data/lib/my_todo/templates/standalone_migrations.yml.erb +4 -4
- data/lib/my_todo/version.rb +1 -1
- data/lib/setup.rb +2 -2
- data/my_todo.gemspec +19 -17
- data/spec/actions/create_spec.rb +17 -15
- data/spec/actions/delete_spec.rb +10 -4
- data/spec/actions/list_spec.rb +6 -5
- data/spec/actions/note_spec.rb +9 -7
- data/spec/actions/notes_spec.rb +6 -7
- data/spec/actions/rm_note_spec.rb +7 -8
- data/spec/actions/rm_tag_spec.rb +9 -8
- data/spec/actions/search_spec.rb +12 -13
- data/spec/actions/tag_spec.rb +12 -10
- data/spec/actions/update_spec.rb +5 -6
- data/{lib → spec}/db/todos_test.sqlite3 +0 -0
- data/spec/models/item_spec.rb +1 -1
- data/spec/models/stub_spec.rb +6 -6
- data/spec/spec_helper.rb +19 -5
- metadata +89 -76
- data/.standalone_migrations +0 -6
- data/lib/db/migrate/20161220143613_add_default_to_item_done.rb +0 -5
- data/lib/db/todos_development.sqlite3 +0 -0
- data/lib/my_todo/db/todos_test.sqlite3 +0 -0
data/lib/my_todo/ar_base.rb
CHANGED
@@ -5,9 +5,10 @@ module ArBase
|
|
5
5
|
# Set path based on bin/my_todo
|
6
6
|
path = case ENV['RAILS_ENV']
|
7
7
|
when 'development'
|
8
|
-
"#{__dir__}
|
8
|
+
"#{__dir__}/../../db/todos_development.sqlite3"
|
9
9
|
when 'test'
|
10
|
-
"#{__dir__}/../db/todos_test.sqlite3"
|
10
|
+
# "#{__dir__}/../db/todos_test.sqlite3"
|
11
|
+
"#{__dir__}/../../spec/db/todos_test.sqlite3"
|
11
12
|
else
|
12
13
|
File.expand_path("#{`echo $HOME`.chomp}/.my_todo/data/todos_production.sqlite3", __FILE__)
|
13
14
|
end
|
data/lib/my_todo/models/item.rb
CHANGED
@@ -0,0 +1,129 @@
|
|
1
|
+
module MyTodo
|
2
|
+
module Actions
|
3
|
+
def self.included(thor)
|
4
|
+
thor.class_eval do
|
5
|
+
|
6
|
+
desc 'list <STATUS>', 'List todo items. Default: undone, [all], [done], [undone]'
|
7
|
+
def list(status='undone')
|
8
|
+
@status = status
|
9
|
+
print_list
|
10
|
+
end
|
11
|
+
|
12
|
+
desc "create \"<BODY>\" <TAGS> [Default: general]>", 'Create a todo item with optional and tags'
|
13
|
+
def create(body, *tags)
|
14
|
+
@body = body
|
15
|
+
@tags = tags.any? ? tags : %w[Default]
|
16
|
+
|
17
|
+
begin
|
18
|
+
create_item
|
19
|
+
print_item
|
20
|
+
rescue ActiveRecord::RecordInvalid => e
|
21
|
+
say e.message
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
desc 'update <ID> "<BODY>" <DONE>', 'Update a todo item'
|
26
|
+
def update(id, body=nil, done=nil)
|
27
|
+
@item = Item.find_by_id(id)
|
28
|
+
@body = body.nil? ? @item.body : body
|
29
|
+
@done = done.nil? ? @item.done : done
|
30
|
+
|
31
|
+
begin
|
32
|
+
update_item
|
33
|
+
print_item
|
34
|
+
rescue ActiveRecord::RecordInvalid => e
|
35
|
+
say e.message
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
desc 'delete <ID>', 'Destroy a todo item'
|
40
|
+
# option :id, required: true
|
41
|
+
def delete(id)
|
42
|
+
@item = Item.find_by_id(id)
|
43
|
+
|
44
|
+
begin
|
45
|
+
item.destroy!
|
46
|
+
say 'Item Deleted'
|
47
|
+
rescue StandardError => e
|
48
|
+
say e.message
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
desc 'search "<TEXT>"', 'Find a todo by item body, tag name, status or note body'
|
53
|
+
def search(text="")
|
54
|
+
@text = text
|
55
|
+
@items = Item.ransack(body_or_detailed_status_or_tags_name_or_notes_body_cont: @text).result
|
56
|
+
print_search_results
|
57
|
+
end
|
58
|
+
|
59
|
+
desc 'tag <ID> <TAGS>', 'Add tags to a todo item'
|
60
|
+
def tag(id, *tags)
|
61
|
+
@item = Item.find_by_id(id)
|
62
|
+
|
63
|
+
begin
|
64
|
+
if tags.any?
|
65
|
+
@banner = "Tags added to todo #{@item.id}"
|
66
|
+
tags.each {|tag| @item.tags.create!(name: tag)}
|
67
|
+
@item = @item.reload
|
68
|
+
print_item
|
69
|
+
end
|
70
|
+
rescue StandardError => e
|
71
|
+
say e.message
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
desc 'rm_tag <ID> <TAGS>', 'Remove tags from a todo item'
|
76
|
+
def rm_tag(id, *tags)
|
77
|
+
@item = Item.find_by_id(id)
|
78
|
+
|
79
|
+
begin
|
80
|
+
if tags.any?
|
81
|
+
@banner = "Tags removed from item #{@item.id}"
|
82
|
+
@item.tags.where(name: tags).destroy_all
|
83
|
+
print_item
|
84
|
+
end
|
85
|
+
rescue StandardError => e
|
86
|
+
say e.message
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
desc 'note <ID> "<TEXT>"', 'Adds note to a todo item'
|
91
|
+
def note(id, text="")
|
92
|
+
@item = Item.find_by_id(id)
|
93
|
+
|
94
|
+
begin
|
95
|
+
@item.notes.create(body: text) unless text.empty?
|
96
|
+
print_notes
|
97
|
+
rescue StandardError => e
|
98
|
+
say e.message
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
desc 'rm_note <ID> <NOTE_IDS>', 'Remove notes from todo item'
|
103
|
+
def rm_note(id, *note_ids)
|
104
|
+
@item = Item.find_by_id(id)
|
105
|
+
|
106
|
+
begin
|
107
|
+
@banner = "Note removed from item: #{@item.id}"
|
108
|
+
@item.notes.where(id: note_ids).destroy_all
|
109
|
+
print_item
|
110
|
+
rescue StandardError => e
|
111
|
+
say e.message
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
desc 'notes <ID>', 'Display notes for a todo item'
|
116
|
+
def notes(id)
|
117
|
+
@item = Item.find_by_id(id)
|
118
|
+
|
119
|
+
begin
|
120
|
+
print_notes
|
121
|
+
rescue StandardError => e
|
122
|
+
say e.message
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module Finders
|
2
2
|
def item
|
3
|
-
@item ||= Item.
|
3
|
+
@item ||= Item.find_by_id(@id)
|
4
4
|
end
|
5
5
|
|
6
6
|
def item_notes
|
@@ -8,13 +8,15 @@ module Finders
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def all_items
|
11
|
-
@items = case
|
11
|
+
@items = case @status
|
12
12
|
when 'all'
|
13
13
|
Item.all
|
14
14
|
when 'done'
|
15
15
|
Item.where(done: true)
|
16
|
-
|
16
|
+
when 'undone'
|
17
17
|
Item.where(done: false)
|
18
|
+
else
|
19
|
+
say 'Unknown status!'
|
18
20
|
end
|
19
21
|
end
|
20
22
|
|
@@ -4,16 +4,17 @@ module MyTodoActions
|
|
4
4
|
@status = ask("Choose a status for item", default: set_default_status)
|
5
5
|
end
|
6
6
|
|
7
|
-
def create_item
|
8
|
-
@
|
7
|
+
def create_item
|
8
|
+
@banner = 'Item Created'
|
9
|
+
@item = Item.new(body: @body)
|
9
10
|
assign_detailed_status
|
10
11
|
@item.save!
|
11
12
|
set_tags
|
12
13
|
end
|
13
14
|
|
14
|
-
def update_item
|
15
|
-
|
16
|
-
@item
|
15
|
+
def update_item
|
16
|
+
@banner = 'Item Updated'
|
17
|
+
@item.assign_attributes(body: @body, done: @done)
|
17
18
|
assign_detailed_status
|
18
19
|
item.save!
|
19
20
|
end
|
@@ -24,7 +25,7 @@ module MyTodoActions
|
|
24
25
|
end
|
25
26
|
|
26
27
|
def set_tags
|
27
|
-
|
28
|
+
@tags.each{|tag| @item.tags.create(name: tag) } if @tags
|
28
29
|
end
|
29
30
|
|
30
31
|
def set_default_status
|
@@ -1,2 +1,6 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
<%= @banner %>
|
2
|
+
|
3
|
+
id: <%= @item.id %> notes: <%= @item.notes.size %> tags: <%= @item.tags.map(&:name).join(', ') %>
|
4
|
+
created: <%= @item.created_at.strftime("%Y-%m-%d") %> status: <%= @item.detailed_status %> (done: <%= @item.done? %>)
|
5
|
+
|
6
|
+
<%= @item.body %>
|
@@ -1,6 +1,8 @@
|
|
1
|
+
Items Found: <%= @items.count %>
|
1
2
|
|
2
3
|
<% @items.each do |item| -%>
|
3
|
-
|
4
|
+
id: <%= item.id %> notes: <%= item.notes.size %> tags: <%= item.tags.map(&:name).join(', ') %>
|
5
|
+
created: <%= item.created_at.strftime("%Y-%m-%d") %> status: <%= item.detailed_status %> (done: <%= item.done? %>)
|
4
6
|
|
5
7
|
<%= item.body %>
|
6
8
|
<%= '*' * 100 %>
|
@@ -1,9 +1,12 @@
|
|
1
|
-
<% if
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
<% if @item.notes.any? -%>
|
2
|
+
notes for item <%= @item.id %>: <%= @item.body %>
|
3
|
+
|
4
|
+
<% @item.notes.each do |note| -%>
|
5
|
+
id: <%= note.id %>
|
6
|
+
created: <%= note.created_at.strftime("%Y-%m-%d")%>
|
7
|
+
|
5
8
|
<%= note.body %>
|
6
9
|
<% end %>
|
7
10
|
<% else -%>
|
8
|
-
No Notes for item <%= item.id %>
|
11
|
+
No Notes for item <%= @item.id %>
|
9
12
|
<% end %>
|
@@ -1,6 +1,12 @@
|
|
1
|
+
Items Found: <%= @items.count %>
|
2
|
+
|
3
|
+
Search Text: <%= @text %>
|
1
4
|
|
2
5
|
<% @items.each do |item| -%>
|
3
|
-
|
6
|
+
|
7
|
+
id: <%= item.id %> notes: <%= item.notes.size %> tags: <%= item.tags.map(&:name).join(', ') %>
|
8
|
+
created: <%= item.created_at.strftime("%Y-%m-%d") %> status: <%= item.detailed_status %> (done: <%= item.done? %>)
|
9
|
+
|
4
10
|
<%= item.body %>
|
5
11
|
|
6
12
|
<% if item.notes.any? -%>
|
@@ -1,6 +1,6 @@
|
|
1
1
|
db:
|
2
|
-
seeds: <%= GEM_DIR %>/
|
3
|
-
migrate: <%= GEM_DIR %>/
|
4
|
-
schema: <%= GEM_DIR %>/
|
2
|
+
seeds: <%= GEM_DIR %>/db/seeds.rb
|
3
|
+
migrate: <%= GEM_DIR %>/db/migrate
|
4
|
+
schema: <%= GEM_DIR %>/db/schema.rb
|
5
5
|
config:
|
6
|
-
database: <%= GEM_DIR %>/
|
6
|
+
database: <%= GEM_DIR %>/db/config.yml
|
data/lib/my_todo/version.rb
CHANGED
data/lib/setup.rb
CHANGED
@@ -16,11 +16,11 @@ class Setup < Thor
|
|
16
16
|
`mkdir -p #{HOME_DIR}/.my_todo/data`
|
17
17
|
say "Created .my_todo in #{HOME_DIR}"
|
18
18
|
end
|
19
|
-
template "config.yml.erb", "#{
|
19
|
+
template "config.yml.erb", "#{GEM_DIR}/db/config.yml", force: true
|
20
20
|
end
|
21
21
|
|
22
22
|
desc 'standard_migrations_override', 'Generate SM override file'
|
23
23
|
def standard_migrations_override
|
24
|
-
template "standalone_migrations.yml.erb", "#{
|
24
|
+
template "standalone_migrations.yml.erb", "#{GEM_DIR}/.standalone_migrations", force: true
|
25
25
|
end
|
26
26
|
end
|
data/my_todo.gemspec
CHANGED
@@ -14,28 +14,30 @@ Gem::Specification.new do |spec|
|
|
14
14
|
spec.homepage = "https://github.com/vmcilwain/my_todo"
|
15
15
|
spec.license = "MIT"
|
16
16
|
|
17
|
-
spec.files = Dir["{bin,lib}/**/*", "LICENSE.txt", "README.md",
|
17
|
+
spec.files = Dir["{bin,lib,db}/**/*", "LICENSE.txt", "README.md", 'Rakefile', 'Gemfile', 'my_todo.gemspec']
|
18
18
|
spec.test_files = Dir["spec/**/*"]
|
19
19
|
spec.bindir = "bin"
|
20
|
-
spec.executables = ['
|
20
|
+
spec.executables = ['mytodo']
|
21
21
|
spec.require_paths = ["lib"]
|
22
22
|
|
23
|
-
spec.add_development_dependency "
|
24
|
-
spec.add_development_dependency "
|
25
|
-
spec.add_development_dependency "
|
26
|
-
spec.add_development_dependency
|
27
|
-
spec.add_development_dependency
|
28
|
-
spec.add_development_dependency 'shoulda-matchers', '~> 3.1'
|
29
|
-
spec.add_development_dependency 'byebug', '~> 9.0.5'
|
23
|
+
spec.add_development_dependency "rspec", "~> 3.8.0"
|
24
|
+
spec.add_development_dependency "factory_bot_rails", "~> 4.11.1"
|
25
|
+
spec.add_development_dependency "database_cleaner", "~> 1.7.0"
|
26
|
+
spec.add_development_dependency 'shoulda-matchers', '~> 3.1.2'
|
27
|
+
spec.add_development_dependency 'byebug', '~> 10.0.2'
|
30
28
|
spec.add_development_dependency 'yard', '~> 0.9.5'
|
31
|
-
spec.add_development_dependency 'simplecov', '~> 0.
|
32
|
-
spec.add_development_dependency '
|
33
|
-
spec.
|
34
|
-
spec.
|
35
|
-
spec.add_dependency
|
36
|
-
spec.add_dependency
|
37
|
-
spec.add_dependency '
|
38
|
-
spec.add_dependency '
|
29
|
+
spec.add_development_dependency 'simplecov', '~> 0.16.1'
|
30
|
+
spec.add_development_dependency 'faker'
|
31
|
+
spec.add_development_dependency 'rubocop-rspec'
|
32
|
+
# spec.add_development_dependency 'codeclimate-test-reporter'
|
33
|
+
spec.add_dependency "bundler", "~> 1.16.0"
|
34
|
+
spec.add_dependency "rake", "~> 12.3.1"
|
35
|
+
spec.add_dependency 'activerecord', '~> 5.2.1'
|
36
|
+
spec.add_dependency 'activesupport', '~> 5.2.1'
|
37
|
+
spec.add_dependency 'thor', '~> 0.20.0'
|
38
|
+
spec.add_dependency 'standalone_migrations', '~> 5.2.6'
|
39
|
+
spec.add_dependency 'sqlite3', '~> 1.3.13'
|
40
|
+
spec.add_dependency 'ransack', '~> 2.0.1'
|
39
41
|
|
40
42
|
spec.metadata["yard.run"] = "yri"
|
41
43
|
spec.post_install_message = "Don't forget to migrate the db. `my_todo rake db:migrate`"
|
data/spec/actions/create_spec.rb
CHANGED
@@ -6,9 +6,10 @@ describe MyTodo do
|
|
6
6
|
end
|
7
7
|
|
8
8
|
describe 'create' do
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
let(:body) {Faker::Lorem.words(5).join("\s")}
|
10
|
+
let(:statuses) {"0: None\n1: In Progress\n2: Waiting Feedback\n3: Complete\n4: Punted"}
|
11
|
+
|
12
|
+
before {expect(Thor::LineEditor).to receive(:readline).with("Choose a status for item (1) ", {default:1}).and_return("")}
|
12
13
|
|
13
14
|
context 'successful creation' do
|
14
15
|
describe 'creation without tags or setting done attribute' do
|
@@ -17,46 +18,47 @@ describe MyTodo do
|
|
17
18
|
end
|
18
19
|
|
19
20
|
it 'creates a todo item' do
|
20
|
-
expect{MyTodo::Todo.start(
|
21
|
+
expect{MyTodo::Todo.start(['create', body])}.to change{Item.count}.by(1)
|
21
22
|
end
|
22
23
|
|
23
24
|
it "sets tags to 'default' when tags option is not present" do
|
24
|
-
MyTodo::Todo.start(
|
25
|
+
MyTodo::Todo.start(['create', body])
|
25
26
|
todo = Item.last
|
26
|
-
expect(todo.tags.map(&:name)).to eq ['
|
27
|
+
expect(todo.tags.map(&:name)).to eq ['Default']
|
27
28
|
end
|
28
29
|
|
29
30
|
it 'sets done to false by when done option is not present' do
|
30
|
-
MyTodo::Todo.start(
|
31
|
+
MyTodo::Todo.start(['create', body])
|
31
32
|
todo = Item.last
|
32
33
|
expect(todo.done).to eq false
|
33
34
|
end
|
34
35
|
|
35
36
|
it 'displays the created todo item' do
|
36
|
-
expect{MyTodo::Todo.start(
|
37
|
+
expect{MyTodo::Todo.start(['create', body])}.to output("#{statuses}\nItem Created\n\nid: 1 notes: 0 tags: Default\ncreated: #{Date.today} status: In Progress (done: No) \n\n#{body}\n").to_stdout
|
37
38
|
end
|
38
39
|
end
|
39
40
|
|
40
41
|
describe 'creation with tags and without setting done attribute' do
|
41
42
|
it 'creates associated tag' do
|
42
|
-
expect{MyTodo::Todo.start(
|
43
|
+
expect{MyTodo::Todo.start(['create', body, 'tag1'])}.to change{Tag.count}.by(1)
|
43
44
|
end
|
44
45
|
|
45
46
|
it 'displays the created todo item with tag' do
|
46
|
-
expect{MyTodo::Todo.start(
|
47
|
+
expect{MyTodo::Todo.start(['create', body, 'tag1'])}.to output("#{statuses}\nItem Created\n\nid: 1 notes: 0 tags: tag1\ncreated: #{Date.today} status: In Progress (done: No) \n\n#{body}\n").to_stdout
|
47
48
|
end
|
48
49
|
end
|
49
50
|
|
50
|
-
describe 'create
|
51
|
-
|
52
|
-
expect{MyTodo::Todo.start(
|
51
|
+
describe 'create a completed item' do
|
52
|
+
xit 'displays the created to item with complete set to true', 'look into being able to set this option again' do
|
53
|
+
expect{MyTodo::Todo.start(['create', body])}.to output("#{statuses}\nItem Created\n\nid: 1 notes: 0 tags: Default\ncreated: #{Date.today} status: In Progress (done: Yes) \n\n#{body}\n").to_stdout
|
53
54
|
end
|
54
55
|
end
|
55
56
|
end
|
56
57
|
|
57
58
|
context 'unsuccessful creation' do
|
58
|
-
|
59
|
-
expect{MyTodo::Todo.start(
|
59
|
+
xit 'returns error message when body is missing', 'look into being able to set this option again' do
|
60
|
+
expect{MyTodo::Todo.start(['create'])}.to output("ERROR: \"my_todo create\" was called with no arguments\n
|
61
|
+
Usage: \"my_todo create \"<BODY>\" <TAGS> [Default: general]>\"").to_stdout
|
60
62
|
end
|
61
63
|
end
|
62
64
|
end
|
data/spec/actions/delete_spec.rb
CHANGED
@@ -2,14 +2,20 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe MyTodo do
|
4
4
|
describe 'delete' do
|
5
|
-
|
6
|
-
|
5
|
+
let(:todo) {FactoryBot.create(:item)}
|
6
|
+
|
7
|
+
before {todo}
|
8
|
+
|
7
9
|
it 'destroys todo item' do
|
8
|
-
expect{MyTodo::Todo.start(
|
10
|
+
expect{MyTodo::Todo.start(['delete', todo.id])}.to change{Item.count}.by(-1)
|
9
11
|
end
|
10
12
|
|
11
13
|
it 'returns nil exception if todo item is invalid' do
|
12
|
-
expect{MyTodo::Todo.start(
|
14
|
+
expect{MyTodo::Todo.start(['delete', todo.id + 1])}.to output("undefined method `destroy!' for nil:NilClass\n").to_stdout
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'displays a notice' do
|
18
|
+
expect{MyTodo::Todo.start(['delete', todo.id])}.to output("Item Deleted\n").to_stdout
|
13
19
|
end
|
14
20
|
end
|
15
21
|
end
|