mirahd 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --colour
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - jruby-18mode
4
+ script: bundle exec rake spec
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'mirah'
4
+
5
+ group :test do
6
+ gem 'rspec'
7
+ gem 'jeweler'
8
+ end
@@ -0,0 +1,33 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ bitescript (0.1.0)
5
+ diff-lcs (1.1.3)
6
+ git (1.2.5)
7
+ jeweler (1.8.3)
8
+ bundler (~> 1.0)
9
+ git (>= 1.2.5)
10
+ rake
11
+ rdoc
12
+ json (1.7.3-java)
13
+ mirah (0.0.11-java)
14
+ bitescript (>= 0.0.8)
15
+ rake (0.9.2.2)
16
+ rdoc (3.12)
17
+ json (~> 1.4)
18
+ rspec (2.9.0)
19
+ rspec-core (~> 2.9.0)
20
+ rspec-expectations (~> 2.9.0)
21
+ rspec-mocks (~> 2.9.0)
22
+ rspec-core (2.9.0)
23
+ rspec-expectations (2.9.1)
24
+ diff-lcs (~> 1.1.3)
25
+ rspec-mocks (2.9.0)
26
+
27
+ PLATFORMS
28
+ java
29
+
30
+ DEPENDENCIES
31
+ jeweler
32
+ mirah
33
+ rspec
@@ -0,0 +1,94 @@
1
+ mirahd
2
+ ======
3
+
4
+ **mirahd** is a Mirah Daemon listening for your requests to compile something.
5
+ When it receives one it does the job quickly. _Really quickly_.
6
+
7
+ [![Build Status](https://secure.travis-ci.org/jstepien/mirahd.png?branch=master)](http://travis-ci.org/jstepien/mirahd)
8
+
9
+ Usage
10
+ -----
11
+
12
+ We'll need:
13
+
14
+ * Bundler,
15
+ * Mirah, and as a result
16
+ * JRuby 1.6.
17
+
18
+ For your own comfort and sanity it is also advisable to install a Ruby
19
+ implementation with a reasonably short start up time. MRI or Rubinius
20
+ are good candidates.
21
+
22
+ jruby -S bundle install
23
+ jruby -S rspec test
24
+ jruby -rubygems -I lib -S bin/mirahd --daemon
25
+ ruby -I lib bin/mirahd test/hello.mirah
26
+
27
+ Rationale
28
+ ---------
29
+
30
+ Mirah is a lovely language but its low compilation speed might be discouraging.
31
+ Using it in development based on a lot of small _code, test, refactor_ cycles
32
+ might be problematic. JVM's start up time and a lag introduced by compilation
33
+ of Mirah's sources by JRuby add up to the sum we see below¹.
34
+
35
+ $ time mirahc test/hello.mirah > /dev/null # with disk's cache warmed up
36
+ 18.60user 0.45system 0:11.85elapsed
37
+
38
+ After the initial warm up JVM and JRuby are pretty fast. The goal of this
39
+ project is to make the JVM start once only and then reuse the existing process
40
+ for all subsequent compilation tasks.
41
+
42
+ Run the daemon.
43
+
44
+ $ jruby -rubygems -I lib -S bin/mirahd --daemon
45
+
46
+ The first compilation is already quite quick.
47
+
48
+ $ time ruby -I lib -S bin/mirahd test/hello.mirah
49
+ 0.05user 0.00system 0:00.89elapsed
50
+
51
+ Then JVM's JIT comes into play. Here's the tenth compilation.
52
+
53
+ $ time ruby -I lib -S bin/mirahd test/hello.mirah
54
+ 0.04user 0.00system 0:00.30elapsed
55
+
56
+ Todo
57
+ ----
58
+
59
+ * Security. By being able to access the port DRb is listening on you
60
+ can `eval` whatever you want to. `$SAFE` won't work as it's unsupported
61
+ by JRuby.
62
+ * Enable users to specify the port number.
63
+ * Write tests covering a server running in a different directory then the
64
+ client. It won't be possible without spawning 2 separate processes.
65
+ * Support `--help` et al. command line arguments.
66
+ * Concurrency. Two compilation requests might interfere with each other,
67
+ especially due to changing the current working directory.
68
+
69
+ Copyrights
70
+ ----------
71
+
72
+ Copyright (c) 2012 Jan Stępień
73
+
74
+ Permission is hereby granted, free of charge, to any person obtaining
75
+ a copy of this software and associated documentation files (the
76
+ "Software"), to deal in the Software without restriction, including
77
+ without limitation the rights to use, copy, modify, merge, publish,
78
+ distribute, sublicense, and/or sell copies of the Software, and to
79
+ permit persons to whom the Software is furnished to do so, subject to
80
+ the following conditions:
81
+
82
+ The above copyright notice and this permission notice shall be
83
+ included in all copies or substantial portions of the Software.
84
+
85
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
86
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
87
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
88
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
89
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
90
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
91
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
92
+
93
+ ___
94
+ ¹ That's a 64-bit OpenJDK 6 on Intel Core 2 Duo with GNU/Linux 3.2.8.
@@ -0,0 +1,34 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "mirahd"
18
+ gem.homepage = "https://github.com/jstepien/mirahd"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{Mirah compilation daemon (in dire need of Javanese name)}
21
+ gem.description = File.read "README.md"
22
+ gem.email = "jstepien@users.sourceforge.net"
23
+ gem.authors = ["Jan Stępień"]
24
+ # dependencies defined in Gemfile
25
+ end
26
+ Jeweler::RubygemsDotOrgTasks.new
27
+
28
+ require 'rspec/core'
29
+ require 'rspec/core/rake_task'
30
+ RSpec::Core::RakeTask.new(:spec) do |spec|
31
+ spec.pattern = FileList['test/**/*_spec.rb']
32
+ end
33
+
34
+ task :default => :spec
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.0
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ if ARGV.include? '--daemon'
3
+ require 'mirahd/server'
4
+ server = MirahD::Server.new
5
+ server.start
6
+ puts 'Ready.' unless ARGV.include? '--quiet'
7
+ server.wait
8
+ else
9
+ require 'mirahd/client'
10
+ begin
11
+ puts MirahD::Client.new.compile ARGV
12
+ rescue => ex
13
+ $stderr.puts ex.message
14
+ exit 1
15
+ end
16
+ end
@@ -0,0 +1,12 @@
1
+ require 'drb/drb'
2
+ require 'fileutils'
3
+
4
+ module MirahD
5
+ class Client
6
+ URI = 'druby://localhost:8787'
7
+
8
+ def compile args
9
+ DRbObject.new_with_uri(URI).compile args, FileUtils.pwd
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,55 @@
1
+ require 'drb/drb'
2
+ require 'stringio'
3
+ require 'mirah'
4
+
5
+ module MirahD
6
+ class Server
7
+ class Compiler
8
+ def compile args, dir = FileUtils.pwd
9
+ intercepting_stdout do
10
+ FileUtils.cd dir do
11
+ Mirah::Commands::Compile.new(args).execute
12
+ end
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def intercepting_stdout
19
+ orig_stdout = $stdout
20
+ $stdout = StringIO.new 'w'
21
+ yield
22
+ rescue Exception => ex
23
+ new_ex = StandardError.new $stdout.string
24
+ new_ex.set_backtrace ex.backtrace
25
+ raise new_ex
26
+ else
27
+ $stdout.string
28
+ ensure
29
+ $stdout = orig_stdout
30
+ end
31
+ end
32
+
33
+ URI = 'druby://localhost:8787'
34
+
35
+ def start
36
+ DRb.start_service URI, Compiler.new
37
+ true
38
+ end
39
+
40
+ def stop
41
+ raise 'The server has not been started yet' unless running?
42
+ DRb.stop_service
43
+ true
44
+ end
45
+
46
+ def wait
47
+ DRb.thread.join if running?
48
+ true
49
+ end
50
+
51
+ def running?
52
+ not DRb.thread.nil? and DRb.thread.alive?
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,51 @@
1
+ require 'test/common'
2
+ require 'mirahd/server'
3
+ require 'mirahd/client'
4
+
5
+ describe MirahD::Client do
6
+ before :all do
7
+ wait_for_the_port_to_become_free 8787
8
+ @server = MirahD::Server.new
9
+ @server.start
10
+ end
11
+
12
+ after :all do
13
+ @server.stop
14
+ end
15
+
16
+ before do
17
+ @client = MirahD::Client.new
18
+ end
19
+
20
+ after do
21
+ rm_f_temp_files
22
+ end
23
+
24
+ it 'can compile to Java source code' do
25
+ @client.compile(['--java', Source]).should_not be_nil
26
+ File.file?(JavaFile).should == true
27
+ end
28
+
29
+ it 'can compile a JVM class' do
30
+ @client.compile([Source]).should_not be_nil
31
+ File.file?(ClassFile).should == true
32
+ end
33
+
34
+ it 'receives compiler\'s standard output' do
35
+ @client.compile([Source]).should =~ /^Parsing.*Inferring.*Done!$/m
36
+ end
37
+
38
+ describe 'after failed compilation' do
39
+ it 'receives an exception' do
40
+ lambda { @client.compile([BadSource]) } .should raise_error StandardError
41
+ end
42
+
43
+ it 'receives error messages' do
44
+ begin
45
+ @client.compile([BadSource])
46
+ rescue => ex
47
+ ex.message.should =~ /^Parsing.*expected statement.*at line/m
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,32 @@
1
+ $: << File.join(File.dirname(__FILE__), '..', 'lib')
2
+
3
+ require 'rspec'
4
+ require 'fileutils'
5
+ require 'socket'
6
+
7
+ Source = 'test/hello.mirah'
8
+ BadSource = 'Gemfile.lock'
9
+ JavaFile = 'test/Hello.java'
10
+ ClassFile = 'test/Hello.class'
11
+
12
+ def rm_f_temp_files
13
+ [JavaFile, ClassFile].each { |file| FileUtils.rm_f file }
14
+ end
15
+
16
+ # This function tries to connect to a given TCP port and close the socket
17
+ # immediately after getting connected. If TCPSocket#new raises an error it
18
+ # means that the port is free and we can begin testing.
19
+ #
20
+ # This function prevents spurious Errno::EADDRINUSE errors which happened from
21
+ # time to time when the port didn't get completely freed before proceeding to
22
+ # a next test.
23
+ def wait_for_the_port_to_become_free port
24
+ while true
25
+ begin
26
+ TCPSocket.new('localhost', port).close
27
+ rescue
28
+ return
29
+ end
30
+ sleep 0.1
31
+ end
32
+ end
@@ -0,0 +1,7 @@
1
+ class Hello
2
+ def hi
3
+ puts "Witaj, Świecie!"
4
+ end
5
+ end
6
+
7
+ Hello.new.hi
@@ -0,0 +1,93 @@
1
+ require 'test/common'
2
+ require 'drb/drb'
3
+ require 'mirahd/server'
4
+
5
+ describe MirahD::Server do
6
+ before do
7
+ wait_for_the_port_to_become_free 8787
8
+ @server = MirahD::Server.new
9
+ end
10
+
11
+ it 'can be started and stopped' do
12
+ @server.start.should == true
13
+ @server.stop.should == true
14
+ end
15
+
16
+ it 'is not running by default' do
17
+ @server.running?.should == false
18
+ end
19
+
20
+ it 'knows when it is stopped' do
21
+ @server.start
22
+ @server.stop
23
+ @server.running?.should == false
24
+ end
25
+
26
+ it 'cannot be stopped before being started' do
27
+ lambda { @server.stop } .should raise_error
28
+ end
29
+
30
+ describe 'when online' do
31
+ before do
32
+ @server.start
33
+ @remote = DRbObject.new_with_uri 'druby://localhost:8787'
34
+ end
35
+
36
+ after do
37
+ @server.stop if @server.running?
38
+ rm_f_temp_files
39
+ end
40
+
41
+ it 'knows that it is running' do
42
+ @server.running?.should == true
43
+ end
44
+
45
+ it 'cannot be started once again' do
46
+ lambda { @server.start } .should raise_error
47
+ end
48
+
49
+ it 'listens on port 8787' do
50
+ @remote.should respond_to :object_id
51
+ end
52
+
53
+ it 'responds to compile' do
54
+ @remote.should respond_to :compile
55
+ end
56
+
57
+ it 'the #wait method should keep it running' do
58
+ # FIXME: busy waiting is considered evil.
59
+ failed = false
60
+ thr = Thread.start do
61
+ @server.wait
62
+ failed = @server.running?
63
+ end
64
+ sleep 0.1 until @server.running?
65
+ @server.stop
66
+ thr.join
67
+ failed.should == false
68
+ end
69
+
70
+ describe 'and given a valid input file' do
71
+ it 'should compile it to Java' do
72
+ @remote.compile(['--java', Source]).should_not be_nil
73
+ File.file?(JavaFile).should == true
74
+ end
75
+
76
+ it 'should compile it to a JVM class' do
77
+ @remote.compile([Source]).should_not be_nil
78
+ File.file?(ClassFile).should == true
79
+ end
80
+ end
81
+
82
+ describe 'and given an invalid input file' do
83
+ it 'should fail' do
84
+ lambda { @remote.compile [BadSource] } .should raise_error
85
+ end
86
+
87
+ it 'should not be killed after handling it' do
88
+ lambda { @remote.compile [BadSource] } .should raise_error
89
+ @remote.should respond_to :compile
90
+ end
91
+ end
92
+ end
93
+ end
metadata ADDED
@@ -0,0 +1,125 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mirahd
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.0
6
+ platform: ruby
7
+ authors:
8
+ - "Jan St\xC4\x99pie\xC5\x84"
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2012-06-10 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: mirah
17
+ version_requirements: &id001 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: "0"
23
+ requirement: *id001
24
+ prerelease: false
25
+ type: :runtime
26
+ description: "mirahd\n\
27
+ ======\n\n\
28
+ **mirahd** is a Mirah Daemon listening for your requests to compile something.\n\
29
+ When it receives one it does the job quickly. _Really quickly_.\n\n\
30
+ [![Build Status](https://secure.travis-ci.org/jstepien/mirahd.png?branch=master)](http://travis-ci.org/jstepien/mirahd)\n\n\
31
+ Usage\n\
32
+ -----\n\n\
33
+ We'll need:\n\n * Bundler,\n * Mirah, and as a result\n * JRuby 1.6.\n\n\
34
+ For your own comfort and sanity it is also advisable to install a Ruby\n\
35
+ implementation with a reasonably short start up time. MRI or Rubinius\n\
36
+ are good candidates.\n\n jruby -S bundle install\n jruby -S rspec test\n jruby -rubygems -I lib -S bin/mirahd --daemon\n ruby -I lib bin/mirahd test/hello.mirah\n\n\
37
+ Rationale\n\
38
+ ---------\n\n\
39
+ Mirah is a lovely language but its low compilation speed might be discouraging.\n\
40
+ Using it in development based on a lot of small _code, test, refactor_ cycles\n\
41
+ might be problematic. JVM's start up time and a lag introduced by compilation\n\
42
+ of Mirah's sources by JRuby add up to the sum we see below\xC2\xB9.\n\n $ time mirahc test/hello.mirah > /dev/null # with disk's cache warmed up\n 18.60user 0.45system 0:11.85elapsed\n\n\
43
+ After the initial warm up JVM and JRuby are pretty fast. The goal of this\n\
44
+ project is to make the JVM start once only and then reuse the existing process\n\
45
+ for all subsequent compilation tasks.\n\n\
46
+ Run the daemon.\n\n $ jruby -rubygems -I lib -S bin/mirahd --daemon\n\n\
47
+ The first compilation is already quite quick.\n\n $ time ruby -I lib -S bin/mirahd test/hello.mirah\n 0.05user 0.00system 0:00.89elapsed\n\n\
48
+ Then JVM's JIT comes into play. Here's the tenth compilation.\n\n $ time ruby -I lib -S bin/mirahd test/hello.mirah\n 0.04user 0.00system 0:00.30elapsed\n\n\
49
+ Todo\n\
50
+ ----\n\n * Security. By being able to access the port DRb is listening on you\n can `eval` whatever you want to. `$SAFE` won't work as it's unsupported\n by JRuby.\n * Enable users to specify the port number.\n * Write tests covering a server running in a different directory then the\n client. It won't be possible without spawning 2 separate processes.\n * Support `--help` et al. command line arguments.\n * Concurrency. Two compilation requests might interfere with each other,\n especially due to changing the current working directory.\n\n\
51
+ Copyrights\n\
52
+ ----------\n\n\
53
+ Copyright (c) 2012 Jan St\xC4\x99pie\xC5\x84\n\n\
54
+ Permission is hereby granted, free of charge, to any person obtaining\n\
55
+ a copy of this software and associated documentation files (the\n\
56
+ \"Software\"), to deal in the Software without restriction, including\n\
57
+ without limitation the rights to use, copy, modify, merge, publish,\n\
58
+ distribute, sublicense, and/or sell copies of the Software, and to\n\
59
+ permit persons to whom the Software is furnished to do so, subject to\n\
60
+ the following conditions:\n\n\
61
+ The above copyright notice and this permission notice shall be\n\
62
+ included in all copies or substantial portions of the Software.\n\n\
63
+ THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n\
64
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n\
65
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n\
66
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\n\
67
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n\
68
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\n\
69
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n\
70
+ ___\n\
71
+ \xC2\xB9 That's a 64-bit OpenJDK 6 on Intel Core 2 Duo with GNU/Linux 3.2.8.\n"
72
+ email: jstepien@users.sourceforge.net
73
+ executables:
74
+ - mirahd
75
+ extensions: []
76
+
77
+ extra_rdoc_files:
78
+ - README.md
79
+ files:
80
+ - .rspec
81
+ - .travis.yml
82
+ - Gemfile
83
+ - Gemfile.lock
84
+ - README.md
85
+ - Rakefile
86
+ - VERSION
87
+ - bin/mirahd
88
+ - lib/mirahd/client.rb
89
+ - lib/mirahd/server.rb
90
+ - test/client_spec.rb
91
+ - test/common.rb
92
+ - test/hello.mirah
93
+ - test/server_spec.rb
94
+ homepage: https://github.com/jstepien/mirahd
95
+ licenses:
96
+ - MIT
97
+ post_install_message:
98
+ rdoc_options: []
99
+
100
+ require_paths:
101
+ - lib
102
+ required_ruby_version: !ruby/object:Gem::Requirement
103
+ none: false
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ hash: 2
108
+ segments:
109
+ - 0
110
+ version: "0"
111
+ required_rubygems_version: !ruby/object:Gem::Requirement
112
+ none: false
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: "0"
117
+ requirements: []
118
+
119
+ rubyforge_project:
120
+ rubygems_version: 1.8.15
121
+ signing_key:
122
+ specification_version: 3
123
+ summary: Mirah compilation daemon (in dire need of Javanese name)
124
+ test_files: []
125
+