taskwarrior 0.0.6 → 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 +5 -5
- data/.ruby-version +1 -0
- data/.travis.yml +1 -3
- data/Gemfile +2 -0
- data/Guardfile +7 -5
- data/Rakefile +7 -2
- data/examples/finished-early +6 -5
- data/lib/taskwarrior.rb +13 -12
- data/lib/taskwarrior/annotation.rb +4 -2
- data/lib/taskwarrior/annotation_mapper.rb +4 -2
- data/lib/taskwarrior/attributes.rb +17 -15
- data/lib/taskwarrior/priority_mapper.rb +4 -2
- data/lib/taskwarrior/project.rb +6 -5
- data/lib/taskwarrior/repository.rb +17 -16
- data/lib/taskwarrior/tag.rb +8 -9
- data/lib/taskwarrior/task.rb +19 -17
- data/lib/taskwarrior/task_mapper.rb +13 -11
- data/lib/taskwarrior/validations.rb +9 -9
- data/lib/taskwarrior/version.rb +3 -1
- data/taskwarrior.gemspec +19 -18
- data/test/test_helper.rb +12 -9
- data/test/unit/test_annotation.rb +8 -6
- data/test/unit/test_priority_mapper.rb +9 -7
- data/test/unit/test_project.rb +3 -1
- data/test/unit/test_repository.rb +10 -8
- data/test/unit/test_tag.rb +3 -1
- data/test/unit/test_tag_habtm.rb +11 -9
- data/test/unit/test_task.rb +15 -13
- metadata +46 -45
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 6aac12222b3d2328aa14bb14caa9311d1c2e12aa77c8e3850ca2120de75fd2aa
|
4
|
+
data.tar.gz: 3e9550497f5cb2eb240819d47a2cfcd4b8b2352caa91b54a2238066f30465a2d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 74d7f8653b90aa92ce15272793d1d5778f8923ebbe509baf90838cc029d0d7e2d0d26a0f174b02951e08215cb15184dfb22361e06ffc4381f822107a940de273
|
7
|
+
data.tar.gz: 9c9dea3ce097baa4a0dc3d88ff8236b83344ac8cb1dc168c5672e07d655995cf6121af4da8915a6d5f9aa33b6aff615f42d961f990fa7f70fd8bcf56cae09b24
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.5.1
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/Guardfile
CHANGED
@@ -1,12 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
guard 'bundler' do
|
2
4
|
watch('Gemfile')
|
3
5
|
watch(/^.+\.gemspec/)
|
4
6
|
end
|
5
7
|
|
6
|
-
guard :test, :
|
7
|
-
watch('lib/twdeps.rb'){
|
8
|
-
watch(%r{^lib/twdeps/(.+)\.rb$}){|m| "test/unit/test_#{m[1]}.rb"}
|
8
|
+
guard :test, test_paths: ['test/unit', 'test/integration'] do
|
9
|
+
watch('lib/twdeps.rb') { 'test' }
|
10
|
+
watch(%r{^lib/twdeps/(.+)\.rb$}) { |m| "test/unit/test_#{m[1]}.rb" }
|
9
11
|
watch(%r{^test/unit/test_(.+)\.rb$})
|
10
|
-
watch('test/test_helper.rb'){
|
11
|
-
watch('test/helpers/**/*'){
|
12
|
+
watch('test/test_helper.rb') { 'test' }
|
13
|
+
watch('test/helpers/**/*') { 'test' }
|
12
14
|
end
|
data/Rakefile
CHANGED
@@ -1,10 +1,15 @@
|
|
1
1
|
#!/usr/bin/env rake
|
2
|
-
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'bundler/gem_tasks'
|
3
5
|
require 'rake/testtask'
|
4
6
|
|
7
|
+
require 'rubocop/rake_task'
|
8
|
+
RuboCop::RakeTask.new
|
9
|
+
|
5
10
|
Rake::TestTask.new(:test) do |test|
|
6
11
|
test.libs << 'lib' << 'test' << 'test/helpers'
|
7
12
|
test.test_files = FileList['test/**/test_*.rb']
|
8
13
|
end
|
9
14
|
|
10
|
-
task :
|
15
|
+
task default: :test
|
data/examples/finished-early
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
#
|
4
5
|
# Prints those tasks the were completed before they were due.
|
@@ -18,9 +19,9 @@ end
|
|
18
19
|
|
19
20
|
puts "#{selected.size} tasks completed before they were due:"
|
20
21
|
|
21
|
-
selected.group_by{|t| (t.due_at - t.end_at).truncate}.sort.each
|
22
|
+
selected.group_by { |t| (t.due_at - t.end_at).truncate }.sort.each do |g, tasks|
|
22
23
|
puts "#{g} days early:"
|
23
|
-
tasks.each
|
24
|
-
|
25
|
-
|
26
|
-
|
24
|
+
tasks.each do |t|
|
25
|
+
puts " #{t.description}"
|
26
|
+
end
|
27
|
+
end
|
data/lib/taskwarrior.rb
CHANGED
@@ -1,21 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'active_model'
|
2
|
-
require 'multi_json'
|
3
4
|
require 'date'
|
4
5
|
|
5
|
-
require
|
6
|
+
require 'taskwarrior/version'
|
6
7
|
|
7
|
-
require
|
8
|
-
require
|
8
|
+
require 'taskwarrior/validations'
|
9
|
+
require 'taskwarrior/attributes'
|
9
10
|
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
13
|
-
require
|
14
|
-
require
|
11
|
+
require 'taskwarrior/repository'
|
12
|
+
require 'taskwarrior/task'
|
13
|
+
require 'taskwarrior/project'
|
14
|
+
require 'taskwarrior/tag'
|
15
|
+
require 'taskwarrior/annotation'
|
15
16
|
|
16
|
-
require
|
17
|
-
require
|
18
|
-
require
|
17
|
+
require 'taskwarrior/task_mapper'
|
18
|
+
require 'taskwarrior/priority_mapper'
|
19
|
+
require 'taskwarrior/annotation_mapper'
|
19
20
|
|
20
21
|
module TaskWarrior
|
21
22
|
end
|
@@ -1,10 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module TaskWarrior
|
2
4
|
class Annotation
|
3
5
|
attr_accessor :entry, :description
|
4
6
|
|
5
7
|
include ActiveModel::Validations
|
6
|
-
validates :entry, :
|
7
|
-
validates :description, :
|
8
|
+
validates :entry, presence: true
|
9
|
+
validates :description, presence: true
|
8
10
|
|
9
11
|
include TaskWarrior::Validations
|
10
12
|
validate :entry_cannot_be_in_the_future
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module TaskWarrior
|
2
4
|
#
|
3
5
|
# A DataMapper that makes new annotations from a JSON representation
|
@@ -5,9 +7,9 @@ module TaskWarrior
|
|
5
7
|
class AnnotationMapper
|
6
8
|
class << self
|
7
9
|
def map(json)
|
8
|
-
Annotation.new(json['description']).tap
|
10
|
+
Annotation.new(json['description']).tap do |t|
|
9
11
|
t.entry = DateTime.parse(json['entry'])
|
10
|
-
|
12
|
+
end
|
11
13
|
end
|
12
14
|
end
|
13
15
|
end
|
@@ -1,19 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module TaskWarrior
|
2
4
|
module Attributes
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
5
|
+
module ClassMethods
|
6
|
+
def attributes(*attr)
|
7
|
+
if attr.nil? || attr.empty?
|
8
|
+
@attributes
|
9
|
+
else
|
10
|
+
@attributes = attr
|
11
|
+
@attributes.each { |attr| send('attr_accessor', attr) }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
13
15
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
16
|
+
# http://blog.jayfields.com/2006/12/ruby-instance-and-class-methods-from.html
|
17
|
+
def self.included(base)
|
18
|
+
base.extend(ClassMethods)
|
19
|
+
end
|
18
20
|
end
|
19
|
-
end
|
21
|
+
end
|
data/lib/taskwarrior/project.rb
CHANGED
@@ -1,15 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module TaskWarrior
|
2
4
|
class Project
|
3
5
|
attr_reader :name, :tasks
|
4
6
|
|
5
7
|
include ActiveModel::Validations
|
6
|
-
validates :name, :
|
8
|
+
validates :name, presence: true
|
7
9
|
validate :name_may_not_contain_spaces
|
8
10
|
|
9
11
|
def initialize(name, tasks = [])
|
10
12
|
@name = name
|
11
13
|
@tasks = tasks
|
12
|
-
@tasks.each{|t| t.project = self}
|
14
|
+
@tasks.each { |t| t.project = self }
|
13
15
|
end
|
14
16
|
|
15
17
|
def <<(task)
|
@@ -33,10 +35,9 @@ module TaskWarrior
|
|
33
35
|
end
|
34
36
|
|
35
37
|
private
|
38
|
+
|
36
39
|
def name_may_not_contain_spaces
|
37
|
-
if !name.blank?
|
38
|
-
errors.add(:name, "may not contain spaces")
|
39
|
-
end
|
40
|
+
errors.add(:name, 'may not contain spaces') if !name.blank? && name[/\s/]
|
40
41
|
end
|
41
42
|
end
|
42
43
|
end
|
@@ -1,41 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module TaskWarrior
|
2
4
|
class Repository
|
3
5
|
def initialize(input)
|
4
6
|
@tasks = {}
|
5
|
-
@projects = Hash.new{|hash, key| hash[key] = Project.new(key)}
|
6
|
-
@tags = Hash.new{|hash, key| hash[key] = Tag.new(key)}
|
7
|
+
@projects = Hash.new { |hash, key| hash[key] = Project.new(key) }
|
8
|
+
@tags = Hash.new { |hash, key| hash[key] = Tag.new(key) }
|
7
9
|
|
8
|
-
|
10
|
+
JSON.parse(input).each do |json|
|
9
11
|
task = TaskWarrior::TaskMapper.map(json)
|
10
12
|
@tasks[task.uuid] = task
|
11
13
|
@projects[task.project].tasks << task if task.project
|
12
14
|
|
13
15
|
# Create a new Tag object in @tags that is the value for each tag name
|
14
|
-
task.tags.each{|tag_name| @tags[tag_name] << task}
|
15
|
-
|
16
|
+
task.tags.each { |tag_name| @tags[tag_name] << task }
|
17
|
+
end
|
16
18
|
|
17
19
|
# Replace the uuid of each dependency with the real task
|
18
|
-
@tasks.each_value{|task| task.dependencies.map!{|uuid| @tasks[uuid]}}
|
20
|
+
@tasks.each_value { |task| task.dependencies.map! { |uuid| @tasks[uuid] } }
|
19
21
|
|
20
22
|
# Replace the project property of each task with a proper Project object carrying a name and all of the project's tasks
|
21
|
-
@tasks.each_value{|task| task.project = @projects[task.project] if task.project}
|
23
|
+
@tasks.each_value { |task| task.project = @projects[task.project] if task.project }
|
22
24
|
|
23
25
|
# Add child tasks to their parent, but keep them in the global index
|
24
26
|
@tasks.each_value do |task|
|
25
|
-
|
26
|
-
|
27
|
+
next unless task.parent
|
28
|
+
parent = @tasks[task.parent]
|
27
29
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
end
|
30
|
+
if parent # we know the parent
|
31
|
+
parent.children << task
|
32
|
+
task.parent = parent
|
32
33
|
end
|
33
34
|
end
|
34
35
|
end
|
35
36
|
|
36
37
|
def tasks
|
37
38
|
# Do not expose child tasks directly
|
38
|
-
@tasks.values.reject
|
39
|
+
@tasks.values.reject(&:parent)
|
39
40
|
end
|
40
41
|
|
41
42
|
# direct lookup by uuid
|
@@ -48,7 +49,7 @@ module TaskWarrior
|
|
48
49
|
end
|
49
50
|
|
50
51
|
def project(name)
|
51
|
-
@projects[name] if @projects.
|
52
|
+
@projects[name] if @projects.key?(name)
|
52
53
|
end
|
53
54
|
|
54
55
|
def tags
|
@@ -56,7 +57,7 @@ module TaskWarrior
|
|
56
57
|
end
|
57
58
|
|
58
59
|
def tag(name)
|
59
|
-
@tags[name] if @tags.
|
60
|
+
@tags[name] if @tags.key?(name)
|
60
61
|
end
|
61
62
|
end
|
62
63
|
end
|
data/lib/taskwarrior/tag.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module TaskWarrior
|
2
4
|
class Tag
|
3
5
|
attr_reader :name
|
4
6
|
|
5
7
|
include ActiveModel::Validations
|
6
|
-
validates :name, :
|
8
|
+
validates :name, presence: true
|
7
9
|
validate :name_may_not_contain_spaces
|
8
10
|
|
9
11
|
def initialize(tag_or_name, tasks = [])
|
@@ -15,18 +17,16 @@ module TaskWarrior
|
|
15
17
|
@tasks = []
|
16
18
|
end
|
17
19
|
|
18
|
-
tasks.each
|
20
|
+
tasks.each do |task|
|
19
21
|
self << task
|
20
|
-
|
22
|
+
end
|
21
23
|
end
|
22
24
|
|
23
25
|
def <<(task)
|
24
26
|
@tasks << task unless @tasks.include?(task)
|
25
27
|
end
|
26
28
|
|
27
|
-
|
28
|
-
@tasks
|
29
|
-
end
|
29
|
+
attr_reader :tasks
|
30
30
|
|
31
31
|
def to_s
|
32
32
|
"Tag: #{name} (#{@tasks.size} tasks)"
|
@@ -44,10 +44,9 @@ module TaskWarrior
|
|
44
44
|
end
|
45
45
|
|
46
46
|
private
|
47
|
+
|
47
48
|
def name_may_not_contain_spaces
|
48
|
-
if !name.blank?
|
49
|
-
errors.add(:name, "may not contain spaces")
|
50
|
-
end
|
49
|
+
errors.add(:name, 'may not contain spaces') if !name.blank? && name[/\s/]
|
51
50
|
end
|
52
51
|
end
|
53
52
|
end
|
data/lib/taskwarrior/task.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module TaskWarrior
|
2
4
|
class Task
|
3
5
|
include TaskWarrior::Attributes
|
@@ -7,33 +9,33 @@ module TaskWarrior
|
|
7
9
|
|
8
10
|
include ActiveModel::Validations
|
9
11
|
|
10
|
-
validates :description, :id, :entry, :status, :uuid, :
|
12
|
+
validates :description, :id, :entry, :status, :uuid, presence: true
|
11
13
|
|
12
|
-
validates :id, :
|
13
|
-
:
|
14
|
-
:
|
14
|
+
validates :id, numericality: {
|
15
|
+
only_integer: true,
|
16
|
+
greater_than: 0
|
15
17
|
}
|
16
18
|
|
17
|
-
validates :uuid, :
|
18
|
-
:
|
19
|
-
:
|
19
|
+
validates :uuid, format: {
|
20
|
+
with: /[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}/,
|
21
|
+
message: "'%{value}' does not match the expected format of a UUID"
|
20
22
|
}
|
21
23
|
|
22
|
-
validates :status, :
|
23
|
-
:
|
24
|
-
:
|
24
|
+
validates :status, inclusion: {
|
25
|
+
in: %i[pending waiting complete],
|
26
|
+
message: '%{value} is not a valid status'
|
25
27
|
}
|
26
28
|
|
27
|
-
validates :priority, :
|
28
|
-
:
|
29
|
-
:
|
30
|
-
:
|
31
|
-
:
|
29
|
+
validates :priority, inclusion: {
|
30
|
+
in: %i[high medium low],
|
31
|
+
allow_nil: true,
|
32
|
+
allow_blank: true,
|
33
|
+
message: '%{value} is not a valid priority'
|
32
34
|
}
|
33
35
|
|
34
36
|
include TaskWarrior::Validations
|
35
37
|
validate :entry_cannot_be_in_the_future
|
36
|
-
validates :start_at, :wait_at, :end_at, :due_at, :
|
38
|
+
validates :start_at, :wait_at, :end_at, :due_at, with: :must_be_date_or_nil
|
37
39
|
|
38
40
|
def initialize(description)
|
39
41
|
@description = description
|
@@ -45,7 +47,7 @@ module TaskWarrior
|
|
45
47
|
end
|
46
48
|
|
47
49
|
def to_s
|
48
|
-
"Task '#{description}'".
|
50
|
+
"Task '#{description}'".yield_self { |result| "#{result} <#{uuid}>" if uuid }
|
49
51
|
end
|
50
52
|
|
51
53
|
# other may have the same uuid, but if its attributes differ, it will not be equal
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module TaskWarrior
|
2
4
|
#
|
3
5
|
# A DataMapper that makes new Tasks from a JSON representation
|
@@ -5,7 +7,7 @@ module TaskWarrior
|
|
5
7
|
class TaskMapper
|
6
8
|
class << self
|
7
9
|
def map(json)
|
8
|
-
Task.new(json['description']).tap
|
10
|
+
Task.new(json['description']).tap do |t|
|
9
11
|
t.id = json['id'].to_i
|
10
12
|
t.uuid = json['uuid']
|
11
13
|
t.entry = DateTime.parse(json['entry'])
|
@@ -13,22 +15,22 @@ module TaskWarrior
|
|
13
15
|
t.project = json['project']
|
14
16
|
|
15
17
|
if json['depends']
|
16
|
-
if json['depends'].respond_to?(:split)
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
18
|
+
t.dependencies = if json['depends'].respond_to?(:split)
|
19
|
+
json['depends'].split(',')
|
20
|
+
else
|
21
|
+
json['depends']
|
22
|
+
end
|
21
23
|
end
|
22
24
|
|
23
25
|
t.parent = json['parent'] # Children will be cross-indexed in the repository
|
24
26
|
t.priority = PriorityMapper.map(json['priority'])
|
25
|
-
json['tags']
|
26
|
-
json['annotations']
|
27
|
-
|
28
|
-
%w
|
27
|
+
json['tags']&.each { |tag| t.tags << tag }
|
28
|
+
json['annotations']&.each { |annotation| t.annotations << AnnotationMapper.map(annotation) }
|
29
|
+
|
30
|
+
%w[start wait end due].each do |datish|
|
29
31
|
t.send("#{datish}_at=", DateTime.parse(json[datish])) if json[datish]
|
30
32
|
end
|
31
|
-
|
33
|
+
end
|
32
34
|
end
|
33
35
|
end
|
34
36
|
end
|
@@ -1,20 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module TaskWarrior
|
2
4
|
module Validations
|
3
5
|
def must_be_date_or_nil(sym)
|
4
|
-
datish =
|
5
|
-
|
6
|
-
errors.add(sym,
|
6
|
+
datish = send(sym)
|
7
|
+
unless datish.nil? || datish.is_a?(DateTime)
|
8
|
+
errors.add(sym, 'must be nil or a valid DateTime object')
|
7
9
|
end
|
8
10
|
end
|
9
11
|
|
10
12
|
def entry_cannot_be_in_the_future
|
11
|
-
|
12
|
-
|
13
|
-
errors.add(:entry, "can't be in the future")
|
14
|
-
end
|
15
|
-
rescue
|
16
|
-
errors.add(:entry, "must be comparable to DateTime")
|
13
|
+
if !entry.blank? && (entry > DateTime.now)
|
14
|
+
errors.add(:entry, "can't be in the future")
|
17
15
|
end
|
16
|
+
rescue StandardError
|
17
|
+
errors.add(:entry, 'must be comparable to DateTime')
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
data/lib/taskwarrior/version.rb
CHANGED
data/taskwarrior.gemspec
CHANGED
@@ -1,27 +1,28 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require File.expand_path('lib/taskwarrior/version', __dir__)
|
3
5
|
|
4
6
|
Gem::Specification.new do |gem|
|
5
|
-
gem.authors = [
|
6
|
-
gem.email = [
|
7
|
-
gem.summary =
|
8
|
-
gem.description =
|
7
|
+
gem.authors = ['Nicholas E. Rabenau']
|
8
|
+
gem.email = ['nerab@gmx.net']
|
9
|
+
gem.summary = 'Ruby wrapper for TaskWarrior'
|
10
|
+
gem.description = 'Wraps access to TaskWarrior, the command-line task manager, in a Ruby gem.'
|
9
11
|
|
10
|
-
gem.files = `git ls-files`.split(
|
11
|
-
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
12
|
+
gem.files = `git ls-files`.split($OUTPUT_RECORD_SEPARATOR)
|
13
|
+
gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
|
12
14
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
13
|
-
gem.name =
|
14
|
-
gem.require_paths = [
|
15
|
+
gem.name = 'taskwarrior'
|
16
|
+
gem.require_paths = ['lib']
|
15
17
|
gem.version = TaskWarrior::VERSION
|
16
18
|
|
17
|
-
gem.add_dependency 'activemodel'
|
18
|
-
gem.add_dependency 'multi_json', '~> 1.3'
|
19
|
-
|
20
|
-
gem.add_development_dependency 'activesupport', '~> 3.2'
|
21
|
-
gem.add_development_dependency 'twtest', '~> 0.0.6'
|
22
|
-
gem.add_development_dependency 'guard-test', '~> 0.5'
|
23
|
-
gem.add_development_dependency 'guard-bundler', '~> 1.0'
|
24
|
-
gem.add_development_dependency 'rake', '~> 0.9'
|
19
|
+
gem.add_dependency 'activemodel'
|
25
20
|
|
21
|
+
gem.add_development_dependency 'activesupport'
|
22
|
+
gem.add_development_dependency 'guard-bundler'
|
23
|
+
gem.add_development_dependency 'guard-test'
|
26
24
|
gem.add_development_dependency 'pry'
|
25
|
+
gem.add_development_dependency 'rake'
|
26
|
+
gem.add_development_dependency 'rubocop'
|
27
|
+
gem.add_development_dependency 'twtest'
|
27
28
|
end
|
data/test/test_helper.rb
CHANGED
@@ -1,4 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'twtest'
|
4
|
+
require 'minitest/autorun'
|
2
5
|
require 'taskwarrior'
|
3
6
|
|
4
7
|
module TaskWarrior
|
@@ -8,7 +11,7 @@ module TaskWarrior
|
|
8
11
|
File.join(File.dirname(__FILE__), 'fixtures', name)
|
9
12
|
end
|
10
13
|
end
|
11
|
-
|
14
|
+
|
12
15
|
module Validations
|
13
16
|
def assert_valid(task)
|
14
17
|
assert(task.valid?, error_message(task.errors))
|
@@ -19,7 +22,7 @@ module TaskWarrior
|
|
19
22
|
end
|
20
23
|
|
21
24
|
def assert_equality(a1, a2)
|
22
|
-
|
25
|
+
refute_equal(a1.object_id, a2.object_id)
|
23
26
|
assert_equal(a1, a2)
|
24
27
|
assert(a1 == a2)
|
25
28
|
assert(a1.hash == a2.hash)
|
@@ -28,19 +31,19 @@ module TaskWarrior
|
|
28
31
|
end
|
29
32
|
|
30
33
|
def assert_inequality(a1, a2)
|
31
|
-
|
32
|
-
|
33
|
-
assert(
|
34
|
-
assert(
|
34
|
+
refute_equal(a1.object_id, a2.object_id)
|
35
|
+
refute_equal(a1, a2)
|
36
|
+
assert(a1 != a2)
|
37
|
+
assert(a1.hash != a2.hash)
|
35
38
|
assert(!a1.eql?(a2))
|
36
39
|
assert_equal(2, [a1, a2].uniq.size)
|
37
40
|
end
|
38
41
|
|
39
42
|
def error_message(errors)
|
40
|
-
errors.each_with_object([])
|
43
|
+
errors.each_with_object([]) do |e, result|
|
41
44
|
result << e.join(' ')
|
42
|
-
|
45
|
+
end.join("\n")
|
43
46
|
end
|
44
47
|
end
|
45
48
|
end
|
46
|
-
end
|
49
|
+
end
|
@@ -1,10 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'test_helper'
|
2
4
|
require 'date'
|
3
5
|
require 'active_support/core_ext'
|
4
6
|
|
5
|
-
class TestAnnotation < Test
|
7
|
+
class TestAnnotation < MiniTest::Test
|
6
8
|
include TaskWarrior::Test::Validations
|
7
|
-
|
9
|
+
|
8
10
|
def setup
|
9
11
|
@annotation = TaskWarrior::Annotation.new
|
10
12
|
|
@@ -38,12 +40,12 @@ class TestAnnotation < Test::Unit::TestCase
|
|
38
40
|
end
|
39
41
|
|
40
42
|
def test_entry_wrong_format
|
41
|
-
@annotation.entry =
|
43
|
+
@annotation.entry = 'foobar'
|
42
44
|
assert_invalid(@annotation)
|
43
45
|
end
|
44
46
|
|
45
47
|
def test_entry_future
|
46
|
-
@annotation.entry = DateTime.now.advance(:
|
48
|
+
@annotation.entry = DateTime.now.advance(days: 1)
|
47
49
|
assert_invalid(@annotation)
|
48
50
|
end
|
49
51
|
|
@@ -69,7 +71,7 @@ class TestAnnotation < Test::Unit::TestCase
|
|
69
71
|
a1.entry = DateTime.now
|
70
72
|
|
71
73
|
a2 = TaskWarrior::Annotation.new('foo')
|
72
|
-
a2.entry = DateTime.now.advance(:
|
74
|
+
a2.entry = DateTime.now.advance(days: -1)
|
73
75
|
|
74
76
|
assert_inequality(a1, a2)
|
75
77
|
end
|
@@ -79,7 +81,7 @@ class TestAnnotation < Test::Unit::TestCase
|
|
79
81
|
a1.entry = DateTime.now
|
80
82
|
|
81
83
|
a2 = TaskWarrior::Annotation.new('bar')
|
82
|
-
a2.entry = DateTime.now.advance(:
|
84
|
+
a2.entry = DateTime.now.advance(days: -1)
|
83
85
|
|
84
86
|
assert_inequality(a1, a2)
|
85
87
|
end
|
@@ -1,27 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'test_helper'
|
2
4
|
|
3
|
-
class TestPriorityMapper < Test
|
5
|
+
class TestPriorityMapper < MiniTest::Test
|
4
6
|
def test_nil
|
5
7
|
assert_nil(TaskWarrior::PriorityMapper.map(nil))
|
6
8
|
end
|
7
|
-
|
9
|
+
|
8
10
|
def test_empty
|
9
11
|
assert_nil(TaskWarrior::PriorityMapper.map(''))
|
10
12
|
end
|
11
|
-
|
13
|
+
|
12
14
|
def test_low
|
13
15
|
assert_equal(:low, TaskWarrior::PriorityMapper.map('L'))
|
14
16
|
end
|
15
|
-
|
17
|
+
|
16
18
|
def test_medium
|
17
19
|
assert_equal(:medium, TaskWarrior::PriorityMapper.map('M'))
|
18
20
|
end
|
19
|
-
|
21
|
+
|
20
22
|
def test_high
|
21
23
|
assert_equal(:high, TaskWarrior::PriorityMapper.map('H'))
|
22
24
|
end
|
23
|
-
|
25
|
+
|
24
26
|
def test_unknown
|
25
27
|
assert_nil(TaskWarrior::PriorityMapper.map('crap'))
|
26
28
|
end
|
27
|
-
end
|
29
|
+
end
|
data/test/unit/test_project.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'test_helper'
|
2
4
|
|
3
|
-
class TestRepository < Test
|
5
|
+
class TestRepository < MiniTest::Test
|
4
6
|
include TaskWarrior
|
5
7
|
include TaskWarrior::Test::Fixtures
|
6
8
|
|
@@ -10,7 +12,7 @@ class TestRepository < Test::Unit::TestCase
|
|
10
12
|
|
11
13
|
def test_tags_of_task
|
12
14
|
atm = @repo['67aafe0b-ddd7-482b-9cfa-ac42c43e7559']
|
13
|
-
|
15
|
+
refute_nil(atm)
|
14
16
|
assert_equal(2, atm.tags.size)
|
15
17
|
end
|
16
18
|
|
@@ -38,13 +40,13 @@ class TestRepository < Test::Unit::TestCase
|
|
38
40
|
|
39
41
|
def test_projects
|
40
42
|
party = @repo.project('party')
|
41
|
-
|
43
|
+
refute_nil(party)
|
42
44
|
assert_equal(6, party.tasks.size)
|
43
45
|
end
|
44
46
|
|
45
47
|
def test_tags
|
46
48
|
tags = @repo.tags
|
47
|
-
|
49
|
+
refute_nil(tags)
|
48
50
|
assert_equal(2, tags.size)
|
49
51
|
assert(tags.include?(@repo.tag('finance')))
|
50
52
|
assert(tags.include?(@repo.tag('mall')))
|
@@ -52,23 +54,23 @@ class TestRepository < Test::Unit::TestCase
|
|
52
54
|
|
53
55
|
def test_tasks_of_tag_finance
|
54
56
|
finance = @repo.tag('finance')
|
55
|
-
|
57
|
+
refute_nil(finance)
|
56
58
|
assert_equal(2, finance.tasks.size)
|
57
59
|
end
|
58
60
|
|
59
61
|
def test_tasks_of_tag_mall
|
60
62
|
mall = @repo.tag('mall')
|
61
|
-
|
63
|
+
refute_nil(mall)
|
62
64
|
assert_equal(3, mall.tasks.size)
|
63
65
|
end
|
64
66
|
|
65
67
|
def test_equality
|
66
68
|
t1 = @repo['b587f364-c68e-4438-b4d6-f2af6ad62518']
|
67
69
|
t2 = t1.dup
|
68
|
-
|
70
|
+
refute_equal(t1.object_id, t2.object_id)
|
69
71
|
|
70
72
|
t1.description = 'changed'
|
71
73
|
assert_equal(t1, t2)
|
72
|
-
assert(!
|
74
|
+
assert(!t1.eql?(t2))
|
73
75
|
end
|
74
76
|
end
|
data/test/unit/test_tag.rb
CHANGED
data/test/unit/test_tag_habtm.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'test_helper'
|
2
4
|
|
3
|
-
class TestTagHasAndBelongsToMany < Test
|
5
|
+
class TestTagHasAndBelongsToMany < MiniTest::Test
|
4
6
|
include TaskWarrior::Test::Validations
|
5
7
|
|
6
8
|
def setup
|
@@ -15,11 +17,11 @@ class TestTagHasAndBelongsToMany < Test::Unit::TestCase
|
|
15
17
|
@foo << @lookup_foo
|
16
18
|
@lookup_foo.tags << @foo
|
17
19
|
@lookup_foo.tags << @metasyntactic
|
18
|
-
|
20
|
+
|
19
21
|
@deadbeef << @lookup_deadbeef
|
20
22
|
@lookup_deadbeef.tags << @deadbeef
|
21
23
|
@lookup_deadbeef.tags << @metasyntactic
|
22
|
-
|
24
|
+
|
23
25
|
@metasyntactic << @lookup_foo
|
24
26
|
@metasyntactic << @lookup_deadbeef
|
25
27
|
end
|
@@ -30,9 +32,9 @@ class TestTagHasAndBelongsToMany < Test::Unit::TestCase
|
|
30
32
|
|
31
33
|
assert_tagged_with(@lookup_foo, @foo)
|
32
34
|
assert_tagged_with(@lookup_foo, @metasyntactic)
|
33
|
-
|
35
|
+
refute_tagged_with(@lookup_foo, @deadbeef)
|
34
36
|
|
35
|
-
|
37
|
+
refute_tagged_with(@lookup_deadbeef, @foo)
|
36
38
|
assert_tagged_with(@lookup_deadbeef, @metasyntactic)
|
37
39
|
assert_tagged_with(@lookup_deadbeef, @deadbeef)
|
38
40
|
end
|
@@ -43,8 +45,8 @@ class TestTagHasAndBelongsToMany < Test::Unit::TestCase
|
|
43
45
|
assert_equal(2, @metasyntactic.tasks.size)
|
44
46
|
|
45
47
|
assert_contains_task(@deadbeef, @lookup_deadbeef)
|
46
|
-
|
47
|
-
|
48
|
+
refute_contains_task(@deadbeef, @lookup_foo)
|
49
|
+
refute_contains_task(@foo, @lookup_deadbeef)
|
48
50
|
assert_contains_task(@foo, @lookup_foo)
|
49
51
|
|
50
52
|
assert_contains_task(@metasyntactic, @lookup_deadbeef)
|
@@ -55,7 +57,7 @@ class TestTagHasAndBelongsToMany < Test::Unit::TestCase
|
|
55
57
|
assert(task.tags.include?(tag), "#{task} expected to be tagged with #{tag}, but it isn't.'")
|
56
58
|
end
|
57
59
|
|
58
|
-
def
|
60
|
+
def refute_tagged_with(task, tag)
|
59
61
|
assert(!task.tags.include?(tag), "#{task} expected not to be tagged with #{tag}, but it actually is.")
|
60
62
|
end
|
61
63
|
|
@@ -63,7 +65,7 @@ class TestTagHasAndBelongsToMany < Test::Unit::TestCase
|
|
63
65
|
assert(tag.tasks.include?(task), "#{tag} expected to contain #{task}, but it doesn't.")
|
64
66
|
end
|
65
67
|
|
66
|
-
def
|
68
|
+
def refute_contains_task(tag, task)
|
67
69
|
assert(!tag.tasks.include?(task), "#{tag} expected to not contain #{task}, but it actually does.")
|
68
70
|
end
|
69
71
|
end
|
data/test/unit/test_task.rb
CHANGED
@@ -1,13 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'test_helper'
|
2
4
|
require 'date'
|
3
5
|
require 'active_support/core_ext'
|
4
6
|
|
5
|
-
# TODO Add tests for dependencies
|
7
|
+
# TODO: Add tests for dependencies
|
6
8
|
|
7
|
-
class TestTask < Test
|
9
|
+
class TestTask < MiniTest::Test
|
8
10
|
include TaskWarrior
|
9
11
|
include TaskWarrior::Test::Validations
|
10
|
-
|
12
|
+
|
11
13
|
def setup
|
12
14
|
@task = Task.new('foobar')
|
13
15
|
@task.id = 1
|
@@ -67,12 +69,12 @@ class TestTask < Test::Unit::TestCase
|
|
67
69
|
end
|
68
70
|
|
69
71
|
def test_entry_wrong_format
|
70
|
-
@task.entry =
|
72
|
+
@task.entry = 'foobar'
|
71
73
|
assert_invalid(@task)
|
72
74
|
end
|
73
75
|
|
74
76
|
def test_entry_future
|
75
|
-
@task.entry = DateTime.now.advance(:
|
77
|
+
@task.entry = DateTime.now.advance(days: 1)
|
76
78
|
assert_invalid(@task)
|
77
79
|
end
|
78
80
|
|
@@ -87,7 +89,7 @@ class TestTask < Test::Unit::TestCase
|
|
87
89
|
end
|
88
90
|
|
89
91
|
def test_status_unknown_string
|
90
|
-
@task.status =
|
92
|
+
@task.status = 'foobar'
|
91
93
|
assert_invalid(@task)
|
92
94
|
end
|
93
95
|
|
@@ -107,7 +109,7 @@ class TestTask < Test::Unit::TestCase
|
|
107
109
|
end
|
108
110
|
|
109
111
|
def test_priority_unknown_string
|
110
|
-
@task.priority =
|
112
|
+
@task.priority = 'foobar'
|
111
113
|
assert_invalid(@task)
|
112
114
|
end
|
113
115
|
|
@@ -170,17 +172,17 @@ class TestTask < Test::Unit::TestCase
|
|
170
172
|
end
|
171
173
|
|
172
174
|
def assert_datish_wrong_format(sym)
|
173
|
-
@task.send("#{sym}=",
|
175
|
+
@task.send("#{sym}=", 'foobar')
|
174
176
|
assert_invalid(@task)
|
175
177
|
end
|
176
178
|
|
177
179
|
def assert_datish_future(sym)
|
178
|
-
@task.send("#{sym}=", DateTime.now.advance(:
|
180
|
+
@task.send("#{sym}=", DateTime.now.advance(days: 1))
|
179
181
|
assert_valid(@task)
|
180
182
|
end
|
181
183
|
|
182
184
|
def assert_datish_past(sym)
|
183
|
-
@task.send("#{sym}=", DateTime.now.advance(:
|
185
|
+
@task.send("#{sym}=", DateTime.now.advance(days: -1))
|
184
186
|
assert_valid(@task)
|
185
187
|
end
|
186
188
|
|
@@ -191,7 +193,7 @@ class TestTask < Test::Unit::TestCase
|
|
191
193
|
# Tasks are entities, so even with the same attributes, two different objects
|
192
194
|
# must not be treated equal
|
193
195
|
assert_inequality(a1, a2)
|
194
|
-
|
196
|
+
|
195
197
|
# But comparing the same thing to itself is fine
|
196
198
|
assert_equal(a1, a1)
|
197
199
|
assert_equal(a2, a2)
|
@@ -208,7 +210,7 @@ class TestTask < Test::Unit::TestCase
|
|
208
210
|
a1.entry = DateTime.now
|
209
211
|
|
210
212
|
a2 = Task.new('foo')
|
211
|
-
a2.entry = DateTime.now.advance(:
|
213
|
+
a2.entry = DateTime.now.advance(days: -1)
|
212
214
|
|
213
215
|
assert_inequality(a1, a2)
|
214
216
|
end
|
@@ -218,7 +220,7 @@ class TestTask < Test::Unit::TestCase
|
|
218
220
|
a1.entry = DateTime.now
|
219
221
|
|
220
222
|
a2 = Task.new('bar')
|
221
|
-
a2.entry = DateTime.now.advance(:
|
223
|
+
a2.entry = DateTime.now.advance(days: -1)
|
222
224
|
|
223
225
|
assert_inequality(a1, a2)
|
224
226
|
end
|
metadata
CHANGED
@@ -1,125 +1,125 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: taskwarrior
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nicholas E. Rabenau
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-03-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: activesupport
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
34
|
-
type: :
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: guard-bundler
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: guard-test
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 0
|
61
|
+
version: '0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 0
|
68
|
+
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: pry
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- -
|
73
|
+
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: '0
|
75
|
+
version: '0'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- -
|
80
|
+
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: '0
|
82
|
+
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
84
|
+
name: rake
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- -
|
87
|
+
- - ">="
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: '
|
89
|
+
version: '0'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- -
|
94
|
+
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: '
|
96
|
+
version: '0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
98
|
+
name: rubocop
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
|
-
- -
|
101
|
+
- - ">="
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version: '0
|
103
|
+
version: '0'
|
104
104
|
type: :development
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
|
-
- -
|
108
|
+
- - ">="
|
109
109
|
- !ruby/object:Gem::Version
|
110
|
-
version: '0
|
110
|
+
version: '0'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
|
-
name:
|
112
|
+
name: twtest
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
|
-
- -
|
115
|
+
- - ">="
|
116
116
|
- !ruby/object:Gem::Version
|
117
117
|
version: '0'
|
118
118
|
type: :development
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
|
-
- -
|
122
|
+
- - ">="
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '0'
|
125
125
|
description: Wraps access to TaskWarrior, the command-line task manager, in a Ruby
|
@@ -130,8 +130,9 @@ executables: []
|
|
130
130
|
extensions: []
|
131
131
|
extra_rdoc_files: []
|
132
132
|
files:
|
133
|
-
- .gitignore
|
134
|
-
- .
|
133
|
+
- ".gitignore"
|
134
|
+
- ".ruby-version"
|
135
|
+
- ".travis.yml"
|
135
136
|
- Gemfile
|
136
137
|
- Guardfile
|
137
138
|
- LICENSE
|
@@ -172,17 +173,17 @@ require_paths:
|
|
172
173
|
- lib
|
173
174
|
required_ruby_version: !ruby/object:Gem::Requirement
|
174
175
|
requirements:
|
175
|
-
- -
|
176
|
+
- - ">="
|
176
177
|
- !ruby/object:Gem::Version
|
177
178
|
version: '0'
|
178
179
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
179
180
|
requirements:
|
180
|
-
- -
|
181
|
+
- - ">="
|
181
182
|
- !ruby/object:Gem::Version
|
182
183
|
version: '0'
|
183
184
|
requirements: []
|
184
185
|
rubyforge_project:
|
185
|
-
rubygems_version: 2.
|
186
|
+
rubygems_version: 2.7.6
|
186
187
|
signing_key:
|
187
188
|
specification_version: 4
|
188
189
|
summary: Ruby wrapper for TaskWarrior
|