synqa 0.0.3 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -40,7 +40,7 @@ Rcov::RcovTask.new do |test|
40
40
  test.verbose = true
41
41
  end
42
42
 
43
- task :default => :rdoc
43
+ task :default => :test
44
44
 
45
45
  require 'rake/rdoctask'
46
46
  Rake::RDocTask.new do |rdoc|
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.3
1
+ 0.1.0
@@ -1,33 +1,21 @@
1
-
2
- # A redacted rakefile example using Synqa
3
- # In this example the source files are copied directly from ./src to
4
- # yourusername@yourhostname.example.com/home/username/public.
5
- #
6
- # For a more complex static site, your rakefile might generate the site
7
- # into an output directory and upload from there.
8
- #
9
- # Tasks:
10
- # clean - removes the cached content files
11
- # upload - syncs local content with remote dir (i.e. uploads new/changed files
12
- # and deletes remote files that don't exist in the local dir
13
- # uploaddry - a "dry run" for upload, doesn't actually upload or delete files
14
-
15
- require 'rejinnirate-rake'
16
- require 'synqa' # This assumes synqa is installed as a gem, otherwise require 'synqa.rb'
1
+ require 'based-directory'
2
+ require 'synqa'
17
3
  require 'digest/sha2'
18
4
 
19
5
  STDOUT.sync = true
20
6
 
21
- include Rejinnirate
22
7
  include Synqa
23
8
 
24
9
  BASE_DIR = File.dirname(__FILE__)
25
10
 
26
11
  SRC_DIR = File.join(BASE_DIR, "src")
27
- UPLOAD_DIR = SRC_DIR
12
+
13
+ UPLOAD_DIR = Based::BaseDirectory.new(SRC_DIR,
14
+ :fileExclude => lambda{|file| file.name.end_with?("~")})
15
+
28
16
  SYNQA_DIR = File.join(BASE_DIR, "output", "synqa")
29
17
 
30
- task :default => [:upload] do |t|
18
+ task :default => [:uploaddry] do |t|
31
19
  end
32
20
 
33
21
  REMOTE_HOST = SshContentHost.new("yourusername@yourhostname.example.com",
@@ -39,8 +27,7 @@ REMOTE_SITE = RemoteContentLocation.new(REMOTE_HOST,
39
27
 
40
28
  LOCAL_SITE = LocalContentLocation.new(UPLOAD_DIR,
41
29
  Digest::SHA256,
42
- File.join(SYNQA_DIR, "localContent.txt"),
43
- :excludes => ["*\\~", "**/*\\~"])
30
+ File.join(SYNQA_DIR, "localContent.txt"))
44
31
 
45
32
  task :init do |t|
46
33
  ensureDirectoryExists(SYNQA_DIR)
@@ -1,6 +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
5
  require 'digest/sha2'
5
6
 
6
7
  STDOUT.sync = true
@@ -9,7 +10,7 @@ include Synqa
9
10
  sha256Sum = Sha256SumCommand.new() # sha256sum (with 2 characters between hash and file name)
10
11
  sha256 = Sha256Command.new() # sha256 -r (with 1 space between hash and file name)
11
12
 
12
- localContentLocation = LocalContentLocation.new("c:/dev/src/project",
13
+ localContentLocation = LocalContentLocation.new(Based::BaseDirectory.new("c:/dev/src/project"),
13
14
  Digest::SHA256,
14
15
  "c:/temp/synqa/local.project.content.cache.txt")
15
16
 
@@ -0,0 +1,177 @@
1
+ # The Based module supports the concept of a "based" directory. Typically in modern software development,
2
+ # a project is represented by a set of sub-directories and files within a base directory. The exact location
3
+ # of the base directory is not so important (i.e. it's wherever you checked it out of source control). For a given
4
+ # file or sub-directory, one is often more interested in the path relative to the base directory, rather than
5
+ # the absolute path. (But you still need the full path when performing an actual file operation on the file
6
+ # or directory.)
7
+ # Also, there might be files and directories that you wish to ignore. Based supports simple functional includes and
8
+ # excludes. (A bit less succint than include/exclude globs, but probably more flexible.)
9
+
10
+ module Based
11
+
12
+ # A base class for directories: i.e. either the base directory itself, or a sub-directory
13
+ class Directory
14
+ # The base directory (object)
15
+ attr_reader :base
16
+
17
+ # The path of this directory relative to the base directory (includes a following "/" if non-empty)
18
+ attr_reader :relativePath
19
+
20
+ # The elements of the relative path as an array
21
+ attr_reader :pathElements
22
+
23
+ # The immediate name of the directory (nil for the base directory)
24
+ attr_reader :name
25
+
26
+ # The parent directory (nil for the base directory)
27
+ attr_reader :parent
28
+
29
+ # The full path of the file
30
+ attr_reader :fullPath
31
+
32
+ # initialise with un-initialised entries
33
+ def initialize
34
+ @entries = nil
35
+ end
36
+
37
+ # get the "entries", i.e. list of files and directories immediately contained in this directory, and cache them.
38
+ # Note that dirExclude, fileInclude and fileExclude functions in the base directory object
39
+ # may be applied to filter out some entries.
40
+ def getEntries
41
+ if @entries == nil
42
+ @entries = Dir.entries(fullPath)
43
+ @dirs = []
44
+ @files = []
45
+ for entry in @entries
46
+ if entry != "." and entry != ".."
47
+ fullEntryPath = fullPath + entry
48
+ if ::File.directory?(fullEntryPath)
49
+ subDirectory = SubDirectory.new(entry, self)
50
+ if @base.dirExclude == nil or not @base.dirExclude.call(subDirectory)
51
+ @dirs << subDirectory
52
+ end
53
+ elsif ::File.file?(fullEntryPath)
54
+ file = File.new(entry, self)
55
+ if @base.fileInclude == nil or @base.fileInclude.call(file)
56
+ if @base.fileExclude == nil or not @base.fileExclude.call(file)
57
+ @files << file
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ @dirs.sort_by! {|dir| dir.name}
64
+ @files.sort_by! {|file| file.name}
65
+ end
66
+ end
67
+
68
+ # Get list of files immediately contained in this directory
69
+ def files
70
+ getEntries()
71
+ return @files
72
+ end
73
+
74
+ # Get list of directories immediately contained in this directory
75
+ def dirs
76
+ getEntries()
77
+ return @dirs
78
+ end
79
+
80
+ # Get a list of all the sub-directories of this directory (with parents preceding children)
81
+ def subDirs
82
+ result = []
83
+ for dir in dirs
84
+ result << dir
85
+ result += dir.subDirs
86
+ end
87
+ return result
88
+ end
89
+
90
+ # Get a list of all files contained within this directory
91
+ def allFiles
92
+ result = files
93
+ for subDir in subDirs
94
+ result += subDir.files
95
+ end
96
+ return result
97
+ end
98
+ end
99
+
100
+ # An object representing a sub-directory (i.e. not the base directory itself)
101
+ class SubDirectory<Directory
102
+
103
+ # Construct directory object from parent directory object and this directory's name
104
+ def initialize(name, parent)
105
+ super()
106
+ @name = name
107
+ @parent = parent
108
+ @base = @parent.base
109
+ @relativePath = @parent.relativePath + @name + "/"
110
+ @pathElements = @parent.pathElements + [name]
111
+ @fullPath = @parent.fullPath + @name + "/"
112
+ end
113
+ end
114
+
115
+ # An object representing the base directory
116
+ class BaseDirectory<Directory
117
+
118
+ # Function to decide if files should be included (if nil, assume all included). Subject
119
+ # to exclusion by fileExclude
120
+ attr_reader :fileInclude
121
+
122
+ # Function to decide if files should be excluded
123
+ attr_reader :fileExclude
124
+
125
+ # Function to decide if sub-directories should be excluded (if a directory is excluded, so
126
+ # are all it's sub-directories and files contained within)
127
+ attr_reader :dirExclude
128
+
129
+ # Initialise from absolute file path. Options include :dirExclude, :fileInclude and :fileExclude
130
+ def initialize(path, options = {})
131
+ super()
132
+ @name = nil
133
+ @parent = nil
134
+ @base = self
135
+ @relativePath = ""
136
+ @pathElements = []
137
+ @fullPath = path.end_with?("/") ? path : path + "/"
138
+ @dirExclude = options.fetch(:dirExclude, nil)
139
+ @fileInclude = options.fetch(:fileInclude, nil)
140
+ @fileExclude = options.fetch(:fileExclude, nil)
141
+ end
142
+ end
143
+
144
+ # An object representing a file within the base directory
145
+ class File
146
+ # immediate name of file
147
+ attr_reader :name
148
+
149
+ # parent, i.e. containing directory
150
+ attr_reader :parent
151
+
152
+ # the base directory
153
+ attr_reader :base
154
+
155
+ # path of this file relative to base directory
156
+ attr_reader :relativePath
157
+
158
+ # elements of file path (including the name) as an array
159
+ attr_reader :pathElements
160
+
161
+ # full absolute path name of file
162
+ attr_reader :fullPath
163
+
164
+ # initialise from name and containing directory
165
+ def initialize(name, parent)
166
+ super()
167
+ @name = name
168
+ @parent = parent
169
+ @base = @parent.base
170
+ @relativePath = @parent.relativePath + @name
171
+ @pathElements = @parent.pathElements + [name]
172
+ @fullPath = @parent.fullPath + @name
173
+ end
174
+
175
+ end
176
+
177
+ end
data/lib/synqa.rb CHANGED
@@ -2,6 +2,17 @@ require 'time'
2
2
 
3
3
  module Synqa
4
4
 
5
+ # ensure that a directory exists
6
+ def ensureDirectoryExists(directoryName)
7
+ if File.exist? directoryName
8
+ if not File.directory? directoryName
9
+ raise "#{directoryName} is a non-directory file"
10
+ end
11
+ else
12
+ FileUtils.makedirs(directoryName)
13
+ end
14
+ end
15
+
5
16
  # Check if the last executed process exited with status 0, if not, raise an exception
6
17
  def checkProcessStatus(description)
7
18
  processStatus = $?
@@ -400,7 +411,7 @@ module Synqa
400
411
  def sort!
401
412
  dirs.sort_by! {|dir| dir.name}
402
413
  files.sort_by! {|file| file.name}
403
- for dir in dirs do
414
+ for dir in dirs
404
415
  dir.sort!
405
416
  end
406
417
  end
@@ -441,10 +452,10 @@ module Synqa
441
452
  puts "#{currentIndent} [DELETE]"
442
453
  end
443
454
  nextIndent = currentIndent + indent
444
- for dir in dirs do
455
+ for dir in dirs
445
456
  dir.showIndented("#{dir.name}/", indent = indent, currentIndent = nextIndent)
446
457
  end
447
- for file in files do
458
+ for file in files
448
459
  puts "#{nextIndent}#{file.name} - #{file.hash}"
449
460
  if file.copyDestination != nil
450
461
  puts "#{nextIndent} [COPY to #{file.copyDestination.fullPath}]"
@@ -460,11 +471,11 @@ module Synqa
460
471
  if time != nil
461
472
  outFile.puts("T #{time.strftime(@@dateTimeFormat)}\n")
462
473
  end
463
- for dir in dirs do
474
+ for dir in dirs
464
475
  outFile.puts("D #{prefix}#{dir.name}\n")
465
476
  dir.writeLinesToFile(outFile, "#{prefix}#{dir.name}/")
466
477
  end
467
- for file in files do
478
+ for file in files
468
479
  outFile.puts("F #{file.hash} #{prefix}#{file.name}\n")
469
480
  end
470
481
  end
@@ -654,26 +665,16 @@ module Synqa
654
665
  # can be calculated directly using Ruby library functions.
655
666
  class LocalContentLocation<ContentLocation
656
667
 
657
- # the base directory
658
- attr_reader :baseDir
668
+ # the base directory, for example of type Based::BaseDirectory. Methods invoked are: allFiles, subDirs and fullPath.
669
+ # For file and dir objects returned by allFiles & subDirs, methods invoked are: relativePath and fullPath
670
+ attr_reader :baseDirectory
659
671
  # the ruby class that generates the hash, e.g. Digest::SHA256
660
672
  attr_reader :hashClass
661
673
 
662
- def initialize(baseDir, hashClass, cachedContentFile = nil, options = {})
674
+ def initialize(baseDirectory, hashClass, cachedContentFile = nil)
663
675
  super(cachedContentFile)
664
- @baseDir = normalisedDir(baseDir)
665
- @baseDirLen = @baseDir.length
676
+ @baseDirectory = baseDirectory
666
677
  @hashClass = hashClass
667
- @excludeGlobs = options.fetch(:excludes, [])
668
- end
669
-
670
- # get the path of a file name relative to the base directory
671
- def getRelativePath(fileName)
672
- if fileName.start_with? @baseDir
673
- return fileName[@baseDirLen..-1]
674
- else
675
- raise "File name #{fileName} does not start with #{baseDir}"
676
- end
677
678
  end
678
679
 
679
680
  # get the path as required for an SCP command
@@ -683,18 +684,7 @@ module Synqa
683
684
 
684
685
  # get the full path of a relative path (i.e. of a file/directory within the base directory)
685
686
  def getFullPath(relativePath)
686
- return @baseDir + relativePath
687
- end
688
-
689
- # is the relative path name excluded by one of the specified exclusion globs?
690
- def fileIsExcluded?(relativeFile)
691
- for excludeGlob in @excludeGlobs
692
- if File.fnmatch(excludeGlob, relativeFile)
693
- puts " file #{relativeFile} excluded by glob #{excludeGlob}"
694
- return true
695
- end
696
- end
697
- return false
687
+ return @baseDirectory.fullPath + relativePath
698
688
  end
699
689
 
700
690
  # get the content tree for this base directory by iterating over all
@@ -709,25 +699,17 @@ module Synqa
709
699
  cachedMapOfHashes = cachedTimeAndMapOfHashes[1]
710
700
  contentTree = ContentTree.new()
711
701
  contentTree.time = Time.now.utc
712
- #puts "LocalContentLocation.getContentTree for baseDir #{baseDir} ..."
713
- for fileOrDir in Dir.glob(baseDir + "**/*", File::FNM_DOTMATCH)
714
- if not (fileOrDir.end_with?("/.") or fileOrDir.end_with?("/.."))
715
- relativePath = getRelativePath(fileOrDir)
716
- #puts " #{relativePath}"
717
- if File.directory? fileOrDir
718
- contentTree.addDir(relativePath)
719
- else
720
- if not fileIsExcluded?(relativePath)
721
- cachedDigest = cachedMapOfHashes[relativePath]
722
- if cachedTime and cachedDigest and File.stat(fileOrDir).mtime < cachedTime
723
- digest = cachedDigest
724
- else
725
- digest = hashClass.file(fileOrDir).hexdigest
726
- end
727
- contentTree.addFile(relativePath, digest)
728
- end
729
- end
702
+ for subDir in @baseDirectory.subDirs
703
+ contentTree.addDir(subDir.relativePath)
704
+ end
705
+ for file in @baseDirectory.allFiles
706
+ cachedDigest = cachedMapOfHashes[file.relativePath]
707
+ if cachedTime and cachedDigest and File.stat(file.fullPath).mtime < cachedTime
708
+ digest = cachedDigest
709
+ else
710
+ digest = hashClass.file(file.fullPath).hexdigest
730
711
  end
712
+ contentTree.addFile(file.relativePath, digest)
731
713
  end
732
714
  contentTree.sort!
733
715
  if cachedContentFile != nil
@@ -892,7 +874,7 @@ module Synqa
892
874
  # Recursively perform all marked copy operations from the source content tree to the
893
875
  # destination content tree, or if dryRun, just pretend to perform them.
894
876
  def doCopyOperations(sourceContent, destinationContent, dryRun)
895
- for dir in sourceContent.dirs do
877
+ for dir in sourceContent.dirs
896
878
  if dir.copyDestination != nil
897
879
  sourcePath = sourceLocation.getScpPath(dir.fullPath)
898
880
  destinationPath = destinationLocation.getScpPath(dir.copyDestination.fullPath)
@@ -901,7 +883,7 @@ module Synqa
901
883
  doCopyOperations(dir, destinationContent.getDir(dir.name), dryRun)
902
884
  end
903
885
  end
904
- for file in sourceContent.files do
886
+ for file in sourceContent.files
905
887
  if file.copyDestination != nil
906
888
  sourcePath = sourceLocation.getScpPath(file.fullPath)
907
889
  destinationPath = destinationLocation.getScpPath(file.copyDestination.fullPath)
@@ -913,7 +895,7 @@ module Synqa
913
895
  # Recursively perform all marked delete operations on the destination content tree,
914
896
  # or if dryRun, just pretend to perform them.
915
897
  def doDeleteOperations(destinationContent, dryRun)
916
- for dir in destinationContent.dirs do
898
+ for dir in destinationContent.dirs
917
899
  if dir.toBeDeleted
918
900
  dirPath = destinationLocation.getFullPath(dir.fullPath)
919
901
  destinationLocation.ssh("rm -r #{dirPath}", dryRun)
@@ -921,7 +903,7 @@ module Synqa
921
903
  doDeleteOperations(dir, dryRun)
922
904
  end
923
905
  end
924
- for file in destinationContent.files do
906
+ for file in destinationContent.files
925
907
  if file.toBeDeleted
926
908
  filePath = destinationLocation.getFullPath(file.fullPath)
927
909
  destinationLocation.ssh("rm #{filePath}", dryRun)
@@ -0,0 +1 @@
1
+ This is file 6.
@@ -0,0 +1 @@
1
+ File 5, with different extension.
@@ -0,0 +1 @@
1
+ This is a third file, inside a sub-directory.
@@ -0,0 +1 @@
1
+ Another file 1
@@ -0,0 +1 @@
1
+ This is a file 1.
@@ -0,0 +1 @@
1
+ This is a second file.
@@ -0,0 +1,114 @@
1
+ require 'helper'
2
+
3
+ require 'based-directory'
4
+
5
+ module Based
6
+
7
+ class BaseDirectoryTestCase < Test::Unit::TestCase
8
+ include Based
9
+ end
10
+
11
+ class TestBaseDirectory < BaseDirectoryTestCase
12
+ context "A base directory" do
13
+ setup do
14
+ @baseDirPath = ::File.expand_path(::File.join(::File.dirname(__FILE__), "data", "dir1"))
15
+ #puts "@baseDirPath = #{@baseDirPath}"
16
+ @baseDir = BaseDirectory.new(@baseDirPath)
17
+ end
18
+
19
+ should "not add / if already in base bath" do
20
+ @baseDir2 = BaseDirectory.new(@baseDirPath + "/")
21
+ assert_equal "#{@baseDirPath}/", @baseDir.fullPath
22
+ dir2 = @baseDir.dirs[0]
23
+ assert_equal "dir2", dir2.name
24
+ end
25
+
26
+ should "find files in top-level directory and get their names and relative paths" do
27
+ names = @baseDir.files.map {|file| file.name}
28
+ assert_equal ["file1.txt", "file2.txt"], names
29
+ relativePaths = @baseDir.files.map {|file| file.relativePath}
30
+ assert_equal ["file1.txt", "file2.txt"], relativePaths
31
+ end
32
+
33
+ should "check attributes of basedir" do
34
+ assert_equal nil, @baseDir.name
35
+ assert_equal nil, @baseDir.parent
36
+ assert_equal @baseDir, @baseDir.base
37
+ assert_equal "", @baseDir.relativePath
38
+ assert_equal [], @baseDir.pathElements
39
+ assert_equal "#{@baseDirPath}/", @baseDir.fullPath
40
+ end
41
+
42
+ should "find one directory and check all its attributes" do
43
+ dir2 = @baseDir.dirs[0]
44
+ dir4 = dir2.dirs[0]
45
+ assert_equal "dir4", dir4.name
46
+ assert_equal dir2, dir4.parent
47
+ assert_equal @baseDir, dir4.base
48
+ assert_equal "dir2/dir4/", dir4.relativePath
49
+ assert_equal ["dir2", "dir4"], dir4.pathElements
50
+ assert_equal "#{@baseDirPath}/dir2/dir4/", dir4.fullPath
51
+ end
52
+
53
+ should "find one file and check all its attributes" do
54
+ dir2 = @baseDir.dirs[0]
55
+ dir4 = dir2.dirs[0]
56
+ file5 = dir4.files[0]
57
+ assert_equal "file5.text", file5.name
58
+ assert_equal dir4, file5.parent
59
+ assert_equal @baseDir, file5.base
60
+ assert_equal "dir2/dir4/file5.text", file5.relativePath
61
+ assert_equal ["dir2", "dir4", "file5.text"], file5.pathElements
62
+ assert_equal "#{@baseDirPath}/dir2/dir4/file5.text", file5.fullPath
63
+ end
64
+
65
+ should "find sub-directories in top-level directory and get their names and relative paths" do
66
+ names = @baseDir.dirs.map {|dir| dir.name}
67
+ assert_equal ["dir2", "dir3"], names
68
+ relativePaths = @baseDir.dirs.map {|dir| dir.relativePath}
69
+ assert_equal ["dir2/", "dir3/"], relativePaths
70
+ end
71
+
72
+ should "find all sub-directories of base directory" do
73
+ relativePaths = @baseDir.subDirs.map{|dir| dir.relativePath}
74
+ assert_equal ["dir2/", "dir2/dir4/", "dir2/dir4/dir5/", "dir3/"], relativePaths
75
+ end
76
+
77
+ should "find all files within base directory" do
78
+ relativePaths = @baseDir.allFiles.map{|dir| dir.relativePath}
79
+ assert_equal ["file1.txt", "file2.txt", "dir2/file3.txt", "dir2/dir4/file5.text",
80
+ "dir2/dir4/dir5/file6.text", "dir3/file1.txt"], relativePaths
81
+ end
82
+
83
+ should "exclude dir2" do
84
+ filteredBaseDir = BaseDirectory.new(@baseDirPath,
85
+ :dirExclude => lambda{|dir| dir.name == "dir2"})
86
+ relativePaths = filteredBaseDir.allFiles.map{|file| file.relativePath}
87
+ assert_equal ["file1.txt", "file2.txt", "dir3/file1.txt"], relativePaths
88
+ end
89
+
90
+ should "include only .txt files" do
91
+ filteredBaseDir = BaseDirectory.new(@baseDirPath,
92
+ :fileInclude => lambda{|file| file.name.end_with? ".txt"})
93
+ relativePaths = filteredBaseDir.allFiles.map{|file| file.relativePath}
94
+ assert_equal ["file1.txt", "file2.txt", "dir2/file3.txt",
95
+ "dir3/file1.txt"], relativePaths
96
+ end
97
+
98
+ should "not include .txt files" do
99
+ filteredBaseDir = BaseDirectory.new(@baseDirPath,
100
+ :fileExclude => lambda{|file| file.name.end_with? ".txt"})
101
+ relativePaths = filteredBaseDir.allFiles.map{|file| file.relativePath}
102
+ assert_equal ["dir2/dir4/file5.text", "dir2/dir4/dir5/file6.text"], relativePaths
103
+ end
104
+
105
+ should "include only .txt files not in dir3" do
106
+ filteredBaseDir = BaseDirectory.new(@baseDirPath,
107
+ :dirExclude => lambda{|dir| dir.name == "dir3"},
108
+ :fileInclude => lambda{|file| file.name.end_with? ".txt"})
109
+ relativePaths = filteredBaseDir.allFiles.map{|file| file.relativePath}
110
+ assert_equal ["file1.txt", "file2.txt", "dir2/file3.txt"], relativePaths
111
+ end
112
+ end
113
+ end
114
+ end
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.0.3
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,12 +9,12 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-03-02 00:00:00.000000000 +13:00
12
+ date: 2011-03-19 00:00:00.000000000 +13:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: shoulda
17
- requirement: &24960612 !ruby/object:Gem::Requirement
17
+ requirement: &24879420 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ! '>='
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: '0'
23
23
  type: :development
24
24
  prerelease: false
25
- version_requirements: *24960612
25
+ version_requirements: *24879420
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: bundler
28
- requirement: &24959928 !ruby/object:Gem::Requirement
28
+ requirement: &24878820 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ~>
@@ -33,10 +33,10 @@ dependencies:
33
33
  version: 1.0.0
34
34
  type: :development
35
35
  prerelease: false
36
- version_requirements: *24959928
36
+ version_requirements: *24878820
37
37
  - !ruby/object:Gem::Dependency
38
38
  name: jeweler
39
- requirement: &24942648 !ruby/object:Gem::Requirement
39
+ requirement: &24878220 !ruby/object:Gem::Requirement
40
40
  none: false
41
41
  requirements:
42
42
  - - ~>
@@ -44,10 +44,10 @@ dependencies:
44
44
  version: 1.5.2
45
45
  type: :development
46
46
  prerelease: false
47
- version_requirements: *24942648
47
+ version_requirements: *24878220
48
48
  - !ruby/object:Gem::Dependency
49
49
  name: rcov
50
- requirement: &24941832 !ruby/object:Gem::Requirement
50
+ requirement: &24877560 !ruby/object:Gem::Requirement
51
51
  none: false
52
52
  requirements:
53
53
  - - ! '>='
@@ -55,7 +55,7 @@ dependencies:
55
55
  version: '0'
56
56
  type: :development
57
57
  prerelease: false
58
- version_requirements: *24941832
58
+ version_requirements: *24877560
59
59
  description: Sync files from a local directory to a remote directory via SSH/SCP
60
60
  email: http://www.1729.com/email.html
61
61
  executables: []
@@ -74,8 +74,16 @@ files:
74
74
  - _project.el
75
75
  - examples/sample-rakefile
76
76
  - examples/synqa-useage.rb
77
+ - lib/based-directory.rb
77
78
  - lib/synqa.rb
79
+ - test/data/dir1/dir2/dir4/dir5/file6.text
80
+ - test/data/dir1/dir2/dir4/file5.text
81
+ - test/data/dir1/dir2/file3.txt
82
+ - test/data/dir1/dir3/file1.txt
83
+ - test/data/dir1/file1.txt
84
+ - test/data/dir1/file2.txt
78
85
  - test/helper.rb
86
+ - test/test_based_directory.rb
79
87
  - test/test_synqa.rb
80
88
  has_rdoc: true
81
89
  homepage: http://www.1729.com/software/synqa/
@@ -93,7 +101,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
93
101
  version: '0'
94
102
  segments:
95
103
  - 0
96
- hash: 346342291
104
+ hash: 537622927
97
105
  required_rubygems_version: !ruby/object:Gem::Requirement
98
106
  none: false
99
107
  requirements:
@@ -109,4 +117,5 @@ summary: Sync files from a local directory to a remote directory via SSH/SCP
109
117
  test_files:
110
118
  - examples/synqa-useage.rb
111
119
  - test/helper.rb
120
+ - test/test_based_directory.rb
112
121
  - test/test_synqa.rb