pgit 0.0.2

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.
@@ -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