my_todo 3.1.1 → 4.0.0.pre1
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 +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
|