gas 0.1.8 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,110 @@
1
+ require 'fileutils'
2
+
3
+ module Gas
4
+
5
+ # Class that keeps track of users
6
+ class Users
7
+ attr_reader :users
8
+
9
+ # Initializes the object. If no users are supplied we look for a config file, if none then create it, and parse it to load users
10
+ # @param [String] config_file The path to the file that stores users
11
+ def initialize(config_file)
12
+ @config_file = config_file
13
+ @users = []
14
+
15
+ setup!
16
+ end
17
+
18
+ # Checks if a user with _nickname_ exists
19
+ # @param [String] nickname
20
+ # @return [Boolean]
21
+ def exists?(nickname)
22
+ users.each do |user|
23
+ if user.nickname == nickname
24
+ return true;
25
+ end
26
+ end
27
+
28
+ false
29
+ end
30
+
31
+ # Returns the user with nickname nil if no such user exists
32
+ # @param [String|Symbol] nickname
33
+ # @return [User|nil]
34
+ def get(nickname)
35
+ users.each do |user|
36
+ if user.nickname == nickname.to_s
37
+ return user
38
+ end
39
+ end
40
+
41
+ nil
42
+ end
43
+
44
+ # Override [] to get hash style acces to users
45
+ # @param [String|Symbol] nickname
46
+ # @return [User|nil]
47
+ def [](nickname)
48
+ get nickname
49
+ end
50
+
51
+ # Adds a user
52
+ # @param [User]
53
+ def add(user)
54
+ @users << user
55
+ end
56
+
57
+ # Deletes a user by nickname
58
+ # @param [String] nickname The nickname of the user to delete
59
+ def delete(nickname)
60
+ @users.delete_if do |user|
61
+ user.nickname == nickname
62
+ end
63
+ end
64
+
65
+ # Saves the current users to the config file
66
+ def save!
67
+ File.open @config_file, 'w' do |file|
68
+ file.write self
69
+ end
70
+ end
71
+
72
+ # Override to_s to output correct format
73
+ def to_s
74
+ current_user = GitConfig.current_user
75
+ users.map do |user|
76
+ if current_user == user
77
+ " ==> #{user.to_s[5,user.to_s.length]}"
78
+ else
79
+ user.to_s
80
+ end
81
+ end.join "\n"
82
+ end
83
+
84
+ # Run the setup steps
85
+ def setup!
86
+ ensure_config_directory_exists!
87
+ load_config
88
+ load_users
89
+ end
90
+
91
+ private
92
+
93
+ def ensure_config_directory_exists!
94
+ unless File.exists? File.dirname(@config_file)
95
+ Dir::mkdir File.dirname(@config_file)
96
+ FileUtils.touch @config_file
97
+ end
98
+ end
99
+
100
+ def load_config
101
+ @config = File.read @config_file
102
+ end
103
+
104
+ def load_users
105
+ @config.scan(/\[(.+)\]\s+name = (.+)\s+email = (.+)/) do |nickname, name, email|
106
+ @users << User.new(name, email, nickname)
107
+ end
108
+ end
109
+ end
110
+ end
@@ -1,6 +1,5 @@
1
1
  module Gas
2
2
 
3
- VERSION = '0.1.8'
4
-
5
- end
3
+ VERSION = '1.0.0'
6
4
 
5
+ end
@@ -0,0 +1,118 @@
1
+ require './spec/spec_helper'
2
+
3
+ require './lib/gas'
4
+
5
+ describe Gas do
6
+
7
+ before :each do
8
+
9
+ end
10
+
11
+ it 'should show correct version' do
12
+ output = capture_stdout { Gas.print_version }
13
+ output.should == "#{Gas::VERSION}\n"
14
+ end
15
+
16
+ it 'should show correct usage' do
17
+ output = capture_stdout { Gas.print_usage }
18
+ output.should == "Usage: command [parameters]\n\nBuilt-in commands:\n add NICKNAME NAME EMAIL - adds a new user to gas\n delete NICKNAME - deletes a user from gas\n import NICKNAME - imports the user from .gitconfig into NICKNAME\n list - lists all users\n show - shows the current user\n use NICKNAME - sets the user with NICKNAME as the current user\n"
19
+ end
20
+
21
+ it 'should return if correct number of params is supplied' do
22
+ mock(ARGV).length { 3 }
23
+ lambda { Gas.check_parameters( 3, 'Nope') }.should_not raise_error SystemExit
24
+ end
25
+
26
+ it 'should exit if incorrect number of params is supplied' do
27
+ mock(ARGV).length { 3 }
28
+ lambda { Gas.check_parameters( 4, 'Error message') }.should raise_error SystemExit
29
+ end
30
+
31
+ it 'should list users' do
32
+ any_instance_of(Gas::Users) do |u|
33
+ stub(u).to_s { 'users' }
34
+ end
35
+ output = capture_stdout { Gas.list }
36
+ output.should == "\nAvailable users:\n\nusers\n\n"
37
+ end
38
+
39
+ it 'should show current user if any' do
40
+ mock(Gas::GitConfig).current_user { Gas::User.new('foo', 'bar') }
41
+ output = capture_stdout { Gas.show }
42
+ output.should == "Current user:\nfoo <bar>\n"
43
+ end
44
+
45
+ it 'should show current user if any' do
46
+ mock(Gas::GitConfig).current_user { nil }
47
+ output = capture_stdout { Gas.show }
48
+ output.should == "No current user in gitconfig\n"
49
+ end
50
+
51
+ it 'should exit if no user by nickname exists' do
52
+ any_instance_of(Gas::Users) do |u|
53
+ stub(u).exists?('foo') { false }
54
+ end
55
+ lambda { Gas.use('foo').should be_false }.should raise_error SystemExit
56
+ end
57
+
58
+ it 'should use given user' do
59
+ user = Gas::User.new('foo bar', 'foo@bar.com', 'foo')
60
+ any_instance_of(Gas::Users) do |u|
61
+ stub(u).exists?('foo') { true }
62
+ stub(u).get('foo') { user }
63
+ end
64
+ mock(Gas::GitConfig).change_user(user) { }
65
+ mock(Gas::GitConfig).current_user { user }
66
+
67
+ output = capture_stdout { Gas.use('foo') }
68
+ output.should == "Current user:\nfoo bar <foo@bar.com>\n"
69
+ end
70
+
71
+ it 'should add new user' do
72
+ any_instance_of(Gas::Users) do |u|
73
+ stub(u).exists?('foo') { false }
74
+ stub(u).save! { }
75
+ end
76
+ output = capture_stdout { Gas.add('foo', 'foo bar', 'foo@bar.com') }
77
+ output.should == "Added new author\n [foo]\n name = foo bar\n email = foo@bar.com\n"
78
+ end
79
+
80
+ it 'should not add new user if nickname exists' do
81
+ any_instance_of(Gas::Users) do |u|
82
+ stub(u).exists?('foo') { true }
83
+ end
84
+ lambda { Gas.add('foo', 'foo bar', 'foo@bar.com') }.should raise_error SystemExit
85
+ end
86
+
87
+ it 'should delete user if nickname exists' do
88
+ any_instance_of(Gas::Users) do |u|
89
+ stub(u).save! { }
90
+ end
91
+ Gas.add('bar', 'foo bar', 'foo@bar.com')
92
+ output = capture_stdout { Gas.delete('bar') }
93
+ output.should == "Deleted author bar\n"
94
+ end
95
+
96
+ it 'should import current_user to gas' do
97
+ user = Gas::User.new('foo bar', 'foo@bar.com')
98
+ any_instance_of(Gas::Users) do |u|
99
+ stub(u).exists?('foo') { false }
100
+ stub(u).save! { }
101
+ end
102
+ mock(Gas::GitConfig).current_user { user }
103
+
104
+ output = capture_stdout { Gas.import('foo') }
105
+ output.should == "Imported author\n [foo]\n name = foo bar\n email = foo@bar.com\n"
106
+ end
107
+
108
+ it 'should not import current_user to gas if no current_user exists' do
109
+ any_instance_of(Gas::Users) do |u|
110
+ stub(u).exists?('foo') { false }
111
+ end
112
+ mock(Gas::GitConfig).current_user { nil }
113
+
114
+ output = capture_stdout { Gas.import('foo') }
115
+ output.should == "No current user to import\n"
116
+ end
117
+
118
+ end
@@ -0,0 +1,40 @@
1
+ require './spec/spec_helper'
2
+
3
+ require './lib/gas'
4
+
5
+ describe Gas::Users do
6
+
7
+ before :each do
8
+ @name = 'Fredrik Wallgren'
9
+ @email = 'fredrik.wallgren@gmail.com'
10
+ @nickname = 'walle'
11
+ @dir = File.join(Dir.tmpdir, "gas_#{rand(42000000-100000) + 10000}")
12
+ @file_path = File.join(@dir, 'gas_users')
13
+ @users = Gas::Users.new @file_path
14
+ end
15
+
16
+ after :each do
17
+ File.delete @file_path
18
+ Dir.delete @dir
19
+ end
20
+
21
+ it 'should be able to parse users from users format' do
22
+ users = "[#{@nickname}]\n name = #{@name}\n email = #{@email}\n\n[user2]\n name = foo\n email = bar"
23
+ file = File.new(@file_path, "w")
24
+ file.puts users
25
+ file.close
26
+ @users = Gas::Users.new @file_path
27
+ @users.users.count.should be 2
28
+ @users.users[0].name.should eq @name
29
+ @users.users[0].email.should eq @email
30
+ @users.users[0].nickname.should eq @nickname
31
+ end
32
+
33
+ it 'should be able to save the config' do
34
+ @users.users.count.should be 0
35
+ @users.add Gas::User.new('Foo Bar', 'foo@bar.com', 'foobar')
36
+ @users.save!
37
+ @users = Gas::Users.new @file_path
38
+ @users.users.count.should be 1
39
+ end
40
+ end
@@ -1,37 +1,16 @@
1
1
  # encoding: utf-8
2
2
 
3
+ require 'tempfile'
4
+
3
5
  if ENV['COVERAGE']
4
6
  require 'simplecov'
5
7
  SimpleCov.start
6
8
  end
7
9
 
8
- require 'fileutils'
9
- include FileUtils
10
-
11
- # Create a virtual directory in the tmp folder so
12
- # we don't risk damaging files on the running machine
13
- fake_home = '/tmp/gas-virtual-fs'
14
- rm_rf fake_home if File.exists? fake_home
15
- mkdir_p fake_home
16
- mkdir_p fake_home + '/.ssh'
17
- ENV['HOME'] = fake_home
18
-
19
-
20
10
  RSpec.configure do |config|
21
11
  config.mock_with :rr
22
12
  end
23
13
 
24
- # Configure VCR, this thing alows you to record HTTP traffic so you never
25
- # Need to connect to a server. Tests run offline just fine!
26
- require 'vcr'
27
-
28
- VCR.configure do |c|
29
- #c.allow_http_connections_when_no_cassette = true # set to true if you're refreshing the cassets in fixtures
30
- c.cassette_library_dir = 'fixtures/vcr_cassettes'
31
- c.hook_into :webmock # or :fakeweb
32
- end
33
-
34
-
35
14
  # Mocks a cli call using ` with rr.
36
15
  # Takes a block to use as rr return block
37
16
  # @param [Object] mock_object The object to mock
@@ -41,123 +20,13 @@ def mock_cli_call(mock_object, command)
41
20
  mock(mock_object).__double_definition_create__.call(:`, command) { yield }
42
21
  end
43
22
 
44
- def clean_out_ssh_directory
45
- if File.exists?(SSH_DIRECTORY + "/id_rsa")
46
- File.delete(SSH_DIRECTORY + "/id_rsa")
47
- end
48
-
49
- if File.exists?(SSH_DIRECTORY + "/id_rsa.pub")
50
- File.delete(SSH_DIRECTORY + "/id_rsa.pub")
51
- end
52
-
53
- end
54
-
55
- def restore_the_testers_ssh_key
56
- if File.exists?(GAS_DIRECTORY + "/temp_test")
57
- @pattern_to_restore_privl = File.open(GAS_DIRECTORY + "/temp_test","r").read # this test requires some juggling of files that may already exist.
58
- File.open(SSH_DIRECTORY + "/id_rsa","w+").puts @pattern_to_restore_privl
59
- File.delete(GAS_DIRECTORY + "/temp_test")
60
- end
61
-
62
- if File.exists?(GAS_DIRECTORY + "/temp_test.pub")
63
- @pattern_to_restore_publ = File.open(GAS_DIRECTORY + "/temp_test.pub","r").read # We don't want to mess things up for the tester, so we will need to save these files and then delete them
64
- File.open(SSH_DIRECTORY + "/id_rsa.pub","w+").puts @pattern_to_restore_publ
65
- File.delete(GAS_DIRECTORY + "/temp_test.pub")
66
- end
67
- end
68
-
69
- def clean_out_gas_directory(nickname)
70
- if File.exists?(GAS_DIRECTORY + "/#{nickname}_id_rsa")
71
- File.delete(GAS_DIRECTORY + "/#{nickname}_id_rsa")
72
- end
73
-
74
- if File.exists?(SSH_DIRECTORY + "/#{nickname}_id_rsa.pub")
75
- File.delete(@ssh_dir + "/#{nickname}_id_rsa.pub")
76
- end
77
- end
78
-
79
- # this function either mutates an existing file, or creates a new file that won't
80
- # have been backed up by gas
81
- def plant_bogus_rsa_keys_in_ssh_directory
82
- id_rsa = "this rsa file is bogus and not backed up by .gas yet"
83
- id_rsa_pub = "this pub rsa file is bogus and not backed up by .gas yet"
84
-
85
- File.open(SSH_DIRECTORY + "/id_rsa","w+") do |f|
86
- f.puts id_rsa
87
- end
88
-
89
- File.open(SSH_DIRECTORY + "/id_rsa.pub","w+") do |f|
90
- f.puts id_rsa_pub
91
- end
92
-
93
- return [id_rsa, id_rsa_pub]
94
- end
95
-
96
-
97
- def create_user_no_git(nickname, name, email)
98
- Gas::Prompter.stub!(:user_wants_gas_to_handle_rsa_keys?).and_return(true)
99
- #Gas::Ssh.stub!(:user_wants_to_use_key_already_in_ssh?).and_return(false)
100
- Gas::Prompter.stub!(:user_wants_to_install_key_to_github?).and_return(false)
101
-
102
- Gas.add(nickname,name,email)
103
-
104
- Gas::Prompter.unstub!(:user_wants_gas_to_handle_rsa_keys?)
105
- #Gas::Ssh.unstub!(:user_wants_to_use_key_already_in_ssh?)
106
- Gas::Prompter.unstub!(:user_wants_to_install_key_to_github?)
107
- end
108
-
109
- # toasts ssh keys for a given nickname and removal from gas.authors
110
- def delete_user_no_git(nickname)
111
- Gas.delete(nickname)
112
- end
113
-
114
- # Cycles through github, looking to see if rsa exists as a public key, then deletes it if it does
115
- def remove_key_from_github_account(username, password, rsa)
116
- # get all keys
117
- keys = Gas::Ssh.get_keys(username, password)
118
- # loop through arrays checking against 'key'
119
- keys.each do |key|
120
- if key["key"] == rsa
121
- return Gas::Ssh.remove_key_by_id!(username, password, key["id"])
122
- end
123
- end
124
-
125
- return false # key not found
126
- end
127
-
128
- def delete_all_keys_in_github_account!(github_speaker)
129
- VCR.use_cassette('delete_all_keys_in_github_account', :record => :new_episodes) do
130
- github_speaker.keys.each do |key|
131
- Gas::GithubSpeaker.publicize_methods do
132
- github_speaker.remove_key_by_id! key['id']
133
- end
134
- end
135
- end
136
- end
137
-
138
- def get_keys(username, password)
139
- server = 'api.github.com'
140
- path = '/user/keys'
141
-
142
- http = Net::HTTP.new(server,443)
143
- req = Net::HTTP::Get.new(path)
144
- http.use_ssl = true
145
- req.basic_auth username, password
146
- response = http.request(req)
147
-
148
- return JSON.parse(response.body)
149
- end
150
-
151
- def count_of_files_in(directory_path)
152
- Dir.glob(File.join(directory_path, '**', '*')).select { |file| File.file?(file) }.count
153
- end
154
-
155
- # This is used for publicizing the methods of a class so you can use TDD for projects, even in RUBY!
156
- class Class
157
- def publicize_methods
158
- saved_private_instance_methods = self.private_instance_methods
159
- self.class_eval { public(*saved_private_instance_methods) }
23
+ def capture_stdout(&block)
24
+ original_stdout = $stdout
25
+ $stdout = fake = StringIO.new
26
+ begin
160
27
  yield
161
- self.class_eval { private(*saved_private_instance_methods) }
28
+ ensure
29
+ $stdout = original_stdout
162
30
  end
163
- end
31
+ fake.string
32
+ end