Class: Shakapacker::Utils::Manager

Inherits:
Object
  • Object
show all
Defined in:
lib/shakapacker/utils/manager.rb

Defined Under Namespace

Classes: Error

Constant Summary collapse

MANAGER_LOCKS =
{
  "bun" => "bun.lockb",
  "npm" => "package-lock.json",
  "pnpm" => "pnpm-lock.yaml",
  "yarn" => "yarn.lock"
}

Class Method Summary collapse

Class Method Details

.error_unless_package_manager_is_obvious!Object

Emits a warning if it’s not obvious what package manager to use

Raises:



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/shakapacker/utils/manager.rb', line 18

def self.error_unless_package_manager_is_obvious!
  return unless PackageJson.read(rails_root).fetch("packageManager", nil).nil?

  guessed_binary = guess_binary

  return if guessed_binary == "npm"

  raise Error, "    You don't have \"packageManager\" set in your package.json\n    meaning that Shakapacker will use npm but you've got a \#{MANAGER_LOCKS[guessed_binary]}\n    file meaning you probably want to be using \#{guessed_binary} instead.\n\n    To make this happen, set \"packageManager\" in your package.json to \#{guessed_binary}@\#{guess_version}\n  MSG\nend\n"

.guess_binaryString

Guesses the binary of the package manager to use based on what lockfiles exist

Returns:

  • (String)


37
38
39
# File 'lib/shakapacker/utils/manager.rb', line 37

def self.guess_binary
  MANAGER_LOCKS.find { |_, lock| File.exist?(rails_root.join(lock)) }&.first || "npm"
end

.guess_versionString

Guesses the version of the package manager to use by calling ‘<manager> –version`

Returns:

  • (String)


44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/shakapacker/utils/manager.rb', line 44

def self.guess_version
  require "open3"

  command = "#{guess_binary} --version"
  stdout, stderr, status = Open3.capture3(command)

  unless status.success?
    raise Error, "#{command} failed with exit code #{status.exitstatus}: #{stderr}"
  end

  stdout.chomp
end

.rails_rootObject



58
59
60
61
62
63
64
65
66
67
68
# File 'lib/shakapacker/utils/manager.rb', line 58

def self.rails_root
  if defined?(APP_ROOT)
    Pathname.new(APP_ROOT)
  elsif ENV["APP_ROOT"]
    Pathname.new(ENV["APP_ROOT"])
  elsif defined?(Rails)
    Rails.root
  else
    raise "can only be called from a rails environment or with APP_ROOT defined"
  end
end