gitpusshuten 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.bundle/config +2 -0
- data/.gitignore +4 -0
- data/Gemfile +9 -0
- data/Gemfile.lock +53 -0
- data/README.md +7 -0
- data/bin/gitpusshuten +4 -0
- data/bin/heavenly +4 -0
- data/bin/ten +4 -0
- data/gitpusshuten.gemspec +26 -0
- data/lib/gitpusshuten/cli.rb +78 -0
- data/lib/gitpusshuten/command.rb +147 -0
- data/lib/gitpusshuten/commands/base.rb +246 -0
- data/lib/gitpusshuten/commands/delete.rb +27 -0
- data/lib/gitpusshuten/commands/help.rb +36 -0
- data/lib/gitpusshuten/commands/initialize.rb +61 -0
- data/lib/gitpusshuten/commands/push.rb +54 -0
- data/lib/gitpusshuten/commands/remote.rb +29 -0
- data/lib/gitpusshuten/commands/user.rb +252 -0
- data/lib/gitpusshuten/commands/version.rb +21 -0
- data/lib/gitpusshuten/configuration.rb +122 -0
- data/lib/gitpusshuten/environment.rb +70 -0
- data/lib/gitpusshuten/gem.rb +33 -0
- data/lib/gitpusshuten/git.rb +111 -0
- data/lib/gitpusshuten/helpers/environment/installers.rb +59 -0
- data/lib/gitpusshuten/helpers/environment/packages.rb +21 -0
- data/lib/gitpusshuten/helpers/environment/scp.rb +57 -0
- data/lib/gitpusshuten/helpers/environment/ssh.rb +77 -0
- data/lib/gitpusshuten/helpers/environment/ssh_key.rb +79 -0
- data/lib/gitpusshuten/helpers/environment/user.rb +70 -0
- data/lib/gitpusshuten/helpers/spinner.rb +98 -0
- data/lib/gitpusshuten/hook.rb +26 -0
- data/lib/gitpusshuten/hooks.rb +147 -0
- data/lib/gitpusshuten/initializer.rb +95 -0
- data/lib/gitpusshuten/local.rb +35 -0
- data/lib/gitpusshuten/log.rb +83 -0
- data/lib/gitpusshuten/modules/active_record/hooks.rb +19 -0
- data/lib/gitpusshuten/modules/apache/command.rb +354 -0
- data/lib/gitpusshuten/modules/bundler/command.rb +43 -0
- data/lib/gitpusshuten/modules/bundler/hooks.rb +8 -0
- data/lib/gitpusshuten/modules/mysql/command.rb +192 -0
- data/lib/gitpusshuten/modules/nanoc/hooks.rb +9 -0
- data/lib/gitpusshuten/modules/nginx/command.rb +447 -0
- data/lib/gitpusshuten/modules/passenger/command.rb +310 -0
- data/lib/gitpusshuten/modules/passenger/hooks.rb +4 -0
- data/lib/gitpusshuten/modules/rvm/command.rb +277 -0
- data/lib/gitpusshuten.rb +21 -0
- data/lib/templates/config.rb +37 -0
- data/lib/templates/hooks.rb +40 -0
- data/spec/cli_spec.rb +83 -0
- data/spec/command_spec.rb +76 -0
- data/spec/configuration_spec.rb +45 -0
- data/spec/environment_spec.rb +64 -0
- data/spec/fixtures/combined_hooks.rb +23 -0
- data/spec/fixtures/config.rb +23 -0
- data/spec/fixtures/hooks.rb +37 -0
- data/spec/fixtures/passenger.json +1 -0
- data/spec/gem_spec.rb +28 -0
- data/spec/git_spec.rb +59 -0
- data/spec/gitpusshuten_spec.rb +9 -0
- data/spec/hook_spec.rb +48 -0
- data/spec/hooks_spec.rb +150 -0
- data/spec/initializer_spec.rb +26 -0
- data/spec/log_spec.rb +20 -0
- data/spec/spec_helper.rb +43 -0
- metadata +220 -0
@@ -0,0 +1,111 @@
|
|
1
|
+
module GitPusshuTen
|
2
|
+
class Git
|
3
|
+
|
4
|
+
##
|
5
|
+
# Push-To Chain
|
6
|
+
# "type" represents either "tag", "branch" or "ref"
|
7
|
+
# "value" represents the value of the "type"
|
8
|
+
attr_accessor :type, :value
|
9
|
+
|
10
|
+
##
|
11
|
+
# Pushing
|
12
|
+
# a boolean that determines whether git is currently busy pushing
|
13
|
+
attr_accessor :pushing
|
14
|
+
alias :pushing? :pushing
|
15
|
+
|
16
|
+
##
|
17
|
+
# Determines whether the repository has the specified remote defined
|
18
|
+
def has_remote?(remote)
|
19
|
+
git('remote') =~ /#{remote}/
|
20
|
+
end
|
21
|
+
|
22
|
+
##
|
23
|
+
# Adds the specified remote with the specified url to the git repository
|
24
|
+
def add_remote(remote, url)
|
25
|
+
git("remote add #{remote} #{url}")
|
26
|
+
end
|
27
|
+
|
28
|
+
##
|
29
|
+
# Removes the specified remote from the git repository
|
30
|
+
def remove_remote(remote)
|
31
|
+
git("remote rm #{remote}")
|
32
|
+
end
|
33
|
+
|
34
|
+
##
|
35
|
+
# Determines whether Git has been initialized
|
36
|
+
def initialized?
|
37
|
+
File.directory?(File.join(Dir.pwd, '.git'))
|
38
|
+
end
|
39
|
+
|
40
|
+
##
|
41
|
+
# Initializes Git
|
42
|
+
def initialize!
|
43
|
+
%x[git init]
|
44
|
+
end
|
45
|
+
|
46
|
+
##
|
47
|
+
# Adds ignore line to the gitignore.
|
48
|
+
def ignore!
|
49
|
+
if File.exist?('.gitignore')
|
50
|
+
if not File.read('.gitignore').include?('.gitpusshuten/**/*')
|
51
|
+
%x[echo '.gitpusshuten/**/*' >> .gitignore]
|
52
|
+
end
|
53
|
+
else
|
54
|
+
%x[echo '.gitpusshuten/**/*' >> .gitignore]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
##
|
59
|
+
# Push
|
60
|
+
# Begin of the push(type, value).to(remote) chain
|
61
|
+
# Pass in the type ("tag", "branch" or "ref") as the first argument
|
62
|
+
# followed by the value of the type (e.g. "1.4.2", "develop", or "9fb5c3201186")
|
63
|
+
def push(type, value)
|
64
|
+
@type = type
|
65
|
+
@value = value
|
66
|
+
self
|
67
|
+
end
|
68
|
+
|
69
|
+
##
|
70
|
+
# To
|
71
|
+
# End of the push(type, value).to(remote) chain
|
72
|
+
# Pass in the remote (e.g. "staging") as the first argument
|
73
|
+
def to(remote)
|
74
|
+
@pushing = true
|
75
|
+
send("push_#{type}", value, remote)
|
76
|
+
@pushing = false
|
77
|
+
@type = nil
|
78
|
+
@value = nil
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
##
|
84
|
+
# Wrapper for the git unix utility command
|
85
|
+
def git(command)
|
86
|
+
%x(git #{command})
|
87
|
+
end
|
88
|
+
|
89
|
+
##
|
90
|
+
# Pushes the local git repository "tag" to the
|
91
|
+
# specified remote repository's master branch (forced)
|
92
|
+
def push_tag(tag, remote)
|
93
|
+
git("push #{remote} #{tag}~0:refs/heads/master --force")
|
94
|
+
end
|
95
|
+
|
96
|
+
##
|
97
|
+
# Pushes the local git repository "branch" to the
|
98
|
+
# specified remote repository's master branch (forced)
|
99
|
+
def push_branch(branch, remote)
|
100
|
+
git("push #{remote} #{branch}:refs/heads/master --force")
|
101
|
+
end
|
102
|
+
|
103
|
+
##
|
104
|
+
# Pushes the local git repository "ref" to the
|
105
|
+
# specified remote repository's master branch (forced)
|
106
|
+
def push_ref(ref, remote)
|
107
|
+
git("push #{remote} #{ref}:refs/heads/master --force")
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module GitPusshuTen
|
2
|
+
module Helpers
|
3
|
+
module Environment
|
4
|
+
module Installers
|
5
|
+
|
6
|
+
##
|
7
|
+
# Installs the specified package(s)
|
8
|
+
def install!(utility)
|
9
|
+
ensure_aptitude_installed!
|
10
|
+
execute_as_root("aptitude update; aptitude install -y #{utility}")
|
11
|
+
end
|
12
|
+
|
13
|
+
##
|
14
|
+
# Uninstalls the specified package(s)
|
15
|
+
def uninstall!(utility)
|
16
|
+
ensure_aptitude_installed!
|
17
|
+
execute_as_root("aptitude remove -y #{utility}")
|
18
|
+
end
|
19
|
+
|
20
|
+
##
|
21
|
+
# Installs PushAnd
|
22
|
+
def install_pushand!
|
23
|
+
download_packages!(home_dir)
|
24
|
+
command = "cd #{home_dir}; cp -R gitpusshuten-packages/pushand/ .; chown -R #{c.user}:#{c.user} pushand;"
|
25
|
+
command += "'#{home_dir}/pushand/pushand_server_uninstall'; '#{home_dir}/pushand/pushand_server_install'"
|
26
|
+
execute_as_root(command)
|
27
|
+
clean_up_packages!(home_dir)
|
28
|
+
end
|
29
|
+
|
30
|
+
##
|
31
|
+
# Installs a generated .gitconfig
|
32
|
+
def install_gitconfig!
|
33
|
+
command = "cd #{home_dir}; echo -e \"[receive]\ndenyCurrentBranch = ignore\" > .gitconfig;"
|
34
|
+
command += "chown #{c.user}:#{c.user} .gitconfig"
|
35
|
+
execute_as_root(command)
|
36
|
+
end
|
37
|
+
|
38
|
+
##
|
39
|
+
# Determines whether the specified utility has been installed or not
|
40
|
+
def installed?(utility)
|
41
|
+
return false if execute_as_root("which #{utility}").nil?
|
42
|
+
true
|
43
|
+
end
|
44
|
+
|
45
|
+
##
|
46
|
+
# Ensures that the aptitude package manager is installed
|
47
|
+
def ensure_aptitude_installed!
|
48
|
+
if not installed?('aptitude')
|
49
|
+
Spinner.return :message => "Ensuring package manager is installed and up to date.." do
|
50
|
+
execute_as_root!('apt-get update; apt-get install -y aptitude')
|
51
|
+
g('Done!')
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module GitPusshuTen
|
2
|
+
module Helpers
|
3
|
+
module Environment
|
4
|
+
module Packages
|
5
|
+
|
6
|
+
##
|
7
|
+
# Downloads the gitpusshuten packages
|
8
|
+
def download_packages!(path, user = 'user')
|
9
|
+
send("execute_as_#{user}", "cd #{path}; git clone git://github.com/meskyanichi/gitpusshuten-packages.git")
|
10
|
+
end
|
11
|
+
|
12
|
+
##
|
13
|
+
# Cleans up the gitpusshuten-packages git repository
|
14
|
+
def clean_up_packages!(path, user = 'user')
|
15
|
+
send("execute_as_#{user}", "cd #{path}; rm -rf gitpusshuten-packages")
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module GitPusshuTen
|
2
|
+
module Helpers
|
3
|
+
module Environment
|
4
|
+
module SCP
|
5
|
+
|
6
|
+
##
|
7
|
+
# Establishes a SCP session for "root"
|
8
|
+
def scp_as_user(direction, from, to)
|
9
|
+
while true
|
10
|
+
begin
|
11
|
+
Net::SCP.start(c.ip, 'root', {
|
12
|
+
:password => @user_password,
|
13
|
+
:passphrase => c.passphrase,
|
14
|
+
:port => c.port
|
15
|
+
}) do |scp|
|
16
|
+
return scp.send("#{direction}!", from, to)
|
17
|
+
end
|
18
|
+
rescue Net::SCP::AuthenticationFailed
|
19
|
+
if @user_attempted
|
20
|
+
GitPusshuTen::Log.error "Password incorrect. Please retry."
|
21
|
+
else
|
22
|
+
GitPusshuTen::Log.message "Please provide the password for #{c.user.to_s.color(:yellow)}."
|
23
|
+
@user_attempted = true
|
24
|
+
end
|
25
|
+
@user_password = ask('') { |q| q.echo = false }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
##
|
31
|
+
# Establishes a SCP session for "root"
|
32
|
+
def scp_as_root(direction, from, to)
|
33
|
+
while true
|
34
|
+
begin
|
35
|
+
Net::SCP.start(c.ip, 'root', {
|
36
|
+
:password => @root_password,
|
37
|
+
:passphrase => c.passphrase,
|
38
|
+
:port => c.port
|
39
|
+
}) do |scp|
|
40
|
+
return scp.send("#{direction}!", from, to)
|
41
|
+
end
|
42
|
+
rescue Net::SSH::AuthenticationFailed
|
43
|
+
if @root_attempted
|
44
|
+
GitPusshuTen::Log.error "Password incorrect. Please retry."
|
45
|
+
else
|
46
|
+
GitPusshuTen::Log.message "Please provide the password for #{"root".color(:yellow)}."
|
47
|
+
@root_attempted = true
|
48
|
+
end
|
49
|
+
@root_password = ask('') { |q| q.echo = false }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module GitPusshuTen
|
2
|
+
module Helpers
|
3
|
+
module Environment
|
4
|
+
module SSH
|
5
|
+
|
6
|
+
##
|
7
|
+
# Tests if the specified directory exists
|
8
|
+
def directory?(path)
|
9
|
+
return true if execute_as_root("if [[ -d '#{path}' ]]; then exit; else echo 1; fi").nil?
|
10
|
+
false
|
11
|
+
end
|
12
|
+
|
13
|
+
##
|
14
|
+
# Tests if the specified file exists
|
15
|
+
def file?(path)
|
16
|
+
return true if execute_as_root("if [[ -f '#{path}' ]]; then exit; else echo 1; fi").nil?
|
17
|
+
false
|
18
|
+
end
|
19
|
+
|
20
|
+
##
|
21
|
+
# Performs a single command on the remote environment as a user
|
22
|
+
def execute_as_user(command)
|
23
|
+
@user_password ||= c.password
|
24
|
+
|
25
|
+
while true
|
26
|
+
begin
|
27
|
+
Net::SSH.start(c.ip, c.user, {
|
28
|
+
:password => @user_password,
|
29
|
+
:passphrase => c.passphrase,
|
30
|
+
:port => c.port
|
31
|
+
}) do |ssh|
|
32
|
+
response = ssh.exec!(command)
|
33
|
+
GitPusshuTen::Log.silent response
|
34
|
+
return response
|
35
|
+
end
|
36
|
+
rescue Net::SSH::AuthenticationFailed
|
37
|
+
if @user_attempted
|
38
|
+
GitPusshuTen::Log.error "Password incorrect. Please retry."
|
39
|
+
else
|
40
|
+
GitPusshuTen::Log.message "Please provide the password for #{c.user.to_s.color(:yellow)} (#{c.ip.color(:yellow)})."
|
41
|
+
@user_attempted = true
|
42
|
+
end
|
43
|
+
@user_password = ask('') { |q| q.echo = false }
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
##
|
49
|
+
# Performs a command as root
|
50
|
+
def execute_as_root(command)
|
51
|
+
while true
|
52
|
+
begin
|
53
|
+
Net::SSH.start(c.ip, 'root', {
|
54
|
+
:password => @root_password,
|
55
|
+
:passphrase => c.passphrase,
|
56
|
+
:port => c.port
|
57
|
+
}) do |ssh|
|
58
|
+
response = ssh.exec!(command)
|
59
|
+
GitPusshuTen::Log.silent response
|
60
|
+
return response
|
61
|
+
end
|
62
|
+
rescue Net::SSH::AuthenticationFailed
|
63
|
+
if @root_attempted
|
64
|
+
GitPusshuTen::Log.error "Password incorrect. Please retry."
|
65
|
+
else
|
66
|
+
GitPusshuTen::Log.message "Please provide the password for #{'root'.color(:yellow)} (#{c.ip.color(:yellow)})."
|
67
|
+
@root_attempted = true
|
68
|
+
end
|
69
|
+
@root_password = ask('') { |q| q.echo = false }
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module GitPusshuTen
|
2
|
+
module Helpers
|
3
|
+
module Environment
|
4
|
+
module SSHKeys
|
5
|
+
|
6
|
+
##
|
7
|
+
# USERS
|
8
|
+
##
|
9
|
+
# Returns true or false, based on whether the (local) ssh
|
10
|
+
# key has been installed on the remote server or not
|
11
|
+
def ssh_key_installed?
|
12
|
+
return false unless has_ssh_key?
|
13
|
+
return true if authorized_ssh_keys.include?(ssh_key)
|
14
|
+
false
|
15
|
+
end
|
16
|
+
|
17
|
+
##
|
18
|
+
# Returns true or false, based on whether the (local) ssh key exists
|
19
|
+
def has_ssh_key?
|
20
|
+
File.exist?(ssh_key_path)
|
21
|
+
end
|
22
|
+
|
23
|
+
##
|
24
|
+
# Reads out the ssh key file contents
|
25
|
+
def ssh_key
|
26
|
+
File.read(ssh_key_path)
|
27
|
+
end
|
28
|
+
|
29
|
+
##
|
30
|
+
# Connects to the server to read out the ~/.ssh/authorized_keys
|
31
|
+
def authorized_ssh_keys
|
32
|
+
execute_as_root("cat '#{File.join(home_dir, '.ssh', 'authorized_keys')}'")
|
33
|
+
end
|
34
|
+
|
35
|
+
##
|
36
|
+
# Returns the default (local) SSH key path
|
37
|
+
def ssh_key_path
|
38
|
+
File.join(ENV['HOME'], '.ssh', 'id_rsa.pub')
|
39
|
+
end
|
40
|
+
|
41
|
+
##
|
42
|
+
# Installs the ssh key on the remote server
|
43
|
+
def install_ssh_key!
|
44
|
+
command = "mkdir -p '#{File.join(home_dir, '.ssh')}';"
|
45
|
+
command += "echo '#{ssh_key}' >> '#{File.join(home_dir, '.ssh', 'authorized_keys')}';"
|
46
|
+
command += "chown -R #{c.user}:#{c.user} '#{File.join(home_dir, '.ssh')}';"
|
47
|
+
command += "chmod 700 '#{File.join(home_dir, '.ssh')}'; chmod 600 '#{File.join(home_dir, '.ssh', 'authorized_keys')}'"
|
48
|
+
execute_as_root(command)
|
49
|
+
end
|
50
|
+
|
51
|
+
##
|
52
|
+
# ROOT
|
53
|
+
##
|
54
|
+
# Checks to see if the user's key is already installed in the authorized keys
|
55
|
+
# of the root user on the remote server
|
56
|
+
def root_ssh_key_installed?
|
57
|
+
return false unless has_ssh_key?
|
58
|
+
return true if authorized_root_ssh_keys.include?(ssh_key)
|
59
|
+
false
|
60
|
+
end
|
61
|
+
|
62
|
+
##
|
63
|
+
# Returns a list of authorized keys for the root user
|
64
|
+
def authorized_root_ssh_keys
|
65
|
+
execute_as_root("cat $HOME/.ssh/authorized_keys")
|
66
|
+
end
|
67
|
+
|
68
|
+
##
|
69
|
+
# Installs the user's SSH key in root's authorized keys file
|
70
|
+
def install_root_ssh_key!
|
71
|
+
command = "mkdir -p $HOME/.ssh; echo '#{ssh_key}' >> $HOME/.ssh/authorized_keys;"
|
72
|
+
command += "chmod 700 $HOME/.ssh; chmod 600 $HOME/.ssh/authorized_keys"
|
73
|
+
execute_as_root(command)
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module GitPusshuTen
|
2
|
+
module Helpers
|
3
|
+
module Environment
|
4
|
+
module User
|
5
|
+
|
6
|
+
##
|
7
|
+
# Removes a user from the remote server but does not remove
|
8
|
+
# the user's home directory since it might contain applications
|
9
|
+
def remove_user!
|
10
|
+
response = execute_as_root("userdel -f '#{c.user}'")
|
11
|
+
return true if response.nil? or response =~ /userdel: user .+ is currently logged in/
|
12
|
+
false
|
13
|
+
end
|
14
|
+
|
15
|
+
##
|
16
|
+
# Adds the user to the sudoers file
|
17
|
+
def add_user_to_sudoers!
|
18
|
+
execute_as_root("echo '#{c.user} ALL=(ALL) ALL' >> /etc/sudoers")
|
19
|
+
end
|
20
|
+
|
21
|
+
##
|
22
|
+
# Checks the remote server to see if the provided user exists
|
23
|
+
def user_exists?
|
24
|
+
return false if execute_as_root("grep '#{c.user}' /etc/passwd").nil?
|
25
|
+
true
|
26
|
+
end
|
27
|
+
|
28
|
+
##
|
29
|
+
# Checks to see if the user is already in the sudoers file or not
|
30
|
+
def user_in_sudoers?
|
31
|
+
return true if execute_as_root("cat /etc/sudoers").include?("#{c.user} ALL=(ALL) ALL")
|
32
|
+
false
|
33
|
+
end
|
34
|
+
|
35
|
+
##
|
36
|
+
# Adds a user to the remote server and sets the home directory
|
37
|
+
# to the path specified in the config.rb. This is the location
|
38
|
+
# to where applications will be deployed
|
39
|
+
#
|
40
|
+
# If a password is not specified in the configuration, it will prompt
|
41
|
+
# the user to fill one in here in the CLI.
|
42
|
+
def add_user!
|
43
|
+
if c.password.nil?
|
44
|
+
GitPusshuTen::Log.message "What password would you like to give #{c.user.to_s.color(:yellow)}?"
|
45
|
+
while @new_password.nil?
|
46
|
+
new_password = ask('Fill in a password.') { |q| q.echo = false }
|
47
|
+
new_password_verification = ask('Verify password.') { |q| q.echo = false }
|
48
|
+
if not new_password.empty? and (new_password == new_password_verification)
|
49
|
+
@new_password = new_password
|
50
|
+
else
|
51
|
+
if new_password.empty?
|
52
|
+
GitPusshuTen::Log.error "Please provide a password."
|
53
|
+
else
|
54
|
+
GitPusshuTen::Log.error "Verification failed, please try again."
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
else
|
59
|
+
@new_password = c.password
|
60
|
+
end
|
61
|
+
|
62
|
+
response = execute_as_root("useradd -m --home='#{home_dir}' -s '/bin/bash' --password='" + %x[openssl passwd #{@new_password}].chomp + "' '#{c.user}'")
|
63
|
+
return true if response.nil? or response =~ /useradd\: warning\: the home directory already exists\./
|
64
|
+
false
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
STDOUT.sync = true
|
2
|
+
|
3
|
+
class Spinner
|
4
|
+
|
5
|
+
##
|
6
|
+
# Loadify Method
|
7
|
+
# * block of code you want to provide a loader for
|
8
|
+
#
|
9
|
+
# Options
|
10
|
+
# * :message => 'Message to be displayed while processing'
|
11
|
+
# * :complete => 'Message to be displayed after processing, regardless of the returned value'
|
12
|
+
# * :return => 'When set to true, it will display the returned value of the executed code'
|
13
|
+
def initialize(options = {}, &code)
|
14
|
+
|
15
|
+
##
|
16
|
+
# Character to loop through (loader)
|
17
|
+
characters = %w[| / - \\ | / - \\]
|
18
|
+
|
19
|
+
##
|
20
|
+
# Create a new thread to run the provided block of code in
|
21
|
+
thread = Thread.new do
|
22
|
+
code.call
|
23
|
+
end
|
24
|
+
|
25
|
+
##
|
26
|
+
# Enter a while loop and stay in it until the thread
|
27
|
+
# finished processing the provided code. This will display
|
28
|
+
# and animate the loader meanwhile.
|
29
|
+
while thread.alive?
|
30
|
+
next_character = characters.shift
|
31
|
+
message = "#{next_character} #{options[:message] || ''}"
|
32
|
+
print message
|
33
|
+
characters << next_character
|
34
|
+
sleep 0.065
|
35
|
+
print "\b" * message.length
|
36
|
+
end
|
37
|
+
|
38
|
+
##
|
39
|
+
# Extract the value from the dead thread
|
40
|
+
returned_value = thread.value
|
41
|
+
|
42
|
+
##
|
43
|
+
# Print Final Message
|
44
|
+
print "#{options[:message]} "
|
45
|
+
|
46
|
+
##
|
47
|
+
# Print On Complete Message if options is set to true
|
48
|
+
unless options[:complete].nil?
|
49
|
+
print options[:complete]
|
50
|
+
print " "
|
51
|
+
end
|
52
|
+
|
53
|
+
##
|
54
|
+
# Prints the returned value from the code block
|
55
|
+
# that was executed if set to true
|
56
|
+
if options[:return]
|
57
|
+
if options[:put]
|
58
|
+
puts "\n" + returned_value
|
59
|
+
else
|
60
|
+
print returned_value
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
##
|
65
|
+
# Add a new line
|
66
|
+
print "\n"
|
67
|
+
|
68
|
+
##
|
69
|
+
# Return the value from the dead thread
|
70
|
+
returned_value
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.return(options = {}, &code)
|
75
|
+
Spinner.new({:return => true}.merge(options), &code)
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.installing(options = {}, &code)
|
79
|
+
Spinner.new({:message => "Installing..", :complete => 'Done!'.color(:green)}.merge(options), &code)
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.installing_a_while(options = {}, &code)
|
83
|
+
Spinner.new({:message => "Installing, this may take a while..", :complete => 'Done!'.color(:green)}.merge(options), &code)
|
84
|
+
end
|
85
|
+
|
86
|
+
def self.configuring(options = {}, &code)
|
87
|
+
Spinner.new({:message => "Configuring..", :complete => 'Done!'.color(:green)}.merge(options), &code)
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.updating(options = {}, &code)
|
91
|
+
Spinner.new({:message => "Updating..", :complete => 'Done!'.color(:green)}.merge(options), &code)
|
92
|
+
end
|
93
|
+
|
94
|
+
def self.loading(options = {}, &code)
|
95
|
+
Spinner.new({:message => "Loading..", :complete => 'Done!'.color(:green)}.merge(options), &code)
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module GitPusshuTen
|
2
|
+
class Hook
|
3
|
+
|
4
|
+
##
|
5
|
+
# Stores the name of the performed hook
|
6
|
+
attr_accessor :name
|
7
|
+
|
8
|
+
##
|
9
|
+
# Stores the type of hook (pre or post)
|
10
|
+
attr_accessor :type
|
11
|
+
|
12
|
+
##
|
13
|
+
# Stores the (parsed) commands that need to be run
|
14
|
+
attr_accessor :commands
|
15
|
+
|
16
|
+
##
|
17
|
+
# Initializes a new hook
|
18
|
+
# Takes a hash of parameters
|
19
|
+
def initialize(options)
|
20
|
+
@name = options[:name]
|
21
|
+
@type = options[:type]
|
22
|
+
@commands = options[:commands]
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|