Class: Node::Compiler

Inherits:
Object
  • Object
show all
Defined in:
lib/node/compiler.rb,
lib/node/compiler/npm.rb,
lib/node/compiler/test.rb,
lib/node/compiler/error.rb,
lib/node/compiler/utils.rb,
lib/node/compiler/constants.rb

Defined Under Namespace

Modules: Utils Classes: Error, Npm, Test

Constant Summary collapse

VERSION =
'0.9.1'
VENDOR_DIR =
File.expand_path('../../../../vendor', __FILE__)
MEMFS =
'/__enclose_io_memfs__'

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(entrance, options = {}) ⇒ Compiler

Returns a new instance of Compiler.



44
45
46
47
48
49
50
51
# File 'lib/node/compiler.rb', line 44

def initialize(entrance, options = {})
  @options = options
  @entrance = entrance

  init_options
  init_entrance
  init_tmpdir
end

Class Method Details

.node_versionObject



19
20
21
# File 'lib/node/compiler.rb', line 19

def self.node_version
  @node_version ||= peek_node_version
end

.peek_node_versionObject



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/node/compiler.rb', line 23

def self.peek_node_version
  version_info = File.read(File.join(VENDOR_DIR, 'node/src/node_version.h'))
  versions = []
  if version_info =~ /NODE_MAJOR_VERSION\s+(\d+)/
    versions << $1.dup
  else
    raise 'Cannot peek NODE_MAJOR_VERSION'
  end
  if version_info =~ /NODE_MINOR_VERSION\s+(\d+)/
    versions << $1.dup
  else
    raise 'Cannot peek NODE_MINOR_VERSION'
  end
  if version_info =~ /NODE_PATCH_VERSION\s+(\d+)/
    versions << $1.dup
  else
    raise 'Cannot peek NODE_PATCH_VERSION'
  end
  versions.join('.')
end

Instance Method Details

#compileObject



123
124
125
126
127
128
129
130
# File 'lib/node/compiler.rb', line 123

def compile
  Utils.chdir(@vendor_node) do
    Utils.run("./configure")
    Utils.run("make #{@options[:make_args]}")
  end
  STDERR.puts "-> FileUtils.cp(#{File.join(@vendor_node, 'out/Release/node')}, #{@options[:output]})"
  FileUtils.cp(File.join(@vendor_node, 'out/Release/node'), @options[:output])
end

#compile_winObject



115
116
117
118
119
120
121
# File 'lib/node/compiler.rb', line 115

def compile_win
  Utils.chdir(@vendor_node) do
    Utils.run("call vcbuild.bat #{@options[:vcbuild_args]}")
  end
  STDERR.puts "-> FileUtils.cp(#{File.join(@vendor_node, 'Release\\node.exe')}, #{@options[:output]})"
  FileUtils.cp(File.join(@vendor_node, 'Release\\node.exe'), @options[:output])
end

#copypath(path) ⇒ Object



138
139
140
141
142
143
144
# File 'lib/node/compiler.rb', line 138

def copypath(path)
  path = File.expand_path(path)
  raise 'Logic error 1 in copypath' unless @project_root == path[0...(@project_root.size)]
  ret = File.join(@copy_dir, path[(@project_root.size)..-1])
  raise 'Logic error 2 in copypath' unless File.exist?(ret)
  ret
end

#init_entranceObject

Raises:



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/node/compiler.rb', line 53

def init_entrance
  # Important to expand_path; otherwiser the while would not be right
  @entrance = File.expand_path(@entrance)
  raise Error, "Cannot find entrance #{@entrance}." unless File.exist?(@entrance)
  if @options[:project_root]
    @project_root = File.expand_path(@options[:project_root])
  else
    @project_root = File.dirname(@entrance)
    # this while has to correspond with the expand_path above
    while !File.exist?(File.expand_path('./package.json', @project_root))
      break if '/' == @project_root
      @project_root = File.expand_path('..', @project_root)
    end
  end
  unless File.exist?(File.expand_path('./package.json', @project_root))
    raise Error, "Cannot find a package.json at the project root #{@project_root}"
  end
end

#init_optionsObject



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/node/compiler.rb', line 72

def init_options
  if Gem.win_platform?
    @options[:output] ||= 'a.exe'
  else
    @options[:output] ||= 'a.out'
  end
  @options[:output] = File.expand_path(@options[:output])

  @options[:tmpdir] ||= File.expand_path("nodec", Dir.tmpdir)
  @options[:tmpdir] = File.expand_path(@options[:tmpdir])
  
  if @options[:npm_package]
    @options[:npm_package_version] ||= 'latest'
    npm = ::Node::Compiler::Npm.new(@options[:npm_package], @options[:npm_package_version], @options[:tmpdir])
    @entrance = npm.get_entrance(@entrance)
  end
end

#init_tmpdirObject



90
91
92
93
94
95
96
97
# File 'lib/node/compiler.rb', line 90

def init_tmpdir
  if @options[:tmpdir].include? @project_root
    raise Error, "tmpdir #{@options[:tmpdir]} cannot reside inside the project root #{@project_root}."
  end

  Utils.prepare_tmpdir(@options[:tmpdir])
  @vendor_node = File.join(@options[:tmpdir], 'node')
end

#inject_entranceObject



105
106
107
108
109
110
111
112
113
# File 'lib/node/compiler.rb', line 105

def inject_entrance
  target = File.expand_path('./lib/enclose_io_entrance.js', @vendor_node)
  path = mempath @entrance
  File.open(target, "w") { |f| f.puts %Q`module.exports = "#{path}";` }
  # remove shebang
  lines = File.read(@entrance).lines
  lines[0] = "// #{lines[0]}" if '#!' == lines[0][0..1]
  File.open(copypath(@entrance), "w") { |f| f.print lines.join }
end

#mempath(path) ⇒ Object



132
133
134
135
136
# File 'lib/node/compiler.rb', line 132

def mempath(path)
  path = File.expand_path(path)
  raise 'Logic error in mempath' unless @project_root == path[0...(@project_root.size)]
  "#{MEMFS}#{path[(@project_root.size)..-1]}"
end

#run!Object



99
100
101
102
103
# File 'lib/node/compiler.rb', line 99

def run!
  @copy_dir = Utils.inject_memfs(@project_root, @vendor_node)
  inject_entrance
  Gem.win_platform? ? compile_win : compile
end