Class: Plansheet::ProjectYAMLFile

Inherits:
Object
  • Object
show all
Defined in:
lib/plansheet/project/yaml.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path) ⇒ ProjectYAMLFile

Returns a new instance of ProjectYAMLFile.



169
170
171
172
# File 'lib/plansheet/project/yaml.rb', line 169

def initialize(path)
  @path = path
  # TODO: this won't GC, inline validation instead?
end

Instance Attribute Details

#projectsObject

Returns the value of attribute projects.



167
168
169
# File 'lib/plansheet/project/yaml.rb', line 167

def projects
  @projects
end

Instance Method Details

#append_project(project) ⇒ Object



217
218
219
220
# File 'lib/plansheet/project/yaml.rb', line 217

def append_project(project)
  load_file
  compare_and_write(@projects.append(project))
end

#compare_and_write(projects) ⇒ Object



222
223
224
225
226
227
228
229
230
231
232
233
234
# File 'lib/plansheet/project/yaml.rb', line 222

def compare_and_write(projects)
  load_file
  orig_string = yaml_dump(@projects)
  updated_projects_string = yaml_dump(projects)

  # Compare the existing file to the newly generated one - we only want a
  # write if something has changed
  return if updated_projects_string == orig_string

  puts "#{@path} has changed, writing"
  puts Diffy::Diff.new(orig_string, updated_projects_string).to_s(:color)
  File.write @path, updated_projects_string
end

#load_fileObject



178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/plansheet/project/yaml.rb', line 178

def load_file
  stub_file unless File.exist? @path

  # Handle pre-Ruby 3.1 psych versions (this is brittle)
  @raw = if Psych::VERSION.split(".")[0].to_i >= 4
           YAML.load_file(@path, permitted_classes: [Date])
         else
           YAML.load_file(@path)
         end

  validate_schema
  @raw ||= []
  @projects = @raw.map do |proj|
    proj["namespace"] = namespace
    Project.new proj
  end
  @projects
end

#namespaceObject



197
198
199
200
# File 'lib/plansheet/project/yaml.rb', line 197

def namespace
  # TODO: yikes
  ::Pathname.new(@path).basename.to_s.gsub(/\.yml$/, "")
end

#sort!Object



213
214
215
# File 'lib/plansheet/project/yaml.rb', line 213

def sort!
  @projects.sort!
end

#stub_fileObject



174
175
176
# File 'lib/plansheet/project/yaml.rb', line 174

def stub_file
  File.write @path, YAML.dump([])
end

#validate_schemaObject



202
203
204
205
206
207
208
209
210
211
# File 'lib/plansheet/project/yaml.rb', line 202

def validate_schema
  validator = Kwalify::Validator.new(Plansheet::PROJECT_SCHEMA)
  errors = validator.validate(@raw)
  # Check YAML validity
  return unless errors && !errors.empty?

  $stderr.write "Schema errors in #{@path}:\n"
  errors.each { |err| puts "- [#{err.path}] #{err.message}" }
  abort
end

#yaml_dump(projects) ⇒ Object



236
237
238
239
240
241
242
243
244
245
246
# File 'lib/plansheet/project/yaml.rb', line 236

def yaml_dump(projects)
  # binding.irb if projects.nil?
  YAML.dump(projects.map do |x|
    x.to_h.delete_if do |k, v|
      # Remove low-value default noise from projects
      k == "namespace" ||
       (k == "priority" && v == "low") ||
       (k == "status" && v == "idea")
    end
  end)
end