directory_push 0.0.1

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.
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: []