class Pith::Project

Attributes

config_provider[R]
input_dir[R]
logger[RW]
output_dir[R]

Public Class Methods

new(input_dir, output_dir = nil, attributes = {}) click to toggle source
# File lib/pith/project.rb, line 15
def initialize(input_dir, output_dir = nil, attributes = {})
  @input_dir = Pathname(input_dir)
  @output_dir = output_dir ? Pathname(output_dir) : (@input_dir + "_out")
  @logger = Logger.new(nil)
  attributes.each do |k,v|
    send("#{k}=", v)
  end
  @input_map = {}
  @output_map = {}
  @mtimes ||= {}
  @config_provider ||= Pith::ConfigProvider.new(self)
  @mutex = Mutex.new
end

Public Instance Methods

build() click to toggle source

Public: build the project, generating output files.

# File lib/pith/project.rb, line 72
def build
  sync
  output_dir.mkpath
  outputs.each(&:build)
  output_dir.touch
end
config() click to toggle source
# File lib/pith/project.rb, line 111
def config
  config_provider.config
end
has_errors?() click to toggle source

Public: check for errors.

Returns true if any errors were encountered during the last build.

# File lib/pith/project.rb, line 100
def has_errors?
  outputs.any?(&:error)
end
input(path) click to toggle source

Public: find an input.

path - an path relative to input_dir

Returns the first input whose path matches. Returns nil if no match is found.

# File lib/pith/project.rb, line 55
def input(path)
  @input_map[Pathname(path)]
end
inputs() click to toggle source

Public: get inputs

Returns Pith::Input objects representing the files in the input_dir.

# File lib/pith/project.rb, line 36
def inputs
  @input_map.values
end
last_built_at() click to toggle source
# File lib/pith/project.rb, line 104
def last_built_at
  output_dir.mtime
end
listen_for_changes() click to toggle source

Public: start a Thread to automatically sync when inputs change.

# File lib/pith/project.rb, line 91
def listen_for_changes
  Listen.to(input_dir.to_s) do
    sync
  end.start
end
output(path) click to toggle source

Public: find an output.

path - an path relative to output_dir

Returns the first output whose path matches. Returns nil if no match is found.

# File lib/pith/project.rb, line 66
def output(path)
  @output_map[Pathname(path)]
end
outputs() click to toggle source

Public: get outputs

Returns Pith::Output objects representing the files in the output_dir.

# File lib/pith/project.rb, line 44
def outputs
  inputs.map(&:output).compact
end
published_inputs() click to toggle source

Return all the published inputs, in order of publication.

# File lib/pith/plugins/publication/project.rb, line 10
def published_inputs
  inputs.select { |i| i.published? }.sort_by { |i| i.published_at }
end
sync() click to toggle source

Public: re-sync with the file-system.

# File lib/pith/project.rb, line 81
def sync
  @mutex.synchronize do
    config_provider.sync
    sync_input_files
    cleanup_output_files
  end
end

Private Instance Methods

cleanup_output_files() click to toggle source
# File lib/pith/project.rb, line 142
def cleanup_output_files
  Pathname.glob(output_dir + "**/*", File::FNM_DOTMATCH) do |file|
    next unless file.file?
    path = file.relative_path_from(output_dir)
    unless output(path)
      logger.info "XXX #{path}"
      FileUtils.rm_f(file)
    end
  end
end
file_added(path) click to toggle source
# File lib/pith/project.rb, line 153
def file_added(path)
  i = Input.new(self, path)
  i.when_added
  @input_map[path] = i
  if o = i.output
    @output_map[o.path] = o
  end
end
file_modified(path) click to toggle source
# File lib/pith/project.rb, line 162
def file_modified(path)
  @input_map[path].when_modified
end
file_removed(path) click to toggle source
# File lib/pith/project.rb, line 166
def file_removed(path)
  i = @input_map.delete(path)
  i.when_removed
  if o = i.output
    @output_map.delete(o.path)
  end
end
sync_input_files() click to toggle source
# File lib/pith/project.rb, line 119
def sync_input_files
  removed_paths = @mtimes.keys
  Pathname.glob(input_dir + "**/*", File::FNM_DOTMATCH) do |file|
    next unless file.file?
    next if file.in?(output_dir)
    mtime = file.mtime
    path = file.relative_path_from(input_dir)
    if @mtimes.has_key?(path)
      if @mtimes[path] < mtime
        file_modified(path)
      end
    else
      file_added(path)
    end
    @mtimes[path] = mtime
    removed_paths.delete(path)
  end
  removed_paths.each do |path|
    @mtimes.delete(path)
    file_removed(path)
  end
end