list-tool 1.0.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.
Files changed (61) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.rspec +2 -0
  4. data/Gemfile +4 -0
  5. data/Guardfile +8 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +29 -0
  8. data/Rakefile +1 -0
  9. data/bin/clt +12 -0
  10. data/lib/list_tool/app/commands/add_item_command.rb +39 -0
  11. data/lib/list_tool/app/commands/add_list_command.rb +30 -0
  12. data/lib/list_tool/app/commands/delete_item_command.rb +39 -0
  13. data/lib/list_tool/app/commands/delete_list_command.rb +32 -0
  14. data/lib/list_tool/app/commands/help_command.rb +24 -0
  15. data/lib/list_tool/app/commands/rename_list_command.rb +34 -0
  16. data/lib/list_tool/app/commands/replace_item_command.rb +34 -0
  17. data/lib/list_tool/app/commands/show_items_command.rb +35 -0
  18. data/lib/list_tool/app/commands/show_lists_command.rb +26 -0
  19. data/lib/list_tool/app/commands/unknown_command.rb +26 -0
  20. data/lib/list_tool/app/commands/use_command.rb +31 -0
  21. data/lib/list_tool/app/commands/version_command.rb +24 -0
  22. data/lib/list_tool/app/commands.rb +43 -0
  23. data/lib/list_tool/app/printer.rb +41 -0
  24. data/lib/list_tool/app/runner.rb +54 -0
  25. data/lib/list_tool/app/string.rb +9 -0
  26. data/lib/list_tool/app.rb +9 -0
  27. data/lib/list_tool/data.rb +75 -0
  28. data/lib/list_tool/file_manager.rb +27 -0
  29. data/lib/list_tool/item.rb +23 -0
  30. data/lib/list_tool/json_parser.rb +11 -0
  31. data/lib/list_tool/list.rb +88 -0
  32. data/lib/list_tool/lister.rb +81 -0
  33. data/lib/list_tool/version.rb +3 -0
  34. data/lib/list_tool.rb +19 -0
  35. data/list_tool.gemspec +31 -0
  36. data/spec/fixtures/data.json +18 -0
  37. data/spec/list_tool/app/commands/add_item_command_spec.rb +108 -0
  38. data/spec/list_tool/app/commands/add_list_command_spec.rb +74 -0
  39. data/spec/list_tool/app/commands/delete_item_command_spec.rb +116 -0
  40. data/spec/list_tool/app/commands/delete_list_command_spec.rb +89 -0
  41. data/spec/list_tool/app/commands/help_command_spec.rb +41 -0
  42. data/spec/list_tool/app/commands/rename_list_command_spec.rb +95 -0
  43. data/spec/list_tool/app/commands/replace_item_command_spec.rb +97 -0
  44. data/spec/list_tool/app/commands/show_items_command_spec.rb +111 -0
  45. data/spec/list_tool/app/commands/show_lists_command_spec.rb +48 -0
  46. data/spec/list_tool/app/commands/unknown_command_spec.rb +31 -0
  47. data/spec/list_tool/app/commands/use_command_spec.rb +79 -0
  48. data/spec/list_tool/app/commands/version_comand_spec.rb +41 -0
  49. data/spec/list_tool/app/commands_spec.rb +80 -0
  50. data/spec/list_tool/app/printer_spec.rb +54 -0
  51. data/spec/list_tool/app/runner_spec.rb +166 -0
  52. data/spec/list_tool/app/string_spec.rb +32 -0
  53. data/spec/list_tool/data_spec.rb +257 -0
  54. data/spec/list_tool/file_manager_spec.rb +84 -0
  55. data/spec/list_tool/item_spec.rb +42 -0
  56. data/spec/list_tool/json_parser_spec.rb +14 -0
  57. data/spec/list_tool/list_spec.rb +221 -0
  58. data/spec/list_tool/lister_spec.rb +186 -0
  59. data/spec/spec_helper.rb +18 -0
  60. data/spec/support/factory.rb +33 -0
  61. metadata +213 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 02b3b401bb917dd37c09651ea107c8331d9d20dd
4
+ data.tar.gz: 214817e634ce79d29ea58f413fa5ff07f017c849
5
+ SHA512:
6
+ metadata.gz: 1eae4a8fdc49fea6567d963e69e3cdf77bb95f17d8529303700f161fbfb03c6cd86563aa525d988313bd504b1b7b62b54dbbd2d3280980111c3e50918a7b06b1
7
+ data.tar.gz: d717f15417c6851f289d5d8a9c1ff975b94c06f6f751e4d6e85c52550e3633d3d5a1b260c873ffb40b4da323ba55139f53f1f7a73bf62c732c8120ab3ad91ce2
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in list_tool.gemspec
4
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,8 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard :rspec do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Vizvamitra
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # ListTool
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'list_tool'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install list_tool
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it ( http://github.com/<my-github-username>/list_tool/fork )
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/clt ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ lib = File.expand_path(File.dirname(__FILE__) + '/../lib')
4
+ $LOAD_PATH.unshift(lib) if File.directory?(lib) && !$LOAD_PATH.include?(lib)
5
+
6
+ require 'list_tool'
7
+
8
+ argv = ARGV.dup
9
+ ARGV.clear
10
+
11
+ app = ListTool::App::Runner.new
12
+ app.run argv
@@ -0,0 +1,39 @@
1
+ module ListTool
2
+ module App
3
+
4
+ class AddItemCommand
5
+
6
+ def self.match? arg
7
+ ['a', 'add-item'].include? arg
8
+ end
9
+
10
+ def self.parse argv
11
+ raise ArgumentError, "expected argument to be an array, #{argv.class} given" unless argv.is_a? Array
12
+
13
+ item, list = argv.shift(2)
14
+ raise ArgumentError, 'item text not specified' if item.nil?
15
+
16
+ out = {text: item}
17
+
18
+ if list
19
+ out[:list] = Integer(list) - 1 rescue raise(ArgumentError, 'list number must be an integer')
20
+ raise ArgumentError, "list number can't be less than 1" if out[:list] < 0
21
+ end
22
+
23
+ out
24
+ end
25
+
26
+ def self.execute options, lister
27
+ args = [ options.delete(:text) ]
28
+ args << options if options[:list]
29
+ raise(ListNotFoundError, 'no list with given number') if lister.add_item(*args).nil?
30
+ end
31
+
32
+ def self.help
33
+ " a, add-item TEXT [LIST]\tAdd item with TEXT to given or default list"
34
+ end
35
+
36
+ end
37
+
38
+ end
39
+ end
@@ -0,0 +1,30 @@
1
+ module ListTool
2
+ module App
3
+
4
+ class AddListCommand
5
+
6
+ def self.match? arg
7
+ ['al', 'add-list'].include? arg
8
+ end
9
+
10
+ def self.parse argv
11
+ raise ArgumentError, "expected argument to be an array, #{argv.class} given" unless argv.is_a? Array
12
+ name = argv.shift
13
+ raise ArgumentError, 'list name not specified' if name.nil?
14
+ raise ArgumentError, 'name is not a string' unless name.is_a? String
15
+
16
+ {name: name}
17
+ end
18
+
19
+ def self.execute options, lister
20
+ raise(RuntimeError, "list creation failed") if lister.add_list(options[:name]).nil?
21
+ end
22
+
23
+ def self.help
24
+ " al, add-list NAME\t\tCreate list with NAME"
25
+ end
26
+
27
+ end
28
+
29
+ end
30
+ end
@@ -0,0 +1,39 @@
1
+ module ListTool
2
+ module App
3
+
4
+ class DeleteItemCommand
5
+
6
+ def self.match? arg
7
+ ['d', 'del-item'].include? arg
8
+ end
9
+
10
+ def self.parse argv
11
+ raise ArgumentError, "expected argument to be an array, #{argv.class} given" unless argv.is_a? Array
12
+
13
+ item, list = argv.shift(2)
14
+ raise ArgumentError, 'item number not specified' if item.nil?
15
+
16
+ out = {item: Integer(item) - 1} rescue raise(ArgumentError, 'item number must be an integer')
17
+
18
+ if list
19
+ out[:list] = Integer(list) - 1 rescue raise(ArgumentError, 'list number must be an integer')
20
+ raise ArgumentError, "list number can't be less than 1" if out[:list] < 0
21
+ end
22
+
23
+ out
24
+ end
25
+
26
+ def self.execute options, lister
27
+ args = [ options[:item] ]
28
+ args << {list: options[:list]} if options[:list]
29
+ raise(ListNotFoundError, 'no list with given number') if lister.delete_item(*args).nil?
30
+ end
31
+
32
+ def self.help
33
+ " d, del-item ITEM [LIST]\tDelete ITEM from given or default list"
34
+ end
35
+
36
+ end
37
+
38
+ end
39
+ end
@@ -0,0 +1,32 @@
1
+ module ListTool
2
+ module App
3
+
4
+ class DeleteListCommand
5
+
6
+ def self.match? arg
7
+ ['dl', 'del-list'].include? arg
8
+ end
9
+
10
+ def self.parse argv
11
+ raise ArgumentError, "expected argument to be an array, #{argv.class} given" unless argv.is_a? Array
12
+ list = argv.shift
13
+ raise ArgumentError, 'list number not specified' if list.nil?
14
+
15
+ list = Integer(list) - 1 rescue raise(ArgumentError, 'list number must be an integer')
16
+ raise ArgumentError, "list number can't be less than 1" if list < 0
17
+
18
+ {list: list}
19
+ end
20
+
21
+ def self.execute options, lister
22
+ raise(ListNotFoundError, 'no list with given number') if lister.delete_list(options[:list]).nil?
23
+ end
24
+
25
+ def self.help
26
+ " dl, del-list LIST\t\tDelete given LIST"
27
+ end
28
+
29
+ end
30
+
31
+ end
32
+ end
@@ -0,0 +1,24 @@
1
+ module ListTool
2
+ module App
3
+
4
+ class HelpCommand
5
+
6
+ def self.match? arg
7
+ ['h', '-h', 'help', '--help'].include? arg
8
+ end
9
+
10
+ def self.parse argv
11
+ {}
12
+ end
13
+
14
+ def self.execute options, lister
15
+ Printer.print_usage
16
+ end
17
+
18
+ def self.help
19
+ " -h, --help\t\t\tPrint this message"
20
+ end
21
+
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,34 @@
1
+ module ListTool
2
+ module App
3
+
4
+ class RenameListCommand
5
+
6
+ def self.match? arg
7
+ ['rl', 'rename-list'].include? arg
8
+ end
9
+
10
+ def self.parse argv
11
+ raise ArgumentError, "expected argument to be an array, #{argv.class} given" unless argv.is_a? Array
12
+ list, name = argv.shift(2)
13
+ raise ArgumentError, 'list number not specified' if list.nil?
14
+ raise ArgumentError, 'new name not specified' if name.nil?
15
+
16
+ list = Integer(list) - 1 rescue raise(ArgumentError, 'list number must be an integer')
17
+ raise ArgumentError, "list number can't be less than 1" if list < 0
18
+
19
+ {name: name, list: list}
20
+ end
21
+
22
+ def self.execute options, lister
23
+ args = [ options[:list], options[:name] ]
24
+ raise(ListNotFoundError, 'no list with given number') if lister.rename_list(*args).nil?
25
+ end
26
+
27
+ def self.help
28
+ " rl, rename-list LIST, NAME\tSet LIST name to NAME"
29
+ end
30
+
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,34 @@
1
+ module ListTool
2
+ module App
3
+
4
+ class ReplaceItemCommand
5
+
6
+ def self.match? arg
7
+ ['r', 'replace-item'].include? arg
8
+ end
9
+
10
+ def self.parse argv
11
+ raise ArgumentError, "expected argument to be an array, #{argv.class} given" unless argv.is_a? Array
12
+ item, name = argv.shift(2)
13
+ raise ArgumentError, 'item number not specified' if item.nil?
14
+ raise ArgumentError, 'new name not specified' if name.nil?
15
+
16
+ item = Integer(item) - 1 rescue raise(ArgumentError, 'item number must be an integer')
17
+ raise ArgumentError, "item number can't be less than 1" if item < 0
18
+
19
+ {name: name, item: item}
20
+ end
21
+
22
+ def self.execute options, lister
23
+ args = [ options[:item], options[:name] ]
24
+ raise(ItemNotFoundError, 'no item with given number') if lister.change_item(*args).nil?
25
+ end
26
+
27
+ def self.help
28
+ " r, replace-item ITEM, TEXT\tSet ITEM text to TEXT"
29
+ end
30
+
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,35 @@
1
+ module ListTool
2
+ module App
3
+
4
+ class ShowItemsCommand
5
+
6
+ def self.match? arg
7
+ ['s', 'show-items'].include? arg
8
+ end
9
+
10
+ def self.parse argv
11
+ raise ArgumentError, "expected argument to be an array, #{argv.class} given" unless argv.is_a? Array
12
+ list = argv.shift
13
+
14
+ if list
15
+ list = Integer( list ) - 1 rescue raise(ArgumentError, 'list number must be an integer')
16
+ raise ArgumentError, "list number can't be less than 1" if list < 0
17
+ end
18
+
19
+ list ? {list: list} : {}
20
+ end
21
+
22
+ def self.execute options, lister
23
+ items = options[:list].nil? ? lister.list() : lister.list(options[:list])
24
+ raise ListNotFoundError if items.nil?
25
+ Printer.print_items( items )
26
+ end
27
+
28
+ def self.help
29
+ " s, show-items [LIST]\t\tPrint contents of default or given list"
30
+ end
31
+
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,26 @@
1
+ module ListTool
2
+ module App
3
+
4
+ class ShowListsCommand
5
+
6
+ def self.match? arg
7
+ ['sl', 'show-lists'].include? arg
8
+ end
9
+
10
+ def self.parse argv
11
+ {}
12
+ end
13
+
14
+ def self.execute options, lister
15
+ lists = lister.lists
16
+ Printer.print_lists(lists)
17
+ end
18
+
19
+ def self.help
20
+ " sl, show-lists\t\tPrint list of existing lists"
21
+ end
22
+
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,26 @@
1
+ module ListTool
2
+ module App
3
+
4
+ class UnknownCommand
5
+
6
+ def self.match? arg
7
+ @unknown_command = arg
8
+ true
9
+ end
10
+
11
+ def self.parse argv
12
+ {}
13
+ end
14
+
15
+ def self.execute options, lister
16
+ raise UnknownCommandError, "unknown command: '#{@unknown_command}'"
17
+ end
18
+
19
+ def self.help
20
+ ""
21
+ end
22
+
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,31 @@
1
+ module ListTool
2
+ module App
3
+
4
+ class UseCommand
5
+
6
+ def self.match? arg
7
+ ['u', 'use'].include? arg
8
+ end
9
+
10
+ def self.parse argv
11
+ raise ArgumentError, "expected argument to be an array, #{argv.class} given" unless argv.is_a? Array
12
+ list = argv.shift
13
+ raise ArgumentError, "list number not specified" if list.nil?
14
+
15
+ list = Integer( list ) - 1 rescue raise(ArgumentError, 'list number must be an integer')
16
+ raise ArgumentError, "list number can't be less than 1" if list < 0
17
+
18
+ {list: list}
19
+ end
20
+
21
+ def self.execute options, lister
22
+ raise(ListNotFoundError, 'no list with given number') if lister.set_default_list( options[:list] ).nil?
23
+ end
24
+
25
+ def self.help
26
+ " u, use LIST\t\t\tSet default list"
27
+ end
28
+
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,24 @@
1
+ module ListTool
2
+ module App
3
+
4
+ class VersionCommand
5
+
6
+ def self.match? arg
7
+ ['v', '-v', 'version', '--version'].include? arg
8
+ end
9
+
10
+ def self.parse argv
11
+ {}
12
+ end
13
+
14
+ def self.execute options, lister
15
+ Printer.print_version
16
+ end
17
+
18
+ def self.help
19
+ " -v, --version\t\t\tPrint version"
20
+ end
21
+
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,43 @@
1
+ require_relative './commands/add_item_command.rb'
2
+ require_relative './commands/replace_item_command.rb'
3
+ require_relative './commands/delete_item_command.rb'
4
+ require_relative './commands/show_items_command.rb'
5
+ require_relative './commands/add_list_command.rb'
6
+ require_relative './commands/rename_list_command.rb'
7
+ require_relative './commands/delete_list_command.rb'
8
+ require_relative './commands/show_lists_command.rb'
9
+ require_relative './commands/use_command.rb'
10
+ require_relative './commands/help_command.rb'
11
+ require_relative './commands/version_command.rb'
12
+ require_relative './commands/unknown_command.rb'
13
+
14
+ module ListTool
15
+ module App
16
+
17
+ class Commands
18
+ COMMANDS = ListTool::App.constants.map {|const| ListTool::App.const_get(const)} - [self, Printer, Runner]
19
+
20
+ def self.process argv, lister
21
+ argv.is_a?(Array) || raise(ArgumentError, "expected first paramenter to be an Array, #{argv.class} given")
22
+ argv << 'h' if argv.empty?
23
+ param = argv.shift
24
+
25
+ begin
26
+ COMMANDS.each do |cmd|
27
+ if cmd.match? param
28
+ cmd.execute cmd.parse(argv), lister
29
+ break
30
+ end
31
+ end
32
+ end
33
+
34
+ end
35
+
36
+ def self.help
37
+ COMMANDS.inject(""){|out, cmd| out << cmd.help << "\n" }
38
+ end
39
+
40
+ end
41
+
42
+ end
43
+ end
@@ -0,0 +1,41 @@
1
+ module ListTool
2
+ module App
3
+
4
+ class Printer
5
+
6
+ def self.error error
7
+ puts "#{"ERROR".red}: #{error.message}\n"
8
+ end
9
+
10
+ def self.print_items list
11
+ out = "Printing #{list[:name].green}:\n"
12
+ list[:items].each.with_index do |item, index|
13
+ out << " %2i. %s\n" % [index+1, item]
14
+ end
15
+ puts out
16
+ end
17
+
18
+ def self.print_lists lists
19
+ out = "Printing lists:\n"
20
+ lists.each.with_index do |list, index|
21
+ out << " %2i. %s (%i)\n" % [index+1, list[0], list[1]]
22
+ end
23
+ puts out
24
+ end
25
+
26
+ def self.print_usage
27
+ out = "#{'USAGE'.green}: clt COMMAND [OPTIONS]\n\nCOMMANDS:\n"
28
+ Commands::COMMANDS.each do |cmd|
29
+ out << cmd.help << "\n"
30
+ end
31
+ puts out
32
+ end
33
+
34
+ def self.print_version
35
+ puts "clt version #{VERSION}"
36
+ end
37
+
38
+ end
39
+
40
+ end
41
+ end
@@ -0,0 +1,54 @@
1
+ module ListTool
2
+ module App
3
+
4
+ class Runner
5
+
6
+ def initialize
7
+ @datadir = File.join(Dir.home, '.clt/')
8
+ @datafile = 'data.json'
9
+
10
+ @lister = Lister.new
11
+ end
12
+
13
+ def run argv
14
+ ensure_data
15
+ load_data
16
+ Commands.process argv, @lister
17
+ @lister.save datafile_fullname
18
+ rescue => e
19
+ Printer.error(e)
20
+ end
21
+
22
+ private
23
+
24
+ def datafile_fullname
25
+ File.join(@datadir, @datafile)
26
+ end
27
+
28
+ def load_data
29
+ @lister.load File.join(@datadir, @datafile)
30
+ end
31
+
32
+ def ensure_data
33
+ ensure_data_dir
34
+ ensure_data_file
35
+ end
36
+
37
+ def ensure_data_dir
38
+ Dir.mkdir(@datadir) unless Dir.exist?(@datadir)
39
+ rescue SystemCallError
40
+ raise SystemCallError, "unable to create data folder"
41
+ end
42
+
43
+ def ensure_data_file
44
+ unless File.exist? datafile_fullname
45
+ File.open(datafile_fullname, 'w') {|f| f << '{"lists":[]}' }
46
+ end
47
+ rescue SystemCallError
48
+ raise SystemCallError, "unable to create data file"
49
+ end
50
+
51
+ end
52
+
53
+ end
54
+ end
@@ -0,0 +1,9 @@
1
+ class String
2
+ def colorize(code)
3
+ "\x1B[#{code}m" + self + "\x1B[0m"
4
+ end
5
+
6
+ def red; colorize(31); end
7
+ def green; colorize(32); end
8
+ def blue; colorize(34); end
9
+ end
@@ -0,0 +1,9 @@
1
+ require_relative './app/string.rb'
2
+ require_relative './app/printer.rb'
3
+ require_relative './app/runner.rb'
4
+ require_relative './app/commands.rb'
5
+
6
+ module ListTool
7
+ module App
8
+ end
9
+ end