active_attr 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of active_attr might be problematic. Click here for more details.

data/.gitignore CHANGED
@@ -1,8 +1,10 @@
1
1
  *.gem
2
2
  .bundle
3
+ .rvmrc
3
4
  .yardoc
4
5
  coverage
5
6
  doc
6
7
  Gemfile.lock
7
8
  gemfiles/*.gemfile.lock
8
9
  pkg/*
10
+ tmp/
@@ -0,0 +1 @@
1
+ ruby-1.9.3@active_attr
@@ -10,6 +10,8 @@ gemfile:
10
10
  - gemfiles/rails_3_1.gemfile
11
11
  - gemfiles/rails_head.gemfile
12
12
  matrix:
13
+ allow_failures:
14
+ - gemfile: gemfiles/rails_head.gemfile
13
15
  exclude:
14
16
  - rvm: ree
15
17
  gemfile: gemfiles/rails_head.gemfile
@@ -1,8 +1,15 @@
1
+ # ActiveAttr 0.7.0 (December 15, 2012) #
2
+
3
+ * Added Serialization
4
+ * Changed Typecasting::DateTypecaster to not raise on invalid Strings
5
+ * #114 Fixed NoMethodError in TypecastedAttributes#attribute_before_type_cast
6
+
1
7
  # ActiveAttr 0.6.0 (June 27, 2012) #
2
8
 
3
9
  * Added AttributeDefinition#inspect
4
10
  * Added Attributes.attribute!
5
11
  * Added Attributes.dangerous_attribute?
12
+ * Added missing autoload for BlockInitialization
6
13
  * Added Typecasting#typecaster_for
7
14
  * Added Typecasting::UnknownTypecasterError
8
15
  * Changed Typecasting#typecast_attribute to take a typecaster, not a type
data/Gemfile CHANGED
@@ -1,7 +1,13 @@
1
1
  source "https://rubygems.org"
2
2
 
3
3
  gemspec :development_group => :test
4
- gem "factory_girl", "< 3.0", :group => :test if RUBY_VERSION < "1.9.2"
4
+
5
+ if RUBY_VERSION < "1.9.2"
6
+ gem "factory_girl", "< 3.0", :group => :test
7
+ gem "strong_parameters", :git => "git://github.com/rails/strong_parameters.git", :group => :test
8
+ else
9
+ gem "strong_parameters"
10
+ end
5
11
 
6
12
  group :development do
7
13
  gem "debugger", :platforms => :mri_19
data/Guardfile CHANGED
@@ -3,7 +3,7 @@ guard "bundler" do
3
3
  watch(/^.+\.gemspec/)
4
4
  end
5
5
 
6
- guard "rspec", :version => 2, :cli=> "--format nested --debugger" do
6
+ guard "rspec", :cli => "--format nested --debugger" do
7
7
  watch(%r{^spec/.+_spec\.rb$})
8
8
  watch(%r{^lib/(.+)\.rb$}) { |m| ["spec/unit/#{m[1]}_spec.rb", "spec/functional/#{m[1]}_spec.rb"] }
9
9
  watch("spec/spec_helper.rb") { "spec" }
data/README.md CHANGED
@@ -1,21 +1,34 @@
1
1
  # ActiveAttr #
2
2
 
3
- [![Build History][2]][1] [![Dependency Status][5]][4]
3
+ [![Build History][travis badge]][travis]
4
+ [![Code Climate][codeclimate badge]][codeclimate]
4
5
 
5
6
  ActiveAttr is a set of modules that makes it easy to create plain old ruby
6
7
  models with functionality found in ORMs, like ActiveRecord, without
7
8
  reinventing the wheel. Think of ActiveAttr as the stuff ActiveModel left out.
8
9
 
9
- ActiveAttr is distributed as a rubygem [on rubygems.org][3].
10
-
11
- * [API Documentation](http://rubydoc.info/gems/active_attr)
12
- * [Contributors](https://github.com/cgriego/active_attr/contributors)
13
-
14
- [1]: http://travis-ci.org/cgriego/active_attr
15
- [2]: https://secure.travis-ci.org/cgriego/active_attr.png?branch=master
16
- [3]: http://rubygems.org/gems/active_attr
17
- [4]: https://gemnasium.com/cgriego/active_attr
18
- [5]: https://gemnasium.com/cgriego/active_attr.png
10
+ ActiveAttr is distributed as a rubygem [on rubygems.org][rubygems].
11
+
12
+ [![Models Models Every Where][speakerdeck slide]][speakerdeck]
13
+ [![ActiveAttr Railscast][railscast poster]][railscast]
14
+
15
+ * [Slides][speakerdeck]
16
+ * [RailsCast][railscast]
17
+ * [API Documentation][api]
18
+ * [Contributors][contributors]
19
+
20
+ [api]: http://rubydoc.info/gems/active_attr
21
+ [codeclimate badge]: https://codeclimate.com/badge.png
22
+ [codeclimate]: https://codeclimate.com/github/cgriego/active_attr
23
+ [contributors]: https://github.com/cgriego/active_attr/contributors
24
+ [railscast poster]: http://railscasts.com/static/episodes/stills/326-activeattr.png
25
+ [railscast]: http://railscasts.com/episodes/326-activeattr
26
+ [rubygems]: http://rubygems.org/gems/active_attr
27
+ [strong_parameters]: https://github.com/rails/strong_parameters
28
+ [speakerdeck slide]: https://speakerd.s3.amazonaws.com/presentations/4f31f1dec583b4001f008ec3/thumb_slide_0.jpg
29
+ [speakerdeck]: https://speakerdeck.com/u/cgriego/p/models-models-every-where
30
+ [travis badge]: https://secure.travis-ci.org/cgriego/active_attr.png?branch=master
31
+ [travis]: http://travis-ci.org/cgriego/active_attr
19
32
 
20
33
  ## Modules ##
21
34
 
@@ -168,6 +181,24 @@ blacklists or whitelists including support for mass assignment roles.
168
181
  person.first_name #=> "Chris"
169
182
  person.last_name #=> nil
170
183
 
184
+ If you prefer the [Strong Paramters][strong_parameters] approach,
185
+ include the ActiveModel::ForbiddenAttributesProtection module after
186
+ including the MassAssignmentSecurity model.
187
+
188
+ class Person
189
+ include ActiveAttr::MassAssignmentSecurity
190
+ include ActiveModel::ForbiddenAttributesProtection
191
+ end
192
+
193
+ ### Serialization ###
194
+
195
+ The Serialization module is a shortcut for incorporating ActiveModel's
196
+ serialization functionality into your model with one include.
197
+
198
+ class Person
199
+ include ActiveAttr::Model
200
+ end
201
+
171
202
  ### Model ###
172
203
 
173
204
  The Model module is a shortcut for incorporating the most common model
@@ -1,7 +1,10 @@
1
1
  source "http://rubygems.org"
2
2
 
3
3
  gemspec :development_group => :test, :path => ".."
4
- gem "factory_girl", "< 3.0", :group => :test if RUBY_VERSION < "1.9.2"
4
+
5
+ if RUBY_VERSION < "1.9.2"
6
+ gem "factory_girl", "< 3.0", :group => :test
7
+ end
5
8
 
6
9
  gem "activemodel", "~> 3.0.2"
7
10
  gem "activesupport", "~> 3.0.2"
@@ -1,7 +1,10 @@
1
1
  source "http://rubygems.org"
2
2
 
3
3
  gemspec :development_group => :test, :path => ".."
4
- gem "factory_girl", "< 3.0", :group => :test if RUBY_VERSION < "1.9.2"
4
+
5
+ if RUBY_VERSION < "1.9.2"
6
+ gem "factory_girl", "< 3.0", :group => :test
7
+ end
5
8
 
6
9
  gem "activemodel", "~> 3.1.0"
7
10
  gem "activesupport", "~> 3.1.0"
@@ -21,6 +21,7 @@ module ActiveAttr
21
21
  autoload :MassAssignmentSecurity
22
22
  autoload :Model
23
23
  autoload :QueryAttributes
24
+ autoload :Serialization
24
25
  autoload :TypecastedAttributes
25
26
  autoload :Typecasting
26
27
  autoload :UnknownAttributeError
@@ -90,7 +90,7 @@ module ActiveAttr
90
90
  #
91
91
  # @since 0.5.0
92
92
  def attribute_defaults
93
- Hash[ self.class.attribute_names.map { |name| [name, _attribute_default(name)] } ]
93
+ attributes_map { |name| _attribute_default name }
94
94
  end
95
95
 
96
96
  # Applies attribute default values
@@ -57,7 +57,7 @@ module ActiveAttr
57
57
  #
58
58
  # @since 0.2.0
59
59
  def attributes
60
- Hash[self.class.attribute_names.map { |key| [key, send(key)] }]
60
+ attributes_map { |name| send name }
61
61
  end
62
62
 
63
63
  # Returns the class name plus its attributes
@@ -138,6 +138,21 @@ module ActiveAttr
138
138
  @attributes[name] = value
139
139
  end
140
140
 
141
+ # Maps all attributes using the given block
142
+ #
143
+ # @example Stringify attributes
144
+ # person.attributes_map { |name| send(name).to_s }
145
+ #
146
+ # @yield [name] block called to return hash value
147
+ # @yieldparam [String] name The name of the attribute to map.
148
+ #
149
+ # @return [Hash{String => Object}] The Hash of mapped attributes
150
+ #
151
+ # @since 0.7.0
152
+ def attributes_map
153
+ Hash[ self.class.attribute_names.map { |name| [name, yield(name)] } ]
154
+ end
155
+
141
156
  module ClassMethods
142
157
  # Defines an attribute
143
158
  #
@@ -32,16 +32,23 @@ module ActiveAttr
32
32
  # @since 0.3.0
33
33
  def assign_attributes(new_attributes, options={})
34
34
  if new_attributes && !options[:without_protection]
35
- if method(:sanitize_for_mass_assignment).arity.abs > 1
36
- mass_assignment_role = options[:as] || :default
37
- new_attributes = sanitize_for_mass_assignment new_attributes, mass_assignment_role
38
- else
39
- # Rails 3.0 has no roles support in mass assignment
40
- new_attributes = sanitize_for_mass_assignment new_attributes
41
- end
35
+ mass_assignment_role = options[:as] || :default
36
+ new_attributes = sanitize_for_mass_assignment_with_or_without_role new_attributes, mass_assignment_role
42
37
  end
43
38
 
44
39
  super
45
40
  end
41
+
42
+ private
43
+
44
+ # Rails 3.0 has no roles support in mass assignment
45
+ # @since 0.7.0
46
+ def sanitize_for_mass_assignment_with_or_without_role(new_attributes, mass_assignment_role)
47
+ if method(:sanitize_for_mass_assignment).arity.abs > 1
48
+ sanitize_for_mass_assignment new_attributes, mass_assignment_role
49
+ else
50
+ sanitize_for_mass_assignment new_attributes
51
+ end
52
+ end
46
53
  end
47
54
  end
@@ -4,8 +4,8 @@ require "active_attr/block_initialization"
4
4
  require "active_attr/logger"
5
5
  require "active_attr/mass_assignment_security"
6
6
  require "active_attr/query_attributes"
7
+ require "active_attr/serialization"
7
8
  require "active_attr/typecasted_attributes"
8
- require "active_model"
9
9
  require "active_support/concern"
10
10
 
11
11
  module ActiveAttr
@@ -29,13 +29,6 @@ module ActiveAttr
29
29
  include AttributeDefaults
30
30
  include QueryAttributes
31
31
  include TypecastedAttributes
32
-
33
- if defined? ActiveModel::Serializable
34
- include ActiveModel::Serializable::JSON
35
- include ActiveModel::Serializable::XML
36
- else
37
- include ActiveModel::Serializers::JSON
38
- include ActiveModel::Serializers::Xml
39
- end
32
+ include Serialization
40
33
  end
41
34
  end
@@ -0,0 +1,31 @@
1
+ require "active_attr/attributes"
2
+ require "active_attr/mass_assignment"
3
+ require "active_model"
4
+ require "active_support/concern"
5
+
6
+ module ActiveAttr
7
+ # Serialization is a shortcut for incorporating ActiveModel's
8
+ # serialization functionality into your model with one include
9
+ #
10
+ # See the included modules to learn more.
11
+ #
12
+ # @example Usage
13
+ # class Person
14
+ # include ActiveAttr::Serialization
15
+ # end
16
+ #
17
+ # @since 0.7.0
18
+ module Serialization
19
+ extend ActiveSupport::Concern
20
+ include Attributes
21
+ include MassAssignment
22
+
23
+ if defined? ActiveModel::Serializable
24
+ include ActiveModel::Serializable::JSON
25
+ include ActiveModel::Serializable::XML
26
+ else
27
+ include ActiveModel::Serializers::JSON
28
+ include ActiveModel::Serializers::Xml
29
+ end
30
+ end
31
+ end
@@ -46,6 +46,7 @@ module ActiveAttr
46
46
  #
47
47
  # @since 0.5.0
48
48
  def attribute_before_type_cast(name)
49
+ @attributes ||= {}
49
50
  @attributes[name.to_s]
50
51
  end
51
52
 
@@ -24,6 +24,7 @@ module ActiveAttr
24
24
  # @since 0.5.0
25
25
  def call(value)
26
26
  value.to_date if value.respond_to? :to_date
27
+ rescue NoMethodError
27
28
  end
28
29
  end
29
30
  end
@@ -1,5 +1,5 @@
1
1
  module ActiveAttr
2
2
  # Complete version string
3
3
  # @since 0.1.0
4
- VERSION = "0.6.0"
4
+ VERSION = "0.7.0"
5
5
  end
@@ -0,0 +1,45 @@
1
+ require "spec_helper"
2
+ require "active_attr/mass_assignment_security"
3
+
4
+ module ActiveAttr
5
+ describe MassAssignmentSecurity, :mass_assignment do
6
+ context "integrating with strong_parameters", :active_model_version => "~> 3.2.0" do
7
+ subject { model_class }
8
+
9
+ before do
10
+ require "strong_parameters"
11
+
12
+ model_class.class_eval do
13
+ include ActiveAttr::MassAssignmentSecurity
14
+ include ActiveModel::ForbiddenAttributesProtection
15
+ attr_accessor :age
16
+ end
17
+ end
18
+
19
+ shared_examples "strong mass assignment method", :strong_mass_assignment_method => true do
20
+ it "raises if provided parameters when none are permitted" do
21
+ expect { mass_assign_attributes(ActionController::Parameters.new(:age => 21)) }.to raise_error ActiveModel::ForbiddenAttributes
22
+ end
23
+
24
+ it "sets a permitted parameter" do
25
+ person = mass_assign_attributes(ActionController::Parameters.new(:age => 21).permit(:age))
26
+ person.age.should == 21
27
+ end
28
+
29
+ it "does not set forbidden parameters" do
30
+ person = mass_assign_attributes(ActionController::Parameters.new(:age => 21).permit(:first_name))
31
+ person.age.should be_nil
32
+ end
33
+
34
+ it "continues to set normal attributes" do
35
+ person = mass_assign_attributes(:age => 21)
36
+ person.age.should == 21
37
+ end
38
+ end
39
+
40
+ describe "#assign_attributes", :assign_attributes, :strong_mass_assignment_method
41
+ describe "#attributes=", :attributes=, :strong_mass_assignment_method
42
+ describe "#initialize", :initialize, :strong_mass_assignment_method
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,31 @@
1
+ require "spec_helper"
2
+ require "active_attr/serialization"
3
+ require "active_support/core_ext/hash/conversions"
4
+ require "active_support/json/decoding"
5
+
6
+ module ActiveAttr
7
+ describe Serialization do
8
+ let :model_class do
9
+ Class.new do
10
+ include Serialization
11
+ attribute :first_name
12
+
13
+ def self.name
14
+ "Person"
15
+ end
16
+ end
17
+ end
18
+
19
+ subject { model_class.new }
20
+
21
+ it "serializes to/from JSON" do
22
+ subject.first_name = "Chris"
23
+ model_class.new.from_json(subject.to_json).first_name.should == "Chris"
24
+ end
25
+
26
+ it "serializes to/from XML" do
27
+ subject.first_name = "Chris"
28
+ model_class.new.from_xml(subject.to_xml).first_name.should == "Chris"
29
+ end
30
+ end
31
+ end
@@ -60,6 +60,10 @@ module ActiveAttr
60
60
  end
61
61
 
62
62
  describe "#attribute_before_type_cast" do
63
+ it "returns nil when the attribute has not been assigned yet" do
64
+ subject.attribute_before_type_cast(:amount).should be_nil
65
+ end
66
+
63
67
  it "returns the assigned attribute value, without typecasting, when given an attribute name as a Symbol" do
64
68
  value = :value
65
69
  subject.amount = value
@@ -14,6 +14,10 @@ module ActiveAttr
14
14
  subject.call(nil).should equal nil
15
15
  end
16
16
 
17
+ it "returns nil for an invalid String" do
18
+ subject.call("x").should equal nil
19
+ end
20
+
17
21
  it "casts a UTC Time to a Date representing the date portion" do
18
22
  subject.call(Time.utc(2012, 1, 1, 0, 0, 0)).should eql Date.new(2012, 1, 1)
19
23
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_attr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.7.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-06-27 00:00:00.000000000 Z
13
+ date: 2012-12-16 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activemodel
@@ -152,7 +152,7 @@ extra_rdoc_files: []
152
152
  files:
153
153
  - .gitignore
154
154
  - .rspec
155
- - .rvmrc
155
+ - .ruby-version
156
156
  - .travis.yml
157
157
  - .yardopts
158
158
  - CHANGELOG.md
@@ -183,6 +183,7 @@ files:
183
183
  - lib/active_attr/query_attributes.rb
184
184
  - lib/active_attr/railtie.rb
185
185
  - lib/active_attr/rspec.rb
186
+ - lib/active_attr/serialization.rb
186
187
  - lib/active_attr/typecasted_attributes.rb
187
188
  - lib/active_attr/typecasting.rb
188
189
  - lib/active_attr/typecasting/big_decimal_typecaster.rb
@@ -200,9 +201,11 @@ files:
200
201
  - spec/functional/active_attr/attribute_defaults_spec.rb
201
202
  - spec/functional/active_attr/attributes_spec.rb
202
203
  - spec/functional/active_attr/chainable_initialization_spec.rb
204
+ - spec/functional/active_attr/mass_assignment_security_spec.rb
203
205
  - spec/functional/active_attr/matchers/have_attribute_matcher_spec.rb
204
206
  - spec/functional/active_attr/model_spec.rb
205
207
  - spec/functional/active_attr/query_attributes_spec.rb
208
+ - spec/functional/active_attr/serialization_spec.rb
206
209
  - spec/functional/active_attr/typecasted_attributes_spec.rb
207
210
  - spec/spec_helper.rb
208
211
  - spec/support/active_model_lint.rb
@@ -250,7 +253,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
250
253
  version: '0'
251
254
  segments:
252
255
  - 0
253
- hash: 1481400115643803652
256
+ hash: 158822626383359135
254
257
  required_rubygems_version: !ruby/object:Gem::Requirement
255
258
  none: false
256
259
  requirements:
@@ -259,10 +262,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
259
262
  version: '0'
260
263
  segments:
261
264
  - 0
262
- hash: 1481400115643803652
265
+ hash: 158822626383359135
263
266
  requirements: []
264
267
  rubyforge_project:
265
- rubygems_version: 1.8.21
268
+ rubygems_version: 1.8.24
266
269
  signing_key:
267
270
  specification_version: 3
268
271
  summary: What ActiveModel left out
@@ -270,9 +273,11 @@ test_files:
270
273
  - spec/functional/active_attr/attribute_defaults_spec.rb
271
274
  - spec/functional/active_attr/attributes_spec.rb
272
275
  - spec/functional/active_attr/chainable_initialization_spec.rb
276
+ - spec/functional/active_attr/mass_assignment_security_spec.rb
273
277
  - spec/functional/active_attr/matchers/have_attribute_matcher_spec.rb
274
278
  - spec/functional/active_attr/model_spec.rb
275
279
  - spec/functional/active_attr/query_attributes_spec.rb
280
+ - spec/functional/active_attr/serialization_spec.rb
276
281
  - spec/functional/active_attr/typecasted_attributes_spec.rb
277
282
  - spec/spec_helper.rb
278
283
  - spec/support/active_model_lint.rb
@@ -306,3 +311,4 @@ test_files:
306
311
  - spec/unit/active_attr/typecasting_spec.rb
307
312
  - spec/unit/active_attr/unknown_attribute_error_spec.rb
308
313
  - spec/unit/active_attr/version_spec.rb
314
+ has_rdoc:
data/.rvmrc DELETED
@@ -1,81 +0,0 @@
1
- #!/usr/bin/env bash
2
-
3
- # This is an RVM Project .rvmrc file, used to automatically load the ruby
4
- # development environment upon cd'ing into the directory
5
-
6
- # First we specify our desired <ruby>[@<gemset>], the @gemset name is optional.
7
- environment_id="ruby-1.9.3@active_attr"
8
-
9
- #
10
- # Uncomment the following lines if you want to verify rvm version per project
11
- #
12
- # rvmrc_rvm_version="1.10.1" # 1.10.1 seams as a safe start
13
- # eval "$(echo ${rvm_version}.${rvmrc_rvm_version} | awk -F. '{print "[[ "$1*65536+$2*256+$3" -ge "$4*65536+$5*256+$6" ]]"}' )" || {
14
- # echo "This .rvmrc file requires at least RVM ${rvmrc_rvm_version}, aborting loading."
15
- # return 1
16
- # }
17
- #
18
-
19
- #
20
- # Uncomment following line if you want options to be set only for given project.
21
- #
22
- # PROJECT_JRUBY_OPTS=( --1.9 )
23
- #
24
- # The variable PROJECT_JRUBY_OPTS requires the following to be run in shell:
25
- #
26
- # chmod +x ${rvm_path}/hooks/after_use_jruby_opts
27
- #
28
-
29
- #
30
- # First we attempt to load the desired environment directly from the environment
31
- # file. This is very fast and efficient compared to running through the entire
32
- # CLI and selector. If you want feedback on which environment was used then
33
- # insert the word 'use' after --create as this triggers verbose mode.
34
- #
35
- if [[ -d "${rvm_path:-$HOME/.rvm}/environments" \
36
- && -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]]
37
- then
38
- \. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
39
-
40
- if [[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]]
41
- then
42
- . "${rvm_path:-$HOME/.rvm}/hooks/after_use"
43
- fi
44
- else
45
- # If the environment file has not yet been created, use the RVM CLI to select.
46
- if ! rvm --create use "$environment_id"
47
- then
48
- echo "Failed to create RVM environment '${environment_id}'."
49
- return 1
50
- fi
51
- fi
52
-
53
- #
54
- # If you use an RVM gemset file to install a list of gems (*.gems), you can have
55
- # it be automatically loaded. Uncomment the following and adjust the filename if
56
- # necessary.
57
- #
58
- # filename=".gems"
59
- # if [[ -s "$filename" ]]
60
- # then
61
- # rvm gemset import "$filename" | grep -v already | grep -v listed | grep -v complete | sed '/^$/d'
62
- # fi
63
-
64
- # If you use bundler, this might be useful to you:
65
- # if [[ -s Gemfile ]] && ! command -v bundle >/dev/null
66
- # then
67
- # printf "%b" "The rubygem 'bundler' is not installed. Installing it now.\n"
68
- # gem install bundler
69
- # fi
70
- # if [[ -s Gemfile ]] && command -v bundle
71
- # then
72
- # bundle install
73
- # fi
74
-
75
- if [[ $- == *i* ]] # check for interactive shells
76
- then
77
- echo "Using: $(tput setaf 2)$GEM_HOME$(tput sgr0)" # show the user the ruby and gemset they are using in green
78
- else
79
- echo "Using: $GEM_HOME" # don't use colors in interactive shells
80
- fi
81
-