Skip to content

Commit

Permalink
reword installer
Browse files Browse the repository at this point in the history
  • Loading branch information
elbywan committed Oct 14, 2024
1 parent 198a518 commit d26d329
Show file tree
Hide file tree
Showing 36 changed files with 164 additions and 153 deletions.
12 changes: 6 additions & 6 deletions packages/backend/backend.cr
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ require "./hardlink"
require "./symlink"

module Backend
def self.install(*, dependency : Data::Package, target : Path | String, backend : Backends, store : Store, &on_installing) : Bool
def self.link(*, dependency : Data::Package, target : Path | String, backend : Backends, store : Store, &on_installing) : Bool
src_path, dest_path, already_installed = self.prepare(dependency, target, store: store)
return false if already_installed

Expand All @@ -139,22 +139,22 @@ module Backend
case backend
in .clone_file?
{% if flag?(:darwin) %}
Backend::CloneFile.install(src_path, dest_path)
Backend::CloneFile.link(src_path, dest_path)
{% else %}
raise "The clonefile backend is not supported on this platform"
{% end %}
in .copy_file?
{% if flag?(:darwin) %}
Backend::CopyFile.install(src_path, dest_path)
Backend::CopyFile.link(src_path, dest_path)
{% else %}
raise "The copyfile backend is not supported on this platform"
{% end %}
in .hardlink?
Backend::Hardlink.install(src_path, dest_path)
Backend::Hardlink.link(src_path, dest_path)
in .copy?
Backend::Copy.install(src_path, dest_path)
Backend::Copy.link(src_path, dest_path)
in .symlink?
Backend::Symlink.install(src_path, dest_path)
Backend::Symlink.link(src_path, dest_path)
end
end
end
2 changes: 1 addition & 1 deletion packages/backend/clonefile.cr
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
require "extensions/libc/clonefile"

module Backend::CloneFile
def self.install(src_path : String | Path, dest_path : String | Path) : Bool
def self.link(src_path : String | Path, dest_path : String | Path) : Bool
result = LibC.clonefile(src_path.to_s, dest_path.to_s, 0)
if result == -1
raise "Error cloning file: #{Errno.value} #{src_path.to_s} -> #{dest_path.to_s}"
Expand Down
2 changes: 1 addition & 1 deletion packages/backend/copy.cr
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
require "concurrency/pipeline"

module Backend::Copy
def self.install(src_path : String | Path, dest_path : String | Path) : Bool
def self.link(src_path : String | Path, dest_path : String | Path) : Bool
# FileUtils.cp_r(src_path, dest_path)
Pipeline.wrap(force_wait: true) do |pipeline|
Backend.recursively(src_path.to_s, dest_path.to_s, pipeline: pipeline) do |src, dest|
Expand Down
2 changes: 1 addition & 1 deletion packages/backend/copyfile.cr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ require "extensions/libc/copyfile"
require "concurrency/pipeline"

module Backend::CopyFile
def self.install(src_path : String | Path, dest_path : String | Path) : Bool
def self.link(src_path : String | Path, dest_path : String | Path) : Bool
Pipeline.wrap(force_wait: true) do |pipeline|
Backend.recursively(src_path.to_s, dest_path.to_s, pipeline) do |src, dest|
LibC.copyfile(src.to_s, dest.to_s, nil, LibC::COPYFILE_CLONE_FORCE | LibC::COPYFILE_ALL)
Expand Down
2 changes: 1 addition & 1 deletion packages/backend/hardlink.cr
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
require "concurrency/pipeline"

module Backend::Hardlink
def self.install(src_path : String | Path, dest_path : String | Path) : Bool
def self.link(src_path : String | Path, dest_path : String | Path) : Bool
Pipeline.wrap(force_wait: true) do |pipeline|
Backend.recursively(src_path.to_s, dest_path.to_s, pipeline: pipeline) do |src, dest|
File.link(src, dest)
Expand Down
2 changes: 1 addition & 1 deletion packages/backend/symlink.cr
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
require "concurrency/pipeline"

module Backend::Symlink
def self.install(src_path : String | Path, dest_path : String | Path) : Bool
def self.link(src_path : String | Path, dest_path : String | Path) : Bool
Pipeline.wrap do |pipeline|
Backend.recursively(src_path.to_s, dest_path.to_s, pipeline: pipeline) do |src, dest|
File.symlink(src, dest)
Expand Down
50 changes: 25 additions & 25 deletions packages/commands/install/install.cr
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ require "data/package/scripts"
require "./config"
require "./state"
require "./resolver"
require "./installer"
require "./installer/classic"
require "./installer/isolated"
require "./installer/pnp"
require "./linker"
require "./linker/classic"
require "./linker/isolated"
require "./linker/pnp"

module Commands::Install
alias Pipeline = Concurrency::Pipeline
Expand Down Expand Up @@ -126,10 +126,10 @@ module Commands::Install
end

# Install dependencies to the appropriate node_modules folder
installer = install_packages(state, pruned_direct_dependencies)
linker = link_packages(state, pruned_direct_dependencies)

# Run package.json hooks for the installed packages
run_install_hooks(state, installer)
run_install_hooks(state, linker)

# Run package.json hooks for the workspace packages
run_own_install_hooks(state)
Expand Down Expand Up @@ -369,37 +369,37 @@ module Commands::Install
end
end

private def self.install_packages(state : State, pruned_direct_dependencies)
state.reporter.report_installer_updates do
installer = case state.install_config.strategy
when .isolated?
Installer::Isolated.new(state)
when .classic?, .classic_shallow?
Installer::Classic.new(state)
when .pnp?
Installer::PnP.new(state)
else
raise "Unsupported install strategy: #{state.install_config.strategy}"
end
private def self.link_packages(state : State, pruned_direct_dependencies)
state.reporter.report_linker_updates do
linker = case state.install_config.strategy
when .isolated?
Linker::Isolated.new(state)
when .classic?, .classic_shallow?
Linker::Classic.new(state)
when .pnp?
Linker::PnP.new(state)
else
raise "Unsupported install strategy: #{state.install_config.strategy}"
end
Log.debug { "• Pruning previous install" }
installer.remove(pruned_direct_dependencies)
installer.prune_orphan_modules
linker.remove(pruned_direct_dependencies)
linker.prune_orphan_modules
Log.debug { "• Installing packages" }
installer.install
installer
linker.install
linker
end
end

private def self.run_install_hooks(state : State, installer : Installer::Base)
private def self.run_install_hooks(state : State, linker : Linker::Base)
Log.debug { "• Running install hooks" }
if !state.install_config.ignore_scripts && installer.installed_packages_with_hooks.size > 0
if !state.install_config.ignore_scripts && linker.installed_packages_with_hooks.size > 0
error_messages = [] of {Exception, String}
state.pipeline.reset
# Process hooks in parallel
state.pipeline.set_concurrency(state.config.concurrency)
begin
state.reporter.report_builder_updates do
installer.installed_packages_with_hooks.each do |package, path|
linker.installed_packages_with_hooks.each do |package, path|
package.scripts.try do |scripts|
state.pipeline.process do
state.reporter.on_building_package
Expand Down
15 changes: 0 additions & 15 deletions packages/commands/install/installer/isolated/writer/registry.cr

This file was deleted.

15 changes: 0 additions & 15 deletions packages/commands/install/installer/pnp/writer/registry.cr

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
require "../installer"
require "../linker"

class Commands::Install::Installer::Classic < Commands::Install::Installer::Base
class Commands::Install::Linker::Classic < Commands::Install::Linker::Base
record DependencyItem,
# the dependency to install
dependency : Data::Package,
Expand Down Expand Up @@ -136,23 +136,23 @@ class Commands::Install::Installer::Classic < Commands::Install::Installer::Base
ancestors_str = dependency_item.ancestors ? dependency_item.ancestors.map { |a| "#{a.name}@#{a.version}" }.join("~>") : ""
package_in_error = dependency ? "#{dependency_item.alias.try &.+(":")}#{dependency.name}@#{dependency.version}" : ""
state.reporter.error(e, "#{package_in_error.colorize.bold} (#{ancestors_str}) at #{parent_path.colorize.dim}")
exit Shared::Constants::ErrorCodes::INSTALLER_ERROR.to_i32
exit Shared::Constants::ErrorCodes::LINKER_ERROR.to_i32
end
end
end

private def install_dependency(dependency : Data::Package, *, location : LocationNode, ancestors : Array(Data::Package), aliased_name : String?) : Writer::InstallResult
writer = case dependency.kind
in .tarball_file?, .link?
Writer::File.new(dependency, installer: self, location: location, state: state, ancestors: ancestors, aliased_name: aliased_name)
Writer::File.new(dependency, linker: self, location: location, state: state, ancestors: ancestors, aliased_name: aliased_name)
in .tarball_url?
Writer::Tarball.new(dependency, installer: self, location: location, state: state, ancestors: ancestors, aliased_name: aliased_name)
Writer::Tarball.new(dependency, linker: self, location: location, state: state, ancestors: ancestors, aliased_name: aliased_name)
in .git?
Writer::Git.new(dependency, installer: self, location: location, state: state, ancestors: ancestors, aliased_name: aliased_name)
Writer::Git.new(dependency, linker: self, location: location, state: state, ancestors: ancestors, aliased_name: aliased_name)
in .registry?
registry_writer = Writer::Registry.new(
dependency,
installer: self,
linker: self,
location: location,
state: state,
ancestors: ancestors,
Expand All @@ -161,14 +161,14 @@ class Commands::Install::Installer::Classic < Commands::Install::Installer::Base
return {nil, false} unless registry_writer
registry_writer
in .workspace?
Writer::Workspace.new(dependency, installer: self, location: location, state: state, ancestors: ancestors, aliased_name: aliased_name)
Writer::Workspace.new(dependency, linker: self, location: location, state: state, ancestors: ancestors, aliased_name: aliased_name)
end

writer.install
end

# Actions to perform after the dependency has been freshly installed.
def on_install(dependency : Data::Package, install_folder : Path, *, state : Commands::Install::State, location : LocationNode, ancestors : Array(Data::Package))
def on_link(dependency : Data::Package, install_folder : Path, *, state : Commands::Install::State, location : LocationNode, ancestors : Array(Data::Package))
# Store package metadata
unless File.symlink?(install_folder)
File.open(install_folder / Shared::Constants::METADATA_FILE_NAME, "w") do |f|
Expand Down Expand Up @@ -226,7 +226,7 @@ class Commands::Install::Installer::Classic < Commands::Install::Installer::Base
end

# Report that this package has been installed
state.reporter.on_package_installed
state.reporter.on_package_linked
end
end

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
class Commands::Install::Installer::Classic
require "./writer"

class Commands::Install::Linker::Classic
struct Writer::File < Writer
def install : InstallResult
case dist = @dependency.dist
Expand All @@ -22,11 +24,11 @@ class Commands::Install::Installer::Classic
if exists
{nil, false}
else
state.reporter.on_installing_package
state.reporter.on_linking_package
Utils::Directories.mkdir_p(target_path.dirname)
FileUtils.rm_rf(target_path) if ::File.directory?(target_path)
::File.symlink(link_source, target_path)
installer.on_install(dependency, target_path, state: state, location: location, ancestors: ancestors)
linker.on_link(dependency, target_path, state: state, location: location, ancestors: ancestors)
{nil, true}
end
end
Expand All @@ -42,7 +44,7 @@ class Commands::Install::Installer::Classic
else
Utils::Directories.mkdir_p(target_path.dirname)
extracted_folder = Path.new(dist.path)
state.reporter.on_installing_package
state.reporter.on_linking_package

# TODO :Double check if this is really needed?
#
Expand All @@ -66,7 +68,7 @@ class Commands::Install::Installer::Classic
# end

FileUtils.cp_r(extracted_folder, target_path)
installer.on_install(dependency, target_path, state: state, location: location, ancestors: ancestors)
linker.on_link(dependency, target_path, state: state, location: location, ancestors: ancestors)
{install_location, true}
end
end
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
class Commands::Install::Installer::Classic
require "./writer"

class Commands::Install::Linker::Classic
struct Writer::Git < Writer
def install : InstallResult
unless packed_tarball_path = dependency.dist.try &.as(Data::Package::Dist::Git).cache_key.try { |key| state.store.package_path(dependency).to_s + ".tgz" }
Expand All @@ -14,11 +16,11 @@ class Commands::Install::Installer::Classic
{install_location, false}
else
Utils::Directories.mkdir_p(target_path.dirname)
state.reporter.on_installing_package
state.reporter.on_linking_package
::File.open(packed_tarball_path, "r") do |tarball|
Utils::TarGzip.unpack_to(tarball, target_path)
end
installer.on_install(dependency, target_path, state: state, location: location, ancestors: ancestors)
linker.on_link(dependency, target_path, state: state, location: location, ancestors: ancestors)
{install_location, true}
end
end
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
class Commands::Install::Installer::Classic
require "./writer"

class Commands::Install::Linker::Classic
struct Writer::Registry < Writer
def hoist : self?
if skip_hoisting?
Expand Down Expand Up @@ -28,23 +30,23 @@ class Commands::Install::Installer::Classic
location: location,
ancestors: self.ancestors,
aliased_name: self.aliased_name,
installer: self.installer
linker: self.linker
)
end

def install : InstallResult
installation_path = location.value.node_modules / (aliased_name || dependency.name)
installed = begin
Backend.install(dependency: dependency, target: installation_path, store: state.store, backend: state.config.file_backend) {
state.reporter.on_installing_package
Backend.link(dependency: dependency, target: installation_path, store: state.store, backend: state.config.file_backend) {
state.reporter.on_linking_package
}
rescue ex
state.reporter.log(%(#{aliased_name.try &.+(":")}#{(dependency.name + '@' + dependency.version).colorize.yellow} Failed to install with #{state.config.file_backend} backend: #{ex.message}))
# Fallback to the widely supported "plain copy" backend
Backend.install(backend: :copy, dependency: dependency, target: installation_path, store: state.store) { }
Backend.link(backend: :copy, dependency: dependency, target: installation_path, store: state.store) { }
end

installer.on_install(dependency, installation_path, state: state, location: location, ancestors: ancestors) if installed
linker.on_link(dependency, installation_path, state: state, location: location, ancestors: ancestors) if installed
{self.class.init_location(dependency, installation_path, location), installed}
end

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
class Commands::Install::Installer::Classic
require "./writer"

class Commands::Install::Linker::Classic
struct Writer::Tarball < Writer
def install : InstallResult
install_folder = aliased_name || dependency.name
Expand All @@ -11,10 +13,10 @@ class Commands::Install::Installer::Classic
else
Utils::Directories.mkdir_p(target_path.dirname)
extracted_folder = Path.new(dependency.dist.as(Data::Package::Dist::Tarball).path)
state.reporter.on_installing_package
state.reporter.on_linking_package

FileUtils.cp_r(extracted_folder, target_path)
installer.on_install(dependency, target_path, state: state, location: location, ancestors: ancestors)
linker.on_link(dependency, target_path, state: state, location: location, ancestors: ancestors)
{install_location, true}
end
end
Expand Down
Loading

0 comments on commit d26d329

Please sign in to comment.