objectified_environments 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0dbbd5683857aac46cbc41e94b23c14acd7589e8
4
+ data.tar.gz: 3b966cafec177eed3f2f0dd1b3e213e6d7929133
5
+ SHA512:
6
+ metadata.gz: 4fa915c3b54bd57762abde66537f713fbf16e2bd1ed22d48e0e4594ed24f93c0c420380af61f3a3b6be807317be644a830f1fb1b829a465090145bf8711dfb26
7
+ data.tar.gz: b0d57fab7cd0f80a1f38f2bef26002fc94687246b5066a159b02b3988b3cdb107c47d292cf2c5b37aaaa477cdbc806b5db1285300c6cbcceb4824546b16a5575
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.travis.yml ADDED
@@ -0,0 +1,29 @@
1
+ rvm:
2
+ - "2.0.0"
3
+ - "1.9.3"
4
+ - "1.9.2"
5
+ - "1.8.7"
6
+ - "jruby-1.7.4"
7
+ env:
8
+ - OBJECTIFIED_ENVIRONMENTS_RAILS_TEST_VERSION=3.0.20
9
+ - OBJECTIFIED_ENVIRONMENTS_RAILS_TEST_VERSION=3.1.12
10
+ - OBJECTIFIED_ENVIRONMENTS_RAILS_TEST_VERSION=3.2.14
11
+ - OBJECTIFIED_ENVIRONMENTS_RAILS_TEST_VERSION=4.0.0
12
+ # - OBJECTIFIED_ENVIRONMENTS_RAILS_TEST_VERSION=master
13
+ matrix:
14
+ exclude:
15
+ - rvm: 1.8.7
16
+ env: OBJECTIFIED_ENVIRONMENTS_RAILS_TEST_VERSION=4.0.0
17
+ - rvm: 1.9.2
18
+ env: OBJECTIFIED_ENVIRONMENTS_RAILS_TEST_VERSION=4.0.0
19
+ - rvm: 1.8.7
20
+ env: OBJECTIFIED_ENVIRONMENTS_RAILS_TEST_VERSION=master
21
+ - rvm: 1.9.2
22
+ env: OBJECTIFIED_ENVIRONMENTS_RAILS_TEST_VERSION=master
23
+ allow_failures:
24
+ - rvm: 1.9.3
25
+ env: OBJECTIFIED_ENVIRONMENTS_RAILS_TEST_VERSION=master
26
+ - rvm: 2.0.0
27
+ env: OBJECTIFIED_ENVIRONMENTS_RAILS_TEST_VERSION=master
28
+ - rvm: jruby-1.7.4
29
+ env: OBJECTIFIED_ENVIRONMENTS_RAILS_TEST_VERSION=master
data/Gemfile ADDED
@@ -0,0 +1,17 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in objectified_environments.gemspec
4
+ gemspec
5
+
6
+ rails_version = ENV['OBJECTIFIED_ENVIRONMENTS_RAILS_TEST_VERSION']
7
+ rails_version = rails_version.strip if rails_version
8
+
9
+ version_spec = case rails_version
10
+ when nil then nil
11
+ when 'master' then { :git => 'git://github.com/rails/rails.git' }
12
+ else "=#{rails_version}"
13
+ end
14
+
15
+ if version_spec
16
+ gem("rails", version_spec)
17
+ end
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2013, Andrew Geweke
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,196 @@
1
+ # ObjectifiedEnvironments
2
+
3
+ Vastly improve maintainability of your Rails.env-dependent code by using object-oriented environments. Supports Rails 3.x and 4.x, running on Ruby 1.8.7 (3.x only), 1.9.2, 1.9.3, 2.0.0, and JRuby 1.7.4.
4
+
5
+ Current build status: ![Current Build Status](https://api.travis-ci.org/ageweke/objectified_environments.png?branch=master)
6
+
7
+ ## What? Why?
8
+
9
+ Before:
10
+
11
+ class UsersController < ApplicationController
12
+ def create_user_from_remote
13
+ ...
14
+
15
+ timeout = case Rails.env
16
+ when 'development' then 10
17
+ when 'test' then 300
18
+ when 'qa', 'beta' then 30
19
+ else 5
20
+ end
21
+
22
+ Timeout::timeout(timeout) {
23
+ ...
24
+ }
25
+
26
+ ...
27
+ end
28
+ end
29
+
30
+ After:
31
+
32
+ class UsersController < ApplicationController
33
+ def create_user_from_remote
34
+ ...
35
+ Timeout::timeout(Rails.objenv.timeout_for_create_user_from_remote) {
36
+ ...
37
+ }
38
+ ...
39
+ end
40
+ end
41
+
42
+ You get:
43
+
44
+ * Elegant encapsulation of environment settings: they're just methods on a class that you define.
45
+ * All the power of Ruby to define those settings: inheritance, encapsulation, modules, delegation, and anything else you want.
46
+ * Utter [DRYness](http://en.wikipedia.org/wiki/Don't_repeat_yourself) of your environment code: if the `production` and `qa` environments are *almost* the same, you have a single superclass that defines all the ways in which they're the same &mdash; and the `Production` and `Qa` subclasses override only the things that vary in those environments. (Want to know why QA is behaving differently from production? Just open up its environment file!)
47
+ * Trivial maintenance of developer- or host-specific settings: if your login name is `joe`, create an environment `users/joe_development.rb` that subclasses `development.rb`, and override only what you want changed. And **check it in**. Now your fellow developers can refactor your changes along with everything else &mdash; and know why your machine behaves differently from everyone else's.
48
+ * Easy creation of new environments: inherit from (or factor out a common superclass from) the environment that is most like your new one, and then override only what you need.
49
+ * Wonderful behavior if you forget a setting: depending on the superclass, you'll get a reasonable default or a blindingly-obvious message about what you need to set, rather than an unintended and possibly-awful fallback.
50
+
51
+ ## Wait, what? Really, why?
52
+
53
+ In large Ruby systems, there is inevitably a *lot* of behavior that is environment-dependent &mdash; cache sizes,
54
+ API keys, timeouts, debugging information, and so on. Rails' default environment mechanism does not accommodate
55
+ such large projects particularly well, and often big maintenance headaches ensue.
56
+
57
+ ### The Theory
58
+
59
+ The way you are supposed to manage this is to create configuration points throughout your code, and set them in
60
+ the environment files in `config/environments`:
61
+
62
+ class UsersController
63
+ cattr_accessor :timeout_for_create_user_from_remote
64
+
65
+ def create_user_from_remote
66
+ Timeout::timeout(timeout_for_create_user_from_remote) {
67
+ ...
68
+ }
69
+ end
70
+ end
71
+
72
+ And then, for example, in `config/environments`:
73
+
74
+ development.rb:
75
+ ...
76
+ UsersController.timeout_for_create_user_from_remote = 10
77
+ ...
78
+ test.rb:
79
+ ...
80
+ UsersController.timeout_for_create_user_from_remote = 300
81
+ ...
82
+ qa.rb:
83
+ ...
84
+ UsersController.timeout_for_create_user_from_remote = 30
85
+ ...
86
+ beta.rb:
87
+ ...
88
+ UsersController.timeout_for_create_user_from_remote = 30
89
+ ...
90
+ production.rb:
91
+ ...
92
+ UsersController.timeout_for_create_user_from_remote = 5
93
+ ...
94
+
95
+ This does work. However, as you create more environments, you end up with more and more files that are almost always
96
+ copy-and-pasted from each other, suffering many of the problems that [Repeating Yourself](http://en.wikipedia.org/wiki/Don't_repeat_yourself) causes. Can you be certain that whoever creates a new environment has carefully thought through every single setting? Can you be certain that, when a developer creates a new setting, they have carefully added it to every environment file? And when someone needs to change a default, they have to go edit every single environment file and carefully think about it. (Is QA's timeout set to 5 for a good reason, or just because it was copy-and-pasted from production's?)
97
+
98
+ Compared to the above, using `objectified_environments` gives you significant improvements in maintainability, extension, and reliability.
99
+
100
+ ### The Practice
101
+
102
+ In reality, unless your developers have incredible discipline, you very often end up with something different, like our first example above: code strewn all over your codebase, explicitly testing against `Rails.env`.
103
+
104
+ **This is a disaster**:
105
+
106
+ * When someone adds a new environment, they need to search *your entire codebase* for tests against `Rails.env` (or `RAILS_ENV`, or `ENV['RAILS_ENV']`), sit and think about every single one, figure out what the right value for the new environment is, and insert it.
107
+ * If someone misses a setting, then, depending on the exact syntax of the code in question (is there an `else` clause? does it use a default value, or raise an exception?), you might: get a reasonable value, get an exception that's clear, get an exception that's very unclear (maybe that variable just stays `nil`, and this causes problems far, far from the call site), or, worst of all, get silent failures that cause bad data in your database, bad pages or API results, or so on.
108
+ * Do you want to know how QA and production differ? Go search the entire codebase again, and think about each one.
109
+
110
+ When code is built in such a way that it naturally tends to cause problems, blaming developers (we're creative! we're wonderful! we're [lazy](http://threevirtues.com/)!) is the cheap way out. Let's build systems that make the easy way also the *right* way.
111
+
112
+ ### The Solution
113
+
114
+ `objectified_environments` simply instantiates a class named after your `Rails.env` setting and binds it to `Rails.objenv`. You can then add methods to those classes, make them inherit from each other, override methods in subclasses, use delegation, modules, and any other tools that Ruby gives you to make them behave appropriately. The result is an easy-to-maintain, powerful environment system that makes it easy to add new environments, figure out the differences between environments, and so on.
115
+
116
+ ## Installation
117
+
118
+ 1. In any supported Rails environment, add this to your Gemfile, and then run `bundle install`:
119
+
120
+ gem 'objectified_environments'
121
+
122
+ 1. Run the generator:
123
+
124
+ rails generate objectified_environments
125
+
126
+ 1. This will generate a hierarchy of classes in `config/lib/objenv`, as so:
127
+
128
+ ObjectifiedEnvironments::Base # this is built-in to the Gem
129
+ Objenv::Environment # 'Objenv::' prefix is required for your classes
130
+ Objenv::LocalEnvironment
131
+ Objenv::Development
132
+ Objenv::Test
133
+ Objenv::ProductionEnvironment
134
+ Objenv::Production
135
+
136
+ 1. If you have any environments beyond the standard three (`development`, `test`, and `production`) defined in `config/environments`, you'll also have classes defined for them. However, because the gem cannot know the proper superclass for them, they will all derive directly from the base `Objenv::Environment` class. Feel free to change this.
137
+
138
+ ## Usage
139
+
140
+ The *only* change this makes in your system is that now `Rails.objenv` will automatically be a reference to an instance of whatever class is named the same as your environment (using Rails' camel-casing conventions) in the `Objenv::` namespace. This enables all the functionality above, but does not require any immediate changes.
141
+
142
+ As you introduce new features &mdash; or want to move existing ones to this system &mdash; simply add a method to one or more of these classes, and call it from your code via `Rails.objenv.my_method`. How you do this depends on the desired behavior of the code in question:
143
+
144
+ * **Reasonable default, needs to be overridden in some environments**: Add the method to `Objenv::Environment` returning the right value or doing the right thing. Override it in whatever subclasses need a different value.
145
+ * **No reasonable default, needs to be defined in all environments**: While you don't need to define the method on `Objenv::Environment`, doing so in such a way that raises an exception (the `ObjectifiedEnvironments::Base#must_implement` method will do this automatically for you) is a nice way to make it clear to other developers that they need to implement this method &mdash; and lets them instantly see what's going on if they forget to override it.
146
+
147
+ **The `LocalEnvironment` and `ProductionEnvironment` classes**: These classes are created by the generator for convenience' sake. Typically, the `development` and `test` environments have a lot in common. The generator sets up `Development` and `Test` to inherit from `LocalEnvironment` &mdash; so, if you put the code they have in common in `LocalEnvironment`, it will automatically be shared. And while Rails does not ship with a default `qa`, `beta`, or other such environment, these are incredibly common and almost always share a lot of code with `production`. Thus, `ProductionEnvironment` is created as a good place for this code.
148
+
149
+ Note that these are all simply suggestions; there is nothing more mysterious going on here than ordinary Ruby object-oriented structure. Do whatever works best for you. The generator sets up defaults that seem reasonable according to the author of this Gem, but the world is yours, and the Gem doesn't enforce any particular structure at all.
150
+
151
+ You may also wish to explore creating methods that actually do things, rather than simply returning configuration information. For example, having a method that returns the client object for Memcached can be very powerful, because now your environment can do anything it needs to do to set up that client &mdash; potentially returning a proxy for multiple servers, for example &mdash; rather than being restricted to only returning a single host and port.
152
+
153
+ ### User- and Host-Specific Environments
154
+
155
+ Often, developers want to override certain environmental behavior on just machines they're logged into. Sometimes, we want to change environmental behavior on only particular hosts. Typically this is done via some (gross) combination of leaving environment files modified, adding a new 'local environment' file and calling it from the end of the master environment file, or even automating this with `patch`, `sed`, or some other such tool.
156
+
157
+ No matter what system is used to do this, it has significant drawbacks &mdash; one of the biggest of which is that these 'local changes' are almost never visible to other developers. If you've changed `MyController.user_cache_size` on your machine, and then someone else renames it to `MyController.people_cache_size`, then at best your next pull breaks your development environment in a very frustrating way &mdash; and at worst, your cache-size change is now forever silently ignored.
158
+
159
+ `objectified_environments` provides a better way. If you are logged in as user `acid_burn` on a machine called `the_gibson` with `Rails.env` set to `development`, then the Gem will assign to `Rails.objenv` the first class that exists from the following list:
160
+
161
+ Objenv::UserHost::AcidBurnTheGibsonDevelopment
162
+ Objenv::Host::TheGibsonDevelopment
163
+ Objenv::User::AcidBurnDevelopment
164
+ Objenv::Development
165
+
166
+ Thus, you can create `Objenv::User::AcidBurnDevelopment` as a subclass of `Objenv::Development`, override whatever settings you want, and *check it in*. Now, all other developers can see what you've overridden locally, cleanly change it for you if they're refactoring, and so on.
167
+
168
+ It is possible to tie yourself into insane knots by creating massive numbers of user-specific, host-specific, and (especially) user-and-host-specific overrides this way. We recommend keeping this extremely simple &mdash; but the power is there, if you need it.
169
+
170
+ ### Relationship with `config/environments` files
171
+
172
+ Because Rails still loads files in `config/environments` for each environment, you will need to keep those files there and create them for any new environments you make, in addition to `Objenv::` classes &mdash; Rails really doesn't like not having one. (A patch that eliminates this requirement would be fantastic!)
173
+
174
+ Also, the configuration done in these files is *not* automatically subsumed by `objectified_environments`. If you wish (and it's highly recommended), you can move this code into the objectified environments, call it from the files in `config/environments`, and refactor it in any way you want. (The generator doesn't move this code automatically because the files in `config/environments` can contain any arbitrary Ruby code that's structured in any manner you want, and doing this safely borders on the impossible.)
175
+
176
+ ### A Few Last Details:
177
+
178
+ * Once you install this gem, having an `Objenv::` class defined that matches your `Rails.env` setting is **mandatory**. This is required because otherwise we would have no idea what object to assign to `Rails.objenv`.
179
+ * The `Objenv::` namespace prefix requirement is so that environment names won't conflict with any classes of your own that you define with these names. (If you want to create a class called `Development` for other purposes, we don't want to stop you.)
180
+ * There is no requirement that your classes inherit from `ObjectifiedEnvironments::Base`; they can be any kind of Ruby object. They must be able to be instantiated with either no arguments, or one argument; if the constructor accepts an argument, it will be passed a hash containing `:rails_env`, `:user_name`, and `:host_name`. `ObjectifiedEnvironments::Base` stores this away and exposes it via *private* methods. (The fact that they're private is important; having you call `Rails.objenv.rails_env` subverts the entire system.)
181
+ * There is actually no requirement that your environment classes live under `config/lib`; this is merely a convention. As long as Rails is able to find them using its autoloading behavior, they will work just fine.
182
+ * `ObjectifiedEnvironments::Base` defines a nice `must_implement` method that simply raises an exception, saying you must implement a method. This is a nice thing to call in methods you define in `Environment` that have no reasonable default.
183
+
184
+ ## Contributing
185
+
186
+ 1. Fork it
187
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
188
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
189
+ 4. Push to the branch (`git push origin my-new-feature`)
190
+ 5. Create new Pull Request
191
+
192
+ While I thoroughly encourage any and all contributions, ideas, bug reports, bug fixes, and so on, I do request that you include full tests (specs) in your patch if you do contribute a patch back.
193
+
194
+ ## License
195
+
196
+ This code is licensed under the terms in the accompanying `LICENSE` file.
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,16 @@
1
+ module ObjectifiedEnvironments
2
+ class Base
3
+ def initialize(environment_properties)
4
+ @rails_env = environment_properties[:rails_env]
5
+ @user_name = environment_properties[:user_name]
6
+ @host_name = environment_properties[:host_name]
7
+ end
8
+
9
+ private
10
+ attr_reader :rails_env, :user_name, :host_name
11
+
12
+ def must_implement
13
+ raise "You must override this method in #{self.class.name} or a superclass."
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,58 @@
1
+ require File.join(File.dirname(__FILE__), 'rails_requirer')
2
+
3
+ module ObjectifiedEnvironments
4
+ class DataProvider
5
+ def rails_env
6
+ @rails_env ||= begin
7
+ out = Rails.env || ''
8
+ if out.strip.length == 0
9
+ raise "#{self.name}: There appears to be no Rails.env set; I can't create an objectified environment for you. I don't know why this would happen. Rails.env is: #{Rails.env.inspect}"
10
+ end
11
+
12
+ out
13
+ end
14
+ end
15
+
16
+ def user_name
17
+ @user_name ||= begin
18
+ require 'etc'
19
+
20
+ candidates = [ Etc.getlogin, ENV['USER'], ENV['LOGNAME'], ENV['USERNAME'] ]
21
+ candidates = candidates.map { |c| c.strip unless (! c) || c.strip.length == 0 }.compact
22
+ candidates[0] || :none
23
+ end
24
+
25
+ @user_name unless @user_name == :none
26
+ end
27
+
28
+ def host_name
29
+ @host_name ||= begin
30
+ candidates = [ host_name_from_hostname_command, socket_gethostname ]
31
+ candidates = candidates.map { |c| normalize_hostname(c) }.compact
32
+ candidates[0] || :none
33
+ end
34
+
35
+ @host_name unless @host_name == :none
36
+ end
37
+
38
+ private
39
+ def host_name_from_hostname_command
40
+ out = `hostname`
41
+ out if $?.success? && out && out.strip.length > 0
42
+ end
43
+
44
+ def socket_gethostname
45
+ require 'socket'
46
+
47
+ out = Socket.gethostname rescue nil
48
+ out.strip if out && out.strip.length > 0
49
+ end
50
+
51
+ def normalize_hostname(hostname)
52
+ return nil unless hostname && hostname.strip.length > 0
53
+
54
+ out = hostname.strip.downcase.gsub(/[\-_]+/, '_')
55
+ out if out =~ /^[A-Z_][A-Z0-9_]*$/i # must be a valid Ruby identifier
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,97 @@
1
+ require 'objectified_environments/errors'
2
+
3
+ module ObjectifiedEnvironments
4
+ class EnvironmentBuilder
5
+ def initialize(data_provider)
6
+ @rails_env = normalize(data_provider.rails_env)
7
+ @user_name = normalize(data_provider.user_name)
8
+ @host_name = normalize(data_provider.host_name)
9
+
10
+ raise ArgumentError, "@rails_env is required: #{rails_env.inspect}" unless @rails_env && @rails_env.strip.length > 0
11
+ end
12
+
13
+ def environment
14
+ candidate_names = [ ]
15
+
16
+ candidate_names << class_name_for_candidate(@rails_env, @user_name, @host_name) if @user_name && @host_name
17
+ candidate_names << class_name_for_candidate(@rails_env, nil, @host_name) if @host_name
18
+ candidate_names << class_name_for_candidate(@rails_env, @user_name, @nil) if @user_name
19
+ candidate_names << class_name_for_candidate(@rails_env, nil, nil)
20
+
21
+ raise "This should be impossible: we should always have a candidate" unless candidate_names.length > 0
22
+
23
+ out = nil
24
+ candidate_names.each do |candidate_name|
25
+ klass = begin
26
+ candidate_name.constantize
27
+ rescue NameError
28
+ nil
29
+ end
30
+
31
+ return instantiate_from_class(klass) if klass
32
+ end
33
+
34
+ no_environment_found!(candidate_names)
35
+ end
36
+
37
+ private
38
+ def normalize(s)
39
+ s.strip unless (!s) || (s.strip.length == 0)
40
+ end
41
+
42
+ def class_name_for_candidate(rails_env, user_name, host_name)
43
+ rails_env = normalize(rails_env)
44
+ user_name = normalize(user_name)
45
+ host_name = normalize(host_name)
46
+
47
+ if user_name && host_name
48
+ target = "#{user_name}_#{host_name}_#{rails_env}"
49
+ "Objenv::UserHost::#{target.camelize}"
50
+ elsif host_name
51
+ target = "#{host_name}_#{rails_env}"
52
+ "Objenv::Host::#{target.camelize}"
53
+ elsif user_name
54
+ target = "#{user_name}_#{rails_env}"
55
+ "Objenv::User::#{target.camelize}"
56
+ else
57
+ "Objenv::#{rails_env.camelize}"
58
+ end
59
+ end
60
+
61
+ def instantiate_from_class(klass)
62
+ begin
63
+ constructor = klass.instance_method(:initialize)
64
+
65
+ args = [ ]
66
+ if constructor.arity != 0
67
+ args = [ { :rails_env => @rails_env, :user_name => @user_name, :host_name => @host_name } ]
68
+ end
69
+
70
+ return klass.new(*args)
71
+ rescue => e
72
+ raise ObjectifiedEnvironments::UnableToInstantiateEnvironmentError, %{We found a valid objectified environment class '#{klass.name}', but,
73
+ when we tried to instantiate it, we got the following exception:
74
+
75
+ #{e.class.name}: #{e.message}
76
+ #{e.backtrace.join("\n")}}
77
+ end
78
+ end
79
+
80
+ def no_environment_found!(candidate_names)
81
+ raise ObjectifiedEnvironments::EnvironmentMissingError, %{No ObjectifiedEnvironment definition was found.
82
+
83
+ Rails.env: #{@rails_env.inspect}
84
+ Username: #{@user_name.inspect}
85
+ Host name: #{@host_name.inspect}
86
+
87
+ This caused us to look for any environment named one of these (in order):
88
+
89
+ #{candidate_names.join("\n")}
90
+
91
+ ...but none of those exist.
92
+
93
+ You may want to run 'rails generate objectified_environments'.
94
+ }
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,5 @@
1
+ module ObjectifiedEnvironments
2
+ class ObjectifiedEnvironmentError < StandardError; end
3
+ class EnvironmentMissingError < ObjectifiedEnvironmentError; end
4
+ class UnableToInstantiateEnvironmentError < ObjectifiedEnvironmentError; end
5
+ end
@@ -0,0 +1,8 @@
1
+ # Rails 3.0 and later let you just "require 'rails'". Rails 2.3 is far less modular; you have to require
2
+ # activesupport and then, super-grossly, just raw 'initializer'. Ick. But it does work.
3
+ begin
4
+ require 'rails'
5
+ rescue LoadError => le
6
+ require 'activesupport'
7
+ require 'initializer'
8
+ end
@@ -0,0 +1,25 @@
1
+ require File.join(File.dirname(__FILE__), 'rails_requirer')
2
+
3
+ module ObjectifiedEnvironments
4
+ class Railtie < Rails::Railtie
5
+ initializer "objectified_environments.setup", :before => :load_environment_config do |app|
6
+ autoload_directory = File.expand_path(File.join(Rails.root, 'config', 'lib'))
7
+ ActiveSupport::Dependencies.autoload_paths << autoload_directory
8
+
9
+ unless defined?(Rails) && Rails.kind_of?(Module)
10
+ raise %{ObjectifiedEnvironments declares a dependency on Rails, and Rails appears to be
11
+ running our initialization code (the Railtie), yet Rails does not appear to be defined as a module.
12
+ We don't know what's wrong, and are bailing out lest we cause more problems. Please report this
13
+ issue, including the version of Rails you are running: #{Rails.version}.}
14
+ end
15
+
16
+ module ::Rails
17
+ class << self
18
+ def objenv
19
+ @_objectified_environment ||= ObjectifiedEnvironments.create_objectified_environment
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,3 @@
1
+ module ObjectifiedEnvironments
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,24 @@
1
+ require "objectified_environments/version"
2
+ require "objectified_environments/railtie"
3
+ require "objectified_environments/data_provider"
4
+ require "objectified_environments/environment_builder"
5
+ require "objectified_environments/base"
6
+ require "objectified_environments_generator"
7
+
8
+ module ObjectifiedEnvironments
9
+ class << self
10
+ def create_objectified_environment
11
+ eb = environment_builder.new(data_provider)
12
+ eb.environment
13
+ end
14
+
15
+ private
16
+ def environment_builder
17
+ ObjectifiedEnvironments::EnvironmentBuilder
18
+ end
19
+
20
+ def data_provider
21
+ @data_provider ||= ObjectifiedEnvironments::DataProvider.new
22
+ end
23
+ end
24
+ end