ki_youtrack 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|