class StandupMD::File

Class for handling reading and writing standup files.

Attributes

entries[R]

The list of entries in the file.

@return [StandupMP::EntryList]

name[R]

The name of the file.

@return [String]

Public Class Methods

config() click to toggle source

Access to the class's configuration.

@return [StandupMD::Config::EntryList]

# File lib/standup_md/file.rb, line 17
def self.config
  @config ||= StandupMD.config.file
end
find(file_name) click to toggle source

Find standup file in directory by file name.

@param [String] File_naem

# File lib/standup_md/file.rb, line 40
def self.find(file_name)
  unless ::File.directory?(config.directory)
    raise "Dir #{config.directory} not found." unless config.create

    FileUtils.mkdir_p(config.directory)
  end
  file = Dir.entries(config.directory).bsearch { |f| f == file_name }
  raise "File #{file_name} not found." if file.nil? && !config.create

  new(file_name)
end
find_by_date(date) click to toggle source

Find standup file in directory by Date object.

@param [Date] date

# File lib/standup_md/file.rb, line 56
def self.find_by_date(date)
  raise ArgumentError, 'Must be a Date object' unless date.is_a?(Date)

  unless ::File.directory?(config.directory)
    raise "Dir #{config.directory} not found." unless config.create

    FileUtils.mkdir_p(config.directory)
  end
  find(date.strftime(config.name_format))
end
load(file_name) click to toggle source

Convenience method for calling File.find(file_name).load

@param [String] file_name

@return [StandupMD::File]

# File lib/standup_md/file.rb, line 27
def self.load(file_name)
  unless ::File.directory?(config.directory)
    raise "Dir #{config.directory} not found." unless config.create

    FileUtils.mkdir_p(config.directory)
  end
  new(file_name).load
end
new(file_name) click to toggle source

Constructs the instance.

@param [String] file_name

@return [StandupMP::File]

# File lib/standup_md/file.rb, line 85
def initialize(file_name)
  @config = self.class.config
  if file_name.include?(::File::SEPARATOR)
    raise ArgumentError,
      "#{file_name} contains directory. Please use `StandupMD.config.file.directory=`"
  end

  unless ::File.directory?(@config.directory)
    raise "Dir #{@config.directory} not found." unless @config.create

    FileUtils.mkdir_p(@config.directory)
  end

  @name = ::File.expand_path(::File.join(@config.directory, file_name))

  unless ::File.file?(@name)
    raise "File #{@name} not found." unless @config.create

    FileUtils.touch(@name)
  end

  @new = ::File.zero?(@name)
  @loaded = false
end

Public Instance Methods

exist?() click to toggle source

Does the file exist?

@return [Boolean] true if exists

# File lib/standup_md/file.rb, line 130
def exist?
  ::File.exist?(name)
end
load() click to toggle source

Loads the file's contents. TODO clean up this method.

@return [StandupMD::FileList]

# File lib/standup_md/file.rb, line 139
def load
  raise "File #{name} does not exist." unless ::File.file?(name)

  entry_list = EntryList.new
  record = {}
  section_type = ''
  ::File.foreach(name) do |line|
    line.chomp!
    next if line.strip.empty?

    if header?(line)
      unless record.empty?
        entry_list << new_entry(record)
        record = {}
      end
      record['header'] = line.sub(/^\#{#{@config.header_depth}}\s*/, '')
      section_type = @config.notes_header
      record[section_type] = []
    elsif sub_header?(line)
      section_type = determine_section_type(line)
      record[section_type] = []
    else
      record[section_type] << line.sub(bullet_character_regex, '')
    end
  end
  entry_list << new_entry(record) unless record.empty?
  @loaded = true
  @entries = entry_list.sort
  self
rescue => e
  raise "File malformation: #{e}"
end
loaded?() click to toggle source

Has the file been loaded?

@return [Boolean] true if loaded

# File lib/standup_md/file.rb, line 122
def loaded?
  @loaded
end
new?() click to toggle source

Was the file just now created?

@return [Boolean] true if new

# File lib/standup_md/file.rb, line 114
def new?
  @new
end
write(**dates) click to toggle source

Writes a new entry to the file if the first entry in the file isn't today. This method is destructive; if a file for entries in the date range already exists, it will be clobbered with the entries in the range.

@param [Hash] {start_date: Date, end_date: Date}

@return [Boolean] true if successful

# File lib/standup_md/file.rb, line 180
def write(**dates)
  sorted_entries = entries.sort
  start_date = dates.fetch(:start_date, sorted_entries.first.date)
  end_date = dates.fetch(:end_date, sorted_entries.last.date)
  ::File.open(name, 'w') do |f|
    sorted_entries.filter(start_date, end_date).sort_reverse.each do |entry|
      f.puts header(entry.date)
      @config.sub_header_order.each do |attr|
        tasks = entry.public_send(attr)
        next if !tasks || tasks.empty?

        f.puts sub_header(@config.public_send("#{attr}_header").capitalize)
        tasks.each { |task| f.puts @config.bullet_character + ' ' + task }
      end
      f.puts
    end
  end
  true
end