keyrack 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,2 @@
1
+ neww -n 'autotest' 'autotest'
2
+ neww -n 'vim' 'vim'
@@ -17,24 +17,27 @@ The configuration file is a YAML file that requires the following data:
17
17
 
18
18
  === Store types
19
19
 
20
- * *filesystem*
21
- * Required options:
22
- * *path*: path to the keyrack database
23
- * +ssh+
24
- * Required options:
25
- * *host*: host name
26
- * *user*: user name
27
- * *path*: path to the keyrack database on remote host
20
+ ==== filesystem
21
+ * Required options:
22
+ * *path*: path to the keyrack database
23
+
24
+ ==== ssh
25
+ * Required options:
26
+ * *host*: host name
27
+ * *user*: user name
28
+ * *path*: path to the keyrack database on remote host
28
29
 
29
30
  === Examples
30
31
 
31
- Filesystem example
32
+ ==== Filesystem example
33
+
32
34
  store:
33
35
  type: filesystem
34
36
  path: ~/.keyrack/database
35
37
  key: ~/.keyrack/id_rsa
36
38
 
37
- SSH example
39
+ ==== SSH example
40
+
38
41
  store:
39
42
  type: ssh
40
43
  host: example.com
@@ -46,8 +49,23 @@ SSH example
46
49
 
47
50
  keyrack [-c path-to-config]
48
51
 
49
- By default, keyrack will look for <b>~/.keyrack/config</b>. The database file
50
- (merely a RSA-encrypted YAML file) will be created on save if it doesn't exist.
52
+ By default, Keyrack will look for <b>~/.keyrack/config</b>. The database file
53
+ (merely a RSA-encrypted Ruby hash) will be created on save if it doesn't exist.
54
+ It's a good idea to generate a seperate RSA key for use with Keyrack, especially
55
+ if you are using the SSH store and are connecting from multiple locations. To
56
+ generate a key, try: <code>ssh-keygen -C keyrack -f ~/.keyrack/id_rsa</code>
57
+
58
+ Starting keyrack will display a simple menu in your terminal, like this:
59
+
60
+ 1. Twitter [foobar]
61
+ 2. Facebook [foobar@example.com]
62
+ 3. Twitter [otherfoobar]
63
+ n. Add new
64
+ s. Save
65
+ q. Quit
66
+
67
+ Selecting <b>1</b> in this case will copy the Twitter password for the foobar user
68
+ to your clipboard.
51
69
 
52
70
  == Contributing to keyrack
53
71
 
data/Rakefile CHANGED
@@ -23,14 +23,14 @@ Jeweler::Tasks.new do |gem|
23
23
  # and development dependencies are only needed for development (ie running rake tasks, tests, etc)
24
24
  # gem.add_runtime_dependency 'jabber4r', '> 0.1'
25
25
  # gem.add_development_dependency 'rspec', '> 1.2.3'
26
- gem.add_runtime_dependency 'net-scp'
27
- gem.add_runtime_dependency 'highline'
28
- gem.add_runtime_dependency 'clipboard'
29
- gem.add_development_dependency 'rspec', '> 1.2.3'
30
- gem.add_development_dependency "bundler", "~> 1.0.0"
31
- gem.add_development_dependency "jeweler", "~> 1.5.1"
32
- gem.add_development_dependency "rcov", ">= 0"
33
- gem.add_development_dependency "mocha"
26
+ # gem.add_runtime_dependency 'net-scp'
27
+ # gem.add_runtime_dependency 'highline'
28
+ # gem.add_runtime_dependency 'clipboard'
29
+ # gem.add_development_dependency 'rspec', '> 1.2.3'
30
+ # gem.add_development_dependency "bundler", "~> 1.0.0"
31
+ # gem.add_development_dependency "jeweler", "~> 1.5.1"
32
+ # gem.add_development_dependency "rcov", ">= 0"
33
+ # gem.add_development_dependency "mocha"
34
34
  end
35
35
  Jeweler::RubygemsDotOrgTasks.new
36
36
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.1
1
+ 0.1.2
@@ -0,0 +1,97 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{keyrack}
8
+ s.version = "0.1.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Jeremy Stephens"]
12
+ s.date = %q{2010-12-12}
13
+ s.default_executable = %q{keyrack}
14
+ s.description = %q{Simple password manager with local/remote database storage and RSA encryption.}
15
+ s.email = %q{viking@pillageandplunder.net}
16
+ s.executables = ["keyrack"]
17
+ s.extra_rdoc_files = [
18
+ "LICENSE.txt",
19
+ "README.rdoc"
20
+ ]
21
+ s.files = [
22
+ ".document",
23
+ ".rvmrc",
24
+ "Gemfile",
25
+ "Gemfile.lock",
26
+ "LICENSE.txt",
27
+ "README.rdoc",
28
+ "Rakefile",
29
+ "VERSION",
30
+ "bin/keyrack",
31
+ "lib/keyrack.rb",
32
+ "lib/keyrack/database.rb",
33
+ "lib/keyrack/runner.rb",
34
+ "lib/keyrack/store.rb",
35
+ "lib/keyrack/store/filesystem.rb",
36
+ "lib/keyrack/store/ssh.rb",
37
+ "lib/keyrack/ui.rb",
38
+ "lib/keyrack/ui/console.rb",
39
+ "test/fixtures/config.yml",
40
+ "test/fixtures/foo.txt",
41
+ "test/fixtures/id_rsa",
42
+ "test/fixtures/id_rsa.pub",
43
+ "test/helper.rb",
44
+ "test/keyrack/store/test_filesystem.rb",
45
+ "test/keyrack/store/test_ssh.rb",
46
+ "test/keyrack/test_database.rb",
47
+ "test/keyrack/test_runner.rb",
48
+ "test/keyrack/test_store.rb",
49
+ "test/keyrack/ui/test_console.rb"
50
+ ]
51
+ s.homepage = %q{http://github.com/viking/keyrack}
52
+ s.licenses = ["MIT"]
53
+ s.require_paths = ["lib"]
54
+ s.rubygems_version = %q{1.3.7}
55
+ s.summary = %q{Simple password manager}
56
+ s.test_files = [
57
+ "test/helper.rb",
58
+ "test/keyrack/store/test_filesystem.rb",
59
+ "test/keyrack/store/test_ssh.rb",
60
+ "test/keyrack/test_database.rb",
61
+ "test/keyrack/test_runner.rb",
62
+ "test/keyrack/test_store.rb",
63
+ "test/keyrack/ui/test_console.rb"
64
+ ]
65
+
66
+ if s.respond_to? :specification_version then
67
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
68
+ s.specification_version = 3
69
+
70
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
71
+ s.add_runtime_dependency(%q<net-scp>, [">= 0"])
72
+ s.add_runtime_dependency(%q<highline>, [">= 0"])
73
+ s.add_runtime_dependency(%q<clipboard>, [">= 0"])
74
+ s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
75
+ s.add_development_dependency(%q<jeweler>, ["~> 1.5.1"])
76
+ s.add_development_dependency(%q<rcov>, [">= 0"])
77
+ s.add_development_dependency(%q<mocha>, [">= 0"])
78
+ else
79
+ s.add_dependency(%q<net-scp>, [">= 0"])
80
+ s.add_dependency(%q<highline>, [">= 0"])
81
+ s.add_dependency(%q<clipboard>, [">= 0"])
82
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
83
+ s.add_dependency(%q<jeweler>, ["~> 1.5.1"])
84
+ s.add_dependency(%q<rcov>, [">= 0"])
85
+ s.add_dependency(%q<mocha>, [">= 0"])
86
+ end
87
+ else
88
+ s.add_dependency(%q<net-scp>, [">= 0"])
89
+ s.add_dependency(%q<highline>, [">= 0"])
90
+ s.add_dependency(%q<clipboard>, [">= 0"])
91
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
92
+ s.add_dependency(%q<jeweler>, ["~> 1.5.1"])
93
+ s.add_dependency(%q<rcov>, [">= 0"])
94
+ s.add_dependency(%q<mocha>, [">= 0"])
95
+ end
96
+ end
97
+
@@ -8,6 +8,7 @@ require 'clipboard'
8
8
  module Keyrack
9
9
  end
10
10
 
11
+ require File.dirname(__FILE__) + '/keyrack/utils'
11
12
  require File.dirname(__FILE__) + '/keyrack/database'
12
13
  require File.dirname(__FILE__) + '/keyrack/store'
13
14
  require File.dirname(__FILE__) + '/keyrack/ui'
@@ -6,10 +6,12 @@ module Keyrack
6
6
  key_path = File.expand_path(config['key'])
7
7
  @key = OpenSSL::PKey::RSA.new(File.read(key_path), config['password'])
8
8
  @data = decrypt
9
+ @dirty = false
9
10
  end
10
11
 
11
12
  def add(site, username, password)
12
13
  @data[site] = { :username => username, :password => password }
14
+ @dirty = true
13
15
  end
14
16
 
15
17
  def get(site)
@@ -20,8 +22,13 @@ module Keyrack
20
22
  @data.keys
21
23
  end
22
24
 
25
+ def dirty?
26
+ @dirty
27
+ end
28
+
23
29
  def save
24
30
  @store.write(@key.public_encrypt(Marshal.dump(@data)))
31
+ @dirty = false
25
32
  end
26
33
 
27
34
  private
@@ -12,7 +12,7 @@ module Keyrack
12
12
 
13
13
  def menu
14
14
  entries = []
15
- choices = %w{n s q}
15
+ choices = %w{n q}
16
16
  @database.sites.each_with_index do |site, i|
17
17
  entry = @database.get(site)
18
18
  entries << entry
@@ -20,7 +20,10 @@ module Keyrack
20
20
  @highline.say("% 2d. %s [%s]" % [i+1, site, entry[:username]])
21
21
  end
22
22
  @highline.say(" n. Add new")
23
- @highline.say(" s. Save")
23
+ if @database.dirty?
24
+ @highline.say(" s. Save")
25
+ choices << "s"
26
+ end
24
27
  @highline.say(" q. Quit")
25
28
  result = @highline.ask(" ? ") { |q| q.in = choices }
26
29
  case result
@@ -29,7 +32,11 @@ module Keyrack
29
32
  when "s"
30
33
  :save
31
34
  when "q"
32
- :quit
35
+ if @database.dirty? && !@highline.agree("Really quit? You have unsaved changes! [yn] ")
36
+ nil
37
+ else
38
+ :quit
39
+ end
33
40
  else
34
41
  Clipboard.copy(entries[result.to_i - 1][:password])
35
42
  @highline.say("The password has been copied to your clipboard.")
@@ -39,9 +46,27 @@ module Keyrack
39
46
 
40
47
  def get_new_entry
41
48
  result = {}
42
- result[:site] = @highline.ask("Site: ")
49
+ result[:site] = @highline.ask("Label: ")
43
50
  result[:username] = @highline.ask("Username: ")
44
- result[:password] = @highline.ask("Password: ")
51
+ if @highline.agree("Generate password? [yn] ")
52
+ loop do
53
+ password = Utils.generate_password
54
+ if @highline.agree("Generated #{@highline.color(password, :blue)}. Sound good? [yn] ")
55
+ result[:password] = password
56
+ break
57
+ end
58
+ end
59
+ else
60
+ loop do
61
+ password = @highline.ask("Password: ") { |q| q.echo = false }
62
+ confirmation = @highline.ask("Password (again): ") { |q| q.echo = false }
63
+ if password == confirmation
64
+ result[:password] = password
65
+ break
66
+ end
67
+ @highline.say("Passwords didn't match. Try again!")
68
+ end
69
+ end
45
70
  result
46
71
  end
47
72
  end
@@ -0,0 +1,11 @@
1
+ module Keyrack
2
+ module Utils
3
+ def self.generate_password
4
+ result = " "
5
+ result.length.times do |i|
6
+ result[i] = (33 + rand(94)).chr
7
+ end
8
+ result
9
+ end
10
+ end
11
+ end
@@ -34,5 +34,11 @@ module Keyrack
34
34
  def test_sites
35
35
  assert_equal(%w{Twitter}, @database.sites)
36
36
  end
37
+
38
+ def test_dirty
39
+ assert !@database.dirty?
40
+ @database.add('Foo', 'bar', 'baz')
41
+ assert @database.dirty?
42
+ end
37
43
  end
38
44
  end
@@ -0,0 +1,10 @@
1
+ require 'helper'
2
+
3
+ module Keyrack
4
+ class TestUtils < Test::Unit::TestCase
5
+ def test_generate_password
6
+ result = Utils.generate_password
7
+ assert_match result, /^[!-~]{8}$/
8
+ end
9
+ end
10
+ end
@@ -22,11 +22,10 @@ module Keyrack
22
22
 
23
23
  highline.expects(:say).with(" 1. Twitter [username]")
24
24
  highline.expects(:say).with(" n. Add new")
25
- highline.expects(:say).with(" s. Save")
26
25
  highline.expects(:say).with(" q. Quit")
27
26
 
28
27
  question = mock('question')
29
- question.expects(:in=).with(%w{n s q 1})
28
+ question.expects(:in=).with(%w{n q 1})
30
29
  highline.expects(:ask).yields(question).returns('1')
31
30
  Clipboard.expects(:copy).with('password')
32
31
  highline.expects(:say).with("The password has been copied to your clipboard.")
@@ -41,11 +40,10 @@ module Keyrack
41
40
 
42
41
  highline.expects(:say).with(" 1. Twitter [username]")
43
42
  highline.expects(:say).with(" n. Add new")
44
- highline.expects(:say).with(" s. Save")
45
43
  highline.expects(:say).with(" q. Quit")
46
44
 
47
45
  question = mock('question')
48
- question.expects(:in=).with(%w{n s q 1})
46
+ question.expects(:in=).with(%w{n q 1})
49
47
  highline.expects(:ask).yields(question).returns('n')
50
48
  assert_equal :new, console.menu
51
49
  end
@@ -58,20 +56,38 @@ module Keyrack
58
56
 
59
57
  highline.expects(:say).with(" 1. Twitter [username]")
60
58
  highline.expects(:say).with(" n. Add new")
61
- highline.expects(:say).with(" s. Save")
62
59
  highline.expects(:say).with(" q. Quit")
63
60
 
64
61
  question = mock('question')
65
- question.expects(:in=).with(%w{n s q 1})
62
+ question.expects(:in=).with(%w{n q 1})
66
63
  highline.expects(:ask).yields(question).returns('q')
67
64
  assert_equal :quit, console.menu
68
65
  end
69
66
 
67
+ def test_select_quit_from_menu_when_database_is_dirty
68
+ highline = mock('highline')
69
+ HighLine.expects(:new).returns(highline)
70
+ console = Console.new
71
+ console.database = @database
72
+ @database.stubs(:dirty?).returns(true)
73
+
74
+ highline.expects(:say).with(" 1. Twitter [username]")
75
+ highline.expects(:say).with(" n. Add new")
76
+ highline.expects(:say).with(" s. Save")
77
+ highline.expects(:say).with(" q. Quit")
78
+
79
+ question = mock('question', :in= => nil)
80
+ highline.expects(:ask).yields(question).returns('q')
81
+ highline.expects(:agree).with("Really quit? You have unsaved changes! [yn] ").returns(false)
82
+ assert_equal nil, console.menu
83
+ end
84
+
70
85
  def test_select_save_from_menu
71
86
  highline = mock('highline')
72
87
  HighLine.expects(:new).returns(highline)
73
88
  console = Console.new
74
89
  console.database = @database
90
+ @database.stubs(:dirty?).returns(true)
75
91
 
76
92
  highline.expects(:say).with(" 1. Twitter [username]")
77
93
  highline.expects(:say).with(" n. Add new")
@@ -79,7 +95,7 @@ module Keyrack
79
95
  highline.expects(:say).with(" q. Quit")
80
96
 
81
97
  question = mock('question')
82
- question.expects(:in=).with(%w{n s q 1})
98
+ question.expects(:in=).with(%w{n q 1 s})
83
99
  highline.expects(:ask).yields(question).returns('s')
84
100
  assert_equal :save, console.menu
85
101
  end
@@ -95,16 +111,40 @@ module Keyrack
95
111
  assert_equal "foobar", console.get_password
96
112
  end
97
113
 
98
- def test_get_new_entry
114
+ def test_get_new_entry_with_manual_password
99
115
  highline = mock('highline')
100
116
  HighLine.expects(:new).returns(highline)
101
117
  console = Console.new
102
118
 
103
- highline.expects(:ask).with("Site: ").returns("Foo")
104
- highline.expects(:ask).with("Username: ").returns("bar")
105
- highline.expects(:ask).with("Password: ").returns("baz")
119
+ seq = sequence("new entry")
120
+ highline.expects(:ask).with("Label: ").returns("Foo").in_sequence(seq)
121
+ highline.expects(:ask).with("Username: ").returns("bar").in_sequence(seq)
122
+ highline.expects(:agree).with("Generate password? [yn] ").returns(false).in_sequence(seq)
123
+ highline.expects(:ask).with("Password: ").yields(mock { expects(:echo=).with(false) }).returns("baz").in_sequence(seq)
124
+ highline.expects(:ask).with("Password (again): ").yields(mock { expects(:echo=).with(false) }).returns("bar").in_sequence(seq)
125
+ highline.expects(:say).with("Passwords didn't match. Try again!").in_sequence(seq)
126
+ highline.expects(:ask).with("Password: ").yields(mock { expects(:echo=).with(false) }).returns("baz").in_sequence(seq)
127
+ highline.expects(:ask).with("Password (again): ").yields(mock { expects(:echo=).with(false) }).returns("baz").in_sequence(seq)
106
128
  assert_equal({:site => "Foo", :username => "bar", :password => "baz"}, console.get_new_entry)
107
129
  end
130
+
131
+ def test_get_new_entry_generated_password
132
+ highline = mock('highline')
133
+ HighLine.expects(:new).returns(highline)
134
+ console = Console.new
135
+
136
+ seq = sequence("new entry")
137
+ highline.expects(:ask).with("Label: ").returns("Foo").in_sequence(seq)
138
+ highline.expects(:ask).with("Username: ").returns("bar").in_sequence(seq)
139
+ highline.expects(:agree).with("Generate password? [yn] ").returns(true).in_sequence(seq)
140
+ Utils.expects(:generate_password).returns('foobar').in_sequence(seq)
141
+ highline.expects(:color).with('foobar', :blue).returns('bluefoobar').in_sequence(seq)
142
+ highline.expects(:agree).with("Generated bluefoobar. Sound good? [yn] ").returns(false).in_sequence(seq)
143
+ Utils.expects(:generate_password).returns('foobar').in_sequence(seq)
144
+ highline.expects(:color).with('foobar', :blue).returns('bluefoobar').in_sequence(seq)
145
+ highline.expects(:agree).with("Generated bluefoobar. Sound good? [yn] ").returns(true).in_sequence(seq)
146
+ assert_equal({:site => "Foo", :username => "bar", :password => "foobar"}, console.get_new_entry)
147
+ end
108
148
  end
109
149
  end
110
150
  end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 1
8
- - 1
9
- version: 0.1.1
8
+ - 2
9
+ version: 0.1.2
10
10
  platform: ruby
11
11
  authors:
12
12
  - Jeremy Stephens
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-12-12 00:00:00 -06:00
17
+ date: 2010-12-13 00:00:00 -06:00
18
18
  default_executable: keyrack
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -112,116 +112,6 @@ dependencies:
112
112
  type: :development
113
113
  prerelease: false
114
114
  version_requirements: *id007
115
- - !ruby/object:Gem::Dependency
116
- name: net-scp
117
- requirement: &id008 !ruby/object:Gem::Requirement
118
- none: false
119
- requirements:
120
- - - ">="
121
- - !ruby/object:Gem::Version
122
- segments:
123
- - 0
124
- version: "0"
125
- type: :runtime
126
- prerelease: false
127
- version_requirements: *id008
128
- - !ruby/object:Gem::Dependency
129
- name: highline
130
- requirement: &id009 !ruby/object:Gem::Requirement
131
- none: false
132
- requirements:
133
- - - ">="
134
- - !ruby/object:Gem::Version
135
- segments:
136
- - 0
137
- version: "0"
138
- type: :runtime
139
- prerelease: false
140
- version_requirements: *id009
141
- - !ruby/object:Gem::Dependency
142
- name: clipboard
143
- requirement: &id010 !ruby/object:Gem::Requirement
144
- none: false
145
- requirements:
146
- - - ">="
147
- - !ruby/object:Gem::Version
148
- segments:
149
- - 0
150
- version: "0"
151
- type: :runtime
152
- prerelease: false
153
- version_requirements: *id010
154
- - !ruby/object:Gem::Dependency
155
- name: rspec
156
- requirement: &id011 !ruby/object:Gem::Requirement
157
- none: false
158
- requirements:
159
- - - ">"
160
- - !ruby/object:Gem::Version
161
- segments:
162
- - 1
163
- - 2
164
- - 3
165
- version: 1.2.3
166
- type: :development
167
- prerelease: false
168
- version_requirements: *id011
169
- - !ruby/object:Gem::Dependency
170
- name: bundler
171
- requirement: &id012 !ruby/object:Gem::Requirement
172
- none: false
173
- requirements:
174
- - - ~>
175
- - !ruby/object:Gem::Version
176
- segments:
177
- - 1
178
- - 0
179
- - 0
180
- version: 1.0.0
181
- type: :development
182
- prerelease: false
183
- version_requirements: *id012
184
- - !ruby/object:Gem::Dependency
185
- name: jeweler
186
- requirement: &id013 !ruby/object:Gem::Requirement
187
- none: false
188
- requirements:
189
- - - ~>
190
- - !ruby/object:Gem::Version
191
- segments:
192
- - 1
193
- - 5
194
- - 1
195
- version: 1.5.1
196
- type: :development
197
- prerelease: false
198
- version_requirements: *id013
199
- - !ruby/object:Gem::Dependency
200
- name: rcov
201
- requirement: &id014 !ruby/object:Gem::Requirement
202
- none: false
203
- requirements:
204
- - - ">="
205
- - !ruby/object:Gem::Version
206
- segments:
207
- - 0
208
- version: "0"
209
- type: :development
210
- prerelease: false
211
- version_requirements: *id014
212
- - !ruby/object:Gem::Dependency
213
- name: mocha
214
- requirement: &id015 !ruby/object:Gem::Requirement
215
- none: false
216
- requirements:
217
- - - ">="
218
- - !ruby/object:Gem::Version
219
- segments:
220
- - 0
221
- version: "0"
222
- type: :development
223
- prerelease: false
224
- version_requirements: *id015
225
115
  description: Simple password manager with local/remote database storage and RSA encryption.
226
116
  email: viking@pillageandplunder.net
227
117
  executables:
@@ -234,6 +124,7 @@ extra_rdoc_files:
234
124
  files:
235
125
  - .document
236
126
  - .rvmrc
127
+ - .tmux.conf
237
128
  - Gemfile
238
129
  - Gemfile.lock
239
130
  - LICENSE.txt
@@ -241,6 +132,7 @@ files:
241
132
  - Rakefile
242
133
  - VERSION
243
134
  - bin/keyrack
135
+ - keyrack.gemspec
244
136
  - lib/keyrack.rb
245
137
  - lib/keyrack/database.rb
246
138
  - lib/keyrack/runner.rb
@@ -249,6 +141,7 @@ files:
249
141
  - lib/keyrack/store/ssh.rb
250
142
  - lib/keyrack/ui.rb
251
143
  - lib/keyrack/ui/console.rb
144
+ - lib/keyrack/utils.rb
252
145
  - test/fixtures/config.yml
253
146
  - test/fixtures/foo.txt
254
147
  - test/fixtures/id_rsa
@@ -259,6 +152,7 @@ files:
259
152
  - test/keyrack/test_database.rb
260
153
  - test/keyrack/test_runner.rb
261
154
  - test/keyrack/test_store.rb
155
+ - test/keyrack/test_utils.rb
262
156
  - test/keyrack/ui/test_console.rb
263
157
  has_rdoc: true
264
158
  homepage: http://github.com/viking/keyrack
@@ -274,7 +168,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
274
168
  requirements:
275
169
  - - ">="
276
170
  - !ruby/object:Gem::Version
277
- hash: -3950856831119826099
171
+ hash: 528577741293551689
278
172
  segments:
279
173
  - 0
280
174
  version: "0"
@@ -300,4 +194,5 @@ test_files:
300
194
  - test/keyrack/test_database.rb
301
195
  - test/keyrack/test_runner.rb
302
196
  - test/keyrack/test_store.rb
197
+ - test/keyrack/test_utils.rb
303
198
  - test/keyrack/ui/test_console.rb