spring 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,29 +1,209 @@
1
1
  # Spring
2
2
 
3
- TODO: Write a gem description
3
+ Spring is a Rails application preloader. It's trying to solve the same
4
+ problem as [spork](https://github.com/sporkrb/spork),
5
+ [zeus](https://github.com/burke/zeus) and
6
+ [commands](https://github.com/rails/commands).
4
7
 
5
- ## Installation
8
+ I made it because we are having a discussion on the rails core team
9
+ about shipping something to solve this problem with rails. So this is my
10
+ proposal, as working code.
6
11
 
7
- Add this line to your application's Gemfile:
12
+ (At least I hope it's working code, but this is alpha software at the
13
+ moment. Please do try it and let me know if you hit problems.)
8
14
 
9
- gem 'spring'
15
+ ## Features
10
16
 
11
- And then execute:
17
+ Spring is most similar to Zeus, but it's implemented in pure Ruby, and
18
+ is more tightly integrated with Rails (it makes use of Rails' built-in
19
+ code reloader).
12
20
 
13
- $ bundle
21
+ Spring tries to be totally automatic.
22
+ It boots up in the background the first time you run a
23
+ command. Then it speeds up subsequent commands. If it detects that your
24
+ pre-loaded environment has changed (maybe `config/application.rb` has
25
+ been edited) then it will reload your environment in the background,
26
+ ready for the next command. When you close your terminal session, Spring
27
+ will automatically shut down. There's no "server" to manually start and
28
+ stop.
14
29
 
15
- Or install it yourself as:
30
+ Spring operates via a command line interface. Other solutions (e.g.
31
+ commands) take the approach of using a special console to run commands
32
+ from. This means we will have to re-implement shell features such as
33
+ history, completion, etc. Whilst it's not impossible to re-implement
34
+ those features, it's unnecessary work and our re-implementation
35
+ won't be as feature complete as a real shell. Using a real shell also
36
+ prevents the user having to constantly jump between a terminal with a
37
+ real shell and a terminal running the rails "commands console".
16
38
 
17
- $ gem install spring
39
+ ## Compatibility
40
+
41
+ At the moment only MRI 1.9.3 / Rails 3.2 is supported.
18
42
 
19
43
  ## Usage
20
44
 
21
- TODO: Write usage instructions here
45
+ Add `spring` to your gemfile and do a `bundle`.
46
+
47
+ You now have a `spring` command. Do a `rbenv rehash` if necessary. Note
48
+ that on my machine I had over 700 gems installed, and activating the gem
49
+ to run the `spring` command added over 0.5s to the runtime. Clearing out
50
+ my gems solved the problem, but I'd like to figure out a way to speed
51
+ this up.
52
+
53
+ For this walkthrough, I'm using the test app in the Spring repository:
54
+
55
+ ```
56
+ cd /path/to/spring/test/apps/rails-3-2
57
+ ```
58
+
59
+ We can run a test:
60
+
61
+ ```
62
+ $ time spring test test/functional/posts_controller_test.rb
63
+ Run options:
64
+
65
+ # Running tests:
66
+
67
+ .......
68
+
69
+ Finished tests in 0.169882s, 41.2051 tests/s, 58.8644 assertions/s.
70
+
71
+ 7 tests, 10 assertions, 0 failures, 0 errors, 0 skips
72
+
73
+ real 0m1.858s
74
+ user 0m0.184s
75
+ sys 0m0.067s
76
+ ```
77
+
78
+ That booted our app in the background:
79
+
80
+ ```
81
+ $ ps ax | grep spring
82
+ 8692 pts/6 Sl 0:00 /home/turnip/.rbenv/versions/1.9.3-p194/bin/ruby -r bundler/setup /home/turnip/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/spring-0.0.1/lib/spring/server.rb
83
+ 8698 pts/6 Sl 0:02 /home/turnip/.rbenv/versions/1.9.3-p194/bin/ruby -r bundler/setup /home/turnip/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/spring-0.0.1/lib/spring/server.rb
84
+ ```
85
+
86
+ We can see two processes, one is the Spring server, the other is the
87
+ application running in the test environment. When we close the terminal,
88
+ the processes will be killed automatically.
89
+
90
+ Running the tests is faster next time:
91
+
92
+ ```
93
+ $ time spring test test/functional/posts_controller_test.rb
94
+ Run options:
95
+
96
+ # Running tests:
97
+
98
+ .......
99
+
100
+ Finished tests in 0.162963s, 42.9546 tests/s, 61.3637 assertions/s.
101
+
102
+ 7 tests, 10 assertions, 0 failures, 0 errors, 0 skips
103
+
104
+ real 0m0.492s
105
+ user 0m0.179s
106
+ sys 0m0.063s
107
+ ```
108
+
109
+ If we edit any of the application files, or test files, the change will
110
+ be picked up on the next run, without having the background process
111
+ having to be restarted. This works even if you e.g. referenced your
112
+ `Post` model in an initializer and then edited it.
113
+
114
+ If we edit any of the preloaded files, the application needs to restart
115
+ automatically. Note that the application process id is 8698 above. Let's
116
+ "edit" the `config/application.rb`:
117
+
118
+ ```
119
+ $ touch config/application.rb
120
+ $ ps ax | grep spring
121
+ 8692 pts/6 Sl 0:00 /home/turnip/.rbenv/versions/1.9.3-p194/bin/ruby -r bundler/setup /home/turnip/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/spring-0.0.1/lib/spring/server.rb
122
+ 8876 pts/6 Sl 0:00 /home/turnip/.rbenv/versions/1.9.3-p194/bin/ruby -r bundler/setup /home/turnip/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/spring-0.0.1/lib/spring/server.rb
123
+ ```
124
+
125
+ The application process detected the change and exited. The server process
126
+ then detected that the application process exited, so it started a new application.
127
+ All of this happens automatically in the background. Next time we run a
128
+ command we'll be running against a fresh application.
129
+
130
+ If we run a command that uses a different environment, then it gets
131
+ booted up. For example, the `rake` command uses the `development`
132
+ environment by default:
133
+
134
+ ```
135
+ $ time spring rake routes
136
+ posts GET /posts(.:format) posts#index
137
+ POST /posts(.:format) posts#create
138
+ new_post GET /posts/new(.:format) posts#new
139
+ edit_post GET /posts/:id/edit(.:format) posts#edit
140
+ post GET /posts/:id(.:format) posts#show
141
+ PUT /posts/:id(.:format) posts#update
142
+ DELETE /posts/:id(.:format) posts#destroy
143
+
144
+ real 0m0.763s
145
+ user 0m0.185s
146
+ sys 0m0.063s
147
+ ```
148
+
149
+ We now have 3 processes: the server, and application in test mode and
150
+ the application in development mode.
151
+
152
+ ```
153
+ $ ps ax | grep spring
154
+ 8692 pts/6 Sl 0:00 /home/turnip/.rbenv/versions/1.9.3-p194/bin/ruby -r bundler/setup /home/turnip/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/spring-0.0.1/lib/spring/server.rb
155
+ 8876 pts/6 Sl 0:15 /home/turnip/.rbenv/versions/1.9.3-p194/bin/ruby -r bundler/setup /home/turnip/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/spring-0.0.1/lib/spring/server.rb
156
+ 9088 pts/6 Sl 0:01 /home/turnip/.rbenv/versions/1.9.3-p194/bin/ruby -r bundler/setup /home/turnip/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/spring-0.0.1/lib/spring/server.rb
157
+ ```
158
+
159
+ Running rake is faster the second time:
160
+
161
+ ```
162
+ $ time spring rake routes
163
+ posts GET /posts(.:format) posts#index
164
+ POST /posts(.:format) posts#create
165
+ new_post GET /posts/new(.:format) posts#new
166
+ edit_post GET /posts/:id/edit(.:format) posts#edit
167
+ post GET /posts/:id(.:format) posts#show
168
+ PUT /posts/:id(.:format) posts#update
169
+ DELETE /posts/:id(.:format) posts#destroy
170
+
171
+ real 0m0.341s
172
+ user 0m0.177s
173
+ sys 0m0.070s
174
+ ```
175
+
176
+ ## Commands
177
+
178
+ The following commands are shipped by default.
179
+
180
+ Custom commands can be specified in `config/initializers/spring.rb`. See
181
+ [`lib/spring/commands.rb`](https://github.com/jonleighton/spring/blob/master/lib/spring/commands.rb)
182
+ for examples.
183
+
184
+ ### `test`
185
+
186
+ Runs a test (e.g. Test::Unit, MiniTest::Unit, etc.) Preloads the `test_helper` file.
187
+
188
+ ### `rspec`
189
+
190
+ Runs an rspec spec, exactly the same as the `rspec` executable. Preloads
191
+ the `spec_helper` file.
192
+
193
+ ### `rake`
194
+
195
+ Runs a rake task.
196
+
197
+ ### `console`
198
+
199
+ Boots into the Rails console. Currently this is usable but not perfect,
200
+ for example you can't scroll back through command history. (That will be
201
+ fixed.)
202
+
203
+ ### `generate`
204
+
205
+ Runs a Rails generator.
22
206
 
23
- ## Contributing
207
+ ### `runner`
24
208
 
25
- 1. Fork it
26
- 2. Create your feature branch (`git checkout -b my-new-feature`)
27
- 3. Commit your changes (`git commit -am 'Add some feature'`)
28
- 4. Push to the branch (`git push origin my-new-feature`)
29
- 5. Create new Pull Request
209
+ The Rails runner.
@@ -1,5 +1,3 @@
1
- # TODO: Need a way for applications to add their own commands.
2
-
3
1
  class Spring
4
2
  @commands = {}
5
3
 
@@ -15,6 +13,12 @@ class Spring
15
13
  commands.fetch name
16
14
  end
17
15
 
16
+ # Load custom commands, if any
17
+ begin
18
+ require "./config/initializers/spring"
19
+ rescue LoadError
20
+ end
21
+
18
22
  module Commands
19
23
  class Test
20
24
  def env
@@ -1,3 +1,3 @@
1
1
  class Spring
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -195,4 +195,8 @@ class AppTest < ActiveSupport::TestCase
195
195
  File.write(application, application_contents)
196
196
  end
197
197
  end
198
+
199
+ test "custom commands" do
200
+ assert_stdout "#{BINFILE} custom", "omg"
201
+ end
198
202
  end
@@ -0,0 +1,7 @@
1
+ class CustomCommand
2
+ def call(args)
3
+ puts "omg"
4
+ end
5
+ end
6
+
7
+ Spring.register_command "custom", CustomCommand
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spring
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -88,6 +88,7 @@ files:
88
88
  - test/apps/rails-3-2/config/initializers/mime_types.rb
89
89
  - test/apps/rails-3-2/config/initializers/secret_token.rb
90
90
  - test/apps/rails-3-2/config/initializers/session_store.rb
91
+ - test/apps/rails-3-2/config/initializers/spring.rb
91
92
  - test/apps/rails-3-2/config/initializers/wrap_parameters.rb
92
93
  - test/apps/rails-3-2/config/locales/en.yml
93
94
  - test/apps/rails-3-2/config/routes.rb
@@ -181,6 +182,7 @@ test_files:
181
182
  - test/apps/rails-3-2/config/initializers/mime_types.rb
182
183
  - test/apps/rails-3-2/config/initializers/secret_token.rb
183
184
  - test/apps/rails-3-2/config/initializers/session_store.rb
185
+ - test/apps/rails-3-2/config/initializers/spring.rb
184
186
  - test/apps/rails-3-2/config/initializers/wrap_parameters.rb
185
187
  - test/apps/rails-3-2/config/locales/en.yml
186
188
  - test/apps/rails-3-2/config/routes.rb
@@ -212,4 +214,3 @@ test_files:
212
214
  - test/apps/rails-3-2/vendor/plugins/.gitkeep
213
215
  - test/helper.rb
214
216
  - test/unit/application_watcher_test.rb
215
- has_rdoc: