multi_sync 0.0.2 → 0.0.3
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 +4 -4
- data/.travis.yml +6 -8
- data/Gemfile +0 -1
- data/README.md +79 -51
- data/Rakefile +0 -22
- data/lib/multi_sync.rb +27 -5
- data/lib/multi_sync/attributes/pathname.rb +1 -1
- data/lib/multi_sync/client.rb +124 -112
- data/lib/multi_sync/configuration.rb +4 -1
- data/lib/multi_sync/extensions/jekyll.rb +24 -0
- data/lib/multi_sync/extensions/middleman.rb +1 -7
- data/lib/multi_sync/extensions/rails.rb +0 -2
- data/lib/multi_sync/{mixins/pluralize_helper.rb → helpers/pluralize.rb} +2 -2
- data/lib/multi_sync/logging.rb +7 -0
- data/lib/multi_sync/resource.rb +0 -2
- data/lib/multi_sync/resources/local_resource.rb +0 -1
- data/lib/multi_sync/source.rb +0 -2
- data/lib/multi_sync/sources/local_source.rb +3 -1
- data/lib/multi_sync/sources/manifest_source.rb +14 -16
- data/lib/multi_sync/target.rb +3 -3
- data/lib/multi_sync/targets/aws_target.rb +6 -10
- data/lib/multi_sync/targets/local_target.rb +7 -15
- data/lib/multi_sync/version.rb +1 -1
- data/lib/tasks/multi_sync_rails.rake +4 -4
- data/multi_sync.gemspec +3 -2
- data/spec/support/fog.rb +0 -1
- data/spec/support/timecop.rb +7 -1
- data/spec/support/tmpdir.rb +18 -0
- data/spec/unit/multi_sync/client_spec.rb +51 -74
- data/spec/unit/multi_sync/configuration_spec.rb +54 -83
- data/spec/unit/multi_sync/resources/local_resource_spec.rb +9 -7
- data/spec/unit/multi_sync/sources/local_source_spec.rb +14 -14
- data/spec/unit/multi_sync/sources/manifest_source_spec.rb +16 -18
- data/spec/unit/multi_sync/targets/aws_target_spec.rb +8 -8
- data/spec/unit/multi_sync/targets/local_target_spec.rb +9 -9
- data/spec/unit/multi_sync_spec.rb +44 -31
- metadata +102 -91
- data/gemfiles/middleman-3.1.x.gemfile +0 -5
- data/gemfiles/rails-3.2.x.gemfile +0 -5
- data/gemfiles/rails-4.0.x.gemfile +0 -5
- data/lib/multi_sync/mixins/log_helper.rb +0 -9
- data/spec/support/fakefs.rb +0 -7
@@ -19,10 +19,13 @@ module MultiSync
|
|
19
19
|
#
|
20
20
|
# @param options [Hash]
|
21
21
|
def initialize(*args)
|
22
|
-
Celluloid.logger = MultiSync.
|
22
|
+
# Celluloid.logger = MultiSync.verbose? ? nil : MultiSync.logger
|
23
|
+
Celluloid.logger = nil
|
23
24
|
super
|
24
25
|
end
|
25
26
|
|
27
|
+
private
|
28
|
+
|
26
29
|
def celluloid_cores
|
27
30
|
Celluloid.cores
|
28
31
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module MultiSync
|
2
|
+
module Extensions
|
3
|
+
class Jekyll
|
4
|
+
MultiSync.debug "Jekyll -v #{::Jekyll::VERSION} auto-detected"
|
5
|
+
class << self
|
6
|
+
def source_dir
|
7
|
+
''
|
8
|
+
end
|
9
|
+
|
10
|
+
def destination_dir
|
11
|
+
''
|
12
|
+
end
|
13
|
+
|
14
|
+
# def jekyll_site
|
15
|
+
# @jekyll_site ||= ::Jekyll::Site.new(jekyll_configuration)
|
16
|
+
# end
|
17
|
+
|
18
|
+
# def jekyll_configuration
|
19
|
+
# @jekyll_configuration ||= ::Jekyll.configuration
|
20
|
+
# end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -2,21 +2,15 @@ module MultiSync
|
|
2
2
|
module Extensions
|
3
3
|
class Middleman
|
4
4
|
MultiSync.debug "Middleman -v #{::Middleman::VERSION} auto-detected"
|
5
|
-
|
6
5
|
class << self
|
7
6
|
def source_dir
|
8
|
-
|
7
|
+
Pathname.new(File.join(ENV['MM_ROOT'], 'build'))
|
9
8
|
end
|
10
9
|
|
11
10
|
def destination_dir
|
12
11
|
''
|
13
12
|
end
|
14
13
|
end
|
15
|
-
|
16
|
-
MultiSync.source(:middleman,
|
17
|
-
type: :local,
|
18
|
-
source_dir: MultiSync::Extensions::Middleman.source_dir
|
19
|
-
)
|
20
14
|
end
|
21
15
|
end
|
22
16
|
end
|
@@ -2,10 +2,8 @@ module MultiSync
|
|
2
2
|
module Extensions
|
3
3
|
require 'multi_sync/extensions/rails/railtie' if defined?(::Rails::Railtie)
|
4
4
|
require 'multi_sync/extensions/rails/asset_sync'
|
5
|
-
|
6
5
|
class Rails
|
7
6
|
MultiSync.debug "Rails -v #{::Rails::VERSION::STRING} auto-detected"
|
8
|
-
|
9
7
|
class << self
|
10
8
|
def source_dir
|
11
9
|
::Rails.root.join('public', destination_dir)
|
data/lib/multi_sync/logging.rb
CHANGED
@@ -5,22 +5,27 @@ module MultiSync
|
|
5
5
|
module Logging
|
6
6
|
MUTEX = Mutex.new
|
7
7
|
|
8
|
+
# Retrieves the current MultiSync logger
|
8
9
|
def logger
|
9
10
|
@logger || initialize_logger
|
10
11
|
end
|
11
12
|
|
13
|
+
# Sets the current MultiSync logger
|
12
14
|
def logger=(new_logger)
|
13
15
|
@logger = new_logger ? new_logger : Logger.new('/dev/null')
|
14
16
|
end
|
15
17
|
|
18
|
+
# Retrieves the current MultiSync status_logger
|
16
19
|
def status_logger
|
17
20
|
@status_logger || initialize_status_logger
|
18
21
|
end
|
19
22
|
|
23
|
+
# Sets the current MultiSync logger
|
20
24
|
def status_logger=(new_status_logger)
|
21
25
|
@status_logger = new_status_logger ? new_status_logger : nil
|
22
26
|
end
|
23
27
|
|
28
|
+
#
|
24
29
|
def say_status(status, message, log_status = true)
|
25
30
|
return if status_logger.nil?
|
26
31
|
|
@@ -31,8 +36,10 @@ module MultiSync
|
|
31
36
|
end
|
32
37
|
end
|
33
38
|
|
39
|
+
#
|
34
40
|
def log(message, level = :debug)
|
35
41
|
# We're not in verbose mode so disable all non-info logs
|
42
|
+
say_status :sync, message
|
36
43
|
return if !MultiSync.verbose && level != :info
|
37
44
|
MUTEX.synchronize do
|
38
45
|
logger.send(level, message)
|
data/lib/multi_sync/resource.rb
CHANGED
@@ -1,13 +1,11 @@
|
|
1
1
|
require 'virtus'
|
2
2
|
require 'pathname'
|
3
3
|
require 'digest/md5'
|
4
|
-
require 'multi_sync/mixins/log_helper'
|
5
4
|
|
6
5
|
module MultiSync
|
7
6
|
class Resource
|
8
7
|
include Comparable
|
9
8
|
include Virtus.model
|
10
|
-
include MultiSync::Mixins::LogHelper
|
11
9
|
|
12
10
|
attribute :path_with_root, Pathname
|
13
11
|
attribute :path_without_root, Pathname
|
data/lib/multi_sync/source.rb
CHANGED
@@ -2,13 +2,11 @@ require 'virtus'
|
|
2
2
|
require 'pathname'
|
3
3
|
require 'lazily'
|
4
4
|
require 'multi_sync/attributes/pathname'
|
5
|
-
require 'multi_sync/mixins/log_helper'
|
6
5
|
require 'multi_sync/resources/local_resource'
|
7
6
|
|
8
7
|
module MultiSync
|
9
8
|
class Source
|
10
9
|
include Virtus.model
|
11
|
-
include MultiSync::Mixins::LogHelper
|
12
10
|
|
13
11
|
attribute :source_dir, MultiSync::Attributes::Pathname
|
14
12
|
|
@@ -5,13 +5,15 @@ module MultiSync
|
|
5
5
|
class LocalSource < Source
|
6
6
|
def files
|
7
7
|
files = []
|
8
|
+
# create a local_resource from each file
|
9
|
+
# making sure to skip any that do not match the include/exclude patterns
|
8
10
|
included_files = Dir.glob(source_dir + include)
|
9
11
|
excluded_files = exclude.nil? ? [] : Dir.glob(source_dir + exclude)
|
10
12
|
(included_files - excluded_files).lazily.each { |path|
|
11
13
|
next if File.directory?(path)
|
12
14
|
files << path_to_local_resource(path)
|
13
15
|
}
|
14
|
-
files
|
16
|
+
files.sort
|
15
17
|
end
|
16
18
|
end
|
17
19
|
end
|
@@ -7,17 +7,6 @@ module MultiSync
|
|
7
7
|
class ManifestSource < Source
|
8
8
|
def files
|
9
9
|
files = []
|
10
|
-
manifest_hash = {}
|
11
|
-
|
12
|
-
# ::ActionView::Base has a shortcut to the manifest file
|
13
|
-
# otherwise lets hunt down that manifest file!
|
14
|
-
if defined?(::ActionView::Base) && ::ActionView::Base.respond_to?(:assets_manifest)
|
15
|
-
manifest_hash = ::ActionView::Base.assets_manifest.files
|
16
|
-
else
|
17
|
-
manifest_path = locate_manifest(source_dir)
|
18
|
-
manifest_hash = parse_manifest(manifest_path)
|
19
|
-
end
|
20
|
-
|
21
10
|
# create a local_resource from each file
|
22
11
|
# making sure to skip any that do not match the include/exclude patterns
|
23
12
|
manifest_hash.lazily.each { |key, value|
|
@@ -26,14 +15,22 @@ module MultiSync
|
|
26
15
|
file = path_to_local_resource(path, mtime: value['mtime'], digest: value['digest'], content_length: value['size'])
|
27
16
|
files << file
|
28
17
|
}
|
29
|
-
|
30
|
-
files
|
18
|
+
files.sort
|
31
19
|
end
|
32
20
|
|
33
21
|
private
|
34
22
|
|
35
|
-
def
|
36
|
-
|
23
|
+
def manifest_hash
|
24
|
+
manifest_hash = {}
|
25
|
+
# ::ActionView::Base has a shortcut to the manifest file
|
26
|
+
# otherwise lets hunt down that manifest file!
|
27
|
+
if defined?(::ActionView::Base) && ::ActionView::Base.respond_to?(:assets_manifest)
|
28
|
+
manifest_hash = ::ActionView::Base.assets_manifest.files
|
29
|
+
else
|
30
|
+
manifest_path = Dir.glob(source_dir + 'manifest*.{json,yaml,yml}').max { |f| File.ctime(f) }
|
31
|
+
manifest_hash = parse_manifest(manifest_path)
|
32
|
+
end
|
33
|
+
manifest_hash
|
37
34
|
end
|
38
35
|
|
39
36
|
def parse_manifest(manifest_path)
|
@@ -46,6 +43,8 @@ module MultiSync
|
|
46
43
|
manifest_hash = MultiJson.load(manifest_data)
|
47
44
|
when '.yml', '.yaml'
|
48
45
|
manifest_hash = YAML.load(manifest_data)
|
46
|
+
else
|
47
|
+
fail ArgumentError, "Unknown manifest type: #{manifest_path}"
|
49
48
|
end
|
50
49
|
|
51
50
|
# different versions of Sprockets have different manifest layouts, lets try and work around this by checking for the presence of "files" and "assets" in the manifest first
|
@@ -71,7 +70,6 @@ module MultiSync
|
|
71
70
|
}
|
72
71
|
}
|
73
72
|
|
74
|
-
#
|
75
73
|
manifest_hash = modified_manifest_hash
|
76
74
|
|
77
75
|
end
|
data/lib/multi_sync/target.rb
CHANGED
@@ -4,18 +4,18 @@ require 'virtus'
|
|
4
4
|
require 'pathname'
|
5
5
|
require 'celluloid'
|
6
6
|
require 'multi_sync/attributes/pathname'
|
7
|
-
require 'multi_sync/mixins/log_helper'
|
8
7
|
|
9
8
|
module MultiSync
|
10
9
|
class Target
|
11
10
|
include Celluloid
|
12
11
|
include Virtus.model
|
13
|
-
|
14
|
-
|
12
|
+
|
15
13
|
attribute :target_dir, MultiSync::Attributes::Pathname, default: Pathname.new('')
|
16
14
|
attribute :destination_dir, MultiSync::Attributes::Pathname, default: Pathname.new('')
|
17
15
|
attribute :credentials, Hash, default: :default_credentials
|
18
16
|
|
17
|
+
private
|
18
|
+
|
19
19
|
def default_credentials
|
20
20
|
Marshal.load(Marshal.dump(MultiSync.credentials))
|
21
21
|
end
|
@@ -3,7 +3,6 @@ require 'multi_sync/resources/remote_resource'
|
|
3
3
|
|
4
4
|
module MultiSync
|
5
5
|
class AwsTarget < Target
|
6
|
-
|
7
6
|
attribute :connection, Fog::Storage, lazy: true, default: lambda { |target, attribute|
|
8
7
|
Fog::Storage.new(target.credentials.merge(provider: :aws))
|
9
8
|
}
|
@@ -15,26 +14,23 @@ module MultiSync
|
|
15
14
|
return files if directory.nil?
|
16
15
|
|
17
16
|
directory.files.lazily.each { |file|
|
18
|
-
|
19
17
|
pathname = Pathname.new(file.key)
|
20
18
|
|
21
19
|
# eg directory or overreaching AWS globbing
|
22
20
|
next unless valid_path?(pathname)
|
23
|
-
|
24
21
|
files << MultiSync::RemoteResource.new(
|
25
22
|
file: file,
|
26
23
|
path_with_root: target_dir + pathname, # pathname seems to already have the prefix (destination_dir)
|
27
24
|
path_without_root: destination_dir != '' ? pathname.relative_path_from(destination_dir).cleanpath : pathname
|
28
25
|
)
|
29
|
-
|
30
26
|
}
|
31
27
|
|
32
|
-
files
|
28
|
+
files.sort
|
33
29
|
end
|
34
30
|
|
35
31
|
def upload(resource)
|
36
|
-
MultiSync.say_status :upload, resource.path_without_root
|
37
|
-
MultiSync.debug "Upload #{resource
|
32
|
+
# MultiSync.say_status :upload, resource.path_without_root
|
33
|
+
MultiSync.debug "Upload #{resource} '#{resource.path_without_root}' to #{self} '/#{target_dir + destination_dir}'"
|
38
34
|
directory = connection.directories.get(target_dir.to_s)
|
39
35
|
return if directory.nil?
|
40
36
|
|
@@ -55,8 +51,8 @@ module MultiSync
|
|
55
51
|
end
|
56
52
|
|
57
53
|
def delete(resource)
|
58
|
-
MultiSync.say_status :delete, resource.path_without_root
|
59
|
-
MultiSync.debug "Delete #{resource
|
54
|
+
# MultiSync.say_status :delete, resource.path_without_root
|
55
|
+
MultiSync.debug "Delete #{resource} '#{resource.path_without_root}' from #{self} '/#{target_dir + destination_dir}'"
|
60
56
|
connection.delete_object(target_dir.to_s, (destination_dir + resource.path_without_root).to_s)
|
61
57
|
resource
|
62
58
|
end
|
@@ -66,7 +62,7 @@ module MultiSync
|
|
66
62
|
# directory or overreaching AWS globbing
|
67
63
|
def valid_path?(pathname)
|
68
64
|
# directory
|
69
|
-
return false if pathname.
|
65
|
+
return false if pathname.directory?
|
70
66
|
|
71
67
|
# overreaching AWS globbing
|
72
68
|
return false if !destination_dir.to_s.empty? && !(pathname.to_s =~ /^#{destination_dir.to_s}\//)
|
@@ -3,7 +3,6 @@ require 'multi_sync/resources/remote_resource'
|
|
3
3
|
|
4
4
|
module MultiSync
|
5
5
|
class LocalTarget < Target
|
6
|
-
|
7
6
|
attribute :connection, Fog::Storage, lazy: true, default: lambda { |target, attribute|
|
8
7
|
Fog::Storage.new(target.credentials.merge(provider: :local))
|
9
8
|
}
|
@@ -15,40 +14,33 @@ module MultiSync
|
|
15
14
|
return files if directory.nil?
|
16
15
|
|
17
16
|
directory.files.lazily.each { |file|
|
18
|
-
|
19
17
|
pathname = Pathname.new(file.key)
|
20
18
|
|
21
19
|
# directory
|
22
20
|
next if pathname.directory?
|
23
|
-
|
24
|
-
MultiSync.debug "Found RemoteResource:'#{pathname}' from #{class_name}:'#{File.join(connection.local_root, destination_dir)}'"
|
25
|
-
|
26
21
|
files << MultiSync::RemoteResource.new(
|
27
22
|
file: file,
|
28
23
|
path_with_root: target_dir + destination_dir + pathname,
|
29
24
|
path_without_root: pathname
|
30
25
|
)
|
31
|
-
|
32
26
|
}
|
33
27
|
|
34
|
-
files
|
28
|
+
files.sort
|
35
29
|
end
|
36
30
|
|
37
31
|
def upload(resource)
|
38
|
-
|
39
|
-
MultiSync.
|
40
|
-
MultiSync.debug "Upload #{resource.class_name}:'#{key}' to #{class_name}:'#{File.join(connection.local_root, destination_dir)}'"
|
32
|
+
# MultiSync.say_status :upload, resource.path_with_root
|
33
|
+
MultiSync.debug "Upload #{resource} '#{resource.path_without_root}' to #{self} '#{File.join(connection.local_root, destination_dir)}'"
|
41
34
|
directory = connection.directories.get(destination_dir.to_s)
|
42
35
|
return if directory.nil?
|
43
|
-
directory.files.create(key:
|
36
|
+
directory.files.create(key: resource.path_without_root.to_s, body: resource.body)
|
44
37
|
resource
|
45
38
|
end
|
46
39
|
|
47
40
|
def delete(resource)
|
48
|
-
|
49
|
-
MultiSync.
|
50
|
-
|
51
|
-
connection.directories.get(destination_dir.to_s).files.get(key).destroy
|
41
|
+
# MultiSync.say_status :delete, resource.path_with_root
|
42
|
+
MultiSync.debug "Delete #{resource} '#{resource.path_without_root}' from #{self} '#{File.join(connection.local_root, destination_dir)}'"
|
43
|
+
connection.directories.get(destination_dir.to_s).files.get(resource.path_without_root.to_s).destroy
|
52
44
|
resource
|
53
45
|
end
|
54
46
|
end
|
data/lib/multi_sync/version.rb
CHANGED
@@ -10,12 +10,12 @@ namespace :assets do
|
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
|
-
Rake::Task['assets:precompile'].enhance do
|
14
|
-
Rake::Task['assets:sync'].invoke if defined?(MultiSync)
|
15
|
-
end
|
16
|
-
|
17
13
|
if Rake::Task.task_defined?('assets:precompile:nondigest')
|
18
14
|
Rake::Task['assets:precompile:nondigest'].enhance do
|
19
15
|
Rake::Task['assets:sync'].invoke if defined?(MultiSync)
|
20
16
|
end
|
17
|
+
else
|
18
|
+
Rake::Task['assets:precompile'].enhance do
|
19
|
+
Rake::Task['assets:sync'].invoke if defined?(MultiSync)
|
20
|
+
end
|
21
21
|
end
|
data/multi_sync.gemspec
CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.version = MultiSync::VERSION
|
9
9
|
spec.authors = ['Karl Freeman']
|
10
10
|
spec.email = ['karlfreeman@gmail.com']
|
11
|
-
spec.summary = %q{
|
12
|
-
spec.description = %q{
|
11
|
+
spec.summary = %q{Flexible synchronisation for your assets}
|
12
|
+
spec.description = %q{Flexible synchronisation for your assets}
|
13
13
|
spec.homepage = 'https://github.com/karlfreeman/multi_sync'
|
14
14
|
spec.license = 'MIT'
|
15
15
|
|
@@ -20,6 +20,7 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.required_ruby_version = '>= 1.9.3'
|
21
21
|
|
22
22
|
spec.add_dependency 'fog', '~> 1.2'
|
23
|
+
spec.add_dependency 'unf'
|
23
24
|
spec.add_dependency 'lazily', '~> 0.1'
|
24
25
|
spec.add_dependency 'virtus', '~> 1.0'
|
25
26
|
spec.add_dependency 'celluloid', '~> 0.15'
|
data/spec/support/fog.rb
CHANGED