pgit 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,48 @@
1
+ #
2
+ # Wrapper for a Pivotal Tracker story
3
+ #
4
+
5
+ module PGit
6
+ class Story
7
+ class << self
8
+ def get(id, current_project)
9
+ @id = id
10
+ @project_id = current_project.id
11
+ @api_token = current_project.api_token
12
+
13
+ define_methods(get!)
14
+
15
+ new
16
+ end
17
+
18
+ def define_methods(json)
19
+ JSON.parse(json).each do |key, value|
20
+ define_method key do
21
+ value
22
+ end
23
+ end
24
+ end
25
+
26
+ def api_version
27
+ "v5"
28
+ end
29
+
30
+ def get!
31
+ request = `#{get_request}`
32
+ if request.match(/error/)
33
+ raise request
34
+ else
35
+ request
36
+ end
37
+ end
38
+
39
+ def link
40
+ "'https://www.pivotaltracker.com/services/#{api_version}/projects/#{@project_id}/stories/#{@id}'"
41
+ end
42
+
43
+ def get_request
44
+ "curl -X GET -H 'X-TrackerToken: #{@api_token}' #{link}"
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,30 @@
1
+ #
2
+ # Used for creating a git branch in relation to a pivotal tracker story.
3
+ #
4
+ # - story_id: the id of the (pivotal tracker) story that you'll be
5
+ # working on
6
+ #
7
+ # - config_yaml: the yaml with the projects. Each project has an api_token,
8
+ # id, and path.
9
+
10
+ module PGit
11
+ class StoryBranch
12
+ attr_reader :id
13
+
14
+ def initialize(name_parser)
15
+ @name_parser = name_parser
16
+ end
17
+
18
+ def start
19
+ `git checkout -b #{name}`
20
+ end
21
+
22
+ def name
23
+ @name_parser.name
24
+ end
25
+
26
+ def id
27
+ @name_parser.story_id
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,19 @@
1
+ module PGit
2
+ class StoryBranch
3
+ class Application
4
+ def initialize(global_options, options, arguments)
5
+ if story_id = options[:start]
6
+ config_yaml = PGit::Configuration.new.to_yaml
7
+ current_project = PGit::CurrentProject.new(config_yaml)
8
+ story = PGit::Story.get(story_id, current_project)
9
+ name_parser = PGit::StoryBranch::NameParser.new(story)
10
+ story_branch = PGit::StoryBranch.new(name_parser)
11
+
12
+ story_branch.start
13
+ else
14
+ puts `pgit story_branch --help`
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,3 @@
1
+ module Pgit
2
+ VERSION = '0.0.2'
3
+ end
@@ -0,0 +1,57 @@
1
+ #
2
+ # Loads the Pivotal-Git configuration file
3
+ #
4
+ # - config_path is the path to the pivotal-git configuration file
5
+ # This loads the file. Throws an error if a key (such as api_token, path, id)
6
+ # is missing. Check #general_error_message for more info
7
+ #
8
+
9
+ module Pivotal
10
+ class Configuration
11
+ def initialize(config_path = '~/.edderic-dotfiles/config/pivotal.yml')
12
+ @expanded_path = File.expand_path(config_path)
13
+ config_file = File.open(@expanded_path, 'r')
14
+ @yaml = YAML.load(config_file)
15
+
16
+ validate_existence_of_at_least_one_project
17
+ validate_presence_of_items_in_each_project
18
+ end
19
+
20
+ def to_yaml
21
+ @yaml
22
+ end
23
+
24
+ private
25
+
26
+ def general_error_message
27
+ "Please have the following layout:\n" +
28
+ "\n" +
29
+ "projects:\n" +
30
+ " - path: ~/some/path/to/a/pivotal-git/project\n" +
31
+ " id: 12345\n" +
32
+ " api_token: somepivotalatoken124"
33
+ end
34
+
35
+ def validate_presence_of_items_in_each_project
36
+ projects = @yaml["projects"]
37
+ all_present = projects.all? do |project|
38
+ project["api_token"] &&
39
+ project["path"] &&
40
+ project["id"]
41
+ end
42
+
43
+ unless all_present
44
+ raise "Error: Must have a path, id, and api_token for each project.\n" +
45
+ general_error_message
46
+ end
47
+ end
48
+
49
+ def validate_existence_of_at_least_one_project
50
+ unless @yaml["projects"]
51
+ raise "Error: #{@expanded_path} needs at least one project.\n" +
52
+ general_error_message
53
+
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,18 @@
1
+ .\" generated with Ronn/v0.7.3
2
+ .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
+ .
4
+ .TH "PGIT" "1" "December 2014" "" ""
5
+ .
6
+ .SH "NAME"
7
+ \fBpgit\fR \- optimize your Pivotal Tracker and Git workflow
8
+ .
9
+ .SH "SYNOPSIS"
10
+ \fBpgit\fR
11
+ .
12
+ .SH "DESCRIPTION"
13
+ \fBpgit\fR is a simple command\-line tool that improves developer workflow\.
14
+ .
15
+ .SH "FILES"
16
+ .
17
+ .SH "EXAMPLES"
18
+
@@ -0,0 +1,96 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta http-equiv='content-type' value='text/html;charset=utf8'>
5
+ <meta name='generator' value='Ronn/v0.7.3 (http://github.com/rtomayko/ronn/tree/0.7.3)'>
6
+ <title>pgit(1) - optimize your Pivotal Tracker and Git workflow</title>
7
+ <style type='text/css' media='all'>
8
+ /* style: man */
9
+ body#manpage {margin:0}
10
+ .mp {max-width:100ex;padding:0 9ex 1ex 4ex}
11
+ .mp p,.mp pre,.mp ul,.mp ol,.mp dl {margin:0 0 20px 0}
12
+ .mp h2 {margin:10px 0 0 0}
13
+ .mp > p,.mp > pre,.mp > ul,.mp > ol,.mp > dl {margin-left:8ex}
14
+ .mp h3 {margin:0 0 0 4ex}
15
+ .mp dt {margin:0;clear:left}
16
+ .mp dt.flush {float:left;width:8ex}
17
+ .mp dd {margin:0 0 0 9ex}
18
+ .mp h1,.mp h2,.mp h3,.mp h4 {clear:left}
19
+ .mp pre {margin-bottom:20px}
20
+ .mp pre+h2,.mp pre+h3 {margin-top:22px}
21
+ .mp h2+pre,.mp h3+pre {margin-top:5px}
22
+ .mp img {display:block;margin:auto}
23
+ .mp h1.man-title {display:none}
24
+ .mp,.mp code,.mp pre,.mp tt,.mp kbd,.mp samp,.mp h3,.mp h4 {font-family:monospace;font-size:14px;line-height:1.42857142857143}
25
+ .mp h2 {font-size:16px;line-height:1.25}
26
+ .mp h1 {font-size:20px;line-height:2}
27
+ .mp {text-align:justify;background:#fff}
28
+ .mp,.mp code,.mp pre,.mp pre code,.mp tt,.mp kbd,.mp samp {color:#131211}
29
+ .mp h1,.mp h2,.mp h3,.mp h4 {color:#030201}
30
+ .mp u {text-decoration:underline}
31
+ .mp code,.mp strong,.mp b {font-weight:bold;color:#131211}
32
+ .mp em,.mp var {font-style:italic;color:#232221;text-decoration:none}
33
+ .mp a,.mp a:link,.mp a:hover,.mp a code,.mp a pre,.mp a tt,.mp a kbd,.mp a samp {color:#0000ff}
34
+ .mp b.man-ref {font-weight:normal;color:#434241}
35
+ .mp pre {padding:0 4ex}
36
+ .mp pre code {font-weight:normal;color:#434241}
37
+ .mp h2+pre,h3+pre {padding-left:0}
38
+ ol.man-decor,ol.man-decor li {margin:3px 0 10px 0;padding:0;float:left;width:33%;list-style-type:none;text-transform:uppercase;color:#999;letter-spacing:1px}
39
+ ol.man-decor {width:100%}
40
+ ol.man-decor li.tl {text-align:left}
41
+ ol.man-decor li.tc {text-align:center;letter-spacing:4px}
42
+ ol.man-decor li.tr {text-align:right;float:right}
43
+ </style>
44
+ </head>
45
+ <!--
46
+ The following styles are deprecated and will be removed at some point:
47
+ div#man, div#man ol.man, div#man ol.head, div#man ol.man.
48
+
49
+ The .man-page, .man-decor, .man-head, .man-foot, .man-title, and
50
+ .man-navigation should be used instead.
51
+ -->
52
+ <body id='manpage'>
53
+ <div class='mp' id='man'>
54
+
55
+ <div class='man-navigation' style='display:none'>
56
+ <a href="#NAME">NAME</a>
57
+ <a href="#SYNOPSIS">SYNOPSIS</a>
58
+ <a href="#DESCRIPTION">DESCRIPTION</a>
59
+ <a href="#FILES">FILES</a>
60
+ <a href="#EXAMPLES">EXAMPLES</a>
61
+ </div>
62
+
63
+ <ol class='man-decor man-head man head'>
64
+ <li class='tl'>pgit(1)</li>
65
+ <li class='tc'></li>
66
+ <li class='tr'>pgit(1)</li>
67
+ </ol>
68
+
69
+ <h2 id="NAME">NAME</h2>
70
+ <p class="man-name">
71
+ <code>pgit</code> - <span class="man-whatis">optimize your Pivotal Tracker and Git workflow</span>
72
+ </p>
73
+
74
+ <h2 id="SYNOPSIS">SYNOPSIS</h2>
75
+
76
+ <p><code>pgit</code></p>
77
+
78
+ <h2 id="DESCRIPTION">DESCRIPTION</h2>
79
+
80
+ <p><strong>pgit</strong> is a simple command-line tool that improves developer
81
+ workflow.</p>
82
+
83
+ <h2 id="FILES">FILES</h2>
84
+
85
+ <h2 id="EXAMPLES">EXAMPLES</h2>
86
+
87
+
88
+ <ol class='man-decor man-foot man foot'>
89
+ <li class='tl'></li>
90
+ <li class='tc'>December 2014</li>
91
+ <li class='tr'>pgit(1)</li>
92
+ </ol>
93
+
94
+ </div>
95
+ </body>
96
+ </html>
@@ -0,0 +1,15 @@
1
+ pgit(1) -- optimize your Pivotal Tracker and Git workflow
2
+ ============================================================
3
+
4
+ ## SYNOPSIS
5
+
6
+ `pgit`
7
+
8
+ ## DESCRIPTION
9
+
10
+ **pgit** is a simple command-line tool that improves developer
11
+ workflow.
12
+
13
+ ## FILES
14
+
15
+ ## EXAMPLES
@@ -0,0 +1,21 @@
1
+ # Ensure we require the local version and not one we might have installed already
2
+ require File.join([File.dirname(__FILE__),'lib','pgit','version.rb'])
3
+ spec = Gem::Specification.new do |s|
4
+ s.name = 'pgit'
5
+ s.version = Pgit::VERSION
6
+ s.author = 'Edderic Ugaddan'
7
+ s.email = 'edderic@gmail.com'
8
+ s.homepage = 'http://edderic.github.io'
9
+ s.platform = Gem::Platform::RUBY
10
+ s.summary = 'Optimize your Pivotal Tracker and Github workflow'
11
+ s.files = `git ls-files`.split("
12
+ ")
13
+ s.require_paths << 'lib'
14
+ s.has_rdoc = true
15
+ s.extra_rdoc_files = ['README.markdown']
16
+ s.rdoc_options << '--title' << 'pgit' << '--main'
17
+ s.bindir = 'bin'
18
+ s.executables << 'pgit'
19
+ s.add_development_dependency('rake')
20
+ s.add_runtime_dependency('gli','2.12.2')
21
+ end
@@ -0,0 +1,5 @@
1
+ = pgit
2
+
3
+ Generate this with
4
+ pgit rdoc
5
+ After you have described your command line interface
@@ -0,0 +1,16 @@
1
+ # require_relative '../../../lib/pgit'
2
+ #
3
+ # describe 'PGit::Application' do
4
+ # describe 'no arguments' do
5
+ # it 'should bring up the usage' do
6
+ # argv = []
7
+ # usage_message = "Usage: pgit\n"\
8
+ # " cob [pivotal-story-id]"
9
+ # error_message = "POOP"
10
+ #
11
+ # expect do
12
+ # PGit::Application.new(argv)
13
+ # end.to raise_error(error_message)
14
+ # end
15
+ # end
16
+ # end
@@ -0,0 +1,158 @@
1
+ require 'pgit'
2
+
3
+ describe 'PGit::Configuration' do
4
+ describe '.default_options' do
5
+ it 'should give us the default options' do
6
+ default_options = PGit::Configuration.default_options
7
+ example_projects = [
8
+ {
9
+ 'api_token' => 'somepivotalatoken124',
10
+ 'id' => '12345',
11
+ "path" => "~/some/path/to/a/pivotal-git/project"
12
+ },
13
+ {
14
+ 'api_token' => 'somepivotalatoken124',
15
+ 'id' => '23429070',
16
+ "path" => "~/some/other/pivotal-git/project"
17
+ }
18
+ ]
19
+
20
+ expect(default_options['projects']).to match_array(example_projects)
21
+ end
22
+ end
23
+ describe '#new(configuration_path)' do
24
+ describe 'empty' do
25
+ it 'should complain that there should be at least one project' do
26
+ fake_path = "~/some/config/path.yml"
27
+ fake_expanded_path = "/Users/edderic/some/config/path.yml"
28
+ fake_file = double('file')
29
+ fake_yaml = {}
30
+ error_message = <<-ERROR
31
+ Error: /Users/edderic/some/config/path.yml needs at least one project.
32
+ Please have the following layout:
33
+ ---
34
+ projects:
35
+ - api_token: somepivotalatoken124
36
+ id: '12345'
37
+ path: "~/some/path/to/a/pivotal-git/project"
38
+ - api_token: somepivotalatoken124
39
+ id: '23429070'
40
+ path: "~/some/other/pivotal-git/project"
41
+ ERROR
42
+
43
+ allow(File).to receive(:expand_path).with(fake_path).and_return(fake_expanded_path)
44
+ allow(File).to receive(:expand_path).with('.')
45
+ allow(File).to receive(:exists?).with(fake_expanded_path).and_return(true)
46
+ allow(File).to receive(:open).with(fake_expanded_path, 'r').and_return(fake_file)
47
+ allow(YAML).to receive(:load).with(fake_file).and_return(fake_yaml)
48
+ error_message.gsub!(/^\s{10}/,'')
49
+
50
+ expect{ PGit::Configuration.new(fake_path) }.to raise_error(error_message)
51
+ end
52
+ end
53
+
54
+ describe 'has projects but is missing a token' do
55
+ it 'should raise an error' do
56
+ fake_path = "~/some/config/path.yml"
57
+ fake_expanded_path = "/Users/edderic/some/config/path.yml"
58
+ fake_file = double('file')
59
+ fake_projects = [ { path: 'fake_path',
60
+ api_token: 'fake_token'
61
+ }]
62
+ fake_yaml = { 'projects' => fake_projects }
63
+
64
+ allow(File).to receive(:expand_path).with(fake_path).and_return(fake_expanded_path)
65
+ allow(File).to receive(:expand_path).with('.')
66
+ allow(File).to receive(:exists?).with(fake_expanded_path).and_return(true)
67
+ allow(File).to receive(:open).with(fake_expanded_path, 'r').and_return(fake_file)
68
+ allow(YAML).to receive(:load).with(fake_file).and_return(fake_yaml)
69
+ error_message = <<-ERROR
70
+ Error: Must have a path, id, and api_token for each project.
71
+ Please have the following layout:
72
+ ---
73
+ projects:
74
+ - api_token: somepivotalatoken124
75
+ id: '12345'
76
+ path: "~/some/path/to/a/pivotal-git/project"
77
+ - api_token: somepivotalatoken124
78
+ id: '23429070'
79
+ path: "~/some/other/pivotal-git/project"
80
+ ERROR
81
+ error_message.gsub!(/^\s{10}/, '')
82
+
83
+ expect{ PGit::Configuration.new(fake_path) }.to raise_error(error_message)
84
+ end
85
+ end
86
+ end
87
+
88
+ describe '#new(configuration_path)' do
89
+ describe 'configuration_path exists' do
90
+ it '#to_yaml should return the yaml file' do
91
+ fake_path = "~/some/config/path.yml"
92
+ fake_expanded_path = "/Users/edderic/some/config/path.yml"
93
+ fake_file = double('file')
94
+ fake_projects = [ { "path" => 'fake_path',
95
+ "id" => 'fake_id',
96
+ "api_token" => 'fake_token'
97
+ }]
98
+
99
+ fake_yaml = { 'projects' => fake_projects }
100
+
101
+ allow(File).to receive(:expand_path).with(fake_path).and_return(fake_expanded_path)
102
+ allow(File).to receive(:exists?).with(fake_expanded_path).and_return(true)
103
+ allow(File).to receive(:open).with(fake_expanded_path, 'r').and_return(fake_file)
104
+ allow(YAML).to receive(:load).with(fake_file).and_return(fake_yaml)
105
+
106
+ configuration = PGit::Configuration.new(fake_path)
107
+
108
+ expect(configuration.to_yaml).to eq fake_yaml
109
+ end
110
+ end
111
+
112
+ describe 'configuration path does not exist' do
113
+ it 'should throw an error' do
114
+ file_path = '~/.edderic-dotfiles/config/project.yml'
115
+ fake_expanded_path = "/home/edderic/.edderic-dotfiles/config/project.yml"
116
+ error_message = "No such file or directory. Please give a valid path to the project.yml"
117
+ allow(File).to receive(:exists?).and_return(false)
118
+
119
+ expect{ PGit::Configuration.new(file_path) }.to raise_error
120
+ end
121
+ end
122
+ end
123
+
124
+ describe '#new (without any arguments)' do
125
+ describe 'default configuration_path does exist' do
126
+ it 'should load the default configuration file' do
127
+ default_path = "~/.pgit.rc.yml"
128
+ default_expanded_path = "/Users/edderic/.pgit.rc.yml"
129
+ fake_file = double('file')
130
+
131
+ fake_projects = [ { "path" => 'fake_path',
132
+ "id" => 'fake_id',
133
+ "api_token" => 'fake_token'
134
+ }]
135
+
136
+ fake_yaml = { 'projects' => fake_projects }
137
+
138
+ allow(File).to receive(:exists?).with(default_expanded_path).and_return(true)
139
+ allow(File).to receive(:expand_path).with(default_path).and_return(default_expanded_path)
140
+ allow(File).to receive(:open).with(default_expanded_path, 'r').and_return(fake_file)
141
+ allow(YAML).to receive(:load).with(fake_file).and_return(fake_yaml)
142
+
143
+ configuration = PGit::Configuration.new
144
+
145
+ expect(File).to have_received(:expand_path).with(default_path)
146
+ end
147
+ end
148
+
149
+ describe 'default configuration file does not exist' do
150
+ it 'should throw an error' do
151
+ allow(File).to receive(:exists?).and_return(false)
152
+
153
+ error_message = "Default configuration file does not exist. Please run `pgit install`"
154
+ expect{ PGit::Configuration.new }.to raise_error(error_message)
155
+ end
156
+ end
157
+ end
158
+ end