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 CHANGED
@@ -16,3 +16,4 @@ test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
18
  spec/fixtures
19
+ spec/configs
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
- json = KiYoutrack::Api.issue(id, :pretty => pretty)
37
- $stdout.puts(json)
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
- desc 'Set up config file'
42
- command :setup do |c|
43
- c.action do |global_options, options, args|
44
- config = Kiseru::Config[:ki_youtrack]
45
-
46
- ui = HighLine.new
47
-
48
- username = config.read(:username) || ui.ask("Username: ")
49
- password = config.read(:password) || ui.ask("Password: ") { |q| q.echo = false }
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
- config.write(:username, username)
53
- config.write(:password, password)
54
- config.write(:subdomain, subdomain)
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')
@@ -2,17 +2,26 @@ module KiYoutrack
2
2
 
3
3
  class Api
4
4
 
5
- def self.issue(id, opts = {})
6
- config = Kiseru::Config[:ki_youtrack]
7
- username = config.read(:username)
8
- password = config.read(:password)
9
- subdomain = config.read(:subdomain)
10
- ssl = config.read(:ssl)
11
- session = Session.new(username, password, subdomain, :ssl => ssl)
12
- session.init
13
- response = session.get_bug(id)
14
-
15
- filtered_data = IssueFilter.filter(response.body['issue'])
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
@@ -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
- DIR_NAME = '.kiseru'
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 + DIR_NAME
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
- file_path = (root_path + "#{app_name}.yml").to_s
31
- @store = YAML::Store.new(file_path)
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, time)
57
+ def write(key, value)
35
58
  @store.transaction do
36
- @store[key] = time
59
+ @store[key] = value
37
60
  end
38
61
  end
39
62
 
@@ -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(username, password, subdomain, opts = {})
17
+ def initialize(login, password, subdomain, opts = {})
16
18
  ssl = opts.fetch(:ssl, true)
17
- @username = username
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 => @username,
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 get_bug(id)
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
@@ -1,3 +1,3 @@
1
1
  module KiYoutrack
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
data/lib/ki_youtrack.rb CHANGED
@@ -10,6 +10,7 @@ autoload :Kiseru, 'ki_youtrack/kiseru'
10
10
 
11
11
  module KiYoutrack
12
12
 
13
+ autoload :Initializer, 'ki_youtrack/initializer'
13
14
  autoload :Api, 'ki_youtrack/api'
14
15
  autoload :Creds, 'ki_youtrack/creds'
15
16
  autoload :Session, 'ki_youtrack/session'
@@ -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
- json = Api.issue("KI-1")
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
- json = Api.issue("KI-1", :pretty => false)
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
- Api.issue("KI-1", :pretty => true).should == pretty_json
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
@@ -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::Config[:ki_youtrack]
9
- @username = config.read(:username)
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
- response = session.init
20
- response.status.should == 403
21
- response.body['error'].should match /Incorrect login or password/
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(@username, @password, @subdomain, :ssl => false)
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 bug", :vcr do
33
- session = Session.new(@username, @password, @subdomain, :ssl => false)
33
+ it "uses authentication cookies to get issue", :vcr do
34
+ session = Session.new(@login, @password, @subdomain, :ssl => false)
34
35
  session.init
35
- response = session.get_bug("KI-1")
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.1
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-14 00:00:00.000000000Z
13
+ date: 2012-08-15 00:00:00.000000000Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: gli
17
- requirement: &70324410656340 !ruby/object:Gem::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: *70324410656340
25
+ version_requirements: *70195634193200
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: faraday
28
- requirement: &70324410655920 !ruby/object:Gem::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: *70324410655920
36
+ version_requirements: *70195634192780
37
37
  - !ruby/object:Gem::Dependency
38
38
  name: faraday_middleware
39
- requirement: &70324410655500 !ruby/object:Gem::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: *70324410655500
47
+ version_requirements: *70195634192360
48
48
  - !ruby/object:Gem::Dependency
49
49
  name: multi_xml
50
- requirement: &70324410655080 !ruby/object:Gem::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: *70324410655080
58
+ version_requirements: *70195634191940
59
59
  - !ruby/object:Gem::Dependency
60
60
  name: multi_json
61
- requirement: &70324410654660 !ruby/object:Gem::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: *70324410654660
69
+ version_requirements: *70195611982480
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: highline
72
- requirement: &70324410654240 !ruby/object:Gem::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: *70324410654240
80
+ version_requirements: *70195611982060
81
81
  - !ruby/object:Gem::Dependency
82
82
  name: debugger
83
- requirement: &70324410653820 !ruby/object:Gem::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: *70324410653820
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: &70324410653400 !ruby/object:Gem::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: *70324410653400
113
+ version_requirements: *70195611980800
103
114
  - !ruby/object:Gem::Dependency
104
115
  name: simplecov
105
- requirement: &70324410652980 !ruby/object:Gem::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: *70324410652980
124
+ version_requirements: *70195611980380
114
125
  - !ruby/object:Gem::Dependency
115
126
  name: test-construct
116
- requirement: &70324410652560 !ruby/object:Gem::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: *70324410652560
135
+ version_requirements: *70195611979960
125
136
  - !ruby/object:Gem::Dependency
126
137
  name: vcr
127
- requirement: &70324410652140 !ruby/object:Gem::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: *70324410652140
146
+ version_requirements: *70195611979540
136
147
  - !ruby/object:Gem::Dependency
137
148
  name: webmock
138
- requirement: &70324410651720 !ruby/object:Gem::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: *70324410651720
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