mingle-macro-development-toolkit 1.3.2 → 1.3.3
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 +8 -0
- data/{README.rdoc → README.txt} +8 -6
- data/Rakefile +19 -27
- data/bin/new_mingle_macro +10 -4
- data/example/integration_test_helper.rb +5 -5
- data/example/unit_test_helper.rb +4 -13
- data/lib/macro_development_toolkit.rb +1 -1
- data/lib/macro_development_toolkit/mingle/project.rb +4 -4
- data/lib/macro_development_toolkit/mingle_model_loader.rb +100 -136
- data/test/fixtures/sample/card_types.yml +9 -1
- data/test/fixtures/sample/project_variables.yml +3 -1
- data/test/fixtures/sample/property_definitions.yml +13 -3
- data/test/integration/integration_test_helper.rb +20 -8
- data/test/integration/rest_loader.rb +172 -250
- data/test/unit/fixture_loader.rb +73 -145
- data/test/unit/fixture_loader_test.rb +11 -11
- data/test/unit/unit_test_helper.rb +6 -5
- metadata +29 -15
data/History.txt
CHANGED
data/{README.rdoc → README.txt}
RENAMED
@@ -1,18 +1,20 @@
|
|
1
1
|
= Macro Development Toolkit - supporting development of custom macros for Mingle
|
2
2
|
|
3
|
-
|
3
|
+
http://mingle-macros.rubyforge.org/
|
4
|
+
|
5
|
+
This toolkit provides support for developing, testing and deploying custom Mingle macros.
|
4
6
|
|
5
7
|
Use the built in generator to create a skeleton of a plugin which you can then deploy to an instance of Mingle running
|
6
8
|
version 2.2 or later of the software.
|
7
9
|
|
8
|
-
This allows you to take advantage of free charting utilities such as the Google Charts API, to create
|
10
|
+
This allows you to take advantage of free charting utilities such as the Google Charts API, to create
|
9
11
|
new visualizations, specific to your project or organization.
|
10
12
|
|
11
13
|
== FEATURES:
|
12
14
|
|
13
15
|
* A command line tool to generate the skeleton of a custom Mingle macro
|
14
16
|
* A unit test helper that uses locally available YAML fixture files to facilitate unit testing of the macros
|
15
|
-
* An integration test helper that can
|
17
|
+
* An integration test helper that can
|
16
18
|
* obtain data from a remote instance of Mingle
|
17
19
|
* test MQL execution against a remote instance of Mingle
|
18
20
|
* Rake task to deploy the custom macro as a plugin to a locally deployed Mingle instance
|
@@ -28,16 +30,16 @@ then use:
|
|
28
30
|
== GETTING STARTED:
|
29
31
|
|
30
32
|
To get started with this gem after you install it, use the new_mingle_macro script to generate a skeleton for your
|
31
|
-
macro, along with test helpers. Say you wanted to create a new macro called "risk_meter" start out by creating
|
33
|
+
macro, along with test helpers. Say you wanted to create a new macro called "risk_meter" start out by creating
|
32
34
|
the macro skeleton as follows
|
33
35
|
|
34
36
|
% new_mingle_macro risk_meter
|
35
37
|
|
36
|
-
The skeleton project will also contain a file, called "getting_started.txt" that will walk you through the steps
|
38
|
+
The skeleton project will also contain a file, called "getting_started.txt" that will walk you through the steps
|
37
39
|
of fleshing out your macro.
|
38
40
|
|
39
41
|
== SUPPORT:
|
40
|
-
|
42
|
+
|
41
43
|
For any issues/clarifications/comments with installation or using this gem, contact us at the Mingle forums[http://community.thoughtworks.com/pages/home]. You can also get in touch with the ThoughtWorks Studios support
|
42
44
|
team over email at support@thoughtworks.com
|
43
45
|
|
data/Rakefile
CHANGED
@@ -17,32 +17,24 @@ end
|
|
17
17
|
require File.dirname(__FILE__) + '/lib/macro_development_toolkit'
|
18
18
|
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
|
40
|
-
p.remote_rdoc_dir = ''
|
41
|
-
p.rsync_args = '-av --delete --ignore-errors'
|
42
|
-
end
|
43
|
-
|
44
|
-
require 'newgem/tasks'
|
45
|
-
|
46
|
-
# end
|
20
|
+
%w[newgem rubigen hoe].each { |f| require f }
|
21
|
+
|
22
|
+
# Generate all the Rake tasks
|
23
|
+
# Run 'rake -T' to see list of generated tasks (from gem root directory)
|
24
|
+
$hoe = Hoe.spec('mingle-macro-development-toolkit') do |p|
|
25
|
+
p.version = MacroDevelopmentToolkit::VERSION
|
26
|
+
p.developer('ThoughtWorks Inc', 'support@thoughtworks.com')
|
27
|
+
p.post_install_message = 'getting_started.txt'
|
28
|
+
p.rubyforge_name = 'mingle-macros'
|
29
|
+
p.extra_deps = [
|
30
|
+
['activesupport','2.3.5'],
|
31
|
+
]
|
32
|
+
p.summary = "This toolkit provides support for developing, testing and deploying custom Mingle macros."
|
33
|
+
p.clean_globs |= %w[**/.DS_Store tmp *.log]
|
34
|
+
path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
|
35
|
+
p.remote_rdoc_dir = ''
|
36
|
+
p.rsync_args = '-av --delete --ignore-errors'
|
37
|
+
end
|
38
|
+
require 'newgem/tasks'
|
47
39
|
|
48
40
|
Dir['tasks/**/*.rake'].each { |t| load t }
|
data/bin/new_mingle_macro
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
#Copyright
|
2
|
+
#Copyright 2011 ThoughtWorks, Inc. All rights reserved.
|
3
3
|
|
4
4
|
module NewMingleMacro
|
5
5
|
module Messages
|
@@ -23,7 +23,7 @@ underscores (_). Is this OK? [Yes/No]"
|
|
23
23
|
SPECIAL_CHARACTER_REPLACEMENT_MESSAGE
|
24
24
|
|
25
25
|
AUTO_GENERATED_CLASS_NAME_MESSAGE = <<-AUTO_GENERATED_CLASS_NAME_MESSAGE
|
26
|
-
|
26
|
+
Succeeded with warnings: You did not provide a class name for your macro. A class name has been generated
|
27
27
|
for you. This name should be considered a guide and we highly recommend naming your own
|
28
28
|
classes name with appropriate namespaces to avoid collisions with standard libraries
|
29
29
|
or Mingle classes. Please run this tool with no command-line arguments to learn
|
@@ -35,10 +35,16 @@ end
|
|
35
35
|
require 'erb'
|
36
36
|
require 'fileutils'
|
37
37
|
begin
|
38
|
-
require 'active_support'
|
38
|
+
require 'active_support/all'
|
39
39
|
rescue LoadError
|
40
40
|
require 'rubygems'
|
41
|
-
require 'active_support'
|
41
|
+
require 'active_support/all'
|
42
|
+
end
|
43
|
+
|
44
|
+
require 'active_support/version'
|
45
|
+
REQUIRED_ACTIVE_SUPPORT_VERSION = '2.3.5'
|
46
|
+
unless ActiveSupport::VERSION::STRING == REQUIRED_ACTIVE_SUPPORT_VERSION
|
47
|
+
raise "For guaranteed compatibility with Mingle, you must develop macros using ActiveSupport #{REQUIRED_ACTIVE_SUPPORT_VERSION}. You are using version #{ActiveSupport::VERSION::STRING}"
|
42
48
|
end
|
43
49
|
|
44
50
|
def print_usage
|
@@ -6,12 +6,13 @@ require File.join(File.dirname(__FILE__), 'rest_loader')
|
|
6
6
|
|
7
7
|
class Test::Unit::TestCase
|
8
8
|
|
9
|
-
def project(
|
10
|
-
@
|
9
|
+
def project(resource)
|
10
|
+
@projects ||= {}
|
11
|
+
@projects[resource] ||= load_project_resource(resource)
|
11
12
|
end
|
12
13
|
|
13
14
|
def projects(*resources)
|
14
|
-
|
15
|
+
resources.collect {|resource| project(resource)}
|
15
16
|
end
|
16
17
|
|
17
18
|
def errors
|
@@ -25,7 +26,6 @@ class Test::Unit::TestCase
|
|
25
26
|
private
|
26
27
|
|
27
28
|
def load_project_resource(resource)
|
28
|
-
RESTfulLoaders::ProjectLoader.new(resource,
|
29
|
+
RESTfulLoaders::ProjectLoader.new(resource, self).project
|
29
30
|
end
|
30
|
-
|
31
31
|
end
|
data/example/unit_test_helper.rb
CHANGED
@@ -6,17 +6,8 @@ require File.join(File.dirname(__FILE__), 'fixture_loader')
|
|
6
6
|
class Test::Unit::TestCase
|
7
7
|
|
8
8
|
def project(name)
|
9
|
-
@
|
9
|
+
@projects ||= {}
|
10
|
+
@projects[name] ||= FixtureLoaders::ProjectLoader.new(name).project
|
10
11
|
end
|
11
|
-
|
12
|
-
|
13
|
-
@projects ||= names.map { |name| load_project_fixture(name) }
|
14
|
-
end
|
15
|
-
|
16
|
-
private
|
17
|
-
|
18
|
-
def load_project_fixture(name)
|
19
|
-
FixtureLoaders::ProjectLoader.new(name).project
|
20
|
-
end
|
21
|
-
|
22
|
-
end
|
12
|
+
|
13
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Mingle
|
2
|
-
# Copyright
|
2
|
+
# Copyright 2010 ThoughtWorks, Inc. All rights reserved.
|
3
3
|
|
4
4
|
# This is a lightweight representation of a project.
|
5
5
|
# From an instance of this class you can the name & identifier of the project.
|
@@ -27,14 +27,14 @@ module Mingle
|
|
27
27
|
end
|
28
28
|
|
29
29
|
# *returns*: A list CardTypes as configured for this project.
|
30
|
-
# There will always be
|
30
|
+
# There will always be at least one element in this list.
|
31
31
|
def card_types
|
32
|
-
@card_types_loader.load
|
32
|
+
@card_types_loader.load.collect(&:card_type)
|
33
33
|
end
|
34
34
|
|
35
35
|
# *returns*: An list of PropertyDefinitions as configured for this project, which may be empty
|
36
36
|
def property_definitions
|
37
|
-
@property_definitions_loader.load
|
37
|
+
@property_definitions_loader.load.collect(&:property_definition)
|
38
38
|
end
|
39
39
|
|
40
40
|
# *accepts*: The name of a project variable configured for this project
|
@@ -9,179 +9,143 @@ module MingleModelLoaders
|
|
9
9
|
@macro_context = macro_context
|
10
10
|
@alert_receiver = alert_receiver
|
11
11
|
end
|
12
|
-
|
13
|
-
def card_types_property_definitions_by_card_type_id_loader(card_type_id)
|
14
|
-
LoadCardTypesPropertyDefinitionsByCardTypeId.new(card_type_id, @project)
|
15
|
-
end
|
16
|
-
|
17
|
-
def card_types_property_definitions_by_property_definition_id_loader(property_definition_id)
|
18
|
-
LoadCardTypesPropertyDefinitionsByPropertyDefinitionId.new(property_definition_id, @project)
|
19
|
-
end
|
20
|
-
|
21
|
-
def values_by_property_definition_id_loader(property_definition_id)
|
22
|
-
LoadValuesByPropertyDefinitionId.new(property_definition_id, @project)
|
23
|
-
end
|
24
|
-
|
25
|
-
def card_type_by_id_loader(card_type_id)
|
26
|
-
LoadCardTypeById.new(card_type_id, @project)
|
27
|
-
end
|
28
|
-
|
29
|
-
def property_definition_by_id_loader(property_definition_id)
|
30
|
-
LoadPropertyDefinitionById.new(property_definition_id, @project)
|
31
|
-
end
|
32
|
-
|
33
|
-
def card_types_by_project_id_loader
|
34
|
-
LoadCardTypesByProjectId.new(@project)
|
35
|
-
end
|
36
|
-
|
37
|
-
def property_definitions_by_project_id_loader
|
38
|
-
LoadPropertyDefinitionsByProjectId.new(@project)
|
39
|
-
end
|
40
|
-
|
41
|
-
def team_by_project_id_loader
|
42
|
-
LoadTeamByProjectId.new(@project)
|
43
|
-
end
|
44
|
-
|
45
|
-
def project_variables_by_project_id_loader
|
46
|
-
LoadProjectVariablesByProjectId.new(@project)
|
47
|
-
end
|
48
12
|
end
|
49
13
|
|
50
14
|
class ProjectLoader < Base
|
51
15
|
def project
|
16
|
+
@proj ||= load
|
17
|
+
end
|
18
|
+
|
19
|
+
def load
|
52
20
|
project = Mingle::Project.new(@project, :content_provider => @macro_context[:content_provider], :alert_receiver => @alert_receiver)
|
53
|
-
project.card_types_loader =
|
54
|
-
project.property_definitions_loader =
|
55
|
-
project.team_loader =
|
56
|
-
project.project_variables_loader =
|
21
|
+
project.card_types_loader = CardTypesLoader.new(@project)
|
22
|
+
project.property_definitions_loader = PropertyDefinitionsLoader.new(@project)
|
23
|
+
project.team_loader = TeamLoader.new(@project)
|
24
|
+
project.project_variables_loader = ProjectVariablesLoader.new(@project)
|
57
25
|
project
|
58
26
|
end
|
59
27
|
end
|
60
|
-
|
61
|
-
class
|
28
|
+
|
29
|
+
class CardTypesLoader
|
30
|
+
def initialize(project)
|
31
|
+
@project = project
|
32
|
+
end
|
33
|
+
|
62
34
|
def load
|
63
35
|
@project.with_active_project do
|
64
36
|
@project.card_types.collect do |ct|
|
65
|
-
|
66
|
-
|
67
|
-
card_type
|
68
|
-
end.sort_by(&:position)
|
37
|
+
CardTypeLoader.new(ct)
|
38
|
+
end.sort_by {|loader| loader.card_type.position}
|
69
39
|
end
|
70
|
-
end
|
40
|
+
end
|
71
41
|
end
|
72
|
-
|
73
|
-
class
|
42
|
+
|
43
|
+
class CardTypeLoader
|
44
|
+
def initialize(ct)
|
45
|
+
@ct = ct
|
46
|
+
end
|
47
|
+
|
48
|
+
def card_type
|
49
|
+
@card_type ||= load
|
50
|
+
end
|
51
|
+
|
52
|
+
def load
|
53
|
+
ct = Mingle::CardType.new(@ct)
|
54
|
+
ct.card_types_property_definitions_loader = CardTypesPropertyDefinitionsLoader.new(@ct)
|
55
|
+
ct
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
class PropertyDefinitionsLoader
|
60
|
+
def initialize(project)
|
61
|
+
@project = project
|
62
|
+
end
|
63
|
+
|
74
64
|
def load
|
75
65
|
@project.with_active_project do
|
76
66
|
(@project.predefined_property_definitions + @project.all_property_definitions).collect do |pd|
|
77
|
-
|
78
|
-
property_definition.card_types_property_definitions_loader = card_types_property_definitions_by_property_definition_id_loader(pd.id)
|
79
|
-
property_definition.values_loader = values_by_property_definition_id_loader(pd.id)
|
80
|
-
property_definition
|
67
|
+
PropertyDefinitionLoader.new(pd)
|
81
68
|
end
|
82
69
|
end
|
83
|
-
end
|
70
|
+
end
|
84
71
|
end
|
85
|
-
|
86
|
-
class LoadCardTypesPropertyDefinitionsByCardTypeId < Base
|
87
|
-
def initialize(card_type_id, fixture_file_name)
|
88
|
-
super(fixture_file_name)
|
89
|
-
@card_type_id = card_type_id
|
90
|
-
end
|
91
72
|
|
73
|
+
class PropertyDefinitionLoader
|
74
|
+
def initialize(pd)
|
75
|
+
@pd = pd
|
76
|
+
end
|
77
|
+
|
78
|
+
def property_definition
|
79
|
+
@property_definition ||= load
|
80
|
+
end
|
81
|
+
|
92
82
|
def load
|
93
|
-
@
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
card_type_property_definition
|
99
|
-
end.sort_by(&:position).compact
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
end
|
104
|
-
|
105
|
-
class LoadCardTypesPropertyDefinitionsByPropertyDefinitionId < Base
|
106
|
-
def initialize(property_definition_id, fixture_file_name)
|
107
|
-
super(fixture_file_name)
|
108
|
-
@property_definition_id = property_definition_id
|
109
|
-
end
|
110
|
-
|
111
|
-
def load
|
112
|
-
@project.with_active_project do
|
113
|
-
@project.all_property_definitions.detect { |pd| pd.id == @property_definition_id }.property_type_mappings do |ctpd|
|
114
|
-
card_type_property_definition = Mingle::CardTypePropertyDefinition.new(ctpd)
|
115
|
-
card_type_property_definition.card_type_loader = card_type_by_id_loader(ctpd.card_type_id)
|
116
|
-
card_type_property_definition.property_definition_loader = property_definition_by_id_loader(ctpd.property_definition_id)
|
117
|
-
card_type_property_definition
|
118
|
-
end.compact.sort_by(&:position).compact
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
83
|
+
pd = Mingle::PropertyDefinition.new(@pd)
|
84
|
+
pd.card_types_property_definitions_loader = CardTypesPropertyDefinitionsLoader.new(@pd)
|
85
|
+
pd.values_loader = PropertyValuesLoader.new(@pd)
|
86
|
+
pd
|
87
|
+
end
|
122
88
|
end
|
123
|
-
|
124
|
-
class
|
125
|
-
def initialize(
|
126
|
-
|
127
|
-
@card_type_id = card_type_id
|
128
|
-
end
|
129
|
-
|
130
|
-
def load
|
131
|
-
@project.with_active_project do
|
132
|
-
ct = Mingle::CardType.new(@project.card_types.find(@card_type_id))
|
133
|
-
ct.card_types_property_definitions_loader = card_types_property_definitions_by_card_type_id_loader(@card_type_id)
|
134
|
-
ct
|
135
|
-
end
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
class LoadPropertyDefinitionById < Base
|
140
|
-
def initialize(property_definition_id, fixture_file_name)
|
141
|
-
super(fixture_file_name)
|
142
|
-
@property_definition_id = property_definition_id
|
89
|
+
|
90
|
+
class CardTypesPropertyDefinitionsLoader
|
91
|
+
def initialize(card_type_or_property_definition)
|
92
|
+
@card_type_or_property_definition = card_type_or_property_definition
|
143
93
|
end
|
144
|
-
|
94
|
+
|
145
95
|
def load
|
146
|
-
@
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
96
|
+
if @card_type_or_property_definition.respond_to?(:property_type_mappings)
|
97
|
+
@card_type_or_property_definition.property_type_mappings.collect do |mapping|
|
98
|
+
ct = CardTypeLoader.new(mapping.card_type)
|
99
|
+
pd = PropertyDefinitionLoader.new(mapping.property_definition)
|
100
|
+
OpenStruct.new(:card_type => ct.load, :property_definition => pd.load)
|
101
|
+
end
|
102
|
+
else #pre_defined_property
|
103
|
+
@card_type_or_property_definition.project.with_active_project do |project|
|
104
|
+
project.card_types.collect do |card_type|
|
105
|
+
ct = CardTypeLoader.new(card_type)
|
106
|
+
pd = PropertyDefinitionLoader.new(@card_type_or_property_definition)
|
107
|
+
OpenStruct.new(:card_type => ct.load, :property_definition => pd.load)
|
108
|
+
end
|
109
|
+
end
|
151
110
|
end
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
class LoadValuesByPropertyDefinitionId < Base
|
156
|
-
def initialize(property_definition_id, fixture_file_name)
|
157
|
-
super(fixture_file_name)
|
158
|
-
@property_definition_id = property_definition_id
|
159
111
|
end
|
112
|
+
end
|
160
113
|
|
114
|
+
class PropertyValuesLoader
|
115
|
+
def initialize(property_definition)
|
116
|
+
@property_definition = property_definition
|
117
|
+
end
|
118
|
+
|
161
119
|
def load
|
162
|
-
@
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
end
|
169
|
-
end
|
120
|
+
@property_definition.light_property_values.collect do |pv|
|
121
|
+
property_value = Mingle::PropertyValue.new(pv)
|
122
|
+
property_value.property_definition_loader = PropertyDefinitionLoader.new(@property_definition)
|
123
|
+
property_value
|
124
|
+
end.compact
|
125
|
+
end
|
170
126
|
end
|
171
127
|
|
172
|
-
class
|
128
|
+
class TeamLoader
|
129
|
+
def initialize(project)
|
130
|
+
@project = project
|
131
|
+
end
|
132
|
+
|
173
133
|
def load
|
174
134
|
@project.with_active_project do
|
175
135
|
@project.users.collect { |user| Mingle::User.new(user) }
|
176
136
|
end
|
177
|
-
end
|
137
|
+
end
|
178
138
|
end
|
179
|
-
|
180
|
-
class
|
139
|
+
|
140
|
+
class ProjectVariablesLoader
|
141
|
+
def initialize(project)
|
142
|
+
@project = project
|
143
|
+
end
|
144
|
+
|
181
145
|
def load
|
182
146
|
@project.with_active_project do
|
183
147
|
@project.project_variables.collect { |plv| Mingle::ProjectVariable.new(plv) }
|
184
148
|
end
|
185
|
-
end
|
149
|
+
end
|
186
150
|
end
|
187
|
-
end
|
151
|
+
end
|