sugarcrm 0.9.13 → 0.9.14
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +13 -1
- data/VERSION +1 -1
- data/WATCHLIST.rdoc +7 -0
- data/lib/sugarcrm/attributes/attribute_methods.rb +18 -8
- data/lib/sugarcrm/base.rb +27 -1
- data/lib/sugarcrm/connection/api/get_entry.rb +1 -1
- data/lib/sugarcrm/connection/api/set_document_revision.rb +9 -3
- data/lib/sugarcrm/connection/api/set_note_attachment.rb +1 -1
- data/lib/sugarcrm/connection/connection.rb +15 -4
- data/lib/sugarcrm/connection/helper.rb +9 -0
- data/lib/sugarcrm/finders/finder_methods.rb +1 -1
- data/sugarcrm.gemspec +3 -2
- data/test/connection/test_set_note_attachment.rb +1 -1
- data/test/test_finders.rb +18 -0
- data/test/test_session.rb +35 -26
- data/test/test_sugarcrm.rb +22 -4
- metadata +22 -53
data/README.rdoc
CHANGED
@@ -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.
|
1
|
+
0.9.14
|
data/WATCHLIST.rdoc
ADDED
@@ -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
|
-
|
37
|
-
|
38
|
-
|
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
|
data/lib/sugarcrm/base.rb
CHANGED
@@ -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
|
-
|
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": "#{
|
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": "#{
|
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::
|
79
|
-
|
80
|
-
|
81
|
-
|
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
|
data/sugarcrm.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{sugarcrm}
|
8
|
-
s.version = "0.9.
|
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-
|
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
|
-
|
12
|
+
assert_equal file, Base64.decode64(attachment["file"])
|
13
13
|
assert n.delete
|
14
14
|
end
|
15
15
|
end
|
data/test/test_finders.rb
CHANGED
@@ -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'
|
data/test/test_session.rb
CHANGED
@@ -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
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
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
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
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
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
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
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
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
|
data/test/test_sugarcrm.rb
CHANGED
@@ -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 "
|
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 =
|
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.
|
99
|
-
b = SugarCRM::User.
|
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
|
-
|
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-
|
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
|
-
|
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
|
-
|
25
|
+
type: :runtime
|
26
|
+
prerelease: false
|
37
27
|
version_requirements: *id001
|
38
28
|
- !ruby/object:Gem::Dependency
|
39
|
-
|
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
|
-
|
36
|
+
type: :runtime
|
37
|
+
prerelease: false
|
51
38
|
version_requirements: *id002
|
52
39
|
- !ruby/object:Gem::Dependency
|
53
|
-
|
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
|
-
|
47
|
+
type: :runtime
|
48
|
+
prerelease: false
|
65
49
|
version_requirements: *id003
|
66
50
|
- !ruby/object:Gem::Dependency
|
67
|
-
|
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
|
-
|
58
|
+
type: :development
|
59
|
+
prerelease: false
|
79
60
|
version_requirements: *id004
|
80
61
|
- !ruby/object:Gem::Dependency
|
81
|
-
|
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
|
-
|
69
|
+
type: :development
|
70
|
+
prerelease: false
|
95
71
|
version_requirements: *id005
|
96
72
|
- !ruby/object:Gem::Dependency
|
97
|
-
|
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
|
-
|
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:
|
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
|
|