google-adwords-api 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -40,7 +40,7 @@ module AdwordsApi
40
40
  # Set other constants
41
41
  API_NAME = 'AdwordsApi'
42
42
  API_PATH = 'adwords_api'
43
- CLIENT_LIB_VERSION = '0.2.0'
43
+ CLIENT_LIB_VERSION = '0.2.1'
44
44
  DEFAULT_CONFIG_FILENAME = 'adwords_api.yml'
45
45
 
46
46
  # Configure the services available to each version
@@ -85,6 +85,7 @@ module AdwordsApi
85
85
  # Configure the different environments, with the base URL for each one
86
86
  @@environment_config = {
87
87
  :PRODUCTION => {
88
+ :oauth_scope => 'https://adwords.google.com/api/adwords/',
88
89
  :v13 => 'https://adwords.google.com/api/adwords/',
89
90
  :v200909 => 'https://adwords.google.com/api/adwords/',
90
91
  :v201003 => 'https://adwords.google.com/api/adwords/',
@@ -92,6 +93,7 @@ module AdwordsApi
92
93
  :v201101 => 'https://adwords.google.com/api/adwords/'
93
94
  },
94
95
  :SANDBOX => {
96
+ :oauth_scope => 'https://adwords-sandbox.google.com/api/adwords/',
95
97
  :v13 => 'https://sandbox.google.com/api/adwords/',
96
98
  :v200909 => 'https://adwords-sandbox.google.com/api/adwords/',
97
99
  :v201003 => 'https://adwords-sandbox.google.com/api/adwords/',
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/ruby
2
2
  #
3
3
  # Authors:: api.sgomes@gmail.com (Sérgio Gomes)
4
+ # api.dklimkin@gmail.com (Danial Klimkin)
4
5
  #
5
6
  # Copyright:: Copyright 2011, Google Inc. All Rights Reserved.
6
7
  #
@@ -24,8 +25,6 @@ require 'adwords_api/api_config'
24
25
 
25
26
  module AdwordsApi
26
27
  class CredentialHandler < AdsCommon::CredentialHandler
27
- SERVICE_NAME = 'adwords'
28
-
29
28
  # Whether we're making MCC-level requests.
30
29
  attr_accessor :use_mcc
31
30
  # Whether we're making validate-only requests.
@@ -34,7 +33,7 @@ module AdwordsApi
34
33
  attr_accessor :partial_failure
35
34
 
36
35
  def initialize(config)
37
- super
36
+ super(config)
38
37
  @use_mcc = false
39
38
  @validate_only = false
40
39
  @partial_failure = false
@@ -44,18 +43,25 @@ module AdwordsApi
44
43
  # generation.
45
44
  def credentials(version = nil)
46
45
  validate_headers_for_server
47
- result = {}
46
+ method = @credentials[:method].to_s.upcase.to_sym
47
+ result = case method
48
+ when :CLIENTLOGIN
49
+ {:email => @credentials[:email],
50
+ :password => @credentials[:password]}
51
+ when :OAUTH
52
+ {:oauth_consumer_key => @credentials[:oauth_consumer_key],
53
+ :oauth_consumer_secret => @credentials[:oauth_consumer_secret],
54
+ :oauth_verification_code => @credentials[:oauth_verification_code],
55
+ :oauth_token => @credentials[:oauth_token],
56
+ :oauth_token_secret => @credentials[:oauth_token_secret],
57
+ :oauth_callback => @credentials[:oauth_callback],
58
+ :oauth_method => @credentials[:oauth_method]}
59
+ end
48
60
  client_lib = 'Ruby-AwApi-%s|' % AdwordsApi::ApiConfig::CLIENT_LIB_VERSION
49
- user_agent = @credentials[:user_agent]
50
- user_agent = $0 if user_agent.nil?
61
+ user_agent = @credentials[:user_agent] || $0
51
62
  user_agent = client_lib + user_agent
52
- if (version == :v13)
53
- result[:useragent] = user_agent
54
- else
55
- result[:userAgent] = user_agent
56
- end
57
- result[:email] = @credentials[:email]
58
- result[:password] = @credentials[:password]
63
+ user_agent_symbol = (version == :v13) ? :useragent : :userAgent
64
+ result[user_agent_symbol] = user_agent
59
65
  result[:developerToken] = @credentials[:developer_token]
60
66
  unless @use_mcc
61
67
  if @credentials[:client_email]
@@ -64,13 +70,11 @@ module AdwordsApi
64
70
  result[:clientCustomerId] = @credentials[:client_customer_id]
65
71
  end
66
72
  end
67
- if version != :v13 and @validate_only
68
- result[:validateOnly] = 'true'
69
- end
70
- if version != :v13 and @partial_failure
71
- result[:partialFailure] = 'true'
73
+ if version != :v13
74
+ result[:validateOnly] = 'true' if @validate_only
75
+ result[:partialFailure] = 'true' if @partial_failure
72
76
  end
73
- return result
77
+ return result.reject {|k,v| v.nil?}
74
78
  end
75
79
 
76
80
  private
@@ -83,28 +87,39 @@ module AdwordsApi
83
87
  # being used for production or vice-versa.
84
88
  #
85
89
  def validate_headers_for_server
86
- email = @credentials[:email]
90
+ method = @credentials[:method].to_s.upcase.to_sym
87
91
  token = @credentials[:developer_token]
88
- client = @credentials[:client_email]
89
- environment = @config.read('service.environment').to_s.upcase
90
-
91
- sandbox_token = (token =~ /#{Regexp.escape(email)}\+\+[a-zA-Z]{3}/)
92
- sandbox_client = (client =~ /client_[1-5]\+#{Regexp.escape(email)}/)
93
-
94
- # Only check the token, because 'client_n+x@y.tld' may be a valid client
95
- # email for some customers.
96
- if environment == 'PRODUCTION' and sandbox_token
97
- raise AdsCommon::Errors::EnvironmentMismatchError,
98
- 'Attempting to connect to production with sandbox credentials.'
99
- # Check if either the token or client email do not follow the correct
100
- # format. Client email may not exist, though.
101
- elsif environment == 'SANDBOX' and (!sandbox_token or
102
- (client.length > 0 and !sandbox_client))
103
- raise AdsCommon::Errors::EnvironmentMismatchError,
104
- 'Attempting to connect to the sandbox with malformatted ' +
105
- 'credentials. Please check ' +
106
- 'http://code.google.com/apis/adwords/docs/developer/' +
107
- 'adwords_api_sandbox.html#requestheaders for details.'
92
+ client_email = @credentials[:client_email]
93
+ (sandbox_token, sandbox_client) = case method
94
+ when :CLIENTLOGIN
95
+ email = @credentials[:email]
96
+ [(token =~ /#{Regexp.escape(email)}\+\+[a-zA-Z]{3}/),
97
+ (client_email =~ /client_[1-5]\+#{Regexp.escape(email)}/)]
98
+ when :OAUTH
99
+ [(token =~ /.+@.+\+\+[a-zA-Z]{3}/),
100
+ (client_email =~ /client_[1-5]\+.+@.+/)]
101
+ else
102
+ [nil, nil]
103
+ end
104
+ environment = @config.read('service.environment')
105
+ case environment
106
+ when :PRODUCTION
107
+ # Only check the token, because 'client_n+x@y.tld' may be a valid
108
+ # client email for some customers.
109
+ if sandbox_token
110
+ raise AdsCommon::Errors::EnvironmentMismatchError,
111
+ 'Attempting to connect to production with sandbox credentials.'
112
+ end
113
+ when :SANDBOX
114
+ # Check if either the token or client email do not follow the
115
+ # correct format. Client email may not exist, though.
116
+ if (!sandbox_token or (!client_email.empty? and !sandbox_client))
117
+ raise AdsCommon::Errors::EnvironmentMismatchError,
118
+ 'Attempting to connect to the sandbox with malformatted ' +
119
+ 'credentials. Please check ' +
120
+ 'http://code.google.com/apis/adwords/docs/developer/' +
121
+ 'adwords_api_sandbox.html#requestheaders for details.'
122
+ end
108
123
  end
109
124
  end
110
125
  end
@@ -354,7 +354,7 @@ module AdwordsApi
354
354
 
355
355
  # Makes sure object is an array.
356
356
  def self.arrayize(object)
357
- return Array.new if object.nil?
357
+ return [] if object.nil?
358
358
  return object.is_a?(Array) ? object : [object]
359
359
  end
360
360
 
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/ruby
2
+ #
3
+ # Authors:: api.sgomes@gmail.com (Sérgio Gomes)
4
+ #
5
+ # Copyright:: Copyright 2011, Google Inc. All Rights Reserved.
6
+ #
7
+ # License:: Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
16
+ # implied.
17
+ # See the License for the specific language governing permissions and
18
+ # limitations under the License.
19
+ #
20
+ # Handles soap headers for AdWords v2009-style SOAP requests (nested headers).
21
+
22
+ require 'soap/header/simplehandler'
23
+
24
+ module AdwordsApi
25
+ class NestedHeaderHandler < SOAP::Header::SimpleHandler
26
+
27
+ def initialize(credential_handler, auth_handler, top_element_name,
28
+ top_namespace, inner_namespace, version = nil)
29
+ super(XSD::QName.new(top_namespace, top_element_name))
30
+ @credential_handler = credential_handler
31
+ @auth_handler = auth_handler
32
+ @ns = inner_namespace
33
+ @version = version
34
+ end
35
+
36
+ # Handles callback.
37
+ def on_simple_outbound
38
+ main_header = SOAP::SOAPElement.new(nil)
39
+ credentials = @credential_handler.credentials
40
+ @auth_handler.headers(credentials).each do |cred, value|
41
+ cred_header = SOAP::SOAPElement.new(XSD::QName.new(@ns, cred), value)
42
+ main_header.add(cred_header)
43
+ end
44
+ return main_header
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/ruby
2
+ #
3
+ # Authors:: api.sgomes@gmail.com (Sérgio Gomes)
4
+ #
5
+ # Copyright:: Copyright 2011, Google Inc. All Rights Reserved.
6
+ #
7
+ # License:: Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
16
+ # implied.
17
+ # See the License for the specific language governing permissions and
18
+ # limitations under the License.
19
+ #
20
+ # Handles soap headers for AdWords v13-style SOAP requests (flat headers).
21
+
22
+ require 'soap/header/simplehandler'
23
+
24
+ module AdwordsApi
25
+ class SingleHeaderHandler < SOAP::Header::SimpleHandler
26
+
27
+ def initialize(credential_handler, auth_handler,
28
+ element_name, element_namespace = nil, version = nil)
29
+ super(XSD::QName.new(element_namespace, element_name))
30
+ @credential_handler = credential_handler
31
+ @auth_handler = auth_handler
32
+ @element_name = element_name
33
+ @version = version
34
+ end
35
+
36
+ def on_simple_outbound
37
+ credentials = @credential_handler.credentials
38
+ return @auth_handler.headers(credentials)[@element_name]
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,345 @@
1
+ #!/usr/bin/ruby
2
+ #
3
+ # Authors:: api.sgomes@gmail.com (Sérgio Gomes)
4
+ # api.jeffy@gmail.com (Jeffrey Posnick)
5
+ # chanezon@google.com (Patrick Chanezon)
6
+ # leavengood@gmail.com (Ryan Leavengood)
7
+ #
8
+ # Copyright:: Copyright 2011, Google Inc. All Rights Reserved.
9
+ #
10
+ # License:: Licensed under the Apache License, Version 2.0 (the "License");
11
+ # you may not use this file except in compliance with the License.
12
+ # You may obtain a copy of the License at
13
+ #
14
+ # http://www.apache.org/licenses/LICENSE-2.0
15
+ #
16
+ # Unless required by applicable law or agreed to in writing, software
17
+ # distributed under the License is distributed on an "AS IS" BASIS,
18
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
19
+ # implied.
20
+ # See the License for the specific language governing permissions and
21
+ # limitations under the License.
22
+ #
23
+ # Common Rake tasks for Soap4r-based AdWords client library.
24
+
25
+ require 'rubygems'
26
+ gem 'rake'
27
+ gem 'soap4r', '=1.5.8'
28
+ require 'fileutils'
29
+ require 'logger'
30
+ require 'rake/gempackagetask'
31
+ require 'rake/rdoctask'
32
+ require 'rake/clean'
33
+ require 'rake/testtask'
34
+ require 'wsdl/soap/wsdl2ruby'
35
+ require 'xsd/codegen/classdef'
36
+
37
+ require 'ads_common/http'
38
+
39
+ require 'adwords_api/soap4r/soap4r_patches'
40
+
41
+ $API_CONFIG = $MODULE::ApiConfig
42
+
43
+ $WSDLDIR = 'wsdl'
44
+ $LIBDIR = 'lib'
45
+ $DOCDIR = 'doc'
46
+ $TESTDIR = 'test'
47
+ $GENDIR = File.join($LIBDIR, $PROJECT_NAME)
48
+ $PKG_VERSION = ENV['REL'] ? ENV['REL'] : $CURRENT_VERSION
49
+
50
+ SRC_RB = FileList["#{$LIBDIR}/**/*.rb"]
51
+
52
+ logger = Logger.new(STDOUT)
53
+ logger.level = Logger::INFO
54
+
55
+ CLEAN.include($WSDLDIR)
56
+ CLEAN.include($DOCDIR)
57
+ $API_CONFIG.versions.each do |version|
58
+ CLEAN.include(File.join($GENDIR, version.to_s))
59
+ end
60
+
61
+ CLOBBER.include('pkg')
62
+
63
+ # ====================================================================
64
+ # Create a default task to prepare library for usage.
65
+ desc "gets the wsdl and generates the classes"
66
+ task :default => [:getwsdl, :generate]
67
+
68
+ # ====================================================================
69
+ # Create a task to retrieve the WSDL files for the services.
70
+ desc "gets the wsdl files for API services"
71
+ task :getwsdl do
72
+ $API_CONFIG.versions.each do |version|
73
+ urls = $API_CONFIG.get_wsdls(version)
74
+ mkdir_p File.join($WSDLDIR, version.to_s)
75
+ config = Generator.config
76
+ config.set('library.logger', logger)
77
+ urls.each do |service, url|
78
+ logger.info("Getting #{url}...")
79
+ save(AdsCommon::Http.get(url, config),
80
+ get_wsdl_file_name(version.to_s, service.to_s))
81
+ end
82
+ end
83
+ end
84
+
85
+ # Return the full file name of the WSDL file for a given version and service
86
+ def get_wsdl_file_name(version, service)
87
+ File.join($WSDLDIR, version.to_s, service.to_s) + '.wsdl'
88
+ end
89
+
90
+ # Apply fixes to the WSDL content in order to make it understandable for the
91
+ # soap4r code generator. The fixes are applied to the original object.
92
+ def fix_wsdl!(wsdl)
93
+ ['type', 'base'].each do |name|
94
+ ['long', 'string', 'date', 'int', 'boolean'].each do |type|
95
+ # Fix this attribute over the entire document
96
+ wsdl.gsub!(Regexp.new("#{name}=\"#{type}\""), "#{name}=\"xsd:#{type}\"")
97
+ end
98
+ end
99
+ schema_ns = "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\""
100
+ if wsdl !~ Regexp.new(schema_ns)
101
+ wsdl.gsub!(/(<wsdl:definitions[^>]*)>/, '\1 ' + schema_ns + '>')
102
+ end
103
+ return wsdl
104
+ end
105
+
106
+ # Saves this document to the specified path.
107
+ # Doesn't create the file if a 404 error page is returned.
108
+ def save(content, path)
109
+ if content !~ /<H2>Error 404<\/H2>/
110
+ File::open(path, 'w') {|f| f.write(fix_wsdl!(content))}
111
+ end
112
+ end
113
+
114
+ # ====================================================================
115
+ # Set the default generation task to use soap4r (can be overriden for client
116
+ # libraries).
117
+ desc "generates API classes from the wsdl files"
118
+ task :generate => [:soap4r_generate]
119
+
120
+ # ====================================================================
121
+ # Create a task to generate all the service classes with soap4r.
122
+ desc "generates API classes from the wsdl files using soap4r"
123
+ task :soap4r_generate do
124
+ $API_CONFIG.versions.each do |version|
125
+ gendir = File.join($LIBDIR, $PRODDIR, version.to_s)
126
+ mkdir_p gendir
127
+ $API_CONFIG.services(version).each do |service|
128
+ # Generate SOAP classes with soap4r
129
+ service_name = service.to_s
130
+ worker = WSDL::SOAP::WSDL2Ruby.new
131
+ worker.logger = logger
132
+ worker.location = get_wsdl_file_name(version, service)
133
+ worker.basedir = gendir
134
+ worker.opt.update(get_wsdl_opt(version, service_name))
135
+ worker.run
136
+
137
+ # Fix the "require" statements so that they work in the client library's
138
+ # directory structure
139
+ fix_import(version, File.join(gendir, "#{service_name}Driver.rb"))
140
+ fix_import(version,
141
+ File.join(gendir, "#{service_name}MappingRegistry.rb"))
142
+ fix_import(version, File.join(gendir, "#{service_name}.rb"))
143
+
144
+ # Fix the comments in the file so that we get better-looking RDoc, and
145
+ # only for the things we want
146
+ fix_rdoc(File.join(gendir, "#{service_name}.rb"))
147
+
148
+ # Generate the wrapper files
149
+ eval("require '#{File.join(gendir, "#{service_name}Driver.rb")}'")
150
+ wrapper_file = File.join(gendir, "#{service_name}Wrapper.rb")
151
+ File.open(wrapper_file, 'w') do |file|
152
+ file.write(Generator.generate_wrapper_class(version, service))
153
+ end
154
+ logger.info("Generated #{version} #{service_name} " +
155
+ "wrapper: #{wrapper_file}")
156
+ end
157
+ end
158
+ end
159
+
160
+ # Fix "require" statements for client lib usage
161
+ def fix_import(version, file)
162
+ tempfile = file + '.tmp'
163
+ outfile = File.new(tempfile, 'w')
164
+ File.open(file, 'r') do |infile|
165
+ infile.each do |line|
166
+ if (line =~ /require.*Service.*\.rb/)
167
+ outfile << line.gsub(/require '(.*)Service(.*)\.rb'/,
168
+ "require '#{$PRODDIR}/#{version.to_s}/\\1Service\\2'")
169
+ else
170
+ outfile << line
171
+ end
172
+ end
173
+ end
174
+ outfile.close
175
+ File.rename(tempfile, file)
176
+ end
177
+
178
+ # Fix RDoc comments in the generated *Service.rb files
179
+ def fix_rdoc(file)
180
+ tempfile = file + '.tmp'
181
+ outfile = File.new(tempfile, 'w')
182
+ should_doc = true
183
+ File.open(file, 'r') do |infile|
184
+ infile.each do |line|
185
+ if (line =~ /# \{.*\}[A-Z]\w*/)
186
+ # This is a regular class. Document and clean up how it's displayed.
187
+ should_doc = true
188
+ outfile << line.gsub(/\{.*\}(.*)/, "\\1")
189
+ elsif (line =~ /# \{.*\}[a-z]\w*/)
190
+ # This is a method wrapping class. Do not document, but still clean up
191
+ # its comment.
192
+ should_doc = false
193
+ outfile << line.gsub(/\{.*\}(.*)/, "\\1")
194
+ elsif (line =~ /# \w+/)
195
+ # Itemize member variables
196
+ outfile << line.gsub(/# (.*)/, "# - \\1")
197
+ elsif (line =~ /class [A-Z].*/)
198
+ if should_doc
199
+ outfile << line
200
+ else
201
+ # Avoid documenting the method classes, since they're made invisible
202
+ # thanks to our service wrappers
203
+ outfile << line.gsub(/(.*)(\w)/, "\\1\\2 #:nodoc: all")
204
+ end
205
+ else
206
+ outfile << line
207
+ end
208
+ end
209
+ end
210
+ outfile.close
211
+ File.rename(tempfile, file)
212
+ end
213
+
214
+ # Create options to be used for class generation from WSDL
215
+ def get_wsdl_opt(version, service_name)
216
+ optcmd= {}
217
+ optcmd['classdef'] = service_name
218
+ optcmd['force'] = true
219
+ optcmd['mapping_registry'] = true
220
+ optcmd['driver'] = nil
221
+
222
+ # Causes soap4r to wrap the classes it outputs into the given modules
223
+ optcmd['module_path'] = [$MODULE.name, version.to_s.capitalize, service_name]
224
+ return optcmd
225
+ end
226
+
227
+ # ====================================================================
228
+ # Create a task to build the RDOC documentation tree.
229
+ Rake::RDocTask.new("rdoc") do |rdoc|
230
+ # Try to use SDoc to generate the docs
231
+ begin
232
+ require 'sdoc'
233
+ rdoc.options << '--fmt' << 'shtml'
234
+ rdoc.template = 'direct'
235
+ rescue LoadError
236
+ # Do nothing, give up on SDoc and continue with whatever is the default.
237
+ end
238
+ rdoc.rdoc_dir = $DOCDIR
239
+ rdoc.title = "#{$PROJECT_NAME} -- Client library for the #{$API_NAME}"
240
+ rdoc.main = 'README'
241
+ rdoc.rdoc_files.include('README', 'COPYING', 'ChangeLog')
242
+ rdoc.rdoc_files.include("#{$LIBDIR}/*.rb", "#{$LIBDIR}/#{$PRODDIR}/*.rb")
243
+ rdoc.rdoc_files.include("#{$LIBDIR}/#{$PRODDIR}/v*/*Wrapper.rb")
244
+ rdoc.rdoc_files.include("#{$LIBDIR}/#{$PRODDIR}/v*/*Service.rb")
245
+ rdoc.rdoc_files.exclude("#{$LIBDIR}/#{$PRODDIR}/soap4rpatches.rb")
246
+ end
247
+
248
+ # ====================================================================
249
+ # Create a task to perform the unit testing.
250
+ Rake::TestTask.new("test") do |test|
251
+ test.libs << $TESTDIR
252
+ test.pattern = "#{$TESTDIR}/**/test_*.rb"
253
+ test.verbose = true
254
+ end
255
+
256
+ # ====================================================================
257
+ # Create a task that will package the Rake software into distributable
258
+ # gem files.
259
+
260
+ # Utility method to create readable version ranges. May not cover a few edge
261
+ # cases, but this is a best effort approach.
262
+ def readable_version_range(version_string)
263
+ return '' if version_string.nil?
264
+
265
+ version_string = version_string.to_s.strip
266
+ pattern = /^(>|<|>=|<=|~>)(\s*)(\d[\d\.]*)$/
267
+ result = pattern.match(version_string)
268
+
269
+ return version_string unless result
270
+
271
+ case result[1]
272
+ when '>'
273
+ return 'greater than version ' + result[3]
274
+ when '<'
275
+ return 'lower than version ' + result[3]
276
+ when '>='
277
+ return 'version ' + result[3] + ' or later'
278
+ when '<='
279
+ return 'version ' + result[3] + ' or earlier'
280
+ when '~>'
281
+ version_pattern = /^(\d[\d\.]*)(\d)$/
282
+ version_result = version_pattern.match(result[3])
283
+ if version_result
284
+ return 'version ' + version_result[1] + 'x'
285
+ else
286
+ return version_string
287
+ end
288
+ else
289
+ return version_string
290
+ end
291
+ end
292
+
293
+ PKG_FILES = FileList[
294
+ '*.*',
295
+ 'Rakefile',
296
+ "#{$LIBDIR}/**/*.rb",
297
+ "#{$LIBDIR}/#{$PRODDIR}/data/*.*",
298
+ 'examples/**/*.rb',
299
+ "#{$DOCDIR}/**/*.*",
300
+ "#{$TESTDIR}/**/*.*"
301
+ ]
302
+
303
+ PKG_FILES.exclude(/\._/)
304
+
305
+ if ! defined?(Gem)
306
+ logger.fatal('Package Target requires RubyGems')
307
+ else
308
+ spec = Gem::Specification.new do |s|
309
+
310
+ # Basic information
311
+ s.name = $GEM_NAME
312
+ s.version = $PKG_VERSION
313
+ s.summary = $GEM_SUMMARY
314
+ s.description = $GEM_DESCRIPTION
315
+
316
+ # Files and dependencies
317
+ dependencies = [['soap4r', '= 1.5.8'],
318
+ ['httpclient', '>= 2.1.2'],
319
+ ['google-ads-common', $ADS_COMMON_VERSION]]
320
+ dependencies += $EXTRA_DEPENDENCIES if $EXTRA_DEPENDENCIES
321
+ s.files = PKG_FILES.to_a
322
+ s.require_path = $LIBDIR
323
+ dependencies.each do |dep|
324
+ s.add_dependency(dep[0], dep[1])
325
+ end
326
+
327
+ # RDoc information
328
+ s.has_rdoc = true
329
+ s.extra_rdoc_files = ['README', 'COPYING', 'ChangeLog']
330
+ s.rdoc_options << '--main' << 'README'
331
+
332
+ # Metadata
333
+ s.authors = $GEM_AUTHORS
334
+ s.email = $GEM_EMAIL
335
+ s.homepage = $GEM_HOMEPAGE
336
+ s.rubyforge_project = $PROJECT_NAME
337
+ dependencies.each do |dep|
338
+ s.requirements << dep[0] + ' ' + readable_version_range(dep[1])
339
+ end
340
+ end
341
+
342
+ Rake::GemPackageTask.new(spec) do |t|
343
+ t.need_tar = true
344
+ end
345
+ end