Skip to content
This repository was archived by the owner on Jan 16, 2025. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 42 additions & 7 deletions Library/Formula/iojs.rb
Original file line number Diff line number Diff line change
@@ -1,37 +1,64 @@
require "language/javascript"

class Iojs < Formula
include Language::JS
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just call these method with the full paths instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I lazily took advantage of the extended scope. I'll have to sort out passing the correct methods and variable to get them to work. I'll peek at it tomorrow.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MikeMcQuaid Can you give me an example of what you were thinking? My knowledge of ruby's class system is failing me. I gave it a shot here: bcomnes@53b7c47

Is there a way to more explicitly call mixin functions, or did you not want to use a mixin in this situation?

It works, but it seems like this way loses the scope of the formula its called in and I have to pass in all local variables and utility functions. npm's verbose output starts to leak to stdout as well. Any ideas?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeh, bcomnes@53b7c47 makes sense to me. I think losing the scope is a feature there (stops being as coupled to the Formula API). @xu-cheng previously handled the stdout leaking case but I can't quite remember how; I'm sure he'll be able to elaborate.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This stdout leaking is caused by losing the scope. You are actually calling Kernel.system instead of Formula.system.

The right solution is leaving include Language::JS as it is. We did the same thing in Haskell(e.g. pandoc.rb).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I remember we talked about exposing Formula.system's behaviour elsewhere? Did we ever do that? If not: maybe this is a good time to do so?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did we ever do that?

I don't know. @jacknagel should know more than I do.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we didn't. Yeh, can leave it as an include for now and I'll add that to my TODO list.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd be happy to go back and update it to decouple from the Formula API in the future once the correct stdout containment ingredients are in place.

Leaving it as a mixin for now.


homepage "https://iojs.org/"
url "https://iojs.org/dist/v1.8.1/iojs-v1.8.1.tar.xz"
sha256 "8b9b4a141daca22e6bf28e8af86ce5f9ca5918d08923fb5619b7e614a674d966"
url "https://iojs.org/dist/v2.0.0/iojs-v2.0.0.tar.xz"
sha256 "4f61318361b752382f13cad631548677f7ec2ba21b3dc4c3cca2369a7e253baa"

bottle do
sha256 "e535a806b9090b4ba229b4a724fd00a44f9df26f9614eb5cac6739376a9fd0b9" => :yosemite
sha256 "e8a671371dfc9adaeea54b4410929ca4bafe9f62bc6b036f0f08f3c278409036" => :mavericks
sha256 "023b19b7fa74a044a358157abdcab628c272860ecd9f12be5ac6aa3cce41da01" => :mountain_lion
end

keg_only "iojs conflicts with node (which is currently more established)"
conflicts_with "node", :because => "node and iojs both install a binary/link named node"

option "with-debug", "Build with debugger hooks"
option "with-icu4c", "Build with Intl (icu4c) support"
option "without-npm", "npm will not be installed"
option "without-completion", "npm bash completion will not be installed"

depends_on "pkg-config" => :build
depends_on "icu4c" => :optional
depends_on :python => :build

resource "npm" do
url Language::JS::NPM_URL
sha256 Language::JS::NPM_SHA256
end

def install
args = %W[--prefix=#{prefix} --without-npm]
args << "--debug" if build.with? "debug"
args << "--with-intl=system-icu" if build.with? "icu4c"

system "./configure", *args
system "make", "install"

if build.with? "npm"
resource("npm").stage npm_buildpath = buildpath/"npm_install"
install_npm npm_buildpath

if build.with? "completion"
install_npm_bash_completion npm_buildpath
end
end
end

def caveats; <<-EOS.undent
iojs was installed without npm.
def post_install
return if build.without? "npm"

iojs currently requires a patched npm (i.e. not the npm installed by node).
EOS
npm_post_install libexec
end

def caveats
s = ""

s += npm_caveats

s
end

test do
Expand All @@ -41,5 +68,13 @@ def caveats; <<-EOS.undent
output = `#{bin}/iojs #{path}`.strip
assert_equal "hello", output
assert_equal 0, $?.exitstatus

if build.with? "npm"
# make sure npm can find node
ENV.prepend_path "PATH", opt_bin
assert_equal which("node"), opt_bin/"node"
npm_test_install
end
end
end

67 changes: 14 additions & 53 deletions Library/Formula/node.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
require "language/javascript"

# Note that x.even are stable releases, x.odd are devel releases
class Node < Formula
include Language::JS

homepage "https://nodejs.org/"
url "https://nodejs.org/dist/v0.12.2/node-v0.12.2.tar.gz"
sha256 "ac7e78ade93e633e7ed628532bb8e650caba0c9c33af33581957f3382e2a772d"
Expand All @@ -12,6 +16,8 @@ class Node < Formula
sha256 "cde73f7ca5b2c080bb8e7d5b99fa02ac43908ec8ad24ef52d9a3a44141ffbe75" => :mountain_lion
end

conflicts_with "iojs", :because => "node and iojs both install a binary/link named node"

option "with-debug", "Build with debugger hooks"
option "without-npm", "npm will not be installed"
option "without-completion", "npm bash completion will not be installed"
Expand All @@ -31,8 +37,8 @@ class Node < Formula
end

resource "npm" do
url "https://registry.npmjs.org/npm/-/npm-2.7.6.tgz"
sha256 "a9445167f68a42ffcdaa36f9f5c14a954237fce6898555c362e8785261fd72a1"
url Language::JS::NPM_URL
sha256 Language::JS::NPM_SHA256
end

def install
Expand All @@ -50,68 +56,25 @@ def install
system "make", "install"

if build.with? "npm"
resource("npm").stage buildpath/"npm_install"

# make sure npm can find node
ENV.prepend_path "PATH", bin
# make sure user prefix settings in $HOME are ignored
ENV["HOME"] = buildpath/"home"
# set log level temporarily for npm's `make install`
ENV["NPM_CONFIG_LOGLEVEL"] = "verbose"

cd buildpath/"npm_install" do
system "./configure", "--prefix=#{libexec}/npm"
system "make", "install"
end
resource("npm").stage npm_buildpath = buildpath/"npm_install"
install_npm npm_buildpath

if build.with? "completion"
bash_completion.install \
buildpath/"npm_install/lib/utils/completion.sh" => "npm"
install_npm_bash_completion npm_buildpath
end
end
end

def post_install
return if build.without? "npm"

node_modules = HOMEBREW_PREFIX/"lib/node_modules"
node_modules.mkpath
npm_exec = node_modules/"npm/bin/npm-cli.js"
# Kill npm but preserve all other modules across node updates/upgrades.
rm_rf node_modules/"npm"

cp_r libexec/"npm/lib/node_modules/npm", node_modules
# This symlink doesn't hop into homebrew_prefix/bin automatically so
# remove it and make our own. This is a small consequence of our bottle
# npm make install workaround. All other installs **do** symlink to
# homebrew_prefix/bin correctly. We ln rather than cp this because doing
# so mimics npm's normal install.
ln_sf npm_exec, "#{HOMEBREW_PREFIX}/bin/npm"

# Let's do the manpage dance. It's just a jump to the left.
# And then a step to the right, with your hand on rm_f.
["man1", "man3", "man5", "man7"].each do |man|
# Dirs must exist first: https://github.com/Homebrew/homebrew/issues/35969
mkdir_p HOMEBREW_PREFIX/"share/man/#{man}"
rm_f Dir[HOMEBREW_PREFIX/"share/man/#{man}/{npm.,npm-,npmrc.}*"]
ln_sf Dir[libexec/"npm/share/man/#{man}/npm*"], HOMEBREW_PREFIX/"share/man/#{man}"
end

npm_root = node_modules/"npm"
npmrc = npm_root/"npmrc"
npmrc.atomic_write("prefix = #{HOMEBREW_PREFIX}\n")
npm_post_install libexec
end

def caveats
s = ""

if build.without? "npm"
s += <<-EOS.undent
Homebrew has NOT installed npm. If you later install it, you should supplement
your NODE_PATH with the npm module folder:
#{HOMEBREW_PREFIX}/lib/node_modules
EOS
end
s += npm_caveats

if build.with? "icu4c"
s += <<-EOS.undent
Expand Down Expand Up @@ -140,9 +103,7 @@ def caveats
# make sure npm can find node
ENV.prepend_path "PATH", opt_bin
assert_equal which("node"), opt_bin/"node"
assert (HOMEBREW_PREFIX/"bin/npm").exist?, "npm must exist"
assert (HOMEBREW_PREFIX/"bin/npm").executable?, "npm must be executable"
system "#{HOMEBREW_PREFIX}/bin/npm", "--verbose", "install", "npm@latest"
npm_test_install
end
end
end
87 changes: 87 additions & 0 deletions Library/Homebrew/language/javascript.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
module Language
module JS

NPM_URL = "https://registry.npmjs.org/npm/-/npm-2.9.0.tgz"
NPM_SHA256 = "a4d1434e934eaf08d985dbe3b70e0d456fb6866828afc91e99b3aac286fca055"

def install_npm(path)
# make sure npm can find node
ENV.prepend_path "PATH", bin
# make sure user prefix settings in $HOME are ignored
ENV["HOME"] = buildpath/"home"
# set log level temporarily for npm's `make install`
ENV["NPM_CONFIG_LOGLEVEL"] = "verbose"

cd path do
system "./configure", "--prefix=#{libexec}/npm"
system "make", "install"
end
end

def install_npm_bash_completion (path)
bash_completion.install \
path/"lib/utils/completion.sh" => "npm"
end

def npm_post_install(libexec)
node_modules = HOMEBREW_PREFIX/"lib/node_modules"
node_modules.mkpath
npm_exec = node_modules/"npm/bin/npm-cli.js"
# Kill npm but preserve all other modules across node updates/upgrades.
rm_rf node_modules/"npm"

cp_r libexec/"npm/lib/node_modules/npm", node_modules
# This symlink doesn't hop into homebrew_prefix/bin automatically so
# remove it and make our own. This is a small consequence of our bottle
# npm make install workaround. All other installs **do** symlink to
# homebrew_prefix/bin correctly. We ln rather than cp this because doing
# so mimics npm's normal install.
ln_sf npm_exec, "#{HOMEBREW_PREFIX}/bin/npm"

# Let's do the manpage dance. It's just a jump to the left.
# And then a step to the right, with your hand on rm_f.
["man1", "man3", "man5", "man7"].each do |man|
# Dirs must exist first: https://github.com/Homebrew/homebrew/issues/35969
mkdir_p HOMEBREW_PREFIX/"share/man/#{man}"
rm_f Dir[HOMEBREW_PREFIX/"share/man/#{man}/{npm.,npm-,npmrc.}*"]
ln_sf Dir[libexec/"npm/share/man/#{man}/npm*"], HOMEBREW_PREFIX/"share/man/#{man}"
end

npm_root = node_modules/"npm"
npmrc = npm_root/"npmrc"
npmrc.atomic_write("prefix = #{HOMEBREW_PREFIX}\n")
end

def npm_caveats
s = ""

if build.without? "npm"
s += <<-EOS.undent
Homebrew has NOT installed npm. If you later install it, you should supplement
your NODE_PATH with the npm module folder:
#{HOMEBREW_PREFIX}/lib/node_modules
EOS
else
s += <<-EOS.undent
npm has been installed. To update run
npm install -g npm@latest

You can install global npm packages with
npm install -g <package>

Packages will install into the global node_modiles directory
#{HOMEBREW_PREFIX}/lib/node_modules
EOS
end
return s
end

def npm_test_install
assert (HOMEBREW_PREFIX/"bin/npm").exist?, "npm must exist"
assert (HOMEBREW_PREFIX/"bin/npm").executable?, "npm must be executable"
system "#{HOMEBREW_PREFIX}/bin/npm", "--verbose", "install", "npm@latest"
# Test if node-gyp is working by building a native addon
system "#{HOMEBREW_PREFIX}/bin/npm", "--verbose", "install", "buffertools"
end
end
end