gas 0.1.8 → 1.0.0

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.
@@ -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