summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorazul <azul@leap.se>2014-06-18 22:09:11 +0200
committerazul <azul@leap.se>2014-06-18 22:09:11 +0200
commit110bc16297d7736f1025bfa85f3551313e913d84 (patch)
tree588b0852cbafdaaa3dcc1c4284b30139e0480f08
parent3051a51a4b7d51994e7cd8d90f0cdf5f237a0a4d (diff)
parent240fd8f1efe9e76540787a17a13dcaf345c7933e (diff)
Merge pull request #172 from elijh/feature/customgem
Add support for custom gems via a dynamic Gemfile
-rw-r--r--Gemfile36
-rw-r--r--config/defaults.yml5
-rw-r--r--lib/gemfile_tools.rb85
3 files changed, 120 insertions, 6 deletions
diff --git a/Gemfile b/Gemfile
index ae11e0e..79e6e45 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,5 +1,7 @@
source 'https://rubygems.org'
+require File.expand_path('../lib/gemfile_tools.rb', __FILE__)
+
gem "rails", "~> 3.2.18"
gem "couchrest", "~> 1.1.3"
gem "couchrest_model", "~> 2.0.0"
@@ -10,9 +12,6 @@ gem "json"
gem "ruby-srp", "~> 0.2.1"
gem "rails_warden"
-gem 'leap_web_help', :path => 'engines/support'
-gem 'leap_web_billing', :path => 'engines/billing'
-
gem 'http_accept_language'
# To use debugger
@@ -45,7 +44,7 @@ group :test do
gem 'poltergeist' # headless js
gem 'launchy' # save_and_open_page
gem 'phantomjs-binaries' # binaries specific to the os
-
+
# moching and stubbing
gem 'mocha', '~> 0.13.0', :require => false
gem 'minitest-stub-const' # why?
@@ -53,7 +52,7 @@ group :test do
# generating test data
gem 'factory_girl_rails' # test data factories
gem 'faker' # names and numbers for test data
-
+
# billing tests
gem 'fake_braintree', require: false
end
@@ -81,3 +80,30 @@ end
# unreleased so far ... but leap_web_certs need it
gem 'certificate_authority', :git => 'https://github.com/cchandler/certificate_authority.git'
+
+#
+# include optional gems and engines
+#
+
+group :test do
+ enabled_engines('test').each do |gem_name, gem_dir|
+ gem gem_name, :path => gem_dir
+ end
+end
+
+group :development do
+ enabled_engines('development').each do |gem_name, gem_dir|
+ gem gem_name, :path => gem_dir
+ end
+end
+
+group :production do
+ enabled_engines('production').each do |gem_name, gem_dir|
+ gem gem_name, :path => gem_dir
+ end
+end
+
+custom_gems.each do |gem_name, gem_dir|
+ gem gem_name, :path => gem_dir
+end
+
diff --git a/config/defaults.yml b/config/defaults.yml
index 1c7e694..0614d1e 100644
--- a/config/defaults.yml
+++ b/config/defaults.yml
@@ -34,7 +34,7 @@ common: &common
token_expires_after: 60
# handles that will be blocked from being used as logins or email aliases
# in addition to the ones in /etc/passwd and http://tools.ietf.org/html/rfc2142
- handle_blacklist: [certmaster, ssladmin, arin-admin, administrator, www-data, maildrop]
+ handle_blacklist: ['certmaster', 'ssladmin', 'arin-admin', 'administrator', 'www-data', 'maildrop', 'postmaster', 'admin', 'contact', 'info']
# handles that will be allowed despite being in /etc/passwd or rfc2142
handle_whitelist: []
# actions enabled in the account settings
@@ -46,6 +46,9 @@ common: &common
available_locales:
- :en
minimum_client_version: "0.5"
+ engines:
+ - support
+ - billing
service_levels: &service_levels
service_levels:
diff --git a/lib/gemfile_tools.rb b/lib/gemfile_tools.rb
new file mode 100644
index 0000000..50798cb
--- /dev/null
+++ b/lib/gemfile_tools.rb
@@ -0,0 +1,85 @@
+#
+# Utilities for use in Gemfile, in order to support
+# enabling and disabling gems, and including custom gems
+# in the deployment.
+#
+# Dynamic code in Gemfile is incompatible with
+# `bundle install --deployment` because dynamic code might
+# produce new Gemfile.lock. For this reason, this app must
+# be deployed with `bundle install --path vendor/bundle` instead.
+#
+
+require 'yaml'
+
+#
+# custom gems are gems placed in config/customization/gems.
+# this are added at deploy time by the platform.
+# The Gemfile.lock is then rebuilt to take these into account.
+#
+def custom_gems
+ custom_gem_dir = File.expand_path('../../config/customization/gems', __FILE__)
+ Dir["#{custom_gem_dir}/*"].collect{|gem_dir|
+ resolve_gem_directory(gem_dir)
+ }.compact
+end
+
+#
+# returns an array of [engine_name, engine_path] from Rails.root/engines/* that are
+# enabled. Uses the 'engines' key from config.yml to determine if engine is enabled
+#
+def enabled_engines(environment)
+ if local_config[environment]
+ if local_config[environment][:engines]
+ local_config[environment][:engines].collect {|engine_dir|
+ full_dir_path = File.join(File.expand_path("../../engines", __FILE__), engine_dir)
+ resolve_gem_directory(full_dir_path)
+ }.compact
+ else
+ []
+ end
+ else
+ []
+ end
+end
+
+#
+# local_config can be accessed as an indifferent hash of
+# the merger of config/default.yml and config/config.yml
+#
+def local_config
+ @local_config ||= begin
+ # a quick and dirty indifferent hash (note: does not affect children):
+ empty_hash = {}
+ empty_hash.default_proc = proc{|h, k| h.key?(k.to_s) ? h[k.to_s] : nil}
+ ["defaults.yml", "config.yml"].inject(empty_hash.dup) {|config, file|
+ filepath = File.join(File.expand_path("../../config", __FILE__), file)
+ if File.exists?(filepath)
+ new_config = YAML.load_file(filepath)
+ ['development', 'test','production'].each do |env|
+ config[env] ||= empty_hash.dup
+ if new_config[env]
+ config[env].merge!(new_config[env])
+ end
+ end
+ end
+ config
+ }
+ end
+end
+
+#
+# return [gem_name, relative_gem_path] for gem at the specific directory
+# or nil if not actually a gem directory
+#
+def resolve_gem_directory(gem_dir)
+ if Dir.exists?(gem_dir)
+ gemspec = Dir["#{gem_dir}/*.gemspec"]
+ if gemspec.any?
+ gem_name = File.basename(gemspec.first).sub(/\.gemspec$/,'')
+ [gem_name, gem_dir]
+ end
+ else
+ puts "Warning: no gem at `#{gem_dir}`"
+ nil
+ end
+end