mingle_cli 0.0.1

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b3f5703f33b0cd3b5455cc44236cc6c6aefe3eb1
4
+ data.tar.gz: 2985930ee09d4593f511f5063fa2e5c4cdea13ee
5
+ SHA512:
6
+ metadata.gz: 39159a96e1556ba3b0c0f48d6e4a1fd0084d7dbd6ae9a2a49e3af9a02b2375304092db87aca1fb0a06fa60a98a5e345c32c3cbc9bdaaf050d733c1ebe22d2c55
7
+ data.tar.gz: 5559c321b0dc15384ba692193397901e07f25c32b51d09bc4256b939dd534adcd777015e4e5a95515c2a7667a5e8e577f9b6c7f7a5a6c563c5ac908af212c46f
data/.autotest ADDED
@@ -0,0 +1 @@
1
+ require 'autotest/growl'
data/.bundle/config ADDED
@@ -0,0 +1,3 @@
1
+ ---
2
+ BUNDLE_DISABLE_SHARED_GEMS: "1"
3
+ BUNDLE_PATH: vendor/bundle
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ .config
2
+ vendor/**/*
3
+ **/.DS_Store
4
+ tags
5
+ Gemfile.lock
6
+ coverage/
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.0.0-p0
data/.travis.yml ADDED
@@ -0,0 +1,22 @@
1
+ language: ruby
2
+ script: 'bundle exec rake spec'
3
+ cache: bundler
4
+ rvm:
5
+ - 1.9.3
6
+ - 2.0.0
7
+ - 2.1.0
8
+ - ruby-head
9
+ env:
10
+ - RUBY_PLATFORM="x86_64-linux"
11
+ - RUBY_PLATFORM="x86_64-darwin11.3.0"
12
+ before_script:
13
+ - bin/mingle_cli.rb config --username=test --hostname=test --password=test --hostname=test.local
14
+ matrix:
15
+ allow_failures:
16
+ - rvm: ruby-head
17
+ notifications:
18
+ email:
19
+ recipients:
20
+ - ike18t@gmail.com
21
+ on_success: change
22
+ on_failure: change
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :test do
6
+ gem 'pry'
7
+ gem 'autotest-standalone'
8
+ gem 'autotest-growl'
9
+ gem 'coveralls'
10
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Isaac Datlof
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,18 @@
1
+ [![Build Status](https://travis-ci.org/ike18t/mingle_cli.png?branch=master)](https://travis-ci.org/ike18t/mingle_cli)
2
+ [![Code Climate](https://codeclimate.com/github/ike18t/mingle_cli.png)](https://codeclimate.com/github/ike18t/mingle_cli)
3
+ [![Coverage Status](https://coveralls.io/repos/ike18t/mingle_cli/badge.png?branch=master)](https://coveralls.io/r/ike18t/mingle_cli?branch=master)
4
+ [![Dependency Status](https://gemnasium.com/ike18t/mingle_cli.png)](https://gemnasium.com/ike18t/mingle_cli)
5
+
6
+ MingleCLI
7
+ =========
8
+ Command line interface to Mingle's API.
9
+
10
+ Use bundler to install dependencies.
11
+
12
+ **Usage**
13
+
14
+ `mingle_cli.rb card \<number\> \<format\>`
15
+
16
+ `mingle_cli.rb cards \<filter\> \<format\>`
17
+
18
+ `mingle_cli.rb comments \<number\>`
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rspec/core/rake_task'
4
+ require "bundler/gem_tasks"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task :default => :spec
data/bin/mingle_cli.rb ADDED
@@ -0,0 +1,114 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'mingle_cli'
5
+ require 'main'
6
+
7
+ module MingleCLI
8
+ Main {
9
+ mode :configure do
10
+ option(:hostname) {
11
+ argument :optional
12
+ description 'Set the server hostname used to access mingle'
13
+ }
14
+
15
+ option(:username) {
16
+ argument :optional
17
+ description 'Set the username used to access mingle'
18
+ }
19
+
20
+ option(:password) {
21
+ argument :optional
22
+ description 'Set the password used to access mingle'
23
+ }
24
+
25
+ option(:project) {
26
+ argument :optional
27
+ description 'Set the project to use to access cards in mingle'
28
+ }
29
+
30
+ def run
31
+ updated = params.select(&:given?)
32
+ updated = updated.inject({}) do |result, p|
33
+ result[p.name.to_sym] = p.value
34
+ result
35
+ end
36
+ ConfigService.update updated
37
+ end
38
+
39
+ mode :view do
40
+ puts ConfigService.get.inspect
41
+ description 'Quick view of the current config'
42
+ end
43
+ end
44
+
45
+ mode :card do
46
+ description 'Get card info'
47
+
48
+ argument(:number) {
49
+ argument :required
50
+ cast :int
51
+ description 'Number of the card to lookup.'
52
+ }
53
+
54
+ argument(:format) {
55
+ argument :required
56
+ cast :string
57
+ description 'Format of the response, enclose desired return properties in brackets.'
58
+ }
59
+
60
+ option(:comments) {
61
+ description 'View comments for the given card number.'
62
+ }
63
+
64
+ def run
65
+ card = Card.find(params[:number].value)
66
+ puts card.format(params[:format].value)
67
+ end
68
+ end
69
+
70
+ mode :cards do
71
+ description 'Get cards by filter'
72
+
73
+ argument(:filter) {
74
+ argument :required
75
+ cast :string
76
+ description 'MQL filter. Example: Status is "in development"'
77
+ }
78
+
79
+ argument(:format) {
80
+ argument :required
81
+ cast :string
82
+ description 'Format of the response, enclose desired return properties in brackets.'
83
+ }
84
+
85
+ def run
86
+ cards = Card.find(:all, :params => { :filters => { :mql => params[:filter].value } } )
87
+ cards.each do |card|
88
+ puts card.format(params[:format].value)
89
+ end
90
+ end
91
+ end
92
+
93
+ mode :comments do
94
+ description 'Get comments for a card.'
95
+
96
+ argument(:number) {
97
+ argument :required
98
+ cast :int
99
+ description 'Number of the card to lookup.'
100
+ }
101
+
102
+ def run
103
+ card = Card.find(params[:number].value)
104
+ card.comments.sort.each do |comment|
105
+ puts "#{comment.created_at} #{comment.created_by.name}: #{comment.content}"
106
+ end
107
+ end
108
+ end
109
+
110
+ def run
111
+ puts 'Please use a mode. See help for more details'
112
+ end
113
+ }
114
+ end
data/lib/mingle_cli.rb ADDED
@@ -0,0 +1,8 @@
1
+ require 'active_resource'
2
+ autoload :AppConfig, 'models/app_config'
3
+ autoload :ConfigService, 'services/config_service'
4
+ autoload :UrlGenerator, 'services/url_generator'
5
+ autoload :MingleModel, 'models/mingle_model'
6
+ autoload :Formattable, 'services/formattable'
7
+ autoload :Comment, 'models/comment'
8
+ autoload :Card, 'models/card'
@@ -0,0 +1,21 @@
1
+ require 'aescrypt'
2
+ require 'base64'
3
+
4
+ class AppConfig
5
+ attr_accessor :hostname, :username, :password, :project
6
+
7
+ def initialize args={}
8
+ args.each { |arg, val| self.send("#{arg}=", val) }
9
+ end
10
+
11
+ PASSWORD_KEY = 'secret_key'
12
+
13
+ def password= value
14
+ @password = AESCrypt.encrypt(value, PASSWORD_KEY)
15
+ end
16
+
17
+ def password
18
+ return nil if @password.nil?
19
+ AESCrypt.decrypt(@password, PASSWORD_KEY)
20
+ end
21
+ end
@@ -0,0 +1,9 @@
1
+ class Card < MingleModel
2
+ include Formattable
3
+
4
+ has_many :comments
5
+
6
+ def id
7
+ self.number
8
+ end
9
+ end
@@ -0,0 +1,7 @@
1
+ class Comment < MingleModel
2
+ self.site = UrlGenerator.generate + '/cards/:card_id'
3
+
4
+ def <=> next_up
5
+ self.created_at <=> next_up.created_at
6
+ end
7
+ end
@@ -0,0 +1,30 @@
1
+ require 'active_resource'
2
+
3
+ class MingleModel < ActiveResource::Base
4
+ self.format = :xml
5
+ self.site = UrlGenerator.generate
6
+
7
+ def method_missing method_name, *args
8
+ super method_name, *args
9
+ rescue NoMethodError
10
+ match = get_attribute_value(method_name)
11
+ match = get_property_value(method_name) if match.nil? and self.respond_to?(:properties)
12
+
13
+ raise if match.nil?
14
+ match
15
+ end
16
+
17
+ def get_attribute_value name
18
+ self.attributes[key_encode(name)]
19
+ end
20
+
21
+ def get_property_value name
22
+ property = self.properties.select{ |prop| key_encode(prop.name) == key_encode(name) }.first
23
+ property.value || 'not set' unless property.nil?
24
+ end
25
+
26
+ private
27
+ def key_encode string
28
+ string.downcase.to_s.gsub('_', ' ')
29
+ end
30
+ end
@@ -0,0 +1,30 @@
1
+ require 'yaml'
2
+
3
+ class ConfigService
4
+ def self.update updates
5
+ updates.each do |key, value|
6
+ get.send("#{key}=", value)
7
+ end
8
+ save!
9
+ end
10
+
11
+ def self.get
12
+ @config ||= (read() || AppConfig.new)
13
+ end
14
+
15
+ protected
16
+ FILENAME = '.config'
17
+
18
+ def self.save!
19
+ File.open(FILENAME, 'w+') do |f|
20
+ f.write get.to_yaml
21
+ end
22
+ end
23
+
24
+ def self.read
25
+ config_data = File.read(FILENAME)
26
+ YAML::load(config_data)
27
+ rescue Errno::ENOENT
28
+ nil
29
+ end
30
+ end
@@ -0,0 +1,7 @@
1
+ module Formattable
2
+ def format string
3
+ string.scan(/\[([^\]]*)\]/).flatten.inject(string) do |string, prop|
4
+ string.gsub("[#{prop}]", self.send(prop).to_s)
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,8 @@
1
+ class UrlGenerator
2
+ SITE = 'http://%s:%s@%s/api/v2/projects/%s'
3
+
4
+ def self.generate
5
+ config = ConfigService.get
6
+ SITE % [config.username, config.password, config.hostname, config.project]
7
+ end
8
+ end
data/lib/version.rb ADDED
@@ -0,0 +1,3 @@
1
+ module MingleCLI
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,31 @@
1
+ $LOAD_PATH.unshift(File.expand_path('../lib', __FILE__))
2
+
3
+ require 'version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'mingle_cli'
7
+ spec.version = MingleCLI::VERSION
8
+ spec.platform = Gem::Platform::RUBY
9
+ spec.required_ruby_version = '>= 1.9.2'
10
+ spec.authors = ['Isaac Datlof']
11
+ spec.email = 'ike18t@gmail.com'
12
+
13
+ spec.homepage = 'http://github.com/ike18t/mingle_cli'
14
+ spec.license = 'MIT'
15
+ spec.summary = 'Command line interface to Mingle.'
16
+ spec.description = 'Command line interface to Mingle.'
17
+
18
+ spec.files = `git ls-files`.split($/)
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.executables = spec.files.grep(/^bin\//) { |f| File.basename(f) }
21
+ spec.extra_rdoc_files = ['LICENSE.txt', 'README.md']
22
+ spec.require_paths = ['lib']
23
+
24
+ spec.add_runtime_dependency('activeresource', '~> 4.0')
25
+ spec.add_runtime_dependency('main', '~> 5.2')
26
+ spec.add_runtime_dependency('aescrypt', '~> 1.0')
27
+ spec.add_development_dependency('rake', '~> 10.1')
28
+ spec.add_development_dependency('rspec', '~> 2.14')
29
+ spec.add_development_dependency('mocha', '~> 0.14')
30
+ spec.add_development_dependency('fakeweb', '~> 1.3')
31
+ end
@@ -0,0 +1,144 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <card>
3
+ <name>Card Name 19480</name>
4
+ <description>This is a card description</description>
5
+ <card_type url="http://mingle.local/api/v2/projects/test_project/card_types/828.xml">
6
+ <name>Card</name>
7
+ </card_type>
8
+ <id type="integer">173599</id>
9
+ <number type="integer">19480</number>
10
+ <project url="http://mingle.local/api/v2/projects/test_project.xml">
11
+ <name>test_project</name>
12
+ <identifier>test_project</identifier>
13
+ </project>
14
+ <version type="integer">12</version>
15
+ <project_card_rank type="integer">1182</project_card_rank>
16
+ <created_on type="datetime">2013-04-01T21:36:52Z</created_on>
17
+ <modified_on type="datetime">2013-04-11T20:56:03Z</modified_on>
18
+ <modified_by url="http://mingle.local/api/v2/users/574.xml">
19
+ <name>Homer Simpson</name>
20
+ <login>hsimpson</login>
21
+ </modified_by>
22
+ <created_by url="http://mingle.local/api/v2/users/574.xml">
23
+ <name>Homer Simpson</name>
24
+ <login>hsimpson</login>
25
+ </created_by>
26
+ <properties type="array">
27
+ <property type_description="Managed text list" hidden="false">
28
+ <name>Status</name>
29
+ <value>In Development</value>
30
+ </property>
31
+ <property type_description="Managed text list" hidden="false">
32
+ <name>Priority to Deliver</name>
33
+ <value nil="true"></value>
34
+ </property>
35
+ <property type_description="Managed number list" hidden="false">
36
+ <name>Commitment Estimate</name>
37
+ <value>0.25</value>
38
+ </property>
39
+ <property type_description="Managed text list" hidden="false">
40
+ <name>Committed</name>
41
+ <value>No</value>
42
+ </property>
43
+ <property type_description="Any text" hidden="false">
44
+ <name>Hangover from</name>
45
+ <value nil="true"></value>
46
+ </property>
47
+ <property type_description="Managed text list" hidden="false">
48
+ <name>Team</name>
49
+ <value>Atoms</value>
50
+ </property>
51
+ <property type_description="Managed text list" hidden="false">
52
+ <name>Release</name>
53
+ <value>1.112 - 5/3/2013</value>
54
+ </property>
55
+ <property type_description="Automatically generated from the team list" hidden="false">
56
+ <name>Application Owner</name>
57
+ <value nil="true"></value>
58
+ </property>
59
+ <property type_description="Automatically generated from the team list" hidden="false">
60
+ <name>Analyst</name>
61
+ <value nil="true"></value>
62
+ </property>
63
+ <property type_description="Managed text list" hidden="false">
64
+ <name>Dev Pair</name>
65
+ <value>Homer/Bart</value>
66
+ </property>
67
+ <property type_description="Date" hidden="true">
68
+ <name>Moved to Complete - IN PRODUCTION on</name>
69
+ <value nil="true"></value>
70
+ </property>
71
+ <property type_description="Card" hidden="true">
72
+ <name>Iteration Added to Scope</name>
73
+ <value nil="true"></value>
74
+ </property>
75
+ <property type_description="Date" hidden="true">
76
+ <name>Moved to New on</name>
77
+ <value nil="true"></value>
78
+ </property>
79
+ <property type_description="Managed text list" hidden="false">
80
+ <name>Data Collection</name>
81
+ <value nil="true"></value>
82
+ </property>
83
+ <property type_description="Managed text list" hidden="false">
84
+ <name>UI Dev Contact</name>
85
+ <value nil="true"></value>
86
+ </property>
87
+ <property type_description="Managed text list" hidden="false">
88
+ <name>UX Contact</name>
89
+ <value nil="true"></value>
90
+ </property>
91
+ <property type_description="Managed text list" hidden="false">
92
+ <name>Related cards</name>
93
+ <value nil="true"></value>
94
+ </property>
95
+ <property type_description="Automatically generated from the team list" hidden="false">
96
+ <name>Tester</name>
97
+ <value nil="true"></value>
98
+ </property>
99
+ <property type_description="Managed number list" hidden="false">
100
+ <name>Dev Pts Estimate</name>
101
+ <value>0.25</value>
102
+ </property>
103
+ <property type_description="Managed text list" hidden="false">
104
+ <name>Business Approval</name>
105
+ <value nil="true"></value>
106
+ </property>
107
+ <property type_description="Card" hidden="false">
108
+ <name>Iteration Card</name>
109
+ <value url="http://mingle.local/api/v2/projects/test_project/cards/14.xml">
110
+ <number type="integer">14</number>
111
+ </value>
112
+ </property>
113
+ <property type_description="Managed text list" hidden="false">
114
+ <name>Dev Tasked by</name>
115
+ <value nil="true"></value>
116
+ </property>
117
+ <property type_description="Managed text list" hidden="false">
118
+ <name>Generic Managed Text List</name>
119
+ <value nil="true"></value>
120
+ </property>
121
+ <property type_description="Any card used in tree" hidden="false">
122
+ <name>Iteration</name>
123
+ <value nil="true"></value>
124
+ </property>
125
+ <property type_description="Any card used in tree" hidden="false">
126
+ <name>Initiative</name>
127
+ <value url="http://mingle.local/api/v2/projects/test_project/cards/19295.xml">
128
+ <number type="integer">19295</number>
129
+ </value>
130
+ </property>
131
+ <property type_description="Any card used in tree" hidden="false">
132
+ <name>UX</name>
133
+ <value nil="true"></value>
134
+ </property>
135
+ <property type_description="Any card used in tree" hidden="false">
136
+ <name>Feature</name>
137
+ <value nil="true"></value>
138
+ </property>
139
+ </properties>
140
+ <tags>
141
+ </tags>
142
+ <rendered_description url="http://mingle.local/api/v2/projects/test_project/render?content_provider%5Bid%5D=173599&amp;content_provider%5Btype%5D=card">
143
+ </rendered_description>
144
+ </card>
@@ -0,0 +1,19 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <card_comments type="array">
3
+ <comment>
4
+ <content>Blocked waiting for tests to gather numbers from card #20012</content>
5
+ <created_by url="http://mingle.ove.local/api/v2/users/574.xml">
6
+ <name>Homer Simpson</name>
7
+ <login>hsimpson</login>
8
+ </created_by>
9
+ <created_at type="datetime">2013-06-12T14:47:51Z</created_at>
10
+ </comment>
11
+ <comment>
12
+ <content>Waiting on decisions from business about how search will work going forward.</content>
13
+ <created_by url="http://mingle.ove.local/api/v2/users/574.xml">
14
+ <name>Homer Simpson</name>
15
+ <login>hsimpson</login>
16
+ </created_by>
17
+ <created_at type="datetime">2013-05-22T13:22:56Z</created_at>
18
+ </comment>
19
+ </card_comments>
@@ -0,0 +1,289 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <cards type="array">
3
+ <card>
4
+ <name>Card Name 18590</name>
5
+ <description>This is a card description</description>
6
+ <card_type url="http://mingle.local/api/v2/projects/test_project/card_types/828.xml">
7
+ <name>Card</name>
8
+ </card_type>
9
+ <id type="integer">173599</id>
10
+ <number type="integer">18590</number>
11
+ <project url="http://mingle.local/api/v2/projects/test_project.xml">
12
+ <name>test_project</name>
13
+ <identifier>test_project</identifier>
14
+ </project>
15
+ <version type="integer">12</version>
16
+ <project_card_rank type="integer">1182</project_card_rank>
17
+ <created_on type="datetime">2013-04-01T21:36:52Z</created_on>
18
+ <modified_on type="datetime">2013-04-11T20:56:03Z</modified_on>
19
+ <modified_by url="http://mingle.local/api/v2/users/574.xml">
20
+ <name>Homer Simpson</name>
21
+ <login>hsimpson</login>
22
+ </modified_by>
23
+ <created_by url="http://mingle.local/api/v2/users/574.xml">
24
+ <name>Homer Simpson</name>
25
+ <login>hsimpson</login>
26
+ </created_by>
27
+ <properties type="array">
28
+ <property type_description="Managed text list" hidden="false">
29
+ <name>Status</name>
30
+ <value>In Development</value>
31
+ </property>
32
+ <property type_description="Managed text list" hidden="false">
33
+ <name>Priority to Deliver</name>
34
+ <value nil="true"></value>
35
+ </property>
36
+ <property type_description="Managed number list" hidden="false">
37
+ <name>Commitment Estimate</name>
38
+ <value>0.25</value>
39
+ </property>
40
+ <property type_description="Managed text list" hidden="false">
41
+ <name>Committed</name>
42
+ <value>No</value>
43
+ </property>
44
+ <property type_description="Any text" hidden="false">
45
+ <name>Hangover from</name>
46
+ <value nil="true"></value>
47
+ </property>
48
+ <property type_description="Managed text list" hidden="false">
49
+ <name>Team</name>
50
+ <value>Atoms</value>
51
+ </property>
52
+ <property type_description="Managed text list" hidden="false">
53
+ <name>Release</name>
54
+ <value>1.112 - 5/3/2013</value>
55
+ </property>
56
+ <property type_description="Automatically generated from the team list" hidden="false">
57
+ <name>Application Owner</name>
58
+ <value nil="true"></value>
59
+ </property>
60
+ <property type_description="Automatically generated from the team list" hidden="false">
61
+ <name>Analyst</name>
62
+ <value nil="true"></value>
63
+ </property>
64
+ <property type_description="Managed text list" hidden="false">
65
+ <name>Dev Pair</name>
66
+ <value>Homer/Bart</value>
67
+ </property>
68
+ <property type_description="Date" hidden="true">
69
+ <name>Moved to Complete - IN PRODUCTION on</name>
70
+ <value nil="true"></value>
71
+ </property>
72
+ <property type_description="Card" hidden="true">
73
+ <name>Iteration Added to Scope</name>
74
+ <value nil="true"></value>
75
+ </property>
76
+ <property type_description="Date" hidden="true">
77
+ <name>Moved to New on</name>
78
+ <value nil="true"></value>
79
+ </property>
80
+ <property type_description="Managed text list" hidden="false">
81
+ <name>Data Collection</name>
82
+ <value nil="true"></value>
83
+ </property>
84
+ <property type_description="Managed text list" hidden="false">
85
+ <name>UI Dev Contact</name>
86
+ <value nil="true"></value>
87
+ </property>
88
+ <property type_description="Managed text list" hidden="false">
89
+ <name>UX Contact</name>
90
+ <value nil="true"></value>
91
+ </property>
92
+ <property type_description="Managed text list" hidden="false">
93
+ <name>Related cards</name>
94
+ <value nil="true"></value>
95
+ </property>
96
+ <property type_description="Automatically generated from the team list" hidden="false">
97
+ <name>Tester</name>
98
+ <value nil="true"></value>
99
+ </property>
100
+ <property type_description="Managed number list" hidden="false">
101
+ <name>Dev Pts Estimate</name>
102
+ <value>0.25</value>
103
+ </property>
104
+ <property type_description="Managed text list" hidden="false">
105
+ <name>Business Approval</name>
106
+ <value nil="true"></value>
107
+ </property>
108
+ <property type_description="Card" hidden="false">
109
+ <name>Iteration Card</name>
110
+ <value url="http://mingle.local/api/v2/projects/test_project/cards/14.xml">
111
+ <number type="integer">14</number>
112
+ </value>
113
+ </property>
114
+ <property type_description="Managed text list" hidden="false">
115
+ <name>Dev Tasked by</name>
116
+ <value nil="true"></value>
117
+ </property>
118
+ <property type_description="Managed text list" hidden="false">
119
+ <name>Generic Managed Text List</name>
120
+ <value nil="true"></value>
121
+ </property>
122
+ <property type_description="Any card used in tree" hidden="false">
123
+ <name>Iteration</name>
124
+ <value nil="true"></value>
125
+ </property>
126
+ <property type_description="Any card used in tree" hidden="false">
127
+ <name>Initiative</name>
128
+ <value url="http://mingle.local/api/v2/projects/test_project/cards/19295.xml">
129
+ <number type="integer">19295</number>
130
+ </value>
131
+ </property>
132
+ <property type_description="Any card used in tree" hidden="false">
133
+ <name>UX</name>
134
+ <value nil="true"></value>
135
+ </property>
136
+ <property type_description="Any card used in tree" hidden="false">
137
+ <name>Feature</name>
138
+ <value nil="true"></value>
139
+ </property>
140
+ </properties>
141
+ <tags>
142
+ </tags>
143
+ <rendered_description url="http://mingle.local/api/v2/projects/test_project/render?content_provider%5Bid%5D=173599&amp;content_provider%5Btype%5D=card">
144
+ </rendered_description>
145
+ </card>
146
+ <card>
147
+ <name>Card Name 19480</name>
148
+ <description>This is a card description</description>
149
+ <card_type url="http://mingle.local/api/v2/projects/test_project/card_types/828.xml">
150
+ <name>Card</name>
151
+ </card_type>
152
+ <id type="integer">173599</id>
153
+ <number type="integer">19480</number>
154
+ <project url="http://mingle.local/api/v2/projects/test_project.xml">
155
+ <name>test_project</name>
156
+ <identifier>test_project</identifier>
157
+ </project>
158
+ <version type="integer">12</version>
159
+ <project_card_rank type="integer">1182</project_card_rank>
160
+ <created_on type="datetime">2013-04-01T21:36:52Z</created_on>
161
+ <modified_on type="datetime">2013-04-11T20:56:03Z</modified_on>
162
+ <modified_by url="http://mingle.local/api/v2/users/574.xml">
163
+ <name>Homer Simpson</name>
164
+ <login>hsimpson</login>
165
+ </modified_by>
166
+ <created_by url="http://mingle.local/api/v2/users/574.xml">
167
+ <name>Homer Simpson</name>
168
+ <login>hsimpson</login>
169
+ </created_by>
170
+ <properties type="array">
171
+ <property type_description="Managed text list" hidden="false">
172
+ <name>Status</name>
173
+ <value>In Development</value>
174
+ </property>
175
+ <property type_description="Managed text list" hidden="false">
176
+ <name>Priority to Deliver</name>
177
+ <value nil="true"></value>
178
+ </property>
179
+ <property type_description="Managed number list" hidden="false">
180
+ <name>Commitment Estimate</name>
181
+ <value>0.25</value>
182
+ </property>
183
+ <property type_description="Managed text list" hidden="false">
184
+ <name>Committed</name>
185
+ <value>No</value>
186
+ </property>
187
+ <property type_description="Any text" hidden="false">
188
+ <name>Hangover from</name>
189
+ <value nil="true"></value>
190
+ </property>
191
+ <property type_description="Managed text list" hidden="false">
192
+ <name>Team</name>
193
+ <value>Atoms</value>
194
+ </property>
195
+ <property type_description="Managed text list" hidden="false">
196
+ <name>Release</name>
197
+ <value>1.112 - 5/3/2013</value>
198
+ </property>
199
+ <property type_description="Automatically generated from the team list" hidden="false">
200
+ <name>Application Owner</name>
201
+ <value nil="true"></value>
202
+ </property>
203
+ <property type_description="Automatically generated from the team list" hidden="false">
204
+ <name>Analyst</name>
205
+ <value nil="true"></value>
206
+ </property>
207
+ <property type_description="Managed text list" hidden="false">
208
+ <name>Dev Pair</name>
209
+ <value>Homer/Bart</value>
210
+ </property>
211
+ <property type_description="Date" hidden="true">
212
+ <name>Moved to Complete - IN PRODUCTION on</name>
213
+ <value nil="true"></value>
214
+ </property>
215
+ <property type_description="Card" hidden="true">
216
+ <name>Iteration Added to Scope</name>
217
+ <value nil="true"></value>
218
+ </property>
219
+ <property type_description="Date" hidden="true">
220
+ <name>Moved to New on</name>
221
+ <value nil="true"></value>
222
+ </property>
223
+ <property type_description="Managed text list" hidden="false">
224
+ <name>Data Collection</name>
225
+ <value nil="true"></value>
226
+ </property>
227
+ <property type_description="Managed text list" hidden="false">
228
+ <name>UI Dev Contact</name>
229
+ <value nil="true"></value>
230
+ </property>
231
+ <property type_description="Managed text list" hidden="false">
232
+ <name>UX Contact</name>
233
+ <value nil="true"></value>
234
+ </property>
235
+ <property type_description="Managed text list" hidden="false">
236
+ <name>Related cards</name>
237
+ <value nil="true"></value>
238
+ </property>
239
+ <property type_description="Automatically generated from the team list" hidden="false">
240
+ <name>Tester</name>
241
+ <value nil="true"></value>
242
+ </property>
243
+ <property type_description="Managed number list" hidden="false">
244
+ <name>Dev Pts Estimate</name>
245
+ <value>0.25</value>
246
+ </property>
247
+ <property type_description="Managed text list" hidden="false">
248
+ <name>Business Approval</name>
249
+ <value nil="true"></value>
250
+ </property>
251
+ <property type_description="Card" hidden="false">
252
+ <name>Iteration Card</name>
253
+ <value url="http://mingle.local/api/v2/projects/test_project/cards/14.xml">
254
+ <number type="integer">14</number>
255
+ </value>
256
+ </property>
257
+ <property type_description="Managed text list" hidden="false">
258
+ <name>Dev Tasked by</name>
259
+ <value nil="true"></value>
260
+ </property>
261
+ <property type_description="Managed text list" hidden="false">
262
+ <name>Generic Managed Text List</name>
263
+ <value nil="true"></value>
264
+ </property>
265
+ <property type_description="Any card used in tree" hidden="false">
266
+ <name>Iteration</name>
267
+ <value nil="true"></value>
268
+ </property>
269
+ <property type_description="Any card used in tree" hidden="false">
270
+ <name>Initiative</name>
271
+ <value url="http://mingle.local/api/v2/projects/test_project/cards/19295.xml">
272
+ <number type="integer">19295</number>
273
+ </value>
274
+ </property>
275
+ <property type_description="Any card used in tree" hidden="false">
276
+ <name>UX</name>
277
+ <value nil="true"></value>
278
+ </property>
279
+ <property type_description="Any card used in tree" hidden="false">
280
+ <name>Feature</name>
281
+ <value nil="true"></value>
282
+ </property>
283
+ </properties>
284
+ <tags>
285
+ </tags>
286
+ <rendered_description url="http://mingle.local/api/v2/projects/test_project/render?content_provider%5Bid%5D=173599&amp;content_provider%5Btype%5D=card">
287
+ </rendered_description>
288
+ </card>
289
+ </cards>
@@ -0,0 +1,15 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+ require 'rspec'
4
+ require 'mocha/api'
5
+ require 'pry'
6
+ require 'autotest'
7
+ require 'coveralls'
8
+ require 'fakeweb'
9
+ require 'mingle_cli'
10
+
11
+ Coveralls.wear!
12
+
13
+ FakeWeb.register_uri(:get, %r|cards.xml|, :body => File.read('spec/fixtures/cards.xml'))
14
+ FakeWeb.register_uri(:get, %r|19480.xml|, :body => File.read('spec/fixtures/19480.xml'))
15
+ FakeWeb.register_uri(:get, %r|19480/comments.xml|, :body => File.read('spec/fixtures/19480_comments.xml'))
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe AppConfig do
4
+ it 'should update attributes with the values passed into initialize' do
5
+ username, password, hostname, project = 'ike', 'password1', 'http://bah', 'ove'
6
+ config = AppConfig.new :username => username, :password => password, :hostname => hostname, :project => project
7
+ config.username.should eq(username)
8
+ config.password.should eq(password)
9
+ config.hostname.should eq(hostname)
10
+ config.project.should eq(project)
11
+ end
12
+
13
+ it 'should have blank values if nothing passed in on intialization' do
14
+ config = AppConfig.new
15
+ config.username.should be_nil
16
+ config.password.should be_nil
17
+ config.hostname.should be_nil
18
+ config.project.should be_nil
19
+ end
20
+
21
+ it 'should update password instance variable with the encrypted hash' do
22
+ password = 'password1'
23
+ config = AppConfig.new :password => password
24
+ config.instance_variable_get('@password').should eq(AESCrypt.encrypt(password, AppConfig::PASSWORD_KEY))
25
+ end
26
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ describe Card do
4
+ before do
5
+ @card = Card.find(19480)
6
+ end
7
+
8
+ context 'should pull properties' do
9
+ it { @card.status.should eq('In Development') }
10
+ it { @card.dev_pair.should eq('Homer/Bart') }
11
+
12
+ it { Proc.new{@card.nonexistent_property }.should raise_error(NoMethodError) }
13
+ end
14
+
15
+ it { @card.id.should eq(19480) }
16
+ end
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ describe Comment do
4
+ before do
5
+ @card = Card.find(19480)
6
+ @comments = @card.comments
7
+ end
8
+
9
+ context 'should pull attributes' do
10
+ it { @comments.first.created_by.name.should eq('Homer Simpson') }
11
+
12
+ it { Proc.new{@comments.first.nonexistent_attribute}.should raise_error(NoMethodError) }
13
+ end
14
+
15
+ it 'should sort comments by created_on date' do
16
+ older, newer = Comment.new, Comment.new
17
+ older.created_at = Date.parse('2001-02-03')
18
+ newer.created_at = Date.parse('2005-02-03')
19
+ comments = [newer, older]
20
+ comments.sort.should eq([older, newer])
21
+ end
22
+ end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ describe MingleModel do
4
+ context 'with attributes' do
5
+ before do
6
+ @mingle = MingleModel.new
7
+ @mingle.attributes = { 'foo' => 'bar', 'bizz' => 'buzz' }
8
+ end
9
+
10
+ it { @mingle.foo.should eq('bar') }
11
+
12
+ it { @mingle.bizz.should eq('buzz') }
13
+ end
14
+
15
+ context 'with properties' do
16
+ before do
17
+ @mingle = MingleModel.new
18
+ @mingle.properties = [ OpenStruct.new({ :name => 'foo', :value => 'bar' }), OpenStruct.new({ :name => 'bizz', :value => 'buzz' }), OpenStruct.new({ :name => 'bah', :value => nil }) ]
19
+ end
20
+
21
+ it { @mingle.foo.should eq('bar') }
22
+
23
+ it { @mingle.bizz.should eq('buzz') }
24
+
25
+ it { @mingle.bah.should eq('not set') }
26
+ end
27
+
28
+ it { expect { MingleModel.new.invalid_method }.to raise_error(NoMethodError) }
29
+
30
+ context 'key encode' do
31
+ before do
32
+ @mingle = MingleModel.new
33
+ @mingle.properties = [ OpenStruct.new({ :name => 'Foo Bar', :value => 'bar' }) ]
34
+ end
35
+
36
+ it { @mingle.foo_bar.should eq('bar') }
37
+ end
38
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe ConfigService do
4
+ before do
5
+ ConfigService.stubs(:save!)
6
+ ConfigService.stubs(:read).returns(AppConfig.new)
7
+ end
8
+
9
+ context 'update' do
10
+ it 'should update config model with hash values passed to update' do
11
+ updates = { :username => 'ike' }
12
+ ConfigService.update updates
13
+ config = ConfigService.get
14
+ config.username.should eq(updates[:username])
15
+ end
16
+
17
+ it { expect { ConfigService.update({ :username1 => 'ike' }) }.to raise_error(NoMethodError) }
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe Formattable do
4
+ before do
5
+ @card = Card.find 19480
6
+ @card.extend Formattable
7
+ end
8
+
9
+ it { @card.format('no attributes here').should eq('no attributes here') }
10
+
11
+ it { @card.status.should eq(@card.format('[status]')) }
12
+
13
+ it { @card.format('name is [name], status is [status]').should eq("name is #{@card.name}, status is #{@card.status}") }
14
+
15
+ it { expect { @card.format('[not invalid] is invalid') }.to raise_error(NoMethodError) }
16
+
17
+ it { @card.format('').should be_empty }
18
+
19
+ end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe UrlGenerator do
4
+ it 'return formatted url' do
5
+ config = AppConfig.new :username => 'username', :password => 'password', :hostname => 'hostname', :project => 'project'
6
+ ConfigService.stubs(:get).returns(config)
7
+ url = UrlGenerator.generate
8
+ expected_site = UrlGenerator::SITE % [config.username, config.password, config.hostname, config.project]
9
+ url.should eq(expected_site)
10
+ end
11
+ end
metadata ADDED
@@ -0,0 +1,187 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mingle_cli
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Isaac Datlof
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-01-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activeresource
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '4.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '4.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: main
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '5.2'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '5.2'
41
+ - !ruby/object:Gem::Dependency
42
+ name: aescrypt
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '1.0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '1.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '10.1'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '10.1'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: '2.14'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: '2.14'
83
+ - !ruby/object:Gem::Dependency
84
+ name: mocha
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ version: '0.14'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ~>
95
+ - !ruby/object:Gem::Version
96
+ version: '0.14'
97
+ - !ruby/object:Gem::Dependency
98
+ name: fakeweb
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ~>
102
+ - !ruby/object:Gem::Version
103
+ version: '1.3'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ~>
109
+ - !ruby/object:Gem::Version
110
+ version: '1.3'
111
+ description: Command line interface to Mingle.
112
+ email: ike18t@gmail.com
113
+ executables:
114
+ - mingle_cli.rb
115
+ extensions: []
116
+ extra_rdoc_files:
117
+ - LICENSE.txt
118
+ - README.md
119
+ files:
120
+ - .autotest
121
+ - .bundle/config
122
+ - .gitignore
123
+ - .rspec
124
+ - .ruby-version
125
+ - .travis.yml
126
+ - Gemfile
127
+ - LICENSE.txt
128
+ - README.md
129
+ - Rakefile
130
+ - bin/mingle_cli.rb
131
+ - lib/mingle_cli.rb
132
+ - lib/models/app_config.rb
133
+ - lib/models/card.rb
134
+ - lib/models/comment.rb
135
+ - lib/models/mingle_model.rb
136
+ - lib/services/config_service.rb
137
+ - lib/services/formattable.rb
138
+ - lib/services/url_generator.rb
139
+ - lib/version.rb
140
+ - mingle_cli.gemspec
141
+ - spec/fixtures/19480.xml
142
+ - spec/fixtures/19480_comments.xml
143
+ - spec/fixtures/cards.xml
144
+ - spec/spec_helper.rb
145
+ - spec/unit/models/app_config_spec.rb
146
+ - spec/unit/models/card_spec.rb
147
+ - spec/unit/models/comment_spec.rb
148
+ - spec/unit/models/mingle_model_spec.rb
149
+ - spec/unit/services/config_service_spec.rb
150
+ - spec/unit/services/formattable_spec.rb
151
+ - spec/unit/services/url_generator_spec.rb
152
+ homepage: http://github.com/ike18t/mingle_cli
153
+ licenses:
154
+ - MIT
155
+ metadata: {}
156
+ post_install_message:
157
+ rdoc_options: []
158
+ require_paths:
159
+ - lib
160
+ required_ruby_version: !ruby/object:Gem::Requirement
161
+ requirements:
162
+ - - '>='
163
+ - !ruby/object:Gem::Version
164
+ version: 1.9.2
165
+ required_rubygems_version: !ruby/object:Gem::Requirement
166
+ requirements:
167
+ - - '>='
168
+ - !ruby/object:Gem::Version
169
+ version: '0'
170
+ requirements: []
171
+ rubyforge_project:
172
+ rubygems_version: 2.2.1
173
+ signing_key:
174
+ specification_version: 4
175
+ summary: Command line interface to Mingle.
176
+ test_files:
177
+ - spec/fixtures/19480.xml
178
+ - spec/fixtures/19480_comments.xml
179
+ - spec/fixtures/cards.xml
180
+ - spec/spec_helper.rb
181
+ - spec/unit/models/app_config_spec.rb
182
+ - spec/unit/models/card_spec.rb
183
+ - spec/unit/models/comment_spec.rb
184
+ - spec/unit/models/mingle_model_spec.rb
185
+ - spec/unit/services/config_service_spec.rb
186
+ - spec/unit/services/formattable_spec.rb
187
+ - spec/unit/services/url_generator_spec.rb