multi_sync 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- 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