env.rb 0.0.1

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/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in env.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,69 @@
1
+ # Env.rb
2
+ Managing your ENVironment
3
+
4
+ ## Purpose
5
+ Many modern web applications consume and post to resources that reside at other urls, often requiring
6
+ more authentication tokens than a database password. These passwords need to be stored in some
7
+ location. A common, secure location that exists outside of the source directory is in the
8
+ application's runtime environment.
9
+
10
+ However, consuming a resource at a url can take up to three different variables to represent
11
+ the location, username, and password. If your app is consuming many endpoints the sheer
12
+ number of variables can become overwhelming. Remember, the average short-term memory holds
13
+ about 7 items. Certain production applications can have upwards of 50 to 100 ENV vars.
14
+
15
+ Env.rb allows you to declare environment variables like dependencies and configure multiple
16
+ environments with a simple ruby DSL. It provides tools for cleaning up existing apps, exporting
17
+ your Envfile to a shell-compatible format, and executing scripts within your environments.
18
+
19
+ ## Examples
20
+
21
+ ### Declaring Dependecies
22
+
23
+ export "PROVIDER_PASSWORD", '1234', :group => :development, :required => false
24
+
25
+ group :development do
26
+ export "SERVICE_URL", 'http://username:password@www.service.com/path"
27
+ end
28
+
29
+ group :test do
30
+ export "SERVICE_URL", 'http://username:password@example.com/"
31
+ end
32
+
33
+ ### In your Ruby files
34
+
35
+ require 'env'
36
+
37
+ Env.load('../path_to_file')
38
+ Env.load! # look for Envfile
39
+
40
+ ENV['HELLO_WORLD'] # => nil
41
+ Env.enforce
42
+ ENV['HELLO_WORLD']
43
+ # => EnvironmentError: HELLO_WORLD is not a declared environment dependency
44
+
45
+ ENV['TEST'] = 'overriding'
46
+ # => EnvironmentError: TEST is not a declared environment dependency
47
+
48
+ Env.eval do
49
+ export 'TEXT', '15', :immutable => true
50
+ # same as export 'TEXT', '15', :mutable => false
51
+ end
52
+
53
+ ENV['TEST'] = 'overriding'
54
+ # => EnvironmentError: variable TEST cannot be changed
55
+
56
+ ## Built-in support for URIs
57
+
58
+ ### in Envfile
59
+ export "SERVICE", 'http://username:password@example.com/"
60
+
61
+ ### in your Ruby Script
62
+ ENV['SERVICE'] #=> 'http://username:password@example.com/"
63
+ ENV['SERVICE'].base_uri #=> 'http://example.com/"
64
+ ENV['SERVICE'].url #=> 'http://example.com/"
65
+ ENV['SERVICE'].user #=> 'username'
66
+ ENV['SERVICE'].password #=> 'password'
67
+ ENV['SERVICE'].host #=> 'example.com'
68
+ ENV['SERVICE'].scheme #=> 'http'
69
+
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ desc "start a console"
4
+ task :console do
5
+ require 'irb'
6
+ require_relative 'lib/env'
7
+ ARGV.clear
8
+ IRB.start
9
+ end
data/env.gemspec ADDED
@@ -0,0 +1,20 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "env/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "env.rb"
7
+ s.version = Env::VERSION
8
+ s.authors = ["Chris Continanza"]
9
+ s.email = ["christopher.continanza@gmail.com"]
10
+ s.homepage = ""
11
+ s.summary = %q{Manage your ENV with ease}
12
+ s.description = %q{Allows your to manage many ENV vars by declaring them as dependencies on ENV vars and then enforcing those dependencies. Supports wrapping URIs with support methods.}
13
+
14
+ s.rubyforge_project = "env.rb"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+ end
data/lib/env.rb ADDED
@@ -0,0 +1,87 @@
1
+ require "env/version"
2
+ require 'uri'
3
+ require 'forwardable'
4
+
5
+ class EnvironmentError < StandardError
6
+ end
7
+
8
+ module Env
9
+ @@dependencies = []
10
+ @@env = {}
11
+ @@enforced = false
12
+
13
+ class << self
14
+ def [](key)
15
+ _raise(key) unless dependencies.include? key
16
+ @@env[key]
17
+ end
18
+
19
+ def []=(key,value)
20
+ _raise(key) unless dependencies.include? key
21
+ @@env[key] = uri?(value) ? proxify(value) : value
22
+ end
23
+
24
+ def export(key, value = nil)
25
+ @@dependencies << key
26
+ @@env[key] = uri?(value) ? proxify(value) : value
27
+ end
28
+
29
+ def load!
30
+ @@enforced or Env.enforce
31
+ eval File.read("Envfile") if File.exist?("Envfile")
32
+ File.exist?("Envfile")
33
+ end
34
+
35
+ def enforce
36
+ class << ENV
37
+ alias_method :get, :[]
38
+ alias_method :set, :[]=
39
+
40
+ def [](key)
41
+ Env[key]
42
+ end
43
+
44
+ def []=(key, value)
45
+ Env[key] = value
46
+ end
47
+ end
48
+ @@enforced = true
49
+ end
50
+
51
+ private
52
+ def _raise(key)
53
+ raise EnvironmentError, "#{key} is not a declared depency, add it to your Envfile"
54
+ end
55
+
56
+ def uri?(value)
57
+ value.to_s.match(/^\w+:\/\//)
58
+ end
59
+
60
+ def proxify(value)
61
+ UriProxy.new(value)
62
+ end
63
+
64
+ def dependencies
65
+ @@dependencies
66
+ end
67
+ end
68
+
69
+ class UriProxy < BasicObject
70
+ extend ::Forwardable
71
+ def_delegators :@uri, :scheme, :user, :password, :host
72
+
73
+ def initialize(uri)
74
+ @original = uri
75
+ @uri = ::URI.parse(uri)
76
+ end
77
+
78
+ def base_uri
79
+ "#{@uri.scheme}://#{@uri.host}"
80
+ end
81
+ alias url base_uri
82
+
83
+ def method_missing(method, *args, &block)
84
+ @original.send(method, *args, &block)
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,3 @@
1
+ module Env
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,38 @@
1
+ require_relative '../lib/env'
2
+
3
+ describe Env, "::enforce" do
4
+ before { Env.enforce }
5
+
6
+ it "should not allow references to undeclared variables" do
7
+ lambda { ENV['UNDECLARED_VARIABLE'] }.should raise_error(EnvironmentError)
8
+ end
9
+
10
+ context "with uninitialized dependency FOO" do
11
+ before do
12
+ Env.instance_eval do
13
+ export 'FOO'
14
+ end
15
+ end
16
+
17
+ it "should return nil for ENV['FOO']" do
18
+ ENV['FOO'].should eql(nil)
19
+ end
20
+
21
+ it "should allow you to set it" do
22
+ ENV['FOO'] = 'bar'
23
+ ENV['FOO'].should eql('bar')
24
+ end
25
+ end
26
+
27
+ context "with initialized dependency FOO=bar" do
28
+ before do
29
+ Env.instance_eval do
30
+ export 'FOO', 'bar'
31
+ end
32
+ end
33
+
34
+ it "should return 'bar' for ENV['FOO']" do
35
+ ENV['FOO'].should eql('bar')
36
+ end
37
+ end
38
+ end
data/spec/load_spec.rb ADDED
@@ -0,0 +1,33 @@
1
+ require_relative '../lib/env'
2
+
3
+ describe Env, '::load!' do
4
+ def envfile(string)
5
+ File.open("Envfile", 'w') do |f|
6
+ f << string
7
+ end
8
+ end
9
+
10
+ it "should return false" do
11
+ Env.load!.should be_false
12
+ end
13
+
14
+ context "with a simple Envfile" do
15
+ before do
16
+ envfile(%{
17
+ export 'FOO', 'bar'
18
+ })
19
+ end
20
+
21
+ after { File.unlink('Envfile') }
22
+
23
+ it "should return true" do
24
+ Env.load!.should be_true
25
+ end
26
+
27
+ it "should load Envfile in this directory" do
28
+ Env.load!
29
+ Env.enforce
30
+ ENV['FOO'].should == 'bar'
31
+ end
32
+ end
33
+ end
data/spec/uri_spec.rb ADDED
@@ -0,0 +1,52 @@
1
+ require_relative '../lib/env'
2
+
3
+ describe Env, 'uri support' do
4
+ context "with a value FOO that is not a URI" do
5
+ before do
6
+ Env.instance_eval do
7
+ export 'FOO', 'bar'
8
+ end
9
+ Env.enforce
10
+ end
11
+
12
+ it "should not wrap it" do
13
+ lambda { ENV['FOO'].scheme }.should raise_error(::NoMethodError)
14
+ end
15
+ end
16
+
17
+ context "with a value FOO that is a URI" do
18
+ URL = 'http://username:password@this.domain.example.com/path?var=val'
19
+
20
+ before do
21
+ Env.instance_eval do
22
+ export 'FOO', URL
23
+ end
24
+ Env.enforce
25
+ end
26
+
27
+ it "should leave the original value unchanged" do
28
+ ENV['FOO'].should == URL
29
+ end
30
+
31
+ it "should return scheme://host for #base_uri and #url" do
32
+ ENV['FOO'].base_uri.should == 'http://this.domain.example.com'
33
+ ENV['FOO'].url.should == 'http://this.domain.example.com'
34
+ end
35
+
36
+ it "should respond to #scheme with the scheme'" do
37
+ ENV['FOO'].scheme.should == 'http'
38
+ end
39
+
40
+ it "should respond to #host with the host" do
41
+ ENV['FOO'].host.should == 'this.domain.example.com'
42
+ end
43
+
44
+ it "should respond to #password with the password" do
45
+ ENV['FOO'].password.should == 'password'
46
+ end
47
+
48
+ it "should respond to #user with the user" do
49
+ ENV['FOO'].user.should == 'username'
50
+ end
51
+ end
52
+ end
metadata ADDED
@@ -0,0 +1,62 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: env.rb
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Chris Continanza
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-08-04 00:00:00.000000000 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+ description: Allows your to manage many ENV vars by declaring them as dependencies
16
+ on ENV vars and then enforcing those dependencies. Supports wrapping URIs with
17
+ support methods.
18
+ email:
19
+ - christopher.continanza@gmail.com
20
+ executables: []
21
+ extensions: []
22
+ extra_rdoc_files: []
23
+ files:
24
+ - .gitignore
25
+ - Gemfile
26
+ - README.md
27
+ - Rakefile
28
+ - env.gemspec
29
+ - lib/env.rb
30
+ - lib/env/version.rb
31
+ - spec/enforce_spec.rb
32
+ - spec/load_spec.rb
33
+ - spec/uri_spec.rb
34
+ has_rdoc: true
35
+ homepage: ''
36
+ licenses: []
37
+ post_install_message:
38
+ rdoc_options: []
39
+ require_paths:
40
+ - lib
41
+ required_ruby_version: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ required_rubygems_version: !ruby/object:Gem::Requirement
48
+ none: false
49
+ requirements:
50
+ - - ! '>='
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
53
+ requirements: []
54
+ rubyforge_project: env.rb
55
+ rubygems_version: 1.6.2
56
+ signing_key:
57
+ specification_version: 3
58
+ summary: Manage your ENV with ease
59
+ test_files:
60
+ - spec/enforce_spec.rb
61
+ - spec/load_spec.rb
62
+ - spec/uri_spec.rb