spring 0.0.1 → 0.0.2

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/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: