mingle4r 0.4.5 → 0.4.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +5 -0
- data/README.rdoc +312 -0
- data/TODO.txt +16 -6
- data/VERSION +1 -0
- data/lib/mingle4r/api/project.rb +24 -39
- data/lib/mingle4r/mingle_client.rb +22 -31
- metadata +7 -7
- data/README +0 -310
- data/lib/mingle4r/version.rb +0 -11
data/History.txt
CHANGED
data/README.rdoc
ADDED
@@ -0,0 +1,312 @@
|
|
1
|
+
== mingle4r
|
2
|
+
|
3
|
+
http://github.com/arusarka/mingle4r/tree/master
|
4
|
+
|
5
|
+
== Description:
|
6
|
+
|
7
|
+
This gem is a wrapper around active resource to access the rest api exposed by mingle
|
8
|
+
(http://studios.thoughtworks.com/mingle-agile-project-management).It provides a easy
|
9
|
+
way to communicate with mingle. For the library to work you need to enable basic authentication
|
10
|
+
(not enabled by default) in Mingle. See below to enable basic authentication in Mingle.
|
11
|
+
The typical use-case for this gem is to help someone getting started with writing code
|
12
|
+
to integrate with Mingle.
|
13
|
+
|
14
|
+
However if you are planning to connect and work with mingle from the terminal, then there
|
15
|
+
is another gem mingle-mingle which you should look at. This library provides a very easy
|
16
|
+
api to write code to work with mingle (see the examples below) but thats it.
|
17
|
+
|
18
|
+
=== Enable basic authentication in Mingle
|
19
|
+
|
20
|
+
1. Go to Mingle DataDir
|
21
|
+
2. Open YAML file <Mingle DataDir>/config/auth_config.yml
|
22
|
+
3. Set 'basic_authentication_enabled' to 'true' (without the quotes) if it is not so
|
23
|
+
|
24
|
+
== Features/Problems:
|
25
|
+
|
26
|
+
It gives you access to projects in the mingle instance, cards under the project and also
|
27
|
+
attachments for a particular card.
|
28
|
+
|
29
|
+
== Synopsis:
|
30
|
+
|
31
|
+
This library is a wrapper around active resource to interact with Mingle easily. So before
|
32
|
+
using this gem a good idea would be to get familiar with active resource and the mingle apis.
|
33
|
+
If you have a mingle server running somewhere you can check the different apis at <server address>/help/mingle_api.html or goto http://www.thoughtworks-studios.com/mingle/3.0/help/mingle_api.html
|
34
|
+
|
35
|
+
A lot of examples are given below to get you started.
|
36
|
+
|
37
|
+
The api now supports only mingle 3. Mingle 2 is no longer supported. If you need to connect
|
38
|
+
to both Mingle 2 and Mingle 3 then try 0.3.0 of the gem.
|
39
|
+
|
40
|
+
In all the documentation below you can replace Mingle4r::MingleClient with MingleClient.
|
41
|
+
Its an alias for easy use.
|
42
|
+
|
43
|
+
=== Getting all the projects for a particular instance
|
44
|
+
|
45
|
+
Suppose you want to connect to the mingle instance hosted at http://localhost:8080 where the
|
46
|
+
username is 'testuser' and password is 'password'.
|
47
|
+
|
48
|
+
m_c = Mingle4r::MingleClient.new('http://localhost:8080', 'testuser', 'password')
|
49
|
+
projs = m_c.projects => array of active resource objects
|
50
|
+
|
51
|
+
=== Getting a particular project
|
52
|
+
|
53
|
+
Before you access a particular project you need to set the project id for the mingle client
|
54
|
+
object. You can do that in two ways. Supposing you are trying to access a project with an
|
55
|
+
identifier of 'great_mingle_project'
|
56
|
+
|
57
|
+
WARNING : project identifier and project name are different. If you named your project as
|
58
|
+
'Great Mingle Project' it's identifier is by default 'great_mingle_project'. To be sure what
|
59
|
+
the identifier of a project is you should look at the url in mingle in the particular project
|
60
|
+
you are trying to access. It should be something like 'http://localhost:8080/projects/great_mingle_project'
|
61
|
+
|
62
|
+
1. Set at initialize time
|
63
|
+
m_c = Mingle4r::MingleClient.new('http://localhost:8080', 'testuser', 'password',
|
64
|
+
'great_mingle_project')
|
65
|
+
m_c.project => active resource object
|
66
|
+
|
67
|
+
2. Set an attribute later
|
68
|
+
m_c = Mingle4r::MingleClient.new('http://localhost:8080', 'testuser', 'password')
|
69
|
+
m_c.proj_id = 'great_mingle_project'
|
70
|
+
project = m_c.project
|
71
|
+
|
72
|
+
=== Validate credentials
|
73
|
+
|
74
|
+
m_c.valid_credentials? => returns true or false
|
75
|
+
|
76
|
+
=== Getting cards for a particular project
|
77
|
+
|
78
|
+
Get a mingle client object. Then call the cards method.
|
79
|
+
|
80
|
+
m_c = Mingle4r::MingleClient.new('http://localhost:8080', 'testuser', 'password')
|
81
|
+
m_c.proj_id = 'great_mingle_project'
|
82
|
+
m_c.cards => array of activeresource objects
|
83
|
+
|
84
|
+
Alternatively you can also do
|
85
|
+
m_c.project.cards => array of activeresource objects
|
86
|
+
|
87
|
+
=== Getting a singe card
|
88
|
+
|
89
|
+
m_c.find_card(42) => card activeresource object
|
90
|
+
|
91
|
+
Alternatively you can also do
|
92
|
+
m_c.project.find_card(42)
|
93
|
+
|
94
|
+
=== Filtering cards
|
95
|
+
|
96
|
+
Mingle allows a lighweight implementation of sql called mql through which you can filter
|
97
|
+
cards. Look at http://www.thoughtworks-studios.com/mingle/3.0/help/mql_reference.html for
|
98
|
+
reference. However when using this feature you should only give the condition not the
|
99
|
+
properties you want out of mingle.
|
100
|
+
|
101
|
+
m_c.filter_cards('Type IS Story') => returns a list card objects
|
102
|
+
|
103
|
+
Do not do this (it simply *won't work*) :
|
104
|
+
m_c.filter_cards('SELECT number, type WHERE Type IS Story')
|
105
|
+
|
106
|
+
If you want to execute a generic mql look at the 'MQL Execution' section
|
107
|
+
|
108
|
+
=== Getting custom properties for a card
|
109
|
+
|
110
|
+
m_c = Mingle4r::MingleClient.new('http://localhost:8080', 'testuser', 'password')
|
111
|
+
m_c.proj_id = 'great_mingle_project'
|
112
|
+
card = m_c.cards.first
|
113
|
+
card.custom_properties => returns an array of hashes, {property name => property value}
|
114
|
+
|
115
|
+
However this gives only custom properties, not all the properties.
|
116
|
+
|
117
|
+
=== Getting a particular property
|
118
|
+
|
119
|
+
gets the value of a property. The property name given should be the same as seen in Mingle.
|
120
|
+
Type, name, description and number of a card can be accessed directly. For any other custom
|
121
|
+
property use the method below.
|
122
|
+
|
123
|
+
m_c = Mingle4r::MingleClient.new('http://localhost:8080', 'testuser', 'password')
|
124
|
+
m_c.proj_id = 'great_mingle_project'
|
125
|
+
card = m_c.cards.first
|
126
|
+
card.property_value('Status')
|
127
|
+
|
128
|
+
=== Setting a particular property
|
129
|
+
|
130
|
+
sets the value of the property. The property name given should be the same as in Mingle.
|
131
|
+
Type, name and description should be set directly when creating or updating a card.
|
132
|
+
In case of a custom property use the following method. The value given should be one of
|
133
|
+
the values that Mingle accepts in case of a managed list
|
134
|
+
|
135
|
+
m_c = Mingle4r::MingleClient.new('http://localhost:8080', 'testuser', 'password')
|
136
|
+
m_c.proj_id = 'great_mingle_project'
|
137
|
+
defect_card = m_c.find_cards('Type IS Defect').first
|
138
|
+
defect_card.property_value('Status', 'Closed')
|
139
|
+
defect_card.save
|
140
|
+
|
141
|
+
In case of properties of type 'Tree Relatioship property' or 'Card'(properties which link
|
142
|
+
to another card) you can should set the property by giving the number of the card. For e.g.
|
143
|
+
|
144
|
+
story_card = m_c.projects.cards.find {|c| c.type == 'Story'}.first
|
145
|
+
story_card.property_value('Feature', 12)
|
146
|
+
story_card.save
|
147
|
+
|
148
|
+
In case of properties of type 'Team member' you can either use the user id (not the name or
|
149
|
+
the login id, you would have to look at the xml to get the id) or more simply the user name.
|
150
|
+
For e.g.
|
151
|
+
|
152
|
+
story_card.property_value('Assignee', 'James Bond')
|
153
|
+
story_card.save
|
154
|
+
|
155
|
+
=== Creating a card
|
156
|
+
|
157
|
+
MingleClient provides a handy method to create a new card.
|
158
|
+
|
159
|
+
task = m_c.new_card
|
160
|
+
task.name = 'set up Cruise build'
|
161
|
+
task.type = 'task'
|
162
|
+
task.description = 'a basic cruise build needs to be set up so that we can start working'
|
163
|
+
task.save
|
164
|
+
|
165
|
+
Alternatively you can also do:
|
166
|
+
Mingle4r::API::Card.site = 'http://localhost:8080/projects/agile/'
|
167
|
+
Mingle4r::API::Card.user = 'foo'
|
168
|
+
Mingle4r::API::Card.password = 'bar'
|
169
|
+
|
170
|
+
task = Mingle4r::API::Card.new , rest of the steps are same as above
|
171
|
+
|
172
|
+
Do not do it like this:
|
173
|
+
|
174
|
+
task = m_c.new_card :name => 'set up Cruise build', :type => 'task',
|
175
|
+
:description => 'a basic cruise build needs to be set up so that we can start working'
|
176
|
+
task.save => It simply won't work, there is a workaround but rather use as described above.
|
177
|
+
|
178
|
+
=== Getting a particular version of a card
|
179
|
+
|
180
|
+
Mingle maintains the different versions of a card. It always shows the latest version
|
181
|
+
by default. However if you want to access a different version you can do so in the
|
182
|
+
following ways.
|
183
|
+
|
184
|
+
m_c = Mingle4r::MingleClient.new('http://localhost:8080', 'testuser', 'password')
|
185
|
+
m_c.proj_id = 'great_mingle_project'
|
186
|
+
defect_card = m_c.find_card(20)
|
187
|
+
|
188
|
+
supposing the latest version of the card is 42
|
189
|
+
|
190
|
+
1. Get the previous version
|
191
|
+
defect_card.version(:previous) # return version 41
|
192
|
+
|
193
|
+
2. Get the next version
|
194
|
+
defect_card.version(:next) # returns version 42 since it is the latest version
|
195
|
+
|
196
|
+
3. Get an arbitrary version
|
197
|
+
defect_card.version(21) # returns version 21
|
198
|
+
|
199
|
+
=== Getting all comments for a card
|
200
|
+
|
201
|
+
m_c = Mingle4r::MingleClient.new('http://localhost:8080', 'testuser', 'password')
|
202
|
+
m_c.proj_id = 'great_mingle_project'
|
203
|
+
defect_card = m_c.find_cards('Type IS Defect').first
|
204
|
+
defect_cards.comments
|
205
|
+
|
206
|
+
=== Adding comment to a particular card
|
207
|
+
|
208
|
+
m_c = Mingle4r::MingleClient.new('http://localhost:8080', 'testuser', 'password')
|
209
|
+
m_c.proj_id = 'great_mingle_project'
|
210
|
+
defect_card = m_c.find_card(420)
|
211
|
+
defect_card.add_comment('Not able to reproduce')
|
212
|
+
|
213
|
+
=== Attachments
|
214
|
+
|
215
|
+
m_c = Mingle4r::MingleClient.new('http://localhost:8080', 'testuser', 'password')
|
216
|
+
m_c.proj_id = 'great_mingle_project'
|
217
|
+
defect_card = m_c.find_cards('Type IS Defect').first
|
218
|
+
defect_card.attachments
|
219
|
+
|
220
|
+
1. Downloading a particular attachment
|
221
|
+
attachment = defect_card.attachments.first
|
222
|
+
attachment.download('page.css')
|
223
|
+
|
224
|
+
2. Uploading an attachment
|
225
|
+
defect_card.upload_attachment('page-screenshot.jpg')
|
226
|
+
|
227
|
+
=== Murmurs
|
228
|
+
|
229
|
+
1. Get the murmurs for a project
|
230
|
+
m_c = Mingle4r::MingleClient.new('http://localhost:8080', 'testuser', 'password')
|
231
|
+
m_c.proj_id = 'great_mingle_project'
|
232
|
+
project = m_c.project
|
233
|
+
project.murmurs
|
234
|
+
|
235
|
+
2. Get the murmurs associated with a card
|
236
|
+
card = m_c.cards.first
|
237
|
+
card.murmurs
|
238
|
+
|
239
|
+
3. post a murmur(hooray!)
|
240
|
+
project.post_murmur('my first murmur, I am excited!')
|
241
|
+
|
242
|
+
=== Get all transitions for a card
|
243
|
+
|
244
|
+
m_c = Mingle4r::MingleClient.new('http://localhost:8080', 'testuser', 'password')
|
245
|
+
m_c.proj_id = 'great_mingle_project'
|
246
|
+
defect_card = m_c.cards.first
|
247
|
+
|
248
|
+
defect_card.transitions # array of active resource objects
|
249
|
+
|
250
|
+
=== Execute a transition on a card
|
251
|
+
|
252
|
+
m_c = Mingle4r::MingleClient.new('http://localhost:8080', 'testuser', 'password')
|
253
|
+
m_c.proj_id = 'great_mingle_project'
|
254
|
+
defect_card = m_c.find_cards('Type IS Defect').first
|
255
|
+
|
256
|
+
defect_card.execute_transition(
|
257
|
+
'comment' => comment for the transition, required only if the transition requires a comment
|
258
|
+
'Property Name as in Mingle exactly' => 'Property value to set for the property', required only
|
259
|
+
if the transition requires to be set manually, multiple properties might need to be set.
|
260
|
+
)
|
261
|
+
|
262
|
+
=== MQL execution
|
263
|
+
|
264
|
+
mingle allows you to write an arbitrary MQL query and returns the results. This gem
|
265
|
+
allows you to do that in a simpler way. If you want to know more about MQL go to http://www.thoughtworks-studios.com/mingle/3.0/help/mql_reference.html.
|
266
|
+
|
267
|
+
m_c = Mingle4r::MingleClient.new('http://localhost:8080', 'testuser', 'password')
|
268
|
+
m_c.proj_id = 'great_mingle_project'
|
269
|
+
m_c.project.execute_mql('SELECT name, "Added in Iteration" WHERE Type = Story')
|
270
|
+
=> returns an array of hash
|
271
|
+
|
272
|
+
== Requirements:
|
273
|
+
|
274
|
+
1) active_resource gem, it would be automatically taken care of
|
275
|
+
during gem install.
|
276
|
+
|
277
|
+
== Limitations:
|
278
|
+
|
279
|
+
updating a property on the card which is a link to another card does not work. So for now
|
280
|
+
only use it for other properties
|
281
|
+
|
282
|
+
== Install:
|
283
|
+
|
284
|
+
since github no longer archives gems, I am hosting the gem at gemcutter. So you would need to
|
285
|
+
add http://gemcutter.org to your gem sources : gem sources -a 'http://gemcutter.org'. Then do
|
286
|
+
|
287
|
+
gem install mingle4r
|
288
|
+
|
289
|
+
== License:
|
290
|
+
|
291
|
+
(The MIT License)
|
292
|
+
|
293
|
+
Copyright (c) 2010 Arusarka Haldar
|
294
|
+
|
295
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
296
|
+
a copy of this software and associated documentation files (the
|
297
|
+
'Software'), to deal in the Software without restriction, including
|
298
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
299
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
300
|
+
permit persons to whom the Software is furnished to do so, subject to
|
301
|
+
the following conditions:
|
302
|
+
|
303
|
+
The above copyright notice and this permission notice shall be
|
304
|
+
included in all copies or substantial portions of the Software.
|
305
|
+
|
306
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
307
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
308
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
309
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
310
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
311
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
312
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/TODO.txt
CHANGED
@@ -1,21 +1,31 @@
|
|
1
1
|
will be fixed/implemented very soon
|
2
2
|
-----------------------------------
|
3
3
|
|
4
|
-
* write documentation about updating card properties of type 'Card', 'Tree Relationship property'
|
5
|
-
and 'Team member'
|
6
4
|
* complete manual QA to ensure/prioritize what needs to be done for card object
|
7
|
-
*
|
5
|
+
* fix global users and users associated with a project
|
8
6
|
|
9
7
|
will be implemented, but not very important for now
|
10
8
|
----------------------------------------------------
|
11
9
|
|
10
|
+
* make the gemspec spec to autodiscover new files in some directories
|
11
|
+
* use a http connection class
|
12
|
+
* test if attachment download works with https
|
13
|
+
* get rid of active resource
|
12
14
|
* update documentation - write about executing transitions directly on the transition
|
13
|
-
* write tests for project class
|
14
15
|
* implement card_types for a project
|
15
|
-
*
|
16
|
+
* investigate setting custom properties at card creation time
|
17
|
+
* provide a block to set up a new card in MingleClient::new_card
|
16
18
|
|
17
19
|
will be done when I've no other work
|
18
20
|
------------------------------------
|
19
21
|
|
20
22
|
* clarify in docs difference between custom properties and native properties
|
21
|
-
* should transtions give the list of properties to be changed directly
|
23
|
+
* should transtions give the list of properties to be changed directly
|
24
|
+
|
25
|
+
What should be done regarding
|
26
|
+
-----------------------------
|
27
|
+
|
28
|
+
* performance fixes - should MingleClient::cards return all cards?
|
29
|
+
* what is the difference between mingle client and project object? mingle client seems to be delegating a
|
30
|
+
lot of methods to project
|
31
|
+
* should MingleClient::projects method reuse the class of @project?
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.4.6
|
data/lib/mingle4r/api/project.rb
CHANGED
@@ -4,47 +4,64 @@ module Mingle4r
|
|
4
4
|
module InstanceMethods
|
5
5
|
# returns the cards for the project.
|
6
6
|
def cards
|
7
|
-
set_attributes_for(Card)
|
7
|
+
set_attributes_for(Card)
|
8
8
|
Card.find_without_pagination(:all)
|
9
9
|
end
|
10
10
|
|
11
11
|
# returns the users for the project.
|
12
12
|
def users
|
13
|
-
set_attributes_for(User)
|
13
|
+
set_attributes_for(User)
|
14
14
|
User.find(:all)
|
15
15
|
end
|
16
16
|
|
17
17
|
# returns the wikis for the project.
|
18
18
|
def wikis
|
19
|
-
set_attributes_for(Wiki)
|
19
|
+
set_attributes_for(Wiki)
|
20
20
|
Wiki.find(:all)
|
21
21
|
end
|
22
22
|
|
23
23
|
# returns the property definitions for the project.
|
24
24
|
def property_definitions
|
25
|
-
set_attributes_for(PropertyDefinition)
|
25
|
+
set_attributes_for(PropertyDefinition)
|
26
26
|
PropertyDefinition.find(:all)
|
27
27
|
end
|
28
28
|
|
29
29
|
# returns the murmurs for the project.
|
30
30
|
def murmurs
|
31
|
-
set_attributes_for(Murmur)
|
31
|
+
set_attributes_for(Murmur)
|
32
32
|
Murmur.find(:all)
|
33
33
|
end
|
34
34
|
|
35
35
|
# posts a murmur
|
36
36
|
def post_murmur(str)
|
37
|
-
set_attributes_for(Murmur)
|
37
|
+
set_attributes_for(Murmur)
|
38
38
|
murmur = Murmur.new(:body => str.to_s)
|
39
39
|
murmur.save
|
40
40
|
end
|
41
41
|
|
42
42
|
# executes an mql
|
43
43
|
def execute_mql(query)
|
44
|
-
set_attributes_for(ExecuteMql)
|
44
|
+
set_attributes_for(ExecuteMql)
|
45
45
|
ExecuteMql.query(query)
|
46
46
|
end
|
47
47
|
|
48
|
+
#finds a single card
|
49
|
+
def find_card(number)
|
50
|
+
set_attributes_for(Card)
|
51
|
+
Card.find(number)
|
52
|
+
end
|
53
|
+
|
54
|
+
#returns a filtered list of cards
|
55
|
+
def filter_cards(filter_str)
|
56
|
+
set_attributes_for(Card)
|
57
|
+
Card.apply_filter(filter_str)
|
58
|
+
end
|
59
|
+
|
60
|
+
def new_card
|
61
|
+
set_attributes_for(Card)
|
62
|
+
Card.new
|
63
|
+
end
|
64
|
+
|
48
65
|
private
|
49
66
|
def set_attributes_for(klass)
|
50
67
|
resource_site = File.join(self.class.site.to_s, "projects/#{self.identifier}")
|
@@ -52,40 +69,8 @@ module Mingle4r
|
|
52
69
|
klass.site = resource_site
|
53
70
|
klass.user = self.class.user
|
54
71
|
klass.password = self.class.password
|
55
|
-
setter_method = klass.name.demodulize.underscore + '_class_set'
|
56
|
-
send(setter_method, true)
|
57
72
|
klass
|
58
73
|
end
|
59
|
-
|
60
|
-
def user_class_set(val = nil)
|
61
|
-
return @user_class_set unless val
|
62
|
-
@user_class_set = val
|
63
|
-
end
|
64
|
-
|
65
|
-
def card_class_set(val = nil)
|
66
|
-
return @card_class_set unless val
|
67
|
-
@card_class_set = val
|
68
|
-
end
|
69
|
-
|
70
|
-
def wiki_class_set(val = nil)
|
71
|
-
return @wiki_class_set unless val
|
72
|
-
@wiki_class_set = val
|
73
|
-
end
|
74
|
-
|
75
|
-
def property_definition_class_set(val = nil)
|
76
|
-
return @property_definition_class_set unless val
|
77
|
-
@property_definition_class_set = val
|
78
|
-
end
|
79
|
-
|
80
|
-
def murmur_class_set(val = nil)
|
81
|
-
return @murmur_class_set unless val
|
82
|
-
@murmur_class_set = val
|
83
|
-
end
|
84
|
-
|
85
|
-
def execute_mql_class_set(val = nil)
|
86
|
-
return @execute_mql_class_set unless val
|
87
|
-
@execute_mql_class_set = val
|
88
|
-
end
|
89
74
|
end # module InstanceMethods
|
90
75
|
|
91
76
|
extend Mingle4r::CommonClassMethods
|
@@ -7,48 +7,38 @@ module Mingle4r
|
|
7
7
|
@user = user
|
8
8
|
@password = password
|
9
9
|
@proj_id = proj_id
|
10
|
-
|
10
|
+
setup_project_class
|
11
11
|
end
|
12
12
|
|
13
13
|
def site=(site)
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
set_resource_attributes()
|
20
|
-
end
|
14
|
+
@site = site
|
15
|
+
user, password = decode_uri(site)
|
16
|
+
@user = user if user
|
17
|
+
@password = password if password
|
18
|
+
setup_project_class
|
21
19
|
@site
|
22
20
|
end
|
23
21
|
|
24
22
|
def user=(user)
|
25
|
-
|
26
|
-
|
27
|
-
set_resource_attributes()
|
28
|
-
end
|
23
|
+
@user = user
|
24
|
+
setup_project_class
|
29
25
|
@user
|
30
26
|
end
|
31
27
|
|
32
28
|
def password=(password)
|
33
|
-
|
34
|
-
|
35
|
-
set_resource_attributes()
|
36
|
-
end
|
29
|
+
@password = password
|
30
|
+
setup_project_class
|
37
31
|
@password
|
38
32
|
end
|
39
33
|
|
40
34
|
def proj_id=(proj_id)
|
41
|
-
|
42
|
-
|
43
|
-
set_resource_attributes()
|
44
|
-
end
|
35
|
+
@proj_id = proj_id
|
36
|
+
setup_project_class
|
45
37
|
@proj_id
|
46
38
|
end
|
47
39
|
|
48
40
|
def valid_credentials?
|
49
|
-
|
50
|
-
API::Project.user = user
|
51
|
-
API::Project.password = password
|
41
|
+
setup_project_class
|
52
42
|
begin
|
53
43
|
API::Project.find(:all)
|
54
44
|
true
|
@@ -67,17 +57,13 @@ module Mingle4r
|
|
67
57
|
API::Project.find(:all)
|
68
58
|
end
|
69
59
|
|
70
|
-
def
|
71
|
-
|
60
|
+
def method_missing(meth_id, *args, &block)
|
61
|
+
project.send(meth_id, *args, &block)
|
72
62
|
end
|
73
63
|
|
74
64
|
private
|
75
|
-
def
|
76
|
-
|
77
|
-
set_attributes(API::User)
|
78
|
-
end
|
79
|
-
|
80
|
-
def set_attributes(klass)
|
65
|
+
def setup_project_class
|
66
|
+
klass = API::Project
|
81
67
|
klass.site = base_url
|
82
68
|
klass.user = @user
|
83
69
|
klass.password = @password
|
@@ -86,6 +72,11 @@ module Mingle4r
|
|
86
72
|
def base_url
|
87
73
|
File.join(@site.to_s, '/api/v2/')
|
88
74
|
end
|
75
|
+
|
76
|
+
def decode_uri(site)
|
77
|
+
uri = URI.parse(site)
|
78
|
+
[uri.user, uri.password]
|
79
|
+
end
|
89
80
|
end
|
90
81
|
end
|
91
82
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mingle4r
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 3
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 4
|
9
|
-
-
|
10
|
-
version: 0.4.
|
9
|
+
- 6
|
10
|
+
version: 0.4.6
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- asur
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-06-
|
18
|
+
date: 2010-06-27 00:00:00 +05:30
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -39,14 +39,13 @@ executables: []
|
|
39
39
|
extensions: []
|
40
40
|
|
41
41
|
extra_rdoc_files:
|
42
|
-
- README
|
42
|
+
- README.rdoc
|
43
43
|
files:
|
44
44
|
- lib/mingle4r.rb
|
45
45
|
- lib/mingle_resource.rb
|
46
46
|
- lib/mingle4r/common_class_methods.rb
|
47
47
|
- lib/mingle4r/helpers.rb
|
48
48
|
- lib/mingle4r/mingle_client.rb
|
49
|
-
- lib/mingle4r/version.rb
|
50
49
|
- lib/mingle4r/card_format.rb
|
51
50
|
- lib/mingle4r/api/card.rb
|
52
51
|
- lib/mingle4r/api/card/attachment.rb
|
@@ -60,7 +59,8 @@ files:
|
|
60
59
|
- lib/mingle4r/api/wiki.rb
|
61
60
|
- MIT-LICENSE
|
62
61
|
- History.txt
|
63
|
-
- README
|
62
|
+
- README.rdoc
|
63
|
+
- VERSION
|
64
64
|
- TODO.txt
|
65
65
|
has_rdoc: true
|
66
66
|
homepage: http://github.com/arusarka/mingle4r/
|
data/README
DELETED
@@ -1,310 +0,0 @@
|
|
1
|
-
== mingle4r
|
2
|
-
|
3
|
-
http://github.com/arusarka/mingle4r/tree/master
|
4
|
-
|
5
|
-
== DESCRIPTION:
|
6
|
-
|
7
|
-
This gem is a wrapper around active resource to access the rest api exposed by mingle
|
8
|
-
(http://studios.thoughtworks.com/mingle-agile-project-management).It provides a easy
|
9
|
-
way to communicate with mingle. For the library to work you need to enable basic authentication
|
10
|
-
(not enabled by default) in Mingle. See below to enable basic authentication in Mingle.
|
11
|
-
The typical use-case for this gem is to help someone getting started with writing code
|
12
|
-
to integrate with Mingle.
|
13
|
-
|
14
|
-
However if you are planning to connect and work with mingle from the terminal, then there
|
15
|
-
is another gem mingle-mingle which you should look at. This library provides a very easy
|
16
|
-
api to write code to work with mingle (see the examples below) but thats it.
|
17
|
-
|
18
|
-
Enable basic authentication in Mingle
|
19
|
-
-------------------------------------
|
20
|
-
|
21
|
-
1) Go to Mingle DataDir
|
22
|
-
|
23
|
-
2) Open YAML file <Mingle DataDir>/config/auth_config.yml
|
24
|
-
|
25
|
-
3) Set 'basic_authentication_enabled' to 'true' (without the quotes) if it is not so
|
26
|
-
|
27
|
-
== FEATURES/PROBLEMS:
|
28
|
-
|
29
|
-
It gives you access to projects in the mingle instance, cards under the project and also
|
30
|
-
attachments for a particular card.
|
31
|
-
|
32
|
-
== SYNOPSIS:
|
33
|
-
|
34
|
-
The api now supports only mingle 3. Mingle 2 is no longer supported. If you need to connect
|
35
|
-
to both Mingle 2 and Mingle 3 then try 0.3.0 of the gem. To see the api for mingle 3, check
|
36
|
-
the api documentation for the mingle instance(located at <mingle instance host>/help/index)
|
37
|
-
|
38
|
-
In all the documentation below you can replace Mingle4r::MingleClient with MingleClient.
|
39
|
-
Its an alias for easy use.
|
40
|
-
|
41
|
-
Getting all the projects for a particular instance
|
42
|
-
--------------------------------------------------
|
43
|
-
|
44
|
-
Suppose you want to connect to the mingle instance hosted at http://localhost:8080 where the
|
45
|
-
username is 'testuser' and password is 'password'.
|
46
|
-
|
47
|
-
m_c = Mingle4r::MingleClient.new('http://localhost:8080', 'testuser', 'password')
|
48
|
-
projs = m_c.projects
|
49
|
-
|
50
|
-
projs is an array of active resource objects
|
51
|
-
|
52
|
-
Getting a particular project
|
53
|
-
----------------------------
|
54
|
-
|
55
|
-
Before you access a particular project you need to set the project id for the mingle client
|
56
|
-
object. You can do that in two ways. Supposing you are trying to access a project with an
|
57
|
-
identifier of 'great_mingle_project'
|
58
|
-
|
59
|
-
WARNING : project identifier and project name are different. If you named your project as
|
60
|
-
'Great Mingle Project' it's identifier is by default 'great_mingle_project'. To be sure what
|
61
|
-
the identifier of a project is you should look at the url in mingle in the particular project
|
62
|
-
you are trying to access. It should be something like 'http://localhost:8080/projects/great_mingle_project'
|
63
|
-
|
64
|
-
1) Set at initialize time
|
65
|
-
|
66
|
-
m_c = Mingle4r::MingleClient.new('http://localhost:8080', 'testuser', 'password',
|
67
|
-
'great_mingle_project')
|
68
|
-
m_c.project
|
69
|
-
|
70
|
-
2) Set an attribute later
|
71
|
-
|
72
|
-
m_c = Mingle4r::MingleClient.new('http://localhost:8080', 'testuser', 'password')
|
73
|
-
m_c.proj_id = 'great_mingle_project'
|
74
|
-
project = m_c.project
|
75
|
-
|
76
|
-
project is a single activeresource object
|
77
|
-
|
78
|
-
Getting cards for a particular project
|
79
|
-
--------------------------------------
|
80
|
-
|
81
|
-
Get a mingle client object initialized as in SECTION B. Then call the cards method.
|
82
|
-
|
83
|
-
m_c = Mingle4r::MingleClient.new('http://localhost:8080', 'testuser', 'password')
|
84
|
-
m_c.proj_id = 'great_mingle_project'
|
85
|
-
m_c.project.cards
|
86
|
-
|
87
|
-
cards will be an array of activeresoure objects.
|
88
|
-
|
89
|
-
Getting custom properties for a card
|
90
|
-
------------------------------------
|
91
|
-
|
92
|
-
m_c = Mingle4r::MingleClient.new('http://localhost:8080', 'testuser', 'password')
|
93
|
-
m_c.proj_id = 'great_mingle_project'
|
94
|
-
card = m_c.project.cards[0]
|
95
|
-
card.custom_properties => returns an array of hashes, {property name => property value}
|
96
|
-
|
97
|
-
However this gives only custom properties, not all the properties.
|
98
|
-
|
99
|
-
Getting a particular property
|
100
|
-
-----------------------------
|
101
|
-
|
102
|
-
gets the value of a property. The property name given should be the same as seen in Mingle.
|
103
|
-
Type, name, description and number of a card can be accessed directly. For any other custom
|
104
|
-
property use the method below.
|
105
|
-
|
106
|
-
m_c = Mingle4r::MingleClient.new('http://localhost:8080', 'testuser', 'password')
|
107
|
-
m_c.proj_id = 'great_mingle_project'
|
108
|
-
card = m_c.project.cards[0]
|
109
|
-
card.property_value('Status')
|
110
|
-
|
111
|
-
Setting a particular property
|
112
|
-
-----------------------------
|
113
|
-
|
114
|
-
sets the value of the property. The property name given should be the same as in Mingle.
|
115
|
-
Type, name and description should be set directly when creating or updating a card.
|
116
|
-
In case of a custom property use the following method. The value given should be one of
|
117
|
-
the values that Mingle accepts in case of a managed list
|
118
|
-
|
119
|
-
m_c = Mingle4r::MingleClient.new('http://localhost:8080', 'testuser', 'password')
|
120
|
-
m_c.proj_id = 'great_mingle_project'
|
121
|
-
defect_card = m_c.project.cards.first
|
122
|
-
defect_card.property_value('Status', 'Closed')
|
123
|
-
defect_card.save
|
124
|
-
|
125
|
-
In case of properties of type 'Tree Relatioship property' or 'Card'(properties which link
|
126
|
-
to another card) you can should set the property by giving the number of the card. For e.g.
|
127
|
-
|
128
|
-
story_card = m_c.projects.cards.find {|c| c.type == 'Story'}.first
|
129
|
-
story_card.property_value('Feature', 12)
|
130
|
-
story_card.save
|
131
|
-
|
132
|
-
In case of properties of type 'Team member' you can either use the user id (not the name or
|
133
|
-
the login id, you would have to look at the xml to get the id) or more simply the user name.
|
134
|
-
For e.g.
|
135
|
-
|
136
|
-
story_card.property_value('Assignee', 'James Bond')
|
137
|
-
story_card.save
|
138
|
-
|
139
|
-
Creating a card
|
140
|
-
---------------
|
141
|
-
|
142
|
-
Mingle4r::API::Card is the ActiveResource class which handles interaction with cards.
|
143
|
-
task = Mingle4r::API::Card.new
|
144
|
-
task.name = 'set up Cruise build'
|
145
|
-
task.type = 'task'
|
146
|
-
task.description = 'a basic cruise build needs to be set up so that we can start working'
|
147
|
-
task.save
|
148
|
-
|
149
|
-
Do not do it like this:
|
150
|
-
|
151
|
-
task = Mingle4r::API::new :name => 'set up Cruise build', :type => 'task',
|
152
|
-
:description => 'a basic cruise build needs to be set up so that we can start working'
|
153
|
-
task.save => It simply won't work, there is a workaround but rather use as described above.
|
154
|
-
|
155
|
-
Adding comment to a particular card
|
156
|
-
-----------------------------------
|
157
|
-
|
158
|
-
m_c = Mingle4r::MingleClient.new('http://localhost:8080', 'testuser', 'password')
|
159
|
-
m_c.proj_id = 'great_mingle_project'
|
160
|
-
defect_card = m_c.project.cards[0]
|
161
|
-
defect_card.add_comment('Not able to reproduce')
|
162
|
-
|
163
|
-
Getting a particular version of a card
|
164
|
-
--------------------------------------
|
165
|
-
|
166
|
-
Mingle maintains the different versions of a card. It always shows the latest version
|
167
|
-
by default. However if you want to access a different version you can do so in the
|
168
|
-
following ways.
|
169
|
-
|
170
|
-
m_c = Mingle4r::MingleClient.new('http://localhost:8080', 'testuser', 'password')
|
171
|
-
m_c.proj_id = 'great_mingle_project'
|
172
|
-
defect_card = m_c.project.cards.first
|
173
|
-
supposing the latest version of the card is 42
|
174
|
-
|
175
|
-
1) Get the previous version
|
176
|
-
---------------------------
|
177
|
-
|
178
|
-
defect_card.version(:previous) # return version 41
|
179
|
-
|
180
|
-
2) Get the next version
|
181
|
-
-----------------------
|
182
|
-
|
183
|
-
defect_card.version(:next) # returns version 42 since it is the latest version
|
184
|
-
|
185
|
-
3) Get an arbitrary version
|
186
|
-
---------------------------
|
187
|
-
|
188
|
-
defect_card.version(21) # returns version 21
|
189
|
-
|
190
|
-
Getting all comments for a card
|
191
|
-
-------------------------------
|
192
|
-
|
193
|
-
m_c = Mingle4r::MingleClient.new('http://localhost:8080', 'testuser', 'password')
|
194
|
-
m_c.proj_id = 'great_mingle_project'
|
195
|
-
defect_card = m_c.project.cards.first
|
196
|
-
defect_cards.comments
|
197
|
-
|
198
|
-
Attachments
|
199
|
-
-----------
|
200
|
-
m_c = Mingle4r::MingleClient.new('http://localhost:8080', 'testuser', 'password')
|
201
|
-
m_c.proj_id = 'great_mingle_project'
|
202
|
-
defect_card = m_c.project.cards.first
|
203
|
-
defect_card.attachments
|
204
|
-
|
205
|
-
1) Downloading a particular attachment
|
206
|
-
--------------------------------------
|
207
|
-
|
208
|
-
attachment = defect_card.attachments.first
|
209
|
-
attachment.download('page.css')
|
210
|
-
|
211
|
-
2) Uploading an attachment
|
212
|
-
--------------------------
|
213
|
-
|
214
|
-
defect_card.upload_attachment('page-screenshot.jpg')
|
215
|
-
|
216
|
-
Murmurs
|
217
|
-
-------
|
218
|
-
|
219
|
-
1) Get the murmurs for a project
|
220
|
-
--------------------------------
|
221
|
-
|
222
|
-
m_c = Mingle4r::MingleClient.new('http://localhost:8080', 'testuser', 'password')
|
223
|
-
m_c.proj_id = 'great_mingle_project'
|
224
|
-
project = m_c.project
|
225
|
-
project.murmurs
|
226
|
-
|
227
|
-
2) Get the murmurs associated with a card
|
228
|
-
-----------------------------------------
|
229
|
-
|
230
|
-
card = project.cards.first
|
231
|
-
card.murmurs
|
232
|
-
|
233
|
-
3) post a murmur(hooray!)
|
234
|
-
-------------------------
|
235
|
-
project.post_murmur('my first murmur, I am excited!')
|
236
|
-
|
237
|
-
Get all transitions for a card
|
238
|
-
------------------------------
|
239
|
-
|
240
|
-
m_c = Mingle4r::MingleClient.new('http://localhost:8080', 'testuser', 'password')
|
241
|
-
m_c.proj_id = 'great_mingle_project'
|
242
|
-
defect_card = m_c.project.cards.first
|
243
|
-
|
244
|
-
defect_card.transitions # array of active resource objects
|
245
|
-
|
246
|
-
Execute a transition on a card
|
247
|
-
------------------------------
|
248
|
-
|
249
|
-
m_c = Mingle4r::MingleClient.new('http://localhost:8080', 'testuser', 'password')
|
250
|
-
m_c.proj_id = 'great_mingle_project'
|
251
|
-
defect_card = m_c.project.cards.first
|
252
|
-
|
253
|
-
defect_card.execute_transition(
|
254
|
-
'comment' => comment for the transition, required only if the transition requires a comment
|
255
|
-
'Property Name as in Mingle exactly' => 'Property value to set for the property', required only
|
256
|
-
if the transition requires to be set manually, multiple properties might need to be set.
|
257
|
-
)
|
258
|
-
|
259
|
-
MQL execution
|
260
|
-
-------------
|
261
|
-
|
262
|
-
mingle allows you to write an arbitrary MQL query and returns the results. This gem
|
263
|
-
allows you to do that in a simpler way. If you want to know more about MQL go to http://www.thoughtworks-studios.com/mingle/3.0/help/mql_reference.html.
|
264
|
-
|
265
|
-
m_c = Mingle4r::MingleClient.new('http://localhost:8080', 'testuser', 'password')
|
266
|
-
m_c.proj_id = 'great_mingle_project'
|
267
|
-
m_c.project.execute_mql('SELECT name, "Added in Iteration" WHERE Type = Story')
|
268
|
-
=> returns an array of hash
|
269
|
-
|
270
|
-
== REQUIREMENTS:
|
271
|
-
|
272
|
-
1) active_resource gem, it would be automatically taken care of
|
273
|
-
during gem install.
|
274
|
-
|
275
|
-
== LIMITATIONS:
|
276
|
-
|
277
|
-
updating a property on the card which is a link to another card does not work. So for now
|
278
|
-
only use it for other properties
|
279
|
-
|
280
|
-
== INSTALL:
|
281
|
-
|
282
|
-
since github no longer archives gems, I am hosting the gem at gemcutter. So you would need to
|
283
|
-
add http://gemcutter.org to your gem sources : gem sources -a 'http://gemcutter.org'. Then do
|
284
|
-
|
285
|
-
gem install mingle4r
|
286
|
-
|
287
|
-
== LICENSE:
|
288
|
-
|
289
|
-
(The MIT License)
|
290
|
-
|
291
|
-
Copyright (c) 2010 Arusarka Haldar
|
292
|
-
|
293
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
294
|
-
a copy of this software and associated documentation files (the
|
295
|
-
'Software'), to deal in the Software without restriction, including
|
296
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
297
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
298
|
-
permit persons to whom the Software is furnished to do so, subject to
|
299
|
-
the following conditions:
|
300
|
-
|
301
|
-
The above copyright notice and this permission notice shall be
|
302
|
-
included in all copies or substantial portions of the Software.
|
303
|
-
|
304
|
-
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
305
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
306
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
307
|
-
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
308
|
-
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
309
|
-
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
310
|
-
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|