synqa 0.1.0 → 0.2.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/Gemfile CHANGED
@@ -3,6 +3,9 @@ source "http://rubygems.org"
3
3
  # Example:
4
4
  # gem "activesupport", ">= 2.3.5"
5
5
 
6
+ gem "net-ssh", ">= 2.0"
7
+ gem "net-scp", ">= 1.0"
8
+
6
9
  # Add dependencies to develop your gem here.
7
10
  # Include everything needed to run rake, tests, features, etc.
8
11
  group :development do
data/Gemfile.lock CHANGED
@@ -6,6 +6,9 @@ GEM
6
6
  bundler (~> 1.0.0)
7
7
  git (>= 1.2.5)
8
8
  rake
9
+ net-scp (1.0.4)
10
+ net-ssh (>= 1.99.1)
11
+ net-ssh (2.1.4)
9
12
  rake (0.8.7)
10
13
  rcov (0.9.9)
11
14
  shoulda (2.11.3)
@@ -16,5 +19,7 @@ PLATFORMS
16
19
  DEPENDENCIES
17
20
  bundler (~> 1.0.0)
18
21
  jeweler (~> 1.5.2)
22
+ net-scp (>= 1.0)
23
+ net-ssh (>= 2.0)
19
24
  rcov
20
25
  shoulda
data/README.rdoc CHANGED
@@ -1,7 +1,7 @@
1
1
  = synqa
2
2
 
3
3
  *Synqa* is a simple file syncing tool that works over SSH, and is designed
4
- primarily for maintaining static websites. It uses a hash function to
4
+ primarily for maintaining static websites. It uses a secure hash function to
5
5
  determine which files don't need to be copied because the destination copy
6
6
  is already identical to the source copy.
7
7
 
@@ -20,8 +20,11 @@ I wrote *synqa* for two main reasons:
20
20
  == Dependencies of *synqa* are:
21
21
 
22
22
  * Ruby 1.9.2
23
- * An SSH client. I use *plink*.
24
- * An SCP client. I use *pscp*.
23
+ * Ruby gems *net-ssh* and *net-scp*
24
+
25
+ Optionally:
26
+ * An external SSH client. I use *plink*.
27
+ * An external SCP client. I use *pscp*.
25
28
 
26
29
  For some sample code, see <b>examples/synga-useage.rb</b> and <b>examples/sample-rakefile</b>.
27
30
 
@@ -35,3 +38,6 @@ Synqa is licensed under the GNU General Public License version 3.
35
38
  containing whitespace or non-ASCII characters. Typically this doesn't matter for
36
39
  many static websites, but it will reduce the tool's usefulness as a general purpose
37
40
  backup tool.
41
+
42
+ * Currently *Synqa* does not provide authentication options, on the assumption that you
43
+ will use Pageant (which automagically provides "presented" keys for specified user/host combinations).
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.2.0
@@ -1,4 +1,4 @@
1
- require 'based-directory'
1
+ require 'based'
2
2
  require 'synqa'
3
3
  require 'digest/sha2'
4
4
 
@@ -19,7 +19,7 @@ task :default => [:uploaddry] do |t|
19
19
  end
20
20
 
21
21
  REMOTE_HOST = SshContentHost.new("yourusername@yourhostname.example.com",
22
- Sha256Command.new(), "plink", "pscp")
22
+ Sha256Command.new())
23
23
 
24
24
  REMOTE_SITE = RemoteContentLocation.new(REMOTE_HOST,
25
25
  "/home/username/public",
@@ -29,22 +29,27 @@ LOCAL_SITE = LocalContentLocation.new(UPLOAD_DIR,
29
29
  Digest::SHA256,
30
30
  File.join(SYNQA_DIR, "localContent.txt"))
31
31
 
32
+ # Ensure that directory for cached content files exists
32
33
  task :init do |t|
33
34
  ensureDirectoryExists(SYNQA_DIR)
34
35
  end
35
36
 
37
+ # Delete the cached content files
36
38
  task :clean => [:init] do |t|
37
39
  SyncOperation.new(LOCAL_SITE, REMOTE_SITE).clearCachedContentFiles()
38
40
  end
39
41
 
42
+ # List the files and directories in the remote directory
40
43
  task :list do |t|
41
44
  REMOTE_SITE.listFiles()
42
45
  end
43
-
46
+
47
+ # Dry run for uploading (i.e. syncing) files to remote site
44
48
  task :uploaddry => [:init] do |t|
45
49
  SyncOperation.new(LOCAL_SITE, REMOTE_SITE).doSync(:dryRun => true)
46
50
  end
47
51
 
52
+ # Upload (i.e. sync) files to remote site
48
53
  task :upload => [:init] do |t|
49
54
  SyncOperation.new(LOCAL_SITE, REMOTE_SITE).doSync()
50
55
  end
@@ -1,7 +1,7 @@
1
1
  # Sample code for synqa useage -- you will need to fill in your own details
2
2
 
3
3
  require 'synqa.rb'
4
- require 'based-directory'
4
+ require 'based'
5
5
  require 'digest/sha2'
6
6
 
7
7
  STDOUT.sync = true
@@ -10,12 +10,18 @@ include Synqa
10
10
  sha256Sum = Sha256SumCommand.new() # sha256sum (with 2 characters between hash and file name)
11
11
  sha256 = Sha256Command.new() # sha256 -r (with 1 space between hash and file name)
12
12
 
13
+ # Default is use Ruby net-ssh & net-scp gems, the following line defines external SSH/SCP applications
14
+ # plinkAndPscp = ExternalSshScp.new("plink", "pscp")
15
+
13
16
  localContentLocation = LocalContentLocation.new(Based::BaseDirectory.new("c:/dev/src/project"),
14
17
  Digest::SHA256,
15
18
  "c:/temp/synqa/local.project.content.cache.txt")
19
+ # Default uses Ruby net-ssh & net-scp gems
20
+ remoteHost = SshContentHost.new("username@host.example.com", sha256)
21
+
22
+ # Alternative uses plink & pscp
23
+ #remoteHost = SshContentHost.new("username@host.example.com", sha256, ExternalSshScp)
16
24
 
17
- remoteHost = SshContentHost.new("username@host.example.com",
18
- sha256, "plink", "pscp")
19
25
 
20
26
  # Note: the specification of plink & pscp assumes that keys are managed with Pageant, and therefore
21
27
  # do not need to be specified on the command line.
File without changes
data/lib/synqa.rb CHANGED
@@ -1,4 +1,6 @@
1
1
  require 'time'
2
+ require 'net/ssh'
3
+ require 'net/scp'
2
4
 
3
5
  module Synqa
4
6
 
@@ -13,6 +15,12 @@ module Synqa
13
15
  end
14
16
  end
15
17
 
18
+ # Return the enumerated lines of the command's output
19
+ def getCommandOutput(command)
20
+ puts "#{command.inspect} ..."
21
+ return IO.popen(command)
22
+ end
23
+
16
24
  # Check if the last executed process exited with status 0, if not, raise an exception
17
25
  def checkProcessStatus(description)
18
26
  processStatus = $?
@@ -161,12 +169,6 @@ module Synqa
161
169
  return fileHashes
162
170
  end
163
171
 
164
- # Return the enumerated lines of the command's output
165
- def getCommandOutput(command)
166
- puts "#{command.inspect} ..."
167
- return IO.popen(command)
168
- end
169
-
170
172
  # Construct the ContentTree for the given base directory
171
173
  def getContentTree(baseDir)
172
174
  contentTree = ContentTree.new()
@@ -181,64 +183,167 @@ module Synqa
181
183
  end
182
184
  end
183
185
 
184
- # Representation of a remote system accessible via SSH
185
- class SshContentHost<DirContentHost
186
+ # Execute a (local) command, or, if dryRun, just pretend to execute it.
187
+ # Raise an exception if the process exit status is not 0.
188
+ def executeCommand(command, dryRun)
189
+ puts "EXECUTE: #{command}"
190
+ if not dryRun
191
+ system(command)
192
+ checkProcessStatus(command)
193
+ end
194
+ end
195
+
196
+ # Base SSH/SCP implementation
197
+ class BaseSshScp
186
198
 
199
+ # delete remote directory (if dryRun is false) using "rm -r"
200
+ def deleteDirectory(userAtHost, dirPath, dryRun)
201
+ ssh(userAtHost, "rm -r #{dirPath}", dryRun)
202
+ end
203
+
204
+ # delete remote file (if dryRun is false) using "rm"
205
+ def deleteFile(userAtHost, filePath, dryRun)
206
+ ssh(userAtHost, "rm #{filePath}", dryRun)
207
+ end
208
+ end
209
+
210
+ # SSH/SCP using Ruby Net::SSH & Net::SCP
211
+ class InternalSshScp<BaseSshScp
212
+
213
+ # execute command on remote host (if dryRun is false), yielding lines of output
214
+ def ssh(userAtHost, commandString, dryRun)
215
+ user, host = userAtHost.split("@")
216
+ description = "SSH #{user}@#{host}: executing #{commandString}"
217
+ puts description
218
+ if not dryRun
219
+ Net::SSH.start(host, user) do |ssh|
220
+ outputText = ssh.exec!(commandString)
221
+ if outputText != nil then
222
+ for line in outputText.split("\n") do
223
+ yield line
224
+ end
225
+ end
226
+ end
227
+ end
228
+ end
229
+
230
+ # copy a local directory to a remote directory (if dryRun is false)
231
+ def copyLocalToRemoteDirectory(userAtHost, sourcePath, destinationPath, dryRun)
232
+ user, host = userAtHost.split("@")
233
+ description = "SCP: copy directory #{sourcePath} to #{user}@#{host}:#{destinationPath}"
234
+ puts description
235
+ if not dryRun
236
+ Net::SCP.upload!(host, user, sourcePath, destinationPath, :recursive => true)
237
+ end
238
+ end
239
+
240
+ # copy a local file to a remote directory (if dryRun is false)
241
+ def copyLocalFileToRemoteDirectory(userAtHost, sourcePath, destinationPath, dryRun)
242
+ user, host = userAtHost.split("@")
243
+ description = "SCP: copy file #{sourcePath} to #{user}@#{host}:#{destinationPath}"
244
+ puts description
245
+ if not dryRun
246
+ Net::SCP.upload!(host, user, sourcePath, destinationPath)
247
+ end
248
+ end
249
+
250
+ end
251
+
252
+ # SSH/SCP using external commands, such as "plink" and "pscp"
253
+ class ExternalSshScp<BaseSshScp
187
254
  # The SSH client, e.g. ["ssh"] or ["plink","-pw","mysecretpassword"] (i.e. command + args as an array)
188
255
  attr_reader :shell
189
256
 
190
257
  # The SCP client, e.g. ["scp"] or ["pscp","-pw","mysecretpassword"] (i.e. command + args as an array)
191
258
  attr_reader :scpProgram
192
-
193
- # The remote host, e.g. "username@host.example.com"
194
- attr_reader :host
195
-
259
+
196
260
  # The SCP command as a string
197
261
  attr_reader :scpCommandString
198
-
199
- def initialize(host, hashCommand, shell, scpProgram)
200
- super(hashCommand)
201
- @host = host
262
+
263
+ def initialize(shell, scpProgram)
202
264
  @shell = shell.is_a?(String) ? [shell] : shell
203
265
  @scpProgram = scpProgram.is_a?(String) ? [scpProgram] : scpProgram
204
266
  @scpCommandString = @scpProgram.join(" ")
205
267
  end
206
268
 
207
- # Return readable description of base directory on remote system
208
- def locationDescriptor(baseDir)
209
- baseDir = normalisedDir(baseDir)
210
- return "#{host}:#{baseDir} (connect = #{shell}/#{scpProgram}, hashCommand = #{hashCommand})"
211
- end
212
-
213
- # execute an SSH command on the remote system, yielding lines of output
214
- # (or don't actually execute, if dryRun is true)
215
- def executeRemoteCommand(commandString, dryRun = false)
216
- puts "SSH #{host} (#{shell.join(" ")}): executing #{commandString}"
269
+ # execute command on remote host (if dryRun is false), yielding lines of output
270
+ def ssh(userAtHost, commandString, dryRun)
271
+ puts "SSH #{userAtHost} (#{shell.join(" ")}): executing #{commandString}"
217
272
  if not dryRun
218
- output = getCommandOutput(shell + [host, commandString])
273
+ output = getCommandOutput(shell + [userAtHost, commandString])
219
274
  while (line = output.gets)
220
275
  yield line.chomp
221
276
  end
222
277
  output.close()
223
- checkProcessStatus("SSH #{host} #{commandString}")
278
+ checkProcessStatus("SSH #{userAtHost} #{commandString}")
224
279
  end
225
280
  end
226
281
 
227
- # execute an SSH command on the remote system, displaying output to stdout,
228
- # (or don't actually execute, if dryRun is true)
282
+ # copy a local directory to a remote directory (if dryRun is false)
283
+ def copyLocalToRemoteDirectory(userAtHost, sourcePath, destinationPath, dryRun)
284
+ executeCommand("#{@scpCommandString} -r #{sourcePath} #{userAtHost}:#{destinationPath}", dryRun)
285
+ end
286
+
287
+ # copy a local file to a remote directory (if dryRun is false)
288
+ def copyLocalFileToRemoteDirectory(userAtHost, sourcePath, destinationPath, dryRun)
289
+ executeCommand("#{@scpCommandString} #{sourcePath} #{userAtHost}:#{destinationPath}", dryRun)
290
+ end
291
+
292
+ end
293
+
294
+ # Representation of a remote system accessible via SSH
295
+ class SshContentHost<DirContentHost
296
+
297
+ # The remote userAtHost, e.g. "username@host.example.com"
298
+ attr_reader :userAtHost, :sshAndScp
299
+
300
+ def initialize(userAtHost, hashCommand, sshAndScp = nil)
301
+ super(hashCommand)
302
+ @sshAndScp = sshAndScp != nil ? sshAndScp : InternalSshScp.new()
303
+ @userAtHost = userAtHost
304
+ end
305
+
306
+ # Return readable description of base directory on remote system
307
+ def locationDescriptor(baseDir)
308
+ baseDir = normalisedDir(baseDir)
309
+ return "#{userAtHost}:#{baseDir} (connect = #{shell}/#{scpProgram}, hashCommand = #{hashCommand})"
310
+ end
311
+
312
+ # execute an SSH command on the remote system, yielding lines of output
313
+ # (or don't actually execute, if dryRun is false)
229
314
  def ssh(commandString, dryRun = false)
230
- executeRemoteCommand(commandString, dryRun) do |line|
231
- puts line
315
+ sshAndScp.ssh(userAtHost, commandString, dryRun) do |line|
316
+ yield line
232
317
  end
233
318
  end
234
319
 
320
+ # delete a remote directory, if dryRun is false
321
+ def deleteDirectory(dirPath, dryRun)
322
+ sshAndScp.deleteDirectory(userAtHost, dirPath, dryRun)
323
+ end
324
+
325
+ # delete a remote file, if dryRun is false
326
+ def deleteFile(filePath, dryRun)
327
+ sshAndScp.deleteFile(userAtHost, filePath, dryRun)
328
+ end
329
+
330
+ # copy a local directory to a remote directory, if dryRun is false
331
+ def copyLocalToRemoteDirectory(sourcePath, destinationPath, dryRun)
332
+ sshAndScp.copyLocalToRemoteDirectory(userAtHost, sourcePath, destinationPath, dryRun)
333
+ end
334
+
335
+ # copy a local file to a remote directory, if dryRun is false
336
+ def copyLocalFileToRemoteDirectory(sourcePath, destinationPath, dryRun)
337
+ sshAndScp.copyLocalFileToRemoteDirectory(userAtHost, sourcePath, destinationPath, dryRun)
338
+ end
339
+
235
340
  # Return a list of all subdirectories of the base directory (as paths relative to the base directory)
236
341
  def listDirectories(baseDir)
237
342
  baseDir = normalisedDir(baseDir)
238
343
  puts "Listing directories ..."
239
344
  directories = []
240
345
  baseDirLen = baseDir.length
241
- executeRemoteCommand(findDirectoriesCommand(baseDir).join(" ")) do |line|
346
+ ssh(findDirectoriesCommand(baseDir).join(" ")) do |line|
242
347
  puts " #{line}"
243
348
  if line.start_with?(baseDir)
244
349
  directories << line[baseDirLen..-1]
@@ -254,7 +359,7 @@ module Synqa
254
359
  def listFileHashLines(baseDir)
255
360
  baseDir = normalisedDir(baseDir)
256
361
  remoteFileHashLinesCommand = findFilesCommand(baseDir) + ["|", "xargs", "-r"] + @hashCommand.command
257
- executeRemoteCommand(remoteFileHashLinesCommand.join(" ")) do |line|
362
+ ssh(remoteFileHashLinesCommand.join(" ")) do |line|
258
363
  puts " #{line}"
259
364
  yield line
260
365
  end
@@ -263,15 +368,11 @@ module Synqa
263
368
  # List all files within the base directory to stdout
264
369
  def listFiles(baseDir)
265
370
  baseDir = normalisedDir(baseDir)
266
- executeRemoteCommand(findFilesCommand(baseDir).join(" ")) do |line|
371
+ ssh(findFilesCommand(baseDir).join(" ")) do |line|
267
372
  puts " #{line}"
268
373
  end
269
374
  end
270
375
 
271
- # Get the remote path of the directory or file on the host, in the format required by SCP
272
- def getScpPath(path)
273
- return host + ":" + path
274
- end
275
376
  end
276
377
 
277
378
  # An object representing the content of a file within a ContentTree.
@@ -315,8 +416,8 @@ module Synqa
315
416
  return "#{name} (#{hash})"
316
417
  end
317
418
 
318
- # The full (relative) name of this file in the content tree
319
- def fullPath
419
+ # The relative name of this file in the content tree (relative to the base dir)
420
+ def relativePath
320
421
  return (parentPathElements + [name]).join("/")
321
422
  end
322
423
  end
@@ -376,8 +477,8 @@ module Synqa
376
477
  @toBeDeleted = true
377
478
  end
378
479
 
379
- # the full path of the directory that this content tree represents (relative to the base directory)
380
- def fullPath
480
+ # the path of the directory that this content tree represents, relative to the base directory
481
+ def relativePath
381
482
  return @pathElements.join("/")
382
483
  end
383
484
 
@@ -446,7 +547,7 @@ module Synqa
446
547
  puts "#{currentIndent}#{name}"
447
548
  end
448
549
  if copyDestination != nil
449
- puts "#{currentIndent} [COPY to #{copyDestination.fullPath}]"
550
+ puts "#{currentIndent} [COPY to #{copyDestination.relativePath}]"
450
551
  end
451
552
  if toBeDeleted
452
553
  puts "#{currentIndent} [DELETE]"
@@ -458,7 +559,7 @@ module Synqa
458
559
  for file in files
459
560
  puts "#{nextIndent}#{file.name} - #{file.hash}"
460
561
  if file.copyDestination != nil
461
- puts "#{nextIndent} [COPY to #{file.copyDestination.fullPath}]"
562
+ puts "#{nextIndent} [COPY to #{file.copyDestination.relativePath}]"
462
563
  end
463
564
  if file.toBeDeleted
464
565
  puts "#{nextIndent} [DELETE]"
@@ -677,11 +778,6 @@ module Synqa
677
778
  @hashClass = hashClass
678
779
  end
679
780
 
680
- # get the path as required for an SCP command
681
- def getScpPath(relativePath)
682
- return getFullPath(relativePath)
683
- end
684
-
685
781
  # get the full path of a relative path (i.e. of a file/directory within the base directory)
686
782
  def getFullPath(relativePath)
687
783
  return @baseDirectory.fullPath + relativePath
@@ -722,25 +818,25 @@ module Synqa
722
818
  # A directory of files on a remote system
723
819
  class RemoteContentLocation<ContentLocation
724
820
  # the remote username@host value
725
- attr_reader :host
821
+ attr_reader :userAtHost
726
822
 
727
823
  # the base directory on the remote system
728
824
  attr_reader :baseDir
729
825
 
730
- def initialize(host, baseDir, cachedContentFile = nil)
826
+ def initialize(userAtHost, baseDir, cachedContentFile = nil)
731
827
  super(cachedContentFile)
732
- @host = host
828
+ @userAtHost = userAtHost
733
829
  @baseDir = normalisedDir(baseDir)
734
830
  end
735
831
 
736
- # list files within the base directory on the remote host
832
+ # list files within the base directory on the remote userAtHost
737
833
  def listFiles()
738
- host.listFiles(baseDir)
834
+ userAtHost.listFiles(baseDir)
739
835
  end
740
836
 
741
- # the command string required to execute SCP (e.g. "scp" or "pscp", possibly with extra args)
742
- def scpCommandString
743
- return host.scpCommandString
837
+ # object required to execute SCP (e.g. "scp" or "pscp", possibly with extra args)
838
+ def sshAndScp
839
+ return userAtHost.sshAndScp
744
840
  end
745
841
 
746
842
  # get the full path of a relative path
@@ -748,28 +844,23 @@ module Synqa
748
844
  return baseDir + relativePath
749
845
  end
750
846
 
751
- # get the full path of a file as required in an SCP command (i.e. with username@host prepended)
752
- def getScpPath(relativePath)
753
- return host.getScpPath(getFullPath(relativePath))
754
- end
755
-
756
847
  # execute an SSH command on the remote host (or just pretend, if dryRun is true)
757
848
  def ssh(commandString, dryRun = false)
758
- host.ssh(commandString, dryRun)
849
+ userAtHost.sshAndScp.ssh(commandString, dryRun)
759
850
  end
760
851
 
761
852
  # list all sub-directories of the base directory on the remote host
762
853
  def listDirectories
763
- return host.listDirectories(baseDir)
854
+ return userAtHost.listDirectories(baseDir)
764
855
  end
765
856
 
766
857
  # list all the file hashes of the files within the base directory
767
858
  def listFileHashes
768
- return host.listFileHashes(baseDir)
859
+ return userAtHost.listFileHashes(baseDir)
769
860
  end
770
861
 
771
862
  def to_s
772
- return host.locationDescriptor(baseDir)
863
+ return userAtHost.locationDescriptor(baseDir)
773
864
  end
774
865
 
775
866
  # Get the content tree, from the cached content file if it exists,
@@ -780,7 +871,7 @@ module Synqa
780
871
  if cachedContentFile and File.exists?(cachedContentFile)
781
872
  return ContentTree.readFromFile(cachedContentFile)
782
873
  else
783
- contentTree = host.getContentTree(baseDir)
874
+ contentTree = userAtHost.getContentTree(baseDir)
784
875
  contentTree.sort!
785
876
  if cachedContentFile != nil
786
877
  contentTree.writeToFile(cachedContentFile)
@@ -845,7 +936,7 @@ module Synqa
845
936
  end
846
937
  doAllCopyOperations(dryRun)
847
938
  doAllDeleteOperations(dryRun)
848
- if (@destinationLocation.cachedContentFile and @sourceLocation.cachedContentFile and
939
+ if (not dryRun and @destinationLocation.cachedContentFile and @sourceLocation.cachedContentFile and
849
940
  File.exists?(@sourceLocation.cachedContentFile))
850
941
  FileUtils::Verbose.cp(@sourceLocation.cachedContentFile, @destinationLocation.cachedContentFile)
851
942
  end
@@ -876,18 +967,18 @@ module Synqa
876
967
  def doCopyOperations(sourceContent, destinationContent, dryRun)
877
968
  for dir in sourceContent.dirs
878
969
  if dir.copyDestination != nil
879
- sourcePath = sourceLocation.getScpPath(dir.fullPath)
880
- destinationPath = destinationLocation.getScpPath(dir.copyDestination.fullPath)
881
- executeCommand("#{destinationLocation.scpCommandString} -r #{sourcePath} #{destinationPath}", dryRun)
970
+ sourcePath = sourceLocation.getFullPath(dir.relativePath)
971
+ destinationPath = destinationLocation.getFullPath(dir.copyDestination.relativePath)
972
+ destinationLocation.userAtHost.copyLocalToRemoteDirectory(sourcePath, destinationPath, dryRun)
882
973
  else
883
974
  doCopyOperations(dir, destinationContent.getDir(dir.name), dryRun)
884
975
  end
885
976
  end
886
977
  for file in sourceContent.files
887
978
  if file.copyDestination != nil
888
- sourcePath = sourceLocation.getScpPath(file.fullPath)
889
- destinationPath = destinationLocation.getScpPath(file.copyDestination.fullPath)
890
- executeCommand("#{destinationLocation.scpCommandString} #{sourcePath} #{destinationPath}", dryRun)
979
+ sourcePath = sourceLocation.getFullPath(file.relativePath)
980
+ destinationPath = destinationLocation.getFullPath(file.copyDestination.relativePath)
981
+ destinationLocation.userAtHost.copyLocalFileToRemoteDirectory(sourcePath, destinationPath, dryRun)
891
982
  end
892
983
  end
893
984
  end
@@ -897,16 +988,16 @@ module Synqa
897
988
  def doDeleteOperations(destinationContent, dryRun)
898
989
  for dir in destinationContent.dirs
899
990
  if dir.toBeDeleted
900
- dirPath = destinationLocation.getFullPath(dir.fullPath)
901
- destinationLocation.ssh("rm -r #{dirPath}", dryRun)
991
+ dirPath = destinationLocation.getFullPath(dir.relativePath)
992
+ destinationLocation.userAtHost.deleteDirectory(dirPath, dryRun)
902
993
  else
903
994
  doDeleteOperations(dir, dryRun)
904
995
  end
905
996
  end
906
997
  for file in destinationContent.files
907
998
  if file.toBeDeleted
908
- filePath = destinationLocation.getFullPath(file.fullPath)
909
- destinationLocation.ssh("rm #{filePath}", dryRun)
999
+ filePath = destinationLocation.getFullPath(file.relativePath)
1000
+ destinationLocation.userAtHost.deleteFile(filePath, dryRun)
910
1001
  end
911
1002
  end
912
1003
  end
@@ -1,6 +1,6 @@
1
1
  require 'helper'
2
2
 
3
- require 'based-directory'
3
+ require 'based'
4
4
 
5
5
  module Based
6
6
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: synqa
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,12 +9,34 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-03-19 00:00:00.000000000 +13:00
12
+ date: 2011-04-19 00:00:00.000000000 +12:00
13
13
  default_executable:
14
14
  dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: net-ssh
17
+ requirement: &25189860 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '2.0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: *25189860
26
+ - !ruby/object:Gem::Dependency
27
+ name: net-scp
28
+ requirement: &25189176 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '1.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: *25189176
15
37
  - !ruby/object:Gem::Dependency
16
38
  name: shoulda
17
- requirement: &24879420 !ruby/object:Gem::Requirement
39
+ requirement: &25188444 !ruby/object:Gem::Requirement
18
40
  none: false
19
41
  requirements:
20
42
  - - ! '>='
@@ -22,10 +44,10 @@ dependencies:
22
44
  version: '0'
23
45
  type: :development
24
46
  prerelease: false
25
- version_requirements: *24879420
47
+ version_requirements: *25188444
26
48
  - !ruby/object:Gem::Dependency
27
49
  name: bundler
28
- requirement: &24878820 !ruby/object:Gem::Requirement
50
+ requirement: &25187796 !ruby/object:Gem::Requirement
29
51
  none: false
30
52
  requirements:
31
53
  - - ~>
@@ -33,10 +55,10 @@ dependencies:
33
55
  version: 1.0.0
34
56
  type: :development
35
57
  prerelease: false
36
- version_requirements: *24878820
58
+ version_requirements: *25187796
37
59
  - !ruby/object:Gem::Dependency
38
60
  name: jeweler
39
- requirement: &24878220 !ruby/object:Gem::Requirement
61
+ requirement: &25180356 !ruby/object:Gem::Requirement
40
62
  none: false
41
63
  requirements:
42
64
  - - ~>
@@ -44,10 +66,10 @@ dependencies:
44
66
  version: 1.5.2
45
67
  type: :development
46
68
  prerelease: false
47
- version_requirements: *24878220
69
+ version_requirements: *25180356
48
70
  - !ruby/object:Gem::Dependency
49
71
  name: rcov
50
- requirement: &24877560 !ruby/object:Gem::Requirement
72
+ requirement: &25179864 !ruby/object:Gem::Requirement
51
73
  none: false
52
74
  requirements:
53
75
  - - ! '>='
@@ -55,7 +77,7 @@ dependencies:
55
77
  version: '0'
56
78
  type: :development
57
79
  prerelease: false
58
- version_requirements: *24877560
80
+ version_requirements: *25179864
59
81
  description: Sync files from a local directory to a remote directory via SSH/SCP
60
82
  email: http://www.1729.com/email.html
61
83
  executables: []
@@ -74,7 +96,7 @@ files:
74
96
  - _project.el
75
97
  - examples/sample-rakefile
76
98
  - examples/synqa-useage.rb
77
- - lib/based-directory.rb
99
+ - lib/based.rb
78
100
  - lib/synqa.rb
79
101
  - test/data/dir1/dir2/dir4/dir5/file6.text
80
102
  - test/data/dir1/dir2/dir4/file5.text
@@ -83,7 +105,7 @@ files:
83
105
  - test/data/dir1/file1.txt
84
106
  - test/data/dir1/file2.txt
85
107
  - test/helper.rb
86
- - test/test_based_directory.rb
108
+ - test/test_based.rb
87
109
  - test/test_synqa.rb
88
110
  has_rdoc: true
89
111
  homepage: http://www.1729.com/software/synqa/
@@ -101,7 +123,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
101
123
  version: '0'
102
124
  segments:
103
125
  - 0
104
- hash: 537622927
126
+ hash: 874582639
105
127
  required_rubygems_version: !ruby/object:Gem::Requirement
106
128
  none: false
107
129
  requirements:
@@ -117,5 +139,5 @@ summary: Sync files from a local directory to a remote directory via SSH/SCP
117
139
  test_files:
118
140
  - examples/synqa-useage.rb
119
141
  - test/helper.rb
120
- - test/test_based_directory.rb
142
+ - test/test_based.rb
121
143
  - test/test_synqa.rb