From 30f336c1a8c1c037014eac884e7fe0888140a669 Mon Sep 17 00:00:00 2001 From: Igor Putina Date: Wed, 20 Jun 2018 16:55:22 +0300 Subject: [PATCH 1/8] Add task description --- 03-command-line-todo-list/README.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 03-command-line-todo-list/README.md diff --git a/03-command-line-todo-list/README.md b/03-command-line-todo-list/README.md new file mode 100644 index 0000000..285bccb --- /dev/null +++ b/03-command-line-todo-list/README.md @@ -0,0 +1,15 @@ +## Command line todo list + +### Description + +Write an command line application that helps you manage your tasks. + +The information can be stored in any prefered way. The program should be launched from the console with different attributes: + +``` + -a or --add adds an item into the list + -l or --list displays the list + -r or --remove removes the last n in the list + -c or --clear clears the list + -h or --help shows list of available commands +``` \ No newline at end of file From e7417ab8d7c07a812ebcbf02437b015d70091686 Mon Sep 17 00:00:00 2001 From: Igor Putina Date: Wed, 20 Jun 2018 18:02:51 +0300 Subject: [PATCH 2/8] Add `thor` to the `Gemfile` --- 03-command-line-todo-list/Gemfile | 3 +++ 03-command-line-todo-list/Gemfile.lock | 13 +++++++++++++ 2 files changed, 16 insertions(+) create mode 100644 03-command-line-todo-list/Gemfile create mode 100644 03-command-line-todo-list/Gemfile.lock diff --git a/03-command-line-todo-list/Gemfile b/03-command-line-todo-list/Gemfile new file mode 100644 index 0000000..80b4e64 --- /dev/null +++ b/03-command-line-todo-list/Gemfile @@ -0,0 +1,3 @@ +source "https://rubygems.org" + +gem 'thor', '~> 0.20.0' \ No newline at end of file diff --git a/03-command-line-todo-list/Gemfile.lock b/03-command-line-todo-list/Gemfile.lock new file mode 100644 index 0000000..a14899f --- /dev/null +++ b/03-command-line-todo-list/Gemfile.lock @@ -0,0 +1,13 @@ +GEM + remote: https://rubygems.org/ + specs: + thor (0.20.0) + +PLATFORMS + ruby + +DEPENDENCIES + thor (~> 0.20.0) + +BUNDLED WITH + 1.16.1 From 457beb742fa87ef2880b3a1ae0877c68cc2b87d3 Mon Sep 17 00:00:00 2001 From: Igor Putina Date: Wed, 20 Jun 2018 18:03:23 +0300 Subject: [PATCH 3/8] Implement commands and empty methods --- 03-command-line-todo-list/todo.rb | 42 +++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100755 03-command-line-todo-list/todo.rb diff --git a/03-command-line-todo-list/todo.rb b/03-command-line-todo-list/todo.rb new file mode 100755 index 0000000..7cc22ee --- /dev/null +++ b/03-command-line-todo-list/todo.rb @@ -0,0 +1,42 @@ +#!/usr/bin/env ruby + +require "thor" +require "yaml/store" + +store = YAML::Store.new('database.yaml') + +module Todo + class CLI < Thor + desc "-a or --add [TASK]", "Adds an item into the list of tasks", :aliases => "-a" + map %w[-a --add] => :add + def add(task) + puts "Adding task: #{task}" + end + + desc "-r or --remove [ITEM]", "Removes an item from the list of tasks" + map %w[-r --remove] => :remove + def remove(task) + puts "Removing task #{task}" + end + + desc "-l or --list", "List the tasks" + map %w[-l --list] => :list + def list() + puts "Listing tasks" + end + + desc "-c or --clear", "Clears all tasks" + map %w[-c --clear] => :clear + def clear() + puts "Clearing tasks" + end + + desc "-h or --help", "Displays a list of possible commands" + map %w[-h --help] => :help + def help + super + end + end +end + +Todo::CLI.start(ARGV) From 8ba3c09b445ae1adb2e28f67f8fc8a95def963be Mon Sep 17 00:00:00 2001 From: Igor Putina Date: Wed, 20 Jun 2018 18:27:15 +0300 Subject: [PATCH 4/8] Implement `add` and `remove` commands --- 03-command-line-todo-list/database.yaml | 9 ++++ 03-command-line-todo-list/todo.rb | 67 +++++++++++++++---------- 2 files changed, 50 insertions(+), 26 deletions(-) create mode 100644 03-command-line-todo-list/database.yaml diff --git a/03-command-line-todo-list/database.yaml b/03-command-line-todo-list/database.yaml new file mode 100644 index 0000000..9399b95 --- /dev/null +++ b/03-command-line-todo-list/database.yaml @@ -0,0 +1,9 @@ +--- +:tasks: +- Lick a car tire +- Eat a whole piece of paper +- Pick your friend’s nose +- Get into a debate with a wall +- Burp the alphabet +- Eat a spoonful of mustard +- Talk without closing your mouth diff --git a/03-command-line-todo-list/todo.rb b/03-command-line-todo-list/todo.rb index 7cc22ee..79dae77 100755 --- a/03-command-line-todo-list/todo.rb +++ b/03-command-line-todo-list/todo.rb @@ -3,40 +3,55 @@ require "thor" require "yaml/store" -store = YAML::Store.new('database.yaml') +$store = YAML::Store.new('database.yaml') module Todo - class CLI < Thor - desc "-a or --add [TASK]", "Adds an item into the list of tasks", :aliases => "-a" - map %w[-a --add] => :add - def add(task) - puts "Adding task: #{task}" - end + class CLI < Thor + desc "-a or --add [TASK]", "Adds an item into the list of tasks", :aliases => "-a" + map %w[-a --add] => :add + def add(task) + $store.transaction do + $store[:tasks] ||= [] + $store[:tasks] << task + $store.commit + end + end - desc "-r or --remove [ITEM]", "Removes an item from the list of tasks" - map %w[-r --remove] => :remove - def remove(task) - puts "Removing task #{task}" - end + desc "-r or --remove [ITEM]", "Removes an item from the list of tasks" + map %w[-r --remove] => :remove + def remove(item) + $store.transaction do + $store[:tasks] ||= [] + if $store[:tasks].length < item.to_i + shell.say "A task at number #{item} does not exist" - desc "-l or --list", "List the tasks" - map %w[-l --list] => :list - def list() - puts "Listing tasks" + # Abort this transaction + $store.abort end - desc "-c or --clear", "Clears all tasks" - map %w[-c --clear] => :clear - def clear() - puts "Clearing tasks" - end + $store[:tasks].delete_at(item.to_i - 1) + $store.commit + end + end - desc "-h or --help", "Displays a list of possible commands" - map %w[-h --help] => :help - def help - super - end + desc "-l or --list", "List the tasks" + map %w[-l --list] => :list + def list() + shell.say "Listing tasks" + end + + desc "-c or --clear", "Clears all tasks" + map %w[-c --clear] => :clear + def clear() + puts "Clearing tasks" + end + + desc "-h or --help", "Displays a list of possible commands" + map %w[-h --help] => :help + def help + super end + end end Todo::CLI.start(ARGV) From 601d7220eb591070f61623d31485e0a784824090 Mon Sep 17 00:00:00 2001 From: Igor Putina Date: Wed, 20 Jun 2018 18:44:37 +0300 Subject: [PATCH 5/8] Implement `list` command --- 03-command-line-todo-list/todo.rb | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/03-command-line-todo-list/todo.rb b/03-command-line-todo-list/todo.rb index 79dae77..ba1e545 100755 --- a/03-command-line-todo-list/todo.rb +++ b/03-command-line-todo-list/todo.rb @@ -7,11 +7,15 @@ module Todo class CLI < Thor + def initialize(*args) + super + prepare_store + end + desc "-a or --add [TASK]", "Adds an item into the list of tasks", :aliases => "-a" map %w[-a --add] => :add def add(task) $store.transaction do - $store[:tasks] ||= [] $store[:tasks] << task $store.commit end @@ -21,7 +25,6 @@ def add(task) map %w[-r --remove] => :remove def remove(item) $store.transaction do - $store[:tasks] ||= [] if $store[:tasks].length < item.to_i shell.say "A task at number #{item} does not exist" @@ -37,7 +40,17 @@ def remove(item) desc "-l or --list", "List the tasks" map %w[-l --list] => :list def list() - shell.say "Listing tasks" + shell.say "Current tasks:" + shell.say + + $store.transaction do + $store[:tasks].each_with_index do |item, index| + shell.say "\t%02d #{item}" % (index + 1) + end + + shell.say + shell.say "There are currently #{$store[:tasks].length} tasks" + end end desc "-c or --clear", "Clears all tasks" @@ -51,6 +64,15 @@ def clear() def help super end + + private + + def prepare_store + $store.transaction do + $store[:tasks] ||= [] + $store.commit + end + end end end From 21cb516412652ce5c42b5713cdfb745eb108df82 Mon Sep 17 00:00:00 2001 From: Igor Putina Date: Wed, 20 Jun 2018 23:27:35 +0300 Subject: [PATCH 6/8] Initial solution implementation --- 03-command-line-todo-list/todo.rb | 78 +----------------- 03-command-line-todo-list/todo/cli.rb | 61 ++++++++++++++ 03-command-line-todo-list/todo/database.rb | 95 ++++++++++++++++++++++ 3 files changed, 158 insertions(+), 76 deletions(-) create mode 100644 03-command-line-todo-list/todo/cli.rb create mode 100644 03-command-line-todo-list/todo/database.rb diff --git a/03-command-line-todo-list/todo.rb b/03-command-line-todo-list/todo.rb index ba1e545..a29c5cb 100755 --- a/03-command-line-todo-list/todo.rb +++ b/03-command-line-todo-list/todo.rb @@ -1,79 +1,5 @@ #!/usr/bin/env ruby -require "thor" -require "yaml/store" +require_relative "todo/cli" -$store = YAML::Store.new('database.yaml') - -module Todo - class CLI < Thor - def initialize(*args) - super - prepare_store - end - - desc "-a or --add [TASK]", "Adds an item into the list of tasks", :aliases => "-a" - map %w[-a --add] => :add - def add(task) - $store.transaction do - $store[:tasks] << task - $store.commit - end - end - - desc "-r or --remove [ITEM]", "Removes an item from the list of tasks" - map %w[-r --remove] => :remove - def remove(item) - $store.transaction do - if $store[:tasks].length < item.to_i - shell.say "A task at number #{item} does not exist" - - # Abort this transaction - $store.abort - end - - $store[:tasks].delete_at(item.to_i - 1) - $store.commit - end - end - - desc "-l or --list", "List the tasks" - map %w[-l --list] => :list - def list() - shell.say "Current tasks:" - shell.say - - $store.transaction do - $store[:tasks].each_with_index do |item, index| - shell.say "\t%02d #{item}" % (index + 1) - end - - shell.say - shell.say "There are currently #{$store[:tasks].length} tasks" - end - end - - desc "-c or --clear", "Clears all tasks" - map %w[-c --clear] => :clear - def clear() - puts "Clearing tasks" - end - - desc "-h or --help", "Displays a list of possible commands" - map %w[-h --help] => :help - def help - super - end - - private - - def prepare_store - $store.transaction do - $store[:tasks] ||= [] - $store.commit - end - end - end -end - -Todo::CLI.start(ARGV) +Todo::CLI.start(ARGV) \ No newline at end of file diff --git a/03-command-line-todo-list/todo/cli.rb b/03-command-line-todo-list/todo/cli.rb new file mode 100644 index 0000000..d4f1460 --- /dev/null +++ b/03-command-line-todo-list/todo/cli.rb @@ -0,0 +1,61 @@ +require "thor" +require_relative "database" + +module Todo + class CLI < Thor + def initialize(*args) + @store = Todo::Database.new + + super + end + + desc "-a or --add [TASK]", "Adds an item into the list of tasks" + map %w[-a --add] => :add + def add(task) + @store.tasks = @store.tasks << task + + pretty_print_tasks(@store.tasks) + end + + desc "-r or --remove [ITEM]", "Removes an item from the list of tasks" + map %w[-r --remove] => :remove + def remove(item) + tasks = @store.tasks + + if tasks.length < item.to_i + shell.say "Task at number #{item} does not exist\n\n" + return + end + + shell.say "\n\"\e[1m#{tasks.delete_at(item.to_i - 1)}\"\e[0m [removed]\n\n" + @store.tasks = tasks + end + + desc "-l or --list", "List the tasks" + map %w[-l --list] => :list + def list + pretty_print_tasks(@store.tasks) + end + + desc "-c or --clear", "Clears all tasks" + map %w[-c --clear] => :clear + def clear + @store.tasks = [] + pretty_print_tasks(@store.tasks) + end + + desc "-h or --help", "Displays a list of possible commands" + map %w[-h --help] => :help + def help + super + end + + protected + + def pretty_print_tasks(tasks) + shell.say "\n\tThere are currently \e[1m#{tasks.length} tasks\e[0m\n\n" + tasks.each_with_index { |item, index| shell.say "\t%02d #{item}" % (index + 1) } + shell.say + end + end +end \ No newline at end of file diff --git a/03-command-line-todo-list/todo/database.rb b/03-command-line-todo-list/todo/database.rb new file mode 100644 index 0000000..7fedba9 --- /dev/null +++ b/03-command-line-todo-list/todo/database.rb @@ -0,0 +1,95 @@ +require "yaml/store" + +module Todo + class CLI < Thor + def initialize(*args) + @store = Todo::Database.new + + super + end + + desc "-a or --add [TASK]", "Adds an item into the list of tasks" + map %w[-a --add] => :add + def add(task) + @store.tasks = @store.tasks << task + + pretty_print_tasks(@store.tasks) + end + + desc "-r or --remove [ITEM]", "Removes an item from the list of tasks" + map %w[-r --remove] => :remove + def remove(item) + tasks = @store.tasks + + if tasks.length < item.to_i + shell.say "A task at number #{item} does not exist" + end + + tasks.delete_at(item.to_i - 1) + @store.tasks = tasks + end + + desc "-l or --list", "List the tasks" + map %w[-l --list] => :list + def list + pretty_print_tasks(@store.tasks) + end + + desc "-c or --clear", "Clears all tasks" + map %w[-c --clear] => :clear + def clear + @store.tasks = [] + pretty_print_tasks(@store.tasks) + end + + desc "-h or --help", "Displays a list of possible commands" + map %w[-h --help] => :help + def help + super + end + + protected + + def pretty_print_tasks(tasks) + shell.say "\n\tThere are currently \e[1m#{tasks.length} tasks\e[0m\n\n" + tasks.each_with_index { |item, index| shell.say "\t%02d #{item}" % (index + 1) } + shell.say + end + end + + class Database + attr_accessor :store, :tasks + + def initialize(db_name = 'database') + @store = YAML::Store.new("#{db_name}.yaml") + initialize_store + end + + def initialize_store + @store.transaction do + @store[:tasks] ||= [] + @store.commit + end + end + + def tasks=(tasks) + @store.transaction do + @store[:tasks] = tasks + @tasks = tasks + @store.commit + end + + @tasks + end + + def tasks + tasks = [] + + @store.transaction do + tasks = @store[:tasks] + end + + tasks + end + end +end \ No newline at end of file From 7b8fc0b43d531465aa98aabd332717ee4f017ba0 Mon Sep 17 00:00:00 2001 From: Igor Putina Date: Wed, 20 Jun 2018 23:31:41 +0300 Subject: [PATCH 7/8] Renamed `todo` to `lib` --- .../{todo => lib}/cli.rb | 0 03-command-line-todo-list/lib/database.rb | 39 ++++++++ 03-command-line-todo-list/todo.rb | 2 +- 03-command-line-todo-list/todo/database.rb | 95 ------------------- 4 files changed, 40 insertions(+), 96 deletions(-) rename 03-command-line-todo-list/{todo => lib}/cli.rb (100%) create mode 100644 03-command-line-todo-list/lib/database.rb delete mode 100644 03-command-line-todo-list/todo/database.rb diff --git a/03-command-line-todo-list/todo/cli.rb b/03-command-line-todo-list/lib/cli.rb similarity index 100% rename from 03-command-line-todo-list/todo/cli.rb rename to 03-command-line-todo-list/lib/cli.rb diff --git a/03-command-line-todo-list/lib/database.rb b/03-command-line-todo-list/lib/database.rb new file mode 100644 index 0000000..6993aaf --- /dev/null +++ b/03-command-line-todo-list/lib/database.rb @@ -0,0 +1,39 @@ +require "yaml/store" + +module Todo + class Database + attr_accessor :store, :tasks + + def initialize(db_name = 'database') + @store = YAML::Store.new("#{db_name}.yaml") + initialize_store + end + + def initialize_store + @store.transaction do + @store[:tasks] ||= [] + @store.commit + end + end + + def tasks=(tasks) + @store.transaction do + @store[:tasks] = tasks + @tasks = tasks + @store.commit + end + + @tasks + end + + def tasks + tasks = [] + + @store.transaction do + tasks = @store[:tasks] + end + + tasks + end + end +end \ No newline at end of file diff --git a/03-command-line-todo-list/todo.rb b/03-command-line-todo-list/todo.rb index a29c5cb..c291400 100755 --- a/03-command-line-todo-list/todo.rb +++ b/03-command-line-todo-list/todo.rb @@ -1,5 +1,5 @@ #!/usr/bin/env ruby -require_relative "todo/cli" +require_relative "lib/cli" Todo::CLI.start(ARGV) \ No newline at end of file diff --git a/03-command-line-todo-list/todo/database.rb b/03-command-line-todo-list/todo/database.rb deleted file mode 100644 index 7fedba9..0000000 --- a/03-command-line-todo-list/todo/database.rb +++ /dev/null @@ -1,95 +0,0 @@ -require "yaml/store" - -module Todo - class CLI < Thor - def initialize(*args) - @store = Todo::Database.new - - super - end - - desc "-a or --add [TASK]", "Adds an item into the list of tasks" - map %w[-a --add] => :add - def add(task) - @store.tasks = @store.tasks << task - - pretty_print_tasks(@store.tasks) - end - - desc "-r or --remove [ITEM]", "Removes an item from the list of tasks" - map %w[-r --remove] => :remove - def remove(item) - tasks = @store.tasks - - if tasks.length < item.to_i - shell.say "A task at number #{item} does not exist" - end - - tasks.delete_at(item.to_i - 1) - @store.tasks = tasks - end - - desc "-l or --list", "List the tasks" - map %w[-l --list] => :list - def list - pretty_print_tasks(@store.tasks) - end - - desc "-c or --clear", "Clears all tasks" - map %w[-c --clear] => :clear - def clear - @store.tasks = [] - pretty_print_tasks(@store.tasks) - end - - desc "-h or --help", "Displays a list of possible commands" - map %w[-h --help] => :help - def help - super - end - - protected - - def pretty_print_tasks(tasks) - shell.say "\n\tThere are currently \e[1m#{tasks.length} tasks\e[0m\n\n" - tasks.each_with_index { |item, index| shell.say "\t%02d #{item}" % (index + 1) } - shell.say - end - end - - class Database - attr_accessor :store, :tasks - - def initialize(db_name = 'database') - @store = YAML::Store.new("#{db_name}.yaml") - initialize_store - end - - def initialize_store - @store.transaction do - @store[:tasks] ||= [] - @store.commit - end - end - - def tasks=(tasks) - @store.transaction do - @store[:tasks] = tasks - @tasks = tasks - @store.commit - end - - @tasks - end - - def tasks - tasks = [] - - @store.transaction do - tasks = @store[:tasks] - end - - tasks - end - end -end \ No newline at end of file From 47db7dcc224578e462571887fe760de725709fa7 Mon Sep 17 00:00:00 2001 From: Igor Putina Date: Thu, 21 Jun 2018 10:41:36 +0300 Subject: [PATCH 8/8] Modified according to spec --- 03-command-line-todo-list/lib/cli.rb | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/03-command-line-todo-list/lib/cli.rb b/03-command-line-todo-list/lib/cli.rb index d4f1460..e84a109 100644 --- a/03-command-line-todo-list/lib/cli.rb +++ b/03-command-line-todo-list/lib/cli.rb @@ -17,9 +17,9 @@ def add(task) pretty_print_tasks(@store.tasks) end - desc "-r or --remove [ITEM]", "Removes an item from the list of tasks" - map %w[-r --remove] => :remove - def remove(item) + desc "-d or --delete [NUMBER]", "Deletes task at index NUMBER from the list" + map %w[-d --delete] => :delete + def delete(item) tasks = @store.tasks if tasks.length < item.to_i @@ -31,6 +31,18 @@ def remove(item) @store.tasks = tasks end + desc "-r or --remove [NUMBER]", "Removes the last NUMBER of items the list" + map %w[-r --remove] => :remove + def remove(items) + tasks = @store.tasks + clear and return if tasks.length <= items.to_i + @store.tasks = tasks - tasks.last(items.to_i) + + tasks.last(items.to_i).each do |task| + shell.say "\"#{task}\" \e[1m[removed]\e[0m" + end + end + desc "-l or --list", "List the tasks" map %w[-l --list] => :list def list