From 964ae7de19035a2baf9bc14cbc7a7a30e9ef68a3 Mon Sep 17 00:00:00 2001 From: Jonathan Jackson Date: Tue, 16 Dec 2014 13:17:27 -0500 Subject: [PATCH 1/5] Add locking feature to prevent stale code --- README.md | 14 ++++---------- lib/ember-cli-rails.rb | 2 ++ lib/ember-cli/app.rb | 19 +++++++++++++++++++ lib/ember-cli/middleware.rb | 18 ++++++++++++++++++ lib/ember-cli/railtie.rb | 4 ++++ 5 files changed, 47 insertions(+), 10 deletions(-) create mode 100644 lib/ember-cli/middleware.rb diff --git a/README.md b/README.md index 065c1864..7ccd3a22 100644 --- a/README.md +++ b/README.md @@ -58,18 +58,12 @@ EmberCLI.configure do |c| end ``` -Once you've updated your initializer to taste, you need to tell EmberCLI that -you want the meta tag to be served in your javascript. Open up your -`Brocfile.js` inside your EmberCLI app and add `{storeConfigInMeta: false}`. +Once you've updated your initializer to taste, you need to install the [ember-cli-rails-addon](https://github.com/rondale-sc/ember-cli-rails-addon). -It should look something like this (if you've left it unchanged): +For each of your EmberCLI applications install the addon with: -```javascript -var EmberApp = require('ember-cli/lib/broccoli/ember-app'); - -var app = new EmberApp({storeConfigInMeta: false}); - -// etc... +```sh +npm install --save-dev ember-cli-rails-addon ``` And that's it! diff --git a/lib/ember-cli-rails.rb b/lib/ember-cli-rails.rb index b19080b5..b4a80b7c 100644 --- a/lib/ember-cli-rails.rb +++ b/lib/ember-cli-rails.rb @@ -2,11 +2,13 @@ module EmberCLI extend self + TIMEOUT = 5 autoload :App, "ember-cli/app" autoload :Configuration, "ember-cli/configuration" autoload :ViewHelpers, "ember-cli/view_helpers" autoload :Helpers, "ember-cli/helpers" + autoload :Middleware, "ember-cli/middleware" def configure yield configuration diff --git a/lib/ember-cli/app.rb b/lib/ember-cli/app.rb index 2556ca9c..765a2aae 100644 --- a/lib/ember-cli/app.rb +++ b/lib/ember-cli/app.rb @@ -32,8 +32,27 @@ def exposed_css_assets %W[#{name}/vendor #{name}/#{ember_app_name}] end + def lock + require 'timeout' + Timeout::timeout(TIMEOUT) do + while File.file?(pre_lockfile) && !File.file?(post_lockfile) + sleep 0.1 + end + end + rescue + stop + end + private + def pre_lockfile + File.join(assets_path, 'preBuild.lock') + end + + def post_lockfile + File.join(assets_path, 'postBuild.lock') + end + delegate :ember_path, to: :configuration delegate :tee_path, to: :configuration delegate :configuration, to: :EmberCLI diff --git a/lib/ember-cli/middleware.rb b/lib/ember-cli/middleware.rb new file mode 100644 index 00000000..958c85e7 --- /dev/null +++ b/lib/ember-cli/middleware.rb @@ -0,0 +1,18 @@ +module EmberCLI + class Middleware + def initialize(app) + @app = app + end + + def call(env) + apps.map(&:lock) + @app.call(env) + end + + private + + def apps + EmberCLI.configuration.apps.values + end + end +end diff --git a/lib/ember-cli/railtie.rb b/lib/ember-cli/railtie.rb index 8dc56876..7f17a614 100644 --- a/lib/ember-cli/railtie.rb +++ b/lib/ember-cli/railtie.rb @@ -4,6 +4,10 @@ class Railtie < Rails::Railtie ActionView::Base.send :include, ViewHelpers end + initializer "ember-cli-rails.insert_middleware" do |app| + app.config.middleware.use "EmberCLI::Middleware" + end + initializer "ember-cli-rails.inflector" do ActiveSupport::Inflector.inflections :en do |inflect| inflect.acronym "CLI" From 38abcaf485e765fb26e4f48e37d1570f3731ea4a Mon Sep 17 00:00:00 2001 From: Pavel Pravosud Date: Wed, 17 Dec 2014 23:41:57 -0500 Subject: [PATCH 2/5] Refactor to use a newer addon version --- lib/ember-cli-rails.rb | 20 ++++---------- lib/ember-cli/app.rb | 50 ++++++++++++++++++++++------------ lib/ember-cli/configuration.rb | 6 +++- lib/ember-cli/middleware.rb | 16 +++++++++-- lib/ember-cli/railtie.rb | 4 --- 5 files changed, 56 insertions(+), 40 deletions(-) diff --git a/lib/ember-cli-rails.rb b/lib/ember-cli-rails.rb index b4a80b7c..a5fcc748 100644 --- a/lib/ember-cli-rails.rb +++ b/lib/ember-cli-rails.rb @@ -2,7 +2,6 @@ module EmberCLI extend self - TIMEOUT = 5 autoload :App, "ember-cli/app" autoload :Configuration, "ember-cli/configuration" @@ -28,20 +27,7 @@ def prepare! def enable! prepare! - - Rails.application.singleton_class.class_eval do - alias_method :call_without_ember_cli, :call - - def call(env) - @_ember_cli_enabled ||= begin - EmberCLI.compile! - EmberCLI.run! if Rails.env.development? - true - end - - call_without_ember_cli(env) - end - end + Rails.configuration.middleware.use Middleware end def run! @@ -58,6 +44,10 @@ def stop! each_app &:stop end + def wait! + each_app &:wait + end + def root @root ||= Rails.root.join("tmp", "ember-cli-#{uid}") end diff --git a/lib/ember-cli/app.rb b/lib/ember-cli/app.rb index 765a2aae..7a9822b1 100644 --- a/lib/ember-cli/app.rb +++ b/lib/ember-cli/app.rb @@ -1,5 +1,9 @@ +require "timeout" + module EmberCLI class App + ADDON_VERSION = "0.0.3" + attr_reader :name, :options, :pid def initialize(name, options={}) @@ -32,39 +36,49 @@ def exposed_css_assets %W[#{name}/vendor #{name}/#{ember_app_name}] end - def lock - require 'timeout' - Timeout::timeout(TIMEOUT) do - while File.file?(pre_lockfile) && !File.file?(post_lockfile) - sleep 0.1 - end + def wait + Timeout.timeout(build_timeout) do + sleep 0.1 while lockfile.exist? end - rescue - stop end private - def pre_lockfile - File.join(assets_path, 'preBuild.lock') - end - - def post_lockfile - File.join(assets_path, 'postBuild.lock') + def lockfile + app_path.join("tmp", "build.lock") end delegate :ember_path, to: :configuration + delegate :build_timeout, to: :configuration delegate :tee_path, to: :configuration delegate :configuration, to: :EmberCLI def prepare @prepared ||= begin + check_addon! + FileUtils.touch lockfile symlink_to_assets_root add_assets_to_precompile_list true end end + def check_addon! + dependencies = package_json.fetch("devDependencies", {}) + + unless dependencies["ember-cli-rails-addon"] == ADDON_VERSION + fail <<-MSG.strip_heredoc + EmberCLI Rails requires your Ember app to have an addon. + + Please run: + + $ npm install --save-dev ember-cli-rails-addon@#{ADDON_VERSION}` + + in you Ember application root: #{app_path} + MSG + end + end + def symlink_to_assets_root symlink_path = dist_path.join("assets") assets_path.join(name).make_symlink symlink_path unless symlink_path.exist? @@ -84,9 +98,7 @@ def log_pipe end def ember_app_name - @ember_app_name ||= options.fetch(:name) do - JSON.parse(app_path.join("package.json").read).fetch("name") - end + @ember_app_name ||= options.fetch(:name){ package_json.fetch(:name) } end def app_path @@ -111,5 +123,9 @@ def assets_path def environment Helpers.non_production?? "development" : "production" end + + def package_json + @package_json ||= JSON.parse(app_path.join("package.json").read).with_indifferent_access + end end end diff --git a/lib/ember-cli/configuration.rb b/lib/ember-cli/configuration.rb index 21302a02..bf79ea11 100644 --- a/lib/ember-cli/configuration.rb +++ b/lib/ember-cli/configuration.rb @@ -23,6 +23,10 @@ def ember_path end end - attr_writer :ember_path + def build_timeout + @build_timeout ||= 5 + end + + attr_writer :ember_path, :build_timeout end end diff --git a/lib/ember-cli/middleware.rb b/lib/ember-cli/middleware.rb index 958c85e7..c7483da6 100644 --- a/lib/ember-cli/middleware.rb +++ b/lib/ember-cli/middleware.rb @@ -5,14 +5,24 @@ def initialize(app) end def call(env) - apps.map(&:lock) + enable_ember_cli + EmberCLI.wait! + @app.call(env) end private - def apps - EmberCLI.configuration.apps.values + def enable_ember_cli + @enabled ||= begin + if Rails.env.development? + EmberCLI.run! + else + EmberCLI.compile! + end + + true + end end end end diff --git a/lib/ember-cli/railtie.rb b/lib/ember-cli/railtie.rb index 7f17a614..8dc56876 100644 --- a/lib/ember-cli/railtie.rb +++ b/lib/ember-cli/railtie.rb @@ -4,10 +4,6 @@ class Railtie < Rails::Railtie ActionView::Base.send :include, ViewHelpers end - initializer "ember-cli-rails.insert_middleware" do |app| - app.config.middleware.use "EmberCLI::Middleware" - end - initializer "ember-cli-rails.inflector" do ActiveSupport::Inflector.inflections :en do |inflect| inflect.acronym "CLI" From ad1b21d67b3ce0d590d4d1ca3cc1c2954b5616e1 Mon Sep 17 00:00:00 2001 From: Pavel Pravosud Date: Wed, 17 Dec 2014 23:43:17 -0500 Subject: [PATCH 3/5] Reformat README --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 7ccd3a22..9bc267d5 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,8 @@ EmberCLI.configure do |c| end ``` -Once you've updated your initializer to taste, you need to install the [ember-cli-rails-addon](https://github.com/rondale-sc/ember-cli-rails-addon). +Once you've updated your initializer to taste, you need to install the +[ember-cli-rails-addon](https://github.com/rondale-sc/ember-cli-rails-addon). For each of your EmberCLI applications install the addon with: From 605dbd711e0365757a1aadbf19bf5ca61d7675db Mon Sep 17 00:00:00 2001 From: Pavel Pravosud Date: Wed, 17 Dec 2014 23:43:31 -0500 Subject: [PATCH 4/5] Add addon version to README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9bc267d5..35f5fc3e 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ Once you've updated your initializer to taste, you need to install the For each of your EmberCLI applications install the addon with: ```sh -npm install --save-dev ember-cli-rails-addon +npm install --save-dev ember-cli-rails-addon@0.0.3 ``` And that's it! From 0ff1dfe564ff23caf29c46c03ff5675181e30054 Mon Sep 17 00:00:00 2001 From: Pavel Pravosud Date: Wed, 17 Dec 2014 23:55:31 -0500 Subject: [PATCH 5/5] Handle build timeouts, make timeout configurable per app --- lib/ember-cli/app.rb | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/lib/ember-cli/app.rb b/lib/ember-cli/app.rb index 7a9822b1..850eb2bf 100644 --- a/lib/ember-cli/app.rb +++ b/lib/ember-cli/app.rb @@ -40,19 +40,46 @@ def wait Timeout.timeout(build_timeout) do sleep 0.1 while lockfile.exist? end - end + rescue Timeout::Error + suggested_timeout = build_timeout + 5 - private + warn <<-MSG.strip_heredoc + ============================= WARNING! ============================= - def lockfile - app_path.join("tmp", "build.lock") + Seems like Ember #{name} application takes more than #{build_timeout} + seconds to compile. + + To prevent race conditions consider adjusting build timeout + configuration in your ember initializer: + + EmberCLI.configure do |config| + config.build_timeout = #{suggested_timeout} # in seconds + end + + Alternatively, you can set build timeout per application like this: + + EmberCLI.configure do |config| + config.app :#{name}, build_timeout: #{suggested_timeout} + end + + ============================= WARNING! ============================= + MSG end + private + delegate :ember_path, to: :configuration - delegate :build_timeout, to: :configuration delegate :tee_path, to: :configuration delegate :configuration, to: :EmberCLI + def build_timeout + options.fetch(:build_timeout){ configuration.build_timeout } + end + + def lockfile + app_path.join("tmp", "build.lock") + end + def prepare @prepared ||= begin check_addon!