jirasync 0.4.5 → 0.4.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +6 -4
- data/bin/jira-sync +14 -7
- data/lib/jirasync/jira_client.rb +48 -19
- data/lib/jirasync/version.rb +1 -1
- metadata +22 -30
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a03445145f26a7d70ba8b1d604823a9a26d21d00b781453587f77f9dc76fe97d
|
4
|
+
data.tar.gz: 5592ecc86a2814a39b8d11cac69f1e11a593d401a59e11239a3a88dab44141f1
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0a320e45f7fde0470f70bf2a904446f0761305480d0a0905fc76f51b049cdf20fa5599ff47d4b415640e358cd9e90d2a460c270dbeec27ef52739b53b868b207
|
7
|
+
data.tar.gz: 5ce8f2dd1a3df4cd2c4df655e7e5bbd7bce44ea0a86a2c71eddf2f7412330e2629bdee0d3134e890fa0d832cf8b14f09ca3213690bbf367bb6331342290769fe
|
data/README.md
CHANGED
@@ -1,12 +1,9 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
A suite of utilities to synchronise JIRA projects to the local file system
|
1
|
+
[![Gem Version](https://badge.fury.io/rb/jirasync.svg)](http://badge.fury.io/rb/jirasync)
|
4
2
|
|
5
3
|
## Installation
|
6
4
|
|
7
5
|
gem install jirasync
|
8
6
|
|
9
|
-
|
10
7
|
## Usage
|
11
8
|
|
12
9
|
### Initial Fetch
|
@@ -152,6 +149,11 @@ jira-format-issues \
|
|
152
149
|
|
153
150
|
~~~
|
154
151
|
|
152
|
+
## Using Cookie-Authentication
|
153
|
+
|
154
|
+
If a single-sign-on solution is used, `jira-sync` can also use the session
|
155
|
+
cookie to authenticate requests to jira.
|
156
|
+
|
155
157
|
## Motivation
|
156
158
|
|
157
159
|
Having a local, unix-friendly copy of all tickets to avoid JIRA performance issues and
|
data/bin/jira-sync
CHANGED
@@ -21,7 +21,7 @@ Usage:
|
|
21
21
|
jira-sync [options] [command]
|
22
22
|
where command is one of the following
|
23
23
|
|
24
|
-
|
24
|
+
fetch: fetches all tickets from the given project
|
25
25
|
update: fetches all tickets that have been updated/
|
26
26
|
added since the last run
|
27
27
|
|
@@ -31,6 +31,7 @@ EOS
|
|
31
31
|
opt :project, "Project key", :type => :string
|
32
32
|
opt :user, "User, defaults to the current system user", :type => :string
|
33
33
|
opt :password, "Password, if not specified there, will be an interactive prompt", :type => :string
|
34
|
+
opt :cookie, "Session cookie, to use cookie-based authentication instead of username & password (e.g. 'JSESSIONID=ABC123')", :type => :string
|
34
35
|
opt :target, "Target directory, defaults to the project key", :type => :string
|
35
36
|
opt :store_attachments, "Fetch and store attachments"
|
36
37
|
end
|
@@ -39,8 +40,14 @@ Trollop::die :baseurl, "must be speficied" if !opts[:baseurl]
|
|
39
40
|
Trollop::die :project, "must be speficied" if !opts[:project]
|
40
41
|
|
41
42
|
|
42
|
-
|
43
|
-
|
43
|
+
authentication = begin
|
44
|
+
cookie = opts[:cookie]
|
45
|
+
if cookie then
|
46
|
+
JiraSync::CookieAuthentication.new(cookie)
|
47
|
+
else
|
48
|
+
JiraSync::UsernamePasswordAuthentication.new(opts[:user] || ENV['USER'], opts[:password] || prompt_for_password)
|
49
|
+
end
|
50
|
+
end
|
44
51
|
target = opts[:target] || opts[:project].chomp
|
45
52
|
project = opts[:project]
|
46
53
|
store_attachments = opts[:store_attachments]
|
@@ -52,7 +59,7 @@ if !["fetch", "update"].include?(command)
|
|
52
59
|
exit 1
|
53
60
|
end
|
54
61
|
|
55
|
-
client = JiraSync::JiraClient.new(opts[:baseurl],
|
62
|
+
client = JiraSync::JiraClient.new(opts[:baseurl], authentication)
|
56
63
|
repo = JiraSync::LocalIssueRepository.new(target)
|
57
64
|
syncer = JiraSync::Syncer.new(client, repo, project, store_attachments)
|
58
65
|
|
@@ -61,7 +68,7 @@ if command == "fetch"
|
|
61
68
|
update_statement=<<-END
|
62
69
|
jira-sync \
|
63
70
|
--baseurl #{opts[:baseurl]} \\
|
64
|
-
--user #{user} \\
|
71
|
+
#{ if authentication.cookie then "--cookie #{cookie}" else "--user #{user}" end} \\
|
65
72
|
--project #{project} \\
|
66
73
|
--target #{target} \\
|
67
74
|
--store-attachments \\
|
@@ -83,7 +90,7 @@ if command == "update"
|
|
83
90
|
fetch_statement=<<-END
|
84
91
|
jira-sync \
|
85
92
|
--baseurl #{opts[:baseurl]} \\
|
86
|
-
--user #{user} \\
|
93
|
+
#{ if authentication.cookie then "--cookie #{cookie}" else "--user #{user}" end} \\
|
87
94
|
--project #{project} \\
|
88
95
|
--target #{target} \\
|
89
96
|
--store-attachments \\
|
@@ -99,4 +106,4 @@ Try to use a statement along the following lines
|
|
99
106
|
end
|
100
107
|
|
101
108
|
syncer.update
|
102
|
-
end
|
109
|
+
end
|
data/lib/jirasync/jira_client.rb
CHANGED
@@ -20,11 +20,48 @@ module JiraSync
|
|
20
20
|
end
|
21
21
|
|
22
22
|
|
23
|
-
class
|
23
|
+
class JiraAuthentication
|
24
|
+
attr_reader :options
|
25
|
+
|
26
|
+
def initialize(options)
|
27
|
+
@options = options
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
24
31
|
|
25
|
-
|
32
|
+
class UsernamePasswordAuthentication < JiraAuthentication
|
33
|
+
attr_reader :username
|
34
|
+
|
35
|
+
def initialize(username, password)
|
36
|
+
super({
|
37
|
+
:basic_auth => {
|
38
|
+
:username => username,
|
39
|
+
:password => password,
|
40
|
+
},
|
41
|
+
})
|
26
42
|
@username = username
|
27
|
-
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
class CookieAuthentication < JiraAuthentication
|
48
|
+
attr_reader :cookie
|
49
|
+
|
50
|
+
def initialize(cookie)
|
51
|
+
super({
|
52
|
+
:headers => {
|
53
|
+
"Cookie" => cookie,
|
54
|
+
},
|
55
|
+
})
|
56
|
+
@cookie = cookie
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
class JiraClient
|
62
|
+
|
63
|
+
def initialize(baseurl, authentication)
|
64
|
+
@authentication = authentication
|
28
65
|
@baseurl = baseurl
|
29
66
|
@timeout = 15
|
30
67
|
@first_requets_timeout = 60
|
@@ -34,8 +71,7 @@ module JiraSync
|
|
34
71
|
|
35
72
|
def get(jira_id)
|
36
73
|
url = "#{@baseurl}/rest/api/latest/issue/#{jira_id}"
|
37
|
-
|
38
|
-
response = HTTParty.get url, {:basic_auth => auth, :timeout => @timeout}
|
74
|
+
response = HTTParty.get url, @authentication.options.merge({:timeout => @timeout})
|
39
75
|
if response.code == 200
|
40
76
|
response.parsed_response
|
41
77
|
else
|
@@ -46,8 +82,7 @@ module JiraSync
|
|
46
82
|
def attachments_for_issue(issue)
|
47
83
|
attachments = []
|
48
84
|
Parallel.map(issue['fields']['attachment'], :in_threads => 64) do |attachment|
|
49
|
-
|
50
|
-
response = HTTParty.get attachment['content'], {:basic_auth => auth, :timeout => @timeout}
|
85
|
+
response = HTTParty.get attachment['content'], @authentication.options.merge({:timeout => @timeout})
|
51
86
|
if response.code == 200
|
52
87
|
attachments.push({:data => response.body, :attachment => attachment, :issue => issue})
|
53
88
|
else
|
@@ -60,13 +95,11 @@ module JiraSync
|
|
60
95
|
|
61
96
|
def latest_issue_for_project(project_id)
|
62
97
|
url = "#{@baseurl}/rest/api/2/search?"
|
63
|
-
auth = {:username => @username, :password => @password}
|
64
98
|
|
65
|
-
response = HTTParty.get url, {
|
66
|
-
:basic_auth => auth,
|
99
|
+
response = HTTParty.get url, @authentication.options.merge({
|
67
100
|
:query => {:jql => 'project="' + project_id + '" order by created', fields: 'summary,updated', maxResults: '1'},
|
68
101
|
:timeout => @first_requets_timeout
|
69
|
-
}
|
102
|
+
})
|
70
103
|
if response.code == 200
|
71
104
|
response.parsed_response
|
72
105
|
else
|
@@ -76,14 +109,12 @@ module JiraSync
|
|
76
109
|
|
77
110
|
def changed_since(project_id, date)
|
78
111
|
url = "#{@baseurl}/rest/api/2/search?"
|
79
|
-
auth = {:username => @username, :password => @password}
|
80
112
|
jql = 'project = "' + project_id + '" AND updated > ' + (date.to_time.to_i * 1000).to_s
|
81
113
|
# "' + date.to_s + '"'
|
82
|
-
response = HTTParty.get url, {
|
83
|
-
:basic_auth => auth,
|
114
|
+
response = HTTParty.get url, @authentication.options.merge({
|
84
115
|
:query => {:jql => jql, fields: 'summary,updated', maxResults: '1000'},
|
85
116
|
:timeout => @timeout
|
86
|
-
}
|
117
|
+
})
|
87
118
|
if response.code == 200
|
88
119
|
response.parsed_response
|
89
120
|
else
|
@@ -93,12 +124,10 @@ module JiraSync
|
|
93
124
|
|
94
125
|
def project_info(project_id)
|
95
126
|
url = "#{@baseurl}/rest/api/2/project/#{project_id}"
|
96
|
-
|
97
|
-
response = HTTParty.get url, {
|
98
|
-
:basic_auth => auth,
|
127
|
+
response = HTTParty.get url, @authentication.options.merge({
|
99
128
|
:query => {:jql => 'project="' + project_id + '"', fields: 'summary,updated', maxResults: '50'},
|
100
129
|
:timeout => @timeout
|
101
|
-
}
|
130
|
+
})
|
102
131
|
if response.code == 200
|
103
132
|
response.parse_response
|
104
133
|
else
|
data/lib/jirasync/version.rb
CHANGED
metadata
CHANGED
@@ -1,84 +1,77 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jirasync
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
5
|
-
prerelease:
|
4
|
+
version: 0.4.6
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Felix Leipold
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2019-03-06 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: trollop
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - ">="
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '0'
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - ">="
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: '0'
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: httparty
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- -
|
31
|
+
- - ">="
|
36
32
|
- !ruby/object:Gem::Version
|
37
33
|
version: '0'
|
38
34
|
type: :runtime
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- -
|
38
|
+
- - ">="
|
44
39
|
- !ruby/object:Gem::Version
|
45
40
|
version: '0'
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: parallel
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
|
-
- -
|
45
|
+
- - ">="
|
52
46
|
- !ruby/object:Gem::Version
|
53
47
|
version: '0'
|
54
48
|
type: :runtime
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
|
-
- -
|
52
|
+
- - ">="
|
60
53
|
- !ruby/object:Gem::Version
|
61
54
|
version: '0'
|
62
55
|
- !ruby/object:Gem::Dependency
|
63
56
|
name: ruby-progressbar
|
64
57
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
58
|
requirements:
|
67
|
-
- -
|
59
|
+
- - ">="
|
68
60
|
- !ruby/object:Gem::Version
|
69
61
|
version: '0'
|
70
62
|
type: :runtime
|
71
63
|
prerelease: false
|
72
64
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
65
|
requirements:
|
75
|
-
- -
|
66
|
+
- - ">="
|
76
67
|
- !ruby/object:Gem::Version
|
77
68
|
version: '0'
|
78
|
-
description:
|
79
|
-
|
80
|
-
|
81
|
-
|
69
|
+
description: |-
|
70
|
+
jirasync synchronises tickets from a jira project to the local
|
71
|
+
file system. It supports a complete fetch operation as well as
|
72
|
+
an incremental update.
|
73
|
+
|
74
|
+
Each ticket is stored in a simple, pretty printed JSON file.
|
82
75
|
email: ''
|
83
76
|
executables:
|
84
77
|
- jira-format-issues
|
@@ -86,7 +79,7 @@ executables:
|
|
86
79
|
extensions: []
|
87
80
|
extra_rdoc_files: []
|
88
81
|
files:
|
89
|
-
- .gitignore
|
82
|
+
- ".gitignore"
|
90
83
|
- Gemfile
|
91
84
|
- LICENSE
|
92
85
|
- README.md
|
@@ -101,26 +94,25 @@ files:
|
|
101
94
|
- lib/jirasync/version.rb
|
102
95
|
homepage: https://github.com/programmiersportgruppe/jira-sync
|
103
96
|
licenses: []
|
97
|
+
metadata: {}
|
104
98
|
post_install_message:
|
105
99
|
rdoc_options: []
|
106
100
|
require_paths:
|
107
101
|
- lib
|
108
102
|
required_ruby_version: !ruby/object:Gem::Requirement
|
109
|
-
none: false
|
110
103
|
requirements:
|
111
|
-
- -
|
104
|
+
- - ">="
|
112
105
|
- !ruby/object:Gem::Version
|
113
106
|
version: '0'
|
114
107
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
115
|
-
none: false
|
116
108
|
requirements:
|
117
|
-
- -
|
109
|
+
- - ">="
|
118
110
|
- !ruby/object:Gem::Version
|
119
111
|
version: '0'
|
120
112
|
requirements: []
|
121
113
|
rubyforge_project:
|
122
|
-
rubygems_version:
|
114
|
+
rubygems_version: 2.7.6
|
123
115
|
signing_key:
|
124
|
-
specification_version:
|
116
|
+
specification_version: 4
|
125
117
|
summary: jirasync synchronises jira projects to the local file system
|
126
118
|
test_files: []
|