ki_youtrack 0.0.1 → 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.
- data/.gitignore +1 -0
- data/bin/ki_youtrack +26 -15
- data/ki_youtrack.gemspec +1 -0
- data/lib/ki_youtrack/api.rb +20 -11
- data/lib/ki_youtrack/initializer.rb +41 -0
- data/lib/ki_youtrack/kiseru.rb +29 -6
- data/lib/ki_youtrack/session.rb +32 -6
- data/lib/ki_youtrack/version.rb +1 -1
- data/lib/ki_youtrack.rb +1 -0
- data/spec/integration/get_bug_spec.rb +10 -3
- data/spec/spec_helper.rb +3 -0
- data/spec/unit/session_spec.rb +10 -12
- metadata +38 -26
data/.gitignore
CHANGED
data/bin/ki_youtrack
CHANGED
@@ -33,25 +33,36 @@ command :issue do |c|
|
|
33
33
|
pretty = $stdout.tty?
|
34
34
|
|
35
35
|
id = args.first
|
36
|
-
|
37
|
-
|
36
|
+
|
37
|
+
begin
|
38
|
+
api = KiYoutrack::Api.new
|
39
|
+
json = api.issue(id, :pretty => pretty)
|
40
|
+
$stdout.puts(json)
|
41
|
+
rescue Kiseru::ConfigError => e
|
42
|
+
$stderr.puts e.message
|
43
|
+
$stderr.puts "Run 'ki_youtrack init' or edit #{api.config.path}"
|
44
|
+
exit 1
|
45
|
+
rescue KiYoutrack::SessionError => e
|
46
|
+
$stderr.puts e.message
|
47
|
+
exit 1
|
48
|
+
end
|
38
49
|
end
|
39
50
|
end
|
40
51
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
subdomain = config.read(:subdomain) || ui.ask("Subdomain: ")
|
52
|
+
on_error do |error|
|
53
|
+
case error
|
54
|
+
when SystemExit
|
55
|
+
exit error.status
|
56
|
+
false
|
57
|
+
else
|
58
|
+
true
|
59
|
+
end
|
60
|
+
end
|
51
61
|
|
52
|
-
|
53
|
-
|
54
|
-
|
62
|
+
desc 'Initialize config file'
|
63
|
+
command :init do |c|
|
64
|
+
c.action do |global_options, options, args|
|
65
|
+
KiYoutrack::Initializer.init
|
55
66
|
end
|
56
67
|
end
|
57
68
|
|
data/ki_youtrack.gemspec
CHANGED
@@ -23,6 +23,7 @@ Gem::Specification.new do |gem|
|
|
23
23
|
gem.add_dependency('highline')
|
24
24
|
|
25
25
|
gem.add_development_dependency('debugger')
|
26
|
+
gem.add_development_dependency('rake')
|
26
27
|
gem.add_development_dependency('rspec')
|
27
28
|
gem.add_development_dependency('simplecov')
|
28
29
|
gem.add_development_dependency('test-construct')
|
data/lib/ki_youtrack/api.rb
CHANGED
@@ -2,17 +2,26 @@ module KiYoutrack
|
|
2
2
|
|
3
3
|
class Api
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
5
|
+
attr_reader :config
|
6
|
+
|
7
|
+
def initialize(config=Kiseru::Config[:ki_youtrack])
|
8
|
+
@config = config
|
9
|
+
end
|
10
|
+
|
11
|
+
def issue(id, opts = {})
|
12
|
+
config.ensure_present(:login, :password, :subdomain, :ssl)
|
13
|
+
|
14
|
+
login = @config.read(:login)
|
15
|
+
password = @config.read(:password)
|
16
|
+
subdomain = @config.read(:subdomain)
|
17
|
+
ssl = @config.read(:ssl)
|
18
|
+
|
19
|
+
session = Session.new(login, password, subdomain, :ssl => ssl)
|
20
|
+
response = session.init
|
21
|
+
|
22
|
+
issue = session.issue(id)
|
23
|
+
|
24
|
+
filtered_data = IssueFilter.filter(issue)
|
16
25
|
MultiJson.dump(filtered_data, :pretty => opts[:pretty])
|
17
26
|
end
|
18
27
|
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module KiYoutrack
|
2
|
+
|
3
|
+
class Initializer
|
4
|
+
|
5
|
+
def self.init
|
6
|
+
config = Kiseru::Config[:ki_youtrack]
|
7
|
+
|
8
|
+
ui = HighLine.new
|
9
|
+
|
10
|
+
$stdout.puts "Initializing config file at #{config.path}"
|
11
|
+
|
12
|
+
old_subdomain = config.read(:subdomain)
|
13
|
+
old_ssl = config.read(:ssl)
|
14
|
+
old_login = config.read(:login)
|
15
|
+
old_password = config.read(:password)
|
16
|
+
|
17
|
+
subdomain = ui.ask("Subdomain: ") { |q| q.default = old_subdomain }
|
18
|
+
convert_to_boolean = lambda do |string|
|
19
|
+
return true if string.downcase == "true"
|
20
|
+
return false if string.downcase == "false"
|
21
|
+
string
|
22
|
+
end
|
23
|
+
ssl = ui.ask("SSL?: ", convert_to_boolean) do |q|
|
24
|
+
q.default = old_ssl || "true";
|
25
|
+
q
|
26
|
+
end
|
27
|
+
login = ui.ask("Login (or email): ") { |q| q.default = old_login }
|
28
|
+
|
29
|
+
$stdout.puts "WARNING: Your YouTrack password will be written in plaintext to #{config.path}"
|
30
|
+
password = ui.ask("Password: ") { |q| q.echo = "*" }
|
31
|
+
|
32
|
+
config.write(:login, login)
|
33
|
+
config.write(:password, password)
|
34
|
+
config.write(:subdomain, subdomain)
|
35
|
+
config.write(:ssl, ssl)
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
data/lib/ki_youtrack/kiseru.rb
CHANGED
@@ -1,16 +1,23 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'fileutils'
|
3
|
+
|
1
4
|
module Kiseru
|
2
5
|
|
6
|
+
class ConfigError < StandardError; end;
|
7
|
+
|
3
8
|
class ConfigDir
|
4
9
|
|
5
|
-
|
10
|
+
NAME = '.kiseru'
|
6
11
|
|
7
12
|
attr_reader :path
|
8
13
|
|
9
14
|
def initialize(opts = {})
|
15
|
+
name = opts.fetch(:name) { NAME }
|
10
16
|
root = Pathname.new(File.expand_path(opts.fetch(:root) { '~' }))
|
11
|
-
@path = root +
|
17
|
+
@path = root + name
|
12
18
|
unless File.directory?(@path)
|
13
19
|
Dir.mkdir(@path)
|
20
|
+
FileUtils.chmod(0700, @path)
|
14
21
|
end
|
15
22
|
end
|
16
23
|
|
@@ -22,18 +29,34 @@ module Kiseru
|
|
22
29
|
|
23
30
|
class Config
|
24
31
|
|
32
|
+
attr_reader :path
|
33
|
+
|
25
34
|
def self.[](key)
|
26
35
|
ConfigDir.new.config(key)
|
27
36
|
end
|
28
37
|
|
29
38
|
def initialize(root_path, app_name)
|
30
|
-
|
31
|
-
|
39
|
+
@path = (root_path + "#{app_name}.yml").to_s
|
40
|
+
unless File.exists?(@path)
|
41
|
+
FileUtils.touch(@path)
|
42
|
+
FileUtils.chmod(0600, @path)
|
43
|
+
end
|
44
|
+
@store = YAML::Store.new(@path)
|
45
|
+
@store.transaction do
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def ensure_present(*keys)
|
50
|
+
keys.each do |key|
|
51
|
+
if read(key).nil?
|
52
|
+
raise ConfigError, "'#{key}' is not defined in config"
|
53
|
+
end
|
54
|
+
end
|
32
55
|
end
|
33
56
|
|
34
|
-
def write(key,
|
57
|
+
def write(key, value)
|
35
58
|
@store.transaction do
|
36
|
-
@store[key] =
|
59
|
+
@store[key] = value
|
37
60
|
end
|
38
61
|
end
|
39
62
|
|
data/lib/ki_youtrack/session.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
module KiYoutrack
|
2
2
|
|
3
|
+
class SessionError < StandardError; end;
|
4
|
+
|
3
5
|
class Session
|
4
6
|
|
5
7
|
attr_reader :session_cookies, :api_url
|
@@ -12,26 +14,50 @@ module KiYoutrack
|
|
12
14
|
"#{protocol}://#{subdomain}.myjetbrains.com"
|
13
15
|
end
|
14
16
|
|
15
|
-
def initialize(
|
17
|
+
def initialize(login, password, subdomain, opts = {})
|
16
18
|
ssl = opts.fetch(:ssl, true)
|
17
|
-
@
|
19
|
+
@login = login
|
18
20
|
@password = password
|
19
21
|
@api_url = Session.url(subdomain, ssl)
|
20
22
|
end
|
21
23
|
|
22
24
|
def init
|
23
25
|
response = connection.post("/youtrack/rest/user/login",
|
24
|
-
:login => @
|
26
|
+
:login => @login,
|
25
27
|
:password => @password)
|
26
28
|
@session_cookies = response.headers['set-cookie']
|
27
|
-
response
|
29
|
+
case response.status
|
30
|
+
when 404
|
31
|
+
if response.body =~ /HTTPS is supported in paid version only/
|
32
|
+
raise SessionError, "Authentication failed because HTTPS is not supported for this domain."
|
33
|
+
else
|
34
|
+
raise SessionError, "Authentication failed. Check subdomain and SSL settings."
|
35
|
+
end
|
36
|
+
when 302
|
37
|
+
raise SessionError, "Authentication failed. Check subdomain."
|
38
|
+
when 403
|
39
|
+
raise SessionError, "Authentication failed. Check login and password."
|
40
|
+
when 200
|
41
|
+
response
|
42
|
+
else
|
43
|
+
raise SessionError, "Unhandled status code #{response.status}"
|
44
|
+
end
|
28
45
|
end
|
29
46
|
|
30
|
-
def
|
31
|
-
connection.get do |req|
|
47
|
+
def issue(id)
|
48
|
+
response = connection.get do |req|
|
32
49
|
req.url "/youtrack/rest/issue/#{id}"
|
33
50
|
req.headers['Cookie'] = session_cookies
|
34
51
|
end
|
52
|
+
|
53
|
+
case response.status
|
54
|
+
when 200
|
55
|
+
response.body['issue']
|
56
|
+
when 404
|
57
|
+
raise SessionError, "Can't find issue #{id}"
|
58
|
+
else
|
59
|
+
raise SessionError, "Unhandled status code #{response.status}"
|
60
|
+
end
|
35
61
|
end
|
36
62
|
|
37
63
|
private
|
data/lib/ki_youtrack/version.rb
CHANGED
data/lib/ki_youtrack.rb
CHANGED
@@ -4,21 +4,28 @@ include KiYoutrack
|
|
4
4
|
|
5
5
|
describe KiYoutrack::Api do
|
6
6
|
|
7
|
+
let(:config) do
|
8
|
+
Kiseru::ConfigDir.new(:root => SPEC_DIR,
|
9
|
+
:name => SPEC_CONFIG_DIR).config(:ki_youtrack)
|
10
|
+
end
|
11
|
+
|
7
12
|
it "gets JSON for issue", :vcr do
|
8
|
-
|
13
|
+
api = Api.new(config)
|
14
|
+
json = api.issue("KI-1")
|
9
15
|
data = MultiJson.load(json)
|
10
16
|
data['id'].should == 'KI-1'
|
11
17
|
data['ki_type'].should == 'youtrack_issue'
|
12
18
|
end
|
13
19
|
|
14
20
|
it "pretty prints JSON if requested", :vcr do
|
15
|
-
|
21
|
+
api = Api.new(config)
|
22
|
+
json = api.issue("KI-1", :pretty => false)
|
16
23
|
|
17
24
|
pretty_json = MultiJson.dump(MultiJson.load(json), :pretty => true)
|
18
25
|
normal_json = MultiJson.dump(MultiJson.load(json), :pretty => false)
|
19
26
|
|
20
27
|
json.should == normal_json
|
21
|
-
|
28
|
+
api.issue("KI-1", :pretty => true).should == pretty_json
|
22
29
|
end
|
23
30
|
|
24
31
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -13,6 +13,9 @@ require 'construct'
|
|
13
13
|
include Construct::Helpers
|
14
14
|
include KiYoutrack
|
15
15
|
|
16
|
+
SPEC_DIR = File.expand_path(File.dirname(__FILE__))
|
17
|
+
SPEC_CONFIG_DIR = 'configs'
|
18
|
+
|
16
19
|
if [0, 'false', false, 'f', 'n', 'no', 'off'].include?(ENV['VCR'])
|
17
20
|
puts "VCR off"
|
18
21
|
else
|
data/spec/unit/session_spec.rb
CHANGED
@@ -5,8 +5,9 @@ describe KiYoutrack::Session do
|
|
5
5
|
before do
|
6
6
|
# These tests will fail until you create a valid config file
|
7
7
|
# by doing 'ki_youtrack setup'
|
8
|
-
config = Kiseru::
|
9
|
-
|
8
|
+
config = Kiseru::ConfigDir.new(:root => SPEC_DIR,
|
9
|
+
:name => SPEC_CONFIG_DIR).config(:ki_youtrack)
|
10
|
+
@login = config.read(:login)
|
10
11
|
@password = config.read(:password)
|
11
12
|
@subdomain = config.read(:subdomain)
|
12
13
|
end
|
@@ -16,26 +17,23 @@ describe KiYoutrack::Session do
|
|
16
17
|
# a valid subdomain must be supplied otherwise the HTTP
|
17
18
|
# status code will be 404 instead of 403
|
18
19
|
session = Session.new("foo", "bar", @subdomain, :ssl => false)
|
19
|
-
|
20
|
-
|
21
|
-
|
20
|
+
lambda do
|
21
|
+
response = session.init
|
22
|
+
end.should raise_error SessionError, /Authentication failed/
|
22
23
|
end
|
23
24
|
|
24
25
|
it "responds 200 and gets headers if creds are valid", :vcr do
|
25
|
-
session = Session.new(@
|
26
|
+
session = Session.new(@login, @password, @subdomain, :ssl => false)
|
26
27
|
response = session.init
|
27
28
|
response.status.should == 200
|
28
29
|
response.headers["set-cookie"].should_not be_nil
|
29
30
|
session.session_cookies.should == response.headers["set-cookie"]
|
30
31
|
end
|
31
32
|
|
32
|
-
it "uses authentication cookies to get
|
33
|
-
session = Session.new(@
|
33
|
+
it "uses authentication cookies to get issue", :vcr do
|
34
|
+
session = Session.new(@login, @password, @subdomain, :ssl => false)
|
34
35
|
session.init
|
35
|
-
|
36
|
-
response.status.should == 200
|
37
|
-
response.body.should_not be_nil
|
38
|
-
issue = response.body['issue']
|
36
|
+
issue = session.issue("KI-1")
|
39
37
|
issue['id'].should == "KI-1"
|
40
38
|
end
|
41
39
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ki_youtrack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,11 +10,11 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2012-08-
|
13
|
+
date: 2012-08-15 00:00:00.000000000Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: gli
|
17
|
-
requirement: &
|
17
|
+
requirement: &70195634193200 !ruby/object:Gem::Requirement
|
18
18
|
none: false
|
19
19
|
requirements:
|
20
20
|
- - ! '>='
|
@@ -22,10 +22,10 @@ dependencies:
|
|
22
22
|
version: '0'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
|
-
version_requirements: *
|
25
|
+
version_requirements: *70195634193200
|
26
26
|
- !ruby/object:Gem::Dependency
|
27
27
|
name: faraday
|
28
|
-
requirement: &
|
28
|
+
requirement: &70195634192780 !ruby/object:Gem::Requirement
|
29
29
|
none: false
|
30
30
|
requirements:
|
31
31
|
- - ! '>='
|
@@ -33,10 +33,10 @@ dependencies:
|
|
33
33
|
version: '0'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
|
-
version_requirements: *
|
36
|
+
version_requirements: *70195634192780
|
37
37
|
- !ruby/object:Gem::Dependency
|
38
38
|
name: faraday_middleware
|
39
|
-
requirement: &
|
39
|
+
requirement: &70195634192360 !ruby/object:Gem::Requirement
|
40
40
|
none: false
|
41
41
|
requirements:
|
42
42
|
- - ! '>='
|
@@ -44,10 +44,10 @@ dependencies:
|
|
44
44
|
version: '0'
|
45
45
|
type: :runtime
|
46
46
|
prerelease: false
|
47
|
-
version_requirements: *
|
47
|
+
version_requirements: *70195634192360
|
48
48
|
- !ruby/object:Gem::Dependency
|
49
49
|
name: multi_xml
|
50
|
-
requirement: &
|
50
|
+
requirement: &70195634191940 !ruby/object:Gem::Requirement
|
51
51
|
none: false
|
52
52
|
requirements:
|
53
53
|
- - ! '>='
|
@@ -55,10 +55,10 @@ dependencies:
|
|
55
55
|
version: '0'
|
56
56
|
type: :runtime
|
57
57
|
prerelease: false
|
58
|
-
version_requirements: *
|
58
|
+
version_requirements: *70195634191940
|
59
59
|
- !ruby/object:Gem::Dependency
|
60
60
|
name: multi_json
|
61
|
-
requirement: &
|
61
|
+
requirement: &70195611982480 !ruby/object:Gem::Requirement
|
62
62
|
none: false
|
63
63
|
requirements:
|
64
64
|
- - ! '>='
|
@@ -66,10 +66,10 @@ dependencies:
|
|
66
66
|
version: '0'
|
67
67
|
type: :runtime
|
68
68
|
prerelease: false
|
69
|
-
version_requirements: *
|
69
|
+
version_requirements: *70195611982480
|
70
70
|
- !ruby/object:Gem::Dependency
|
71
71
|
name: highline
|
72
|
-
requirement: &
|
72
|
+
requirement: &70195611982060 !ruby/object:Gem::Requirement
|
73
73
|
none: false
|
74
74
|
requirements:
|
75
75
|
- - ! '>='
|
@@ -77,10 +77,10 @@ dependencies:
|
|
77
77
|
version: '0'
|
78
78
|
type: :runtime
|
79
79
|
prerelease: false
|
80
|
-
version_requirements: *
|
80
|
+
version_requirements: *70195611982060
|
81
81
|
- !ruby/object:Gem::Dependency
|
82
82
|
name: debugger
|
83
|
-
requirement: &
|
83
|
+
requirement: &70195611981640 !ruby/object:Gem::Requirement
|
84
84
|
none: false
|
85
85
|
requirements:
|
86
86
|
- - ! '>='
|
@@ -88,10 +88,21 @@ dependencies:
|
|
88
88
|
version: '0'
|
89
89
|
type: :development
|
90
90
|
prerelease: false
|
91
|
-
version_requirements: *
|
91
|
+
version_requirements: *70195611981640
|
92
|
+
- !ruby/object:Gem::Dependency
|
93
|
+
name: rake
|
94
|
+
requirement: &70195611981220 !ruby/object:Gem::Requirement
|
95
|
+
none: false
|
96
|
+
requirements:
|
97
|
+
- - ! '>='
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '0'
|
100
|
+
type: :development
|
101
|
+
prerelease: false
|
102
|
+
version_requirements: *70195611981220
|
92
103
|
- !ruby/object:Gem::Dependency
|
93
104
|
name: rspec
|
94
|
-
requirement: &
|
105
|
+
requirement: &70195611980800 !ruby/object:Gem::Requirement
|
95
106
|
none: false
|
96
107
|
requirements:
|
97
108
|
- - ! '>='
|
@@ -99,10 +110,10 @@ dependencies:
|
|
99
110
|
version: '0'
|
100
111
|
type: :development
|
101
112
|
prerelease: false
|
102
|
-
version_requirements: *
|
113
|
+
version_requirements: *70195611980800
|
103
114
|
- !ruby/object:Gem::Dependency
|
104
115
|
name: simplecov
|
105
|
-
requirement: &
|
116
|
+
requirement: &70195611980380 !ruby/object:Gem::Requirement
|
106
117
|
none: false
|
107
118
|
requirements:
|
108
119
|
- - ! '>='
|
@@ -110,10 +121,10 @@ dependencies:
|
|
110
121
|
version: '0'
|
111
122
|
type: :development
|
112
123
|
prerelease: false
|
113
|
-
version_requirements: *
|
124
|
+
version_requirements: *70195611980380
|
114
125
|
- !ruby/object:Gem::Dependency
|
115
126
|
name: test-construct
|
116
|
-
requirement: &
|
127
|
+
requirement: &70195611979960 !ruby/object:Gem::Requirement
|
117
128
|
none: false
|
118
129
|
requirements:
|
119
130
|
- - ! '>='
|
@@ -121,10 +132,10 @@ dependencies:
|
|
121
132
|
version: '0'
|
122
133
|
type: :development
|
123
134
|
prerelease: false
|
124
|
-
version_requirements: *
|
135
|
+
version_requirements: *70195611979960
|
125
136
|
- !ruby/object:Gem::Dependency
|
126
137
|
name: vcr
|
127
|
-
requirement: &
|
138
|
+
requirement: &70195611979540 !ruby/object:Gem::Requirement
|
128
139
|
none: false
|
129
140
|
requirements:
|
130
141
|
- - ! '>='
|
@@ -132,10 +143,10 @@ dependencies:
|
|
132
143
|
version: '0'
|
133
144
|
type: :development
|
134
145
|
prerelease: false
|
135
|
-
version_requirements: *
|
146
|
+
version_requirements: *70195611979540
|
136
147
|
- !ruby/object:Gem::Dependency
|
137
148
|
name: webmock
|
138
|
-
requirement: &
|
149
|
+
requirement: &70195611979120 !ruby/object:Gem::Requirement
|
139
150
|
none: false
|
140
151
|
requirements:
|
141
152
|
- - ! '>='
|
@@ -143,7 +154,7 @@ dependencies:
|
|
143
154
|
version: '0'
|
144
155
|
type: :development
|
145
156
|
prerelease: false
|
146
|
-
version_requirements: *
|
157
|
+
version_requirements: *70195611979120
|
147
158
|
description: Kiseru YouTrack client
|
148
159
|
email:
|
149
160
|
- ben@freeagent.com
|
@@ -164,6 +175,7 @@ files:
|
|
164
175
|
- lib/ki_youtrack.rb
|
165
176
|
- lib/ki_youtrack/api.rb
|
166
177
|
- lib/ki_youtrack/creds.rb
|
178
|
+
- lib/ki_youtrack/initializer.rb
|
167
179
|
- lib/ki_youtrack/issue_filter.rb
|
168
180
|
- lib/ki_youtrack/kiseru.rb
|
169
181
|
- lib/ki_youtrack/session.rb
|