duyoji_todo 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.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +5 -0
- data/bin/duyoji_todo +5 -0
- data/duyoji_todo.gemspec +28 -0
- data/lib/duyoji_todo.rb +9 -0
- data/lib/duyoji_todo/command.rb +106 -0
- data/lib/duyoji_todo/command/options.rb +119 -0
- data/lib/duyoji_todo/db.rb +52 -0
- data/lib/duyoji_todo/task.rb +37 -0
- data/lib/duyoji_todo/version.rb +3 -0
- metadata +143 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 2b94f5c63e1af147d5b7717f08b1767fc004d0d8
|
|
4
|
+
data.tar.gz: 9b96544a4547ca86ff3b5f14e55a049652857f29
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: fe6d846d42ed990583d2f2ed2b3f880a4545657317bd4f042bb6e3e9b81447302cbe3cd56c63f781348c490887c3aa476a4619fc78d7810a5624b2e37a7247d2
|
|
7
|
+
data.tar.gz: a60e761580d8e169d8db555b096a2c4962fbac05080fcff28911637cb899715aa66aaf0b31b6aa1d96c25b6089222c8d04b8b98411e97a6d2a681547541ed68b
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Copyright (c) 2013 Tsuyoshi Maeda
|
|
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
|
+
# DuyojiTodo
|
|
2
|
+
|
|
3
|
+
TODO: Write a gem description
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
Add this line to your application's Gemfile:
|
|
8
|
+
|
|
9
|
+
gem 'duyoji_todo'
|
|
10
|
+
|
|
11
|
+
And then execute:
|
|
12
|
+
|
|
13
|
+
$ bundle
|
|
14
|
+
|
|
15
|
+
Or install it yourself as:
|
|
16
|
+
|
|
17
|
+
$ gem install duyoji_todo
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
TODO: Write usage instructions here
|
|
22
|
+
|
|
23
|
+
## Contributing
|
|
24
|
+
|
|
25
|
+
1. Fork it
|
|
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
data/bin/duyoji_todo
ADDED
data/duyoji_todo.gemspec
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
require 'duyoji_todo/version'
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |spec|
|
|
7
|
+
spec.name = "duyoji_todo"
|
|
8
|
+
spec.version = DuyojiTodo::VERSION
|
|
9
|
+
spec.authors = ["Tsuyoshi Maeda"]
|
|
10
|
+
spec.email = ["oasis5tsuyoshi@gmail.com"]
|
|
11
|
+
spec.description = %q{Perfect Ruby chapter15}
|
|
12
|
+
spec.summary = %q{Perfect Ruby chapter15}
|
|
13
|
+
spec.homepage = "http://duyoji.hatenablog.com/"
|
|
14
|
+
spec.license = "MIT"
|
|
15
|
+
|
|
16
|
+
spec.files = `git ls-files`.split($/)
|
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
19
|
+
spec.require_paths = ["lib"]
|
|
20
|
+
|
|
21
|
+
spec.add_dependency "activerecord", "~> 3.2.0"
|
|
22
|
+
spec.add_dependency "sqlite3", "~> 1.3.0"
|
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
|
24
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
|
25
|
+
spec.add_development_dependency "yard", "~> 0.8"
|
|
26
|
+
spec.add_development_dependency "redcarpet", "~> 2.2"
|
|
27
|
+
|
|
28
|
+
end
|
data/lib/duyoji_todo.rb
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
#coding: utf-8
|
|
2
|
+
|
|
3
|
+
module DuyojiTodo
|
|
4
|
+
|
|
5
|
+
# コマンドラインベースの処理を行うクラスです
|
|
6
|
+
# @author Tsuyoshi Maeda
|
|
7
|
+
class Command
|
|
8
|
+
|
|
9
|
+
class << self
|
|
10
|
+
def run(argv)
|
|
11
|
+
new(argv).execute
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def initialize(argv)
|
|
16
|
+
@argv = argv
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def execute
|
|
20
|
+
options = Options.parse!(@argv)
|
|
21
|
+
sub_command = options.delete(:command)
|
|
22
|
+
|
|
23
|
+
#puts options
|
|
24
|
+
|
|
25
|
+
DB.prepare
|
|
26
|
+
|
|
27
|
+
tasks = case sub_command
|
|
28
|
+
when 'create'
|
|
29
|
+
create_task(options[:name], options[:content])
|
|
30
|
+
when 'delete'
|
|
31
|
+
delete_task(options[:id])
|
|
32
|
+
when 'update'
|
|
33
|
+
update_task(options.delete(:id), options)
|
|
34
|
+
when 'list'
|
|
35
|
+
find_tasks(options[:status])
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
display_tasks tasks
|
|
39
|
+
|
|
40
|
+
rescue => e
|
|
41
|
+
abort "Error: #{e.message}"
|
|
42
|
+
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def create_task(name, content)
|
|
46
|
+
# タスク作成時のstatusはデフォルト値が使われNOT_YETとなる
|
|
47
|
+
Task.create!(name: name, content: content).reload
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def delete_task(id)
|
|
51
|
+
task = Task.find(id)
|
|
52
|
+
task.destroy
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def update_task(id, attributes)
|
|
56
|
+
if status_name = attributes[:status]
|
|
57
|
+
attributes[:status] = DuyojiTodo::Task::STATUS.fetch(status_name.upcase)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
task = Task.find(id)
|
|
61
|
+
task.update_attributes! attributes
|
|
62
|
+
|
|
63
|
+
task.reload
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def find_tasks(status_name)
|
|
67
|
+
all_tasks = Task.order('created_at DESC')
|
|
68
|
+
|
|
69
|
+
if status_name
|
|
70
|
+
status = DuyojiTodo::Task::STATUS.fetch(status_name.upcase)
|
|
71
|
+
all_tasks.status_is(status)
|
|
72
|
+
else
|
|
73
|
+
all_tasks
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
private
|
|
78
|
+
|
|
79
|
+
# タスクの表示
|
|
80
|
+
def display_tasks(tasks)
|
|
81
|
+
header = display_format('ID', 'Name', 'Content', 'Status')
|
|
82
|
+
|
|
83
|
+
puts header
|
|
84
|
+
puts '-' * header.size
|
|
85
|
+
Array(tasks).each do |task|
|
|
86
|
+
puts display_format(task.id, task.name, task.content, task.status_name)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# タスク表示のフォーマット化
|
|
92
|
+
def display_format(id, name, content, status)
|
|
93
|
+
name_length = 20 - full_width_count(name)
|
|
94
|
+
content_length = 40 - full_width_count(content)
|
|
95
|
+
|
|
96
|
+
[ id.to_s.rjust(4), name.ljust(name_length), content.ljust(content_length), status.ljust(8) ].join(' | ')
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# リスト表示の際の文字調整
|
|
100
|
+
def full_width_count(string)
|
|
101
|
+
string.each_char.select{ |char| !( /[ -~.]/.match(char) ) }.count
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
end
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
#coding: utf-8
|
|
2
|
+
|
|
3
|
+
require "optparse"
|
|
4
|
+
|
|
5
|
+
module DuyojiTodo
|
|
6
|
+
|
|
7
|
+
class Command
|
|
8
|
+
|
|
9
|
+
module Options
|
|
10
|
+
|
|
11
|
+
def self.parse!(argv)
|
|
12
|
+
options = {}
|
|
13
|
+
|
|
14
|
+
# サブコマンドなどのOptionParserを定義
|
|
15
|
+
sub_command_parsers = create_sub_command_parsers(options)
|
|
16
|
+
command_parser = create_command_parser
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
# 引数解析を行う
|
|
20
|
+
begin
|
|
21
|
+
command_parser.order!(argv)
|
|
22
|
+
options[:command] = argv.shift
|
|
23
|
+
sub_command_parsers[ options[:command] ].parse!(argv)
|
|
24
|
+
|
|
25
|
+
#updateとdeleteの場合は
|
|
26
|
+
if %w(update delete).include?( options[:command] )
|
|
27
|
+
raise ArgumentError, "#{options[:command]} id not found." if argv.empty?
|
|
28
|
+
options[:id] = Integer(argv.first)
|
|
29
|
+
end
|
|
30
|
+
rescue OptionParser::MissingArgument => e
|
|
31
|
+
abort "OptionParserMissingArgument : #{e.message}"
|
|
32
|
+
rescue OptionParser::InvalidOption => e
|
|
33
|
+
abort "OptionParserInvalidOption : #{e.message}"
|
|
34
|
+
rescue ArgumentError => e
|
|
35
|
+
abort "ArgumentError : #{e.message}"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
options
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def self.create_sub_command_parsers(options)
|
|
42
|
+
# サブコマンドの処理をする際に、未定義のkeyを指定されたら例外を発生させる
|
|
43
|
+
sub_command_parsers = Hash.new do |k, v|
|
|
44
|
+
raise ArgumentError, "'#{v}' is not duyoji_todo sub command."
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# サブコマンド用の定義
|
|
48
|
+
sub_command_parsers['create'] = OptionParser.new do |opt|
|
|
49
|
+
opt.banner = "Usage: create <args>"
|
|
50
|
+
opt.on('-n', '--name=VAL', 'task name') { |v| options[:name] = v }
|
|
51
|
+
opt.on('-c', '--content=VAL', 'task content') { |v| options[:content] = v }
|
|
52
|
+
opt.on_tail('-h', '--help', 'Show this message') { |v| help_sub_command(opt) }
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
sub_command_parsers['list'] = OptionParser.new do |opt|
|
|
56
|
+
opt.banner = "Usage: list <args>"
|
|
57
|
+
opt.on('-s', '--status=VAL', 'search status') { |v| options[:status] = v }
|
|
58
|
+
opt.on_tail('-h', '--help', 'Show this message') { |v| help_sub_command(opt) }
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
sub_command_parsers['update'] = OptionParser.new do |opt|
|
|
62
|
+
opt.banner = "Usage: update id <args>"
|
|
63
|
+
opt.on('-n', '--name=VAL', 'update name') { |v| options[:name] = v }
|
|
64
|
+
opt.on('-c', '--content=VAL', 'update content') { |v| options[:content] = v }
|
|
65
|
+
opt.on('-s', '--status=VAL', 'update status') { |v| options[:status] = v }
|
|
66
|
+
opt.on_tail('-h', '--help', 'Show this message') { |v| help_sub_command(opt) }
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
sub_command_parsers['delete'] = OptionParser.new do |opt|
|
|
70
|
+
opt.banner = "Usage: delete id"
|
|
71
|
+
opt.on_tail('-h', '--help', 'Show this message') { |v| help_sub_command(opt) }
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
sub_command_parsers
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def self.create_command_parser
|
|
78
|
+
# サブコマンド以外の定数の定義
|
|
79
|
+
OptionParser.new do |opt|
|
|
80
|
+
sub_command_help = [
|
|
81
|
+
{name: 'create -n name -c content', summary: 'Create Todo Task'},
|
|
82
|
+
{name: 'update id -n name -c content -s status', summary: 'Update Todo Task'},
|
|
83
|
+
{name: 'list -s status', summary: 'List Todo Task'},
|
|
84
|
+
{name: 'delete id', summary: 'Delete Todo Task'},
|
|
85
|
+
]
|
|
86
|
+
|
|
87
|
+
opt.banner = "Usage: #{opt.program_name} [-h|--help] [-v|--version] <command> [<args>]"
|
|
88
|
+
opt.separator ''
|
|
89
|
+
opt.separator "#{opt.program_name} Available Commands:"
|
|
90
|
+
|
|
91
|
+
sub_command_help.each do |command|
|
|
92
|
+
opt.separator [ opt.summary_indent, command[:name].ljust(40), command[:summary] ].join(' ')
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
opt.on_head('-h', '--help', 'Show this version') do |v|
|
|
96
|
+
puts opt.help
|
|
97
|
+
exit
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
opt.on_head('-v', '--version', 'Show program version') do |v|
|
|
101
|
+
opt.version = DuyojiTodo::VERSION
|
|
102
|
+
puts opt.ver
|
|
103
|
+
exit
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# サブコマンドのヘルプ情報
|
|
109
|
+
def self.help_sub_command(parser)
|
|
110
|
+
puts parser.help
|
|
111
|
+
exit
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
private_class_method :create_sub_command_parsers, :create_command_parser, :help_sub_command
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
##coding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'fileutils'
|
|
4
|
+
require 'active_record'
|
|
5
|
+
|
|
6
|
+
module DuyojiTodo
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
# データベースへの接続処理を扱うモジュール
|
|
10
|
+
# @author Tsuyoshi Maeda
|
|
11
|
+
module DB
|
|
12
|
+
|
|
13
|
+
# データベースへの接続とテーブルの作成を行う
|
|
14
|
+
# @return [void]
|
|
15
|
+
def self.prepare
|
|
16
|
+
database_path = File.join(ENV['HOME'], '.duyoji_todo', 'duyoji_todo.sqlite3')
|
|
17
|
+
|
|
18
|
+
connect_database database_path
|
|
19
|
+
create_table_if_not_exists database_path
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def self.connect_database(path)
|
|
23
|
+
spec = {adapter: 'sqlite3', database: path}
|
|
24
|
+
ActiveRecord::Base.establish_connection spec
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def self.create_table_if_not_exists(path)
|
|
28
|
+
create_database_path path
|
|
29
|
+
|
|
30
|
+
connection = ActiveRecord::Base.connection
|
|
31
|
+
|
|
32
|
+
return if connection.table_exists?(:tasks)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
connection.create_table :tasks do |t|
|
|
36
|
+
t.column :name, :string, null: false
|
|
37
|
+
t.column :content, :text, null: false
|
|
38
|
+
t.column :status, :integer, default: 0, null: false
|
|
39
|
+
t.timestamps
|
|
40
|
+
end
|
|
41
|
+
connection.add_index :tasks, :status
|
|
42
|
+
connection.add_index :tasks, :created_at
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def self.create_database_path(path)
|
|
46
|
+
FileUtils.mkdir_p File.dirname(path)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
private_class_method :connect_database, :create_table_if_not_exists, :create_database_path
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#coding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'active_record'
|
|
4
|
+
|
|
5
|
+
module DuyojiTodo
|
|
6
|
+
|
|
7
|
+
# tasksテーブルを表現するモデルクラスです
|
|
8
|
+
# @author Tsuyoshi Maeda
|
|
9
|
+
class Task < ActiveRecord::Base
|
|
10
|
+
|
|
11
|
+
NOT_YET = 0 # タスクが完了していない
|
|
12
|
+
DONE = 1 # タスクが完了した
|
|
13
|
+
PENDING = 2 # 保留状態
|
|
14
|
+
|
|
15
|
+
# ステータ薄の名称と数値の組み合わせの値
|
|
16
|
+
STATUS = {
|
|
17
|
+
'NOT_YET' => NOT_YET,
|
|
18
|
+
'DONE' => DONE,
|
|
19
|
+
'PENDING' => PENDING
|
|
20
|
+
}.freeze
|
|
21
|
+
|
|
22
|
+
# ステータスの条件のよって取得する値を切り替える
|
|
23
|
+
scope :status_is, ->(status) { where(status: status) }
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
# バリデート
|
|
27
|
+
validates :name, presence: true, length: {maximum: 140}
|
|
28
|
+
validates :content, presence: true
|
|
29
|
+
validates :status, numericality: true, inclusion: {in: STATUS.values}
|
|
30
|
+
|
|
31
|
+
def status_name
|
|
32
|
+
STATUS.key(self.status)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: duyoji_todo
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Tsuyoshi Maeda
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2013-12-01 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: activerecord
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ~>
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: 3.2.0
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ~>
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: 3.2.0
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: sqlite3
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ~>
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: 1.3.0
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ~>
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: 1.3.0
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: bundler
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - ~>
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '1.3'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - ~>
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '1.3'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: rake
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - ~>
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '10.0'
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - ~>
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '10.0'
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: yard
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - ~>
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '0.8'
|
|
76
|
+
type: :development
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - ~>
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '0.8'
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: redcarpet
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - ~>
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '2.2'
|
|
90
|
+
type: :development
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - ~>
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '2.2'
|
|
97
|
+
description: Perfect Ruby chapter15
|
|
98
|
+
email:
|
|
99
|
+
- oasis5tsuyoshi@gmail.com
|
|
100
|
+
executables:
|
|
101
|
+
- duyoji_todo
|
|
102
|
+
extensions: []
|
|
103
|
+
extra_rdoc_files: []
|
|
104
|
+
files:
|
|
105
|
+
- .gitignore
|
|
106
|
+
- Gemfile
|
|
107
|
+
- LICENSE.txt
|
|
108
|
+
- README.md
|
|
109
|
+
- Rakefile
|
|
110
|
+
- bin/duyoji_todo
|
|
111
|
+
- duyoji_todo.gemspec
|
|
112
|
+
- lib/duyoji_todo.rb
|
|
113
|
+
- lib/duyoji_todo/command.rb
|
|
114
|
+
- lib/duyoji_todo/command/options.rb
|
|
115
|
+
- lib/duyoji_todo/db.rb
|
|
116
|
+
- lib/duyoji_todo/task.rb
|
|
117
|
+
- lib/duyoji_todo/version.rb
|
|
118
|
+
homepage: http://duyoji.hatenablog.com/
|
|
119
|
+
licenses:
|
|
120
|
+
- MIT
|
|
121
|
+
metadata: {}
|
|
122
|
+
post_install_message:
|
|
123
|
+
rdoc_options: []
|
|
124
|
+
require_paths:
|
|
125
|
+
- lib
|
|
126
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
127
|
+
requirements:
|
|
128
|
+
- - '>='
|
|
129
|
+
- !ruby/object:Gem::Version
|
|
130
|
+
version: '0'
|
|
131
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
132
|
+
requirements:
|
|
133
|
+
- - '>='
|
|
134
|
+
- !ruby/object:Gem::Version
|
|
135
|
+
version: '0'
|
|
136
|
+
requirements: []
|
|
137
|
+
rubyforge_project:
|
|
138
|
+
rubygems_version: 2.1.11
|
|
139
|
+
signing_key:
|
|
140
|
+
specification_version: 4
|
|
141
|
+
summary: Perfect Ruby chapter15
|
|
142
|
+
test_files: []
|
|
143
|
+
has_rdoc:
|