New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP] language/node: fix prepublish scripts #2820
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,44 @@ | ||
require "json" | ||
|
||
module Language | ||
module Node | ||
def self.npm_cache_config | ||
"cache=#{HOMEBREW_CACHE}/npm_cache" | ||
end | ||
|
||
def self.pack_for_installation | ||
def self.node_system(cmd, *args) | ||
ohai "#{cmd} #{args * " "}" | ||
if ARGV.verbose? | ||
safe_system(cmd, *args) | ||
else | ||
quiet_system(cmd, *args) | ||
raise ErrorDuringExecution.new(cmd, args) unless $CHILD_STATUS.exitstatus.zero? | ||
end | ||
end | ||
|
||
# Read https://gist.github.com/chrmoritz/34e4c4d7779d72b549e2fc41f77c365c | ||
# for a complete overview of the edge cases this method has to handle. | ||
def self.pack_for_installation(prepare_required: false) | ||
# Rewrites the package.json so that npm pack will bundle all deps | ||
# into a self-contained package, so that we avoid installing them a | ||
# second time during the final installation of the package to libexec. | ||
pkg_json = JSON.parse(IO.read("package.json")) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. May be worth producing a nice error message if this file doesn't exist? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What error message do you have in mind here? A There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Replacing the error msg with our own custom one would also hide the actual kind of the IO error: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was thinking any error message that's not a raw exception but you've convinced me this is fine as-is. |
||
if pkg_json["dependencies"] | ||
pkg_json["bundledDependencies"] = pkg_json["dependencies"].keys | ||
IO.write("package.json", JSON.pretty_generate(pkg_json)) | ||
end | ||
|
||
# If `prepare_required` is false we pass `--production` to install all | ||
# production deps (no devDeps) for bundling them into the pack and also | ||
# to prevent the toplevel prepare / prepublish script from being executed | ||
# while still executing all lifecycle scripts for the deps. | ||
# Otherwise we omit `--production` to install all deps (devDeps might be | ||
# required in `prepare`). This already executes the prepare script too, | ||
# so that we can continue to `npm pack` with `--ignore-scripts`. | ||
install_args = local_npm_install_args | ||
install_args << "--production" unless prepare_required | ||
node_system "npm", "install", *install_args | ||
|
||
# Homebrew assumes the buildpath/testpath will always be disposable | ||
# and from npm 5.0.0 the logic changed so that when a directory is | ||
# fed to `npm install` only symlinks are created linking back to that | ||
|
@@ -30,13 +64,13 @@ def self.setup_npm_environment | |
end | ||
end | ||
|
||
def self.std_npm_install_args(libexec) | ||
def self.std_npm_install_args(libexec, prepare_required: false) | ||
setup_npm_environment | ||
# tell npm to not install .brew_home by adding it to the .npmignore file | ||
# (or creating a new one if no .npmignore file already exists) | ||
open(".npmignore", "a") { |f| f.write("\n.brew_home\n") } | ||
|
||
pack = pack_for_installation | ||
pack = pack_for_installation(prepare_required: prepare_required) | ||
|
||
# npm install args for global style module format installed into libexec | ||
%W[ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be good to use the formula system method instead of reimplementing it here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, but how to do so? Using just
system
inside alanguage
will callHomebrew/utils.rb
system and notHomebrew/formula.rb
one.An alternative implementation of this using util's
_system
(basically mixing the implementation ofsafe_system
andquite_system
) would be:There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And speaking about
formula
: Is it possible to access theformula
's downloadurl
insidelanguage/node
? With it we could match it against a npm registry url regex and figure the correct way to handle life cycle scripts out on our own without requiring the formula author to set theprepare_require
parameter.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The formula object can be passed through as an argument or this module could be included inside the formula itself. That'll handle both of these cases.