rsync-deploy 0.0.9
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/.gitignore +18 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +70 -0
- data/Rakefile +1 -0
- data/bin/deploy +88 -0
- data/lib/deploy/environment.rb +96 -0
- data/lib/deploy/version.rb +5 -0
- data/lib/deploy.rb +58 -0
- data/rsync-deploy.gemspec +31 -0
- metadata +88 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Ross Zurowski
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
**_Note: This tool is still in development and likely will not work in many cases._**
|
2
|
+
|
3
|
+
# Deploy
|
4
|
+
|
5
|
+
**Deploy is an rsync deployment tool built using Ruby**
|
6
|
+
Essentially acts as a wrapper for the rsync utility, providing a simple YAML based configuration file.
|
7
|
+
|
8
|
+
|
9
|
+
## Install
|
10
|
+
|
11
|
+
To install just run:
|
12
|
+
|
13
|
+
```
|
14
|
+
gem install rsync-deploy
|
15
|
+
```
|
16
|
+
|
17
|
+
|
18
|
+
## Commands
|
19
|
+
|
20
|
+
#### deploy install
|
21
|
+
|
22
|
+
Will create an template `deploy.yml` file in the current directory.
|
23
|
+
|
24
|
+
#### deploy [env...]
|
25
|
+
|
26
|
+
Will deploy to the environment(s) listed in the command. This can be used to deploy to a single server, like this:
|
27
|
+
|
28
|
+
```
|
29
|
+
deploy production
|
30
|
+
```
|
31
|
+
|
32
|
+
Or to multiple servers, like this:
|
33
|
+
|
34
|
+
```
|
35
|
+
deploy dev staging production
|
36
|
+
```
|
37
|
+
|
38
|
+
All environments called (eg. **dev**, **staging**, and **production**) are expected to be listed in your `deploy.yml` file.
|
39
|
+
|
40
|
+
# Basic example
|
41
|
+
|
42
|
+
Set up your server in the `deploy.yml` file
|
43
|
+
|
44
|
+
```
|
45
|
+
production:
|
46
|
+
host: "server.com"
|
47
|
+
user: "username"
|
48
|
+
path:
|
49
|
+
local: "deploy/"
|
50
|
+
remote: "public_html/"
|
51
|
+
```
|
52
|
+
|
53
|
+
And then use the following command to deploy:
|
54
|
+
|
55
|
+
```
|
56
|
+
deploy production
|
57
|
+
```
|
58
|
+
|
59
|
+
# Mentions
|
60
|
+
|
61
|
+
Deploy is almost identical to [DPLOY](https://github.com/LeanMeanFightingMachine/dploy), which was in turn inspired by [dandelion](https://github.com/scttnlsn/dandelion). However, Deploy separates version control from deployment, which helps avoid messy version control history with commits like _bug fix_, _typo_, and so on.
|
62
|
+
|
63
|
+
|
64
|
+
## Uninstall
|
65
|
+
|
66
|
+
To uninstall Deploy, download the [project files](https://github.com/rosszurowski/deploy/archive/master.zip), navigate to the unzipped directory, and run:
|
67
|
+
|
68
|
+
```
|
69
|
+
gem uninstall rsync-deploy
|
70
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/deploy
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'deploy'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
def help
|
7
|
+
%Q(
|
8
|
+
Usage: deploy [COMMAND] [ENVIRONMENTS] [OPTIONS]
|
9
|
+
|
10
|
+
Commands:
|
11
|
+
install Configure directory for deployment
|
12
|
+
help Prints this help document
|
13
|
+
version Prints the siteleaf gem version
|
14
|
+
|
15
|
+
Environments:
|
16
|
+
<env> Deploys listed environments
|
17
|
+
|
18
|
+
If no commands, environments, or options are given, the first environment in the config file will be deployed.
|
19
|
+
|
20
|
+
Options:
|
21
|
+
-h, --help Prints this help document
|
22
|
+
-v, --version Prints the deploy gem version
|
23
|
+
|
24
|
+
See https://github.com/rosszurowski/deploy for additional documentation.
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
# TODO: Allow creation of environments from install command, for example
|
29
|
+
# `deploy install live dev` would create a file with live and dev
|
30
|
+
# configurations to be filled in
|
31
|
+
def install
|
32
|
+
|
33
|
+
if File.exist?(Deploy::CONFIG_PATH)
|
34
|
+
|
35
|
+
puts "Deployment configuration file `#{Deploy::CONFIG_PATH}` already exists."
|
36
|
+
|
37
|
+
# Use a Y/n prompt to see if things should be overwritten
|
38
|
+
prompt = "Would you like to overwrite it?"
|
39
|
+
answer = ''
|
40
|
+
default = 'y'
|
41
|
+
until %w[y n].include? answer
|
42
|
+
print prompt + ' [Y/n]:'
|
43
|
+
answer = STDIN.gets.chomp.downcase
|
44
|
+
answer = default if answer.length == 0
|
45
|
+
end
|
46
|
+
|
47
|
+
if(answer == 'y')
|
48
|
+
File.open(Deploy::CONFIG_PATH, 'w+') do |file|
|
49
|
+
file.puts 'server_name:',' host: ""',' user: ""',' pass: ""',' path:',' local: "/"',' remote: "/public_html/"'
|
50
|
+
end
|
51
|
+
puts "Configuration file created. Fill in `#{Deploy::CONFIG_PATH}` with server details before deploying."
|
52
|
+
else
|
53
|
+
puts "No congifuration file has been installed."
|
54
|
+
end
|
55
|
+
|
56
|
+
else
|
57
|
+
|
58
|
+
File.open(Deploy::CONFIG_PATH, 'w+') do |file|
|
59
|
+
file.puts 'server_name:',' host: ""',' user: ""',' pass: ""',' path:',' local: "/"',' remote: "/public_html/"'
|
60
|
+
end
|
61
|
+
puts "Deployment configuration file created. Fill in `#{Deploy::CONFIG_PATH}` with server details before deploying."
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
# See if they're running a command
|
68
|
+
if ARGV.size > 0
|
69
|
+
case ARGV[0]
|
70
|
+
when '-v', '--version', 'version'
|
71
|
+
puts "Deploy v" + Deploy::VERSION
|
72
|
+
exit
|
73
|
+
when '-h', '--help', 'help'
|
74
|
+
puts help
|
75
|
+
exit
|
76
|
+
when 'install', 'setup'
|
77
|
+
install
|
78
|
+
exit
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
if File.exist?(Deploy::CONFIG_PATH)
|
83
|
+
deploy = Deploy::Deployment.new
|
84
|
+
deploy.go ARGV
|
85
|
+
else
|
86
|
+
puts "No config file found, run `deploy install` to create one"
|
87
|
+
exit
|
88
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# Parses and provides an easy interface for working with
|
2
|
+
# deployment environment variables.
|
3
|
+
|
4
|
+
require 'tempfile'
|
5
|
+
|
6
|
+
module Deploy
|
7
|
+
class Environment
|
8
|
+
|
9
|
+
attr_reader :name
|
10
|
+
attr_accessor :config, :options
|
11
|
+
|
12
|
+
def initialize(name, hash)
|
13
|
+
|
14
|
+
@name = name
|
15
|
+
@config = { :host => '', :user => '', :pass => '', :local => '', :remote => '' }
|
16
|
+
@options = { :verbose => false, :sync => true }
|
17
|
+
|
18
|
+
@config[:host] = hash['host']
|
19
|
+
@config[:user] = hash['user']
|
20
|
+
@config[:pass] = hash['pass'] unless hash['pass'].nil?
|
21
|
+
|
22
|
+
@config[:local] = hash['path']['local'].gsub(/\s+/, "")
|
23
|
+
@config[:remote] = hash['path']['remote'].gsub(/\s+/, "")
|
24
|
+
|
25
|
+
# Set to project and server root if local/remote are empty
|
26
|
+
@config[:local] = '/' if @config[:local].empty?
|
27
|
+
@config[:local].insert(0,'/') unless @config[:local].start_with?('/')
|
28
|
+
@config[:remote] = '/' if @config[:remote].empty?
|
29
|
+
@config[:remote].insert(0,'/') unless @config[:remote].start_with?('/')
|
30
|
+
|
31
|
+
|
32
|
+
@config[:excludes] = hash['exclude'] if hash['exclude']
|
33
|
+
|
34
|
+
@options[:verbose] = hash['verbose'] unless hash['verbose'].nil?
|
35
|
+
@options[:sync] = hash['sync'] unless hash['sync'].nil?
|
36
|
+
|
37
|
+
validate
|
38
|
+
|
39
|
+
# TODO: Find a way to do a setter for @config[:excludes] instead of
|
40
|
+
# freezing the hash
|
41
|
+
@config[:excludes].freeze
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
# Runs the deploy based upon the current @config and @options settings
|
46
|
+
# Creates rsync command and creates exclude file then cleans up
|
47
|
+
def deploy
|
48
|
+
|
49
|
+
# Create excludes file if needed
|
50
|
+
if(@config[:excludes])
|
51
|
+
tmp_exclude = Tempfile.new(['excludes','.txt'])
|
52
|
+
@config[:excludes].each do |ex|
|
53
|
+
tmp_exclude.puts ex
|
54
|
+
end
|
55
|
+
tmp_exclude.close
|
56
|
+
end
|
57
|
+
|
58
|
+
rsync_cmd = 'rsync -a' # Always keep permissions
|
59
|
+
rsync_cmd += 'v' if @options[:verbose] # Verbose if requested
|
60
|
+
rsync_cmd += 'z' # Always zip files
|
61
|
+
|
62
|
+
rsync_cmd += ' --progress' # Always show progress
|
63
|
+
rsync_cmd += ' --force --delete' unless !@options[:sync] # Sync unless explicitly requested
|
64
|
+
rsync_cmd += " --exclude-from=#{tmp_exclude.path}" if @config[:excludes] # Include exclude file if it exists
|
65
|
+
rsync_cmd += " -e \"ssh -p22\""
|
66
|
+
|
67
|
+
rsync_cmd += " " + `pwd`.gsub(/\s+/, "") + "#{@config[:local]}" # The local path from the current directory
|
68
|
+
rsync_cmd += " #{@config[:user]}@#{@config[:host]}:"
|
69
|
+
rsync_cmd += "~#{@config[:remote]}"
|
70
|
+
|
71
|
+
# Run the command
|
72
|
+
# puts rsync_cmd
|
73
|
+
system(rsync_cmd)
|
74
|
+
|
75
|
+
# Remove excludes file if needed
|
76
|
+
tmp_exclude.unlink if @config[:excludes]
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def validate
|
83
|
+
|
84
|
+
# Fail without hostname/username (password is optional)
|
85
|
+
raise "Error: no hostname set for #{@name}" if @config[:host].empty?
|
86
|
+
raise "Error: no user set for #{@name}" if @config[:user].empty?
|
87
|
+
|
88
|
+
# Fail if local/remote paths not set (because they should be in initialize
|
89
|
+
# even if they're not set in the yml config file.
|
90
|
+
raise "Error: no local path set for #{@name}" if @config[:local].empty?
|
91
|
+
raise "Error: no remote path set for #{@name}" if @config[:remote].empty?
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
end
|
data/lib/deploy.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
libdir = File.dirname(__FILE__)
|
2
|
+
$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
|
3
|
+
|
4
|
+
require 'yaml'
|
5
|
+
require 'deploy/version'
|
6
|
+
require 'deploy/environment'
|
7
|
+
|
8
|
+
module Deploy
|
9
|
+
|
10
|
+
# TODO: Make this adjustable from the command line
|
11
|
+
CONFIG_PATH = "deploy.yml"
|
12
|
+
|
13
|
+
class Deployment
|
14
|
+
|
15
|
+
attr_reader :environments
|
16
|
+
|
17
|
+
def initialize()
|
18
|
+
|
19
|
+
@config = YAML::load(File.open(CONFIG_PATH))
|
20
|
+
@environments = Array.new
|
21
|
+
|
22
|
+
@config.each do |env|
|
23
|
+
@environments.push Environment.new(env[0], env[1])
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
def go(args)
|
29
|
+
|
30
|
+
# If there are no arguments, deploy using the first environment in
|
31
|
+
# the configuration file, otherwise loop through and deploy each one
|
32
|
+
if args.size == 0
|
33
|
+
|
34
|
+
@environments.first.deploy
|
35
|
+
|
36
|
+
else
|
37
|
+
|
38
|
+
# Loop through the arguments and deploy any given ones that are also
|
39
|
+
# present in the config file.
|
40
|
+
args.each do |arg_env|
|
41
|
+
|
42
|
+
curr_env = @environments.find { |e| e.name == arg_env }
|
43
|
+
|
44
|
+
if curr_env.nil?
|
45
|
+
puts "No environment found for #{arg_env}, add it to `#{Deploy::CONFIG_PATH}`"
|
46
|
+
else
|
47
|
+
curr_env.deploy
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
lib = File.expand_path('../lib', __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
|
4
|
+
require 'deploy/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
|
8
|
+
s.name = 'rsync-deploy'
|
9
|
+
s.version = Deploy::VERSION
|
10
|
+
s.date = '2013-12-23'
|
11
|
+
|
12
|
+
s.summary = "Deployments based on rsync"
|
13
|
+
s.description = "A simple rsync based deployment gem"
|
14
|
+
|
15
|
+
s.authors = ["Ross Zurowski"]
|
16
|
+
s.email = 'ross@rosszurowski.com'
|
17
|
+
s.homepage = 'http://rubygems.org/gems/rsync-deploy'
|
18
|
+
s.license = 'WTFPL'
|
19
|
+
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
s.add_development_dependency "bundler", "~> 1.3"
|
23
|
+
s.add_development_dependency "rake"
|
24
|
+
|
25
|
+
s.files = `git ls-files`.split($/)
|
26
|
+
s.files += Dir.glob("lib/**/*.rb")
|
27
|
+
s.executables = ["deploy"]
|
28
|
+
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
29
|
+
s.require_paths = ["lib"]
|
30
|
+
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rsync-deploy
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.9
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Ross Zurowski
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-12-23 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '1.3'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.3'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rake
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
description: A simple rsync based deployment gem
|
47
|
+
email: ross@rosszurowski.com
|
48
|
+
executables:
|
49
|
+
- deploy
|
50
|
+
extensions: []
|
51
|
+
extra_rdoc_files: []
|
52
|
+
files:
|
53
|
+
- .gitignore
|
54
|
+
- Gemfile
|
55
|
+
- LICENSE.txt
|
56
|
+
- README.md
|
57
|
+
- Rakefile
|
58
|
+
- bin/deploy
|
59
|
+
- lib/deploy.rb
|
60
|
+
- lib/deploy/environment.rb
|
61
|
+
- lib/deploy/version.rb
|
62
|
+
- rsync-deploy.gemspec
|
63
|
+
homepage: http://rubygems.org/gems/rsync-deploy
|
64
|
+
licenses:
|
65
|
+
- WTFPL
|
66
|
+
post_install_message:
|
67
|
+
rdoc_options: []
|
68
|
+
require_paths:
|
69
|
+
- lib
|
70
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
71
|
+
none: false
|
72
|
+
requirements:
|
73
|
+
- - ! '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
77
|
+
none: false
|
78
|
+
requirements:
|
79
|
+
- - ! '>='
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
requirements: []
|
83
|
+
rubyforge_project:
|
84
|
+
rubygems_version: 1.8.23
|
85
|
+
signing_key:
|
86
|
+
specification_version: 3
|
87
|
+
summary: Deployments based on rsync
|
88
|
+
test_files: []
|