plansheet 0.12.0 → 0.12.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d1c4e7e5e45d00a1218ac7346c60ba9182c7b73ac2761958c24ea8c8dcf15d9d
4
- data.tar.gz: 50cc492240c458e5bc13539f03203007b8922dcd2e00e5108d6f929c81419f2e
3
+ metadata.gz: 72d3799f5166153c1775c768f0734cf0e390adfd80893ef1ae1aa710b7888b0b
4
+ data.tar.gz: a18fd6eeb6a787438ddcdff1e6b0f25a17688f05a7bccff82495520517754b19
5
5
  SHA512:
6
- metadata.gz: 2fe3310c09dfe7d4e79172a476f3bcfc0a3ef6261757a4070a6f49d9857673524663ee97622db603acae911201d5f1acc9cdb65d7c30547ea0e3f4610dc5e0bf
7
- data.tar.gz: 58aee2a5ab4f95c114461a8ef614823b5c4e22e0961c792623d0720b033a40c1abbdf1d23887b7b5a38b4823138994116d3eb6b42f2675263d0825d567fee173
6
+ metadata.gz: c97c83093f8e70948a96392b5d02329128c5f1031a0645b35b9c42bebeabb82192207c3ff71671081792ef3d61e9277c219984f0f558a7b54c1fac632fa68445
7
+ data.tar.gz: 6723401a02c2086976e1002e4f8d08855f25726d1610fd9f4e593ae3ceac707c47bb6a1114ec1b40f707295c1c627fd5b72cce5ebe45f84b78b24d8304107bcf
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
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- plansheet (0.12.0)
4
+ plansheet (0.12.3)
5
5
  dc-kwalify (~> 1.0)
6
6
 
7
7
  GEM
@@ -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,148 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "yaml"
4
+ require "date"
5
+
6
+ module Plansheet
7
+ # Once there's some stability in plansheet and dc-kwalify, will pre-load this
8
+ # to save the later YAML.load
9
+ PROJECT_YAML_SCHEMA = <<~YAML
10
+ desc: dc-tasks project schema
11
+ type: seq
12
+ sequence:
13
+ - type: map
14
+ mapping:
15
+ "project":
16
+ desc: Project name
17
+ type: str
18
+ required: yes
19
+ "priority":
20
+ desc: Project priority
21
+ type: str
22
+ enum:
23
+ - high
24
+ - medium
25
+ - low
26
+ "status":
27
+ desc: The current status of the project
28
+ type: str
29
+ enum:
30
+ - wip # project is a work-in-progress
31
+ - ready # project has tasks, ready to go
32
+ - waiting # project in waiting on some external person/event
33
+ - blocked # project is blocked by another project, but otherwise ready/wip
34
+ - planning # project in planning phase (set manually)
35
+ - idea # project is little more than an idea
36
+ - dropped # project has been explicitly dropped, but
37
+ # want to keep around for reference, etc
38
+ - done # project is finished, but want to keep around
39
+ # for reference, etc.
40
+ "location":
41
+ desc: Location
42
+ type: str
43
+ "notes":
44
+ desc: Free-form notes string
45
+ type: str
46
+ "time_estimate":
47
+ desc: The estimated amount of time before a project is completed
48
+ type: str
49
+ "frequency":
50
+ desc: The amount of time before a recurring project moves to ready status again from when it was last done (WIP)
51
+ type: str
52
+ pattern: /\\d+[dwDW]/
53
+ "lead_time":
54
+ desc: The amount of time before a recurring project is "due" moved to ready where the project (sort of a deferral mechanism) (WIP)
55
+ type: str
56
+ pattern: /\\d+[dwDW]/
57
+ "due":
58
+ desc: Due date of the task
59
+ type: date
60
+ "defer":
61
+ desc: Defer task until this day
62
+ type: date
63
+ "completed_on":
64
+ desc: When the (non-recurring) project was completed
65
+ type: date
66
+ "created_on":
67
+ desc: When the project was created
68
+ type: date
69
+ "starts_on":
70
+ desc: For ICS (WIP)
71
+ type: date
72
+ "last_reviewed":
73
+ desc: When the project was last reviewed (WIP)
74
+ type: date
75
+ "last_done":
76
+ desc: When the recurring project was last completed (WIP)
77
+ type: date
78
+ "dependencies":
79
+ desc: The names of projects that need to be completed before this project can be started/completed
80
+ type: seq
81
+ sequence:
82
+ - type: str
83
+ "externals":
84
+ desc: List of external commitments, ie who else cares about project completion?
85
+ type: seq
86
+ sequence:
87
+ - type: str
88
+ "urls":
89
+ desc: List of URLs that may be pertinent
90
+ type: seq
91
+ sequence:
92
+ - type: str
93
+ "tasks":
94
+ desc: List of tasks to do
95
+ type: seq
96
+ sequence:
97
+ - type: str
98
+ "done":
99
+ desc: List of tasks which have been completed
100
+ type: seq
101
+ sequence:
102
+ - type: str
103
+ "tags":
104
+ desc: List of tags (WIP)
105
+ type: seq
106
+ sequence:
107
+ - type: str
108
+ YAML
109
+ PROJECT_SCHEMA = YAML.safe_load(PROJECT_YAML_SCHEMA)
110
+
111
+ class ProjectYAMLFile
112
+ attr_reader :projects
113
+
114
+ def initialize(path)
115
+ @path = path
116
+ # TODO: this won't GC, inline validation instead?
117
+
118
+ # Handle pre-Ruby 3.1 psych versions (this is brittle)
119
+ @raw = if Psych::VERSION.split(".")[0].to_i >= 4
120
+ YAML.load_file(path, permitted_classes: [Date])
121
+ else
122
+ YAML.load_file(path)
123
+ end
124
+
125
+ validate_schema
126
+ @projects = @raw.map { |proj| Project.new proj }
127
+ end
128
+
129
+ def validate_schema
130
+ validator = Kwalify::Validator.new(Plansheet::PROJECT_SCHEMA)
131
+ errors = validator.validate(@raw)
132
+ # Check YAML validity
133
+ return unless errors && !errors.empty?
134
+
135
+ $stderr.write "Schema errors in #{@path}:\n"
136
+ errors.each { |err| puts "- [#{err.path}] #{err.message}" }
137
+ abort
138
+ end
139
+
140
+ def sort!
141
+ @projects.sort!
142
+ end
143
+
144
+ def yaml_dump
145
+ YAML.dump(@projects.map(&:to_h))
146
+ end
147
+ end
148
+ end
@@ -2,6 +2,8 @@
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 = {
@@ -21,107 +23,6 @@ module Plansheet
21
23
  "low" => 3
22
24
  }.freeze
23
25
 
24
- # Once there's some stability in plansheet and dc-kwalify, will pre-load this
25
- # to save the later YAML.load
26
- PROJECT_YAML_SCHEMA = <<~YAML
27
- desc: dc-tasks project schema
28
- type: seq
29
- sequence:
30
- - type: map
31
- mapping:
32
- "project":
33
- desc: Project name
34
- type: str
35
- required: yes
36
- "priority":
37
- desc: Project priority
38
- type: str
39
- enum:
40
- - high
41
- - medium
42
- - low
43
- "status":
44
- desc: The current status of the project
45
- type: str
46
- enum:
47
- - wip # project is a work-in-progress
48
- - ready # project has tasks, ready to go
49
- - waiting # project in waiting on some external person/event
50
- - blocked # project is blocked by another project, but otherwise ready/wip
51
- - planning # project in planning phase (set manually)
52
- - idea # project is little more than an idea
53
- - dropped # project has been explicitly dropped, but
54
- # want to keep around for reference, etc
55
- - done # project is finished, but want to keep around
56
- # for reference, etc.
57
- "location":
58
- desc: Location
59
- type: str
60
- "notes":
61
- desc: Free-form notes string
62
- type: str
63
- "time_estimate":
64
- desc: The estimated amount of time before a project is completed
65
- type: str
66
- "frequency":
67
- desc: The amount of time before a recurring project moves to ready status again from when it was last done (WIP)
68
- type: str
69
- pattern: /\\d+[dwDW]/
70
- "lead_time":
71
- desc: The amount of time before a recurring project is "due" moved to ready where the project (sort of a deferral mechanism) (WIP)
72
- type: str
73
- pattern: /\\d+[dwDW]/
74
- "due":
75
- desc: Due date of the task
76
- type: date
77
- "defer":
78
- desc: Defer task until this day
79
- type: date
80
- "created_on":
81
- desc: When the project was created
82
- type: date
83
- "starts_on":
84
- desc: For ICS (WIP)
85
- type: date
86
- "last_reviewed":
87
- desc: When the project was last reviewed (WIP)
88
- type: date
89
- "last_done":
90
- desc: When the recurring project was last completed (WIP)
91
- type: date
92
- "dependencies":
93
- desc: The names of projects that need to be completed before this project can be started/completed
94
- type: seq
95
- sequence:
96
- - type: str
97
- "externals":
98
- desc: List of external commitments, ie who else cares about project completion?
99
- type: seq
100
- sequence:
101
- - type: str
102
- "urls":
103
- desc: List of URLs that may be pertinent
104
- type: seq
105
- sequence:
106
- - type: str
107
- "tasks":
108
- desc: List of tasks to do
109
- type: seq
110
- sequence:
111
- - type: str
112
- "done":
113
- desc: List of tasks which have been completed
114
- type: seq
115
- sequence:
116
- - type: str
117
- "tags":
118
- desc: List of tags (WIP)
119
- type: seq
120
- sequence:
121
- - type: str
122
- YAML
123
- PROJECT_SCHEMA = YAML.safe_load(PROJECT_YAML_SCHEMA)
124
-
125
26
  def self.parse_date_duration(str)
126
27
  return Regexp.last_match(1).to_i if str.strip.match(/(\d+)[dD]/)
127
28
  return (Regexp.last_match(1).to_i * 7) if str.strip.match(/(\d+)[wW]/)
@@ -148,7 +49,7 @@ module Plansheet
148
49
  ].map { |x| "compare_#{x}".to_sym }.freeze
149
50
  # NOTE: The order of these affects presentation!
150
51
  STRING_PROPERTIES = %w[priority status location notes time_estimate frequency lead_time].freeze
151
- DATE_PROPERTIES = %w[due defer created_on starts_on last_done last_reviewed].freeze
52
+ DATE_PROPERTIES = %w[due defer completed_on created_on starts_on last_done last_reviewed].freeze
152
53
  ARRAY_PROPERTIES = %w[dependencies externals urls tasks done tags].freeze
153
54
 
154
55
  ALL_PROPERTIES = STRING_PROPERTIES + DATE_PROPERTIES + ARRAY_PROPERTIES
@@ -240,8 +141,8 @@ module Plansheet
240
141
  def status
241
142
  return @status if @status
242
143
  return recurring_status if recurring?
243
- return task_based_status if (@tasks || @done)
244
- # TODO: return done if done count is positive...
144
+ return task_based_status if @tasks || @done
145
+ return "done" if @completed_on && @tasks.nil?
245
146
 
246
147
  "idea"
247
148
  end
@@ -260,18 +161,19 @@ module Plansheet
260
161
 
261
162
  def recurring_status
262
163
  # add frequency to last_done
263
- unless @last_done
264
- # This recurring project is being done for the first time
265
- task_based_status
266
- else
164
+ if @last_done
267
165
  # This project has been done once before
268
166
  subsequent_recurring_status
167
+ else
168
+ # This recurring project is being done for the first time
169
+ task_based_status
269
170
  end
270
171
  end
271
172
 
272
173
  def subsequent_recurring_status
273
174
  return "done" if @lead_time && defer > Date.today
274
175
  return "done" if due > Date.today
176
+
275
177
  task_based_status
276
178
  end
277
179
 
@@ -284,6 +186,7 @@ module Plansheet
284
186
  def due
285
187
  return @due if @due
286
188
  return recurring_due_date if recurring?
189
+
287
190
  nil
288
191
  end
289
192
 
@@ -298,6 +201,7 @@ module Plansheet
298
201
  def defer
299
202
  return @defer if @defer
300
203
  return lead_time_deferral if @lead_time && due
204
+
301
205
  nil
302
206
  end
303
207
 
@@ -314,48 +218,6 @@ module Plansheet
314
218
  status == "dropped" || status == "done"
315
219
  end
316
220
 
317
- def to_s
318
- str = String.new
319
- str << "# #{@name}\n"
320
- STRING_PROPERTIES.each do |o|
321
- str << stringify_string_property(o)
322
- end
323
- DATE_PROPERTIES.each do |o|
324
- str << stringify_string_property(o)
325
- end
326
- ARRAY_PROPERTIES.each do |o|
327
- str << stringify_array_property(o)
328
- end
329
- str
330
- end
331
-
332
- def stringify_string_property(prop)
333
- if instance_variable_defined? "@#{prop}"
334
- "#{prop}: #{instance_variable_get("@#{prop}")}\n"
335
- else
336
- ""
337
- end
338
- end
339
-
340
- def stringify_date_property(prop)
341
- if instance_variable_defined? "@#{prop}"
342
- "#{prop}: #{instance_variable_get("@#{prop}")}\n"
343
- else
344
- ""
345
- end
346
- end
347
-
348
- def stringify_array_property(prop)
349
- str = String.new
350
- if instance_variable_defined? "@#{prop}"
351
- str << "#{prop}:\n"
352
- instance_variable_get("@#{prop}").each do |t|
353
- str << "- #{t}\n"
354
- end
355
- end
356
- str
357
- end
358
-
359
221
  def to_h
360
222
  h = { "project" => @name }
361
223
  ALL_PROPERTIES.each do |prop|
@@ -366,42 +228,4 @@ module Plansheet
366
228
  h
367
229
  end
368
230
  end
369
-
370
- class ProjectYAMLFile
371
- attr_reader :projects
372
-
373
- def initialize(path)
374
- @path = path
375
- # TODO: this won't GC, inline validation instead?
376
-
377
- # Handle pre-Ruby 3.1 psych versions (this is brittle)
378
- @raw = if Psych::VERSION.split(".")[0].to_i >= 4
379
- YAML.load_file(path, permitted_classes: [Date])
380
- else
381
- YAML.load_file(path)
382
- end
383
-
384
- validate_schema
385
- @projects = @raw.map { |proj| Project.new proj }
386
- end
387
-
388
- def validate_schema
389
- validator = Kwalify::Validator.new(Plansheet::PROJECT_SCHEMA)
390
- errors = validator.validate(@raw)
391
- # Check YAML validity
392
- return unless errors && !errors.empty?
393
-
394
- $stderr.write "Schema errors in #{@path}:\n"
395
- errors.each { |err| puts "- [#{err.path}] #{err.message}" }
396
- abort
397
- end
398
-
399
- def sort!
400
- @projects.sort!
401
- end
402
-
403
- def yaml_dump
404
- YAML.dump(@projects.map(&:to_h))
405
- end
406
- end
407
231
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Plansheet
4
- VERSION = "0.12.0"
4
+ VERSION = "0.12.3"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: plansheet
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.0
4
+ version: 0.12.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Crosby
@@ -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,35 +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
- Enabled: false
13
-
14
- # Offense count: 1
15
- # Configuration parameters: IgnoredMethods.
16
- Metrics/CyclomaticComplexity:
17
- Enabled: false
18
-
19
- # Offense count: 2
20
- # Configuration parameters: CountComments, CountAsOne, ExcludedMethods, IgnoredMethods.
21
- Metrics/MethodLength:
22
- Enabled: false
23
-
24
- # Offense count: 1
25
- # Configuration parameters: IgnoredMethods.
26
- Metrics/PerceivedComplexity:
27
- Enabled: false
28
-
29
- # Offense count: 2
30
- # Configuration parameters: AllowedConstants.
31
- Style/Documentation:
32
- Exclude:
33
- - 'test/**/*'
34
- - 'lib/plansheet.rb'
35
- - 'lib/plansheet/project.rb'