ki_pivotal 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.
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ spec/fixtures
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in ki_pivotal.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Ben Brinckerhoff
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,2 @@
1
+ ki_pivotal
2
+ ==========
data/Rakefile ADDED
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+ require 'rspec/core/rake_task'
4
+
5
+ desc 'Default: run specs.'
6
+ task :default => :spec
7
+
8
+ desc "Run specs"
9
+ RSpec::Core::RakeTask.new do |t|
10
+ t.pattern = "./spec/**/*_spec.rb"
11
+ end
12
+
13
+ desc "Generate code coverage"
14
+ RSpec::Core::RakeTask.new("spec:coverage") do |t|
15
+ ENV['COVERAGE'] = "true"
16
+ end
17
+
18
+ desc "Delete *all* VCR cassettes (!)"
19
+ namespace :spec do
20
+ task :vcr_wipe do
21
+ FileUtils.rm_rf('spec/fixtures/vcr_cassettes')
22
+ end
23
+ end
data/bin/ki_pivotal ADDED
@@ -0,0 +1,69 @@
1
+ #!/usr/bin/env ruby
2
+ # 1.9 adds realpath to resolve symlinks; 1.8 doesn't
3
+ # have this method, so we add it so we get resolved symlinks
4
+ # and compatibility
5
+ unless File.respond_to? :realpath
6
+ class File #:nodoc:
7
+ def self.realpath path
8
+ return realpath(File.readlink(path)) if symlink?(path)
9
+ path
10
+ end
11
+ end
12
+ end
13
+
14
+ $LOAD_PATH << File.expand_path(File.dirname(File.realpath(__FILE__)) + '/../lib')
15
+
16
+ require 'rubygems'
17
+ require 'gli'
18
+ require 'ki_pivotal'
19
+ require 'colored'
20
+ include GLI
21
+
22
+ program_desc 'A command-line interface for Pivotal Tracker'
23
+
24
+ version KiPivotal::VERSION
25
+
26
+ desc 'Setup'
27
+ command :setup do |c|
28
+ c.action do |global_options,options,args|
29
+ print "Enter API key> "
30
+ token = $stdin.gets.chomp
31
+ Kiseru::Config[:ki_pivotal].write('api_token', token)
32
+ end
33
+ end
34
+
35
+ desc 'Get projects'
36
+ command :projects do |c|
37
+ c.action do |global_options,options,args|
38
+ pretty = $stdout.tty?
39
+ $stdout.puts KiPivotal::Api.projects(:pretty => pretty)
40
+ end
41
+ end
42
+
43
+ desc 'Create a bug'
44
+ command :story do |c|
45
+ c.flag [:project]
46
+ c.flag [:f, :file]
47
+ c.action do |global_options,options,args|
48
+
49
+ unless project_id = options[:project]
50
+ projects = KiPivotal::Api.projects
51
+
52
+ $stderr.puts "\n Project ID must be specified with --project=<ID>"
53
+ $stderr.puts "\n Available projects:"
54
+
55
+ MultiJson.load(projects).each { |project| $stderr.puts " #{project['id']}".green + " #{project['name']}" }
56
+
57
+ $stderr.puts
58
+ raise "No project ID given"
59
+ end
60
+
61
+ if options[:f]
62
+ story_json = File.read(options[:f])
63
+ end
64
+ story_json ||= $stdin.read
65
+ $stdout.puts KiPivotal::Api.create_story(project_id, story_json)
66
+ end
67
+ end
68
+
69
+ exit GLI.run(ARGV)
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/ki_pivotal/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Ben Brinckerhoff", "Aaron Cronin"]
6
+ gem.email = ["ben@freeagent.com", "aaron@freeagent.com"]
7
+ gem.description = %q{Kiseru Pivotal Tracker client}
8
+ gem.summary = %q{Kiseru Pivotal Tracker client}
9
+ gem.homepage = ""
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "ki_pivotal"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = KiPivotal::VERSION
17
+
18
+ gem.add_dependency 'gli'
19
+ gem.add_dependency 'multi_json'
20
+ gem.add_dependency 'pivotal-tracker'
21
+ gem.add_dependency 'colored'
22
+
23
+ gem.add_development_dependency('debugger')
24
+ gem.add_development_dependency('rake')
25
+ gem.add_development_dependency('simplecov')
26
+ gem.add_development_dependency('rspec')
27
+ gem.add_development_dependency('test-construct')
28
+ gem.add_development_dependency('vcr')
29
+ gem.add_development_dependency('webmock')
30
+ end
@@ -0,0 +1,82 @@
1
+ module KiPivotal
2
+
3
+ class Api
4
+
5
+ # TODO - this is only used internally, unlike the other methods
6
+ # It also doesn't return JSON because it is used internally
7
+ def self.get_token(username, password)
8
+ PivotalTracker::Client.token(username, password)
9
+ end
10
+
11
+ def self.projects(opts = {})
12
+ with_session do
13
+ pretty = opts.fetch(:pretty) { true }
14
+
15
+ projects = PivotalTracker::Project.all
16
+ data = []
17
+ projects.each do |project|
18
+ data <<
19
+ {
20
+ 'id' => project.id,
21
+ 'name' => project.name
22
+ }
23
+ end
24
+ MultiJson.dump(data, :pretty => pretty)
25
+ end
26
+ end
27
+
28
+ def self.create_story(project_id, json)
29
+ from_and_to_json(json, true) do |data|
30
+ with_session do
31
+ data.delete('ki_type')
32
+
33
+ # You must provide current_state or the Pivotal UI will give an error
34
+ defaults = {
35
+ :current_state => 'unscheduled'
36
+ }
37
+
38
+ new_story = add_story_to_project(project_id, defaults.merge(data))
39
+ new_story
40
+ end
41
+ end
42
+ end
43
+
44
+ private
45
+
46
+ # TODO - We need to determine what concerns the API has vs
47
+ # 'lower-level' classes. Right now it's all mixed in. At least we
48
+ # have smallish methods
49
+ # Possible different responsibilities:
50
+ # * change JSON to data
51
+ # * set up session
52
+ # * clean up incoming data (remove fields that don't make sense)
53
+ # * interact with PivotalTracker gem
54
+ # * convert PivotalTracker gem response (object) into data
55
+ # * convert data back into JSON
56
+ def self.add_story_to_project(project_id, data)
57
+ project = PivotalTracker::Project.find(project_id)
58
+ story = project.stories.create(data)
59
+
60
+ created_story = {}
61
+ story.instance_variables.each do |instance_var|
62
+ string_name = instance_var.to_s.gsub('@','')
63
+ created_story[string_name] = story.instance_variable_get(instance_var)
64
+ end
65
+ created_story
66
+ end
67
+
68
+ def self.from_and_to_json(json, pretty=false)
69
+ data = MultiJson.load(json)
70
+ new_data = yield data
71
+ MultiJson.dump(new_data, :pretty => pretty)
72
+ end
73
+
74
+ def self.with_session
75
+ session = Session.new(Kiseru::Config[:ki_pivotal])
76
+ session.init
77
+ yield
78
+ end
79
+
80
+ end
81
+
82
+ end
@@ -0,0 +1,48 @@
1
+ module Kiseru
2
+
3
+ class ConfigDir
4
+
5
+ DIR_NAME = '.kiseru'
6
+
7
+ attr_reader :path
8
+
9
+ def initialize(opts = {})
10
+ root = Pathname.new(File.expand_path(opts.fetch(:root) { '~' }))
11
+ @path = root + DIR_NAME
12
+ unless File.directory?(@path)
13
+ Dir.mkdir(@path)
14
+ end
15
+ end
16
+
17
+ def config(app_name)
18
+ Config.new(@path, app_name)
19
+ end
20
+
21
+ end
22
+
23
+ class Config
24
+
25
+ def self.[](key)
26
+ ConfigDir.new.config(key)
27
+ end
28
+
29
+ def initialize(root_path, app_name)
30
+ file_path = (root_path + "#{app_name}.yml").to_s
31
+ @store = YAML::Store.new(file_path)
32
+ end
33
+
34
+ def write(key, time)
35
+ @store.transaction do
36
+ @store[key] = time
37
+ end
38
+ end
39
+
40
+ def read(key)
41
+ @store.transaction(read_only=true) do
42
+ @store[key]
43
+ end
44
+ end
45
+
46
+ end
47
+
48
+ end
@@ -0,0 +1,16 @@
1
+ module KiPivotal
2
+
3
+ class Session
4
+
5
+ def initialize(config)
6
+ @config = config
7
+ end
8
+
9
+ def init
10
+ PivotalTracker::Client.token = @config.read('api_token')
11
+ end
12
+
13
+ end
14
+
15
+
16
+ end
@@ -0,0 +1,3 @@
1
+ module KiPivotal
2
+ VERSION = "0.0.1"
3
+ end
data/lib/ki_pivotal.rb ADDED
@@ -0,0 +1,14 @@
1
+ require 'yaml/store'
2
+ require 'pivotal-tracker'
3
+ require 'multi_json'
4
+
5
+ require "ki_pivotal/version"
6
+
7
+ autoload :Kiseru, 'ki_pivotal/kiseru'
8
+
9
+ module KiPivotal
10
+
11
+ autoload :Api, 'ki_pivotal/api'
12
+ autoload :Session, 'ki_pivotal/session'
13
+
14
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ include KiPivotal
4
+
5
+ describe KiPivotal::Api do
6
+
7
+ it "returns projects", :vcr do
8
+ json = Api.projects
9
+ projects = MultiJson.load(json)
10
+
11
+ projects.each do |project|
12
+ project['id'].should_not be_nil
13
+ project['name'].should_not be_nil
14
+ end
15
+ end
16
+
17
+ it "creates bugs", :vcr do
18
+ # uses open-source kiseru tracker project
19
+ name = "Something is broken"
20
+
21
+ input_json = MultiJson.dump({ 'ki_type' => 'pivotal_story',
22
+ 'name' => name,
23
+ 'requested_by' => 'Kiseru',
24
+ 'story_type' => 'bug'
25
+ })
26
+ json = Api.create_story(617613, input_json)
27
+ story = MultiJson.load(json)
28
+
29
+ story['id'].should_not be_nil
30
+ story['name'].should == name
31
+ story['story_type'].should == 'bug'
32
+ end
33
+
34
+ end
@@ -0,0 +1,42 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # Require this file using `require "spec_helper"` to ensure that it is only
4
+ # loaded once.
5
+ #
6
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
+
8
+ require 'ki_pivotal'
9
+ require 'construct'
10
+ require 'pp'
11
+ require 'vcr'
12
+
13
+ include Construct::Helpers
14
+
15
+ if [0, 'false', false, 'f', 'n', 'no', 'off'].include?(ENV['VCR'])
16
+ puts "VCR off"
17
+ else
18
+ puts "VCR on!"
19
+ VCR.configure do |c|
20
+ c.cassette_library_dir = 'spec/fixtures/vcr_cassettes'
21
+ c.hook_into :webmock
22
+ c.allow_http_connections_when_no_cassette = true
23
+ c.configure_rspec_metadata!
24
+ end
25
+ end
26
+
27
+ if ENV['COVERAGE']
28
+ require 'simplecov'
29
+ SimpleCov.start
30
+ end
31
+
32
+ RSpec.configure do |config|
33
+ config.treat_symbols_as_metadata_keys_with_true_values = true
34
+ config.run_all_when_everything_filtered = true
35
+ config.filter_run :focus
36
+
37
+ # Run specs in random order to surface order dependencies. If you find an
38
+ # order dependency and want to debug it, you can fix the order by providing
39
+ # the seed, which is printed after each run.
40
+ # --seed 1234
41
+ config.order = 'random'
42
+ end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+
3
+ include KiPivotal
4
+
5
+ describe Kiseru::ConfigDir do
6
+
7
+ context "when directory does not exist" do
8
+
9
+ it "should create directory" do
10
+ within_construct(false) do |c|
11
+ Kiseru::ConfigDir.new(:root => c)
12
+ File.directory?(c+'.kiseru').should be_true
13
+ end
14
+ end
15
+
16
+ end
17
+
18
+ it "creates ki_pivotal.yml and writes API token" do
19
+ within_construct(false) do |c|
20
+ d = c.directory '.kiseru'
21
+ config_dir = Kiseru::ConfigDir.new(:root => c)
22
+ config = config_dir.config(:ki_pivotal)
23
+
24
+ config.write(:api_token, 'fake_token')
25
+
26
+ config.read(:api_token).should == 'fake_token'
27
+ end
28
+ end
29
+
30
+ end
metadata ADDED
@@ -0,0 +1,194 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ki_pivotal
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Ben Brinckerhoff
9
+ - Aaron Cronin
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2012-08-14 00:00:00.000000000Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: gli
17
+ requirement: &70342954522960 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: *70342954522960
26
+ - !ruby/object:Gem::Dependency
27
+ name: multi_json
28
+ requirement: &70342954521720 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: *70342954521720
37
+ - !ruby/object:Gem::Dependency
38
+ name: pivotal-tracker
39
+ requirement: &70342954520800 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ! '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ type: :runtime
46
+ prerelease: false
47
+ version_requirements: *70342954520800
48
+ - !ruby/object:Gem::Dependency
49
+ name: colored
50
+ requirement: &70342954519680 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ type: :runtime
57
+ prerelease: false
58
+ version_requirements: *70342954519680
59
+ - !ruby/object:Gem::Dependency
60
+ name: debugger
61
+ requirement: &70342954518840 !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ! '>='
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ type: :development
68
+ prerelease: false
69
+ version_requirements: *70342954518840
70
+ - !ruby/object:Gem::Dependency
71
+ name: rake
72
+ requirement: &70342954517660 !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ type: :development
79
+ prerelease: false
80
+ version_requirements: *70342954517660
81
+ - !ruby/object:Gem::Dependency
82
+ name: simplecov
83
+ requirement: &70342954516980 !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ! '>='
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ type: :development
90
+ prerelease: false
91
+ version_requirements: *70342954516980
92
+ - !ruby/object:Gem::Dependency
93
+ name: rspec
94
+ requirement: &70342954516480 !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ! '>='
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ type: :development
101
+ prerelease: false
102
+ version_requirements: *70342954516480
103
+ - !ruby/object:Gem::Dependency
104
+ name: test-construct
105
+ requirement: &70342954515800 !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ! '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ type: :development
112
+ prerelease: false
113
+ version_requirements: *70342954515800
114
+ - !ruby/object:Gem::Dependency
115
+ name: vcr
116
+ requirement: &70342954515260 !ruby/object:Gem::Requirement
117
+ none: false
118
+ requirements:
119
+ - - ! '>='
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ type: :development
123
+ prerelease: false
124
+ version_requirements: *70342954515260
125
+ - !ruby/object:Gem::Dependency
126
+ name: webmock
127
+ requirement: &70342954514660 !ruby/object:Gem::Requirement
128
+ none: false
129
+ requirements:
130
+ - - ! '>='
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ type: :development
134
+ prerelease: false
135
+ version_requirements: *70342954514660
136
+ description: Kiseru Pivotal Tracker client
137
+ email:
138
+ - ben@freeagent.com
139
+ - aaron@freeagent.com
140
+ executables:
141
+ - ki_pivotal
142
+ extensions: []
143
+ extra_rdoc_files: []
144
+ files:
145
+ - .gitignore
146
+ - .rspec
147
+ - Gemfile
148
+ - LICENSE
149
+ - README.md
150
+ - Rakefile
151
+ - bin/ki_pivotal
152
+ - ki_pivotal.gemspec
153
+ - lib/ki_pivotal.rb
154
+ - lib/ki_pivotal/api.rb
155
+ - lib/ki_pivotal/kiseru.rb
156
+ - lib/ki_pivotal/session.rb
157
+ - lib/ki_pivotal/version.rb
158
+ - spec/integration/api_spec.rb
159
+ - spec/spec_helper.rb
160
+ - spec/unit/kiseru_spec.rb
161
+ homepage: ''
162
+ licenses: []
163
+ post_install_message:
164
+ rdoc_options: []
165
+ require_paths:
166
+ - lib
167
+ required_ruby_version: !ruby/object:Gem::Requirement
168
+ none: false
169
+ requirements:
170
+ - - ! '>='
171
+ - !ruby/object:Gem::Version
172
+ version: '0'
173
+ segments:
174
+ - 0
175
+ hash: -2523248348125131754
176
+ required_rubygems_version: !ruby/object:Gem::Requirement
177
+ none: false
178
+ requirements:
179
+ - - ! '>='
180
+ - !ruby/object:Gem::Version
181
+ version: '0'
182
+ segments:
183
+ - 0
184
+ hash: -2523248348125131754
185
+ requirements: []
186
+ rubyforge_project:
187
+ rubygems_version: 1.8.10
188
+ signing_key:
189
+ specification_version: 3
190
+ summary: Kiseru Pivotal Tracker client
191
+ test_files:
192
+ - spec/integration/api_spec.rb
193
+ - spec/spec_helper.rb
194
+ - spec/unit/kiseru_spec.rb