directory_push 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 713af2d1df5f371834bcca64bffff82b116e9a6d
4
+ data.tar.gz: ecc2f95f17e166f897ad284ab1e2e20294af0e8a
5
+ SHA512:
6
+ metadata.gz: 496b80ddb9ca54d78fc833f416dd71563424769e1975703ee9fc4c508ba199ac24ead082d384e5e3738fa88d76ca73fe8aa00a5ff0dde1d375cc38b8d87eea33
7
+ data.tar.gz: 19b30ca77b92136e98d6e75e20d6c0484ad01cf708b80d2e91060c115626d64e11dfe6a792f75644c51c6fadd9d27bfff702b77889df7e6e41117bd337361819
data/.gitignore ADDED
@@ -0,0 +1,50 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /spec/examples.txt
9
+ /test/tmp/
10
+ /test/version_tmp/
11
+ /tmp/
12
+
13
+ # Used by dotenv library to load environment variables.
14
+ # .env
15
+
16
+ ## Specific to RubyMotion:
17
+ .dat*
18
+ .repl_history
19
+ build/
20
+ *.bridgesupport
21
+ build-iPhoneOS/
22
+ build-iPhoneSimulator/
23
+
24
+ ## Specific to RubyMotion (use of CocoaPods):
25
+ #
26
+ # We recommend against adding the Pods directory to your .gitignore. However
27
+ # you should judge for yourself, the pros and cons are mentioned at:
28
+ # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
29
+ #
30
+ # vendor/Pods/
31
+
32
+ ## Documentation cache and generated files:
33
+ /.yardoc/
34
+ /_yardoc/
35
+ /doc/
36
+ /rdoc/
37
+
38
+ ## Environment normalization:
39
+ /.bundle/
40
+ /vendor/bundle
41
+ /lib/bundler/man/
42
+
43
+ # for a library or gem, you might want to ignore these files since the code is
44
+ # intended to run in multiple environments; otherwise, check them in:
45
+ # Gemfile.lock
46
+ # .ruby-version
47
+ # .ruby-gemset
48
+
49
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
50
+ .rvmrc
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in directory_push.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2017 Dustin Morrill
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,16 @@
1
+ # Directory Push
2
+
3
+ Pushes changes to files in a directory to a directory on a remote server.
4
+
5
+
6
+ ## Usage
7
+
8
+ 1. Install this gem with `gem install directory_push`.
9
+ 2. Run `directory_push` script.
10
+
11
+
12
+ ## License
13
+
14
+ Copyright Dustin Morrill, 2017
15
+
16
+ MIT License
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'directory_push/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'directory_push'
8
+ spec.version = DirectoryPush::VERSION
9
+ spec.authors = ['Dustin Morrill']
10
+ spec.email = ['dmorrill10@gmail.com']
11
+ spec.summary = 'DirectoryPush: Push file changes to a remote server.'
12
+ spec.description = ''
13
+ spec.homepage = ''
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.bindir = 'exe'
18
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ['lib']
21
+
22
+ spec.add_dependency 'guard'
23
+ spec.add_dependency 'guard-shell'
24
+ spec.add_dependency 'guard-compat'
25
+ spec.add_dependency 'highline'
26
+ spec.add_dependency "rsync"
27
+
28
+ spec.add_development_dependency 'bundler', '~> 1.6'
29
+ spec.add_development_dependency 'rake'
30
+ end
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+ require 'directory_push'
5
+ include DirectoryPush
6
+
7
+ options = {}
8
+ OptionParser.new do |opts|
9
+ opts.banner = "Usage: #{__FILE__} [options]"
10
+
11
+ opts.on_tail("-h", "--help", "Show this message") do
12
+ puts opts
13
+ exit
14
+ end
15
+
16
+ options[:directory_path] = nil
17
+ opts.on(
18
+ "-d",
19
+ "--directory-path [PROJECT PATH]",
20
+ "Path to the directory to push."
21
+ ) do |d|
22
+ options[:directory_path] = d
23
+ end
24
+
25
+ options[:pull] = false
26
+ opts.on(
27
+ "-l",
28
+ "--[no-]pull",
29
+ "Pull changes before pushing. Defaults to #{options[:pull]}"
30
+ ) do |d|
31
+ options[:pull] = d
32
+ end
33
+
34
+ options[:path_on_remote] = nil
35
+ opts.on("-n", "--path-on-remote [PATH]", "Path to the pushed directory on the remote server.") do |d|
36
+ options[:path_on_remote] = d
37
+ end
38
+
39
+ options[:remote_address] = nil
40
+ opts.on("-r", "--remote-address [ADDRESS]", "Address to the remote server.") do |d|
41
+ options[:remote_address] = d
42
+ end
43
+
44
+ options[:user] = Cli::DEFAULT_USER
45
+ opts.on(
46
+ "-u",
47
+ "--user [USER]",
48
+ %W{The user name to use to login to the remote server. Defaults to "#{options[:user]}".}
49
+ ) do |d|
50
+ options[:user] = d
51
+ end
52
+
53
+ options[:rsync_options] = Cli::DEFAULT_RSYNC_OPTIONS
54
+ opts.on(
55
+ "-o",
56
+ "--rsync-options OPTS",
57
+ Array,
58
+ %Q{rsync options. Defaults to #{options[:rsync_options]}.}
59
+ ) { |a| options[:rsync_options] = a.map { |e| e.to_s } }
60
+
61
+ options[:ignore_pattern] = nil
62
+ opts.on(
63
+ "-i",
64
+ "--ignore-pattern [PATTERN]",
65
+ %W{Pattern describing files that gaurd should ignore during its watch.}
66
+ ) do |d|
67
+ options[:ignore_pattern] = d
68
+ end
69
+
70
+ options[:preserve_settings] = true
71
+ opts.on(
72
+ "-s",
73
+ "--[no-]preserve_settings",
74
+ %W{Preserve the configuration settings and a backup of the remote directory before pushing after exiting. Defaults to #{options[:preserve_settings]}.}
75
+ ) do |d|
76
+ options[:preserve_settings] = d
77
+ end
78
+ end.parse!
79
+
80
+ Cli.new(
81
+ options[:directory_path],
82
+ options[:remote_address],
83
+ user: options[:user],
84
+ path_on_remote: options[:path_on_remote],
85
+ pull: options[:pull],
86
+ rsync_options: options[:rsync_options],
87
+ guard_ignore_pattern: options[:ignore_pattern],
88
+ preserve_settings: options[:preserve_settings]
89
+ ).watch
@@ -0,0 +1,3 @@
1
+ module DirectoryPush
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,251 @@
1
+ require File.expand_path('../directory_push/version', __FILE__)
2
+ require 'highline'
3
+ require 'yaml'
4
+ require 'etc'
5
+ require 'fileutils'
6
+ require 'rsync'
7
+
8
+
9
+ module DirectoryPush
10
+ class Cli
11
+ attr_reader(
12
+ :directory_path,
13
+ :path_on_remote,
14
+ :user,
15
+ :remote_address,
16
+ :rsync_options,
17
+ :settings_dir_path
18
+ )
19
+
20
+ FILTER_FILE_NAME = '.rsync-filter'
21
+ DEFAULT_RSYNC_OPTIONS = [
22
+ '--verbose',
23
+ '--archive',
24
+ '--compress',
25
+ '--progress',
26
+ %Q{--exclude-from '#{FILTER_FILE_NAME}'},
27
+ %Q{--timeout '9999'}
28
+ ]
29
+ GUARDFILE_TEXT = %q{
30
+ require 'yaml'
31
+ require 'guard/compat/plugin'
32
+ require 'rsync'
33
+
34
+ config = YAML.load(File.read(File.join(File.dirname(__FILE__), 'config.yml')))
35
+ $rsync_options = config.delete(:rsync)
36
+ $rsync_options << '--delete'
37
+ $source = config.delete(:source)
38
+ ignore_pattern = config.delete(:ignore)
39
+ $remote = %Q{#{config.delete(:user)}@#{config.delete(:remote_address)}:"#{config.delete(:destination)}"}
40
+
41
+ module ::Guard
42
+ class DirectoryPush < Plugin
43
+ private
44
+ def sync()
45
+ Compat::UI.info %Q{Guard::DirectoryPush source: "#{$source}", destination: "#{$remote}", options: #{$rsync_options}}
46
+ result = Rsync.run $source, $remote, $rsync_options
47
+ if result.success?
48
+ result.changes.each do |change|
49
+ Compat::UI.info "#{change.filename} (#{change.summary})"
50
+ end
51
+ else
52
+ Compat::UI.error result.error
53
+ raise result.error
54
+ end
55
+ end
56
+
57
+ public
58
+
59
+ alias_method :start, :sync
60
+ alias_method :stop, :sync
61
+ alias_method :reload, :sync
62
+ alias_method :run_all, :sync
63
+ def run_on_additions(paths)
64
+ Compat::UI.info "Guard::DirectoryPush Files created: #{paths}"
65
+ sync
66
+ end
67
+ def run_on_modifications(paths)
68
+ Compat::UI.info "Guard::DirectoryPush Files changed: #{paths}"
69
+ sync
70
+ end
71
+ def run_on_removals(paths)
72
+ Compat::UI.info "Guard::DirectoryPush Files removed: #{paths}"
73
+ sync
74
+ end
75
+ end
76
+ end
77
+
78
+ config[:verbose] = true
79
+ config[:cli] = '--color'
80
+ config[:sync_on_start] = true
81
+
82
+ directories [$source]
83
+ guard 'directory-push', config do
84
+ watch %r{^.+$}
85
+ if ignore_pattern
86
+ ignore ignore_pattern
87
+ end
88
+ end
89
+ }
90
+
91
+ DEFAULT_USER = Etc.getlogin
92
+
93
+ def initialize(
94
+ directory_path,
95
+ remote_address,
96
+ user: DEFAULT_USER,
97
+ path_on_remote: nil,
98
+ pull: false,
99
+ rsync_options: DEFAULT_RSYNC_OPTIONS,
100
+ guard_ignore_pattern: nil,
101
+ preserve_settings: false
102
+ )
103
+ if (
104
+ remote_address.nil? ||
105
+ remote_address.empty? ||
106
+ remote_address == '~' ||
107
+ remote_address == '$HOME'
108
+ )
109
+ raise ArgumentError.new(
110
+ %Q{Remote address, "#{remote_address}", is invalid!}
111
+ )
112
+ end
113
+
114
+ @directory_path = File.expand_path(directory_path, Dir.pwd)
115
+ unless File.exists?(@directory_path)
116
+ raise ArgumentError.new(
117
+ %Q{Directory "#{@directory_path}" does not exist!}
118
+ )
119
+ end
120
+
121
+ @user = user
122
+ if @user.nil? || @user.empty?
123
+ raise ArgumentError.new(%Q{User "#{@user}" is invalid!.})
124
+ end
125
+
126
+ @remote_address = remote_address
127
+ @path_on_remote = path_on_remote || @directory_path
128
+ @terminal = HighLine.new
129
+ @pull = pull
130
+ @rsync_options = rsync_options
131
+ @guard_ignore_pattern = guard_ignore_pattern
132
+ @preserve_settings = preserve_settings
133
+ @settings_dir_path = File.join(
134
+ Dir.pwd,
135
+ ".#{directory_name}.directory_push-settings"
136
+ )
137
+ end
138
+
139
+ def pull?() @pull end
140
+
141
+ def directory_name() File.basename(@directory_path) end
142
+
143
+ def ensure_setting_dir_present()
144
+ unless File.directory?(settings_dir_path)
145
+ @terminal.say("Creating settings directory, \"#{settings_dir_path}\".")
146
+ FileUtils.mkdir(settings_dir_path)
147
+ end
148
+ end
149
+
150
+ def filter_path() File.join(settings_dir_path, FILTER_FILE_NAME) end
151
+ def config_path() File.join(settings_dir_path, 'config.yml') end
152
+ def guardfile_path() File.join(settings_dir_path, 'Guardfile') end
153
+
154
+ def ensure_filter_file_present()
155
+ ensure_setting_dir_present
156
+ @terminal.say("Creating rsync-filter file")
157
+ gitignore = File.join(@directory_path, '.gitignore')
158
+ if File.exists?(gitignore)
159
+ @terminal.say(
160
+ %Q{Using "#{gitignore}" as rsync-filter since they have the same format.}
161
+ )
162
+ FileUtils.cp(gitignore, filter_path)
163
+ else
164
+ FileUtils.touch(filter_path) unless File.exist?(filter_path)
165
+ end
166
+ end
167
+
168
+ def config()
169
+ {
170
+ source: "#{@directory_path}/",
171
+ user: @user,
172
+ remote_address: @remote_address,
173
+ destination: @path_on_remote,
174
+ rsync: @rsync_options,
175
+ ignore: @guard_ignore_pattern
176
+ }
177
+ end
178
+
179
+ def config_to_yml() YAML.dump(config) end
180
+
181
+ def ensure_config_file_present()
182
+ ensure_setting_dir_present
183
+ unless File.exist?(config_path)
184
+ @terminal.say %Q{Creating config file in "#{config_path}".}
185
+ File.open(config_path, 'w') { |f| f.print config_to_yml }
186
+ end
187
+ end
188
+
189
+ def ensure_guardfile_present()
190
+ ensure_setting_dir_present
191
+ unless File.exist?(guardfile_path)
192
+ @terminal.say %Q{Creating Guardfile in "#{guardfile_path}".}
193
+ File.open(guardfile_path, 'w') { |f| f.print GUARDFILE_TEXT }
194
+ end
195
+ end
196
+
197
+ def pull_from_remote(destination)
198
+ source = "#{@user}@#{@remote_address}:#{@path_on_remote}"
199
+
200
+ @terminal.say %Q{Pulling from "#{source}" and replacing the contents of "#{destination}".}
201
+
202
+ sync source, destination
203
+ end
204
+
205
+ def sync(source, destination)
206
+ result = Rsync.run source, destination, @rsync_options
207
+ if result.success?
208
+ result.changes.each do |change|
209
+ @terminal.say "#{change.filename} (#{change.summary})"
210
+ end
211
+ else
212
+ @terminal.say result.error
213
+ end
214
+ end
215
+
216
+ def backup_dir_path(d)
217
+ File.join settings_dir_path, "#{File.basename(d)}.bak"
218
+ end
219
+
220
+ def watch()
221
+ ensure_config_file_present
222
+ ensure_guardfile_present
223
+ ensure_filter_file_present
224
+ Dir.chdir settings_dir_path do |d|
225
+ if pull?
226
+ directory_path_bak = backup_dir_path(@directory_path)
227
+ @terminal.say %Q{Backing up "#{@directory_path}" in "#{directory_path_bak}".}
228
+ FileUtils.cp_r @directory_path, directory_path_bak
229
+
230
+ pull_from_remote @directory_path
231
+ else
232
+ source = "#{@user}@#{@remote_address}:#{@path_on_remote}/"
233
+ source_bak = backup_dir_path(@path_on_remote)
234
+
235
+ @terminal.say %Q{Backing up "#{source}" in "#{source_bak}".}
236
+ sync source, source_bak
237
+ end
238
+
239
+ @terminal.say "Starting Guard"
240
+ command = "guard"
241
+ @terminal.say command
242
+ system command
243
+ end
244
+
245
+ unless @preserve_settings
246
+ @terminal.say %Q{Removing settings directory, "#{settings_dir_path}".}
247
+ FileUtils.rm_rf(settings_dir_path)
248
+ end
249
+ end
250
+ end
251
+ end
metadata ADDED
@@ -0,0 +1,152 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: directory_push
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Dustin Morrill
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-07-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: guard
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: guard-shell
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: guard-compat
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: highline
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rsync
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: bundler
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.6'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '1.6'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rake
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ description: ''
112
+ email:
113
+ - dmorrill10@gmail.com
114
+ executables:
115
+ - directory_push
116
+ extensions: []
117
+ extra_rdoc_files: []
118
+ files:
119
+ - ".gitignore"
120
+ - Gemfile
121
+ - LICENSE
122
+ - README.md
123
+ - Rakefile
124
+ - directory_push.gemspec
125
+ - exe/directory_push
126
+ - lib/directory_push.rb
127
+ - lib/directory_push/version.rb
128
+ homepage: ''
129
+ licenses:
130
+ - MIT
131
+ metadata: {}
132
+ post_install_message:
133
+ rdoc_options: []
134
+ require_paths:
135
+ - lib
136
+ required_ruby_version: !ruby/object:Gem::Requirement
137
+ requirements:
138
+ - - ">="
139
+ - !ruby/object:Gem::Version
140
+ version: '0'
141
+ required_rubygems_version: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ requirements: []
147
+ rubyforge_project:
148
+ rubygems_version: 2.6.11
149
+ signing_key:
150
+ specification_version: 4
151
+ summary: 'DirectoryPush: Push file changes to a remote server.'
152
+ test_files: []