schubert-minglr 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. data/Rakefile +2 -0
  2. data/VERSION.yml +2 -2
  3. data/bin/minglr +11 -11
  4. data/bin/mtx +1 -1
  5. data/lib/minglr.rb +18 -10
  6. data/lib/minglr/action.rb +75 -0
  7. data/lib/minglr/config_parser.rb +49 -0
  8. data/lib/minglr/extensions/array.rb +23 -0
  9. data/lib/minglr/input_cache.rb +3 -3
  10. data/lib/minglr/options_parser.rb +79 -0
  11. data/lib/minglr/resources/attachment.rb +46 -0
  12. data/lib/minglr/resources/base.rb +42 -0
  13. data/lib/minglr/resources/card.rb +107 -0
  14. data/lib/minglr/resources/project.rb +25 -0
  15. data/lib/minglr/resources/property_definition.rb +12 -0
  16. data/lib/minglr/resources/transition_execution.rb +6 -0
  17. data/lib/minglr/resources/user.rb +25 -0
  18. data/minglr.gemspec +30 -28
  19. data/minglrconfig.sample +19 -0
  20. data/test/extensions/array_test.rb +41 -0
  21. data/test/resources/attachment_test.rb +40 -0
  22. data/test/resources/base_test.rb +45 -0
  23. data/test/resources/card_test.rb +89 -0
  24. data/test/resources/project_test.rb +26 -0
  25. data/test/resources/property_definition_test.rb +25 -0
  26. data/test/resources/user_test.rb +39 -0
  27. data/test/test_helper.rb +15 -5
  28. metadata +27 -15
  29. data/lib/minglr/attachment.rb +0 -7
  30. data/lib/minglr/card.rb +0 -2
  31. data/lib/minglr/mingle_resource.rb +0 -5
  32. data/lib/minglr/minglr_action.rb +0 -200
  33. data/lib/minglr/minglr_config_parser.rb +0 -44
  34. data/lib/minglr/minglr_options_parser.rb +0 -70
  35. data/lib/minglr/property_definition.rb +0 -2
  36. data/lib/minglr/transition_execution.rb +0 -2
  37. data/lib/minglr/user.rb +0 -2
  38. data/test/attachment_test.rb +0 -24
  39. data/test/minglr_resource_test.rb +0 -24
@@ -0,0 +1,26 @@
1
+ require 'test_helper'
2
+
3
+ module Resources
4
+
5
+ class ProjectTest < Test::Unit::TestCase
6
+
7
+ context Project do
8
+
9
+ context "configure" do
10
+
11
+ should "subtract the project name from the url" do
12
+ options = { :username => "user",
13
+ :password => "pass",
14
+ :url => "proto://somehost.com:1234/projects/my_project" }
15
+ Base.configure(options)
16
+ Project.configure
17
+ assert_equal "/projects", Project.prefix
18
+ end
19
+
20
+ end
21
+
22
+ end
23
+
24
+ end
25
+
26
+ end
@@ -0,0 +1,25 @@
1
+ require 'test_helper'
2
+
3
+ module Resources
4
+
5
+ class PropertyDefinitionTest < Test::Unit::TestCase
6
+
7
+ context PropertyDefinition do
8
+
9
+ context "project_options" do
10
+
11
+ should "collect all property definitions into an array of arrays" do
12
+ property1 = stub("PropertyDefinition", :column_name => "cp_name", :name => "Name")
13
+ property2 = stub("PropertyDefinition", :column_name => "cp_accepted_on_iteration_card_id", :name => "Accepted in Iteration")
14
+ PropertyDefinition.expects(:find).with(:all).returns([property1, property2])
15
+
16
+ assert_equal PropertyDefinition.project_options, [[:cp_name, "Name"], [:cp_accepted_on_iteration_card_id, "Accepted in Iteration"]]
17
+ end
18
+
19
+ end
20
+
21
+ end
22
+
23
+ end
24
+
25
+ end
@@ -0,0 +1,39 @@
1
+ require 'test_helper'
2
+
3
+ module Resources
4
+
5
+ class UserTest < Test::Unit::TestCase
6
+
7
+ context User do
8
+
9
+ context "print_all" do
10
+
11
+ should "warn if there are no users" do
12
+ User.expects(:find).with(:all).returns([])
13
+ User.expects(:warn).with("No users in project")
14
+ User.print_all
15
+ end
16
+
17
+ should "print the users found with format" do
18
+ user1 = stub("UserXml", :user => stub("User", :login => "user1", :name => "User One", :email => "user1@test"))
19
+ user2 = stub("UserXml", :user => stub("User", :login => "user22", :name => "User TwoTwo", :email => "user22@test"))
20
+ User.expects(:find).with(:all).returns([user1, user2])
21
+ User.expects(:puts).with(" user1 - User One - user1@test")
22
+ User.expects(:puts).with("user22 - User TwoTwo - user22@test")
23
+ User.print_all
24
+ end
25
+
26
+ end
27
+
28
+ context "find_user_id_for_user" do
29
+
30
+ should_eventually "return the owner_id of the user matching the username" do
31
+ end
32
+
33
+ end
34
+
35
+ end
36
+
37
+ end
38
+
39
+ end
data/test/test_helper.rb CHANGED
@@ -1,10 +1,20 @@
1
- require 'rubygems'
2
- require 'test/unit'
3
- require 'shoulda'
1
+ require "rubygems"
2
+ require "test/unit"
3
+ begin
4
+ require "shoulda"
5
+ rescue LoadError
6
+ puts "Missing shoulda: sudo gem install thoughtbot-shoulda --source=http://gems.github.com/"
7
+ end
8
+ begin
9
+ require "mocha"
10
+ rescue LoadError
11
+ puts "Missing mocha: sudo gem install mocha"
12
+ end
4
13
 
5
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
14
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
6
15
  $LOAD_PATH.unshift(File.dirname(__FILE__))
7
- require 'minglr'
16
+ $LOAD_PATH.unshift(File.dirname(__FILE__), "resources")
17
+ require "minglr"
8
18
 
9
19
  class Test::Unit::TestCase
10
20
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: schubert-minglr
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Schubert
@@ -11,7 +11,7 @@ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
13
 
14
- date: 2009-07-09 00:00:00 -07:00
14
+ date: 2009-07-26 00:00:00 -07:00
15
15
  default_executable:
16
16
  dependencies: []
17
17
 
@@ -36,23 +36,30 @@ files:
36
36
  - bin/minglr
37
37
  - bin/mtx
38
38
  - lib/minglr.rb
39
- - lib/minglr/attachment.rb
40
- - lib/minglr/card.rb
39
+ - lib/minglr/action.rb
40
+ - lib/minglr/config_parser.rb
41
+ - lib/minglr/extensions/array.rb
41
42
  - lib/minglr/input_cache.rb
42
- - lib/minglr/mingle_resource.rb
43
- - lib/minglr/minglr_action.rb
44
- - lib/minglr/minglr_config_parser.rb
45
- - lib/minglr/minglr_options_parser.rb
46
43
  - lib/minglr/mtx_options_parser.rb
47
- - lib/minglr/property_definition.rb
48
- - lib/minglr/transition_execution.rb
49
- - lib/minglr/user.rb
44
+ - lib/minglr/options_parser.rb
45
+ - lib/minglr/resources/attachment.rb
46
+ - lib/minglr/resources/base.rb
47
+ - lib/minglr/resources/card.rb
48
+ - lib/minglr/resources/project.rb
49
+ - lib/minglr/resources/property_definition.rb
50
+ - lib/minglr/resources/transition_execution.rb
51
+ - lib/minglr/resources/user.rb
50
52
  - minglr.gemspec
51
53
  - minglrconfig.sample
52
54
  - tasks/commit.sample.rake
53
55
  - tasks/svn.sample.rake
54
- - test/attachment_test.rb
55
- - test/minglr_resource_test.rb
56
+ - test/extensions/array_test.rb
57
+ - test/resources/attachment_test.rb
58
+ - test/resources/base_test.rb
59
+ - test/resources/card_test.rb
60
+ - test/resources/project_test.rb
61
+ - test/resources/property_definition_test.rb
62
+ - test/resources/user_test.rb
56
63
  - test/test_helper.rb
57
64
  has_rdoc: true
58
65
  homepage: http://github.com/schubert/minglr
@@ -81,6 +88,11 @@ signing_key:
81
88
  specification_version: 2
82
89
  summary: command line user tool for Mingle (http://mingle.thoughtworks.com/mingle-agile-project-management)
83
90
  test_files:
84
- - test/attachment_test.rb
85
- - test/minglr_resource_test.rb
91
+ - test/extensions/array_test.rb
92
+ - test/resources/attachment_test.rb
93
+ - test/resources/base_test.rb
94
+ - test/resources/card_test.rb
95
+ - test/resources/project_test.rb
96
+ - test/resources/property_definition_test.rb
97
+ - test/resources/user_test.rb
86
98
  - test/test_helper.rb
@@ -1,7 +0,0 @@
1
- class Attachment < MingleResource
2
-
3
- def self.configure
4
- self.prefix += "cards/:card_number/"
5
- end
6
-
7
- end
data/lib/minglr/card.rb DELETED
@@ -1,2 +0,0 @@
1
- class Card < MingleResource
2
- end
@@ -1,5 +0,0 @@
1
- class MingleResource < ActiveResource::Base
2
- def self.configure(uri_options)
3
- self.site = "#{uri_options[:protocol]}://#{uri_options[:username]}:#{uri_options[:password]}@#{uri_options[:host_and_port]}/projects/#{uri_options[:project]}"
4
- end
5
- end
@@ -1,200 +0,0 @@
1
- class MinglrAction
2
-
3
- ACTIONS = ["cards", "card", "create", "update", "move", "users", "attach", "fetch"].sort!
4
-
5
- def self.execute(action, options = [], flag_options = {}, config = {})
6
- MinglrAction.new(action.to_sym, options, flag_options, config)
7
- end
8
-
9
- attr_reader :action, :options, :flag_options, :config
10
-
11
- def initialize(action, options, flag_options, config)
12
- @action = action
13
- if action == options[0].to_sym
14
- options.shift
15
- else
16
- options.shift; options.shift
17
- end
18
- @options = options
19
- @flag_options = flag_options
20
- @config = config
21
- begin
22
- self.send(action)
23
- rescue ActiveResource::ResourceNotFound => error
24
- puts error.message + " for URL #{MingleResource.site}..."
25
- end
26
- end
27
-
28
- def cards
29
- attributes = [:number, :card_type_name, @config[:status_property].to_sym, :name]
30
- cards = Card.find(:all)
31
- cards = filter_collection(cards, attributes, @options)
32
- print_collection(cards, attributes)
33
- end
34
-
35
- def users
36
- attributes = [:login, :name, :email]
37
- users = User.find(:all).collect! { |user| user.user }
38
- users = filter_collection(users, attributes, @options)
39
- print_collection(users, attributes, "right")
40
- end
41
-
42
- def card
43
- card_number = @options.first
44
- attributes = [:number, :card_type_name, @config[:status_property].to_sym, :name, :description]
45
- card = card_by_number(card_number)
46
- attachments = Attachment.find(:all, :params => { :card_number => card_number })
47
- attachments = attachments.collect do |attachment|
48
- "* #{attachment.file_name}: #{MingleResource.site + attachment.url}"
49
- end
50
- output = <<-EOS
51
- Number: #{card.number}
52
- Name: #{card.name}
53
- Type: #{card.card_type_name}
54
- Status: #{card.send(@config[:status_property].to_sym)}
55
- Description: #{card.description}
56
-
57
- Attachments:
58
- #{attachments.join("\n")}
59
- EOS
60
- puts output
61
- end
62
-
63
- def attach
64
- card_number = @options.first
65
- if card_to_update = card_by_number(card_number)
66
- url = Attachment.site
67
- url = (url.to_s.gsub(/#{url.path}$/, '')) + Attachment.collection_path(:card_number => card_number)
68
- file_name = @flag_options[:file_attachment]
69
- require 'httpclient'
70
- if File.exist?(file_name)
71
- File.open(file_name) do |file|
72
- body = { 'file' => file, "filename" => file_name }
73
- client = HTTPClient.new
74
- client.set_auth(nil, @config[:username], @config[:password])
75
- res = client.post(url, body)
76
- if res.status_code == 201
77
- puts "File '#{file_name}' attached to card #{card_number}"
78
- else
79
- puts "Error attaching file '#{file_name}' to card #{card_number} (Got back HTTP code #{res.status_code})"
80
- end
81
- end
82
- else
83
- puts "Unable to open file '#{file_name}'"
84
- end
85
- end
86
- end
87
-
88
- def fetch
89
- card_number = @options.first
90
- if card_to_update = card_by_number(card_number)
91
- attachments = Attachment.find(:all, :params => { :card_number => card_number })
92
- attachments.each do |attachment|
93
- url = MingleResource.site + attachment.url
94
- url.userinfo = nil, nil
95
- puts "Downloading #{url.to_s}:"
96
- `curl --insecure --progress-bar --output #{attachment.file_name} --user #{@config[:username]}:#{@config[:password]} #{url}`
97
- end
98
- end
99
- end
100
-
101
- def create
102
- @flag_options.merge!({ @config[:status_property].to_sym => "New", :cp_owner_user_id => owner_id })
103
- card = Card.new(@flag_options)
104
- card.save
105
- card.reload
106
- puts "Card #{card.number} created"
107
- end
108
-
109
- def update
110
- @flag_options.merge!({ :cp_owner_user_id => owner_id })
111
- card_number = @options.first
112
- card_to_update = card_by_number(card_number)
113
- @flag_options.each do |attribute, value|
114
- card_to_update.send("#{attribute.to_s}=".to_sym, value)
115
- end
116
- card_to_update.save
117
- puts "Card #{card_to_update.number} updated\n\n"
118
- card
119
- end
120
-
121
- def move
122
- card_number = @options.first
123
- card_to_move = card_by_number(card_number)
124
- transition_options = { :card => card_number }
125
- transition_options.merge!({ :comment => @flag_options[:comment]}) if @flag_options[:comment]
126
- current_status = card_to_move.send(@config[:status_property])
127
- next_transition = nil
128
-
129
- case card_to_move.card_type_name.downcase
130
- when /task/
131
- status_states = @config.select do |key, value|
132
- key.to_s =~ /^task_state_/
133
- end
134
- when /story/
135
- status_states = @config.select do |key, value|
136
- key.to_s =~ /^story_state/
137
- end
138
- else
139
- puts "No transitions defined for card of type #{card_to_move.card_type_name}"
140
- end
141
- status_states = status_states.collect {|state| state.last }.collect {|state| state.split(">").collect { |value| value.strip } }
142
- next_transition = status_states.select {|state| state.first.downcase == current_status.downcase }.first.last
143
- transition_options.merge!({ :transition => next_transition })
144
-
145
- if response = TransitionExecution.create(transition_options)
146
- if response.attributes["status"] == "completed"
147
- puts "Moved card from #{current_status} to #{next_transition}"
148
- end
149
- end
150
- end
151
-
152
- def pickup
153
- raise "not implemented yet"
154
- end
155
-
156
- private
157
-
158
- def filter_collection(collection, attributes, words)
159
- words.each do |word|
160
- collection = collection.select do |element|
161
- output = ""
162
- attributes.each { |attribute| output << element.send(attribute).to_s + " " }
163
- output =~ /#{word}/i
164
- end
165
- end
166
- collection
167
- end
168
-
169
- def print_collection(collection, attributes, align = "left")
170
- output = []
171
- longest_attributes = Array.new(attributes.length, 0)
172
- alignment = (align == "left" ? :ljust : :rjust)
173
- collection.each do |element|
174
- entry = []
175
- attributes.each_with_index do |attribute, index|
176
- attribute_value = element.send(attribute).to_s
177
- longest_attributes[index] = attribute_value.length if attribute_value.length > longest_attributes[index]
178
- entry << attribute_value
179
- end
180
- output << entry
181
- end
182
- output.each do |entry|
183
- row = []
184
- entry.each_with_index do |part, index|
185
- row << [part.send(alignment, longest_attributes[index])]
186
- end
187
- puts row.join(" - ")
188
- end
189
- end
190
-
191
- def card_by_number(number)
192
- Card.find(number)
193
- end
194
-
195
- def owner_id
196
- user = User.find(:all).select { |user| user.user.login == @config[:username] }.first
197
- user.user_id
198
- end
199
-
200
- end
@@ -1,44 +0,0 @@
1
- class MinglrConfigParser
2
- CONFIG_FILE = ".minglrconfig"
3
- attr_reader :config
4
-
5
- def self.parse
6
- config_files = [File.join(ENV["HOME"], CONFIG_FILE), File.join(ENV["PWD"], CONFIG_FILE)]
7
- config_files.each do |config_file_name|
8
- if File.exist?(config_file_name)
9
- return self.new(File.read(config_file_name)).config
10
- end
11
- end
12
- puts "Unable to find #{CONFIG_FILE} in #{config_files.join(", ")}"
13
- end
14
-
15
- def initialize(config_contents)
16
- @config = {}
17
- @current_section = nil
18
- config_contents.each_line do |line|
19
- line = line.strip!
20
- case line
21
- when ""
22
- next
23
- when /\[(.*)\]/
24
- define_section($1.to_s)
25
- else
26
- define_var(line)
27
- end
28
- end
29
- @config
30
- end
31
-
32
- def define_section(section_name)
33
- @config[section_name.to_sym] = {} unless @config.has_key?(section_name.to_sym)
34
- @current_section = section_name.to_sym
35
- end
36
-
37
- def define_var(line)
38
- key, value = line.split("=")
39
- key.strip!
40
- value.strip!
41
- @config[@current_section][key.to_sym] = value
42
- end
43
-
44
- end