openc-asana 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.codeclimate.yml +4 -0
- data/.gitignore +13 -0
- data/.rspec +4 -0
- data/.rubocop.yml +11 -0
- data/.travis.yml +12 -0
- data/.yardopts +5 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +21 -0
- data/Guardfile +86 -0
- data/LICENSE.txt +21 -0
- data/README.md +355 -0
- data/Rakefile +65 -0
- data/examples/Gemfile +6 -0
- data/examples/Gemfile.lock +59 -0
- data/examples/api_token.rb +21 -0
- data/examples/cli_app.rb +25 -0
- data/examples/events.rb +38 -0
- data/examples/omniauth_integration.rb +54 -0
- data/lib/asana.rb +12 -0
- data/lib/asana/authentication.rb +8 -0
- data/lib/asana/authentication/oauth2.rb +42 -0
- data/lib/asana/authentication/oauth2/access_token_authentication.rb +51 -0
- data/lib/asana/authentication/oauth2/bearer_token_authentication.rb +32 -0
- data/lib/asana/authentication/oauth2/client.rb +50 -0
- data/lib/asana/authentication/token_authentication.rb +20 -0
- data/lib/asana/client.rb +124 -0
- data/lib/asana/client/configuration.rb +165 -0
- data/lib/asana/errors.rb +92 -0
- data/lib/asana/http_client.rb +155 -0
- data/lib/asana/http_client/environment_info.rb +53 -0
- data/lib/asana/http_client/error_handling.rb +103 -0
- data/lib/asana/http_client/response.rb +32 -0
- data/lib/asana/resource_includes/attachment_uploading.rb +33 -0
- data/lib/asana/resource_includes/collection.rb +68 -0
- data/lib/asana/resource_includes/event.rb +51 -0
- data/lib/asana/resource_includes/event_subscription.rb +14 -0
- data/lib/asana/resource_includes/events.rb +103 -0
- data/lib/asana/resource_includes/registry.rb +63 -0
- data/lib/asana/resource_includes/resource.rb +103 -0
- data/lib/asana/resource_includes/response_helper.rb +14 -0
- data/lib/asana/resources.rb +14 -0
- data/lib/asana/resources/attachment.rb +44 -0
- data/lib/asana/resources/project.rb +154 -0
- data/lib/asana/resources/story.rb +64 -0
- data/lib/asana/resources/tag.rb +120 -0
- data/lib/asana/resources/task.rb +300 -0
- data/lib/asana/resources/team.rb +55 -0
- data/lib/asana/resources/user.rb +72 -0
- data/lib/asana/resources/workspace.rb +91 -0
- data/lib/asana/ruby2_0_0_compatibility.rb +3 -0
- data/lib/asana/version.rb +5 -0
- data/lib/templates/index.js +8 -0
- data/lib/templates/resource.ejs +225 -0
- data/openc-asana.gemspec +32 -0
- data/package.json +7 -0
- metadata +200 -0
@@ -0,0 +1,72 @@
|
|
1
|
+
### WARNING: This file is auto-generated by the asana-api-meta repo. Do not
|
2
|
+
### edit it manually.
|
3
|
+
|
4
|
+
module Asana
|
5
|
+
module Resources
|
6
|
+
# A _user_ object represents an account in Asana that can be given access to
|
7
|
+
# various workspaces, projects, and tasks.
|
8
|
+
#
|
9
|
+
# Like other objects in the system, users are referred to by numerical IDs.
|
10
|
+
# However, the special string identifier `me` can be used anywhere
|
11
|
+
# a user ID is accepted, to refer to the current authenticated user.
|
12
|
+
class User < Resource
|
13
|
+
|
14
|
+
|
15
|
+
attr_reader :id
|
16
|
+
|
17
|
+
attr_reader :email
|
18
|
+
|
19
|
+
attr_reader :photo
|
20
|
+
|
21
|
+
attr_reader :workspaces
|
22
|
+
|
23
|
+
class << self
|
24
|
+
# Returns the plural name of the resource.
|
25
|
+
def plural_name
|
26
|
+
'users'
|
27
|
+
end
|
28
|
+
|
29
|
+
# Returns the full user record for the currently authenticated user.
|
30
|
+
#
|
31
|
+
# options - [Hash] the request I/O options.
|
32
|
+
def me(client, options: {})
|
33
|
+
|
34
|
+
Resource.new(parse(client.get("/users/me", options: options)).first, client: client)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Returns the full user record for a single user.
|
38
|
+
#
|
39
|
+
# id - [Id] Globally unique identifier for the user.
|
40
|
+
#
|
41
|
+
# options - [Hash] the request I/O options.
|
42
|
+
def find_by_id(client, id, options: {})
|
43
|
+
|
44
|
+
self.new(parse(client.get("/users/#{id}", options: options)).first, client: client)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Returns the user records for all users in all workspaces and organizations
|
48
|
+
# accessible to the authenticated user.
|
49
|
+
#
|
50
|
+
# workspace - [Id] The workspace in which to get users.
|
51
|
+
# per_page - [Integer] the number of records to fetch per page.
|
52
|
+
# options - [Hash] the request I/O options.
|
53
|
+
def find_by_workspace(client, workspace: required("workspace"), per_page: 20, options: {})
|
54
|
+
params = { limit: per_page }.reject { |_,v| v.nil? || Array(v).empty? }
|
55
|
+
Collection.new(parse(client.get("/workspaces/#{workspace}/users", params: params, options: options)), type: self, client: client)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Returns the user records for all users in the specified workspace or
|
59
|
+
# organization.
|
60
|
+
#
|
61
|
+
# workspace - [Id] The workspace or organization to filter users on.
|
62
|
+
# per_page - [Integer] the number of records to fetch per page.
|
63
|
+
# options - [Hash] the request I/O options.
|
64
|
+
def find_all(client, workspace: nil, per_page: 20, options: {})
|
65
|
+
params = { workspace: workspace, limit: per_page }.reject { |_,v| v.nil? || Array(v).empty? }
|
66
|
+
Collection.new(parse(client.get("/users", params: params, options: options)), type: self, client: client)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
### WARNING: This file is auto-generated by the asana-api-meta repo. Do not
|
2
|
+
### edit it manually.
|
3
|
+
|
4
|
+
module Asana
|
5
|
+
module Resources
|
6
|
+
# A _workspace_ is the highest-level organizational unit in Asana. All projects
|
7
|
+
# and tasks have an associated workspace.
|
8
|
+
#
|
9
|
+
# An _organization_ is a special kind of workspace that represents a company.
|
10
|
+
# In an organization, you can group your projects into teams. You can read
|
11
|
+
# more about how organizations work on the Asana Guide.
|
12
|
+
# To tell if your workspace is an organization or not, check its
|
13
|
+
# `is_organization` property.
|
14
|
+
#
|
15
|
+
# Over time, we intend to migrate most workspaces into organizations and to
|
16
|
+
# release more organization-specific functionality. We may eventually deprecate
|
17
|
+
# using workspace-based APIs for organizations. Currently, and until after
|
18
|
+
# some reasonable grace period following any further announcements, you can
|
19
|
+
# still reference organizations in any `workspace` parameter.
|
20
|
+
class Workspace < Resource
|
21
|
+
|
22
|
+
|
23
|
+
attr_reader :id
|
24
|
+
|
25
|
+
attr_reader :name
|
26
|
+
|
27
|
+
attr_reader :is_organization
|
28
|
+
|
29
|
+
class << self
|
30
|
+
# Returns the plural name of the resource.
|
31
|
+
def plural_name
|
32
|
+
'workspaces'
|
33
|
+
end
|
34
|
+
|
35
|
+
# Returns the full workspace record for a single workspace.
|
36
|
+
#
|
37
|
+
# id - [Id] Globally unique identifier for the workspace or organization.
|
38
|
+
#
|
39
|
+
# options - [Hash] the request I/O options.
|
40
|
+
def find_by_id(client, id, options: {})
|
41
|
+
|
42
|
+
self.new(parse(client.get("/workspaces/#{id}", options: options)).first, client: client)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Returns the compact records for all workspaces visible to the authorized user.
|
46
|
+
#
|
47
|
+
# per_page - [Integer] the number of records to fetch per page.
|
48
|
+
# options - [Hash] the request I/O options.
|
49
|
+
def find_all(client, per_page: 20, options: {})
|
50
|
+
params = { limit: per_page }.reject { |_,v| v.nil? || Array(v).empty? }
|
51
|
+
Collection.new(parse(client.get("/workspaces", params: params, options: options)), type: self, client: client)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Update properties on a workspace. Returns the complete, updated workspace record.
|
56
|
+
#
|
57
|
+
# options - [Hash] the request I/O options.
|
58
|
+
# data - [Hash] the attributes to post.
|
59
|
+
def update(options: {}, **data)
|
60
|
+
|
61
|
+
refresh_with(parse(client.put("/workspaces/#{id}", body: data, options: options)).first)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Retrieves objects in the workspace based on an auto-completion/typeahead
|
65
|
+
# search algorithm. This feature is meant to provide results quickly, so do
|
66
|
+
# not rely on this API to provide extremely accurate search results. The
|
67
|
+
# result set is limited to a single page of results with a maximum size,
|
68
|
+
# so you won't be able to fetch large numbers of results.
|
69
|
+
#
|
70
|
+
# type - [Enum] The type of values the typeahead should return.
|
71
|
+
# Note that unlike in the names of endpoints, the types listed here are
|
72
|
+
# in singular form (e.g. `task`). Using multiple types is not yet supported.
|
73
|
+
#
|
74
|
+
# query - [String] The string that will be used to search for relevant objects. If an
|
75
|
+
# empty string is passed in, the API will currently return an empty
|
76
|
+
# result set.
|
77
|
+
#
|
78
|
+
# count - [Number] The number of results to return. The default is `20` if this
|
79
|
+
# parameter is omitted, with a minimum of `1` and a maximum of `100`.
|
80
|
+
# If there are fewer results found than requested, all will be returned.
|
81
|
+
#
|
82
|
+
# per_page - [Integer] the number of records to fetch per page.
|
83
|
+
# options - [Hash] the request I/O options.
|
84
|
+
def typeahead(type: required("type"), query: nil, count: nil, per_page: 20, options: {})
|
85
|
+
params = { type: type, query: query, count: count, limit: per_page }.reject { |_,v| v.nil? || Array(v).empty? }
|
86
|
+
Collection.new(parse(client.get("/workspaces/#{id}/typeahead", params: params, options: options)), type: Resource, client: client)
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,225 @@
|
|
1
|
+
<%
|
2
|
+
var singularName = resource.name,
|
3
|
+
pluralName = plural(singularName),
|
4
|
+
mixins = {
|
5
|
+
task: ["AttachmentUploading", "EventSubscription"],
|
6
|
+
project: ["EventSubscription"]
|
7
|
+
},
|
8
|
+
skip = { attachment: ["createOnTask"] },
|
9
|
+
formatComment = function formatComment(text, indentation) {
|
10
|
+
var indent = Array(indentation + 1).join(" ")
|
11
|
+
return text.trim().split("\n").map(function(line) {
|
12
|
+
return indent + (line.length > 0 ? "# " : "#") + line
|
13
|
+
}).join("\n")
|
14
|
+
}
|
15
|
+
|
16
|
+
|
17
|
+
function Action(action) {
|
18
|
+
var that = this
|
19
|
+
this.action = action
|
20
|
+
this.collection = action.collection == true
|
21
|
+
this.requiresData = action.method == "POST" || action.method == "PUT"
|
22
|
+
this.isInstanceAction = (action.method == "PUT" || action.method == "DELETE")
|
23
|
+
this.method = action.method
|
24
|
+
this.methodName = snake(action.name)
|
25
|
+
this.clientMethod = action.method.toLowerCase()
|
26
|
+
this.returnsUpdatedRecord = action.method == 'PUT' || action.comment.match(/Returns[a-z\W]+updated/) !== null
|
27
|
+
this.returnsNothing = action.comment.match(/Returns an empty/) !== null
|
28
|
+
|
29
|
+
// Params and idParams
|
30
|
+
var params = action.params || []
|
31
|
+
this.idParams = _.filter(params, function(p) { return p.type == "Id" })
|
32
|
+
|
33
|
+
// If it looks like an instance action but it's not, make it one
|
34
|
+
if (!this.isInstanceAction) {
|
35
|
+
var mainIdParam = _.find(this.idParams, function(p) { return p.name == singularName })
|
36
|
+
if (mainIdParam !== undefined && !action.name.match(/Id/)) {
|
37
|
+
this.isInstanceAction = true
|
38
|
+
this.mainIdParam = mainIdParam
|
39
|
+
}
|
40
|
+
}
|
41
|
+
|
42
|
+
if (this.idParams.length == 1 &&
|
43
|
+
action.path.match(/%d/) &&
|
44
|
+
(action.name.match(/Id/) || (this.isInstanceAction && this.mainIdParam == undefined))) {
|
45
|
+
var mainIdParam = this.idParams[0]
|
46
|
+
this.mainIdParam = mainIdParam
|
47
|
+
this.inferredReturnType = this.isInstanceAction ? 'self.class' : 'self'
|
48
|
+
}
|
49
|
+
|
50
|
+
if (mainIdParam !== undefined) {
|
51
|
+
this.params = _.reject(params, function(p) { return p.name == mainIdParam.name })
|
52
|
+
} else {
|
53
|
+
this.params = params
|
54
|
+
}
|
55
|
+
|
56
|
+
if (!this.inferredReturnType) {
|
57
|
+
// Infer return type
|
58
|
+
var name = action.path.match(/\/([a-zA-Z]+)$/)
|
59
|
+
if (name !== null) {
|
60
|
+
name = name[1]
|
61
|
+
|
62
|
+
// Desugarize 'addProject' to 'project'
|
63
|
+
var camelCaseTail = name.match(/.*([A-Z][a-z]+)$/)
|
64
|
+
if (camelCaseTail !== null) { name = decap(camelCaseTail[1]) }
|
65
|
+
|
66
|
+
name = single(name)
|
67
|
+
|
68
|
+
var explicit = _.find(resources, function(p) { return p == name })
|
69
|
+
|
70
|
+
if (name == singularName || name == 'parent' || name == 'children' || name.match(/^sub/) !== null) {
|
71
|
+
this.inferredReturnType = this.isInstanceAction ? 'self.class' : 'self'
|
72
|
+
} else if (explicit !== undefined) {
|
73
|
+
this.inferredReturnType = cap(explicit)
|
74
|
+
} else {
|
75
|
+
this.inferredReturnType = 'Resource'
|
76
|
+
}
|
77
|
+
} else {
|
78
|
+
this.inferredReturnType = 'Resource'
|
79
|
+
}
|
80
|
+
}
|
81
|
+
|
82
|
+
// Endpoint path
|
83
|
+
this.path = _.reduce(this.idParams, function(acc, id) {
|
84
|
+
var localName = that.mainIdParam == id ? "id" : id.name
|
85
|
+
return acc.replace("\%d", "#{" + localName + "}")
|
86
|
+
}, action.path)
|
87
|
+
|
88
|
+
// Extra params (not in the URL) to be passed in the body of the call
|
89
|
+
this.extraParams = _.reject(this.params, function(p) {
|
90
|
+
return that.path.match(new RegExp("#{" + p.name + "}"))
|
91
|
+
})
|
92
|
+
|
93
|
+
// Params processing
|
94
|
+
var paramsLocal = "data"
|
95
|
+
if (this.collection) { this.extraParams.push({ name: "per_page", apiParamName: "limit" }) }
|
96
|
+
if (this.extraParams.length > 0) {
|
97
|
+
var paramNames = _.map(this.extraParams, function(p) { return (p.apiParamName || p.name) + ": " + p.name })
|
98
|
+
if (this.requiresData) {
|
99
|
+
var paramsProcessing = "with_params = data.merge(" + paramNames.join(", ") + ")"
|
100
|
+
paramsLocal = "with_params"
|
101
|
+
} else {
|
102
|
+
var paramsProcessing = "params = { " + paramNames.join(", ") + " }"
|
103
|
+
paramsLocal = "params"
|
104
|
+
}
|
105
|
+
paramsProcessing += ".reject { |_,v| v.nil? || Array(v).empty? }"
|
106
|
+
}
|
107
|
+
|
108
|
+
this.paramsProcessing = paramsProcessing
|
109
|
+
this.paramsLocal = paramsLocal
|
110
|
+
|
111
|
+
// Method argument names
|
112
|
+
var argumentNames = Array()
|
113
|
+
if (!this.isInstanceAction) { argumentNames.push("client") }
|
114
|
+
if (this.mainIdParam !== undefined && !this.isInstanceAction) { argumentNames.push("id") }
|
115
|
+
_.forEach(this.params, function(param) {
|
116
|
+
argumentNames.push(param.name + ":" + (param.required ? " required(\"" + param.name + "\")" : " nil"))
|
117
|
+
})
|
118
|
+
if (this.collection) { argumentNames.push("per_page: 20") }
|
119
|
+
if (this.method != 'DELETE') { argumentNames.push("options: {}") }
|
120
|
+
if (this.requiresData) { argumentNames.push("**data") }
|
121
|
+
this.argumentNames = argumentNames
|
122
|
+
|
123
|
+
// API request params
|
124
|
+
var requestParams = Array()
|
125
|
+
requestParams.push('"' + this.path + '"')
|
126
|
+
if (this.paramsProcessing || this.argumentNames.indexOf("**data") != -1) {
|
127
|
+
var argument = this.requiresData ? "body" : "params"
|
128
|
+
requestParams.push(argument + ": " + paramsLocal)
|
129
|
+
}
|
130
|
+
if (this.method != 'DELETE') { requestParams.push("options: options") }
|
131
|
+
this.requestParams = requestParams
|
132
|
+
this.documentation = this.renderDocumentation()
|
133
|
+
|
134
|
+
// Constructor
|
135
|
+
this.constructor = function(body) {
|
136
|
+
var pre = '', post = ''
|
137
|
+
var wrapWithParsing = function(body) {
|
138
|
+
var pre = '', post = ''
|
139
|
+
if (!that.returnsNothing) {
|
140
|
+
pre = 'parse('
|
141
|
+
post = ')' + (that.collection ? '' : '.first')
|
142
|
+
}
|
143
|
+
return pre + body + post
|
144
|
+
}
|
145
|
+
|
146
|
+
if (!that.returnsNothing) {
|
147
|
+
if (that.isInstanceAction && that.returnsUpdatedRecord) {
|
148
|
+
pre = "refresh_with("
|
149
|
+
post = ')'
|
150
|
+
} else {
|
151
|
+
pre = that.collection ? "Collection.new(" : that.inferredReturnType + ".new("
|
152
|
+
post = (that.collection ? ', type: ' + that.inferredReturnType : '') + ', client: client)'
|
153
|
+
}
|
154
|
+
} else { post = ' && true' }
|
155
|
+
return pre + wrapWithParsing(body) + post
|
156
|
+
}
|
157
|
+
|
158
|
+
this.request = this.constructor("client." + this.clientMethod + "(" + this.requestParams.join(", ") + ")")
|
159
|
+
}
|
160
|
+
|
161
|
+
Action.prototype.renderDocumentation = function () {
|
162
|
+
var formatParamNotes = function(params) {
|
163
|
+
var trimmed = _.flatten(_.map(params, function(p) {
|
164
|
+
return _.map(p.notes, function(note) { return note.trim() })
|
165
|
+
}))
|
166
|
+
return (trimmed.length > 0 ? "\nNotes:\n\n" + trimmed.join("\n\n") : "")
|
167
|
+
}
|
168
|
+
|
169
|
+
var formatParam = function(p, name) {
|
170
|
+
return (name !== undefined ? name : p.name) + " - [" + p.type + "] " + p.comment
|
171
|
+
}
|
172
|
+
var lines = _.map(this.params, function(p) { return formatParam(p) })
|
173
|
+
if (this.mainIdParam !== undefined && !this.isInstanceAction) { lines.unshift(formatParam(this.mainIdParam, "id")) }
|
174
|
+
if (this.collection) { lines.push("per_page - [Integer] the number of records to fetch per page.") }
|
175
|
+
if (this.method != 'DELETE') { lines.push("options - [Hash] the request I/O options.") }
|
176
|
+
if (this.requiresData) { lines.push("data - [Hash] the attributes to post.") }
|
177
|
+
return this.action.comment + "\n" + lines.join("\n") + formatParamNotes(this.params)
|
178
|
+
}
|
179
|
+
|
180
|
+
var actionsToSkip = skip[resource.name] || []
|
181
|
+
var actionsToGen = _.reject(resource.actions, function(action) {
|
182
|
+
return actionsToSkip.indexOf(action.name) != -1
|
183
|
+
})
|
184
|
+
|
185
|
+
var allActions = _.map(actionsToGen, function(action) { return new Action(action) }),
|
186
|
+
instanceActions = _.filter(allActions, function(action) { return action.isInstanceAction }),
|
187
|
+
classActions = _.reject(allActions, function(action) { return action.isInstanceAction })
|
188
|
+
|
189
|
+
var mixinsToInclude = mixins[resource.name] || []
|
190
|
+
|
191
|
+
%>### WARNING: This file is auto-generated by the asana-api-meta repo. Do not
|
192
|
+
### edit it manually.
|
193
|
+
|
194
|
+
module Asana
|
195
|
+
module Resources
|
196
|
+
<%= formatComment(resource.comment, 4) %>
|
197
|
+
class <%= cap(singularName) %> < Resource
|
198
|
+
<% _.forEach(mixinsToInclude, function(mixin) { %>
|
199
|
+
include <%= mixin %>
|
200
|
+
<% }) %>
|
201
|
+
<% _.forEach(resource.properties, function(property) { %>
|
202
|
+
attr_reader :<%= property.name %>
|
203
|
+
<% }) %>
|
204
|
+
class << self
|
205
|
+
# Returns the plural name of the resource.
|
206
|
+
def plural_name
|
207
|
+
'<%= pluralName %>'
|
208
|
+
end
|
209
|
+
<% _.forEach(classActions, function(action) { %>
|
210
|
+
<%= formatComment(action.documentation, 8) %>
|
211
|
+
def <%= action.methodName %>(<%= action.argumentNames.join(", ") %>)
|
212
|
+
<% if (action.paramsProcessing) { %> <%= action.paramsProcessing %><% } %>
|
213
|
+
<%= action.request %>
|
214
|
+
end
|
215
|
+
<% }) %> end
|
216
|
+
<% _.forEach(instanceActions, function(action) { %>
|
217
|
+
<%= formatComment(action.documentation, 6) %>
|
218
|
+
def <%= action.methodName %>(<%= action.argumentNames.join(", ") %>)
|
219
|
+
<% if (action.paramsProcessing) { %> <%= action.paramsProcessing %><% } %>
|
220
|
+
<%= action.request %>
|
221
|
+
end
|
222
|
+
<% }) %>
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
data/openc-asana.gemspec
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'asana/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "openc-asana"
|
8
|
+
spec.version = Asana::VERSION
|
9
|
+
spec.authors = ["Txus"]
|
10
|
+
spec.email = ["me@txus.io"]
|
11
|
+
|
12
|
+
spec.summary = %q{Fork of Official Ruby client for the Asana API}
|
13
|
+
spec.description = %q{Fork of Official Ruby client for the Asana API}
|
14
|
+
spec.homepage = "https://github.com/openc/ruby-asana"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
+
spec.bindir = "exe"
|
19
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
spec.required_ruby_version = '>= 2.0'
|
23
|
+
|
24
|
+
spec.add_dependency "oauth2", "~> 1.0"
|
25
|
+
spec.add_dependency "faraday", "~> 0.9"
|
26
|
+
spec.add_dependency "faraday_middleware", "~> 0.9"
|
27
|
+
spec.add_dependency "faraday_middleware-multi_json", "~> 0.0"
|
28
|
+
|
29
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
30
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
31
|
+
spec.add_development_dependency "rspec", "~> 3.2"
|
32
|
+
end
|