caplock 0.1.0 → 0.2.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.
- data/README.rdoc +13 -0
- data/VERSION +1 -1
- data/caplock.gemspec +13 -19
- data/lib/caplock.rb +67 -47
- data/test/test_caplock.rb +30 -2
- metadata +9 -11
- data/.gitignore +0 -21
data/README.rdoc
CHANGED
@@ -2,6 +2,19 @@
|
|
2
2
|
|
3
3
|
Adds a lock file to Capistrano deployments.
|
4
4
|
|
5
|
+
== Installation
|
6
|
+
|
7
|
+
$ gem install caplock
|
8
|
+
|
9
|
+
Include in your Capfile
|
10
|
+
require 'rubygems'
|
11
|
+
require 'caplock'
|
12
|
+
|
13
|
+
== Usage
|
14
|
+
|
15
|
+
Define the name of your lock file in your deploy.rb
|
16
|
+
set :lockfile, "my.lock" # defaults to "cap.lock"
|
17
|
+
|
5
18
|
== Note on Patches/Pull Requests
|
6
19
|
|
7
20
|
* Fork the project.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/caplock.gemspec
CHANGED
@@ -1,42 +1,36 @@
|
|
1
1
|
# Generated by jeweler
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{caplock}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = [%q{Dru Ibarra}]
|
12
|
-
s.date = %q{2012-
|
12
|
+
s.date = %q{2012-03-09}
|
13
13
|
s.description = %q{Adds a lock file to Capistrano deployments to prevent concurrent deployments.}
|
14
14
|
s.email = %q{Druwerd@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
16
16
|
"LICENSE",
|
17
|
-
|
17
|
+
"README.rdoc"
|
18
18
|
]
|
19
19
|
s.files = [
|
20
20
|
".document",
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
"test/test_caplock.rb"
|
21
|
+
"LICENSE",
|
22
|
+
"README.rdoc",
|
23
|
+
"Rakefile",
|
24
|
+
"VERSION",
|
25
|
+
"caplock.gemspec",
|
26
|
+
"lib/caplock.rb",
|
27
|
+
"test/helper.rb",
|
28
|
+
"test/test_caplock.rb"
|
30
29
|
]
|
31
30
|
s.homepage = %q{http://github.com/Druwerd/caplock}
|
32
|
-
s.rdoc_options = [%q{--charset=UTF-8}]
|
33
31
|
s.require_paths = [%q{lib}]
|
34
|
-
s.rubygems_version = %q{1.8.
|
32
|
+
s.rubygems_version = %q{1.8.6}
|
35
33
|
s.summary = %q{Adds a lock file to Capistrano deployments}
|
36
|
-
s.test_files = [
|
37
|
-
"test/helper.rb",
|
38
|
-
"test/test_caplock.rb"
|
39
|
-
]
|
40
34
|
|
41
35
|
if s.respond_to? :specification_version then
|
42
36
|
s.specification_version = 3
|
data/lib/caplock.rb
CHANGED
@@ -1,59 +1,79 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
require 'capistrano'
|
2
|
+
|
3
|
+
module Capistrano
|
4
|
+
module Caplock
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
6
|
+
# Returns Boolean indicating the result of +filetest+ on +full_path+ on the server, evaluated by shell on
|
7
|
+
# the server (usually bash or something roughly compatible).
|
8
|
+
def remote_filetest_passes?(filetest, full_path)
|
9
|
+
'true' == capture("if [ #{filetest} #{full_path} ]; then echo 'true'; fi").strip
|
10
|
+
end
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
# Checks if a symlink exists on the remote machine.
|
13
|
+
def remote_symlink_exists?(full_path)
|
14
|
+
remote_filetest_passes?('-L', full_path)
|
15
|
+
end
|
15
16
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
17
|
+
# Returns Boolean value indicating whether file exists on server
|
18
|
+
def remote_file_exists?(full_path)
|
19
|
+
remote_filetest_passes?('-e', full_path)
|
20
|
+
end
|
20
21
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
22
|
+
# Returns Boolean value indicating whether the file at +full_path+ matches +content+. Checks if file
|
23
|
+
# is equivalent to content by checking whether or not the MD5 of the remote content is the same as the
|
24
|
+
# MD5 of the String in +content+.
|
25
|
+
def remote_file_content_same_as?(full_path, content)
|
26
|
+
Digest::MD5.hexdigest(content) == capture("md5sum #{full_path} | awk '{ print $1 }'").strip
|
27
|
+
end
|
27
28
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
end
|
33
|
-
|
34
|
-
namespace :lock do
|
35
|
-
desc "check lock"
|
36
|
-
task :check, :roles => :app do
|
37
|
-
if remote_file_exists?("#{deploy_to}/#{lockfile}")
|
38
|
-
abort "\n\n\n\e[0;31m A Deployment is already in progress\n Remove #{deploy_to}/#{lockfile} to unlock \e[0m\n\n\n"
|
39
|
-
end
|
29
|
+
# Returns Boolean indicating whether the remote file is present and has the same contents as
|
30
|
+
# the String in +content+.
|
31
|
+
def remote_file_differs?(full_path, content)
|
32
|
+
!remote_file_exists?(full_path) || remote_file_exists?(full_path) && !remote_file_content_same_as?(full_path, content)
|
40
33
|
end
|
41
34
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
35
|
+
def self.load_into(configuration)
|
36
|
+
configuration.load do
|
37
|
+
set :lockfile, "cap.lock"
|
38
|
+
|
39
|
+
namespace :lock do
|
40
|
+
desc "check lock"
|
41
|
+
task :check, :roles => :app do
|
42
|
+
if caplock.remote_file_exists?("#{deploy_to}/#{lockfile}")
|
43
|
+
abort "\n\n\n\e[0;31m A Deployment is already in progress\n Remove #{deploy_to}/#{lockfile} to unlock \e[0m\n\n\n"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
desc "create lock"
|
48
|
+
task :create, :roles => :app do
|
49
|
+
timestamp = Time.now.strftime("%m/%d/%Y %H:%M:%S %Z")
|
50
|
+
lock_message = "Deploy started at #{timestamp} in progress"
|
51
|
+
put lock_message, "#{deploy_to}/#{lockfile}", :mode => 0644
|
52
|
+
end
|
53
|
+
|
54
|
+
desc "release lock"
|
55
|
+
task :release, :roles => :app do
|
56
|
+
run "rm -f #{deploy_to}/#{lockfile}"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Deployment
|
61
|
+
before "deploy", "lock:check"
|
62
|
+
after "lock:check", "lock:create"
|
63
|
+
after "deploy", "lock:release"
|
64
|
+
|
65
|
+
# Rollback
|
66
|
+
before "deploy:rollback", "lock:check"
|
67
|
+
after "deploy:rollback", "lock:release"
|
68
|
+
|
69
|
+
end
|
47
70
|
end
|
48
71
|
|
49
|
-
|
50
|
-
|
51
|
-
run "rm -f #{deploy_to}/#{lockfile}"
|
52
|
-
end
|
72
|
+
Capistrano.plugin :caplock, Caplock
|
73
|
+
|
53
74
|
end
|
54
|
-
|
55
|
-
before "deploy", "lock:check"
|
56
|
-
after "lock:check", "lock:create"
|
57
|
-
after "deploy", "lock:release"
|
75
|
+
end
|
58
76
|
|
77
|
+
if Capistrano::Configuration.instance
|
78
|
+
Capistrano::Caplock.load_into(Capistrano::Configuration.instance)
|
59
79
|
end
|
data/test/test_caplock.rb
CHANGED
@@ -1,7 +1,35 @@
|
|
1
1
|
require 'helper'
|
2
2
|
|
3
3
|
class TestCaplock < Test::Unit::TestCase
|
4
|
-
|
5
|
-
|
4
|
+
def setup
|
5
|
+
@config = Capistrano::Configuration.new
|
6
|
+
Capistrano::Caplock.load_into(@config)
|
7
|
+
@config.set :deploy_to, "/tmp"
|
8
|
+
@config.role :app, "localhost"
|
9
|
+
end
|
10
|
+
|
11
|
+
should "use default lockfile name 'cap.lock'" do
|
12
|
+
assert_equal @config.lockfile, 'cap.lock'
|
13
|
+
end
|
14
|
+
|
15
|
+
should "set lockfile name to 'test.lock'" do
|
16
|
+
@config.set :lockfile, 'test.lock'
|
17
|
+
assert_equal @config.lockfile, 'test.lock'
|
18
|
+
end
|
19
|
+
|
20
|
+
should "create lock" do
|
21
|
+
assert_nil @config.lock.create
|
22
|
+
assert File.exists?("/tmp/cap.lock")
|
23
|
+
end
|
24
|
+
|
25
|
+
should "remove lock" do
|
26
|
+
assert_nil @config.lock.create
|
27
|
+
assert_nil @config.lock.release
|
28
|
+
assert !File.exists?("/tmp/cap.lock")
|
29
|
+
end
|
30
|
+
|
31
|
+
should "check for lock and pass" do
|
32
|
+
assert_nil @config.lock.release
|
33
|
+
assert_nil @config.lock.check
|
6
34
|
end
|
7
35
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: caplock
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 23
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
8
|
+
- 2
|
9
9
|
- 0
|
10
|
-
version: 0.
|
10
|
+
version: 0.2.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Dru Ibarra
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-
|
18
|
+
date: 2012-03-09 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: capistrano
|
@@ -58,7 +58,6 @@ extra_rdoc_files:
|
|
58
58
|
- README.rdoc
|
59
59
|
files:
|
60
60
|
- .document
|
61
|
-
- .gitignore
|
62
61
|
- LICENSE
|
63
62
|
- README.rdoc
|
64
63
|
- Rakefile
|
@@ -71,8 +70,8 @@ homepage: http://github.com/Druwerd/caplock
|
|
71
70
|
licenses: []
|
72
71
|
|
73
72
|
post_install_message:
|
74
|
-
rdoc_options:
|
75
|
-
|
73
|
+
rdoc_options: []
|
74
|
+
|
76
75
|
require_paths:
|
77
76
|
- lib
|
78
77
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -96,10 +95,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
96
95
|
requirements: []
|
97
96
|
|
98
97
|
rubyforge_project:
|
99
|
-
rubygems_version: 1.8.
|
98
|
+
rubygems_version: 1.8.6
|
100
99
|
signing_key:
|
101
100
|
specification_version: 3
|
102
101
|
summary: Adds a lock file to Capistrano deployments
|
103
|
-
test_files:
|
104
|
-
|
105
|
-
- test/test_caplock.rb
|
102
|
+
test_files: []
|
103
|
+
|