revup 0.1.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/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (C) 2012 Eloy Duran <eloy@fngtps.com>
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ this software and associated documentation files (the "Software"), to deal in
5
+ the Software without restriction, including without limitation the rights to
6
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
7
+ of the Software, and to permit persons to whom the Software is furnished to do
8
+ so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
@@ -0,0 +1,150 @@
1
+ require 'rake/tasklib'
2
+ require 'net/ssh'
3
+ require 'net/scp'
4
+ require 'logger'
5
+
6
+ require 'revup/version'
7
+
8
+ module Revup
9
+ class DeployTask < Rake::TaskLib
10
+ DEFAULT_TO_CLASS_ATTRS = [:host, :app_dir, :remote_setup, :files_root, :logger, :local_tmp_dir, :remote_tmp_dir]
11
+ class << self
12
+ attr_accessor *DEFAULT_TO_CLASS_ATTRS
13
+ end
14
+
15
+ self.local_tmp_dir = self.remote_tmp_dir = '/tmp'
16
+
17
+ self.logger = Logger.new(STDOUT)
18
+ logger.level = Logger::INFO
19
+ logger.progname = "revup (#{VERSION})"
20
+
21
+ attr_accessor :component_name
22
+
23
+ attr_accessor :component_name_and_prerequisites
24
+
25
+ attr_accessor :files_root, :files
26
+
27
+ attr_accessor :host
28
+
29
+ attr_accessor :app_dir
30
+
31
+ attr_accessor :revision
32
+
33
+ attr_accessor :local_tmp_dir, :remote_tmp_dir
34
+
35
+ attr_accessor :remote_setup
36
+
37
+ attr_accessor :logger
38
+
39
+ def initialize(component_name_and_prerequisites)
40
+ DEFAULT_TO_CLASS_ATTRS.each do |attr|
41
+ send("#{attr}=", self.class.send(attr))
42
+ end
43
+
44
+ @component_name_and_prerequisites = component_name_and_prerequisites
45
+ @component_name = @component_name_and_prerequisites.is_a?(Hash) ?
46
+ @component_name_and_prerequisites.keys.first : @component_name_and_prerequisites
47
+
48
+ yield self if block_given?
49
+ define
50
+ end
51
+
52
+ def revision
53
+ @revision ||= begin
54
+ result = sh("git rev-parse --short HEAD 2>&1")
55
+ result unless result.empty?
56
+ end
57
+ end
58
+
59
+ def archive_basename
60
+ "#{@component_name}-#{@revision}"
61
+ end
62
+
63
+ def local_archive_path
64
+ File.join(@local_tmp_dir, "#{archive_basename}.tgz")
65
+ end
66
+
67
+ def remote_archive_path
68
+ File.join(@remote_tmp_dir, "#{archive_basename}.tgz")
69
+ end
70
+
71
+ def remote_archive_dir
72
+ File.join(@remote_tmp_dir, archive_basename)
73
+ end
74
+
75
+ # Actual task definition
76
+
77
+ def define
78
+ desc "Deploy build of the `#{@component_name}' component"
79
+ task(@component_name_and_prerequisites) do
80
+ deploy
81
+ end
82
+ end
83
+
84
+ def deploy
85
+ validate files_root, "Please specify the location of the root of the files that should be deployed."
86
+ validate files, "Please specify a list of files that should be deployed."
87
+ validate host, "Please specify the host of the machine to deploy to."
88
+ validate app_dir, "Please specify the path to the application."
89
+ validate revision, "Please specify the Git revision hash."
90
+
91
+ create_archive
92
+ upload_and_register
93
+
94
+ rescue Object => e
95
+ @logger.error("#{e.message}\n\t#{e.backtrace.join("\n\t")}")
96
+ raise e
97
+ end
98
+
99
+ def create_archive
100
+ sh "mkdir -p '#{@local_tmp_dir}'"
101
+ sh "tar -C '#{@files_root}' -zcf '#{local_archive_path}' '#{@files.sort.join("' '")}'"
102
+ end
103
+
104
+ def upload_and_register
105
+ Net::SSH.start(@host, ENV['USER']) do |connection|
106
+ @ssh = connection
107
+
108
+ ssh "mkdir -p '#{remote_archive_dir}'"
109
+ # Upload archive
110
+ @logger.info("Transferring `#{local_archive_path}' to `#{@host}:#{remote_archive_path}'")
111
+ @ssh.scp.upload!(local_archive_path, remote_archive_path)
112
+ # Unpack archive
113
+ ssh "tar -C '#{remote_archive_dir}' -zxf '#{remote_archive_path}'"
114
+ # Register revision
115
+ ssh "cd '#{@app_dir}' && bundle exec ./script/register_component_revision '#{remote_archive_dir}' '#{component_name}' '#{revision}'"
116
+
117
+ cleanup!
118
+ end
119
+ @ssh = nil
120
+ end
121
+
122
+ def cleanup!
123
+ sh "rm -f '#{local_archive_path}'"
124
+ ssh "rm -f '#{remote_archive_path}'"
125
+ ssh "rm -rf '#{remote_archive_dir}'"
126
+ end
127
+
128
+ private
129
+
130
+ def validate(value, message)
131
+ raise message if value.nil? || value.empty?
132
+ end
133
+
134
+ def sh(cmd)
135
+ @logger.info("[local] executing: #{cmd}")
136
+ result = `#{cmd} 2>&1`.strip
137
+ raise "Failed to execute: #{result}" unless $?.success?
138
+ @logger.info("[local] output: #{result}") unless result.empty?
139
+ result
140
+ end
141
+
142
+ def ssh(cmd)
143
+ cmd = "#{remote_setup}; #{cmd}" if remote_setup
144
+ @logger.info("[remote] executing: #{cmd}")
145
+ if result = @ssh.exec!(cmd)
146
+ @logger.info("[remote] output: #{result}")
147
+ end
148
+ end
149
+ end
150
+ end
@@ -0,0 +1,3 @@
1
+ module Revup
2
+ VERSION = '0.1.0'
3
+ end
metadata ADDED
@@ -0,0 +1,107 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: revup
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - Eloy Duran
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2012-01-12 00:00:00 +01:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: net-ssh
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ~>
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 2
29
+ - 3
30
+ - 0
31
+ version: 2.3.0
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: net-scp
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ~>
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 1
43
+ - 0
44
+ - 4
45
+ version: 1.0.4
46
+ type: :runtime
47
+ version_requirements: *id002
48
+ - !ruby/object:Gem::Dependency
49
+ name: rspec
50
+ prerelease: false
51
+ requirement: &id003 !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ~>
54
+ - !ruby/object:Gem::Version
55
+ segments:
56
+ - 2
57
+ - 8
58
+ - 0
59
+ version: 2.8.0
60
+ type: :development
61
+ version_requirements: *id003
62
+ description:
63
+ email:
64
+ - eloy@fngtps.com
65
+ - martin@sauspiel.de
66
+ executables: []
67
+
68
+ extensions: []
69
+
70
+ extra_rdoc_files: []
71
+
72
+ files:
73
+ - lib/revup/deploy_task.rb
74
+ - lib/revup/version.rb
75
+ - LICENSE
76
+ has_rdoc: true
77
+ homepage:
78
+ licenses:
79
+ - MIT
80
+ post_install_message:
81
+ rdoc_options: []
82
+
83
+ require_paths:
84
+ - lib
85
+ required_ruby_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ segments:
90
+ - 0
91
+ version: "0"
92
+ required_rubygems_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ segments:
97
+ - 0
98
+ version: "0"
99
+ requirements: []
100
+
101
+ rubyforge_project:
102
+ rubygems_version: 1.3.6
103
+ signing_key:
104
+ specification_version: 3
105
+ summary: A simple deploy tool, packaged as a rake task. Currently targeted for sauspiel.de
106
+ test_files: []
107
+