diff --git a/lib/package_manager.rb b/lib/package_manager.rb new file mode 100644 index 0000000..8218c73 --- /dev/null +++ b/lib/package_manager.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +module ViteRuby::PackageManager + def self.resolve(root:) + package_manager_name = ENV.fetch('VITE_RUBY_PACKAGE_MANAGER', detect_package_manager(root)) + package_manager_class_for(package_manager_name).new(root: root) + end + + def self.package_manager_class_for(package_manager_name) + case package_manager_name.to_sym + when :bun + ViteRuby::PackageManager::Bun + when :pnpm + ViteRuby::PackageManager::Pnpm + when :yarn + ViteRuby::PackageManager::Yarn + else + ViteRuby::PackageManager::Npm + end + end + + def self.detect_package_manager(root) + if root.join('bun.lockb').exist? + :bun + elsif root.join('pnpm-lock.yaml').exist? + :pnpm + elsif root.join('yarn.lock').exist? + :yarn + else + :npm + end + end +end diff --git a/lib/package_manager/base.rb b/lib/package_manager/base.rb new file mode 100644 index 0000000..051ad93 --- /dev/null +++ b/lib/package_manager/base.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +class ViteRuby::PackageManager::Base + attr_reader :root + + def initialize(root: ViteRuby.config.root) + @root = root + end + + # Internal: Returns an Array with the command to run. + def command_for(args) + [config.to_env(env)].tap do |cmd| + args = args.clone + + # Apply runtime arguments for nodejs + if nodejs_runtime? && (args.include?('--inspect') || args.include?('--trace_deprecation')) + cmd.push('node') + cmd.push('--inspect-brk') if args.delete('--inspect') + cmd.push('--trace-deprecation') if args.delete('--trace_deprecation') + end + + # Add vite executable + cmd.push(*vite_executable) + + # Adds vite's arguments + cmd.push(*args) + + # Force `mode`, a vite's argument, to be set + cmd.push('--mode', config.mode) unless args.include?('--mode') || args.include?('-m') + end + end + +private + + def nodejs_runtime? + true + end + + # Internal: Resolves to an executable for Vite. + def vite_executable + bin_path = config.vite_bin_path + [bin_path] if File.exist?(bin_path) + end + + def commands + ViteRuby.commands + end + + def config + ViteRuby.config + end + + def env + ViteRuby.env + end +end diff --git a/lib/package_manager/bun.rb b/lib/package_manager/bun.rb new file mode 100644 index 0000000..5a1268d --- /dev/null +++ b/lib/package_manager/bun.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +module ViteRuby::PackageManager + class Bun < Base + def install_dependencies_command(frozen: true) + frozen ? 'bun install --frozen-lockfile' : 'bun install' + end + + def add_dependencies_command + 'bun install' + end + + private + + def nodejs_runtime? + false + end + + def vite_executable + shimmed_vite_executable = super || ['vite'] + + # Forces a script or package to use Bun's runtime instead of Node.js (via symlinking node) + shimmed_vite_executable.unshift('bun', '--bun') + end + end +end diff --git a/lib/package_manager/npm.rb b/lib/package_manager/npm.rb new file mode 100644 index 0000000..182abd4 --- /dev/null +++ b/lib/package_manager/npm.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +module ViteRuby::PackageManager + class Npm < Base + def install_dependencies_command(frozen: true) + if frozen + commands.legacy_npm_version? ? 'npm ci --yes' : 'npm --yes ci' + else + 'npm install' + end + end + + def add_dependencies_command + 'npm install' + end + + private + + # Internal: Resolves to an executable for Vite. + def vite_executable + super || ["#{ `npm bin`.chomp }/vite"] + end + end +end diff --git a/lib/package_manager/pnpm.rb b/lib/package_manager/pnpm.rb new file mode 100644 index 0000000..3c1c1a7 --- /dev/null +++ b/lib/package_manager/pnpm.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module ViteRuby::PackageManager + class Pnpm < Npm + def install_dependencies_command(*) + 'pnpm install' + end + + def add_dependencies_command + 'pnpm install' + end + end +end diff --git a/lib/package_manager/yarn.rb b/lib/package_manager/yarn.rb new file mode 100644 index 0000000..e0dd62f --- /dev/null +++ b/lib/package_manager/yarn.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module ViteRuby::PackageManager + class Yarn < Base + def install_dependencies_command(frozen: true) + frozen ? 'yarn install --frozen-lockfile' : 'yarn install' + end + + def add_dependencies_command + 'yarn add' + end + + private + + def vite_executable + super || %w[yarn vite] + end + end +end