google-ads-common 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +68 -0
- data/Rakefile +128 -0
- data/lib/ads_common/api.rb +183 -0
- data/lib/ads_common/api_config.rb +284 -0
- data/lib/ads_common/auth/base_handler.rb +53 -0
- data/lib/ads_common/auth/client_login_handler.rb +180 -0
- data/lib/ads_common/build/rake_common.rb +339 -0
- data/lib/ads_common/build/savon_abstract_generator.rb +59 -0
- data/lib/ads_common/build/savon_generator.rb +136 -0
- data/lib/ads_common/build/savon_registry.rb +236 -0
- data/lib/ads_common/build/savon_registry_generator.rb +139 -0
- data/lib/ads_common/build/savon_service_generator.rb +130 -0
- data/lib/ads_common/build/soap4r_generator.rb +565 -0
- data/lib/ads_common/config.rb +122 -0
- data/lib/ads_common/credential_handler.rb +72 -0
- data/lib/ads_common/errors.rb +70 -0
- data/lib/ads_common/http.rb +75 -0
- data/lib/ads_common/logger.rb +68 -0
- data/lib/ads_common/savon_headers/simple_header_handler.rb +148 -0
- data/lib/ads_common/soap4r_headers/nested_header_handler.rb +50 -0
- data/lib/ads_common/soap4r_headers/single_header_handler.rb +44 -0
- data/lib/ads_common/soap4r_patches.rb +210 -0
- data/lib/ads_common/soap4r_response_handler.rb +89 -0
- metadata +141 -0
@@ -0,0 +1,53 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
#
|
3
|
+
# Authors:: api.sgomes@gmail.com (Sérgio Gomes)
|
4
|
+
#
|
5
|
+
# Copyright:: Copyright 2010, 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
|
+
# Base class for authentication handlers, providing the basic mechanism for
|
21
|
+
# different authentication methods to be able to handle the details sent to
|
22
|
+
# the server.
|
23
|
+
|
24
|
+
module AdsCommon
|
25
|
+
module Auth
|
26
|
+
class BaseHandler
|
27
|
+
# Callback to be used by CredentialHandlers to notify the auth handler of
|
28
|
+
# a change in one of the credentials. Useful for e.g. invalidating a
|
29
|
+
# token. The generic method does nothing.
|
30
|
+
def property_changed(credential, value)
|
31
|
+
end
|
32
|
+
|
33
|
+
# This method handles an error according to the specifics of an
|
34
|
+
# authentication mechanism (to regenerate tokens, for example). The
|
35
|
+
# generic method simply re-raises the error.
|
36
|
+
def handle_error(error)
|
37
|
+
raise error
|
38
|
+
end
|
39
|
+
|
40
|
+
# This method returns the set of fields to be included in the header.
|
41
|
+
# The generic method simply returns everything passed to it.
|
42
|
+
def header_list(credentials)
|
43
|
+
return credentials.keys
|
44
|
+
end
|
45
|
+
|
46
|
+
# This method returns the key value pairs to be included in the header.
|
47
|
+
# The generic method simply returns everything passed to it.
|
48
|
+
def headers(credentials)
|
49
|
+
return credentials
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,180 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
#
|
3
|
+
# Authors:: api.sgomes@gmail.com (Sérgio Gomes)
|
4
|
+
# api.dklimkin@gmail.com (Danial Klimkin)
|
5
|
+
#
|
6
|
+
# Copyright:: Copyright 2011, Google Inc. All Rights Reserved.
|
7
|
+
#
|
8
|
+
# License:: Licensed under the Apache License, Version 2.0 (the "License");
|
9
|
+
# you may not use this file except in compliance with the License.
|
10
|
+
# You may obtain a copy of the License at
|
11
|
+
#
|
12
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
13
|
+
#
|
14
|
+
# Unless required by applicable law or agreed to in writing, software
|
15
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
16
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
17
|
+
# implied.
|
18
|
+
# See the License for the specific language governing permissions and
|
19
|
+
# limitations under the License.
|
20
|
+
#
|
21
|
+
# This module manages ClientLogin authentication. It either uses a user-provided
|
22
|
+
# auth token, or automatically connects to Google's ClientLogin service and
|
23
|
+
# generates an auth token that can be used to login to an API.
|
24
|
+
|
25
|
+
require 'cgi'
|
26
|
+
require 'ads_common/http'
|
27
|
+
require 'ads_common/auth/base_handler'
|
28
|
+
require 'ads_common/errors'
|
29
|
+
|
30
|
+
module AdsCommon
|
31
|
+
module Auth
|
32
|
+
|
33
|
+
# Credentials class to handle ClientLogin authentication.
|
34
|
+
class ClientLoginHandler < AdsCommon::Auth::BaseHandler
|
35
|
+
|
36
|
+
ACCOUNT_TYPE = 'GOOGLE'
|
37
|
+
AUTH_PATH = '/accounts/ClientLogin'
|
38
|
+
IGNORED_FIELDS = [:email, :password, :auth_token]
|
39
|
+
|
40
|
+
# Initializes the ClientLoginHandler with all the necessary details.
|
41
|
+
def initialize(config, server, service_name)
|
42
|
+
@token = config.read('authentication.auth_token')
|
43
|
+
@config = config
|
44
|
+
@server = server
|
45
|
+
@service_name = service_name
|
46
|
+
end
|
47
|
+
|
48
|
+
# Invalidates the stored token if the email, password or provided auth
|
49
|
+
# token have changed.
|
50
|
+
def property_changed(prop, value)
|
51
|
+
case prop
|
52
|
+
when :auth_token
|
53
|
+
@token = config.read('authentication.auth_token')
|
54
|
+
when :email, :password
|
55
|
+
@token = nil
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# Handle specific ClientLogin errors.
|
60
|
+
def handle_error(error)
|
61
|
+
# TODO: Add support for automatically regenerating auth tokens when they
|
62
|
+
# expire.
|
63
|
+
raise error
|
64
|
+
end
|
65
|
+
|
66
|
+
# Returns all of the fields that this auth handler will fill.
|
67
|
+
def header_list(credentials)
|
68
|
+
result = []
|
69
|
+
result << :authToken
|
70
|
+
credentials.each do |p, v|
|
71
|
+
result << p unless IGNORED_FIELDS.include?(p)
|
72
|
+
end
|
73
|
+
return result
|
74
|
+
end
|
75
|
+
|
76
|
+
# Returns all of the credentials received from the CredentialHandler,
|
77
|
+
# except for email and password.
|
78
|
+
def headers(credentials)
|
79
|
+
@token = generate_token(credentials) if @token == nil
|
80
|
+
result = {}
|
81
|
+
result[:authToken] = @token
|
82
|
+
credentials.each do |p, v|
|
83
|
+
result[p] = v unless IGNORED_FIELDS.include?(p)
|
84
|
+
end
|
85
|
+
return result
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
# Auxiliary method to validate the credentials for token generation.
|
91
|
+
#
|
92
|
+
# Args:
|
93
|
+
# - credentials: a hash with the credentials for the account being
|
94
|
+
# accessed
|
95
|
+
#
|
96
|
+
#
|
97
|
+
# Raises:
|
98
|
+
# AdsCommon::Errors::AuthError if validation fails.
|
99
|
+
#
|
100
|
+
def validate_credentials(credentials)
|
101
|
+
if credentials.nil?
|
102
|
+
raise AdsCommon::Errors::AuthError,
|
103
|
+
'No credentials supplied.'
|
104
|
+
end
|
105
|
+
|
106
|
+
if credentials[:email].nil?
|
107
|
+
raise AdsCommon::Errors::AuthError,
|
108
|
+
'Email address not included in credentials.'
|
109
|
+
end
|
110
|
+
|
111
|
+
if credentials[:password].nil?
|
112
|
+
raise AdsCommon::Errors::AuthError,
|
113
|
+
'Password not included in credentials.'
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
# Auxiliary method to generate an authentication token for logging via
|
118
|
+
# the ClientLogin API.
|
119
|
+
#
|
120
|
+
# Args:
|
121
|
+
# - credentials: a hash with the credentials for the account being
|
122
|
+
# accessed
|
123
|
+
#
|
124
|
+
# Returns:
|
125
|
+
# The auth token for the account (as a string).
|
126
|
+
#
|
127
|
+
# Raises:
|
128
|
+
# AdsCommon::Errors::AuthError if authentication fails.
|
129
|
+
#
|
130
|
+
def generate_token(credentials)
|
131
|
+
validate_credentials(credentials)
|
132
|
+
|
133
|
+
email = CGI.escape(credentials[:email])
|
134
|
+
password = CGI.escape(credentials[:password])
|
135
|
+
|
136
|
+
url = @server + AUTH_PATH
|
137
|
+
|
138
|
+
data = "accountType=%s&Email=%s&Passwd=%s&service=%s" %
|
139
|
+
[ACCOUNT_TYPE, email, password, @service_name]
|
140
|
+
headers = {'Content-Type' => 'application/x-www-form-urlencoded'}
|
141
|
+
|
142
|
+
response = AdsCommon::Http.post_response(url, data, @config, headers)
|
143
|
+
results = parse_token_text(response.body)
|
144
|
+
|
145
|
+
if response.code == 200 and results.include?(:Auth)
|
146
|
+
return results[:Auth]
|
147
|
+
else
|
148
|
+
error_message = "Login failed for email %s: HTTP code %d." %
|
149
|
+
[credentials[:email], response.code]
|
150
|
+
if results.include?(:Error)
|
151
|
+
error_message += " Error: %s." % results[:Error]
|
152
|
+
else
|
153
|
+
error_message += " Raw error: %s." % response.body
|
154
|
+
end
|
155
|
+
if results.include?(:Info)
|
156
|
+
error_message += " Info: %s." % results[:Info]
|
157
|
+
end
|
158
|
+
raise AdsCommon::Errors::AuthError, error_message
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
# Extracts key-value pairs from ClientLogin server response.
|
163
|
+
#
|
164
|
+
# Args:
|
165
|
+
# - text: server response string.
|
166
|
+
#
|
167
|
+
# Returns:
|
168
|
+
# Hash of key-value pairs.
|
169
|
+
#
|
170
|
+
def parse_token_text(text)
|
171
|
+
result = {}
|
172
|
+
text.split("\n").each do |line|
|
173
|
+
key, value = line.split("=")
|
174
|
+
result[key.to_sym] = value
|
175
|
+
end
|
176
|
+
return result
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
@@ -0,0 +1,339 @@
|
|
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 Ads client libraries.
|
24
|
+
|
25
|
+
require 'fileutils'
|
26
|
+
require 'logger'
|
27
|
+
require 'rubygems'
|
28
|
+
gem 'rake'
|
29
|
+
require 'rake/gempackagetask'
|
30
|
+
require 'rake/rdoctask'
|
31
|
+
require 'rake/clean'
|
32
|
+
require 'rake/testtask'
|
33
|
+
gem 'soap4r', '=1.5.8'
|
34
|
+
require 'wsdl/soap/wsdl2ruby'
|
35
|
+
require 'xsd/codegen/classdef'
|
36
|
+
require 'ads_common/soap4r_patches'
|
37
|
+
require 'ads_common/http'
|
38
|
+
|
39
|
+
$API_CONFIG = $MODULE::ApiConfig
|
40
|
+
|
41
|
+
$WSDLDIR = 'wsdl'
|
42
|
+
$LIBDIR = 'lib'
|
43
|
+
$DOCDIR = 'doc'
|
44
|
+
$TESTDIR = 'test'
|
45
|
+
$GENDIR = File.join($LIBDIR, $PROJECT_NAME)
|
46
|
+
$PKG_VERSION = ENV['REL'] ? ENV['REL'] : $CURRENT_VERSION
|
47
|
+
|
48
|
+
SRC_RB = FileList["#{$LIBDIR}/**/*.rb"]
|
49
|
+
|
50
|
+
logger = Logger.new(STDERR)
|
51
|
+
|
52
|
+
CLEAN.include($WSDLDIR)
|
53
|
+
CLEAN.include($DOCDIR)
|
54
|
+
$API_CONFIG.versions.each do |version|
|
55
|
+
CLEAN.include(File.join($GENDIR, version.to_s))
|
56
|
+
end
|
57
|
+
|
58
|
+
CLOBBER.include('pkg')
|
59
|
+
|
60
|
+
# ====================================================================
|
61
|
+
# Create a default task to prepare library for usage.
|
62
|
+
desc "gets the wsdl and generates the classes"
|
63
|
+
task :default => [:getwsdl, :generate]
|
64
|
+
|
65
|
+
# ====================================================================
|
66
|
+
# Create a task to retrieve the WSDL files for the services.
|
67
|
+
desc "gets the wsdl files for API services"
|
68
|
+
task :getwsdl do
|
69
|
+
$API_CONFIG.versions.each do |version|
|
70
|
+
urls = $API_CONFIG.get_wsdls(version)
|
71
|
+
mkdir_p File.join($WSDLDIR, version.to_s)
|
72
|
+
urls.each do |service, url|
|
73
|
+
puts "getting #{url}"
|
74
|
+
save(AdsCommon::Http.get(url, Generator.config),
|
75
|
+
get_wsdl_file_name(version.to_s, service.to_s))
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# Return the full file name of the WSDL file for a given version and service
|
81
|
+
def get_wsdl_file_name(version, service)
|
82
|
+
File.join($WSDLDIR, version.to_s, service.to_s) + '.wsdl'
|
83
|
+
end
|
84
|
+
|
85
|
+
# Apply fixes to the WSDL content in order to make it understandable for the
|
86
|
+
# soap4r code generator. The fixes are applied to the original object.
|
87
|
+
def fix_wsdl!(wsdl)
|
88
|
+
['type', 'base'].each do |name|
|
89
|
+
['long', 'string', 'date', 'int', 'boolean'].each do |type|
|
90
|
+
# Fix this attribute over the entire document
|
91
|
+
wsdl.gsub!(Regexp.new("#{name}=\"#{type}\""), "#{name}=\"xsd:#{type}\"")
|
92
|
+
end
|
93
|
+
end
|
94
|
+
schema_ns = "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\""
|
95
|
+
if wsdl !~ Regexp.new(schema_ns)
|
96
|
+
wsdl.gsub!(/(<wsdl:definitions[^>]*)>/, '\1 ' + schema_ns + '>')
|
97
|
+
end
|
98
|
+
return wsdl
|
99
|
+
end
|
100
|
+
|
101
|
+
# Saves this document to the specified path.
|
102
|
+
# Doesn't create the file if a 404 error page is returned.
|
103
|
+
def save(content, path)
|
104
|
+
if content !~ /<H2>Error 404<\/H2>/
|
105
|
+
File::open(path, 'w') {|f| f.write(fix_wsdl!(content))}
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# ====================================================================
|
110
|
+
# Set the default generation task to use soap4r (can be overriden for client
|
111
|
+
# libraries).
|
112
|
+
desc "generates API classes from the wsdl files"
|
113
|
+
task :generate => [:soap4r_generate]
|
114
|
+
|
115
|
+
# ====================================================================
|
116
|
+
# Create a task to generate all the service classes with soap4r.
|
117
|
+
desc "generates API classes from the wsdl files using soap4r"
|
118
|
+
task :soap4r_generate do
|
119
|
+
$API_CONFIG.versions.each do |version|
|
120
|
+
gendir = File.join($LIBDIR, $PRODDIR, version.to_s)
|
121
|
+
mkdir_p gendir
|
122
|
+
$API_CONFIG.services(version).each do |service|
|
123
|
+
# Generate SOAP classes with soap4r
|
124
|
+
service_name = service.to_s
|
125
|
+
worker = WSDL::SOAP::WSDL2Ruby.new
|
126
|
+
worker.logger = logger
|
127
|
+
worker.location = get_wsdl_file_name(version, service)
|
128
|
+
worker.basedir = gendir
|
129
|
+
worker.opt.update(get_wsdl_opt(version, service_name))
|
130
|
+
worker.run
|
131
|
+
|
132
|
+
# Fix the "require" statements so that they work in the client library's
|
133
|
+
# directory structure
|
134
|
+
fix_import(version, File.join(gendir, "#{service_name}Driver.rb"))
|
135
|
+
fix_import(version,
|
136
|
+
File.join(gendir, "#{service_name}MappingRegistry.rb"))
|
137
|
+
fix_import(version, File.join(gendir, "#{service_name}.rb"))
|
138
|
+
|
139
|
+
# Fix the comments in the file so that we get better-looking RDoc, and
|
140
|
+
# only for the things we want
|
141
|
+
fix_rdoc(File.join(gendir, "#{service_name}.rb"))
|
142
|
+
|
143
|
+
# Generate the wrapper files
|
144
|
+
eval("require '#{File.join(gendir, "#{service_name}Driver.rb")}'")
|
145
|
+
wrapper_file = File.join(gendir, "#{service_name}Wrapper.rb")
|
146
|
+
File.open(wrapper_file, 'w') do |file|
|
147
|
+
file.write(Generator.generate_wrapper_class(version, service))
|
148
|
+
end
|
149
|
+
puts "Generated #{version} #{service_name} wrapper: #{wrapper_file}"
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
# Fix "require" statements for client lib usage
|
155
|
+
def fix_import(version, file)
|
156
|
+
tempfile = file + '.tmp'
|
157
|
+
outfile = File.new(tempfile, 'w')
|
158
|
+
File.open(file, 'r') do |infile|
|
159
|
+
infile.each do |line|
|
160
|
+
if (line =~ /require.*Service.*\.rb/)
|
161
|
+
outfile << line.gsub(/require '(.*)Service(.*)\.rb'/,
|
162
|
+
"require '#{$PRODDIR}/#{version.to_s}/\\1Service\\2'")
|
163
|
+
else
|
164
|
+
outfile << line
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
outfile.close
|
169
|
+
File.rename(tempfile, file)
|
170
|
+
end
|
171
|
+
|
172
|
+
# Fix RDoc comments in the generated *Service.rb files
|
173
|
+
def fix_rdoc(file)
|
174
|
+
tempfile = file + '.tmp'
|
175
|
+
outfile = File.new(tempfile, 'w')
|
176
|
+
should_doc = true
|
177
|
+
File.open(file, 'r') do |infile|
|
178
|
+
infile.each do |line|
|
179
|
+
if (line =~ /# \{.*\}[A-Z]\w*/)
|
180
|
+
# This is a regular class. Document and clean up how it's displayed.
|
181
|
+
should_doc = true
|
182
|
+
outfile << line.gsub(/\{.*\}(.*)/, "\\1")
|
183
|
+
elsif (line =~ /# \{.*\}[a-z]\w*/)
|
184
|
+
# This is a method wrapping class. Do not document, but still clean up
|
185
|
+
# its comment.
|
186
|
+
should_doc = false
|
187
|
+
outfile << line.gsub(/\{.*\}(.*)/, "\\1")
|
188
|
+
elsif (line =~ /# \w+/)
|
189
|
+
# Itemize member variables
|
190
|
+
outfile << line.gsub(/# (.*)/, "# - \\1")
|
191
|
+
elsif (line =~ /class [A-Z].*/)
|
192
|
+
if should_doc
|
193
|
+
outfile << line
|
194
|
+
else
|
195
|
+
# Avoid documenting the method classes, since they're made invisible
|
196
|
+
# thanks to our service wrappers
|
197
|
+
outfile << line.gsub(/(.*)(\w)/, "\\1\\2 #:nodoc: all")
|
198
|
+
end
|
199
|
+
else
|
200
|
+
outfile << line
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
outfile.close
|
205
|
+
File.rename(tempfile, file)
|
206
|
+
end
|
207
|
+
|
208
|
+
# Create options to be used for class generation from WSDL
|
209
|
+
def get_wsdl_opt(version, service_name)
|
210
|
+
optcmd= {}
|
211
|
+
optcmd['classdef'] = service_name
|
212
|
+
optcmd['force'] = true
|
213
|
+
optcmd['mapping_registry'] = true
|
214
|
+
optcmd['driver'] = nil
|
215
|
+
|
216
|
+
# Causes soap4r to wrap the classes it outputs into the given modules
|
217
|
+
optcmd['module_path'] = [$MODULE.name, version.to_s.capitalize, service_name]
|
218
|
+
return optcmd
|
219
|
+
end
|
220
|
+
|
221
|
+
# ====================================================================
|
222
|
+
# Create a task to build the RDOC documentation tree.
|
223
|
+
Rake::RDocTask.new("rdoc") do |rdoc|
|
224
|
+
# Try to use SDoc to generate the docs
|
225
|
+
begin
|
226
|
+
require 'sdoc'
|
227
|
+
rdoc.options << '--fmt' << 'shtml'
|
228
|
+
rdoc.template = 'direct'
|
229
|
+
rescue LoadError
|
230
|
+
# Do nothing, give up on SDoc and continue with whatever is the default.
|
231
|
+
end
|
232
|
+
rdoc.rdoc_dir = $DOCDIR
|
233
|
+
rdoc.title = "#{$PROJECT_NAME} -- Client library for the #{$API_NAME}"
|
234
|
+
rdoc.main = 'README'
|
235
|
+
rdoc.rdoc_files.include('README', 'COPYING', 'ChangeLog')
|
236
|
+
rdoc.rdoc_files.include("#{$LIBDIR}/*.rb", "#{$LIBDIR}/#{$PRODDIR}/*.rb")
|
237
|
+
rdoc.rdoc_files.include("#{$LIBDIR}/#{$PRODDIR}/v*/*Wrapper.rb")
|
238
|
+
rdoc.rdoc_files.include("#{$LIBDIR}/#{$PRODDIR}/v*/*Service.rb")
|
239
|
+
rdoc.rdoc_files.exclude("#{$LIBDIR}/#{$PRODDIR}/soap4rpatches.rb")
|
240
|
+
end
|
241
|
+
|
242
|
+
# ====================================================================
|
243
|
+
# Create a task to perform the unit testing.
|
244
|
+
Rake::TestTask.new("test") do |test|
|
245
|
+
test.libs << $TESTDIR
|
246
|
+
test.pattern = "#{$TESTDIR}/**/test_*.rb"
|
247
|
+
test.verbose = true
|
248
|
+
end
|
249
|
+
|
250
|
+
# ====================================================================
|
251
|
+
# Create a task that will package the Rake software into distributable
|
252
|
+
# gem files.
|
253
|
+
|
254
|
+
# Utility method to create readable version ranges. May not cover a few edge
|
255
|
+
# cases, but this is a best effort approach.
|
256
|
+
def readable_version_range(version_string)
|
257
|
+
return '' if version_string.nil?
|
258
|
+
|
259
|
+
version_string = version_string.to_s.strip
|
260
|
+
pattern = /^(>|<|>=|<=|~>)(\s*)(\d[\d\.]*)$/
|
261
|
+
result = pattern.match(version_string)
|
262
|
+
|
263
|
+
return version_string unless result
|
264
|
+
|
265
|
+
case result[1]
|
266
|
+
when '>'
|
267
|
+
return 'greater than version ' + result[3]
|
268
|
+
when '<'
|
269
|
+
return 'lower than version ' + result[3]
|
270
|
+
when '>='
|
271
|
+
return 'version ' + result[3] + ' or later'
|
272
|
+
when '<='
|
273
|
+
return 'version ' + result[3] + ' or earlier'
|
274
|
+
when '~>'
|
275
|
+
version_pattern = /^(\d[\d\.]*)(\d)$/
|
276
|
+
version_result = version_pattern.match(result[3])
|
277
|
+
if version_result
|
278
|
+
return 'version ' + version_result[1] + 'x'
|
279
|
+
else
|
280
|
+
return version_string
|
281
|
+
end
|
282
|
+
else
|
283
|
+
return version_string
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
PKG_FILES = FileList[
|
288
|
+
'*.*',
|
289
|
+
'Rakefile',
|
290
|
+
"#{$LIBDIR}/**/*.rb",
|
291
|
+
"#{$LIBDIR}/#{$PRODDIR}/data/*.*",
|
292
|
+
'examples/**/*.rb',
|
293
|
+
"#{$DOCDIR}/**/*.*",
|
294
|
+
"#{$TESTDIR}/**/*.*"
|
295
|
+
]
|
296
|
+
|
297
|
+
PKG_FILES.exclude(/\._/)
|
298
|
+
|
299
|
+
if ! defined?(Gem)
|
300
|
+
puts "Package Target requires RubyGems"
|
301
|
+
else
|
302
|
+
spec = Gem::Specification.new do |s|
|
303
|
+
|
304
|
+
# Basic information
|
305
|
+
s.name = $GEM_NAME
|
306
|
+
s.version = $PKG_VERSION
|
307
|
+
s.summary = $GEM_SUMMARY
|
308
|
+
s.description = $GEM_DESCRIPTION
|
309
|
+
|
310
|
+
# Files and dependencies
|
311
|
+
dependencies = [['soap4r', '= 1.5.8'],
|
312
|
+
['httpclient', '>= 2.1.2'],
|
313
|
+
['google-ads-common', $ADS_COMMON_VERSION]]
|
314
|
+
dependencies += $EXTRA_DEPENDENCIES if $EXTRA_DEPENDENCIES
|
315
|
+
s.files = PKG_FILES.to_a
|
316
|
+
s.require_path = $LIBDIR
|
317
|
+
dependencies.each do |dep|
|
318
|
+
s.add_dependency(dep[0], dep[1])
|
319
|
+
end
|
320
|
+
|
321
|
+
# RDoc information
|
322
|
+
s.has_rdoc = true
|
323
|
+
s.extra_rdoc_files = ['README']
|
324
|
+
s.rdoc_options << '--main' << 'README'
|
325
|
+
|
326
|
+
# Metadata
|
327
|
+
s.authors = $GEM_AUTHORS
|
328
|
+
s.email = $GEM_EMAIL
|
329
|
+
s.homepage = $GEM_HOMEPAGE
|
330
|
+
s.rubyforge_project = $PROJECT_NAME
|
331
|
+
dependencies.each do |dep|
|
332
|
+
s.requirements << dep[0] + ' ' + readable_version_range(dep[1])
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
336
|
+
Rake::GemPackageTask.new(spec) do |t|
|
337
|
+
t.need_tar = true
|
338
|
+
end
|
339
|
+
end
|