sugarcrm 0.9.13 → 0.9.14

Sign up to get free protection for your applications and to get access to all the features.
@@ -128,6 +128,16 @@ A less clunky way to interact with SugarCRM via REST.
128
128
  # because records are passed to the block as they get fetched from SugarCRM (whereas `each`
129
129
  # will fetch all records, and only then pass them to the block). This will make a major difference
130
130
  # in resource use and execution time if you're dealing with many records.
131
+
132
+ # Create a document instance and upload a file
133
+ file = File.read(File.join(File.dirname(__FILE__),"test_excel.xls"))
134
+ doc = SugarCRM::Document.new
135
+ doc.active_date = Date.today
136
+ doc.document_name = "test_excel.xls"
137
+ doc.filename = "test_excel.xls"
138
+ doc.revision = 0
139
+ doc.uploadfile = SugarCRM.connection.b64_encode(file)
140
+ doc.save!
131
141
 
132
142
  # Look up the fields for a given module
133
143
  SugarCRM::Module.find("Accounts").fields
@@ -190,7 +200,7 @@ An example, accompanied by instructions, can be found in the `config/sugarcrm.ya
190
200
 
191
201
  1. Type `irb` in your command prompt
192
202
 
193
- 2. Require the gem with `require 'sugarcrm'`
203
+ 2. Require the gem with `require 'sugarcrm'` (Note: Windows users might need to `require 'rubygems'` before `require 'sugarcrm'`.)
194
204
 
195
205
  3. * if your login credentials are stored in the `config/sugarcrm.yaml` file, you have been automagically logged in already ;
196
206
  * if your login credentials are stored in a different config file, just call `SugarCRM.load_config` followed by the absolute path to your config file. This will log you in automatically ;
@@ -243,6 +253,8 @@ To disconnect an active session:
243
253
 
244
254
  * sudo gem install sugarcrm
245
255
 
256
+ Note: Windows users might need to `require 'rubygems'` before `require 'sugarcrm'`.
257
+
246
258
  == TEST:
247
259
 
248
260
  Put your credentials in a file called `test/config.yaml` (which you will have to create). These must point to a SugarCRM test instance with demo data. See an example file in `test/config_test.yaml` (leave that file as is).
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.9.13
1
+ 0.9.14
@@ -0,0 +1,7 @@
1
+ Each time a new version of SugarCRM comes out, the following should be checked to see whether it is still an issue. Conditional code based on SugarCRM version can be added if SugarCRM patches buggy functionality.
2
+
3
+ The get_entries_count function does not work properly (always returns 0) if a condition on a custom (i.e. made with studio and ending in _c) is passed
4
+ When functionality is fixed in SugarCRM: add conditional code so InvalidAttribute exception is raised on ly when dealing with broken versions
5
+
6
+ get_entry_list function has a bug where, when :limit and :offset options are passed simultaneously, :limit is considered to be the smallest of the two, and :offset is the larger
7
+ When functionality is fixed in SugarCRM: update comment in find_by_sql to reflect the fix (code can stay as is)
@@ -33,15 +33,25 @@ module SugarCRM; module AttributeMethods
33
33
  operator ||= '='
34
34
  # Extract value from query
35
35
  value = $3
36
- if [TrueClass, FalseClass].include? attribute_condition.class
37
- # fix value for checkboxes: users can pass true/false as condition, should be converted to '1' or '0' respectively
38
- value = (attribute_condition.class == TrueClass ? '1' : '0')
36
+ unless attribute_condition.class == FalseClass
37
+ if attribute_condition.class == TrueClass
38
+ # fix value for checkboxes: users can pass true as condition, should be converted to '1' (false case for checkboxes is treated separately below)
39
+ value = (attribute_condition.class == TrueClass ? '1' : '0')
40
+ end
41
+
42
+ # TODO: Write a test for sending invalid attribute names.
43
+ # strip single quotes
44
+ value = value.strip[/'?([^']*)'?/,1]
45
+ conditions << "#{table_name_for(attribute)}.#{attribute} #{operator} \'#{value}\'"
46
+ else
47
+ # When a user creates a custom checkbox field, a column is added to the *_cstm table for that module (e.g. contacts_cstm for Contacts module).
48
+ # Each time a new record is created, the value of the checkbox will be stored in that _cstm table.
49
+ # However, records that exsited before that field was created are absent from the _cstm table.
50
+ # To return the expected results when a user is searching for records with an unchecked checkbox, we must return all records that aren't present in
51
+ # the _cstm table with a value of 1 (returning the record with 0 in the table will ignore the pre-existing records).
52
+ # Here, we create the appropriate query that will return all records that don't have a value of "true" in the checkbox field.
53
+ conditions << "#{self._module.table_name}.id NOT IN (SELECT id_c FROM #{table_name_for(attribute)} WHERE #{table_name_for(attribute)}.#{attribute} #{operator} 1)"
39
54
  end
40
-
41
- # TODO: Write a test for sending invalid attribute names.
42
- # strip single quotes
43
- value = value.strip[/'?([^']*)'?/,1]
44
- conditions << "#{table_name_for(attribute)}.#{attribute} #{operator} \'#{value}\'"
45
55
  end
46
56
  conditions
47
57
  end
@@ -27,7 +27,19 @@ module SugarCRM; class Base
27
27
  class << self # Class methods
28
28
  def find(*args, &block)
29
29
  options = args.extract_options!
30
- options = {:order_by => 'date_entered'}.merge(options)
30
+ # add default sorting date (necessary for first and last methods to work)
31
+ # most modules (Contacts, Accounts, etc.) use 'date_entered' to store when the record was created
32
+ # other modules (e.g. EmailAddresses) use 'date_created'
33
+ # Here, we account for this discrepancy...
34
+ self.new # make sure the fields are loaded from SugarCRM so method_defined? will work properly
35
+ if self.method_defined? :date_entered
36
+ sort_criteria = 'date_entered'
37
+ elsif self.method_defined? :date_created
38
+ sort_criteria = 'date_created'
39
+ else
40
+ raise InvalidAttribute, "Unable to determine record creation date for sorting criteria: expected date_entered or date_created attribute to be present"
41
+ end
42
+ options = {:order_by => sort_criteria}.merge(options)
31
43
  validate_find_options(options)
32
44
 
33
45
  case args.first
@@ -52,7 +64,11 @@ module SugarCRM; class Base
52
64
  self.session.connection
53
65
  end
54
66
 
67
+ # return the number of records satifsying the options
68
+ # note: the REST API has a bug (documented with Sugar as bug 43339) where passing custom attributes in the options will result in the
69
+ # options being ignored and '0' being returned, regardless of the existence of records satisfying the options
55
70
  def count(options={})
71
+ raise InvalidAttribute, 'Conditions on custom attributes are not supported due to REST API bug' if contains_custom_attribute(options[:conditions])
56
72
  query = query_from_options(options)
57
73
  connection.get_entries_count(self._module.name, query, options)['result_count'].to_i
58
74
  end
@@ -111,6 +127,7 @@ module SugarCRM; class Base
111
127
 
112
128
  # Creates an instance of a Module Class, i.e. Account, User, Contact, etc.
113
129
  def initialize(attributes={}, &block)
130
+ attributes.delete('id')
114
131
  @errors = {}
115
132
  @modified_attributes = {}
116
133
  merge_attributes(attributes.with_indifferent_access)
@@ -257,6 +274,15 @@ module SugarCRM; class Base
257
274
  alias :=== :is_a?
258
275
 
259
276
  private
277
+ # returns true if the hash contains a custom attribute created in Studio (and whose name therefore ends in '_c')
278
+ def self.contains_custom_attribute(attributes)
279
+ attributes ||= {}
280
+ attributes.each_key{|k|
281
+ return true if k.to_s =~ /_c$/
282
+ }
283
+ false
284
+ end
285
+
260
286
  def superclasses
261
287
  return @superclasses if @superclasses
262
288
  @superclasses = [self.class]
@@ -13,7 +13,7 @@ module SugarCRM; class Connection
13
13
  "module_name": "#{module_name}",
14
14
  "id": "#{id}",
15
15
  "select_fields": #{resolve_fields(module_name, options[:fields])},
16
- "link_name_to_fields_array": #{options[:link_fields]}
16
+ "link_name_to_fields_array": #{options[:link_fields].to_json}
17
17
  }
18
18
  EOF
19
19
 
@@ -3,7 +3,8 @@ module SugarCRM; class Connection
3
3
  def set_document_revision(document_id, revision_number, opts={})
4
4
  options = {
5
5
  :file => '',
6
- :file_name => ''
6
+ :file_name => '',
7
+ :document_name => nil
7
8
  }.merge! opts
8
9
 
9
10
  # Raise an exception of we try to pass :file, but not :file_name
@@ -11,15 +12,20 @@ module SugarCRM; class Connection
11
12
  raise ArgumentException, ":file_name must be specified if :file is specified"
12
13
  end
13
14
 
15
+ # If no document_name is given, use the file_name
16
+ options[:document_name] ||= options[:file_name]
17
+
14
18
  login! unless logged_in?
19
+
15
20
  json = <<-EOF
16
21
  {
17
22
  "session": "#{@sugar_session_id}",
18
23
  "document_revision": {
19
24
  "id": "#{document_id}",
25
+ "document_name": "#{options[:document_name]}",
26
+ "revision": "#{revision_number}",
20
27
  "filename": "#{options[:file_name]}",
21
- "file": "#{Base64.encode64(options[:file])}",
22
- "revision": "#{revision_number}"
28
+ "file": "#{b64_encode(options[:file])}"
23
29
  }
24
30
  }
25
31
  EOF
@@ -13,7 +13,7 @@ module SugarCRM; class Connection
13
13
  "note": {
14
14
  "id": "#{id}",
15
15
  "filename": "#{filename}",
16
- "file": "#{Base64.encode64(file)}",
16
+ "file": "#{b64_encode(file)}",
17
17
  "related_module_id": "#{options[:module_id]}",
18
18
  "related_module_name": "#{options[:module_name]}"
19
19
  }
@@ -68,6 +68,7 @@ module SugarCRM; class Connection
68
68
 
69
69
  # Send a request to the Sugar Instance
70
70
  def send!(method, json)
71
+ nb_failed_attempts = 0 # how many times we have failed to send
71
72
  @request = SugarCRM::Request.new(@url, method, json, @options[:debug])
72
73
  begin
73
74
  if @request.length > 3900
@@ -75,10 +76,20 @@ module SugarCRM; class Connection
75
76
  else
76
77
  @response = @connection.get(@url.path.dup + "?" + @request.to_s)
77
78
  end
78
- rescue Errno::ECONNRESET
79
- retry!(method, json)
80
- rescue EOFError
81
- retry!(method, json)
79
+ rescue Timeout::Error, Errno::ECONNABORTED
80
+ nb_failed_attempts += 1
81
+ unless nb_failed_attempts >= 3
82
+ retry
83
+ else
84
+ raise
85
+ end
86
+ rescue Errno::ECONNRESET, EOFError
87
+ nb_failed_attempts += 1
88
+ unless nb_failed_attempts >= 3
89
+ retry!(method, json)
90
+ else
91
+ raise
92
+ end
82
93
  end
83
94
  handle_response
84
95
  end
@@ -38,4 +38,13 @@ module SugarCRM; class Connection
38
38
  end
39
39
  end
40
40
 
41
+ # We need to strip newlines from Base64 encoding for JSON validation purposes.
42
+ def b64_encode(file)
43
+ Base64.encode64(file).gsub(/\n/, '')
44
+ end
45
+
46
+ def b64_decode(file)
47
+ Base64.decode64(file)
48
+ end
49
+
41
50
  end; end
@@ -72,7 +72,7 @@ module SugarCRM; module FinderMethods
72
72
  SLICE_SIZE.freeze
73
73
  # results accumulator stores the results we have fetched so far, recursively
74
74
  def find_by_sql(options, results_accumulator=nil, &block)
75
- # SugarCRM REST API has a bug where, when :limit and :offset options are passed simultaneously,
75
+ # SugarCRM REST API has a bug (documented with Sugar as bug 43338) where, when :limit and :offset options are passed simultaneously,
76
76
  # :limit is considered to be the smallest of the two, and :offset is the larger
77
77
  # In addition to allowing querying of large datasets while avoiding timeouts (by fetching results in small slices),
78
78
  # this implementation fixes the :limit - :offset bug so that it behaves correctly
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{sugarcrm}
8
- s.version = "0.9.13"
8
+ s.version = "0.9.14"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Carl Hicks", "David Sulc"]
12
- s.date = %q{2011-04-06}
12
+ s.date = %q{2011-05-03}
13
13
  s.default_executable = %q{sugarcrm}
14
14
  s.email = %q{carl.hicks@gmail.com}
15
15
  s.executables = ["sugarcrm"]
@@ -23,6 +23,7 @@ Gem::Specification.new do |s|
23
23
  "./README.rdoc",
24
24
  "./Rakefile",
25
25
  "./VERSION",
26
+ "./WATCHLIST.rdoc",
26
27
  "./lib/rails/generators/sugarcrm/config/config_generator.rb",
27
28
  "./lib/rails/generators/sugarcrm/config/templates/initializer.rb",
28
29
  "./lib/rails/generators/sugarcrm/config/templates/sugarcrm.yml",
@@ -9,7 +9,7 @@ class TestSetNoteAttachment < ActiveSupport::TestCase
9
9
  file = File.read("test/config_test.yaml")
10
10
  assert SugarCRM.connection.set_note_attachment(n.id, "config_test.yaml", file)
11
11
  attachment = SugarCRM.connection.get_note_attachment(n.id)
12
- assert Base64.decode64(attachment["file"]) == file
12
+ assert_equal file, Base64.decode64(attachment["file"])
13
13
  assert n.delete
14
14
  end
15
15
  end
@@ -13,6 +13,24 @@ class TestFinders < ActiveSupport::TestCase
13
13
  assert users.length == 0
14
14
  end
15
15
 
16
+ should "support finding first instance with default sort order (for module using date_entered as creation date)" do
17
+ expected_account = SugarCRM::Account.first({:order_by => 'date_entered'})
18
+ account = nil
19
+ assert_nothing_raised do
20
+ account = SugarCRM::Account.first
21
+ end
22
+ assert_equal expected_account.id, account.id
23
+ end
24
+
25
+ should "support finding first instance with default sort order (for module using date_created as creation date)" do
26
+ expected_email = SugarCRM::EmailAddress.first({:order_by => 'date_created'})
27
+ email = nil
28
+ assert_nothing_raised do
29
+ email = SugarCRM::EmailAddress.first
30
+ end
31
+ assert_equal expected_email.id, email.id
32
+ end
33
+
16
34
  should "support finding first instance (sorted by attribute)" do
17
35
  account = SugarCRM::Account.first({
18
36
  :order_by => 'name'
@@ -19,14 +19,17 @@ class TestSession < ActiveSupport::TestCase
19
19
  end
20
20
 
21
21
  should "assign namespaces in a way that prevents collisions" do
22
- # Namespae0 already assigned (linked to the current connection)
23
- One = SugarCRM::Session.from_file(CONFIG_PATH)
24
- Two = SugarCRM::Session.from_file(CONFIG_PATH)
25
- One.disconnect!
26
- Three = SugarCRM::Session.from_file(CONFIG_PATH)
27
- assert_not_equal Two, Three # namespaces must be different
28
- Two.disconnect!
29
- Three.disconnect!
22
+ begin
23
+ # Namespae0 already assigned (linked to the current connection)
24
+ One = SugarCRM::Session.from_file(CONFIG_PATH)
25
+ Two = SugarCRM::Session.from_file(CONFIG_PATH)
26
+ One.disconnect!
27
+ Three = SugarCRM::Session.from_file(CONFIG_PATH)
28
+ assert_not_equal Two, Three # namespaces must be different
29
+ ensure
30
+ Two.disconnect!
31
+ Three.disconnect!
32
+ end
30
33
  end
31
34
 
32
35
  should "parse config parameters from a file" do
@@ -91,23 +94,27 @@ class TestSession < ActiveSupport::TestCase
91
94
  should "show the only the namespaces currently in use with SugarCRM.namespaces" do
92
95
  assert_equal 1, SugarCRM.namespaces.size
93
96
 
94
- assert_difference('SugarCRM.namespaces.size') do
95
- OneA = SugarCRM::Session.from_file(CONFIG_PATH)
96
- end
97
-
98
- assert_difference('SugarCRM.namespaces.size', -1) do
99
- OneA.disconnect!
97
+ begin
98
+ assert_difference('SugarCRM.namespaces.size') do
99
+ OneA = SugarCRM::Session.from_file(CONFIG_PATH)
100
+ end
101
+ ensure
102
+ assert_difference('SugarCRM.namespaces.size', -1) do
103
+ OneA.disconnect!
104
+ end
100
105
  end
101
106
  end
102
107
 
103
108
  should "add a used namespace on each new connection" do
104
- assert_difference('SugarCRM.used_namespaces.size') do
105
- OneB = SugarCRM::Session.from_file(CONFIG_PATH)
106
- end
107
-
108
- # connection (and namespace) is reused => no used namespace should be added
109
- assert_no_difference('SugarCRM.used_namespaces.size') do
110
- OneB.reconnect!
109
+ begin
110
+ assert_difference('SugarCRM.used_namespaces.size') do
111
+ OneB = SugarCRM::Session.from_file(CONFIG_PATH)
112
+ end
113
+ ensure
114
+ # connection (and namespace) is reused => no used namespace should be added
115
+ assert_no_difference('SugarCRM.used_namespaces.size') do
116
+ OneB.reconnect!
117
+ end
111
118
  end
112
119
 
113
120
  assert_no_difference('SugarCRM.used_namespaces.size') do
@@ -116,11 +123,13 @@ class TestSession < ActiveSupport::TestCase
116
123
  end
117
124
 
118
125
  should "not allow access to methods on SugarCRM if there are multiple active connections" do
119
- OneC = SugarCRM::Session.from_file(CONFIG_PATH)
120
-
121
- assert_raise(SugarCRM::MultipleSessions){ SugarCRM.current_user }
122
-
123
- OneC.disconnect!
126
+ begin
127
+ OneC = SugarCRM::Session.from_file(CONFIG_PATH)
128
+
129
+ assert_raise(SugarCRM::MultipleSessions){ SugarCRM.current_user }
130
+ ensure
131
+ OneC.disconnect!
132
+ end
124
133
  end
125
134
  end
126
135
  end
@@ -2,15 +2,33 @@ require 'helper'
2
2
 
3
3
  class TestSugarCRM < ActiveSupport::TestCase
4
4
  context "A class inheriting SugarCRM::Base" do
5
- should "implement self.class.count" do
5
+ should "ignore 'id' attibute when creating an instance" do
6
+ first_account = SugarCRM::Account.first
7
+ new_account = nil
8
+ assert_difference('SugarCRM::Account.count') do
9
+ new_account = SugarCRM::Account.create(first_account.attributes)
10
+ end
11
+ assert first_account.id != new_account.id
12
+ end
13
+
14
+ should "implement self.count" do
6
15
  nb_accounts = SugarCRM::Account.count
7
16
  assert nb_accounts > 0
8
- nb_inc_accounts = SugarCRM::Account.count(:conditions => {:name => "LIKE '%Inc'"})
17
+ nb_inc_accounts = nil
18
+ assert_nothing_raised do
19
+ nb_inc_accounts = SugarCRM::Account.count(:conditions => {:name => "LIKE '%Inc'"})
20
+ end
9
21
  nb_inc_accounts_size = SugarCRM::Account.all(:conditions => {:name => "LIKE '%Inc'"}).size
10
22
  assert nb_inc_accounts > 0
11
23
  assert nb_inc_accounts < nb_accounts
12
24
  assert_equal nb_inc_accounts_size, nb_inc_accounts
13
25
  end
26
+
27
+ should "raise InvalidAttribute if self.count is called with a custom attribute" do
28
+ assert_raise SugarCRM::InvalidAttribute do
29
+ SugarCRM::Account.count(:conditions => {:custom_attribute_c => "value"})
30
+ end
31
+ end
14
32
  end
15
33
 
16
34
  context "A SugarCRM::Base instance" do
@@ -95,8 +113,8 @@ class TestSugarCRM < ActiveSupport::TestCase
95
113
  end
96
114
 
97
115
  should "implement Base#reload!" do
98
- a = SugarCRM::User.last
99
- b = SugarCRM::User.last
116
+ a = SugarCRM::User.find("seed_will_id")
117
+ b = SugarCRM::User.find("seed_will_id")
100
118
  assert_not_equal 'admin', a.user_name # make sure we don't mess up admin user
101
119
  # Save the original value, so we can set it back.
102
120
  orig_last_name = a.last_name.dup
metadata CHANGED
@@ -1,13 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sugarcrm
3
3
  version: !ruby/object:Gem::Version
4
- hash: 33
5
4
  prerelease:
6
- segments:
7
- - 0
8
- - 9
9
- - 13
10
- version: 0.9.13
5
+ version: 0.9.14
11
6
  platform: ruby
12
7
  authors:
13
8
  - Carl Hicks
@@ -16,98 +11,74 @@ autorequire:
16
11
  bindir: bin
17
12
  cert_chain: []
18
13
 
19
- date: 2011-04-06 00:00:00 -07:00
14
+ date: 2011-05-03 00:00:00 -07:00
20
15
  default_executable: sugarcrm
21
16
  dependencies:
22
17
  - !ruby/object:Gem::Dependency
23
- prerelease: false
24
- type: :runtime
18
+ name: activesupport
25
19
  requirement: &id001 !ruby/object:Gem::Requirement
26
20
  none: false
27
21
  requirements:
28
22
  - - ">="
29
23
  - !ruby/object:Gem::Version
30
- hash: 7
31
- segments:
32
- - 3
33
- - 0
34
- - 0
35
24
  version: 3.0.0
36
- name: activesupport
25
+ type: :runtime
26
+ prerelease: false
37
27
  version_requirements: *id001
38
28
  - !ruby/object:Gem::Dependency
39
- prerelease: false
40
- type: :runtime
29
+ name: i18n
41
30
  requirement: &id002 !ruby/object:Gem::Requirement
42
31
  none: false
43
32
  requirements:
44
33
  - - ">="
45
34
  - !ruby/object:Gem::Version
46
- hash: 3
47
- segments:
48
- - 0
49
35
  version: "0"
50
- name: i18n
36
+ type: :runtime
37
+ prerelease: false
51
38
  version_requirements: *id002
52
39
  - !ruby/object:Gem::Dependency
53
- prerelease: false
54
- type: :runtime
40
+ name: json
55
41
  requirement: &id003 !ruby/object:Gem::Requirement
56
42
  none: false
57
43
  requirements:
58
44
  - - ">="
59
45
  - !ruby/object:Gem::Version
60
- hash: 3
61
- segments:
62
- - 0
63
46
  version: "0"
64
- name: json
47
+ type: :runtime
48
+ prerelease: false
65
49
  version_requirements: *id003
66
50
  - !ruby/object:Gem::Dependency
67
- prerelease: false
68
- type: :development
51
+ name: shoulda
69
52
  requirement: &id004 !ruby/object:Gem::Requirement
70
53
  none: false
71
54
  requirements:
72
55
  - - ">="
73
56
  - !ruby/object:Gem::Version
74
- hash: 3
75
- segments:
76
- - 0
77
57
  version: "0"
78
- name: shoulda
58
+ type: :development
59
+ prerelease: false
79
60
  version_requirements: *id004
80
61
  - !ruby/object:Gem::Dependency
81
- prerelease: false
82
- type: :development
62
+ name: bundler
83
63
  requirement: &id005 !ruby/object:Gem::Requirement
84
64
  none: false
85
65
  requirements:
86
66
  - - ~>
87
67
  - !ruby/object:Gem::Version
88
- hash: 23
89
- segments:
90
- - 1
91
- - 0
92
- - 0
93
68
  version: 1.0.0
94
- name: bundler
69
+ type: :development
70
+ prerelease: false
95
71
  version_requirements: *id005
96
72
  - !ruby/object:Gem::Dependency
97
- prerelease: false
98
- type: :development
73
+ name: jeweler
99
74
  requirement: &id006 !ruby/object:Gem::Requirement
100
75
  none: false
101
76
  requirements:
102
77
  - - ~>
103
78
  - !ruby/object:Gem::Version
104
- hash: 7
105
- segments:
106
- - 1
107
- - 5
108
- - 2
109
79
  version: 1.5.2
110
- name: jeweler
80
+ type: :development
81
+ prerelease: false
111
82
  version_requirements: *id006
112
83
  description:
113
84
  email: carl.hicks@gmail.com
@@ -124,6 +95,7 @@ files:
124
95
  - ./README.rdoc
125
96
  - ./Rakefile
126
97
  - ./VERSION
98
+ - ./WATCHLIST.rdoc
127
99
  - ./lib/rails/generators/sugarcrm/config/config_generator.rb
128
100
  - ./lib/rails/generators/sugarcrm/config/templates/initializer.rb
129
101
  - ./lib/rails/generators/sugarcrm/config/templates/sugarcrm.yml
@@ -222,7 +194,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
222
194
  requirements:
223
195
  - - ">="
224
196
  - !ruby/object:Gem::Version
225
- hash: 3
197
+ hash: -4256578188939241626
226
198
  segments:
227
199
  - 0
228
200
  version: "0"
@@ -231,9 +203,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
231
203
  requirements:
232
204
  - - ">="
233
205
  - !ruby/object:Gem::Version
234
- hash: 3
235
- segments:
236
- - 0
237
206
  version: "0"
238
207
  requirements: []
239
208