plansheet 0.3.3 → 0.5.1

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: e78fa7422ef53cce690b2d8500c406ac6bb2136d195725b3d839d67cc234c780
4
- data.tar.gz: 65093bd8b89bf39b2a144de85867bcb4635e41f5a8c379b8486c0a8a0135cebb
3
+ metadata.gz: 3546f42fdd342ea128be90bff2e19b7bcb5c0910990e2132b89b87cbf6a1f776
4
+ data.tar.gz: 2ea5d505262832e19e77a63e7aa7c59c9fff0b98ddc3ee8218c68b010f4768eb
5
5
  SHA512:
6
- metadata.gz: a70d01f6617f79041d95e4a1b596f68c36de68a9be8abd7be684f3d394dd15a5d49bc0a7560435670fab7d5fc59dd505c1f4adee0aba68d7feaed46cc2f61bcb
7
- data.tar.gz: f63764aaaca3a1a7efa75c07f2776d279171dc297cee0d34306416690fb2b08f5c85697f7d1ebc1a40a03671727f3162f0293d552231405c0084438a61dfb9b6
6
+ metadata.gz: 335cb1a3e74ab82a1441ec034099427dc0caabaad8a87c1f2620c7143d1fd4772023fe089a7305063fb12a96d169e44dd0b01f8f20437f45bdfa945b03aa2422
7
+ data.tar.gz: 5d618d61c6a07d8e32e46cfb4dba5df0264370f01d8b4ecef4c68f9fdcf6fcf600ca33bda0a8918e63992434e2a009e4d836f1f838851e0ee94de53128fe1ab2
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- plansheet (0.3.3)
4
+ plansheet (0.5.1)
5
5
  dc-kwalify (~> 1.0)
6
6
 
7
7
  GEM
data/exe/plansheet CHANGED
@@ -1,81 +1,39 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- require "kwalify"
5
- require "yaml"
6
4
  require "plansheet"
7
-
8
- begin
9
- config = YAML.load_file "#{Dir.home}/.plansheet.yml"
10
- rescue StandardError
11
- abort "unable to load plansheet config file"
12
- end
13
-
14
- project_hash = {}
15
- projects = Dir.glob("*yml", base: config["projects_dir"])
16
- projects.each do |l|
17
- contents = YAML.load_file(File.join(config["projects_dir"], l))
18
- validator = Kwalify::Validator.new(Plansheet::PROJECT_SCHEMA)
19
- errors = validator.validate(contents)
20
- # Check YAML validity
21
- if errors && !errors.empty?
22
- $stderr.write "Schema errors in #{l}\n"
23
- errors.each { |err| puts "- [#{err.path}] #{err.message}" }
24
- abort
25
- end
26
-
27
- key = l.gsub(".yml", "")
28
- contents.each do |project|
29
- key = project["project"]
30
- project_hash[key] = {
31
- name: project["project"]
32
- }
33
- %w[tasks desc done].each do |k|
34
- project_hash[key][k.to_sym] = project[k] if project[k]
35
- end
36
- project_hash[key][:status] = if project["status"]
37
- project["status"]
38
- elsif project_hash[key][:tasks]
39
- "planning"
40
- else
41
- "idea"
42
- end
5
+ require "optparse"
6
+
7
+ parser = OptionParser.new
8
+ parser.on(
9
+ "--sheet",
10
+ "Generates MD/LaTeX project PDF"
11
+ )
12
+ parser.on(
13
+ "--sort",
14
+ "Sort project files"
15
+ )
16
+ parser.on(
17
+ "--cli",
18
+ "CLI dump of projects (WIP)"
19
+ )
20
+ options = {}
21
+ parser.parse!(into: options)
22
+
23
+ config = Plansheet.load_config
24
+
25
+ if options[:sheet] || options.empty?
26
+ project_arr = Plansheet.load_projects_dir config["projects_dir"]
27
+
28
+ Dir.mkdir config["output_dir"] unless Dir.exist? config["output_dir"]
29
+
30
+ Plansheet::Sheet.new("#{config["output_dir"]}/projects.md", project_arr)
31
+ elsif options[:sort]
32
+ Plansheet.resort_projects_in_dir config["projects_dir"]
33
+ elsif options[:cli]
34
+ project_arr = Plansheet.load_projects_dir config["projects_dir"]
35
+ project_arr.each do |proj|
36
+ puts proj
37
+ puts "\n"
43
38
  end
44
39
  end
45
-
46
- sorted_hash = project_hash.sort_by do |_, v|
47
- Plansheet::PROJECT_STATUS_PRIORITY[v[:status]]
48
- end
49
-
50
- def project_minipage(proj)
51
- str = String.new
52
- str << "\\begin{minipage}{5cm}\n"
53
- str << "#{proj[:name]} - #{proj[:status]} \\\\\n"
54
- proj[:tasks]&.each do |t|
55
- str << "$\\square$ #{t} \\\\\n"
56
- end
57
- str << "\\end{minipage}\n"
58
- str
59
- end
60
-
61
- require "date"
62
- projects_str = String.new
63
- projects_str << <<~FRONTMATTER
64
- ---
65
- geometry: margin=3cm
66
- ---
67
- \\thispagestyle{empty}
68
-
69
- # Date: #{Date.today}
70
- FRONTMATTER
71
-
72
- sorted_hash.first(60).each do |_, p|
73
- projects_str << project_minipage(p)
74
- end
75
-
76
- output_file = "#{config["output_dir"]}/projects.md"
77
- puts "Writing to #{output_file}"
78
- Dir.mkdir config["output_dir"] unless Dir.exist? config["output_dir"]
79
- f = File.open(output_file, "w")
80
- f.write(projects_str)
81
- f.close
@@ -44,6 +44,9 @@ module Plansheet
44
44
  enum:
45
45
  - high
46
46
  - low
47
+ "location":
48
+ desc: Location (not currently implemented)
49
+ type: str
47
50
  "tasks":
48
51
  desc: List of tasks to do
49
52
  type: seq
@@ -59,4 +62,91 @@ module Plansheet
59
62
  type: str
60
63
  YAML
61
64
  PROJECT_SCHEMA = YAML.safe_load(PROJECT_YAML_SCHEMA)
65
+ class Project
66
+ attr_reader :name, :tasks, :done, :notes, :location
67
+
68
+ def initialize(options)
69
+ @name = options["project"]
70
+
71
+ @tasks = options["tasks"] || []
72
+ @done = options["done"] || []
73
+
74
+ @notes = options["notes"] if options["notes"]
75
+ @location = options["location"] if options["location"]
76
+ @status = options["status"] if options["status"]
77
+ end
78
+
79
+ def status
80
+ return @status if @status
81
+
82
+ if @tasks.count.positive?
83
+ if @done.count.positive?
84
+ "wip"
85
+ else
86
+ "planning"
87
+ end
88
+ else
89
+ "idea"
90
+ end
91
+ end
92
+
93
+ def to_s
94
+ str = String.new
95
+ str << "# #{@name}\n"
96
+ str << "status: #{status}\n"
97
+ str << "notes: #{notes}\n" unless @notes.nil?
98
+ str << "location: #{location}\n" unless @location.nil?
99
+ str << "tasks:\n" unless @tasks.empty?
100
+ @tasks.each do |t|
101
+ str << "- #{t}\n"
102
+ end
103
+ str << "done:\n" unless @done.empty?
104
+ @done.each do |d|
105
+ str << "- #{d}\n"
106
+ end
107
+ str
108
+ end
109
+ def to_h
110
+ h = { "project" => @name }
111
+ h["status"] = status unless status == "idea"
112
+ h["notes"] = @notes unless @notes.nil?
113
+ h["location"] = @location unless @location.nil?
114
+ h["tasks"] = @tasks unless @tasks.empty?
115
+ h["done"] = @done unless @done.empty?
116
+ h
117
+ end
118
+ end
119
+
120
+ class ProjectYAMLFile
121
+ attr_reader :projects
122
+
123
+ def initialize(path)
124
+ @path = path
125
+ # TODO: this won't GC, inline validation instead?
126
+ @raw = YAML.load_file(path)
127
+ validate_schema
128
+ @projects = @raw.map { |proj| Project.new proj }
129
+ end
130
+
131
+ def validate_schema
132
+ validator = Kwalify::Validator.new(Plansheet::PROJECT_SCHEMA)
133
+ errors = validator.validate(@raw)
134
+ # Check YAML validity
135
+ if errors && !errors.empty?
136
+ $stderr.write "Schema errors in #{l}\n"
137
+ errors.each { |err| puts "- [#{err.path}] #{err.message}" }
138
+ abort
139
+ end
140
+ end
141
+
142
+ def sort!
143
+ @projects.sort_by! do |project|
144
+ Plansheet::PROJECT_STATUS_PRIORITY[project.status]
145
+ end
146
+ end
147
+
148
+ def yaml_dump
149
+ YAML.dump(@projects.map(&:to_h))
150
+ end
151
+ end
62
152
  end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "date"
4
+ module Plansheet
5
+ # The Sheet class constructs a Markdown/LaTeX file for use with pandoc
6
+ class Sheet
7
+ def initialize(output_file, project_arr)
8
+ sorted_arr = project_arr.sort_by do |p|
9
+ Plansheet::PROJECT_STATUS_PRIORITY[p.status]
10
+ end
11
+
12
+ projects_str = String.new
13
+ projects_str << sheet_header
14
+
15
+ sorted_arr.first(60).each do |p|
16
+ projects_str << project_minipage(p)
17
+ end
18
+ puts "Writing to #{output_file}"
19
+ File.write(output_file, projects_str)
20
+ end
21
+
22
+ def sheet_header
23
+ <<~FRONTMATTER
24
+ ---
25
+ geometry: margin=1.5cm
26
+ ---
27
+ \\thispagestyle{empty}
28
+
29
+ # Date: #{Date.today}
30
+ FRONTMATTER
31
+ end
32
+
33
+ def project_minipage(proj)
34
+ str = String.new
35
+ str << "\\begin{minipage}{4.5cm}\n"
36
+ str << project_header(proj)
37
+ proj.tasks.each do |t|
38
+ str << "$\\square$ #{t} \\\\\n"
39
+ end
40
+ str << "\\end{minipage}\n"
41
+ str
42
+ end
43
+
44
+ def project_header(proj)
45
+ str = String.new
46
+ str << "#{proj.name} - #{proj.status}"
47
+ str << " - #{proj.location}" if proj.location
48
+ str << " \\\\\n"
49
+ str
50
+ end
51
+ end
52
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Plansheet
4
- VERSION = "0.3.3"
4
+ VERSION = "0.5.1"
5
5
  end
data/lib/plansheet.rb CHANGED
@@ -2,8 +2,35 @@
2
2
 
3
3
  require_relative "plansheet/version"
4
4
  require_relative "plansheet/project"
5
+ require_relative "plansheet/sheet"
6
+ require "yaml"
7
+ require "kwalify"
5
8
 
6
9
  module Plansheet
7
10
  class Error < StandardError; end
8
- # Your code goes here...
11
+
12
+ def self.load_config
13
+ YAML.load_file "#{Dir.home}/.plansheet.yml"
14
+ rescue StandardError
15
+ abort "unable to load plansheet config file"
16
+ end
17
+
18
+ def self.resort_projects_in_dir(dir)
19
+ project_files = Dir.glob("#{dir}/*yml")
20
+ project_files.each do |f|
21
+ pyf = ProjectYAMLFile.new(f)
22
+ pyf.sort!
23
+ File.write(f, pyf.yaml_dump)
24
+ end
25
+ end
26
+
27
+ def self.load_projects_dir(dir)
28
+ project_arr = []
29
+ projects = Dir.glob("*yml", base: dir)
30
+ projects.each do |l|
31
+ project_arr << ProjectYAMLFile.new(File.join(dir, l)).projects
32
+ end
33
+
34
+ project_arr.flatten!
35
+ end
9
36
  end
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.3.3
4
+ version: 0.5.1
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-05-24 00:00:00.000000000 Z
11
+ date: 2022-05-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dc-kwalify
@@ -29,7 +29,6 @@ email:
29
29
  - dave@dafyddcrosby.com
30
30
  executables:
31
31
  - plansheet
32
- - plansheet-sorter
33
32
  extensions: []
34
33
  extra_rdoc_files: []
35
34
  files:
@@ -42,9 +41,9 @@ files:
42
41
  - Rakefile
43
42
  - examples/backpack.yml
44
43
  - exe/plansheet
45
- - exe/plansheet-sorter
46
44
  - lib/plansheet.rb
47
45
  - lib/plansheet/project.rb
46
+ - lib/plansheet/sheet.rb
48
47
  - lib/plansheet/version.rb
49
48
  homepage: https://dafyddcrosby.com
50
49
  licenses:
data/exe/plansheet-sorter DELETED
@@ -1,25 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- # An ugly script to sort projects by status (and eventually priority)
5
-
6
- require "yaml"
7
- require "plansheet"
8
-
9
- def project_priority(project)
10
- if project["status"]
11
- project["status"]
12
- elsif project["tasks"]
13
- "planning"
14
- else
15
- "idea"
16
- end
17
- end
18
-
19
- filename = ARGV.first
20
- contents = YAML.load_file(filename)
21
- sorted_hash = contents.sort_by do |project|
22
- Plansheet::PROJECT_STATUS_PRIORITY[project_priority project]
23
- end
24
-
25
- File.write(filename, YAML.dump(sorted_hash))