git_go 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.travis.yml CHANGED
@@ -5,7 +5,7 @@ rvm:
5
5
  - "1.9.3"
6
6
  - "rbx-18mode"
7
7
  - "rbx-19mode"
8
- - "jruby-18mode"
9
- - "jruby-19mode"
8
+ # - "jruby-18mode"
9
+ # - "jruby-19mode"
10
10
  script: bundle exec rspec spec
11
11
 
data/Gemfile CHANGED
@@ -5,6 +5,7 @@ source "https://rubygems.org"
5
5
  gemspec
6
6
 
7
7
  group :development do
8
+ gem "open4"
8
9
  gem "rake"
9
10
  gem "yard"
10
11
  gem "rspec"
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- git_go (0.0.1)
4
+ git_go (0.1.0)
5
5
  net-ssh (~> 2.6.2)
6
6
  thor (~> 0.16.0)
7
7
 
@@ -27,12 +27,13 @@ GEM
27
27
  mocha (0.13.1)
28
28
  metaclass (~> 0.0.1)
29
29
  net-ssh (2.6.2)
30
+ open4 (1.3.0)
30
31
  pry (0.9.10)
31
32
  coderay (~> 1.0.5)
32
33
  method_source (~> 0.8)
33
34
  slop (~> 3.3.1)
34
35
  rake (10.0.2)
35
- rb-fchange (0.0.5)
36
+ rb-fchange (0.0.6)
36
37
  ffi
37
38
  rb-fsevent (0.9.2)
38
39
  rb-inotify (0.8.8)
@@ -47,7 +48,7 @@ GEM
47
48
  rspec-mocks (2.12.0)
48
49
  slop (3.3.3)
49
50
  thor (0.16.0)
50
- yard (0.8.2.1)
51
+ yard (0.8.3)
51
52
 
52
53
  PLATFORMS
53
54
  ruby
@@ -57,6 +58,7 @@ DEPENDENCIES
57
58
  growl
58
59
  guard-rspec
59
60
  mocha
61
+ open4
60
62
  rake
61
63
  rb-fchange
62
64
  rb-fsevent
data/README.md CHANGED
@@ -1,11 +1,18 @@
1
1
  # Git Go
2
2
 
3
- [![Build Status](https://travis-ci.org/meskyanichi/git_go.png)](https://travis-ci.org/meskyanichi/git_go)
4
-
5
3
  Git Go is a small command-line utility distributed as a RubyGem that allows you to easily create/destroy/rename/list all your private-hosted git repositories on your own server. All you need is a small VPS (256MB RAM / 10GB HDD / 1vCPUCore should be sufficient).
6
4
 
7
5
  Git Go also provides you with detailed instructions on how to set up your server in order to be able to create remote repositories from your local machine using the provided command-line utility. The instructions also show you how to set up automatic/daily compressed/archived backups of all your git repositories, store them on Amazon S3, cycle them and send you success/error notifications by email, all using the [Backup](http://github.com/meskyanichi/backup) RubyGem. It's easy, and only takes a few minutes to set up.
8
6
 
7
+ Git Go is tested against:
8
+
9
+ * **Ruby** 1.9.3, 1.9.2, 1.8.7
10
+ * **Rubinius** 1.8 mode, 1.9 mode
11
+
12
+ It *should* work with **JRuby**, but it's currently untestable due to issues with `Process.waitpid`. But, `Process.waitpid` is only used in the test environment, not in the distributed gem you'll be using.
13
+
14
+ [![Build Status](https://travis-ci.org/meskyanichi/git_go.png)](https://travis-ci.org/meskyanichi/git_go)
15
+
9
16
  ## Get Git Go
10
17
 
11
18
  Install Git Go with the following command:
data/bin/gg CHANGED
@@ -4,7 +4,7 @@
4
4
  $: << File.expand_path("../../lib", __FILE__)
5
5
 
6
6
  require "git_go"
7
- require "git_go/cli/gg"
7
+ require "git_go/cli"
8
8
 
9
- GitGo::Repository.start
9
+ GitGo::CLI.start
10
10
 
@@ -1,16 +1,17 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
 
3
3
  module GitGo
4
- class Repository < Thor
4
+ class CLI < Thor
5
5
  include Thor::Actions
6
6
 
7
7
  desc "create NAME", "Create a new remote repository named NAME"
8
8
  def create(name)
9
9
  core = GitGo::Core.new
10
10
  conn = core.connection
11
+
11
12
  if conn.directory?("#{name}.git")
12
- puts "'#{name}' already exists."
13
- conn.close_and_exit(1)
13
+ puts %Q("#{name}" already exists.)
14
+ return conn.close_and_exit(1)
14
15
  else
15
16
  conn.mkdir("#{name}.git")
16
17
  conn.cd("#{name}.git")
@@ -29,23 +30,24 @@ module GitGo
29
30
 
30
31
  desc "destroy NAME", "Destroy the remote repository named NAME"
31
32
  def destroy(name)
32
- core = GitGo::Core.new
33
- conn = core.connection
33
+ core = GitGo::Core.new
34
+ conn = core.connection
34
35
  repository = "#{name}.git"
36
+
35
37
  if conn.directory?(repository)
36
- if yes?("Are you sure you want to destroy '#{name}'?")
38
+ if yes?(%Q(Are you sure you want to destroy "#{name}"?))
37
39
  response = conn.rm(repository)
38
40
  if response[:exit_code] == 0
39
- puts "Repository '#{name}' was destroyed."
41
+ puts %Q(Repository "#{name}" was destroyed.)
40
42
  else
41
- puts "Repository '#{name}' could not be destroyed."
43
+ puts %Q(Repository "#{name}" could not be destroyed.)
42
44
  puts response[:stdout] + response[:stderr]
43
- conn.close_and_exit(1)
45
+ return conn.close_and_exit(1)
44
46
  end
45
47
  end
46
48
  else
47
- puts "Repository '#{name}' does not exist."
48
- conn.close_and_exit(1)
49
+ puts %Q(Repository "#{name}" does not exist.)
50
+ return conn.close_and_exit(1)
49
51
  end
50
52
 
51
53
  conn.close
@@ -59,22 +61,22 @@ module GitGo
59
61
  new_repository = "#{new_name}.git"
60
62
 
61
63
  if not conn.directory?(repository)
62
- puts "Repository '#{name}' does not exist."
63
- conn.close_and_exit(1)
64
+ puts %Q(Repository "#{name}" does not exist.)
65
+ return conn.close_and_exit(1)
64
66
  end
65
67
 
66
68
  if conn.directory?(new_repository)
67
- puts "Repository '#{new_name}' already exists."
68
- conn.close_and_exit(1)
69
+ puts %Q(Repository "#{new_name}" already exists.)
70
+ return conn.close_and_exit(1)
69
71
  end
70
72
 
71
73
  response = conn.mv(repository, new_repository)
72
74
  if response[:exit_code] == 0
73
- puts "Repository '#{name}' renamed to '#{new_name}'."
75
+ puts %Q(Repository "#{name}" renamed to "#{new_name}".)
74
76
  else
75
- puts "Could not rename '#{name}' to '#{new_name}'."
77
+ puts %Q(Could not rename "#{name}" to "#{new_name}".)
76
78
  puts response[:stderr] + response[:stdout]
77
- conn.close_and_exit(1)
79
+ return conn.close_and_exit(1)
78
80
  end
79
81
 
80
82
  conn.close
@@ -101,7 +103,8 @@ module GitGo
101
103
  amount = list.count - 1
102
104
  out = Formatter.columns(list, :spacing => 4, :header => true)
103
105
 
104
- puts "\n" + out
106
+ puts "\n"
107
+ puts out
105
108
  puts "\nThere #{amount == 1 ? "is" : "are"} #{amount} git " +
106
109
  "#{amount == 1 ? "repository" : "repositories"}.\n"
107
110
  else
@@ -0,0 +1,102 @@
1
+ # -*- encoding : utf-8 -*-
2
+
3
+ class GitGo::Connection::Base
4
+
5
+ # @return [GitGo::Core] instance.
6
+ attr_reader :core
7
+
8
+ # @return [String] the current path on the host.
9
+ attr_reader :current_path
10
+
11
+ def initialize(core)
12
+ @core = core
13
+ @current_path = ""
14
+ end
15
+
16
+ # Moves the instance to the provided path and remembers it for the next
17
+ # action performed through the #bash method. It keeps the current path
18
+ # in #current_path
19
+ #
20
+ # @see #bash
21
+ # @see #current_path
22
+ # @param [String] path the path to navigate to.
23
+ # @return [String] the new path.
24
+ def cd(path)
25
+ @current_path = bash("cd '#{current_path}'; cd '#{path}'; pwd")[:stdout].chomp
26
+ end
27
+
28
+ # Tests to see whether the provided path is a directory.
29
+ # It will take the path relative from #current_path if no absolute
30
+ # path was provided.
31
+ #
32
+ # @param [String] path the path to test.
33
+ # @return [true, false]
34
+ def directory?(path)
35
+ bash("[ -d '#{path}' ]")[:exit_code] == 0
36
+ end
37
+
38
+ # Tests to see whether the provided path is a file.
39
+ # It will take the path relative from #current_path if no absolute
40
+ # path was provided.
41
+ #
42
+ # @param [String] path the path to test.
43
+ # @return [true, false]
44
+ def file?(path)
45
+ bash("[ -f '#{path}' ]")[:exit_code] == 0
46
+ end
47
+
48
+ # Creates a directory at the provided path.
49
+ # It will take the path relative from #current_path if no absolute
50
+ # path was provided.
51
+ #
52
+ # @param [String] path the path to create one or more directories for.
53
+ # @return [Hash] containing #bash response data.
54
+ def mkdir(path)
55
+ bash("mkdir -p '#{path}'")
56
+ end
57
+
58
+ # Removes a file or directory at the provided path.
59
+ # It will take the path relative from #current_path if no absolute
60
+ # path was provided.
61
+ #
62
+ # @param [String] path the path to the file or directory to remove.
63
+ # @return [Hash] containing #bash response data.
64
+ def rm(path)
65
+ bash("rm -rf '#{path}'")
66
+ end
67
+
68
+ # Moves a file or directory from the PATH to the NEW_PATH.
69
+ # It will take the path relative from #current_path if no absolute
70
+ # path was provided.
71
+ #
72
+ # @param [String] path the path to the file or directory to move.
73
+ # @param [String] new_path the path to where the new file or directory should be placed.
74
+ # @return [Hash] containing #bash response data.
75
+ def mv(path, new_path)
76
+ bash("mv '#{path}' '#{new_path}'")
77
+ end
78
+
79
+ # Closes the connection and exits the program with CODE.
80
+ #
81
+ # @see #close
82
+ # @param [Integer] code the code to exit the program with.
83
+ def close_and_exit(code = 0)
84
+ close
85
+ exit(code)
86
+ end
87
+
88
+ private
89
+
90
+ # Sources the ~/.bashrc or ~/.zshrc files.
91
+ # This ensures that the correct $PATH is always set and the propper binaries
92
+ # can be accessed by the remote shell. Will only source files if present.
93
+ #
94
+ # @return [String] code to source the .bashrc/.zshrc files.
95
+ def source
96
+ [
97
+ "if [ -f ~/.bashrc ]; then source ~/.bashrc; fi;",
98
+ "if [ -f ~/.zshrc ]; then source ~/.zshrc; fi;",
99
+ ].join(" ")
100
+ end
101
+ end
102
+
@@ -0,0 +1,37 @@
1
+ # -*- encoding : utf-8 -*-
2
+
3
+ require "open4"
4
+
5
+ class GitGo::Connection::Local < GitGo::Connection::Base
6
+
7
+ # Creates a new instance of GitGo::Connection::Local.
8
+ #
9
+ # @param [GitGo::Core] core takes and assigns a reference to parent class in #core.
10
+ # @return [GitGo::Connection::Local] an instance of GitGo::Connection.
11
+ def initialize(core)
12
+ super(core)
13
+ end
14
+
15
+ # Clears the `@connection` instance variable of this objects parent `Core`
16
+ # instance so new connections can be established.
17
+ def close
18
+ core.clear_connection
19
+ end
20
+
21
+ # Executes the provided COMMAND on the local machine.
22
+ # This is a blocking (non-asynchronous) operation.
23
+ #
24
+ # @param [String] command the command to perform on the host.
25
+ # @return [Hash] containing response data (:stdout, :stderr, :exit_code).
26
+ def bash(command)
27
+ pid, _, stdout, stderr = Open4::popen4(%Q(#{source} cd "#{current_path}"; #{command}))
28
+ _, status = Process::waitpid2(pid)
29
+
30
+ {
31
+ :stdout => stdout.read.strip,
32
+ :stderr => stderr.read.strip,
33
+ :exit_code => status.exitstatus
34
+ }
35
+ end
36
+ end
37
+
@@ -0,0 +1,51 @@
1
+ # -*- encoding : utf-8 -*-
2
+
3
+ class GitGo::Connection::Remote < GitGo::Connection::Base
4
+
5
+ # @return [Net::SSH::Connection::Session] instance.
6
+ attr_reader :ssh
7
+
8
+ # Creates a new instance of GitGo::Connection::Remote. Establishes
9
+ # a session with the host and stores that session in #ssh.
10
+ #
11
+ # @param [GitGo::Core] core takes and assigns a reference to parent class in #core.
12
+ # @return [GitGo::Connection::Remote] an instance of GitGo::Connection.
13
+ def initialize(core)
14
+ super(core)
15
+ @ssh = Net::SSH.start(core.host, core.user)
16
+ end
17
+
18
+ # Closes the #ssh connection and clears the `@connection` instance
19
+ # variable of this objects parent `Core` instance so new connections
20
+ # can be established.
21
+ def close
22
+ ssh.close
23
+ core.clear_connection
24
+ end
25
+
26
+ # Executes the provided COMMAND over the #ssh connection.
27
+ # This is a blocking (non-asynchronous) operation.
28
+ #
29
+ # @param [String] command the command to perform on the host.
30
+ # @return [Hash] containing response data (:stdout, :stderr, :exit_code).
31
+ def bash(command)
32
+ response = {
33
+ :stdout => "",
34
+ :stderr => ""
35
+ }
36
+
37
+ ssh.open_channel do |channel|
38
+ channel.exec(%Q(#{source} cd "#{current_path}"; #{command})) do |ch, success|
39
+ abort "Failed: Couldn't execute command (ssh.channel.exec)." unless success
40
+
41
+ channel.on_data { |_, data| response[:stdout] += data }
42
+ channel.on_extended_data { |_, __, data| response[:stderr] += data }
43
+ channel.on_request("exit-status") { |_, data| response[:exit_code] = data.read_long }
44
+ end
45
+ end
46
+
47
+ ssh.loop
48
+ response
49
+ end
50
+ end
51
+
@@ -1,139 +1,7 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
 
3
3
  module GitGo
4
- class Connection
5
-
6
- # @return [GitGo::Core] instance.
7
- attr_reader :core
8
-
9
- # @return [Net::SSH::Connection::Session] instance.
10
- attr_reader :ssh
11
-
12
- # @return [String] the current path on the host.
13
- attr_reader :current_path
14
-
15
- # Creates a new instane of GitGo::Connection. Establishes
16
- # a session with the host and stores that session in #ssh.
17
- #
18
- # @param [GitGo::Core] core takes and assigns a reference to parent class in #core.
19
- # @return [GitGo::Connection] an instance of GitGo::Connection.
20
- def initialize(core)
21
- @core = core
22
- @ssh = Net::SSH.start(core.host, core.user)
23
- @current_path = ""
24
- end
25
-
26
- # Moves the session to the provided path and remembers it for the next
27
- # action performed through the #bash method. It keeps the current path
28
- # in #current_path
29
- #
30
- # @see #bash
31
- # @see #current_path
32
- # @param [String] path the path to navigate to.
33
- # @return [String] the new path.
34
- def cd(path)
35
- @current_path = bash("cd '#{current_path}'; cd '#{path}'; pwd")[:stdout].chomp
36
- end
37
-
38
- # Tests to see whether the provided path is a directory.
39
- # It will take the path relative from #current_path if no absolute
40
- # path was provided.
41
- #
42
- # @param [String] path the path to test.
43
- # @return [true, false]
44
- def directory?(path)
45
- bash("[ -d '#{path}' ]")[:exit_code] == 0
46
- end
47
-
48
- # Tests to see whether the provided path is a file.
49
- # It will take the path relative from #current_path if no absolute
50
- # path was provided.
51
- #
52
- # @param [String] path the path to test.
53
- # @return [true, false]
54
- def file?(path)
55
- bash("[ -f '#{path}' ]")[:exit_code] == 0
56
- end
57
-
58
- # Creates a directory at the provided path.
59
- # It will take the path relative from #current_path if no absolute
60
- # path was provided.
61
- #
62
- # @param [String] path the path to create one or more directories for.
63
- # @return [Hash] containing #bash response data.
64
- def mkdir(path)
65
- bash("mkdir -p '#{path}'")
66
- end
67
-
68
- # Removes a file or directory at the provided path.
69
- # It will take the path relative from #current_path if no absolute
70
- # path was provided.
71
- #
72
- # @param [String] path the path to the file or directory to remove.
73
- # @return [Hash] containing #bash response data.
74
- def rm(path)
75
- bash("rm -rf '#{path}'")
76
- end
77
-
78
- # Moves a file or directory from the provided path to the newly specified path.
79
- # It will take the path relative from #current_path if no absolute
80
- # path was provided.
81
- #
82
- # @param [String] path the path to the file or directory to move.
83
- # @param [String] new_path the path to where the new file or directory should be placed.
84
- # @return [Hash] containing #bash response data.
85
- def mv(path, new_path)
86
- bash("mv '#{path}' '#{new_path}'")
87
- end
88
-
89
- # Closes the #ssh connection and clears the `@connection` instance
90
- # variable of this objects parent `Core` instance so new connections
91
- # can be established.
92
- def close
93
- ssh.close
94
- core.clear_connection
95
- end
96
-
97
- # Closes the #ssh connection and exits the program with CODE.
98
- #
99
- # @see #close
100
- # @param [Integer] code the code to exit the program with.
101
- def close_and_exit(code = 0)
102
- close
103
- exit(code)
104
- end
105
-
106
- # Opens a channel for the #ssh connection and executes the provided COMMAND.
107
- # This is a blocking (non-asynchronous) operation.
108
- #
109
- # @param [String] command the command to perform on the host.
110
- # @return [Hash] containing response data (:stdout, :stderr, :exit_code, :exit_signal).
111
- def bash(command)
112
- stdout_data = ""
113
- stderr_data = ""
114
- exit_code = nil
115
- exit_signal = nil
116
-
117
- ssh.open_channel do |channel|
118
- channel.exec("cd '#{current_path}'; #{command}") do |ch, success|
119
- abort "FAILED: couldn't execute command (ssh.channel.exec)" unless success
120
-
121
- channel.on_data { |ch,data| stdout_data += data }
122
- channel.on_extended_data { |ch,type,data| stderr_data += data }
123
- channel.on_request("exit-status") { |ch,data| exit_code = data.read_long }
124
- channel.on_request("exit-signal") { |ch, data|exit_signal = data.read_long }
125
- end
126
- end
127
-
128
- ssh.loop
129
-
130
- {
131
- :stdout => stdout_data,
132
- :stderr => stderr_data,
133
- :exit_code => exit_code,
134
- :exit_signal => exit_signal
135
- }
136
- end
4
+ module Connection
137
5
  end
138
6
  end
139
7
 
@@ -3,6 +3,6 @@
3
3
  module GitGo
4
4
 
5
5
  # @return [String] the current GitGo version.
6
- VERSION = "0.0.1"
6
+ VERSION = "0.1.0"
7
7
  end
8
8
 
data/lib/git_go.rb CHANGED
@@ -5,6 +5,8 @@ require "thor"
5
5
  require "net/ssh"
6
6
 
7
7
  require "git_go/connection"
8
+ require "git_go/connection/base"
9
+ require "git_go/connection/remote"
8
10
  require "git_go/formatter"
9
11
  require "git_go/version"
10
12
 
@@ -37,9 +39,17 @@ module GitGo
37
39
  # Subsequent calls to this method will returned the same cached
38
40
  # reference to the previously created instance.
39
41
  #
42
+ # @note
43
+ # GitGo::Connection::Local is intended for the test-suite.
44
+ # End-users should only use remote IP addresses.
45
+ #
40
46
  # @return [GitGo::Connection] an instance of GitGo::Connection
41
47
  def connection
42
- @connection ||= Connection.new(self)
48
+ if host == "127.0.0.1"
49
+ @connection ||= Connection::Local.new(self)
50
+ else
51
+ @connection ||= Connection::Remote.new(self)
52
+ end
43
53
  end
44
54
 
45
55
  # Clears a previously established connection reference. After
@@ -0,0 +1,220 @@
1
+ # -*- encoding : utf-8 -*-
2
+
3
+ require "spec_helper"
4
+
5
+ describe GitGo::CLI do
6
+
7
+ let(:cli) { GitGo::CLI.new }
8
+ let(:core) { GitGo::Core.new }
9
+ let(:conn) { core.connection }
10
+
11
+ before do
12
+ conn.rm(TMP)
13
+ conn.mkdir(TMP)
14
+ conn.cd(TMP)
15
+ end
16
+
17
+ def after
18
+ conn.close
19
+ end
20
+
21
+ def init
22
+ cli = GitGo::CLI.new
23
+ core = GitGo::Core.new
24
+ conn = core.connection
25
+ conn.cd(TMP)
26
+ GitGo::Core.stubs(:new).returns(core)
27
+
28
+ [cli, core, conn]
29
+ end
30
+
31
+ def create_silent(name)
32
+ cli, core, conn = init
33
+ cli.expects(:puts)
34
+ cli.create(name)
35
+
36
+ [cli, core, conn]
37
+ end
38
+
39
+ describe "#create" do
40
+ it "should create a repository" do
41
+ cli, core, conn = init
42
+
43
+ cli.expects(:puts).with("Repository created at: git@127.0.0.1:rspec.git")
44
+ cli.create("rspec")
45
+ conn.directory?("#{TMP}/rspec.git").should be_true
46
+ end
47
+
48
+ it "should not create a repository if it already exists" do
49
+ cli, core, conn = create_silent("rspec")
50
+
51
+ cli, core, conn = init
52
+ cli.expects(:puts).with(%Q("rspec" already exists.))
53
+ conn.expects(:close_and_exit).with(1)
54
+ cli.create("rspec")
55
+ end
56
+
57
+ it "should report an error on failure" do
58
+ cli, core, conn = init
59
+
60
+ cli.expects(:puts).with("Failed to create repository.")
61
+ cli.expects(:puts).with("failed")
62
+
63
+ conn.expects(:directory?).returns(false)
64
+ conn.expects(:mkdir)
65
+ conn.expects(:cd)
66
+ conn.expects(:bash).with("git init --bare").returns({
67
+ :exit_code => 1, :stdout => "", :stderr => "failed"
68
+ })
69
+
70
+ cli.create("rspec")
71
+ end
72
+ end
73
+
74
+ describe "#destroy" do
75
+ it "should destroy an existing repository" do
76
+ cli, core, conn = create_silent("rspec")
77
+
78
+ cli, core, conn = init
79
+ cli.expects(:yes?).returns(true)
80
+ cli.expects(:puts).with(%Q(Repository "rspec" was destroyed.))
81
+ cli.destroy("rspec")
82
+ conn.directory?("#{TMP}/rspec.git").should be_false
83
+ end
84
+
85
+ it "should not destroy a non-existing repository" do
86
+ cli, core, conn = init
87
+ cli.expects(:puts).with(%Q(Repository "rspec" does not exist.))
88
+ conn.expects(:close_and_exit).with(1)
89
+ cli.destroy("rspec")
90
+ conn.directory?("#{TMP}/rspec.git").should be_false
91
+ end
92
+
93
+ it "should report an error on failure" do
94
+ cli, core, conn = init
95
+
96
+ cli.expects(:puts).with(%Q(Repository "rspec" could not be destroyed.))
97
+ cli.expects(:puts).with("failed")
98
+
99
+ conn.expects(:directory?).returns(true)
100
+ conn.expects(:close_and_exit).with(1)
101
+ cli.expects(:yes?).returns(true)
102
+ conn.expects(:rm).returns(
103
+ :exit_code => 1, :stdout => "", :stderr => "failed"
104
+ )
105
+
106
+ cli.destroy("rspec")
107
+ end
108
+ end
109
+
110
+ describe "#rename" do
111
+ it "should rename the repository" do
112
+ cli, core, conn = create_silent("rspec")
113
+
114
+ cli, core, conn = init
115
+ cli.expects(:puts).with(%Q(Repository "rspec" renamed to "minitest".))
116
+ cli.rename("rspec", "minitest")
117
+ conn.directory?("#{TMP}/rspec.git").should be_false
118
+ conn.directory?("#{TMP}/minitest.git").should be_true
119
+ end
120
+
121
+ it "should not rename a non-existent repository" do
122
+ cli, core, conn = init
123
+
124
+ cli.expects(:puts).with(%Q(Repository "rspec" does not exist.))
125
+ conn.expects(:close_and_exit).with(1)
126
+ cli.rename("rspec", "minitest")
127
+ end
128
+
129
+ it "should not rename to an already existing repository" do
130
+ create_silent("rspec")
131
+ create_silent("minitest")
132
+
133
+ cli, core, conn = init
134
+ cli.expects(:puts).with(%Q(Repository "minitest" already exists.))
135
+ conn.expects(:close_and_exit).with(1)
136
+ cli.rename("rspec", "minitest")
137
+ end
138
+
139
+ it "should report an error on failure" do
140
+ create_silent("rspec")
141
+ create_silent("minitest")
142
+
143
+ cli, core, conn = init
144
+ cli.expects(:puts).with(%Q(Could not rename "rspec" to "minitest".))
145
+ cli.expects(:puts).with("failed")
146
+ conn.expects(:mv).with("rspec.git", "minitest.git").returns({
147
+ :exit_code => 1, :stdout => "", :stderr => "failed"
148
+ })
149
+
150
+ conn.expects(:directory?).with("rspec.git").returns(true)
151
+ conn.expects(:directory?).with("minitest.git").returns(false)
152
+ conn.expects(:close_and_exit).with(1)
153
+
154
+ cli.rename("rspec", "minitest")
155
+ end
156
+ end
157
+
158
+ describe "#list" do
159
+ it "should not list any repositories" do
160
+ cli.expects(:puts).with(%Q(There are no repositories at git@127.0.0.1.))
161
+ cli.list
162
+ end
163
+
164
+ it "should list one repository" do
165
+ create_silent("rspec")
166
+
167
+ cli, core, conn = init
168
+ cli.expects(:puts).with("\n")
169
+ cli.expects(:puts).with((<<-EOS
170
+ Repository Git Fetch/Push URL#{" " * 5}
171
+ ---------- -----------------------
172
+ rspec git@127.0.0.1:rspec.git
173
+ EOS
174
+ ).gsub(/^\s+/, ""))
175
+ cli.expects(:puts).with("\nThere is 1 git repository.\n")
176
+ cli.list
177
+ end
178
+
179
+ it "should list two repositories" do
180
+ create_silent("rspec")
181
+ create_silent("minitest")
182
+
183
+ cli, core, conn = init
184
+ cli.expects(:puts).with("\n")
185
+ cli.expects(:puts).with((<<-EOS
186
+ Repository Git Fetch/Push URL#{" " * 8}
187
+ ---------- --------------------------
188
+ minitest git@127.0.0.1:minitest.git
189
+ rspec git@127.0.0.1:rspec.git#{" " * 3}
190
+ EOS
191
+ ).gsub(/^\s+/, ""))
192
+ cli.expects(:puts).with("\nThere are 2 git repositories.\n")
193
+ cli.list
194
+ end
195
+
196
+ it "should list 5 repositories" do
197
+ create_silent("rspec")
198
+ create_silent("minitest")
199
+ create_silent("testunit")
200
+ create_silent("mocha")
201
+ create_silent("fabrication")
202
+
203
+ cli, core, conn = init
204
+ cli.expects(:puts).with("\n")
205
+ cli.expects(:puts).with((<<-EOS
206
+ Repository Git Fetch/Push URL#{" " * 11}
207
+ ----------- -----------------------------
208
+ fabrication git@127.0.0.1:fabrication.git
209
+ minitest git@127.0.0.1:minitest.git#{" " * 3}
210
+ mocha git@127.0.0.1:mocha.git#{" " * 6}
211
+ rspec git@127.0.0.1:rspec.git#{" " * 6}
212
+ testunit git@127.0.0.1:testunit.git#{" " * 3}
213
+ EOS
214
+ ).gsub(/^\s+/, ""))
215
+ cli.expects(:puts).with("\nThere are 5 git repositories.\n")
216
+ cli.list
217
+ end
218
+ end
219
+ end
220
+
@@ -2,19 +2,10 @@
2
2
 
3
3
  require "spec_helper"
4
4
 
5
- describe GitGo::Connection do
5
+ describe GitGo::Connection::Base do
6
6
 
7
- let(:core) { GitGo::Core.new }
8
- let(:conn) { GitGo::Connection.new(core) }
9
- let(:ssh) { mock("Net::SSH") }
10
-
11
- before do
12
- ENV["GIT_GO_USER"] = "git"
13
- ENV["GIT_GO_HOST"] = "127.0.0.1"
14
- Net::SSH.stubs(:start).returns(ssh)
15
- end
16
-
17
- it("test if propperly mocked") { core; conn; ssh }
7
+ let(:core) { GitGo::Core.new }
8
+ let(:conn) { GitGo::Connection::Base.new(core) }
18
9
 
19
10
  describe "#cd" do
20
11
  it "should update the #current_path" do
@@ -79,18 +70,6 @@ describe GitGo::Connection do
79
70
  end
80
71
  end
81
72
 
82
- describe "#close" do
83
- it "should close the ssh connection and unset the instance variable on `core`" do
84
- ssh.expects(:close)
85
-
86
- core.connection
87
- core.instance_variable_get("@connection").should_not be_nil
88
-
89
- conn.close
90
- core.instance_variable_get("@connection").should be_nil
91
- end
92
- end
93
-
94
73
  describe "#close_and_exit" do
95
74
  it "should #close the connection, and #exit the program" do
96
75
  conn.expects(:close)
@@ -105,4 +84,3 @@ describe GitGo::Connection do
105
84
  end
106
85
  end
107
86
  end
108
-
@@ -0,0 +1,20 @@
1
+ # -*- encoding : utf-8 -*-
2
+
3
+ require "spec_helper"
4
+
5
+ describe GitGo::Connection::Local do
6
+
7
+ let(:core) { GitGo::Core.new }
8
+ let(:conn) { GitGo::Connection::Local.new(core) }
9
+
10
+ describe "#close" do
11
+ it "should close the ssh connection and unset the instance variable on `core`" do
12
+ core.connection
13
+ core.instance_variable_get("@connection").should_not be_nil
14
+
15
+ conn.close
16
+ core.instance_variable_get("@connection").should be_nil
17
+ end
18
+ end
19
+ end
20
+
@@ -0,0 +1,29 @@
1
+ # -*- encoding : utf-8 -*-
2
+
3
+ require "spec_helper"
4
+
5
+ describe GitGo::Connection::Remote do
6
+
7
+ let(:core) { GitGo::Core.new }
8
+ let(:conn) { GitGo::Connection::Remote.new(core) }
9
+ let(:ssh) { mock("Net::SSH") }
10
+
11
+ before do
12
+ ENV["GIT_GO_USER"] = "git"
13
+ ENV["GIT_GO_HOST"] = "192.168.1.1" # Remote IP
14
+ Net::SSH.stubs(:start).returns(ssh)
15
+ end
16
+
17
+ describe "#close" do
18
+ it "should close the ssh connection and unset the instance variable on `core`" do
19
+ ssh.expects(:close)
20
+
21
+ core.connection
22
+ core.instance_variable_get("@connection").should_not be_nil
23
+
24
+ conn.close
25
+ core.instance_variable_get("@connection").should be_nil
26
+ end
27
+ end
28
+ end
29
+
@@ -19,5 +19,25 @@ describe GitGo do
19
19
  GitGo::Core.any_instance.expects(:exit).never
20
20
  GitGo::Core.new
21
21
  end
22
+
23
+ it "should initialize a GitGo::Connection::Remote connection" do
24
+ ENV["GIT_GO_USER"] = "git"
25
+ ENV["GIT_GO_HOST"] = "192.168.1.1"
26
+
27
+ core = GitGo::Core.new
28
+ GitGo::Connection::Remote.expects(:new).with(core)
29
+
30
+ core.connection
31
+ end
32
+
33
+ it "should initialize a GitGo::Connection::Local connection" do
34
+ ENV["GIT_GO_USER"] = "git"
35
+ ENV["GIT_GO_HOST"] = "127.0.0.1"
36
+
37
+ core = GitGo::Core.new
38
+ GitGo::Connection::Local.expects(:new).with(core)
39
+
40
+ core.connection
41
+ end
22
42
  end
23
43
 
data/spec/spec_helper.rb CHANGED
@@ -1,12 +1,22 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
 
3
3
  require "git_go"
4
+ require "git_go/connection/local"
5
+ require "git_go/cli"
6
+ require "etc"
4
7
 
5
8
  RSpec.configure do |config|
6
9
  config.treat_symbols_as_metadata_keys_with_true_values = true
7
- config.run_all_when_everything_filtered = true
10
+ config.run_all_when_everything_filtered = true
11
+ config.mock_framework = :mocha
12
+ config.order = "random"
8
13
  config.filter_run :focus
9
- config.mock_framework = :mocha
10
- config.order = "random"
14
+
15
+ config.before do
16
+ ENV["GIT_GO_USER"] = "git"
17
+ ENV["GIT_GO_HOST"] = "127.0.0.1" # localhost
18
+ end
11
19
  end
12
20
 
21
+ TMP = "/tmp/git_go"
22
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: git_go
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-12-11 00:00:00.000000000 Z
12
+ date: 2012-12-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: thor
@@ -66,11 +66,17 @@ files:
66
66
  - bin/gg
67
67
  - gitgo.gemspec
68
68
  - lib/git_go.rb
69
- - lib/git_go/cli/gg.rb
69
+ - lib/git_go/cli.rb
70
70
  - lib/git_go/connection.rb
71
+ - lib/git_go/connection/base.rb
72
+ - lib/git_go/connection/local.rb
73
+ - lib/git_go/connection/remote.rb
71
74
  - lib/git_go/formatter.rb
72
75
  - lib/git_go/version.rb
73
- - spec/lib/git_go/connection_spec.rb
76
+ - spec/lib/git_go/cli_spec.rb
77
+ - spec/lib/git_go/connection/base_spec.rb
78
+ - spec/lib/git_go/connection/local_spec.rb
79
+ - spec/lib/git_go/connection/remote_spec.rb
74
80
  - spec/lib/git_go/formatter_spec.rb
75
81
  - spec/lib/git_go/version_spec.rb
76
82
  - spec/lib/git_go_spec.rb
@@ -89,7 +95,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
89
95
  version: '0'
90
96
  segments:
91
97
  - 0
92
- hash: -1366446642123636879
98
+ hash: -3461265323293730929
93
99
  required_rubygems_version: !ruby/object:Gem::Requirement
94
100
  none: false
95
101
  requirements:
@@ -98,7 +104,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
98
104
  version: '0'
99
105
  segments:
100
106
  - 0
101
- hash: -1366446642123636879
107
+ hash: -3461265323293730929
102
108
  requirements: []
103
109
  rubyforge_project:
104
110
  rubygems_version: 1.8.23
@@ -108,7 +114,10 @@ summary: Git Go is a small command-line utility distributed as a RubyGem that al
108
114
  you to easily create/destroy/rename/list all your private-hosted git repositories
109
115
  on your own server.
110
116
  test_files:
111
- - spec/lib/git_go/connection_spec.rb
117
+ - spec/lib/git_go/cli_spec.rb
118
+ - spec/lib/git_go/connection/base_spec.rb
119
+ - spec/lib/git_go/connection/local_spec.rb
120
+ - spec/lib/git_go/connection/remote_spec.rb
112
121
  - spec/lib/git_go/formatter_spec.rb
113
122
  - spec/lib/git_go/version_spec.rb
114
123
  - spec/lib/git_go_spec.rb