loljira 0.0.0

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/loljira ADDED
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env ruby
2
+ require 'bundler/setup'
3
+ require 'trollop'
4
+ require 'httparty'
5
+ require_relative '../lib/sprint.rb'
6
+ require_relative '../lib/message_parser.rb'
7
+ require_relative '../lib/component.rb'
8
+
9
+ options = Trollop::options do
10
+ opt :username, "username that you login with on jira", :type => String
11
+ opt :password, "login password (not stored)", :type => String
12
+ opt :url, "jira api endpoint", :type => String
13
+ opt :projectname, "project name (key, not id!)", :type => String
14
+ opt :projectid, "project id"
15
+ opt :file, "file to the git commit message", :type => String
16
+ opt :sprint, "sprint id", :type => String
17
+ end
18
+
19
+ JIRA_URL = options[ :url ].to_s
20
+ JIRA_USERNAME = options[ :username ].to_s
21
+ JIRA_PASSWORD = options[ :password ].to_s
22
+ JIRA_PROJECT_NAME = options[ :projectname ].to_s
23
+ JIRA_SPRINT_ID = options[:sprint].to_i
24
+ FPATH = options[:file].to_s
25
+
26
+ unless FPATH.length > 0
27
+ puts "File required!"
28
+ exit 1
29
+ end
30
+
31
+ require_relative '../lib/jira.rb'
32
+
33
+ file = File.open FPATH, "r"
34
+ contents = file.read
35
+ file.close
36
+ if MessageParser.already_in_jira?( contents , /#?CNVS\-/ )
37
+ puts "commit message already appears to have a jira ID. skipping."
38
+ exit 0
39
+ end
40
+ message = MessageParser.parse( contents )
41
+ puts message.fields
42
+ if !message.components?
43
+ puts "Components are required!"
44
+ exit 1
45
+ end
46
+ jira = Jira.new( JIRA_USERNAME, JIRA_PASSWORD, JIRA_URL )
47
+ issue = jira.create_issue({'summary'=> message.summary,
48
+ 'project'=> {'key' => JIRA_PROJECT_NAME},
49
+ 'issuetype' => {'id'=> "7" },
50
+ 'assignee' => { 'name' => JIRA_USERNAME },
51
+ 'description' => message.description,
52
+ 'components' => message.components
53
+ })
54
+ jira.add_issue_to_sprint issue.key, jira.first_open_sprint( JIRA_SPRINT_ID ).id
55
+
56
+ file = File.open FPATH, "w+"
57
+ file.write message.without_fields_s( "fixes ##{issue.key}" )
58
+ file.close
59
+ puts "Issue ##{issue.key} Created!"
60
+ exit 0
data/lib/component.rb ADDED
@@ -0,0 +1,10 @@
1
+ class Component
2
+
3
+ attr_reader :id, :name
4
+
5
+ def initialize( id, name )
6
+ @id = id
7
+ @name = name
8
+ end
9
+
10
+ end
data/lib/jira.rb ADDED
@@ -0,0 +1,82 @@
1
+ class Issue
2
+ attr_reader :id, :key, :self_url
3
+
4
+ def initialize( args )
5
+ @self_url = args.fetch( 'self' )
6
+ @id = args.fetch( 'id' )
7
+ @key = args.fetch( 'key' )
8
+ end
9
+
10
+ end
11
+ require 'json'
12
+ class Jira
13
+ include HTTParty
14
+
15
+ base_uri JIRA_URL
16
+
17
+ def initialize( username, password, endpoint_url )
18
+ @url = endpoint_url
19
+ @username = username
20
+ @password = password
21
+ end
22
+
23
+ def components
24
+ response = self.class.get "/project/CNVS/components", auth
25
+ response.map do |item|
26
+ Component.new item['id'], item['name']
27
+ end
28
+ end
29
+
30
+ def sprints( rapid_board_id )
31
+ response = self.class.get "/greenhopper/1.0/sprints/#{rapid_board_id}", auth
32
+ response['sprints'].map{ |sprint|
33
+ spr = {
34
+ 'id' => sprint['id'],
35
+ 'name' => sprint['name'],
36
+ 'closed' => sprint[ 'closed' ],
37
+ 'end_date' => sprint[ 'name' ].split( " " ).last.to_s
38
+ }
39
+ Sprint.new spr
40
+ }
41
+ end
42
+
43
+ def first_open_sprint( rapid_board_id )
44
+ sprints = sprints(rapid_board_id).sort_by(&:end_date)
45
+ sprint = sprints.detect{ |sprint| sprint.open? }
46
+ if !sprint
47
+ sprint = sprints.last
48
+ end
49
+ sprint
50
+ end
51
+
52
+ def add_issue_to_sprint( issue_id, sprint_id )
53
+ options = auth.merge({:body => JSON.dump({ 'issueKeys' => [ issue_id ] }) }).
54
+ merge({:headers => { "Content-Type" => "application/json",
55
+ "Accept" => "application/json"
56
+ }})
57
+ self.class.put "/greenhopper/1.0/sprint/#{sprint_id}/issues/add", options
58
+ end
59
+
60
+ def projects
61
+ self.class.get "/api/2/project", auth
62
+ end
63
+
64
+ def find_project_by_key( project_key )
65
+ projects = self.class.get "/api/2/project", auth
66
+ projects.detect { | project | project['key'] == project_key }
67
+ end
68
+
69
+ def create_issue( issue_params )
70
+ body = { :body => JSON.dump({'fields'=> issue_params }) }
71
+ body = body.merge({:headers => {"Content-Type" => "application/json", "Accept" => "application/json"}})
72
+ Issue.new( self.class.post "/api/2/issue", body.merge(auth) )
73
+ end
74
+
75
+ def auth
76
+ {
77
+ :basic_auth =>
78
+ {:username => @username, :password => @password}
79
+ }
80
+ end
81
+
82
+ end
@@ -0,0 +1,74 @@
1
+ class Message
2
+
3
+ attr_reader :summary,:description,:fields
4
+
5
+ def initialize( summary, description, fields)
6
+ @summary = summary.to_s
7
+ @description = description.to_s
8
+ @fields = fields
9
+ end
10
+
11
+ def components
12
+ fields['components']
13
+ end
14
+
15
+ def components?
16
+ !!components
17
+ end
18
+
19
+ def without_fields_s( commit_msg = "" )
20
+ @summary + "\n" + @description + "\n" + commit_msg.to_s
21
+ end
22
+
23
+ end
24
+
25
+ class MessageParser
26
+
27
+ def self.commit_summary_and_body( message )
28
+ messages = message.split("\n")
29
+ return messages.first.to_s, (messages[1..-1]).join("\n").split(/jira:/).first.to_s
30
+ end
31
+
32
+ def self.parse( message )
33
+ summary, body = commit_summary_and_body( message )
34
+ fields = split_keys (message.split /jira:/).last.to_s.split( /Change-Id/ ).first.to_s.strip
35
+ Message.new( summary, body, fields )
36
+ end
37
+
38
+ def self.listify_components( value )
39
+ return [] if value.length == 0
40
+ value.split(',').map do | component_name |
41
+ {:name => component_name.to_s}
42
+ end
43
+ end
44
+
45
+ def self.split_keys( message )
46
+ message.split( "\n" ).inject({}) do | memo, line |
47
+ key, value = line.split( ":" )
48
+ key = key.to_s.strip.downcase; value = value.to_s.strip
49
+ if key == 'components'
50
+ value = listify_components value
51
+ end
52
+ memo[key] = value
53
+ memo
54
+ end
55
+ end
56
+
57
+ def self.already_in_jira?( msg, msg_regex )
58
+ !!msg.match(msg_regex)
59
+ end
60
+
61
+ def self.message
62
+ <<-eos
63
+ this is the example commit message
64
+ blah blah blah blah blah
65
+
66
+ jira:
67
+ components#Assignments
68
+ sprint#15
69
+
70
+ Change-Id: 982374ujalskdfj
71
+ eos
72
+ end
73
+
74
+ end
data/lib/sprint.rb ADDED
@@ -0,0 +1,22 @@
1
+ require 'date'
2
+ require 'time'
3
+ class Sprint
4
+
5
+ attr_reader :id, :name, :closed, :end_date
6
+
7
+ def initialize( args )
8
+ @id = args.fetch( 'id', '' )
9
+ @name = args.fetch( 'name', '' )
10
+ @closed = !!args.fetch( 'closed', false )
11
+ @end_date = Date.parse args.fetch( 'end_date' )
12
+ end
13
+
14
+ def to_s
15
+ "Sprint id: #{id} name: #{name}, closed: #{closed?}"
16
+ end
17
+
18
+ def closed?; !!closed; end
19
+ def open?; !closed?; end
20
+ def over?; open?; end
21
+
22
+ end
metadata ADDED
@@ -0,0 +1,52 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: loljira
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Stanley Stuart
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-01-16 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: command line utility for use with git to automatically create jira tickets
15
+ email:
16
+ - dstanley.stuart@gmail.com
17
+ executables:
18
+ - loljira
19
+ extensions: []
20
+ extra_rdoc_files: []
21
+ files:
22
+ - lib/jira.rb
23
+ - lib/sprint.rb
24
+ - lib/message_parser.rb
25
+ - lib/component.rb
26
+ - bin/loljira
27
+ homepage:
28
+ licenses: []
29
+ post_install_message:
30
+ rdoc_options: []
31
+ require_paths:
32
+ - lib
33
+ required_ruby_version: !ruby/object:Gem::Requirement
34
+ none: false
35
+ requirements:
36
+ - - ! '>='
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ required_rubygems_version: !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ! '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ requirements: []
46
+ rubyforge_project:
47
+ rubygems_version: 1.8.23
48
+ signing_key:
49
+ specification_version: 3
50
+ summary: loljira
51
+ test_files: []
52
+ has_rdoc: