rtasklib 0.2.3.pre.alpha → 0.2.3.pre.beta
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE.txt +2 -1
- data/README.md +77 -5
- data/bin/env +1 -1
- data/lib/rtasklib.rb +78 -1
- data/lib/rtasklib/controller.rb +90 -22
- data/lib/rtasklib/execute.rb +6 -9
- data/lib/rtasklib/helpers.rb +25 -2
- data/lib/rtasklib/models.rb +26 -7
- data/lib/rtasklib/taskrc.rb +15 -1
- data/lib/rtasklib/version.rb +7 -1
- data/rtasklib.gemspec +0 -1
- data/spec/controller_spec.rb +5 -0
- data/spec/execute_spec.rb +5 -0
- data/spec/helpers_spec.rb +5 -0
- data/spec/models_spec.rb +5 -0
- data/spec/rtasklib_spec.rb +5 -0
- data/spec/spec_helper.rb +6 -1
- data/spec/taskrc_spec.rb +5 -0
- metadata +1 -17
- data/rubygem-rtasklib.spec +0 -71
- data/rubygem-rtasklib.spec.template +0 -69
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6ea31920458cceb17a1ce39892a1ec2ae5d5174e
|
4
|
+
data.tar.gz: 0f4bc7d917dc78a366a2d10185845c937be0451c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4cf37fe6283bb192b1f1333a08713c70787459b8faae75ff56c1f9a3c713cf1641e437b724a4499a9f7f13de741534f6b6240088668a5d07dccafe9532d5bc5e
|
7
|
+
data.tar.gz: 9f66f97b08122ffa14a3b7633c4fc6714dc02e67a97cda0cdb6ac7817aff71f0ef9f14fc50e45fb2f620153a01f86f181ae514c92c88a56024def52d415cbb3a
|
data/LICENSE.txt
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
The MIT License (MIT)
|
2
2
|
|
3
|
-
Copyright (c) 2015 Will Paul
|
3
|
+
Copyright (c) 2015 Will Paul (whp3652@rit.edu)
|
4
|
+
All rights reserved.
|
4
5
|
|
5
6
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
7
|
of this software and associated documentation files (the "Software"), to deal
|
data/README.md
CHANGED
@@ -10,6 +10,10 @@ A Ruby wrapper around the TaskWarrior command line tool.
|
|
10
10
|
|
11
11
|
## Installation
|
12
12
|
|
13
|
+
### Using `bundle` or `gem`
|
14
|
+
|
15
|
+
#### With Bundler
|
16
|
+
|
13
17
|
Add this line to your application's Gemfile:
|
14
18
|
|
15
19
|
```ruby
|
@@ -20,23 +24,75 @@ And then execute:
|
|
20
24
|
|
21
25
|
$ bundle
|
22
26
|
|
27
|
+
#### With Rubygems
|
28
|
+
|
23
29
|
Or install it yourself as:
|
24
30
|
|
25
31
|
$ gem install rtasklib
|
26
32
|
|
33
|
+
With this method you will need to install TaskWarrior (version 2.4 or above) yourself.
|
34
|
+
|
35
|
+
**On OSX:**
|
36
|
+
|
37
|
+
$ brew install task
|
38
|
+
|
39
|
+
**On Fedora:**
|
40
|
+
|
41
|
+
$ yum install task
|
42
|
+
|
43
|
+
**On Debian/Ubuntu:**
|
44
|
+
|
45
|
+
The major repos TaskWarrior packages are extremely outdated, so you will have to install from source. The following is what we're using to build on Travis CI, your mileage may vary:
|
46
|
+
|
47
|
+
$ sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y
|
48
|
+
$ sudo apt-get update -qq
|
49
|
+
$ sudo apt-get install -qq build-essential cmake uuid-dev g++-4.8
|
50
|
+
$ sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 50
|
51
|
+
$ git clone https://git.tasktools.org/scm/tm/task.git
|
52
|
+
$ cd task
|
53
|
+
$ git checkout $TASK_VERSION
|
54
|
+
$ git clean -dfx
|
55
|
+
$ cmake .
|
56
|
+
$ make
|
57
|
+
$ sudo make install
|
58
|
+
|
59
|
+
### Using the RPM
|
60
|
+
|
61
|
+
If you are running Fedora there is an RPM available, this comes with the advantage of being managed by `yum` and installing TaskWarrior for you. Simply get the desired version RPM from the `pkg/` dir:
|
62
|
+
|
63
|
+
$ sudo yum install rubygem-rtasklib-VERSION.rpm
|
64
|
+
|
65
|
+
### Configure TaskWarrior
|
66
|
+
|
67
|
+
Once you install TaskWarrior a database still needs to be created, luckily this is as simple as running `task` and answer `yes` when it asks you about creating a `.taskrc` file.
|
68
|
+
|
69
|
+
There is a small testing database in `spec/data/.task` if you would like to test on something other than you main TaskWarrior db. You can experiment with this by running:
|
70
|
+
|
71
|
+
```
|
72
|
+
$ ./bin/console
|
73
|
+
```
|
74
|
+
|
75
|
+
Which returns an interactive Pry Ruby session with the variable `tw` already initialized to a `Rtasklib::TW` instance with the test database. Changes to the database aren't tracked so don't worry about merge conflicts if you plan on contributing.
|
76
|
+
|
27
77
|
|
28
78
|
## Dependencies
|
29
79
|
|
30
|
-
*
|
80
|
+
* Ruby > 2.0 (Uses keyword args)
|
81
|
+
|
82
|
+
* TaskWarrior > 2.4, require custom UDAs, recurrences, and duration data types (MIT license)
|
83
|
+
|
84
|
+
* ISO8601 gem, for dealing with duration and datetimes from TaskWarrior (MIT license)
|
85
|
+
|
86
|
+
* Virtus gem, for simple Ruby object based domain modeling (TaskModel and TaskrcModel) (MIT license)
|
31
87
|
|
32
|
-
*
|
88
|
+
* multi_json gem, for parsing JSON objects (MIT license)
|
33
89
|
|
34
|
-
* See `./rtasklib.gemspec`
|
90
|
+
* See `./rtasklib.gemspec` to verify the latest Ruby dependencies
|
35
91
|
|
36
92
|
|
37
93
|
## Usage
|
38
94
|
|
39
|
-
```
|
95
|
+
```ruby
|
40
96
|
require 'rtasklib'
|
41
97
|
|
42
98
|
tw = Rtasklib::TW.new('../path/to/.task')
|
@@ -44,7 +100,23 @@ tw = Rtasklib::TW.new('../path/to/.task')
|
|
44
100
|
# do some stuff with the task database
|
45
101
|
# available commands are documented in the Controller class
|
46
102
|
|
47
|
-
tw.all
|
103
|
+
tasks = tw.all
|
104
|
+
#=> returns an array of TaskModels
|
105
|
+
|
106
|
+
tasks.first.description
|
107
|
+
#=> "An example task"
|
108
|
+
|
109
|
+
tasks[-1].due
|
110
|
+
#=> #<DateTime: 2015-03-16T17:48:23+00:00 ((2457098j,64103s,0n),+0s,2299161j)>
|
111
|
+
|
112
|
+
tw.some(ids: [1..5, 10]).size
|
113
|
+
#=> 6
|
114
|
+
|
115
|
+
tw.done!(ids: 5)
|
116
|
+
#=> 0
|
117
|
+
|
118
|
+
tw.some(ids: [1..5, 10]).size
|
119
|
+
#=> 5
|
48
120
|
```
|
49
121
|
|
50
122
|
[Controller docs](http://will-paul.com/rtasklib/Rtasklib/Controller.html)
|
data/bin/env
CHANGED
data/lib/rtasklib.rb
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
# Copyright (c) 2015 Will Paul (whp3652@rit.edu)
|
2
|
+
# All rights reserved.
|
3
|
+
#
|
4
|
+
# This file is distributed under the MIT license. See LICENSE.txt for details.
|
5
|
+
|
1
6
|
require_relative "rtasklib/version"
|
2
7
|
require_relative "rtasklib/models"
|
3
8
|
require_relative "rtasklib/execute"
|
@@ -7,24 +12,89 @@ require_relative "rtasklib/taskrc"
|
|
7
12
|
|
8
13
|
require "pathname"
|
9
14
|
|
15
|
+
# Top level namespace for all `rtasklib` functionality
|
10
16
|
module Rtasklib
|
11
17
|
|
18
|
+
# To interact with the TaskWarrior database simply instantiate this with a
|
19
|
+
# path to the .task folder where data is stored. If left out it will look
|
20
|
+
# for a database in the default location `~/.task`
|
21
|
+
#
|
22
|
+
# Optionally pass in a hash of taskrc options to override what is in your
|
23
|
+
# .taskrc on every command. By default `rtasklib` provides a set of sensible
|
24
|
+
# defaults:
|
25
|
+
#
|
26
|
+
# @example
|
27
|
+
# # Use the default path and overrides
|
28
|
+
# tw = Rtasklib::TaskWarrior.new
|
29
|
+
# # TaskWarrior is also available aliased as TW:
|
30
|
+
# tw = Rtasklib::TW.new
|
31
|
+
# # Custom path, in this case the test db in spec/
|
32
|
+
# tw = Rtasklib::TW.new("./spec/data/.task")
|
33
|
+
# # Custom override, in this case calling the gc everytime
|
34
|
+
# # This will change id numbers whenever the task list changes
|
35
|
+
# # By default this is off, but may have some performance implications.
|
36
|
+
# tw = Rtasklib::TW.new(opts={gc: "on"})
|
37
|
+
#
|
38
|
+
# @example
|
39
|
+
# DEFAULTS = {
|
40
|
+
# json_array: 'true',
|
41
|
+
# verbose: 'nothing',
|
42
|
+
# gc: 'off',
|
43
|
+
# confirmation: 'no',
|
44
|
+
# dependency_confirmation: 'no',
|
45
|
+
# exit_on_missing_db: 'yes', }
|
46
|
+
#
|
47
|
+
# These of course can be overridden with opts param as well
|
48
|
+
#
|
49
|
+
# In general `rtasklib` is only feature complete on TaskWarrior installs 2.4
|
50
|
+
# and greater and it will warn you if yours is lower or can't be determined,
|
51
|
+
# but will still allow you to interact with it. Proceed at your own risk.
|
52
|
+
#
|
53
|
+
# @!attribute [r] version
|
54
|
+
# @return [Gem::Version] The version of the current TaskWarrior install
|
55
|
+
# @!attribute [r] data_location
|
56
|
+
# @return [String] The file path that you passed in at initialization
|
57
|
+
# @!attribute [r] taskrc
|
58
|
+
# @return [Rtasklib::Taskrc] Your current TaskWarrior configuration
|
59
|
+
# @!attribute [r] udas
|
60
|
+
# @return [Hash{Symbol=>Hash}] Currently configured User Defined Attributes
|
61
|
+
# @!attribute [r] override
|
62
|
+
# @return [Rtasklib::Taskrc] The options to override the default .taskrc
|
63
|
+
# @!attribute [r] override_a
|
64
|
+
# @return [Array] override in array form, useful for passing to shell
|
65
|
+
# @!attribute [r] override_str
|
66
|
+
# @return [String] override in string form, useful for passing to shell
|
12
67
|
class TaskWarrior
|
13
68
|
attr_reader :version, :data_location, :taskrc, :udas,
|
14
69
|
:override, :override_a, :override_str
|
15
70
|
|
16
71
|
include Controller
|
17
72
|
|
73
|
+
# Sane defaults to override a base .taskrc
|
18
74
|
DEFAULTS = {
|
75
|
+
# Wrap export objects in an array? Disabling this will break Rtasklib
|
76
|
+
# functionality
|
19
77
|
json_array: 'true',
|
78
|
+
# Stop writing user friendly methods. Disabling this will break Rtasklib
|
79
|
+
# functionality
|
20
80
|
verbose: 'nothing',
|
81
|
+
# Call the gc on every execution. This will change id numbers whenever the
|
82
|
+
# task list changes. By default this is off, but may have some
|
83
|
+
# performance implications.
|
21
84
|
gc: 'off',
|
85
|
+
# Will ask for confirmation before we do anything TaskWarrior decides is
|
86
|
+
# dangerous. We handle most of these cases in Rtasklib.
|
22
87
|
confirmation: 'no',
|
23
88
|
dependency_confirmation: 'no',
|
89
|
+
# If it can't find a TaskWarrior db just exit.
|
24
90
|
exit_on_missing_db: 'yes', }
|
25
91
|
|
92
|
+
# Lowest supported TaskWarrior version
|
26
93
|
LOWEST_VERSION = Gem::Version.new('2.4.0')
|
27
94
|
|
95
|
+
# @param data [String, Pathname] path to the .task database
|
96
|
+
# @param opts [Hash] overrides to the .taskrc to run on each command
|
97
|
+
# @api public
|
28
98
|
def initialize data="#{Dir.home}/.task", opts = {}
|
29
99
|
# Check TaskWarrior version, and throw warning if unavailable
|
30
100
|
begin
|
@@ -42,6 +112,13 @@ module Rtasklib
|
|
42
112
|
add_udas_to_model!(udas) unless udas.nil?
|
43
113
|
end
|
44
114
|
|
115
|
+
# Check the state of the TaskWarrior install. Either pass a Gem::Version
|
116
|
+
# representation passed to the version param or call with no args for
|
117
|
+
# it to make a call to the shell to figure that out itself.
|
118
|
+
#
|
119
|
+
# @param version [Gem::Version, nil] version to check
|
120
|
+
# @return [Gem::Version]
|
121
|
+
# @api public
|
45
122
|
def check_version version=nil
|
46
123
|
version = get_version if version.nil?
|
47
124
|
if version < LOWEST_VERSION
|
@@ -51,6 +128,6 @@ module Rtasklib
|
|
51
128
|
end
|
52
129
|
end
|
53
130
|
|
54
|
-
# Add a convenience alias
|
131
|
+
# Add a convenience alias to Rtasklib::TaskWarrior => Rtasklib:TW
|
55
132
|
TW = TaskWarrior
|
56
133
|
end
|
data/lib/rtasklib/controller.rb
CHANGED
@@ -1,21 +1,35 @@
|
|
1
|
+
# Copyright (c) 2015 Will Paul (whp3652@rit.edu)
|
2
|
+
# All rights reserved.
|
3
|
+
#
|
4
|
+
# This file is distributed under the MIT license. See LICENSE.txt for details.
|
5
|
+
|
1
6
|
require "multi_json"
|
2
|
-
require "active_support/core_ext/object/blank"
|
3
7
|
|
4
8
|
module Rtasklib
|
5
9
|
|
6
10
|
# Accessed through the main TW, which includes this module, e.g. `tw.all`
|
7
11
|
#
|
8
|
-
#
|
9
|
-
# We're getting there.
|
12
|
+
# This module contains the public, user-facing methods.
|
10
13
|
#
|
11
14
|
# By convention bang methods modify the task database, and non-bang read
|
12
15
|
# from the database, e.g. `Controller#all` vs `Controller#modify!`
|
13
16
|
#
|
14
|
-
#
|
17
|
+
# Changes to the config are not effected by #undo!
|
18
|
+
#
|
19
|
+
# XXX: depends on TaskWarrior#override_a currently, which isn't great.
|
15
20
|
module Controller
|
16
21
|
extend self
|
17
22
|
|
18
|
-
# Retrieves the current task list from the
|
23
|
+
# Retrieves the current task list from the TaskWarrior database. Defaults
|
24
|
+
# to just show active (waiting & pending) tasks, which is usually what is
|
25
|
+
# exposed to the end user through the default reports. To see everything
|
26
|
+
# including completed, deleted, and parent recurring tasks, set
|
27
|
+
# `active: false`. For more granular control see Controller#some.
|
28
|
+
#
|
29
|
+
# @example
|
30
|
+
# tw.all.count #=> 200
|
31
|
+
# tw.all(active: true) #=> 200
|
32
|
+
# tw.all(active: false) #=> 578
|
19
33
|
#
|
20
34
|
# @param active [Boolean] return only pending & waiting tasks
|
21
35
|
# @return [Array<Models::TaskModel>]
|
@@ -37,16 +51,28 @@ module Rtasklib
|
|
37
51
|
# tw.some(ids: [1..2, 5])
|
38
52
|
# @example filter by tags
|
39
53
|
# tw.some(tags: ["+school", "or", "-work"]
|
54
|
+
# # You can also pass in a TW style string if you prefer
|
55
|
+
# tw.some(tags: "+school or -work"]
|
56
|
+
# @example filter by a dom query
|
57
|
+
# require "date"
|
58
|
+
# today = DateTime.now
|
59
|
+
# # note that queries with dots need to be Strings, as they would be
|
60
|
+
# # invalid Symbols
|
61
|
+
# tw.some(dom: {project: "Work", "due.before" => today})
|
62
|
+
# # You can also pass in a TW style string if you prefer
|
63
|
+
# tw.some(dom: "project:Work due.before:#{today}")
|
40
64
|
#
|
41
65
|
# @param ids [Array<Range, Fixnum, String>, String, Range, Fixnum]
|
42
66
|
# @param tags [Array<String>, String]
|
43
67
|
# @param dom [Array<String>, String]
|
68
|
+
# @param active [Boolean] return only pending & waiting tasks
|
44
69
|
# @return [Array<Models::TaskModel>]
|
45
70
|
# @api public
|
46
|
-
def some ids: nil, tags: nil, dom: nil
|
71
|
+
def some ids: nil, tags: nil, dom: nil, active: true
|
47
72
|
some = []
|
48
73
|
f = Helpers.filter(ids: ids, tags: tags, dom: dom)
|
49
|
-
|
74
|
+
a = Helpers.pending_or_waiting(active)
|
75
|
+
Execute.task_popen3(*@override_a, f, a, "export") do |i, o, e, t|
|
50
76
|
some = MultiJson.load(o.read).map do |x|
|
51
77
|
Rtasklib::Models::TaskModel.new(x)
|
52
78
|
end
|
@@ -54,15 +80,18 @@ module Rtasklib
|
|
54
80
|
return some
|
55
81
|
end
|
56
82
|
|
57
|
-
#
|
83
|
+
# Count the number of tasks that match a given filter. Faster than counting
|
84
|
+
# an array returned by Controller#all or Controller#some.
|
58
85
|
#
|
59
86
|
# @param ids [Array<Range, Fixnum, String>, String, Range, Fixnum]
|
60
87
|
# @param tags [Array<String>, String]
|
61
88
|
# @param dom [Array<String>, String]
|
89
|
+
# @param active [Boolean] return only pending & waiting tasks
|
62
90
|
# @api public
|
63
|
-
def count ids: nil, tags: nil, dom: nil
|
91
|
+
def count ids: nil, tags: nil, dom: nil, active: true
|
64
92
|
f = Helpers.filter(ids: ids, tags: tags, dom: dom)
|
65
|
-
|
93
|
+
a = Helpers.pending_or_waiting(active)
|
94
|
+
Execute.task_popen3(*@override_a, f, a, "count") do |i, o, e, t|
|
66
95
|
return Integer(o.read)
|
67
96
|
end
|
68
97
|
end
|
@@ -72,7 +101,7 @@ module Rtasklib
|
|
72
101
|
# Calls `task _show` with initial overrides returns a Taskrc object of the
|
73
102
|
# result
|
74
103
|
#
|
75
|
-
# @return [Taskrc]
|
104
|
+
# @return [Rtasklib::Taskrc]
|
76
105
|
# @api public
|
77
106
|
def get_rc
|
78
107
|
res = []
|
@@ -97,12 +126,19 @@ module Rtasklib
|
|
97
126
|
# Mark the filter of tasks as started
|
98
127
|
# Returns false if filter (ids:, tags:, dom:) is blank.
|
99
128
|
#
|
129
|
+
# @param ids [Array<Range, Fixnum, String>, String, Range, Fixnum]
|
130
|
+
# @param tags [Array<String>, String]
|
131
|
+
# @param dom [Array<String>, String]
|
132
|
+
# @param active [Boolean] return only pending & waiting tasks
|
133
|
+
# @return [Process::Status, False] the exit status of the thread or false
|
134
|
+
# if it exited early because filter was blank.
|
100
135
|
# @api public
|
101
|
-
def start! ids: nil, tags: nil, dom: nil
|
136
|
+
def start! ids: nil, tags: nil, dom: nil, active: true
|
102
137
|
f = Helpers.filter(ids: ids, tags: tags, dom: dom)
|
138
|
+
a = Helpers.pending_or_waiting(active)
|
103
139
|
return false if f.blank?
|
104
140
|
|
105
|
-
Execute.task_popen3(*@override_a, f, "start") do |i, o, e, t|
|
141
|
+
Execute.task_popen3(*@override_a, f, a, "start") do |i, o, e, t|
|
106
142
|
return t.value
|
107
143
|
end
|
108
144
|
end
|
@@ -110,12 +146,19 @@ module Rtasklib
|
|
110
146
|
# Mark the filter of tasks as stopped
|
111
147
|
# Returns false if filter (ids:, tags:, dom:) is blank.
|
112
148
|
#
|
149
|
+
# @param ids [Array<Range, Fixnum, String>, String, Range, Fixnum]
|
150
|
+
# @param tags [Array<String>, String]
|
151
|
+
# @param dom [Array<String>, String]
|
152
|
+
# @param active [Boolean] return only pending & waiting tasks
|
153
|
+
# @return [Process::Status, False] the exit status of the thread or false
|
154
|
+
# if it exited early because filter was blank.
|
113
155
|
# @api public
|
114
|
-
def stop! ids: nil, tags: nil, dom: nil
|
156
|
+
def stop! ids: nil, tags: nil, dom: nil, active: true
|
115
157
|
f = Helpers.filter(ids: ids, tags: tags, dom: dom)
|
158
|
+
a = Helpers.pending_or_waiting(active)
|
116
159
|
return false if f.blank?
|
117
160
|
|
118
|
-
Execute.task_popen3(*@override_a, f, "stop") do |i, o, e, t|
|
161
|
+
Execute.task_popen3(*@override_a, f, a, "stop") do |i, o, e, t|
|
119
162
|
return t.value
|
120
163
|
end
|
121
164
|
end
|
@@ -126,6 +169,7 @@ module Rtasklib
|
|
126
169
|
# @param description [String] the required desc of the task
|
127
170
|
# @param tags [Array<String>, String]
|
128
171
|
# @param dom [Array<String>, String]
|
172
|
+
# @return [Process::Status] the exit status of the thread
|
129
173
|
# @api public
|
130
174
|
def add! description, tags: nil, dom: nil
|
131
175
|
f = Helpers.filter(tags: tags, dom: dom)
|
@@ -144,29 +188,35 @@ module Rtasklib
|
|
144
188
|
# @param ids [Array<Range, Fixnum, String>, String, Range, Fixnum]
|
145
189
|
# @param tags [Array<String>, String]
|
146
190
|
# @param dom [Array<String>, String]
|
191
|
+
# @param active [Boolean] return only pending & waiting tasks
|
192
|
+
# @return [Process::Status] the exit status of the thread
|
147
193
|
# @api public
|
148
|
-
def modify! attr, val, ids: nil, tags: nil, dom: nil
|
194
|
+
def modify! attr, val, ids: nil, tags: nil, dom: nil, active: true
|
149
195
|
f = Helpers.filter(ids: ids, tags: tags, dom: dom)
|
196
|
+
a = Helpers.pending_or_waiting(active)
|
150
197
|
return false if f.blank?
|
151
198
|
|
152
|
-
query = "#{f} modify #{attr}
|
199
|
+
query = "#{f} #{a} modify #{attr}:#{val}"
|
153
200
|
Execute.task_popen3(*override_a, query) do |i, o, e, t|
|
154
201
|
return t.value
|
155
202
|
end
|
156
203
|
end
|
157
204
|
|
158
|
-
# Finishes the filtered tasks
|
205
|
+
# Finishes the filtered tasks.
|
159
206
|
# Returns false if filter (ids:, tags:, dom:) is blank.
|
160
207
|
#
|
161
208
|
# @param ids [Array<Range, Fixnum, String>, String, Range, Fixnum]
|
162
209
|
# @param tags [Array<String>, String]
|
163
210
|
# @param dom [Array<String>, String]
|
211
|
+
# @param active [Boolean] return only pending & waiting tasks
|
212
|
+
# @return [Process::Status] the exit status of the thread
|
164
213
|
# @api public
|
165
|
-
def done! ids: nil, tags: nil, dom: nil
|
214
|
+
def done! ids: nil, tags: nil, dom: nil, active: true
|
166
215
|
f = Helpers.filter(ids: ids, tags: tags, dom: dom)
|
216
|
+
a = Helpers.pending_or_waiting(active)
|
167
217
|
return false if f.blank?
|
168
218
|
|
169
|
-
Execute.task_popen3(*override_a, f, "done") do |i, o, e, t|
|
219
|
+
Execute.task_popen3(*override_a, f, a, "done") do |i, o, e, t|
|
170
220
|
return t.value
|
171
221
|
end
|
172
222
|
end
|
@@ -176,12 +226,15 @@ module Rtasklib
|
|
176
226
|
# @param ids [Array<Range, Fixnum, String>, String, Range, Fixnum]
|
177
227
|
# @param tags [Array<String>, String]
|
178
228
|
# @param dom [Array<String>, String]
|
229
|
+
# @param active [Boolean] return only pending & waiting tasks
|
230
|
+
# @return [Process::Status] the exit status of the thread
|
179
231
|
# @api public
|
180
|
-
def delete! ids: nil, tags: nil, dom: nil
|
232
|
+
def delete! ids: nil, tags: nil, dom: nil, active: true
|
181
233
|
f = Helpers.filter(ids: ids, tags: tags, dom: dom)
|
234
|
+
a = Helpers.pending_or_waiting(active)
|
182
235
|
return false if f.blank?
|
183
236
|
|
184
|
-
Execute.task_popen3(*override_a, f, "delete") do |i, o, e, t|
|
237
|
+
Execute.task_popen3(*override_a, f, a, "delete") do |i, o, e, t|
|
185
238
|
return t.value
|
186
239
|
end
|
187
240
|
end
|
@@ -219,6 +272,7 @@ module Rtasklib
|
|
219
272
|
#
|
220
273
|
# @param attr [String]
|
221
274
|
# @param val [String]
|
275
|
+
# @return [Process::Status] the exit status of the thread
|
222
276
|
# @api public
|
223
277
|
def update_config! attr, val
|
224
278
|
Execute.task_popen3(*override_a, "config #{attr} #{val}") do |i, o, e, t|
|
@@ -286,6 +340,20 @@ module Rtasklib
|
|
286
340
|
update_config("uda.#{name}.urgency", urgency) unless urgency.nil?
|
287
341
|
end
|
288
342
|
|
343
|
+
# Sync the local TaskWarrior database changes to the remote databases.
|
344
|
+
# Remotes need to be configured in the .taskrc.
|
345
|
+
#
|
346
|
+
# @example
|
347
|
+
# # make some local changes with add!, modify!, or the like
|
348
|
+
# tw.sync!
|
349
|
+
#
|
350
|
+
# @return [Process::Status] the exit status of the thread
|
351
|
+
# @api public
|
352
|
+
def sync!
|
353
|
+
Execute.task_popen3(*override_a, "sync") do |i, o, e, t|
|
354
|
+
return t.value
|
355
|
+
end
|
356
|
+
end
|
289
357
|
|
290
358
|
# TODO: implement and test convenience methods for modifying tasks
|
291
359
|
#
|
data/lib/rtasklib/execute.rb
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
# Copyright (c) 2015 Will Paul (whp3652@rit.edu)
|
2
|
+
# All rights reserved.
|
3
|
+
#
|
4
|
+
# This file is distributed under the MIT license. See LICENSE.txt for details.
|
5
|
+
|
1
6
|
require "open3"
|
2
7
|
|
3
8
|
module Rtasklib
|
@@ -7,17 +12,9 @@ module Rtasklib
|
|
7
12
|
# so that the methods are available within the modules lookup path
|
8
13
|
extend self
|
9
14
|
|
15
|
+
# When true writes all shell commands to STDERR
|
10
16
|
DEBUG = false
|
11
17
|
|
12
|
-
# Turned off confirmations, so this regex is deprecated
|
13
|
-
# This also means we have to handle that all ourselves
|
14
|
-
# For example warn user with bang methods.
|
15
|
-
#
|
16
|
-
# @@exp_regex = {
|
17
|
-
# create_rc: %r{Would \s you \s like \s a \s sample \s *.+ \s created, \s
|
18
|
-
# so \s taskwarrior \s can \s proceed\? \s
|
19
|
-
# \(yes/no\)}x }
|
20
|
-
|
21
18
|
# Use Open3#popen3 to execute a unix program with an array of options
|
22
19
|
# and an optional block to handle the response.
|
23
20
|
#
|
data/lib/rtasklib/helpers.rb
CHANGED
@@ -1,5 +1,27 @@
|
|
1
|
+
# Copyright (c) 2015 Will Paul (whp3652@rit.edu)
|
2
|
+
# All rights reserved.
|
3
|
+
#
|
4
|
+
# This file is distributed under the MIT license. See LICENSE.txt for details.
|
5
|
+
|
1
6
|
require "multi_json"
|
2
7
|
|
8
|
+
# Monkey patching String, instead of importing ActiveSupport, bc its overkill
|
9
|
+
# for what we were using it for
|
10
|
+
class String
|
11
|
+
# Returns true for blank Strings
|
12
|
+
#
|
13
|
+
# @example
|
14
|
+
# "".blank? #=> true
|
15
|
+
# " ".blank? #=> true
|
16
|
+
# ".".blank? #=> false
|
17
|
+
#
|
18
|
+
# @return [Boolean]
|
19
|
+
# @api public
|
20
|
+
def blank?
|
21
|
+
self.strip.empty?
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
3
25
|
module Rtasklib
|
4
26
|
|
5
27
|
# A collection of stateless, non-end-user facing functions available
|
@@ -89,8 +111,10 @@ module Rtasklib
|
|
89
111
|
end
|
90
112
|
end
|
91
113
|
|
92
|
-
# Ensures that a tag begins with a + or -
|
114
|
+
# Ensures that a tag begins with a + or - or is one of the operational
|
115
|
+
# operators `and or xor < <= = != >= > ( )`
|
93
116
|
#
|
117
|
+
# @param tag [String]
|
94
118
|
# @return [String]
|
95
119
|
# @api public
|
96
120
|
def process_tag tag
|
@@ -185,7 +209,6 @@ module Rtasklib
|
|
185
209
|
# Doesn't detect arrays, b/c task stores these as comma separated strings
|
186
210
|
# which could just as easily be Strings....
|
187
211
|
# If nothing works it defaults to String.
|
188
|
-
# TODO: JSON parse
|
189
212
|
#
|
190
213
|
# @param value [Object] anything that needs to be coerced, probably string
|
191
214
|
# @return [Axiom::Types::Boolean, Integer, Float, String]
|
data/lib/rtasklib/models.rb
CHANGED
@@ -1,7 +1,14 @@
|
|
1
|
+
# Copyright (c) 2015 Will Paul (whp3652@rit.edu)
|
2
|
+
# All rights reserved.
|
3
|
+
#
|
4
|
+
# This file is distributed under the MIT license. See LICENSE.txt for details.
|
5
|
+
|
1
6
|
require "virtus"
|
2
7
|
require 'iso8601'
|
3
8
|
require 'date'
|
4
9
|
|
10
|
+
# Module that holds all domain model related functionality.
|
11
|
+
# Primarily Taskrc and TaskModel representations.
|
5
12
|
module Rtasklib::Models
|
6
13
|
|
7
14
|
# A subclass of the ISO8601::Duration object that use `task calc` to parse
|
@@ -19,13 +26,20 @@ module Rtasklib::Models
|
|
19
26
|
end
|
20
27
|
end
|
21
28
|
|
22
|
-
# Custom coercer
|
29
|
+
# Custom coercer that changes a string input into an TWDuration object
|
30
|
+
# If nil? or blank? it returns nil
|
31
|
+
#
|
32
|
+
# Modifies the #coerce method.
|
23
33
|
class VirtusDuration < Virtus::Attribute
|
34
|
+
# @param [Object] any value that we are trying to coerce, probably String
|
35
|
+
# @return [TWDuration, nil]
|
24
36
|
def coerce(v)
|
25
37
|
if v.nil? || v.blank? then nil else TWDuration.new(v) end
|
26
38
|
end
|
27
39
|
end
|
28
40
|
|
41
|
+
# Allows us to treat the strings "on", "off", "no", "yes" as Booleans,
|
42
|
+
# Which is how TaskWarrior does it.
|
29
43
|
RcBooleans = Virtus.model do |mod|
|
30
44
|
mod.coerce = true
|
31
45
|
mod.coercer.config.string.boolean_map = {
|
@@ -33,18 +47,23 @@ module Rtasklib::Models
|
|
33
47
|
'no' => false, 'off' => false }
|
34
48
|
end
|
35
49
|
|
50
|
+
# A base Virtus model whose attributes are created dynamically based on the
|
51
|
+
# given attributes are read from a .taskrc or Hash
|
52
|
+
#
|
53
|
+
# attr_accessors are available for all attributes, and more can be added
|
54
|
+
# See Rtasklib::Controller for methods to do this
|
36
55
|
class TaskrcModel
|
37
|
-
#
|
38
|
-
# given attributes are read from a .taskrc or Hash
|
39
|
-
#
|
40
|
-
# Dynamically add convert Boolean Strings to Ruby's Boolean values
|
56
|
+
# Dynamically add attrs that use Boolean Strings to Ruby's Boolean values
|
41
57
|
include RcBooleans
|
42
58
|
end
|
43
59
|
|
60
|
+
# Defines a Virtus model for a single task, defining the data types for all
|
61
|
+
# the default attributes
|
62
|
+
#
|
44
63
|
class TaskModel
|
45
64
|
include Virtus.model
|
46
|
-
# perhaps use Veto
|
47
|
-
#
|
65
|
+
# TODO: perhaps use Veto to validate these, if we ever implement mutable
|
66
|
+
# changes, e.g. task_model.save!
|
48
67
|
|
49
68
|
# Default attributes from TW
|
50
69
|
# Should match: http://taskwarrior.org/docs/design/task.html
|
data/lib/rtasklib/taskrc.rb
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
# Copyright (c) 2015 Will Paul (whp3652@rit.edu)
|
2
|
+
# All rights reserved.
|
3
|
+
#
|
4
|
+
# This file is distributed under the MIT license. See LICENSE.txt for details.
|
5
|
+
|
1
6
|
require "virtus"
|
2
7
|
require "enumerator"
|
3
8
|
|
@@ -5,8 +10,13 @@ module Rtasklib
|
|
5
10
|
|
6
11
|
# A class that wraps a single Virtus domain model with a number of creation
|
7
12
|
# and manipulation methods
|
13
|
+
#
|
14
|
+
# Intialize with either a hash of attribute value pairs or a Pathname
|
15
|
+
# to the raw taskrc file to read.
|
16
|
+
#
|
17
|
+
# @!attribute [rw] config
|
18
|
+
# @return [Models::TaskrcModel] a custom Virtus domain model
|
8
19
|
class Taskrc
|
9
|
-
# @attr config [Models::TaskrcModel] a custom Virtus domain model
|
10
20
|
attr_accessor :config
|
11
21
|
|
12
22
|
# Generate a dynamic Virtus model, with the attributes defined by the input
|
@@ -154,6 +164,8 @@ module Rtasklib
|
|
154
164
|
config.send("#{attr.to_s}".to_sym)
|
155
165
|
end
|
156
166
|
|
167
|
+
# Convert dot notation to Symbol safe underscores
|
168
|
+
#
|
157
169
|
# @param attr [String] the name for the attr, e.g. "json_array"
|
158
170
|
# @return [String]
|
159
171
|
# @api private
|
@@ -162,6 +174,8 @@ module Rtasklib
|
|
162
174
|
end
|
163
175
|
private :get_hash_attr_from_rc
|
164
176
|
|
177
|
+
# Convert Symbol safe underscores to dot notation
|
178
|
+
#
|
165
179
|
# @param attr [String] the name for the attr, e.g. "json_array"
|
166
180
|
# @return [String]
|
167
181
|
# @api private
|
data/lib/rtasklib/version.rb
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
# Copyright (c) 2015 Will Paul (whp3652@rit.edu)
|
2
|
+
# All rights reserved.
|
3
|
+
#
|
4
|
+
# This file is distributed under the MIT license. See LICENSE.txt for details.
|
5
|
+
|
1
6
|
module Rtasklib
|
2
|
-
|
7
|
+
# The latest version of rtasklib
|
8
|
+
VERSION = "0.2.3-beta"
|
3
9
|
end
|
data/rtasklib.gemspec
CHANGED
@@ -21,7 +21,6 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.required_ruby_version = '>= 2.0'
|
22
22
|
spec.requirements << 'taskwarrior, >=2.4.0'
|
23
23
|
|
24
|
-
spec.add_dependency "activesupport", "~> 4"
|
25
24
|
spec.add_dependency "multi_json", "~> 1.7"
|
26
25
|
spec.add_dependency "virtus", "~> 1.0"
|
27
26
|
spec.add_dependency "iso8601", "~> 0.8"
|
data/spec/controller_spec.rb
CHANGED
data/spec/execute_spec.rb
CHANGED
data/spec/helpers_spec.rb
CHANGED
data/spec/models_spec.rb
CHANGED
data/spec/rtasklib_spec.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -1,5 +1,10 @@
|
|
1
|
+
# Copyright (c) 2015 Will Paul (whp3652@rit.edu)
|
2
|
+
# All rights reserved.
|
3
|
+
#
|
4
|
+
# This file is distributed under the MIT license. See LICENSE.txt for details.
|
5
|
+
|
1
6
|
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
2
7
|
require 'coveralls'
|
8
|
+
|
3
9
|
Coveralls.wear!
|
4
10
|
require 'rtasklib'
|
5
|
-
|
data/spec/taskrc_spec.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rtasklib
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.3.pre.
|
4
|
+
version: 0.2.3.pre.beta
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Will Paul
|
@@ -10,20 +10,6 @@ bindir: exe
|
|
10
10
|
cert_chain: []
|
11
11
|
date: 2015-05-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: activesupport
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '4'
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - "~>"
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '4'
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: multi_json
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -208,8 +194,6 @@ files:
|
|
208
194
|
- lib/rtasklib/taskrc.rb
|
209
195
|
- lib/rtasklib/version.rb
|
210
196
|
- rtasklib.gemspec
|
211
|
-
- rubygem-rtasklib.spec
|
212
|
-
- rubygem-rtasklib.spec.template
|
213
197
|
- spec/controller_spec.rb
|
214
198
|
- spec/data/.task/backlog.data
|
215
199
|
- spec/data/.task/completed.data
|
data/rubygem-rtasklib.spec
DELETED
@@ -1,71 +0,0 @@
|
|
1
|
-
# Generated from rtasklib-0.2.1.gem by gem2rpm -*- rpm-spec -*-
|
2
|
-
%define rbname rtasklib
|
3
|
-
%define version 0.2.1
|
4
|
-
%define release 1
|
5
|
-
|
6
|
-
Summary: A Ruby wrapper around the TaskWarrior CLI
|
7
|
-
Name: ruby-gems-%{rbname}
|
8
|
-
|
9
|
-
Version: %{version}
|
10
|
-
Release: %{release}
|
11
|
-
Group: Development/Ruby
|
12
|
-
License: MIT
|
13
|
-
URL: http://github.com/dropofwill/rtasklib
|
14
|
-
Source0: %{rbname}-%{version}.gem
|
15
|
-
# Make sure the spec template is included in the SRPM
|
16
|
-
Source1: ruby-gems-%{rbname}.spec.in
|
17
|
-
BuildRoot: %{_tmppath}/%{name}-%{version}-root
|
18
|
-
Requires: ruby >= 2
|
19
|
-
Requires: ruby-gems >= 2
|
20
|
-
Requires: ruby-gems-virtus
|
21
|
-
Requires: ruby-gems-activesupport
|
22
|
-
Requires: ruby-gems-activemodel
|
23
|
-
Requires: ruby-gems-active_model_serializers
|
24
|
-
Requires: ruby-gems-oj
|
25
|
-
Requires: ruby-gems-multi_json
|
26
|
-
Requires: ruby-gems-iso8601
|
27
|
-
Requires: ruby-gems-bundler => 1.8
|
28
|
-
Requires: ruby-gems-bundler < 2
|
29
|
-
Requires: ruby-gems-rake => 10.0
|
30
|
-
Requires: ruby-gems-rake < 11
|
31
|
-
Requires: ruby-gems-coveralls
|
32
|
-
Requires: ruby-gems-rspec
|
33
|
-
Requires: ruby-gems-rspec-nc
|
34
|
-
Requires: ruby-gems-guard
|
35
|
-
Requires: ruby-gems-guard-rspec
|
36
|
-
Requires: ruby-gems-yard
|
37
|
-
BuildRequires: ruby >= 2
|
38
|
-
BuildRequires: ruby-gems >= 2
|
39
|
-
BuildArch: noarch
|
40
|
-
Provides: ruby(Rtasklib) = %{version}
|
41
|
-
|
42
|
-
%define gemdir /usr/share/gems
|
43
|
-
%define gembuilddir %{buildroot}%{gemdir}
|
44
|
-
|
45
|
-
%description
|
46
|
-
A Ruby wrapper around the TaskWarrior CLI. Requires a TaskWarrior install
|
47
|
-
version 2.4.0 of greater.
|
48
|
-
|
49
|
-
|
50
|
-
%prep
|
51
|
-
%setup -T -c
|
52
|
-
|
53
|
-
%build
|
54
|
-
|
55
|
-
%install
|
56
|
-
%{__rm} -rf %{buildroot}
|
57
|
-
mkdir -p %{gembuilddir}
|
58
|
-
gem install --local --install-dir %{gembuilddir} --force %{SOURCE0}
|
59
|
-
|
60
|
-
%clean
|
61
|
-
%{__rm} -rf %{buildroot}
|
62
|
-
|
63
|
-
%files
|
64
|
-
%defattr(-, root, root)
|
65
|
-
%{gemdir}/gems/rtasklib-0.2.1/
|
66
|
-
|
67
|
-
%doc %{gemdir}/doc/rtasklib-0.2.1
|
68
|
-
%{gemdir}/cache/rtasklib-0.2.1.gem
|
69
|
-
%{gemdir}/specifications/rtasklib-0.2.1.gemspec
|
70
|
-
|
71
|
-
%changelog
|
@@ -1,69 +0,0 @@
|
|
1
|
-
# Generated from <%= package.spec.file_name %> by gem2rpm -*- rpm-spec -*-
|
2
|
-
%define rbname <%= spec.name %>
|
3
|
-
%define version <%= spec.version %>
|
4
|
-
%define release 1
|
5
|
-
|
6
|
-
Summary: <%= spec.summary %>
|
7
|
-
Name: ruby-gems-%{rbname}
|
8
|
-
|
9
|
-
Version: %{version}
|
10
|
-
Release: %{release}
|
11
|
-
Group: Development/Ruby
|
12
|
-
License: MIT
|
13
|
-
URL: <%= spec.homepage %>
|
14
|
-
Source0: %{rbname}-%{version}.gem
|
15
|
-
# Make sure the spec template is included in the SRPM
|
16
|
-
Source1: ruby-gems-%{rbname}.spec.in
|
17
|
-
BuildRoot: %{_tmppath}/%{name}-%{version}-root
|
18
|
-
Requires: ruby <%= spec.required_ruby_version %>
|
19
|
-
Requires: ruby-gems >= <%= Gem::RubyGemsVersion %>
|
20
|
-
<% for d in spec.dependencies -%>
|
21
|
-
<% for req in d.requirement -%>
|
22
|
-
Requires: ruby-gems-<%= d.name %> <%= req %>
|
23
|
-
<% end -%>
|
24
|
-
<% end -%>
|
25
|
-
BuildRequires: ruby <%= spec.required_ruby_version %>
|
26
|
-
BuildRequires: ruby-gems >= <%= Gem::RubyGemsVersion %>
|
27
|
-
BuildArch: noarch
|
28
|
-
Provides: ruby(<%= spec.name.capitalize %>) = %{version}
|
29
|
-
|
30
|
-
%define gemdir /usr/share/gems
|
31
|
-
%define gembuilddir %{buildroot}%{gemdir}
|
32
|
-
|
33
|
-
%description
|
34
|
-
<%= spec.description %>
|
35
|
-
|
36
|
-
%prep
|
37
|
-
%setup -T -c
|
38
|
-
|
39
|
-
%build
|
40
|
-
|
41
|
-
%install
|
42
|
-
%{__rm} -rf %{buildroot}
|
43
|
-
mkdir -p %{gembuilddir}
|
44
|
-
gem install --local --install-dir %{gembuilddir} --force %{SOURCE0}
|
45
|
-
<% if ! spec.executables.empty? -%>
|
46
|
-
mkdir -p %{buildroot}/%{_bindir}
|
47
|
-
mv %{gembuilddir}/bin/* %{buildroot}/%{_bindir}
|
48
|
-
rmdir %{gembuilddir}/bin
|
49
|
-
<% end -%>
|
50
|
-
|
51
|
-
%clean
|
52
|
-
%{__rm} -rf %{buildroot}
|
53
|
-
|
54
|
-
%files
|
55
|
-
%defattr(-, root, root)
|
56
|
-
<% for f in spec.executables -%>
|
57
|
-
%{_bindir}/<%= f %>
|
58
|
-
<% end -%>
|
59
|
-
<% package.spec.files.each do |entry, data| -%>
|
60
|
-
<% path = entry['path'] -%>
|
61
|
-
<% doc_prefix = spec.extra_rdoc_files.include?(path) ? "%doc " : "" -%>
|
62
|
-
<%= doc_prefix %>%{gemdir}/gems/<%= spec.name %>-<%= spec.version %>/<%= path %>
|
63
|
-
<% end %>
|
64
|
-
|
65
|
-
%doc %{gemdir}/doc/<%= spec.name %>-<%= spec.version %>
|
66
|
-
%{gemdir}/cache/<%= package.spec.file_name %>
|
67
|
-
%{gemdir}/specifications/<%= package.spec.file_name %>spec
|
68
|
-
|
69
|
-
%changelog
|