gplan 0.0.3
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/bin/gplan +89 -0
- data/lib/github.rb +69 -0
- data/lib/planbox.rb +75 -0
- metadata +48 -0
data/bin/gplan
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This script is used to find all of the planbox story numbers from the git log
|
4
|
+
# For lesson-player it is dependent on lesson-player being in the directory name for the repo
|
5
|
+
|
6
|
+
require 'pathname'
|
7
|
+
bin_path = Pathname.new(__FILE__).realpath
|
8
|
+
$:.unshift File.expand_path('../../lib', bin_path)
|
9
|
+
require 'planbox'
|
10
|
+
require 'github'
|
11
|
+
|
12
|
+
PB_STORY_REGEX=/\[(?:fixes)? *#*([0-9]*)\]/i
|
13
|
+
GH_PR_REGEX=/Merge pull request #(\d*)/i
|
14
|
+
|
15
|
+
@gh_release_array = []
|
16
|
+
@pb_release_array = []
|
17
|
+
@combined = []
|
18
|
+
|
19
|
+
def combine_results
|
20
|
+
@pb_release_array.each do |pb_story|
|
21
|
+
@gh_release_array.each do |gh_pr|
|
22
|
+
if gh_pr['pb_id'] and gh_pr['pb_id'].to_i == pb_story["id"]
|
23
|
+
gh_pr.delete('id') # doing this so we don't overide the pb id
|
24
|
+
pb_story = pb_story.merge gh_pr
|
25
|
+
@gh_release_array.delete gh_pr
|
26
|
+
break
|
27
|
+
end
|
28
|
+
end
|
29
|
+
@combined << pb_story
|
30
|
+
end
|
31
|
+
|
32
|
+
# add the remaining unmatched PRs
|
33
|
+
@gh_release_array.each do |gh_pr|
|
34
|
+
@combined << gh_pr
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# used to pull story numbers from pull request titles
|
39
|
+
def pull_pb_numbers_from_prs
|
40
|
+
@gh_release_array.each do |gh_pr|
|
41
|
+
pb_ids = gh_pr['title'].scan(PB_STORY_REGEX).flatten.uniq
|
42
|
+
if !pb_ids.empty?
|
43
|
+
gh_pr.merge!({"pb_id" => pb_ids.first.to_i}) # making an assumption that there is only 1 pb story number
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def print
|
49
|
+
end_of_pbs = false
|
50
|
+
release_notes = "ID:STATUS:TITLE:PROJECT_NAME:PROJECT_ALIAS:PR:TITLE\n"
|
51
|
+
@combined.each do |story|
|
52
|
+
if !end_of_pbs and story['name'].nil?
|
53
|
+
end_of_pbs = true
|
54
|
+
release_notes += "\n---- Unmatched PRs ----\n\n"
|
55
|
+
release_notes += "PR:TITLE\n"
|
56
|
+
end
|
57
|
+
line = ""
|
58
|
+
line += "#{story['id']}:#{story['status']}:#{story['name']}:#{story['project_name']}:#{story['project_alias']}" unless end_of_pbs
|
59
|
+
line += ":#{story['number']}:#{story['title']}" unless story['number'].nil?
|
60
|
+
release_notes += line + "\n"
|
61
|
+
end
|
62
|
+
puts release_notes
|
63
|
+
end
|
64
|
+
|
65
|
+
def setup_repository
|
66
|
+
conf_file =Dir.pwd+"/.gplan"
|
67
|
+
if File.exists?(conf_file)
|
68
|
+
File.open(conf_file, "r") do |f|
|
69
|
+
@prod_branch = f.each_line.first.chomp
|
70
|
+
end
|
71
|
+
end
|
72
|
+
# Set the default branch if one is not set
|
73
|
+
@prod_branch = "production/master" unless @prod_branch
|
74
|
+
@repo = @prod_branch.split("/").first
|
75
|
+
end
|
76
|
+
|
77
|
+
# MAIN
|
78
|
+
|
79
|
+
setup_repository
|
80
|
+
`git fetch #{@repo}`
|
81
|
+
list= `git log #{@prod_branch}..`
|
82
|
+
|
83
|
+
pb_story_ids = list.scan(PB_STORY_REGEX).flatten.uniq
|
84
|
+
gh_pr_ids = list.scan(GH_PR_REGEX).flatten.uniq
|
85
|
+
@gh_release_array = Github.get_release_notes_array gh_pr_ids
|
86
|
+
@pb_release_array = Planbox.get_release_notes_array pb_story_ids
|
87
|
+
pull_pb_numbers_from_prs
|
88
|
+
combine_results
|
89
|
+
print
|
data/lib/github.rb
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
|
3
|
+
GITHUB_USERNAME=ENV['GITHUB_USERNAME']
|
4
|
+
GITHUB_TOKEN=ENV['GITHUB_TOKEN']
|
5
|
+
GITHUB_BASE_URL="https://api.github.com"
|
6
|
+
|
7
|
+
module Github
|
8
|
+
include HTTParty
|
9
|
+
|
10
|
+
@repo_name
|
11
|
+
@app_name
|
12
|
+
|
13
|
+
def self.check_environment
|
14
|
+
if GITHUB_USERNAME == nil || GITHUB_TOKEN == nil
|
15
|
+
raise "environment variables not set. Please check that you have the following set...\
|
16
|
+
\nGITHUB_USERNAME\nGITHUB_TOKEN"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.set_repo_info
|
21
|
+
cmd = "git remote -v |grep origin"
|
22
|
+
repo_info = `#{cmd}`
|
23
|
+
@repo_name = repo_info.scan(/\:(.*)\//).uniq.flatten.first
|
24
|
+
@app_name = repo_info.scan(/\/(.*)\.git/).uniq.flatten.first
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.get_release_notes gh_pr_ids
|
28
|
+
stories = get_release_notes_array gh_pr_ids
|
29
|
+
result_string = format stories
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.get_release_notes_array gh_pr_ids
|
33
|
+
check_environment
|
34
|
+
get_stories gh_pr_ids
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.get_story(pr_id)
|
38
|
+
set_repo_info
|
39
|
+
story_response = self.get("#{GITHUB_BASE_URL}/repos/#{@repo_name}/#{@app_name}/pulls/#{pr_id}?access_token=#{GITHUB_TOKEN}",
|
40
|
+
{
|
41
|
+
:headers => { 'User-Agent' => GITHUB_USERNAME, 'Content-Type' => 'application/json', 'Accept' => 'application/json'}
|
42
|
+
})
|
43
|
+
return story_response.parsed_response unless story_response.parsed_response.nil? || story_response.parsed_response["code"] == "error"
|
44
|
+
{"id" => story_id, "name" => "PR not found in github"}
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.get_stories(array_of_pr_ids)
|
48
|
+
stories = []
|
49
|
+
return [] unless array_of_pr_ids
|
50
|
+
array_of_pr_ids.each do |id|
|
51
|
+
stories<< get_story(id)
|
52
|
+
end
|
53
|
+
stories
|
54
|
+
end
|
55
|
+
|
56
|
+
# formats the output of stories
|
57
|
+
def self.format(stories)
|
58
|
+
result_string = ""
|
59
|
+
stories.each do |story|
|
60
|
+
result_string += "#{story['number']}:"
|
61
|
+
result_string += "#{story['title']}"
|
62
|
+
result_string += "\n"
|
63
|
+
end
|
64
|
+
|
65
|
+
# clean up any troublesome chars
|
66
|
+
result_string.gsub!('`', ' ') || result_string
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
data/lib/planbox.rb
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
|
3
|
+
PLANBOX_EMAIL=ENV['PLANBOX_EMAIL']
|
4
|
+
PLANBOX_TOKEN=ENV['PLANBOX_TOKEN']
|
5
|
+
PLANBOX_BASE_URL="https://www.planbox.com/api"
|
6
|
+
|
7
|
+
module Planbox
|
8
|
+
include HTTParty
|
9
|
+
|
10
|
+
def self.check_environment
|
11
|
+
if PLANBOX_EMAIL == nil || PLANBOX_TOKEN == nil
|
12
|
+
raise "environment variables not set. Please check that you have the following set...\
|
13
|
+
\nPLANBOX_EMAIL\nPLANBOX_TOKEN"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.get_release_notes pb_story_ids
|
18
|
+
stories = get_release_notes_array pb_story_ids
|
19
|
+
result_string = format stories
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.get_release_notes_array pb_story_ids
|
23
|
+
check_environment
|
24
|
+
stories = get_stories pb_story_ids
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.login
|
28
|
+
response = self.post("#{PLANBOX_BASE_URL}/auth", { :body => {:email => PLANBOX_EMAIL, :password => PLANBOX_TOKEN}})
|
29
|
+
self.basic_auth response['content']['access_token'], ""
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.get_story(story_id)
|
33
|
+
story_response = self.post("#{PLANBOX_BASE_URL}/get_story", { :body => { :story_id => story_id}})
|
34
|
+
|
35
|
+
if story_response.parsed_response.nil? || story_response.parsed_response["code"] == "error"
|
36
|
+
return {"id" => story_id, "name" => "story not found in planbox"}
|
37
|
+
end
|
38
|
+
|
39
|
+
story = story_response.parsed_response["content"]
|
40
|
+
project_response = self.post("#{PLANBOX_BASE_URL}/get_project", { :body => { :project_id => story['project_id'], :product_id => story['product_id']}})
|
41
|
+
project = project_response.parsed_response["content"]
|
42
|
+
project_alias = project["alias"]
|
43
|
+
project_name = project["name"]
|
44
|
+
|
45
|
+
story = story.merge({"project_name" => project_name})
|
46
|
+
story = story.merge({"project_alias" => project_alias})
|
47
|
+
|
48
|
+
story
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.get_stories(array_of_pb_ids)
|
52
|
+
login
|
53
|
+
stories = []
|
54
|
+
return [] unless array_of_pb_ids
|
55
|
+
array_of_pb_ids.each do |id|
|
56
|
+
stories<< get_story(id)
|
57
|
+
end
|
58
|
+
stories
|
59
|
+
end
|
60
|
+
|
61
|
+
# formats the output of stories
|
62
|
+
def self.format(stories)
|
63
|
+
result_string = ""
|
64
|
+
stories.each do |story|
|
65
|
+
result_string += "#{story['id']}:"
|
66
|
+
result_string += "#{story['status']}: "
|
67
|
+
result_string += "#{story['name']}"
|
68
|
+
result_string += "\n"
|
69
|
+
end
|
70
|
+
|
71
|
+
# clean up any troublesome chars
|
72
|
+
result_string.gsub!('`', ' ') || result_string
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
metadata
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: gplan
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.3
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Jeff Koenig
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2014-04-14 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: Creates release notes from the git log and planbox
|
15
|
+
email: jkoenig311@gmail.com
|
16
|
+
executables:
|
17
|
+
- gplan
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- bin/gplan
|
22
|
+
- lib/github.rb
|
23
|
+
- lib/planbox.rb
|
24
|
+
homepage: https://github.com/jkoenig311/gplan
|
25
|
+
licenses: []
|
26
|
+
post_install_message:
|
27
|
+
rdoc_options: []
|
28
|
+
require_paths:
|
29
|
+
- lib
|
30
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
31
|
+
none: false
|
32
|
+
requirements:
|
33
|
+
- - '>='
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: '0'
|
36
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
37
|
+
none: false
|
38
|
+
requirements:
|
39
|
+
- - '>='
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
requirements: []
|
43
|
+
rubyforge_project:
|
44
|
+
rubygems_version: 1.8.28
|
45
|
+
signing_key:
|
46
|
+
specification_version: 3
|
47
|
+
summary: Creates release notes from the git log and planbox
|
48
|
+
test_files: []
|