plansheet 0.9.0 → 0.13.2
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 +4 -4
- data/.rubocop.yml +6 -2
- data/Gemfile.lock +1 -1
- data/exe/plansheet +8 -1
- data/lib/plansheet/project/stringify.rb +47 -0
- data/lib/plansheet/project/yaml.rb +162 -0
- data/lib/plansheet/project.rb +98 -174
- data/lib/plansheet/sheet.rb +1 -1
- data/lib/plansheet/version.rb +1 -1
- metadata +4 -3
- data/.rubocop_todo.yml +0 -36
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 76e5120430c540166b342a58cf0a0c07dfaf773d0a46b1dcd05614be677fe1a6
|
4
|
+
data.tar.gz: 83eb24c7811f8e1e49d8f7f79a059c1451673907460203d95a5c28e98fbc74c2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 71d3b9dad2c16601ef4472805c282cbfced288e0fc1cee42b0b2e6cb508c5aa255a688c3301fbdee38ae5188f36a2d65cbee2ebc9aa3290771a8f2a2f84854ac
|
7
|
+
data.tar.gz: bc7d994b5d320c0c9f7ed53ca625afb6f586f228a48f16e2e9f1b2f392cae4cb1e1cef45ddc305069fb06a59a8e1fa9cf2324c1dc4a322e411f801d5802c41fe
|
data/.rubocop.yml
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
inherit_from: .rubocop_todo.yml
|
2
|
-
|
3
1
|
AllCops:
|
4
2
|
TargetRubyVersion: 2.6
|
5
3
|
NewCops: enable
|
@@ -15,3 +13,9 @@ Style/StringLiteralsInInterpolation:
|
|
15
13
|
|
16
14
|
Layout/LineLength:
|
17
15
|
Max: 120
|
16
|
+
|
17
|
+
Metrics:
|
18
|
+
Enabled: false
|
19
|
+
|
20
|
+
Style/Documentation:
|
21
|
+
Enabled: false
|
data/Gemfile.lock
CHANGED
data/exe/plansheet
CHANGED
@@ -17,6 +17,10 @@ parser.on(
|
|
17
17
|
"--cli",
|
18
18
|
"CLI dump of projects (WIP)"
|
19
19
|
)
|
20
|
+
parser.on(
|
21
|
+
"--location_filter LOCATION",
|
22
|
+
"location filter for CLI dump (WIP)"
|
23
|
+
)
|
20
24
|
options = {}
|
21
25
|
parser.parse!(into: options)
|
22
26
|
|
@@ -32,7 +36,10 @@ elsif options[:sort]
|
|
32
36
|
Plansheet.resort_projects_in_dir config["projects_dir"]
|
33
37
|
elsif options[:cli]
|
34
38
|
project_arr = Plansheet.load_projects_dir config["projects_dir"]
|
35
|
-
project_arr.sort
|
39
|
+
project_arr.sort!
|
40
|
+
project_arr.delete_if { |x| x.status == "dropped" || x.status == "done" }
|
41
|
+
project_arr.select! { |x| x.location == options[:location_filter] } if options[:location_filter]
|
42
|
+
project_arr.each do |proj|
|
36
43
|
puts proj
|
37
44
|
puts "\n"
|
38
45
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Plansheet
|
4
|
+
class Project
|
5
|
+
def to_s
|
6
|
+
str = String.new
|
7
|
+
str << "# #{@name}\n"
|
8
|
+
STRING_PROPERTIES.each do |o|
|
9
|
+
str << stringify_string_property(o)
|
10
|
+
end
|
11
|
+
DATE_PROPERTIES.each do |o|
|
12
|
+
str << stringify_string_property(o)
|
13
|
+
end
|
14
|
+
ARRAY_PROPERTIES.each do |o|
|
15
|
+
str << stringify_array_property(o)
|
16
|
+
end
|
17
|
+
str
|
18
|
+
end
|
19
|
+
|
20
|
+
def stringify_string_property(prop)
|
21
|
+
if instance_variable_defined? "@#{prop}"
|
22
|
+
"#{prop}: #{instance_variable_get("@#{prop}")}\n"
|
23
|
+
else
|
24
|
+
""
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def stringify_date_property(prop)
|
29
|
+
if instance_variable_defined? "@#{prop}"
|
30
|
+
"#{prop}: #{instance_variable_get("@#{prop}")}\n"
|
31
|
+
else
|
32
|
+
""
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def stringify_array_property(prop)
|
37
|
+
str = String.new
|
38
|
+
if instance_variable_defined? "@#{prop}"
|
39
|
+
str << "#{prop}:\n"
|
40
|
+
instance_variable_get("@#{prop}").each do |t|
|
41
|
+
str << "- #{t}\n"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
str
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,162 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "yaml"
|
4
|
+
require "date"
|
5
|
+
require "pathname"
|
6
|
+
|
7
|
+
module Plansheet
|
8
|
+
# Once there's some stability in plansheet and dc-kwalify, will pre-load this
|
9
|
+
# to save the later YAML.load
|
10
|
+
PROJECT_YAML_SCHEMA = <<~YAML
|
11
|
+
desc: dc-tasks project schema
|
12
|
+
type: seq
|
13
|
+
sequence:
|
14
|
+
- type: map
|
15
|
+
mapping:
|
16
|
+
"project":
|
17
|
+
desc: Project name
|
18
|
+
type: str
|
19
|
+
required: yes
|
20
|
+
"namespace":
|
21
|
+
desc: Namespace of a group of projects (for organizing)
|
22
|
+
type: str
|
23
|
+
required: yes
|
24
|
+
"priority":
|
25
|
+
desc: Project priority
|
26
|
+
type: str
|
27
|
+
enum:
|
28
|
+
- high
|
29
|
+
- medium
|
30
|
+
- low
|
31
|
+
"status":
|
32
|
+
desc: The current status of the project
|
33
|
+
type: str
|
34
|
+
enum:
|
35
|
+
- wip # project is a work-in-progress
|
36
|
+
- ready # project has tasks, ready to go
|
37
|
+
- waiting # project in waiting on some external person/event
|
38
|
+
- blocked # project is blocked by another project, but otherwise ready/wip
|
39
|
+
- planning # project in planning phase (set manually)
|
40
|
+
- idea # project is little more than an idea
|
41
|
+
- dropped # project has been explicitly dropped, but
|
42
|
+
# want to keep around for reference, etc
|
43
|
+
- done # project is finished, but want to keep around
|
44
|
+
# for reference, etc.
|
45
|
+
"location":
|
46
|
+
desc: Location
|
47
|
+
type: str
|
48
|
+
"notes":
|
49
|
+
desc: Free-form notes string
|
50
|
+
type: str
|
51
|
+
"time_estimate":
|
52
|
+
desc: The estimated amount of time before a project is completed
|
53
|
+
type: str
|
54
|
+
"frequency":
|
55
|
+
desc: The amount of time before a recurring project moves to ready status again from when it was last done (WIP)
|
56
|
+
type: str
|
57
|
+
pattern: /\\d+[dwDW]/
|
58
|
+
"lead_time":
|
59
|
+
desc: The amount of time before a recurring project is "due" moved to ready where the project (sort of a deferral mechanism) (WIP)
|
60
|
+
type: str
|
61
|
+
pattern: /\\d+[dwDW]/
|
62
|
+
"due":
|
63
|
+
desc: Due date of the task
|
64
|
+
type: date
|
65
|
+
"defer":
|
66
|
+
desc: Defer task until this day
|
67
|
+
type: date
|
68
|
+
"completed_on":
|
69
|
+
desc: When the (non-recurring) project was completed
|
70
|
+
type: date
|
71
|
+
"created_on":
|
72
|
+
desc: When the project was created
|
73
|
+
type: date
|
74
|
+
"starts_on":
|
75
|
+
desc: For ICS (WIP)
|
76
|
+
type: date
|
77
|
+
"last_reviewed":
|
78
|
+
desc: When the project was last reviewed (WIP)
|
79
|
+
type: date
|
80
|
+
"last_done":
|
81
|
+
desc: When the recurring project was last completed (WIP)
|
82
|
+
type: date
|
83
|
+
"dependencies":
|
84
|
+
desc: The names of projects that need to be completed before this project can be started/completed
|
85
|
+
type: seq
|
86
|
+
sequence:
|
87
|
+
- type: str
|
88
|
+
"externals":
|
89
|
+
desc: List of external commitments, ie who else cares about project completion?
|
90
|
+
type: seq
|
91
|
+
sequence:
|
92
|
+
- type: str
|
93
|
+
"urls":
|
94
|
+
desc: List of URLs that may be pertinent
|
95
|
+
type: seq
|
96
|
+
sequence:
|
97
|
+
- type: str
|
98
|
+
"tasks":
|
99
|
+
desc: List of tasks to do
|
100
|
+
type: seq
|
101
|
+
sequence:
|
102
|
+
- type: str
|
103
|
+
"done":
|
104
|
+
desc: List of tasks which have been completed
|
105
|
+
type: seq
|
106
|
+
sequence:
|
107
|
+
- type: str
|
108
|
+
"tags":
|
109
|
+
desc: List of tags (WIP)
|
110
|
+
type: seq
|
111
|
+
sequence:
|
112
|
+
- type: str
|
113
|
+
YAML
|
114
|
+
PROJECT_SCHEMA = YAML.safe_load(PROJECT_YAML_SCHEMA)
|
115
|
+
|
116
|
+
class ProjectYAMLFile
|
117
|
+
attr_reader :projects
|
118
|
+
|
119
|
+
def initialize(path)
|
120
|
+
@path = path
|
121
|
+
# TODO: this won't GC, inline validation instead?
|
122
|
+
|
123
|
+
# Handle pre-Ruby 3.1 psych versions (this is brittle)
|
124
|
+
@raw = if Psych::VERSION.split(".")[0].to_i >= 4
|
125
|
+
YAML.load_file(path, permitted_classes: [Date])
|
126
|
+
else
|
127
|
+
YAML.load_file(path)
|
128
|
+
end
|
129
|
+
|
130
|
+
validate_schema
|
131
|
+
@raw ||= []
|
132
|
+
@projects = @raw.map do |proj|
|
133
|
+
proj["namespace"] = namespace
|
134
|
+
Project.new proj
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def namespace
|
139
|
+
# TODO: yikes
|
140
|
+
::Pathname.new(@path).basename.to_s.gsub(/\.yml$/, "")
|
141
|
+
end
|
142
|
+
|
143
|
+
def validate_schema
|
144
|
+
validator = Kwalify::Validator.new(Plansheet::PROJECT_SCHEMA)
|
145
|
+
errors = validator.validate(@raw)
|
146
|
+
# Check YAML validity
|
147
|
+
return unless errors && !errors.empty?
|
148
|
+
|
149
|
+
$stderr.write "Schema errors in #{@path}:\n"
|
150
|
+
errors.each { |err| puts "- [#{err.path}] #{err.message}" }
|
151
|
+
abort
|
152
|
+
end
|
153
|
+
|
154
|
+
def sort!
|
155
|
+
@projects.sort!
|
156
|
+
end
|
157
|
+
|
158
|
+
def yaml_dump
|
159
|
+
YAML.dump(@projects.map(&:to_h))
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
data/lib/plansheet/project.rb
CHANGED
@@ -2,16 +2,19 @@
|
|
2
2
|
|
3
3
|
require "yaml"
|
4
4
|
require "date"
|
5
|
+
require_relative "project/yaml"
|
6
|
+
require_relative "project/stringify"
|
5
7
|
|
6
8
|
module Plansheet
|
7
9
|
PROJECT_STATUS_PRIORITY = {
|
8
10
|
"wip" => 1,
|
9
11
|
"ready" => 2,
|
10
12
|
"blocked" => 3,
|
11
|
-
"
|
12
|
-
"
|
13
|
-
"
|
14
|
-
"
|
13
|
+
"waiting" => 4,
|
14
|
+
"planning" => 5,
|
15
|
+
"idea" => 6,
|
16
|
+
"dropped" => 7,
|
17
|
+
"done" => 8
|
15
18
|
}.freeze
|
16
19
|
|
17
20
|
PROJECT_PRIORITY = {
|
@@ -20,77 +23,12 @@ module Plansheet
|
|
20
23
|
"low" => 3
|
21
24
|
}.freeze
|
22
25
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
- type: map
|
30
|
-
mapping:
|
31
|
-
"project":
|
32
|
-
desc: Project name
|
33
|
-
type: str
|
34
|
-
required: yes
|
35
|
-
"priority":
|
36
|
-
desc: Project priority
|
37
|
-
type: str
|
38
|
-
enum:
|
39
|
-
- high
|
40
|
-
- medium
|
41
|
-
- low
|
42
|
-
"status":
|
43
|
-
desc: The current status of the project
|
44
|
-
type: str
|
45
|
-
enum:
|
46
|
-
- wip # project is a work-in-progress
|
47
|
-
- ready # project is fully scoped, ready to go
|
48
|
-
- blocked # project is blocked, but otherwise ready/wip
|
49
|
-
- planning # project in planning phase
|
50
|
-
- idea # project is little more than an idea
|
51
|
-
- dropped # project has been explicitly dropped, but
|
52
|
-
# want to keep around for reference, etc
|
53
|
-
- done # project is finished, but want to keep around
|
54
|
-
# for reference, etc.
|
55
|
-
"location":
|
56
|
-
desc: Location
|
57
|
-
type: str
|
58
|
-
"notes":
|
59
|
-
desc: Free-form notes string
|
60
|
-
type: str
|
61
|
-
"due":
|
62
|
-
desc: Due date of the task
|
63
|
-
type: date
|
64
|
-
"defer":
|
65
|
-
desc: Defer task until this day
|
66
|
-
type: date
|
67
|
-
"dependencies":
|
68
|
-
desc: The names of projects that need to be completed before this project can be started/completed
|
69
|
-
type: seq
|
70
|
-
sequence:
|
71
|
-
- type: str
|
72
|
-
"externals":
|
73
|
-
desc: List of external commitments, ie who else cares about project completion?
|
74
|
-
type: seq
|
75
|
-
sequence:
|
76
|
-
- type: str
|
77
|
-
"urls":
|
78
|
-
desc: List of URLs that may be pertinent
|
79
|
-
type: seq
|
80
|
-
sequence:
|
81
|
-
- type: str
|
82
|
-
"tasks":
|
83
|
-
desc: List of tasks to do
|
84
|
-
type: seq
|
85
|
-
sequence:
|
86
|
-
- type: str
|
87
|
-
"done":
|
88
|
-
desc: List of tasks which have been completed
|
89
|
-
type: seq
|
90
|
-
sequence:
|
91
|
-
- type: str
|
92
|
-
YAML
|
93
|
-
PROJECT_SCHEMA = YAML.safe_load(PROJECT_YAML_SCHEMA)
|
26
|
+
def self.parse_date_duration(str)
|
27
|
+
return Regexp.last_match(1).to_i if str.strip.match(/(\d+)[dD]/)
|
28
|
+
return (Regexp.last_match(1).to_i * 7) if str.strip.match(/(\d+)[wW]/)
|
29
|
+
|
30
|
+
raise "Can't parse time duration string #{str}"
|
31
|
+
end
|
94
32
|
|
95
33
|
# The use of instance_variable_set/get probably seems a bit weird, but the
|
96
34
|
# intent is to avoid object allocation on non-existent project properties, as
|
@@ -101,10 +39,19 @@ module Plansheet
|
|
101
39
|
class Project
|
102
40
|
include Comparable
|
103
41
|
|
42
|
+
DEFAULT_COMPARISON_ORDER = %w[
|
43
|
+
completeness
|
44
|
+
dependency
|
45
|
+
priority
|
46
|
+
defer
|
47
|
+
due
|
48
|
+
status
|
49
|
+
].map { |x| "compare_#{x}".to_sym }.freeze
|
104
50
|
# NOTE: The order of these affects presentation!
|
105
|
-
|
106
|
-
|
107
|
-
|
51
|
+
# namespace is derived from file name
|
52
|
+
STRING_PROPERTIES = %w[namespace priority status location notes time_estimate frequency lead_time].freeze
|
53
|
+
DATE_PROPERTIES = %w[due defer completed_on created_on starts_on last_done last_reviewed].freeze
|
54
|
+
ARRAY_PROPERTIES = %w[dependencies externals urls tasks done tags].freeze
|
108
55
|
|
109
56
|
ALL_PROPERTIES = STRING_PROPERTIES + DATE_PROPERTIES + ARRAY_PROPERTIES
|
110
57
|
|
@@ -132,14 +79,7 @@ module Plansheet
|
|
132
79
|
|
133
80
|
def <=>(other)
|
134
81
|
ret_val = 0
|
135
|
-
|
136
|
-
compare_completeness
|
137
|
-
compare_dependency
|
138
|
-
compare_priority
|
139
|
-
compare_due
|
140
|
-
compare_defer
|
141
|
-
compare_status
|
142
|
-
].each do |method|
|
82
|
+
DEFAULT_COMPARISON_ORDER.each do |method|
|
143
83
|
ret_val = send(method, other)
|
144
84
|
break if ret_val != 0
|
145
85
|
end
|
@@ -177,132 +117,116 @@ module Plansheet
|
|
177
117
|
|
178
118
|
def compare_dependency(other)
|
179
119
|
return 0 if @dependencies.nil? && other.dependencies.nil?
|
120
|
+
|
180
121
|
if @dependencies.nil?
|
181
|
-
return -1 if other.dependencies.any?
|
122
|
+
return -1 if other.dependencies.any? do |dep|
|
182
123
|
@name.downcase == dep.downcase
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
124
|
+
end
|
125
|
+
elsif @dependencies.any? do |dep|
|
126
|
+
other.name.downcase == dep.downcase
|
127
|
+
end
|
128
|
+
return 1
|
188
129
|
end
|
189
|
-
|
130
|
+
0
|
190
131
|
end
|
191
132
|
|
192
133
|
# Projects that are dropped or done are considered "complete", insofar as
|
193
134
|
# they are only kept around for later reference.
|
194
135
|
def compare_completeness(other)
|
195
|
-
return 0 if
|
196
|
-
return 0 if !
|
197
|
-
|
136
|
+
return 0 if dropped_or_done? && other.dropped_or_done?
|
137
|
+
return 0 if !dropped_or_done? && !other.dropped_or_done?
|
138
|
+
|
139
|
+
dropped_or_done? ? 1 : -1
|
198
140
|
end
|
199
141
|
|
200
142
|
def status
|
201
143
|
return @status if @status
|
144
|
+
return recurring_status if recurring?
|
145
|
+
return task_based_status if @tasks || @done
|
146
|
+
return "done" if @completed_on && @tasks.nil?
|
202
147
|
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
148
|
+
"idea"
|
149
|
+
end
|
150
|
+
|
151
|
+
def task_based_status
|
152
|
+
if @tasks&.count&.positive? && @done&.count&.positive?
|
153
|
+
"wip"
|
154
|
+
elsif @tasks&.count&.positive?
|
155
|
+
"ready"
|
156
|
+
elsif @done&.count&.positive?
|
157
|
+
"done"
|
209
158
|
else
|
210
159
|
"idea"
|
211
160
|
end
|
212
161
|
end
|
213
162
|
|
214
|
-
def
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
str << stringify_string_property(o)
|
223
|
-
end
|
224
|
-
DATE_PROPERTIES.each do |o|
|
225
|
-
str << stringify_string_property(o)
|
226
|
-
end
|
227
|
-
ARRAY_PROPERTIES.each do |o|
|
228
|
-
str << stringify_array_property(o)
|
163
|
+
def recurring_status
|
164
|
+
# add frequency to last_done
|
165
|
+
if @last_done
|
166
|
+
# This project has been done once before
|
167
|
+
subsequent_recurring_status
|
168
|
+
else
|
169
|
+
# This recurring project is being done for the first time
|
170
|
+
task_based_status
|
229
171
|
end
|
230
|
-
str
|
231
172
|
end
|
232
173
|
|
233
|
-
def
|
234
|
-
if
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
end
|
174
|
+
def subsequent_recurring_status
|
175
|
+
return "done" if @lead_time && defer > Date.today
|
176
|
+
return "done" if due > Date.today
|
177
|
+
|
178
|
+
task_based_status
|
239
179
|
end
|
240
180
|
|
241
|
-
def
|
242
|
-
if
|
243
|
-
|
244
|
-
else
|
245
|
-
""
|
246
|
-
end
|
181
|
+
def process_recurring
|
182
|
+
# TODO: Tasks will be moved from done->tasks if recurring project is
|
183
|
+
# starting again
|
247
184
|
end
|
248
185
|
|
249
|
-
|
250
|
-
|
251
|
-
if
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
end
|
256
|
-
end
|
257
|
-
str
|
186
|
+
# Due date either explicit or recurring
|
187
|
+
def due
|
188
|
+
return @due if @due
|
189
|
+
return recurring_due_date if recurring?
|
190
|
+
|
191
|
+
nil
|
258
192
|
end
|
259
193
|
|
260
|
-
def
|
261
|
-
|
262
|
-
|
263
|
-
|
194
|
+
def recurring_due_date
|
195
|
+
if @last_done
|
196
|
+
@last_done + Plansheet.parse_date_duration(@frequency)
|
197
|
+
else
|
198
|
+
Date.today
|
264
199
|
end
|
265
|
-
h.delete "priority" if h.key?("priority") && h["priority"] == "low"
|
266
|
-
h.delete "status" if h.key?("status") && h["status"] == "idea"
|
267
|
-
h
|
268
200
|
end
|
269
|
-
end
|
270
|
-
|
271
|
-
class ProjectYAMLFile
|
272
|
-
attr_reader :projects
|
273
|
-
|
274
|
-
def initialize(path)
|
275
|
-
@path = path
|
276
|
-
# TODO: this won't GC, inline validation instead?
|
277
201
|
|
278
|
-
|
279
|
-
@
|
280
|
-
|
281
|
-
else
|
282
|
-
YAML.load_file(path)
|
283
|
-
end
|
202
|
+
def defer
|
203
|
+
return @defer if @defer
|
204
|
+
return lead_time_deferral if @lead_time && due
|
284
205
|
|
285
|
-
|
286
|
-
@projects = @raw.map { |proj| Project.new proj }
|
206
|
+
nil
|
287
207
|
end
|
288
208
|
|
289
|
-
def
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
return unless errors && !errors.empty?
|
209
|
+
def lead_time_deferral
|
210
|
+
[(due - Plansheet.parse_date_duration(@lead_time)),
|
211
|
+
Date.today].max
|
212
|
+
end
|
294
213
|
|
295
|
-
|
296
|
-
|
297
|
-
abort
|
214
|
+
def recurring?
|
215
|
+
!@frequency.nil?
|
298
216
|
end
|
299
217
|
|
300
|
-
def
|
301
|
-
|
218
|
+
def dropped_or_done?
|
219
|
+
status == "dropped" || status == "done"
|
302
220
|
end
|
303
221
|
|
304
|
-
def
|
305
|
-
|
222
|
+
def to_h
|
223
|
+
h = { "project" => @name }
|
224
|
+
ALL_PROPERTIES.each do |prop|
|
225
|
+
h[prop] = instance_variable_get("@#{prop}") if instance_variable_defined?("@#{prop}")
|
226
|
+
end
|
227
|
+
h.delete "priority" if h.key?("priority") && h["priority"] == "low"
|
228
|
+
h.delete "status" if h.key?("status") && h["status"] == "idea"
|
229
|
+
h
|
306
230
|
end
|
307
231
|
end
|
308
232
|
end
|
data/lib/plansheet/sheet.rb
CHANGED
data/lib/plansheet/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: plansheet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.13.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Crosby
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-06-
|
11
|
+
date: 2022-06-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dc-kwalify
|
@@ -33,7 +33,6 @@ extensions: []
|
|
33
33
|
extra_rdoc_files: []
|
34
34
|
files:
|
35
35
|
- ".rubocop.yml"
|
36
|
-
- ".rubocop_todo.yml"
|
37
36
|
- CODE_OF_CONDUCT.md
|
38
37
|
- Gemfile
|
39
38
|
- Gemfile.lock
|
@@ -45,6 +44,8 @@ files:
|
|
45
44
|
- exe/plansheet
|
46
45
|
- lib/plansheet.rb
|
47
46
|
- lib/plansheet/project.rb
|
47
|
+
- lib/plansheet/project/stringify.rb
|
48
|
+
- lib/plansheet/project/yaml.rb
|
48
49
|
- lib/plansheet/sheet.rb
|
49
50
|
- lib/plansheet/version.rb
|
50
51
|
homepage: https://dafyddcrosby.com
|
data/.rubocop_todo.yml
DELETED
@@ -1,36 +0,0 @@
|
|
1
|
-
# This configuration was generated by
|
2
|
-
# `rubocop --auto-gen-config`
|
3
|
-
# on 2022-06-04 17:25:54 UTC using RuboCop version 1.29.1.
|
4
|
-
# The point is for the user to remove these configuration records
|
5
|
-
# one by one as the offenses are removed from the code base.
|
6
|
-
# Note that changes in the inspected code, or installation of new
|
7
|
-
# versions of RuboCop, may require this file to be generated again.
|
8
|
-
|
9
|
-
# Offense count: 1
|
10
|
-
# Configuration parameters: CountComments, CountAsOne.
|
11
|
-
Metrics/ClassLength:
|
12
|
-
Max: 105
|
13
|
-
|
14
|
-
# Offense count: 1
|
15
|
-
# Configuration parameters: IgnoredMethods.
|
16
|
-
Metrics/CyclomaticComplexity:
|
17
|
-
Max: 8
|
18
|
-
|
19
|
-
# Offense count: 2
|
20
|
-
# Configuration parameters: CountComments, CountAsOne, ExcludedMethods, IgnoredMethods.
|
21
|
-
Metrics/MethodLength:
|
22
|
-
Max: 12
|
23
|
-
|
24
|
-
# Offense count: 1
|
25
|
-
# Configuration parameters: IgnoredMethods.
|
26
|
-
Metrics/PerceivedComplexity:
|
27
|
-
Max: 10
|
28
|
-
|
29
|
-
# Offense count: 2
|
30
|
-
# Configuration parameters: AllowedConstants.
|
31
|
-
Style/Documentation:
|
32
|
-
Exclude:
|
33
|
-
- 'spec/**/*'
|
34
|
-
- 'test/**/*'
|
35
|
-
- 'lib/plansheet.rb'
|
36
|
-
- 'lib/plansheet/project.rb'
|