Giter Club home page Giter Club logo

spring's Introduction

Spring

Build Status Gem Version

Spring is a Rails application preloader. It speeds up development by keeping your application running in the background, so you don't need to boot it every time you run a test, rake task or migration.

Features

  • Totally automatic; no need to explicitly start and stop the background process
  • Reloads your application code on each run
  • Restarts your application when configs / initializers / gem dependencies are changed

Compatibility

  • Ruby versions: MRI 2.7, MRI 3.0, MRI 3.1, MRI 3.2
  • Rails versions: 6.0, 6.1, 7.0
  • Bundler v2.1+

Spring makes extensive use of Process.fork, so won't be able to provide a speed up on platforms which don't support forking (Windows, JRuby).

Walkthrough

Setup

Add Spring to your Gemfile:

gem "spring", group: :development

(Note: using gem "spring", git: "..." won't work and is not a supported way of using Spring.)

It's recommended to 'springify' the executables in your bin/ directory:

$ bundle install
$ bundle exec spring binstub --all

This generates a bin/spring executable, and inserts a small snippet of code into relevant existing executables. The snippet looks like this:

begin
  load File.expand_path('../spring', __FILE__)
rescue LoadError => e
  raise unless e.message.include?('spring')
end

On platforms where Spring is installed and supported, this snippet hooks Spring into the execution of commands. In other cases, the snippet will just be silently ignored, and the lines after it will be executed as normal.

If you don't want to prefix every command you type with bin/, you can use direnv to automatically add ./bin to your PATH when you cd into your application. Simply create an .envrc file with the command PATH_add bin in your Rails directory.

Enable reloading

Spring reloads application code, and therefore needs the application to have reloading enabled.

Ensure that config.enable_reloading is true in the environments that Spring manages. That setting is typically configured in config/environments/*.rb. In particular, make sure it is true for the test environment.

Note: in versions of Rails before 7.1, the setting is called cache_classes, and it needs to be false for Spring to work.

Usage

For this walkthrough I've generated a new Rails application, and run rails generate scaffold post name:string.

Let's run a test:

$ time bin/rake test test/controllers/posts_controller_test.rb
Running via Spring preloader in process 2734
Run options:

# Running tests:

.......

Finished tests in 0.127245s, 55.0121 tests/s, 78.5887 assertions/s.

7 tests, 10 assertions, 0 failures, 0 errors, 0 skips

real    0m2.165s
user    0m0.281s
sys     0m0.066s

That wasn't particularly fast because it was the first run, so Spring had to boot the application. It's now running:

$ bin/spring status
Spring is running:

26150 spring server | spring-demo-app | started 3 secs ago
26155 spring app    | spring-demo-app | started 3 secs ago | test mode

The next run is faster:

$ time bin/rake test test/controllers/posts_controller_test.rb
Running via Spring preloader in process 8352
Run options:

# Running tests:

.......

Finished tests in 0.176896s, 39.5714 tests/s, 56.5305 assertions/s.

7 tests, 10 assertions, 0 failures, 0 errors, 0 skips

real    0m0.610s
user    0m0.276s
sys     0m0.059s

If we edit any of the application files, or test files, the changes will be picked up on the next run without the background process having to restart. This works in exactly the same way as the code reloading which allows you to refresh your browser and instantly see changes during development.

But if we edit any of the files which were used to start the application (configs, initializers, your gemfile), the application needs to be fully restarted. This happens automatically.

Let's "edit" config/application.rb:

$ touch config/application.rb
$ bin/spring status
Spring is running:

26150 spring server | spring-demo-app | started 36 secs ago
26556 spring app    | spring-demo-app | started 1 sec ago | test mode

The application detected that config/application.rb changed and automatically restarted itself.

If we run a command that uses a different environment, then that environment gets booted up:

$ bin/rake routes
Running via Spring preloader in process 2363
    posts GET    /posts(.:format)          posts#index
          POST   /posts(.:format)          posts#create
 new_post GET    /posts/new(.:format)      posts#new
edit_post GET    /posts/:id/edit(.:format) posts#edit
     post GET    /posts/:id(.:format)      posts#show
          PUT    /posts/:id(.:format)      posts#update
          DELETE /posts/:id(.:format)      posts#destroy

$ bin/spring status
Spring is running:

26150 spring server | spring-demo-app | started 1 min ago
26556 spring app    | spring-demo-app | started 42 secs ago | test mode
26707 spring app    | spring-demo-app | started 2 secs ago | development mode

There's no need to "shut down" Spring. This will happen automatically when you close your terminal. However, if you do want to do a manual shut down, use the stop command:

$ bin/spring stop
Spring stopped.

From within your code, you can check whether Spring is active with if defined?(Spring).

Removal

To remove Spring:

  • 'Unspring' your bin/ executables: bin/spring binstub --remove --all
  • Remove spring from your Gemfile

Deployment

You must not install Spring on your production environment. To prevent it from being installed, run the bundle config set without 'development test' before bundle install command which is used to install gems on your production machines:

$ bundle config set without 'development test'
$ bundle install

Commands

rake

Runs a rake task. Rake tasks run in the development environment by default. You can change this on the fly by using the RAILS_ENV environment variable. The environment is also configurable with the Spring::Commands::Rake.environment_matchers hash. This has sensible defaults, but if you need to match a specific task to a specific environment, you'd do it like this:

Spring::Commands::Rake.environment_matchers["perf_test"] = "test"
Spring::Commands::Rake.environment_matchers[/^perf/]     = "test"

# To change the environment when you run `rake` with no arguments
Spring::Commands::Rake.environment_matchers[:default] = "development"

rails console, rails generate, rails runner

These execute the rails command you already know and love. If you run a different sub command (e.g. rails server) then Spring will automatically pass it through to the underlying rails executable (without the speed-up).

Additional commands

You can add these to your Gemfile for additional commands:

Use without adding to bundle

If you don't want Spring-related code checked into your source repository, it's possible to use Spring without adding to your Gemfile. However, using Spring binstubs without adding Spring to the Gemfile is not supported.

To use Spring like this, do a gem install spring and then prefix commands with spring. For example, rather than running bin/rake -T, you'd run spring rake -T.

Temporarily disabling Spring

If you're using Spring binstubs, but temporarily don't want commands to run through Spring, set the DISABLE_SPRING environment variable.

Class reloading

Spring uses Rails' class reloading mechanism to keep your code up to date between test runs. This is the same mechanism which allows you to see changes during development when you refresh the page. However, you may never have used this mechanism with your test environment before, and this can cause problems.

It's important to realise that code reloading means that the constants in your application are different objects after files have changed:

$ bin/rails runner 'puts User.object_id'
70127987886040
$ touch app/models/user.rb
$ bin/rails runner 'puts User.object_id'
70127976764620

Suppose you have an initializer config/initializers/save_user_class.rb like so:

USER_CLASS = User

This saves off the first version of the User class, which will not be the same object as User after the code has been reloaded:

$ bin/rails runner 'puts User == USER_CLASS'
true
$ touch app/models/user.rb
$ bin/rails runner 'puts User == USER_CLASS'
false

So to avoid this problem, don't save off references to application constants in your initialization code.

Using Spring with a containerized development environment

As of Spring 1.7, there is some support for doing this. See this example repository for information about how to do it with Docker.

Configuration

Spring will read ~/.spring.rb and config/spring.rb for custom settings. Note that ~/.spring.rb is loaded before bundler, but config/spring.rb is loaded after bundler. So if you have any spring-commands-* gems installed that you want to be available in all projects without having to be added to the project's Gemfile, require them in your ~/.spring.rb.

config/spring_client.rb is also loaded before bundler and before a server process is started, it can be used to add new top-level commands.

Application root

Spring must know how to find your Rails application. If you have a normal app everything works out of the box. If you are working on a project with a special setup (an engine for example), you must tell Spring where your app is located:

Spring.application_root = './test/dummy'

Running code before forking

There is no Spring.before_fork callback. To run something before the fork, you can place it in ~/.spring.rb or config/spring.rb or in any of the files which get run when your application initializes, such as config/application.rb, config/environments/*.rb or config/initializers/*.rb.

Running code after forking

You might want to run code after Spring forked off the process but before the actual command is run. You might want to use an after_fork callback if you have to connect to an external service, do some general cleanup or set up dynamic configuration.

Spring.after_fork do
  # run arbitrary code
end

If you want to register multiple callbacks you can simply call Spring.after_fork multiple times with different blocks.

Watching files and directories

Spring will automatically detect file changes to any file loaded when the server boots. Changes will cause the affected environments to be restarted.

If there are additional files or directories which should trigger an application restart, you can specify them with Spring.watch:

Spring.watch "config/some_config_file.yml"

By default, Spring polls the filesystem for changes once every 0.2 seconds. This method requires zero configuration, but if you find that it's using too much CPU, then you can use event-based file system listening by installing the spring-watcher-listen gem.

Quiet output

To disable the "Running via Spring preloader" message which is shown each time a command runs:

Spring.quiet = true

You can also set the initial state of the quiet configuration option to true by setting the SPRING_QUIET environment variable before executing Spring. This is useful if you want to set quiet mode when invoking the Spring executable in a subprocess, and cannot or prefer not to set it programmatically via the Spring.quiet option in ~/.spring.rb or the app's config/spring.rb.

Environment variables

The following environment variables are used by Spring:

  • DISABLE_SPRING - If set, Spring will be bypassed, and your application will boot in a foreground process
  • SPRING_LOG - The path to a file which Spring will write log messages to.
  • SPRING_TMP_PATH - The directory where Spring should write its temporary files (a pidfile and a socket). By default, we use the XDG_RUNTIME_DIR environment variable, or else Dir.tmpdir, and then create a directory in that named spring-$UID. We don't use your Rails application's tmp/ directory because that may be on a filesystem which doesn't support UNIX sockets.
  • SPRING_APPLICATION_ID - Used to identify distinct Rails applications. By default, it is an MD5 hash of the current RUBY_VERSION, and the path to your Rails project root.
  • SPRING_SOCKET - The path which should be used for the UNIX socket which Spring uses to communicate with the long-running Spring server process. By default, this is SPRING_TMP_PATH/SPRING_APPLICATION_ID.
  • SPRING_PIDFILE - The path which should be used to store the pid of the long-running Spring server process. By default, this is related to the socket path; if the socket path is /foo/bar/spring.sock the pidfile will be /foo/bar/spring.pid.
  • SPRING_QUIET - If set, the initial state of the Spring.quiet configuration option will default to true.
  • SPRING_SERVER_COMMAND - The command to run to start up the Spring server when it is not already running. Defaults to spring _[version]_ server --background.

Troubleshooting

If you want to get more information about what Spring is doing, you can run Spring explicitly in a separate terminal:

$ spring server

Logging output will be printed to stdout. You can also send log output to a file with the SPRING_LOG environment variable.

spring's People

Contributors

agis avatar amatsuda avatar byroot avatar ccutrer avatar cgamesplay avatar deivid-rodriguez avatar dosire avatar eileencodes avatar felixbuenemann avatar fxn avatar gmcgibbon avatar grosser avatar guilleiguaran avatar jeremy avatar jonleighton avatar junaruga avatar mattbrictson avatar matthewd avatar morgoth avatar mtsmfm avatar rafaelfranca avatar rubemz avatar rwjblue avatar rymai avatar senny avatar sixeight avatar sobrinho avatar sonalkr132 avatar tenderlove avatar y-yagi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

spring's Issues

stale pid file makes spring unusable

If a process crashes and does not clean up the associated PID file spring won't work until the PID file is removed. The error I get is:

/Users/senny/.rvm/gems/ruby-1.9.3-p194@equis/gems/spring-0.0.2/lib/spring.rb:66:in `ensure in run': undefined method `close' for nil:NilClass (NoMethodError)
    from /Users/senny/.rvm/gems/ruby-1.9.3-p194@equis/gems/spring-0.0.2/lib/spring.rb:66:in `run'
    from /Users/senny/.rvm/gems/ruby-1.9.3-p194@equis/gems/spring-0.0.2/lib/spring.rb:19:in `run'
    from /Users/senny/.rvm/gems/ruby-1.9.3-p194@equis/gems/spring-0.0.2/bin/spring:5:in `<top (required)>'
    from /Users/senny/.rvm/gems/ruby-1.9.3-p194@equis/bin/spring:19:in `load'
    from /Users/senny/.rvm/gems/ruby-1.9.3-p194@equis/bin/spring:19:in `<main>'

Would it be reasonable to unlink the PID file if the returned socket is nil and re-run the process? Let me know and I'll submit a PR.

Add after fork callback

Certain users might need to run some arbitrary code after forking. (For example to reload something, or whatever.) So we should support doing this.

Integrate with `rails` command

We should have a seamless integration such that bin/rails console uses spring but bin/rails server executes as normal (without spring).

can't seem to get it to work - file descriptor was not passed

Once I'm past the error described in #2 I'm stuck with:

/Users/senny/.rvm/gems/ruby-1.9.3-p194@equis/gems/spring-0.0.2/lib/spring/application.rb:98:in `recv_io': file descriptor was not passed (msg_controllen=0 smaller than sizeof(struct cmsghdr)=12) (SocketError)
    from /Users/senny/.rvm/gems/ruby-1.9.3-p194@equis/gems/spring-0.0.2/lib/spring/application.rb:98:in `redirect_output'
    from /Users/senny/.rvm/gems/ruby-1.9.3-p194@equis/gems/spring-0.0.2/lib/spring/application.rb:64:in `serve'
    from /Users/senny/.rvm/gems/ruby-1.9.3-p194@equis/gems/spring-0.0.2/lib/spring/application.rb:53:in `block in run'
    from /Users/senny/.rvm/gems/ruby-1.9.3-p194@equis/gems/spring-0.0.2/lib/spring/application.rb:47:in `loop'
    from /Users/senny/.rvm/gems/ruby-1.9.3-p194@equis/gems/spring-0.0.2/lib/spring/application.rb:47:in `run'
    from /Users/senny/.rvm/gems/ruby-1.9.3-p194@equis/gems/spring-0.0.2/lib/spring/application.rb:43:in `start'
    from /Users/senny/.rvm/gems/ruby-1.9.3-p194@equis/gems/spring-0.0.2/lib/spring/application_manager.rb:60:in `block in start_child'
    from /Users/senny/.rvm/gems/ruby-1.9.3-p194@equis/gems/spring-0.0.2/lib/spring/application_manager.rb:55:in `fork'
    from /Users/senny/.rvm/gems/ruby-1.9.3-p194@equis/gems/spring-0.0.2/lib/spring/application_manager.rb:55:in `start_child'
    from /Users/senny/.rvm/gems/ruby-1.9.3-p194@equis/gems/spring-0.0.2/lib/spring/application_manager.rb:17:in `start'
    from /Users/senny/.rvm/gems/ruby-1.9.3-p194@equis/gems/spring-0.0.2/lib/spring/application_manager.rb:36:in `block in run'
    from <internal:prelude>:10:in `synchronize'
    from /Users/senny/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/mutex_m.rb:62:in `mu_synchronize'
    from /Users/senny/.rvm/gems/ruby-1.9.3-p194@equis/gems/spring-0.0.2/lib/spring/application_manager.rb:35:in `run'
    from /Users/senny/.rvm/gems/ruby-1.9.3-p194@equis/gems/spring-0.0.2/lib/spring/server.rb:28:in `block in boot'
    from /Users/senny/.rvm/gems/ruby-1.9.3-p194@equis/gems/spring-0.0.2/lib/spring/server.rb:28:in `loop'
    from /Users/senny/.rvm/gems/ruby-1.9.3-p194@equis/gems/spring-0.0.2/lib/spring/server.rb:28:in `boot'
    from /Users/senny/.rvm/gems/ruby-1.9.3-p194@equis/gems/spring-0.0.2/lib/spring/server.rb:9:in `boot'
    from /Users/senny/.rvm/gems/ruby-1.9.3-p194@equis/gems/spring-0.0.2/lib/spring/server.rb:59:in `<main>'

I'm running spring inside one of our production rails apps (3.2.9) with the following command:
spring rspec spec/functional

JRuby Support

I have been playing with the idea of JRuby support for a few days now, and figured that I would see if you would be interested before I put too much work into it.

I have been using drip under JRuby for a little while to help speedup the general process launch case, but I would love to get something working directly with spring.

The only real issue with the current code base (that I can see) under JRuby is the usage of Kernel.fork and Process.spawn. Obviously, running under the JVM fork isn't available.

The easiest (still not simple) solution that I can see is to use the api provided by childprocess and refactor the code where fork and spawn are called to allow them to be called directly from the command line.

It would still use fork under *nix, but under JRuby it would use java.lang.ProcessBuilder to build up a process. Alternatively, we could set childprocess to use posix_spawn mode so that both are on equal footing.

command to stop everything

While debugging it's pretty annoying to stop everything and get a clean slate to try again. I think it would help if we have some kind of "reset" command to shut everything down and get the project into a clean state.

executing spring outside RAILS_ROOT results in NoMethodError

When calling spring outside the RAILS_ROOT directory I get the following error:

/Users/senny/.rvm/gems/ruby-1.9.3-p194@equis/gems/spring-0.0.2/lib/spring.rb:66:in `ensure in run': undefined method `close' for nil:NilClass (NoMethodError)
    from /Users/senny/.rvm/gems/ruby-1.9.3-p194@equis/gems/spring-0.0.2/lib/spring.rb:66:in `run'
    from /Users/senny/.rvm/gems/ruby-1.9.3-p194@equis/gems/spring-0.0.2/lib/spring.rb:19:in `run'
    from /Users/senny/.rvm/gems/ruby-1.9.3-p194@equis/gems/spring-0.0.2/bin/spring:5:in `<top (required)>'
    from /Users/senny/.rvm/gems/ruby-1.9.3-p194@equis/bin/spring:19:in `load'
    from /Users/senny/.rvm/gems/ruby-1.9.3-p194@equis/bin/spring:19:in `<main>'

This happens for subdirectories of your rails application as well as directories outside a rails app.

Figure out integration for 3rd-party commands

Ideally if somebody wants an rspec command, it should be in another gem, rather than in spring (either rspec or rspec-spring or something).

Therefore, they should be able to add something like:

require "rspec/spring"

To their config/spring.rb

However, this require activating the gem, which we don't want to do when running the spring client (because it's slow).

So we either need to stop loading config/spring.rb when running the spring client, or figure out some other integration method.

FactoryGirl seems not to like Spring

Because zeus seems to have a problem with rspec-guard I looked into spring today tried it with

spring rspec spec

and of 550 rspec tests 55 failed... running them standalone with just plain rspec works without errors.

All the error messages look like this:

  26) api/v1/images/show with image should return the image preview url for download
     Failure/Error: let(:image) { FactoryGirl.build_stubbed(:image_without_file) }
     ActiveRecord::AssociationTypeMismatch:
       Client(#70184004674200) expected, got Client(#70184002607880)
     # ./spec/views/api/v1/images/show_spec.rb:4:in `block (2 levels) in <top (required)>'
     # ./spec/views/api/v1/images/show_spec.rb:8:in `block (2 levels) in <top (required)>'
     # <internal:prelude>:10:in `synchronize'
     # -e:1:in `<main>'

After a little searching I came across this stackoverflow articles which describes an issue which sounds very similar....

Has anybody tested the combination of spring & rspec and factorygirl?
By the way I am using Ruby 1.9.3, Rails 3.2.9 and latest rspec and factory girl...

Cheers,

Govinda

cannot load such file -- fiddle (LoadError) (0.0.6, Rails 3.2.12)

I just installed your gem (0.0.6) by adding it in the Gemfile, then running bundle update.

Then, I tried...

$ spring console

...but got:

/home/tom/.rvm/rubies/ruby-1.9.3-p327/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require': cannot load such file -- fiddle (LoadError)
    from /home/me/.rvm/rubies/ruby-1.9.3-p327/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require'

Any ideas?

tmp/spring directory needs to be configurable

When running in an environment like Vagrant, the project folder is shared into the VM. This means it's not possible to create a socket file under this directory:

/var/lib/gems/1.9.1/gems/spring-0.0.4/lib/spring/server.rb:28:in `initialize': Operation not permitted - /vagrant/tmp/spring/2249 (Errno::EPERM)
    from /var/lib/gems/1.9.1/gems/spring-0.0.4/lib/spring/server.rb:28:in `open'
    from /var/lib/gems/1.9.1/gems/spring-0.0.4/lib/spring/server.rb:28:in `boot'
    from /var/lib/gems/1.9.1/gems/spring-0.0.4/lib/spring/server.rb:9:in `boot'
    from -e:1:in `<main>'

Using /tmp/spring instead seems to work fine.

Issues with readline on OS X

When I run spring console I don't see the characters I type. I can still execute the entered command and it will print the response but I don't see anything while typing.

Avoid creating new server process if another one is already running

Currently, each spring server is strictly attached to the current terminal session, without caring about potential existing servers in the same project.

This means that if we open 3-4 terminal sessions in the same project and run a spring test command in each one of them, 8 processes will be created (4 spring servers + 4 spring apps loading the test environment).

Could this be optimized?

I think that if only a server process were allowed to exist it would solve this problem. So each time a server is about to be created, it will first check if there's already a running and if not, only then create a new server, else use the existing one.

Or maybe another solution would be to check the pid files in tmp/ and use the already existing ones if there are any.

Consider renaming?

I'm sure you're aware that that's a very popular Java framework, used frequently for web apps, called Spring. In case this was an oversight, you may want to consider renaming. Certainly name clashes happen across communities all the time, but given the domain overlap, the SEO for this is likely to be really wonky.

Console doesn't display prompt in OS X

Running bin/console loads the console but it's not displayed properly as you can see in the image below. Also I can't tell if it's a pry console:

Screen Shot 2013-02-22 at 11 37 27 AM

A proper console would look something like this (this is what I get by rails console):

Screen Shot 2013-02-22 at 2 14 11 PM

I'm on OS X Mountain Lion and I have pry-rails in my Gemfile.

cannot load such file -- spring/server

The latest published version is not working:

λ spring rspec spec/integrations/models/fiscal_shift_spec.rb 
-e:in `require': cannot load such file -- spring/server (LoadError)

λ spring console
-e:in `require': cannot load such file -- spring/server (LoadError)

Using bundler:

λ bundle exec spring console
/Users/sobrinho/Developer/.../vendor/bundle/ruby/1.9.1/gems/spring-0.0.2/lib/spring/application.rb:98:in `recv_io': file descriptor was not passed (msg_controllen=0 smaller than sizeof(struct cmsghdr)=12) (SocketError)
        from /Users/sobrinho/Developer/.../vendor/bundle/ruby/1.9.1/gems/spring-0.0.2/lib/spring/application.rb:98:in `redirect_output'
        from /Users/sobrinho/Developer/.../vendor/bundle/ruby/1.9.1/gems/spring-0.0.2/lib/spring/application.rb:64:in `serve'
        from /Users/sobrinho/Developer/.../vendor/bundle/ruby/1.9.1/gems/spring-0.0.2/lib/spring/application.rb:53:in `block in run'
        from /Users/sobrinho/Developer/.../vendor/bundle/ruby/1.9.1/gems/spring-0.0.2/lib/spring/application.rb:47:in `loop'
        from /Users/sobrinho/Developer/.../vendor/bundle/ruby/1.9.1/gems/spring-0.0.2/lib/spring/application.rb:47:in `run'
        from /Users/sobrinho/Developer/.../vendor/bundle/ruby/1.9.1/gems/spring-0.0.2/lib/spring/application.rb:43:in `start'
        from /Users/sobrinho/Developer/.../vendor/bundle/ruby/1.9.1/gems/spring-0.0.2/lib/spring/application_manager.rb:59:in `block in start_child'
        from /Users/sobrinho/Developer/.../vendor/bundle/ruby/1.9.1/gems/spring-0.0.2/lib/spring/application_manager.rb:55:in `fork'
        from /Users/sobrinho/Developer/.../vendor/bundle/ruby/1.9.1/gems/spring-0.0.2/lib/spring/application_manager.rb:55:in `start_child'
        from /Users/sobrinho/Developer/.../vendor/bundle/ruby/1.9.1/gems/spring-0.0.2/lib/spring/application_manager.rb:17:in `start'
        from /Users/sobrinho/Developer/.../vendor/bundle/ruby/1.9.1/gems/spring-0.0.2/lib/spring/application_manager.rb:36:in `block in run'
        from <internal:prelude>:10:in `synchronize'
        from /Users/sobrinho/.rbenv/versions/1.9.3-p327/lib/ruby/1.9.1/mutex_m.rb:62:in `mu_synchronize'
        from /Users/sobrinho/Developer/.../vendor/bundle/ruby/1.9.1/gems/spring-0.0.2/lib/spring/application_manager.rb:35:in `run'
        from /Users/sobrinho/Developer/.../vendor/bundle/ruby/1.9.1/gems/spring-0.0.2/lib/spring/server.rb:28:in `block in boot'
        from /Users/sobrinho/Developer/.../vendor/bundle/ruby/1.9.1/gems/spring-0.0.2/lib/spring/server.rb:28:in `loop'
        from /Users/sobrinho/Developer/.../vendor/bundle/ruby/1.9.1/gems/spring-0.0.2/lib/spring/server.rb:28:in `boot'
        from /Users/sobrinho/Developer/.../vendor/bundle/ruby/1.9.1/gems/spring-0.0.2/lib/spring/server.rb:9:in `boot'
        from /Users/sobrinho/Developer/.../vendor/bundle/ruby/1.9.1/gems/spring-0.0.2/lib/spring/server.rb:59:in `<main>'

I don't care about bundler, makes more sense to use spring without it.

Let's focus on require issue :)

Integrating with Guard

I'm having a hard time figuring out how to integrate this with guard. I would love to see this work with my current guard setup and would be even willing to write some code if someone gives me helpful pointers on what to do...

fiddle library missing

When I tried to run the tests under spec/lib it didn't work complaining about not finding 'fiddle'. I'd create a pull-request to add the 'fiddle' dependency if that was the only problem.

But that doesn't help because fiddle seems to depend on inherited_resources although it also doesn't declare this dependency in its gemspecs...

Maybe fiddle should be fixed before fixing this gem...

Better error message when fiddle cannot be required

We should explain that ruby needs to be compiled with the fiddle stdlib enabled, which required libffi to be installed on the system.

Actually I'd like to figure out if there's a way to avoid depending on fiddle, but I don't know if there is.

Spring ignores exit status

When I run rspec spec/failing_spec.rb ; echo $? the exit status is 1.

But spring always reports 0, regardless of whether the command succeeded or failed.

When I run spring rspec spec/failing_spec.rb ; echo $? the exit status is 0.

Reporting the wrong exit status breaks my test-runner shell, and might impact guard etc.

Rspec time spent overestimated when using Timecop

When I use Spring to run a spec that calls Timecop, Rspec's time estimate is way high.

$ time spring rspec spec/models/quiz_spec.rb 
.........................................

Finished in 48 minutes 10.14 seconds
41 examples, 0 failures


real    0m11.434s
user    0m0.266s
sys 0m0.054s

That spec has these lines:

      time_now = Time.now()
      time_future = time_now + 16*60 #moving 16 minutes forward (in seconds)
      Timecop.travel(time_future)

Note that Timecop.travel() doesn't execute a block. So it advances time 16 minutes and that must happen three times to account for the 48 minutes. I thought maybe I was using it wrong, but running this spec without Spring works fine:

$ time rspec spec/models/quiz_spec.rb 
Rack::File headers parameter replaces cache_control after Rack 1.5.
.........................................

Finished in 8.88 seconds
41 examples, 0 failures


real    0m15.876s
user    0m11.543s
sys 0m1.708s

Is this a bug or by design?

Should use rb-inotify

Currently, running top shows a spring app process consuming 10% of CPU. This is obviously unacceptable if you're going to work from a laptop.

Please, implement inotify support.

Ensure client and server versions match

The spring command is designed to be run outside of bundler, to keep it fast. This introduces the issue that the spring server may be at a different version to the spring client. So the first thing a server should do when a client connects is send its version. If the don't match, the client should exit with an error.

OS X issues (bad environment variable, file descriptor was not passed)

/Users/jack/.rvm/gems/ruby-1.9.3-p327@app-gemset/gems/spring-0.0.2/lib/spring/application_manager.rb:58:in `[]=': bad environment variable value (ArgumentError)

Originally had it in :development group, now trying at top level in gemfile. Neither seems to work. Have you come across this yourself?

cucumber

Any examples of support for cucumber?

Thx

REQ: aliases for Rails commands

Would like to do spring g migration AddFooToBar

Currently throws a couple errors:

/Users/turadg/.rbenv/versions/1.9.3-p327-perf/lib/ruby/gems/1.9.1/gems/spring-0.0.4/lib/spring/commands.rb:13:in `fetch': key not found: "g" (KeyError)
    from /Users/turadg/.rbenv/versions/1.9.3-p327-perf/lib/ruby/gems/1.9.1/gems/spring-0.0.4/lib/spring/commands.rb:13:in `command'
    from /Users/turadg/.rbenv/versions/1.9.3-p327-perf/lib/ruby/gems/1.9.1/gems/spring-0.0.4/lib/spring.rb:97:in `rails_env_for'
    from /Users/turadg/.rbenv/versions/1.9.3-p327-perf/lib/ruby/gems/1.9.1/gems/spring-0.0.4/lib/spring.rb:60:in `run'
    from /Users/turadg/.rbenv/versions/1.9.3-p327-perf/lib/ruby/gems/1.9.1/gems/spring-0.0.4/lib/spring.rb:21:in `run'
    from /Users/turadg/.rbenv/versions/1.9.3-p327-perf/lib/ruby/gems/1.9.1/gems/spring-0.0.4/bin/spring:5:in `<top (required)>'
    from /Users/turadg/.rbenv/versions/1.9.3-p327-perf/bin/spring:23:in `load'
    from /Users/turadg/.rbenv/versions/1.9.3-p327-perf/bin/spring:23:in `<main>'
/Users/turadg/.rbenv/versions/1.9.3-p327-perf/lib/ruby/gems/1.9.1/gems/spring-0.0.4/lib/spring/server.rb:34:in `serve': undefined method `chomp' for nil:NilClass (NoMethodError)
    from /Users/turadg/.rbenv/versions/1.9.3-p327-perf/lib/ruby/gems/1.9.1/gems/spring-0.0.4/lib/spring/server.rb:29:in `block in boot'
    from /Users/turadg/.rbenv/versions/1.9.3-p327-perf/lib/ruby/gems/1.9.1/gems/spring-0.0.4/lib/spring/server.rb:29:in `loop'
    from /Users/turadg/.rbenv/versions/1.9.3-p327-perf/lib/ruby/gems/1.9.1/gems/spring-0.0.4/lib/spring/server.rb:29:in `boot'
    from /Users/turadg/.rbenv/versions/1.9.3-p327-perf/lib/ruby/gems/1.9.1/gems/spring-0.0.4/lib/spring/server.rb:9:in `boot'
    from -e:1:in `<main>'

Pry and ruby-debug19 causes spring to hang

When I use this gems in a project, spring won't start (no error, just hangs).
Removing them from Gemfile and spring works normally.
Any ideas on what's going on?

Thanks!

does not work inside engines

Engines have a different directory structure than rails apps. Spring wants to load config/application.rb to boot up the application. Inside an engine we need to load the dummy application. Otherwise we get:

/Users/senny/Projects/spring/lib/spring/application.rb:30:in `require': cannot load such file -- ./config/application (LoadError)
    from /Users/senny/Projects/spring/lib/spring/application.rb:30:in `start'
    from /Users/senny/Projects/spring/lib/spring/application_manager.rb:67:in `block in start_child'
    from /Users/senny/Projects/spring/lib/spring/application_manager.rb:63:in `fork'
    from /Users/senny/Projects/spring/lib/spring/application_manager.rb:63:in `start_child'
    from /Users/senny/Projects/spring/lib/spring/application_manager.rb:17:in `start'
    from /Users/senny/Projects/spring/lib/spring/application_manager.rb:46:in `block in run'
    from <internal:prelude>:10:in `synchronize'
    from /Users/senny/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/mutex_m.rb:62:in `mu_synchronize'
    from /Users/senny/Projects/spring/lib/spring/application_manager.rb:36:in `run'
    from /Users/senny/Projects/spring/lib/spring/server.rb:37:in `serve'
    from /Users/senny/Projects/spring/lib/spring/server.rb:29:in `block in boot'
    from /Users/senny/Projects/spring/lib/spring/server.rb:29:in `loop'
    from /Users/senny/Projects/spring/lib/spring/server.rb:29:in `boot'
    from /Users/senny/Projects/spring/lib/spring/server.rb:9:in `boot'
    from -e:1:in `<main>'
/Users/senny/Projects/spring/lib/spring/application_manager.rb:51:in `run': undefined method `chomp' for nil:NilClass (NoMethodError)
    from /Users/senny/Projects/spring/lib/spring/server.rb:37:in `serve'
    from /Users/senny/Projects/spring/lib/spring/server.rb:29:in `block in boot'
    from /Users/senny/Projects/spring/lib/spring/server.rb:29:in `loop'
    from /Users/senny/Projects/spring/lib/spring/server.rb:29:in `boot'
    from /Users/senny/Projects/spring/lib/spring/server.rb:9:in `boot'
    from -e:1:in `<main>'
/Users/senny/Projects/spring/lib/spring.rb:102:in `run_command': undefined method `chomp' for nil:NilClass (NoMethodError)
    from /Users/senny/Projects/spring/lib/spring.rb:56:in `run'
    from /Users/senny/Projects/spring/lib/spring.rb:22:in `run'
    from /Users/senny/Projects/spring/bin/spring:5:in `<top (required)>'
    from bin/spring:16:in `load'
    from bin/spring:16:in `<main>'

crashes when no command is given

When no command is supplied spring crashes with:

/Users/senny/.rvm/gems/ruby-1.9.3-p194@equis/gems/spring-0.0.2/lib/spring/commands.rb:13:in `fetch': key not found: nil (KeyError)
    from /Users/senny/.rvm/gems/ruby-1.9.3-p194@equis/gems/spring-0.0.2/lib/spring/commands.rb:13:in `command'
    from /Users/senny/.rvm/gems/ruby-1.9.3-p194@equis/gems/spring-0.0.2/lib/spring.rb:72:in `rails_env_for'
    from /Users/senny/.rvm/gems/ruby-1.9.3-p194@equis/gems/spring-0.0.2/lib/spring.rb:44:in `run'
    from /Users/senny/.rvm/gems/ruby-1.9.3-p194@equis/gems/spring-0.0.2/lib/spring.rb:19:in `run'
    from /Users/senny/.rvm/gems/ruby-1.9.3-p194@equis/gems/spring-0.0.2/bin/spring:5:in `<top (required)>'
    from /Users/senny/.rvm/gems/ruby-1.9.3-p194@equis/bin/spring:19:in `load'
    from /Users/senny/.rvm/gems/ruby-1.9.3-p194@equis/bin/spring:19:in `<main>'

I know this is mostly a proof of concept and not refined. I just think I'll log every exception in an issue so you can decide which ones have priority.

"No such file or directory" error

Example:

/home/turnip/.rbenv/versions/1.9.3-p194-falcon/lib/ruby/gems/1.9.1/gems/spring-0.0.4/lib/spring/application_watcher.rb:33:in `mtime': No such file or directory - /home/turnip/Code/loco2/journeyplanner/lib/core_ext/time.rb (Errno::ENOENT)
    from /home/turnip/.rbenv/versions/1.9.3-p194-falcon/lib/ruby/gems/1.9.1/gems/spring-0.0.4/lib/spring/application_watcher.rb:33:in `block in compute_mtime'
    from /home/turnip/.rbenv/versions/1.9.3-p194-falcon/lib/ruby/gems/1.9.1/gems/spring-0.0.4/lib/spring/application_watcher.rb:33:in `map'
    from /home/turnip/.rbenv/versions/1.9.3-p194-falcon/lib/ruby/gems/1.9.1/gems/spring-0.0.4/lib/spring/application_watcher.rb:33:in `compute_mtime'
    from /home/turnip/.rbenv/versions/1.9.3-p194-falcon/lib/ruby/gems/1.9.1/gems/spring-0.0.4/lib/spring/application_watcher.rb:27:in `stale?'
    from /home/turnip/.rbenv/versions/1.9.3-p194-falcon/lib/ruby/gems/1.9.1/gems/spring-0.0.4/lib/spring/application.rb:57:in `watch_application'
    from /home/turnip/.rbenv/versions/1.9.3-p194-falcon/lib/ruby/gems/1.9.1/gems/spring-0.0.4/lib/spring/application.rb:50:in `block in run'
    from /home/turnip/.rbenv/versions/1.9.3-p194-falcon/lib/ruby/gems/1.9.1/gems/spring-0.0.4/lib/spring/application.rb:49:in `loop'
    from /home/turnip/.rbenv/versions/1.9.3-p194-falcon/lib/ruby/gems/1.9.1/gems/spring-0.0.4/lib/spring/application.rb:49:in `run'
    from /home/turnip/.rbenv/versions/1.9.3-p194-falcon/lib/ruby/gems/1.9.1/gems/spring-0.0.4/lib/spring/application.rb:45:in `start'
    from /home/turnip/.rbenv/versions/1.9.3-p194-falcon/lib/ruby/gems/1.9.1/gems/spring-0.0.4/lib/spring/application_manager.rb:67:in `block in start_child'
    from /home/turnip/.rbenv/versions/1.9.3-p194-falcon/lib/ruby/gems/1.9.1/gems/spring-0.0.4/lib/spring/application_manager.rb:63:in `fork'
    from /home/turnip/.rbenv/versions/1.9.3-p194-falcon/lib/ruby/gems/1.9.1/gems/spring-0.0.4/lib/spring/application_manager.rb:63:in `start_child'
    from /home/turnip/.rbenv/versions/1.9.3-p194-falcon/lib/ruby/gems/1.9.1/gems/spring-0.0.4/lib/spring/application_manager.rb:17:in `start'
    from /home/turnip/.rbenv/versions/1.9.3-p194-falcon/lib/ruby/gems/1.9.1/gems/spring-0.0.4/lib/spring/application_manager.rb:46:in `block in run'
    from <internal:prelude>:10:in `synchronize'
    from /home/turnip/.rbenv/versions/1.9.3-p194-falcon/lib/ruby/1.9.1/mutex_m.rb:62:in `mu_synchronize'
    from /home/turnip/.rbenv/versions/1.9.3-p194-falcon/lib/ruby/gems/1.9.1/gems/spring-0.0.4/lib/spring/application_manager.rb:36:in `run'
    from /home/turnip/.rbenv/versions/1.9.3-p194-falcon/lib/ruby/gems/1.9.1/gems/spring-0.0.4/lib/spring/server.rb:36:in `serve'
    from /home/turnip/.rbenv/versions/1.9.3-p194-falcon/lib/ruby/gems/1.9.1/gems/spring-0.0.4/lib/spring/server.rb:29:in `block in boot'
    from /home/turnip/.rbenv/versions/1.9.3-p194-falcon/lib/ruby/gems/1.9.1/gems/spring-0.0.4/lib/spring/server.rb:29:in `loop'
    from /home/turnip/.rbenv/versions/1.9.3-p194-falcon/lib/ruby/gems/1.9.1/gems/spring-0.0.4/lib/spring/server.rb:29:in `boot'
    from /home/turnip/.rbenv/versions/1.9.3-p194-falcon/lib/ruby/gems/1.9.1/gems/spring-0.0.4/lib/spring/server.rb:9:in `boot'
    from -e:1:in `<main>'

ApplicationWatcher should just tolerate ENOENT rather than exploding.

jruby support

I wanted to try this out on jruby (where the startup issues are even more prominent than mri) but saw that fork was used.

`rails s` ?

Am I missing something, or is there currently no way to replace rails s with spring ___ ?

ctrl+c do not stop the process

Hi,

Hitting ctrl+c during a rspec command don't kill the process.

I'm back to the bash but the command is still running and outputting (like when we call ctrl+z and bg on bash).

Consider renaming the `spring test` command

Bash has a built-in test command, which means things can get a bit confusing:

$ spring binstub test
$ export PATH=./bin:$PATH
$ which test
./bin/test
$ test test/unit/user_test.rb # runs the bash test built-in, no output
$ bin/test test/unit/user_test.rb # runs the spring binstub

Perhaps spring testunit would be more appropriate?

Confused about binstubs

I'm confused by the suggested use of binstubs.

We use bundle install --binstubs on all of our projects, which creates stubs such as bin/rails, bin/rspec, etc.

But the instructions imply that I should also run spin binstub rspec in order to overwrite the bin/rspec stub with one that uses spin. This feels like a world of pain as bundler and spin continually overwrite each other's binstubs. It's also not clear if spin will precede rspec with bundle exec, since bundler's bin/rspec stub is no longer there.

So how are we supposed to use both bunder and spin binstubs?

Don't watch any files outside the app root

This seemed like a nice idea at the time but it means we're watching lots more files than just those under the app root, so using more CPU and I think it's simpler to just say "spring will only notice changes under your app root". If you change e.g. a gem which resides on the filesystem then you'll need to stop spring to notice the changes.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.