# typed: true
# frozen_string_literal: true
require 'frontman/builder/file'
require 'frontman/config'
require 'frontman/concerns/dispatch_events'
require 'frontman/iterator'
require 'sorbet-runtime'
module Frontman
module Builder
class Builder
extend T::Sig
include Frontman::DispatchEvents
attr_accessor :build_directory, :current_build_files, :public_dir
sig { void }
def initialize
@emit_events = true
@build_directory = Dir.pwd + '/build/'
@public_dir = Frontman::Config.get(:public_dir, fallback: 'public/')
@current_build_files = []
end
sig do
params(resource: Frontman::Resource).returns(Frontman::Builder::File)
end
def build_resource(resource)
build_from_content(create_path_from_resource(resource), resource.render)
end
sig do
params(resources: T::Array[Frontman::Resource])
.returns(T::Array[String])
end
def build_from_resources(resources)
# Disable emitting of events, this causes problems when done in parallel
@emit_events = false
opts = { in_processes: (Frontman::Iterator.processor_count / 2).ceil }
resources = Frontman::Iterator.map(resources, opts) do |resource|
build_resource(resource)
end
# After the resources are built, we emit all events synchronously
@emit_events = true
resources.map do |build_file|
fire_build_event(build_file)
build_file.path
end
end
sig do
params(assets_to_build: T::Array[String]).returns(T::Array[String])
end
def build_assets(assets_to_build)
# We need to go through ERB files at the end so assets_manifest filled
assets_to_build.sort_by! { |f| f.end_with?('.erb') ? 1 : 0 }
assets_to_build.map do |path|
public_dir = ::File.join(@public_dir, '')
if path.end_with?('.erb')
build_file = build_from_erb(
path,
path.sub(public_dir, '').gsub('.erb', '')
)
else
build_file = build_from_asset(
path,
path.sub(public_dir, '')
)
end
build_file.path
end
end
sig do
params(path: String, manifest_path: String)
.returns(Frontman::Builder::File)
end
def build_from_asset(path, manifest_path)
target_path = create_target_path(manifest_path)
build_from_content(target_path, ::File.read(path))
end
sig do
params(path: String, manifest_path: String)
.returns(Frontman::Builder::File)
end
def build_from_erb(path, manifest_path)
build_resource(Resource.from_path(path, manifest_path))
end
sig { returns(T::Array[String]) }
def build_redirects
Frontman::App.instance.redirects.map do |from, to|
build_file = build_redirect("#{from}index.html", to)
build_file.path
end
end
sig { params(files_to_delete: T::Array[String]).void }
def delete_files(files_to_delete)
files_to_delete.each do |path|
delete_from_path(path)
end
end
private
sig do
params(destination_path: String, redirect_to: String)
.returns(Frontman::Builder::File)
end
def build_redirect(destination_path, redirect_to)
content = <<~REDIRECT