hem-tasks-rsync 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.rubocop.yml +5 -0
- data/Gemfile +4 -0
- data/README.md +28 -0
- data/Rakefile +2 -0
- data/hem-tasks-rsync.gemspec +24 -0
- data/lib/hem/lib/vm/ReverseCommand.rb +65 -0
- data/lib/hem/tasks/rsync/deps.rb +59 -0
- data/lib/hem/tasks/rsync/version.rb +7 -0
- data/lib/hem/tasks/rsync/vm.rb +135 -0
- data/lib/hem/tasks/rsync.rb +5 -0
- metadata +96 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 96b11ce518ce92a91f176d63a4d87f2b408ce1fa
|
4
|
+
data.tar.gz: 825a8668a45c01a0d6ec4891b2cde9a5b1a5d688
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 00b691108e3083fe1732616559caed2aa62d0124bfb68a8dab613dbb7bc5f2bd55e269eec2bd9f1702dd03d98f7901bd1cec0f384d161fce4fc784ae3f7c25e5
|
7
|
+
data.tar.gz: 1633488b1b2cb678d41f4ddc58f1b08bff72819215604b3b4aaf8a30c6b61611df241b2503f6e858765e1765916241c8a903b13e27a277c964a693166332211c
|
data/.rubocop.yml
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# Hem::Tasks::Rsync
|
2
|
+
|
3
|
+
Contains tasks for [Hem](https://github.com/inviqa/hem) to provide rsync functionality
|
4
|
+
for projects
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
Add this line to your application's Hemfile:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
plugins do
|
12
|
+
gem 'hem-tasks-rsync'
|
13
|
+
end
|
14
|
+
```
|
15
|
+
|
16
|
+
## Usage
|
17
|
+
`hem deps` will give a nice overview of what functionality is provided!
|
18
|
+
|
19
|
+
## Development
|
20
|
+
|
21
|
+
After checking out the repo, run `bundle install` to install dependencies.
|
22
|
+
|
23
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
24
|
+
|
25
|
+
## Contributing
|
26
|
+
|
27
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/inviqa/hem-tasks-rsync. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
28
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
|
5
|
+
require 'hem/tasks/rsync/version'
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = 'hem-tasks-rsync'
|
9
|
+
spec.version = Hem::Tasks::Rsync::VERSION
|
10
|
+
spec.authors = ['Kieren Evans']
|
11
|
+
spec.email = ['kevans+hem_tasks@inviqa.com']
|
12
|
+
|
13
|
+
spec.summary = 'Rsync tasks for Hem'
|
14
|
+
spec.description = 'Rsync tasks for Hem'
|
15
|
+
spec.homepage = ''
|
16
|
+
spec.licenses = ['MIT']
|
17
|
+
|
18
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features|\.rubocop\.yml|Rakefile)/}) }
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
|
21
|
+
spec.add_development_dependency 'bundler', '~> 1.11'
|
22
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
23
|
+
spec.add_development_dependency 'rubocop', '~> 0.43.0'
|
24
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# ^ Syntax hint
|
3
|
+
|
4
|
+
# Hem
|
5
|
+
module Hem
|
6
|
+
# Lib!
|
7
|
+
module Lib
|
8
|
+
# VM!
|
9
|
+
module Vm
|
10
|
+
# Place the ssh configuration within a command, using sprintf
|
11
|
+
class ReverseCommand < Command
|
12
|
+
def to_s
|
13
|
+
ssh_config = ssh_config()
|
14
|
+
ssh_command = ssh_command(ssh_config)
|
15
|
+
pwd_set_command = pwd_set_command()
|
16
|
+
vm_command = vm_command()
|
17
|
+
|
18
|
+
[
|
19
|
+
@pipe,
|
20
|
+
full_command(pwd_set_command, vm_command, ssh_command)
|
21
|
+
].compact.join(' | ')
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def ssh_config
|
27
|
+
require 'tempfile'
|
28
|
+
|
29
|
+
config = ::Tempfile.new 'hem_ssh_config'
|
30
|
+
config.write @@vm_inspector.ssh_config
|
31
|
+
config.close
|
32
|
+
|
33
|
+
config
|
34
|
+
end
|
35
|
+
|
36
|
+
def ssh_command(config)
|
37
|
+
psuedo_tty = @opts[:psuedo_tty] ? '-t' : ''
|
38
|
+
[
|
39
|
+
'ssh',
|
40
|
+
"-F #{config.path.shellescape}",
|
41
|
+
psuedo_tty
|
42
|
+
].reject(&:empty?).join(' ')
|
43
|
+
end
|
44
|
+
|
45
|
+
def pwd_set_command
|
46
|
+
"cd #{@opts[:pwd].shellescape}; exec /bin/bash"
|
47
|
+
end
|
48
|
+
|
49
|
+
def vm_command
|
50
|
+
[
|
51
|
+
@pipe_in_vm.nil? ? nil : @pipe_in_vm.gsub(/(\\+)/, '\\\\\1'),
|
52
|
+
@command
|
53
|
+
].compact.join(' | ')
|
54
|
+
end
|
55
|
+
|
56
|
+
def full_command(pwd_set_command, vm_command, ssh_command)
|
57
|
+
[
|
58
|
+
pwd_set_command,
|
59
|
+
vm_command.empty? ? nil : (vm_command % ssh_command).shellescape
|
60
|
+
].compact.join(' -c ') + @opts[:append].shellescape
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# ^ Syntax hint
|
3
|
+
|
4
|
+
before 'deps:composer', 'deps:sync:composer_files_to_guest'
|
5
|
+
after 'deps:composer', 'deps:sync:reload_or_sync'
|
6
|
+
|
7
|
+
namespace :deps do
|
8
|
+
desc 'Syncing dependencies to/from the VM'
|
9
|
+
namespace :sync do
|
10
|
+
desc 'Download the composer.json and lock from the guest to the host'
|
11
|
+
task :composer_files_from_guest do
|
12
|
+
Hem.ui.title 'Downloading composer files to host'
|
13
|
+
|
14
|
+
Rake::Task['vm:rsync_manual'].execute(
|
15
|
+
from_path: File.join(Hem.project_config.vm.project_mount_path, 'composer.json'),
|
16
|
+
to_path: File.join(Hem.project_path, 'composer.json'),
|
17
|
+
is_reverse: true
|
18
|
+
)
|
19
|
+
Rake::Task['vm:rsync_manual'].execute(
|
20
|
+
from_path: File.join(Hem.project_config.vm.project_mount_path, 'composer.lock'),
|
21
|
+
to_path: File.join(Hem.project_path, 'composer.lock'),
|
22
|
+
is_reverse: true
|
23
|
+
)
|
24
|
+
Hem.ui.success 'Downloaded composer files to host'
|
25
|
+
end
|
26
|
+
|
27
|
+
desc 'Upload the composer.json and lock from the host to the guest'
|
28
|
+
task :composer_files_to_guest do
|
29
|
+
Hem.ui.title 'Uploading composer files to guest'
|
30
|
+
|
31
|
+
Rake::Task['vm:upload_root_files_to_guest'].invoke
|
32
|
+
|
33
|
+
Hem.ui.success('Uploaded composer files to guest')
|
34
|
+
end
|
35
|
+
|
36
|
+
desc 'Download the vendor directory from the guest to the host'
|
37
|
+
task :vendor_directory_from_guest do
|
38
|
+
Hem.ui.title 'Downloading vendor directory changes from guest'
|
39
|
+
|
40
|
+
Rake::Task['vm:sync_guest_changes'].execute(
|
41
|
+
from_path: 'vendor/',
|
42
|
+
to_path: 'vendor',
|
43
|
+
deciding_file_path: File.join('vendor', 'autoload.php'),
|
44
|
+
guest_to_host_allowed: false
|
45
|
+
)
|
46
|
+
end
|
47
|
+
|
48
|
+
desc 'Reload the VM to use NFS mounts per directory, or sync rsync mounts if already enabled'
|
49
|
+
task :reload_or_sync do
|
50
|
+
one_mount_point = run 'grep "/vagrant " /proc/mounts || true', capture: true
|
51
|
+
if one_mount_point != ''
|
52
|
+
Rake::Task['vm:reload'].execute
|
53
|
+
else
|
54
|
+
Rake::Task['deps:sync:vendor_directory_from_guest'].execute
|
55
|
+
Rake::Task['vm:rsync_mount_sync'].execute
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# ^ Syntax hint
|
3
|
+
|
4
|
+
after 'vm:reload', 'vm:provision_shell'
|
5
|
+
after 'vm:reload', 'vm:upload_root_files_to_guest'
|
6
|
+
after 'vm:start', 'vm:provision_shell'
|
7
|
+
after 'vm:start', 'vm:upload_root_files_to_guest'
|
8
|
+
|
9
|
+
namespace :vm do
|
10
|
+
desc 'Trigger a sync to occur for rsync mountpoints'
|
11
|
+
task :rsync_mount_sync do
|
12
|
+
vagrantfile do
|
13
|
+
Hem.ui.title 'Syncing directories'
|
14
|
+
vagrant_exec 'rsync'
|
15
|
+
Hem.ui.success('Vendor directory synced')
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
desc 'Rsync any files in the project root the guest'
|
20
|
+
task :upload_root_files_to_guest do
|
21
|
+
one_mount_point = run 'grep "/vagrant " /proc/mounts || true', capture: true
|
22
|
+
next unless one_mount_point == ''
|
23
|
+
|
24
|
+
Hem.ui.title 'Uploading project root files to the guest'
|
25
|
+
|
26
|
+
files = shell "find '#{Hem.project_path}' -type f -maxdepth 1 -print0",
|
27
|
+
local: true, on: :host, capture: true, pwd: Hem.project_path
|
28
|
+
|
29
|
+
next unless files
|
30
|
+
|
31
|
+
rsync_command = <<-COMMAND
|
32
|
+
find '.' -type f -maxdepth 1 -print0 | \
|
33
|
+
rsync --files-from=- --from0 --human-readable --progress \
|
34
|
+
--verbose --compress --archive --rsh='%s' \
|
35
|
+
'#{Hem.project_path}' 'default:#{Hem.project_config.vm.project_mount_path}'
|
36
|
+
COMMAND
|
37
|
+
args = [rsync_command, { local: true, realtime: true, indent: 2, on: :host, pwd: Hem.project_path }]
|
38
|
+
require_relative File.join('..', '..', 'lib', 'vm', 'ReverseCommand')
|
39
|
+
Hem::Lib::Vm::ReverseCommand.new(*args).run
|
40
|
+
|
41
|
+
Hem.ui.success 'Uploaded project root files to the guest'
|
42
|
+
end
|
43
|
+
|
44
|
+
desc 'Rsync from host to guest, or if in reverse mode, from guest to host'
|
45
|
+
argument :from_path
|
46
|
+
argument :to_path
|
47
|
+
argument 'is_reverse', optional: true, default: false
|
48
|
+
task :rsync_manual do |_task_name, args|
|
49
|
+
from_path = args[:from_path]
|
50
|
+
to_path = args[:to_path]
|
51
|
+
|
52
|
+
Hem.ui.title "Syncing #{from_path} to #{to_path}"
|
53
|
+
|
54
|
+
hostname = 'default'
|
55
|
+
if args[:is_reverse]
|
56
|
+
# '--delete' deliberately skipped. VM should not delete files from the host OS.
|
57
|
+
# Don't want to lose work in case of mistakes
|
58
|
+
remote_file_exists = run "if [ -e '#{from_path}' ]; then echo 1; else echo 0; fi", capture: true
|
59
|
+
rsync_command = if remote_file_exists == '1'
|
60
|
+
<<-COMMAND
|
61
|
+
rsync --human-readable --compress --archive --rsh='%s' \
|
62
|
+
'#{hostname}:#{from_path}' '#{to_path}'
|
63
|
+
COMMAND
|
64
|
+
else
|
65
|
+
"echo 'Failed to find source file, skipping'"
|
66
|
+
end
|
67
|
+
else
|
68
|
+
rsync_command = <<-COMMAND
|
69
|
+
if [ -e '#{from_path}' ]; then
|
70
|
+
rsync --human-readable --compress --archive --rsh='%s' \
|
71
|
+
'#{from_path}' '#{hostname}:#{to_path}';
|
72
|
+
else
|
73
|
+
echo 'Failed to find source file, skipping';
|
74
|
+
fi
|
75
|
+
COMMAND
|
76
|
+
end
|
77
|
+
|
78
|
+
args = [rsync_command, { local: true, realtime: true, indent: 2, on: :host, pwd: Hem.project_path }]
|
79
|
+
require_relative File.join('..', '..', 'lib', 'vm', 'ReverseCommand')
|
80
|
+
Hem::Lib::Vm::ReverseCommand.new(*args).run
|
81
|
+
|
82
|
+
Hem.ui.success("Synced #{from_path} to #{to_path}")
|
83
|
+
end
|
84
|
+
|
85
|
+
desc 'Sync changes from a guest directory to a host directory if a given file is newer'
|
86
|
+
argument :from_path
|
87
|
+
argument :to_path
|
88
|
+
argument :deciding_file_path
|
89
|
+
argument :guest_to_host_allowed, optional: true, default: true
|
90
|
+
task :sync_guest_changes do |_task_name, args|
|
91
|
+
Hem.ui.title "Determining if #{args[:deciding_file_path]} is newer on the host or guest"
|
92
|
+
|
93
|
+
local_file_path = File.join(Hem.project_path, args[:deciding_file_path])
|
94
|
+
local_file_modified = 0
|
95
|
+
local_file_modified = File.mtime(local_file_path).to_i if File.exist? local_file_path
|
96
|
+
|
97
|
+
remote_file_path = File.join(Hem.project_config.vm.project_mount_path, args[:deciding_file_path])
|
98
|
+
remote_file_modified = run "if [ -e '#{remote_file_path}' ]; then stat -c \%Y '#{remote_file_path}' ; fi",
|
99
|
+
capture: true
|
100
|
+
|
101
|
+
if local_file_modified.to_i < remote_file_modified.to_i
|
102
|
+
Hem.ui.success("Guest file #{args[:deciding_file_path]} is newer, syncing to host")
|
103
|
+
from_path = File.join(Hem.project_config.vm.project_mount_path, args[:from_path])
|
104
|
+
to_path = File.join(Hem.project_path, args[:to_path])
|
105
|
+
|
106
|
+
Rake::Task['vm:rsync_manual'].execute(
|
107
|
+
from_path: from_path,
|
108
|
+
to_path: to_path,
|
109
|
+
is_reverse: true
|
110
|
+
)
|
111
|
+
elsif args[:guest_to_host_allowed] && local_file_modified.to_i > remote_file_modified.to_i
|
112
|
+
Hem.ui.success("Host file #{args[:deciding_file_path]} is newer, syncing to guest")
|
113
|
+
from_path = File.join(Hem.project_path, args[:to_path])
|
114
|
+
to_path = File.join(Hem.project_config.vm.project_mount_path, args[:from_path])
|
115
|
+
|
116
|
+
Rake::Task['vm:rsync_manual'].execute(
|
117
|
+
from_path: from_path,
|
118
|
+
to_path: to_path
|
119
|
+
)
|
120
|
+
elsif !args[:guest_to_host_allowed]
|
121
|
+
Hem.ui.success('Host is more up to date than the guest but syncing via another method')
|
122
|
+
else
|
123
|
+
Hem.ui.success("Host and guest file #{args[:deciding_file_path]} are up to date, not doing anything")
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
desc 'Provision VM via files and shell scripts only'
|
128
|
+
task :provision_shell do
|
129
|
+
vagrantfile do
|
130
|
+
Hem.ui.title 'Provisioning VM via files and shell scripts only'
|
131
|
+
vagrant_exec 'provision', '--provision-with', 'shell,file'
|
132
|
+
Hem.ui.separator
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
metadata
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: hem-tasks-rsync
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Kieren Evans
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-10-13 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.11'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.11'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rubocop
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.43.0
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.43.0
|
55
|
+
description: Rsync tasks for Hem
|
56
|
+
email:
|
57
|
+
- kevans+hem_tasks@inviqa.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- ".rubocop.yml"
|
63
|
+
- Gemfile
|
64
|
+
- README.md
|
65
|
+
- Rakefile
|
66
|
+
- hem-tasks-rsync.gemspec
|
67
|
+
- lib/hem/lib/vm/ReverseCommand.rb
|
68
|
+
- lib/hem/tasks/rsync.rb
|
69
|
+
- lib/hem/tasks/rsync/deps.rb
|
70
|
+
- lib/hem/tasks/rsync/version.rb
|
71
|
+
- lib/hem/tasks/rsync/vm.rb
|
72
|
+
homepage: ''
|
73
|
+
licenses:
|
74
|
+
- MIT
|
75
|
+
metadata: {}
|
76
|
+
post_install_message:
|
77
|
+
rdoc_options: []
|
78
|
+
require_paths:
|
79
|
+
- lib
|
80
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
requirements: []
|
91
|
+
rubyforge_project:
|
92
|
+
rubygems_version: 2.4.8
|
93
|
+
signing_key:
|
94
|
+
specification_version: 4
|
95
|
+
summary: Rsync tasks for Hem
|
96
|
+
test_files: []
|