multi_sync 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.
Files changed (150) hide show
  1. checksums.yaml +7 -0
  2. data/.document +3 -0
  3. data/.gitignore +20 -0
  4. data/.rubocop.yml +26 -0
  5. data/.travis.yml +24 -0
  6. data/.yardopts +6 -0
  7. data/CHANGELOG.md +0 -0
  8. data/CONTRIBUTING.md +44 -0
  9. data/Gemfile +17 -0
  10. data/LICENSE.md +20 -0
  11. data/README.md +134 -0
  12. data/Rakefile +45 -0
  13. data/examples/custom.rb +34 -0
  14. data/examples/rails-3-2/.gitignore +15 -0
  15. data/examples/rails-3-2/Gemfile +43 -0
  16. data/examples/rails-3-2/README.rdoc +261 -0
  17. data/examples/rails-3-2/Rakefile +7 -0
  18. data/examples/rails-3-2/app/assets/images/rails.png +0 -0
  19. data/examples/rails-3-2/app/assets/javascripts/application.js +15 -0
  20. data/examples/rails-3-2/app/assets/stylesheets/application.css +13 -0
  21. data/examples/rails-3-2/app/controllers/application_controller.rb +3 -0
  22. data/examples/rails-3-2/app/helpers/application_helper.rb +2 -0
  23. data/examples/rails-3-2/app/mailers/.gitkeep +0 -0
  24. data/examples/rails-3-2/app/models/.gitkeep +0 -0
  25. data/examples/rails-3-2/app/views/layouts/application.html.erb +14 -0
  26. data/examples/rails-3-2/config.ru +4 -0
  27. data/examples/rails-3-2/config/application.rb +62 -0
  28. data/examples/rails-3-2/config/asset_sync.yml +21 -0
  29. data/examples/rails-3-2/config/boot.rb +6 -0
  30. data/examples/rails-3-2/config/database.yml +25 -0
  31. data/examples/rails-3-2/config/environment.rb +5 -0
  32. data/examples/rails-3-2/config/environments/development.rb +37 -0
  33. data/examples/rails-3-2/config/environments/production.rb +67 -0
  34. data/examples/rails-3-2/config/environments/test.rb +37 -0
  35. data/examples/rails-3-2/config/initializers/backtrace_silencers.rb +7 -0
  36. data/examples/rails-3-2/config/initializers/inflections.rb +15 -0
  37. data/examples/rails-3-2/config/initializers/mime_types.rb +5 -0
  38. data/examples/rails-3-2/config/initializers/multi_sync.rb +29 -0
  39. data/examples/rails-3-2/config/initializers/secret_token.rb +7 -0
  40. data/examples/rails-3-2/config/initializers/session_store.rb +8 -0
  41. data/examples/rails-3-2/config/initializers/wrap_parameters.rb +14 -0
  42. data/examples/rails-3-2/config/locales/en.yml +5 -0
  43. data/examples/rails-3-2/config/routes.rb +58 -0
  44. data/examples/rails-3-2/db/seeds.rb +7 -0
  45. data/examples/rails-3-2/lib/assets/.gitkeep +0 -0
  46. data/examples/rails-3-2/lib/tasks/.gitkeep +0 -0
  47. data/examples/rails-3-2/log/.gitkeep +0 -0
  48. data/examples/rails-3-2/public/404.html +26 -0
  49. data/examples/rails-3-2/public/422.html +26 -0
  50. data/examples/rails-3-2/public/500.html +25 -0
  51. data/examples/rails-3-2/public/favicon.ico +0 -0
  52. data/examples/rails-3-2/public/index.html +241 -0
  53. data/examples/rails-3-2/public/robots.txt +5 -0
  54. data/examples/rails-3-2/script/rails +6 -0
  55. data/examples/rails-3-2/test/fixtures/.gitkeep +0 -0
  56. data/examples/rails-3-2/test/functional/.gitkeep +0 -0
  57. data/examples/rails-3-2/test/integration/.gitkeep +0 -0
  58. data/examples/rails-3-2/test/performance/browsing_test.rb +12 -0
  59. data/examples/rails-3-2/test/test_helper.rb +13 -0
  60. data/examples/rails-3-2/test/unit/.gitkeep +0 -0
  61. data/examples/rails-4-0/.gitignore +16 -0
  62. data/examples/rails-4-0/Gemfile +50 -0
  63. data/examples/rails-4-0/README.rdoc +28 -0
  64. data/examples/rails-4-0/Rakefile +6 -0
  65. data/examples/rails-4-0/app/assets/images/.keep +0 -0
  66. data/examples/rails-4-0/app/assets/javascripts/application.js +16 -0
  67. data/examples/rails-4-0/app/assets/stylesheets/application.css +13 -0
  68. data/examples/rails-4-0/app/controllers/application_controller.rb +5 -0
  69. data/examples/rails-4-0/app/controllers/concerns/.keep +0 -0
  70. data/examples/rails-4-0/app/helpers/application_helper.rb +2 -0
  71. data/examples/rails-4-0/app/mailers/.keep +0 -0
  72. data/examples/rails-4-0/app/models/.keep +0 -0
  73. data/examples/rails-4-0/app/models/concerns/.keep +0 -0
  74. data/examples/rails-4-0/app/views/layouts/application.html.erb +14 -0
  75. data/examples/rails-4-0/config.ru +4 -0
  76. data/examples/rails-4-0/config/application.rb +24 -0
  77. data/examples/rails-4-0/config/asset_sync.yml +21 -0
  78. data/examples/rails-4-0/config/boot.rb +4 -0
  79. data/examples/rails-4-0/config/database.yml +25 -0
  80. data/examples/rails-4-0/config/environment.rb +5 -0
  81. data/examples/rails-4-0/config/environments/development.rb +29 -0
  82. data/examples/rails-4-0/config/environments/production.rb +80 -0
  83. data/examples/rails-4-0/config/environments/test.rb +36 -0
  84. data/examples/rails-4-0/config/initializers/backtrace_silencers.rb +7 -0
  85. data/examples/rails-4-0/config/initializers/filter_parameter_logging.rb +4 -0
  86. data/examples/rails-4-0/config/initializers/inflections.rb +16 -0
  87. data/examples/rails-4-0/config/initializers/mime_types.rb +5 -0
  88. data/examples/rails-4-0/config/initializers/multi_sync.rb +29 -0
  89. data/examples/rails-4-0/config/initializers/secret_token.rb +12 -0
  90. data/examples/rails-4-0/config/initializers/session_store.rb +3 -0
  91. data/examples/rails-4-0/config/initializers/wrap_parameters.rb +14 -0
  92. data/examples/rails-4-0/config/locales/en.yml +23 -0
  93. data/examples/rails-4-0/config/routes.rb +56 -0
  94. data/examples/rails-4-0/db/seeds.rb +7 -0
  95. data/examples/rails-4-0/lib/assets/.keep +0 -0
  96. data/examples/rails-4-0/lib/tasks/.keep +0 -0
  97. data/examples/rails-4-0/log/.keep +0 -0
  98. data/examples/rails-4-0/public/404.html +58 -0
  99. data/examples/rails-4-0/public/422.html +58 -0
  100. data/examples/rails-4-0/public/500.html +57 -0
  101. data/examples/rails-4-0/public/favicon.ico +0 -0
  102. data/examples/rails-4-0/public/robots.txt +5 -0
  103. data/examples/rails-4-0/test/controllers/.keep +0 -0
  104. data/examples/rails-4-0/test/fixtures/.keep +0 -0
  105. data/examples/rails-4-0/test/helpers/.keep +0 -0
  106. data/examples/rails-4-0/test/integration/.keep +0 -0
  107. data/examples/rails-4-0/test/mailers/.keep +0 -0
  108. data/examples/rails-4-0/test/models/.keep +0 -0
  109. data/examples/rails-4-0/test/test_helper.rb +15 -0
  110. data/gemfiles/middleman-3.1.x.gemfile +5 -0
  111. data/gemfiles/rails-3.2.x.gemfile +5 -0
  112. data/gemfiles/rails-4.0.x.gemfile +5 -0
  113. data/lib/multi_sync.rb +92 -0
  114. data/lib/multi_sync/client.rb +243 -0
  115. data/lib/multi_sync/configuration.rb +36 -0
  116. data/lib/multi_sync/environment.rb +37 -0
  117. data/lib/multi_sync/extensions/middleman.rb +22 -0
  118. data/lib/multi_sync/extensions/rails.rb +20 -0
  119. data/lib/multi_sync/extensions/rails/asset_sync.rb +44 -0
  120. data/lib/multi_sync/extensions/rails/railtie.rb +11 -0
  121. data/lib/multi_sync/logging.rb +60 -0
  122. data/lib/multi_sync/mixins/log_helper.rb +9 -0
  123. data/lib/multi_sync/mixins/pluralize_helper.rb +15 -0
  124. data/lib/multi_sync/resource.rb +84 -0
  125. data/lib/multi_sync/resources/local_resource.rb +30 -0
  126. data/lib/multi_sync/resources/remote_resource.rb +32 -0
  127. data/lib/multi_sync/source.rb +40 -0
  128. data/lib/multi_sync/sources/local_source.rb +17 -0
  129. data/lib/multi_sync/sources/manifest_source.rb +82 -0
  130. data/lib/multi_sync/target.rb +34 -0
  131. data/lib/multi_sync/targets/aws_target.rb +80 -0
  132. data/lib/multi_sync/targets/local_target.rb +58 -0
  133. data/lib/multi_sync/version.rb +3 -0
  134. data/lib/tasks/multi_sync_rails.rake +15 -0
  135. data/multi_sync.gemspec +35 -0
  136. data/spec/spec_helper.rb +22 -0
  137. data/spec/support/celluloid.rb +14 -0
  138. data/spec/support/fakefs.rb +7 -0
  139. data/spec/support/fog.rb +25 -0
  140. data/spec/support/pry.rb +6 -0
  141. data/spec/support/timecop.rb +2 -0
  142. data/spec/unit/multi_sync/client_spec.rb +301 -0
  143. data/spec/unit/multi_sync/configuration_spec.rb +92 -0
  144. data/spec/unit/multi_sync/resources/local_resource_spec.rb +55 -0
  145. data/spec/unit/multi_sync/sources/local_source_spec.rb +48 -0
  146. data/spec/unit/multi_sync/sources/manifest_source_spec.rb +57 -0
  147. data/spec/unit/multi_sync/targets/aws_target_spec.rb +60 -0
  148. data/spec/unit/multi_sync/targets/local_target_spec.rb +41 -0
  149. data/spec/unit/multi_sync_spec.rb +55 -0
  150. metadata +377 -0
data/lib/multi_sync.rb ADDED
@@ -0,0 +1,92 @@
1
+ require 'forwardable'
2
+ require 'multi_sync/client'
3
+ require 'multi_sync/version'
4
+ require 'multi_sync/logging'
5
+ require 'multi_sync/environment'
6
+ require 'multi_sync/configuration'
7
+
8
+ module MultiSync
9
+ extend SingleForwardable
10
+ extend MultiSync::Logging
11
+ extend MultiSync::Environment
12
+
13
+ # a list of libraries, extension file and class name
14
+ REQUIREMENT_MAP = [
15
+ ['rails', 'multi_sync/extensions/rails'].freeze,
16
+ ['middleman-core', 'multi_sync/extensions/middleman'].freeze
17
+ ]
18
+
19
+ # delegate all MultiSync::Configuration's attribute accessors to the configuration
20
+ def_delegators :configuration, *MultiSync::Configuration.attribute_set.map(&:name)
21
+
22
+ # delegate all MultiSync::Configuration's attribute setters to the configuration ( hacky I know... )
23
+ def_delegators :configuration, *(MultiSync::Configuration.attribute_set.map(&:name).map { |key| "#{key}=".to_sym })
24
+
25
+ # delegate all MultiSync::Client's attribute accessors to the configuration
26
+ def_delegators :client, *MultiSync::Client.attribute_set.map(&:name)
27
+
28
+ # include some public methods
29
+ def_delegators :client, :target, :source, :synchronize
30
+
31
+ # Configure
32
+ #
33
+ # @return [MultiSync]
34
+ def self.configure(&block)
35
+ instance_eval(&block) if block_given?
36
+ self
37
+ end
38
+
39
+ # Run
40
+ #
41
+ # @return [MultiSync]
42
+ def self.run(&block)
43
+ configure(&block).synchronize
44
+ end
45
+
46
+ # Prepare
47
+ #
48
+ # @return [MultiSync]
49
+ def self.prepare(&block)
50
+ configure(&block)
51
+ end
52
+
53
+ # Fetch the MultiSync::Client
54
+ #
55
+ # @return [MultiSync::Client]
56
+ def self.client(options = {})
57
+ @client ||= MultiSync::Client.new(options)
58
+ end
59
+
60
+ # Fetch the MultiSync::Configuration
61
+ #
62
+ # @return [MultiSync::Configuration]
63
+ def self.configuration(options = {})
64
+ @configuration ||= MultiSync::Configuration.new(options)
65
+ end
66
+
67
+ # Reset the MultiSync::Client
68
+ def self.reset_client!
69
+ remove_instance_variable :@client if defined?(@client)
70
+ end
71
+
72
+ # Reset the MultiSync::Configuration
73
+ def self.reset_configuration!
74
+ remove_instance_variable :@configuration if defined?(@configuration)
75
+ end
76
+
77
+ # Reset MultiSync::Configuration and MultiSync::Client
78
+ def self.reset!
79
+ self.reset_client!
80
+ self.reset_configuration!
81
+ end
82
+
83
+ # by rescuing from a LoadError we can sniff out gems in use and try to automagically hook into them
84
+ REQUIREMENT_MAP.each do |library, extension|
85
+ begin
86
+ require library
87
+ require extension
88
+ rescue ::LoadError
89
+ next
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,243 @@
1
+ require 'set'
2
+ require 'virtus'
3
+ require 'lazily'
4
+ require 'celluloid'
5
+ require 'multi_sync/sources/local_source'
6
+ require 'multi_sync/sources/manifest_source'
7
+ require 'multi_sync/targets/aws_target'
8
+ require 'multi_sync/targets/local_target'
9
+ require 'multi_sync/mixins/pluralize_helper'
10
+
11
+ module MultiSync
12
+ class Client
13
+ include Virtus
14
+ include MultiSync::Mixins::PluralizeHelper
15
+
16
+ attribute :supervisor
17
+ attribute :incomplete_jobs, Set, default: Set.new
18
+ attribute :running_jobs, Set, default: Set.new
19
+ attribute :complete_jobs, Set, default: Set.new
20
+ attribute :sources, Array, default: []
21
+ attribute :sync_attempts, Integer, default: 0
22
+ attribute :file_sync_attempts, Integer, default: 0
23
+ attribute :started_at, Time
24
+ attribute :finished_at, Time
25
+
26
+ # Initialize a new Client object
27
+ #
28
+ # @param options [Hash]
29
+ def initialize(options = {})
30
+ self.supervisor = Celluloid::SupervisionGroup.run!
31
+ end
32
+
33
+ def add_target(name, options = {})
34
+ fail ArgumentError, "Duplicate target names detected, please rename '#{name}' to be unique" if supervisor_actor_names.include?(name)
35
+ clazz = MultiSync.const_get("#{options[:type].capitalize}Target")
36
+ supervisor.pool(clazz, as: name, args: [options], size: MultiSync.target_pool_size)
37
+ rescue NameError
38
+ MultiSync.warn "Unknown target type: #{options[:type]}"
39
+ raise ArgumentError, "Unknown target type: #{options[:type]}"
40
+ end
41
+ alias_method :target, :add_target
42
+
43
+ def add_source(name, options = {})
44
+ clazz = MultiSync.const_get("#{options[:type].capitalize}Source")
45
+ sources << clazz.new(options)
46
+ rescue NameError
47
+ MultiSync.warn "Unknown source type: #{options[:type]}"
48
+ raise ArgumentError, "Unknown source type: #{options[:type]}"
49
+ end
50
+ alias_method :source, :add_source
51
+
52
+ def synchronize
53
+ if sync_pointless?
54
+ MultiSync.debug "Preventing synchronization as there are #{sources.length} sources to sync..."
55
+ return
56
+ else
57
+ MultiSync.debug 'Starting synchronization...'
58
+ end
59
+
60
+ determine_sync if first_run?
61
+ sync_attempted
62
+
63
+ MultiSync.debug 'Scheduling jobs in the future...'
64
+ incomplete_jobs.delete_if do | job |
65
+ running_jobs << { id: job[:id], future: Celluloid::Actor[job[:target_id]].future.send(job[:method], job[:args]), method: job[:method] }
66
+ end
67
+
68
+ MultiSync.debug 'Fetching jobs from the future...'
69
+ running_jobs.delete_if do | job |
70
+ begin
71
+ completed_job = { id: job[:id], response: job[:future].value, method: job[:method] }
72
+ rescue
73
+ self.file_sync_attempts = file_sync_attempts + 1
74
+ false
75
+ else
76
+ complete_jobs << completed_job
77
+ true
78
+ end
79
+ end
80
+
81
+ finish_sync
82
+ finalize
83
+ end
84
+ alias_method :sync, :synchronize
85
+
86
+ def finalize
87
+ # if finished_at
88
+ # elapsed = finished_at.to_f - started_at.to_f
89
+ # minutes, seconds = elapsed.divmod 60.0
90
+ # kilobytes = get_total_file_size_from_complete_jobs / 1024.0
91
+ # MultiSync.debug "Sync completed in #{pluralize(minutes.round, 'minute')} and #{pluralize(seconds.round, 'second')}"
92
+ # MultiSync.debug "#{pluralize(complete_jobs.length, 'file')} were synchronised (#{pluralize(get_complete_deleted_jobs.length, 'deleted file')} and #{pluralize(get_complete_upload_jobs.length, 'uploaded file')}) from #{pluralize(sources.length, 'source')} to #{pluralize(supervisor.actors.length, 'target')}"
93
+ # MultiSync.debug "The upload weight totalled %.#{0}f #{pluralize(kilobytes, 'KB', 'KB', false)}" % kilobytes
94
+ # MultiSync.debug "#{pluralize(file_sync_attempts, 'failed request')} were detected and re-tried"
95
+ # else
96
+ # MultiSync.debug "Sync failed to complete with #{pluralize(incomplete_jobs.length, 'outstanding file')} to be synchronised"
97
+ # MultiSync.debug "#{pluralize(complete_jobs.length, 'file')} were synchronised (#{pluralize(get_complete_deleted_jobs.length, 'deleted file')} and #{pluralize(get_complete_upload_jobs.length, 'uploaded file')}) from #{pluralize(sources.length, 'source')} to #{pluralize(supervisor.actors.length, 'target')}"
98
+ # end
99
+
100
+ supervisor.finalize
101
+ end
102
+ alias_method :fin, :finalize
103
+
104
+ def get_complete_deleted_jobs
105
+ complete_jobs.select { |job| job[:method] == :delete }
106
+ end
107
+
108
+ def get_complete_upload_jobs
109
+ complete_jobs.select { |job| job[:method] == :upload }
110
+ end
111
+
112
+ def get_total_file_size_from_complete_jobs
113
+ total_file_size = 0
114
+ get_complete_upload_jobs.each do | job |
115
+ # MultiSync.info job[:response]
116
+ # MultiSync.info job[:response].determine_content_length
117
+ if job[:response].content_length
118
+ total_file_size += job[:response].content_length
119
+ end
120
+
121
+ end
122
+ total_file_size
123
+ end
124
+
125
+ private
126
+
127
+ def determine_sync
128
+ sources.lazily.each do |source|
129
+
130
+ source_files = []
131
+
132
+ starting_synchronizing_msg = "ynchronizing: '#{source.source_dir}'"
133
+ starting_synchronizing_msg.prepend MultiSync.force ? 'Forcefully s' : 'S'
134
+ MultiSync.info starting_synchronizing_msg
135
+
136
+ source_files = source.files
137
+ source_files.sort! # sort to make sure the source's indexes match the targets
138
+
139
+ # when no targets are specified, assume all targets
140
+ source.targets = supervisor_actor_names if source.targets.empty?
141
+
142
+ source.targets.lazily.each do | target_id |
143
+
144
+ missing_files = []
145
+ abandoned_files = []
146
+ outdated_files = []
147
+
148
+ MultiSync.debug "#{pluralize(source_files.length, 'file')} found from the source"
149
+
150
+ MultiSync.debug 'Fetching files from the target...'
151
+
152
+ target_files = Celluloid::Actor[target_id].files
153
+ target_files.sort! # sort to make sure the target's indexs match the sources
154
+
155
+ MultiSync.debug "#{pluralize(target_files.length, 'file')} found from the target"
156
+
157
+ missing_files.concat determine_missing_files(source_files, target_files)
158
+ missing_files_msg = "#{missing_files.length} of the files are missing"
159
+ missing_files_msg += ", however we're skipping them as :upload_missing_files is false" unless MultiSync.upload_missing_files
160
+ MultiSync.debug missing_files_msg
161
+
162
+ abandoned_files.concat determine_abandoned_files(source_files, target_files)
163
+ abandoned_files_msg = "#{abandoned_files.length} of the files are abandoned"
164
+ abandoned_files_msg += ", however we're skipping them as :delete_abandoned_files is false" unless MultiSync.delete_abandoned_files
165
+ MultiSync.debug abandoned_files_msg
166
+
167
+ # remove missing_files from source_files ( as we know they are missing so don't need to check them )
168
+ # remove abandoned_files from target_files ( as we know they are abandoned so don't need to check them )
169
+ outdated_files.concat determine_outdated_files(source_files - missing_files, target_files - abandoned_files)
170
+ MultiSync.debug "#{outdated_files.length} of the files are outdated"
171
+
172
+ # abandoned files
173
+ if MultiSync.delete_abandoned_files
174
+ abandoned_files.lazily.each do | file |
175
+ incomplete_jobs << { id: Celluloid.uuid, target_id: target_id, method: :delete, args: file }
176
+ end
177
+ end
178
+
179
+ # missing files
180
+ if MultiSync.upload_missing_files
181
+ missing_files.lazily.each do | file |
182
+ incomplete_jobs << { id: Celluloid.uuid, target_id: target_id, method: :upload, args: file }
183
+ end
184
+ end
185
+
186
+ # outdated files
187
+ outdated_files.lazily.each do | file |
188
+ incomplete_jobs << { id: Celluloid.uuid, target_id: target_id, method: :upload, args: file }
189
+ end
190
+
191
+ end
192
+
193
+ end
194
+ end
195
+
196
+ def determine_missing_files(source_files, target_files)
197
+ missing_files = (source_files - target_files)
198
+ missing_files
199
+ end
200
+
201
+ def determine_abandoned_files(source_files, target_files)
202
+ abandoned_files = (target_files - source_files)
203
+ abandoned_files
204
+ end
205
+
206
+ def determine_outdated_files(source_files, target_files)
207
+ outdated_files = []
208
+
209
+ # TODO: replace with celluloid pool of futures
210
+ # check each source file against the matching target_file's etag
211
+ source_files.lazily.each_with_index do |file, i|
212
+ outdated_files << file unless !MultiSync.force && file.matching_etag?(target_files[i])
213
+ end
214
+
215
+ outdated_files
216
+ end
217
+
218
+ def sync_attempted
219
+ self.started_at = Time.now if first_run?
220
+ self.sync_attempts = sync_attempts.next
221
+ if sync_attempts > MultiSync.max_sync_attempts
222
+ MultiSync.warn "Sync was attempted more then #{MultiSync.max_sync_attempts} times"
223
+ fail ArgumentError, "Sync was attempted more then #{MultiSync.max_sync_attempts} times"
224
+ end
225
+ end
226
+
227
+ def finish_sync
228
+ incomplete_jobs.length != 0 ? synchronize : self.finished_at = Time.now
229
+ end
230
+
231
+ def first_run?
232
+ sync_attempts == 0
233
+ end
234
+
235
+ def sync_pointless?
236
+ sources.empty?
237
+ end
238
+
239
+ def supervisor_actor_names
240
+ supervisor.actors.map { |actor| actor.registered_name }
241
+ end
242
+ end
243
+ end
@@ -0,0 +1,36 @@
1
+ require 'virtus'
2
+ require 'fog'
3
+ require 'celluloid'
4
+
5
+ module MultiSync
6
+ class Configuration
7
+ include Virtus
8
+
9
+ attribute :verbose, Boolean, default: false
10
+ attribute :force, Boolean, default: false
11
+ attribute :run_on_build, Boolean, default: true
12
+ attribute :delete_abandoned_files, Boolean, default: true
13
+ attribute :upload_missing_files, Boolean, default: true
14
+ attribute :target_pool_size, Integer, default: :celluloid_cores
15
+ attribute :max_sync_attempts, Integer, default: 3
16
+ attribute :credentials, Hash, default: :fog_credentials
17
+
18
+ # Initialize a new Configuration object
19
+ #
20
+ # @param options [Hash]
21
+ def initialize(options = {})
22
+ Celluloid.logger = MultiSync.test? ? nil : MultiSync.logger
23
+ options.each_pair do |key, value|
24
+ send("#{key}=", value) if attributes.keys.include?(key)
25
+ end
26
+ end
27
+
28
+ def celluloid_cores
29
+ Celluloid.cores
30
+ end
31
+
32
+ def fog_credentials
33
+ Fog.credentials
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,37 @@
1
+ module MultiSync
2
+ module Environment
3
+ # Retrieves the current MultiSync environment
4
+ #
5
+ # @return [String] the current environment
6
+ def environment
7
+ @environment ||= ENV['MULTI_SYNC_ENV'] || ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'development'
8
+ end
9
+ alias_method :env, :environment
10
+
11
+ # Sets the current MultiSync environment
12
+ #
13
+ # @param [String|Symbol] env the environment symbol
14
+ def environment=(e)
15
+ @environment = e.to_s
16
+ end
17
+ alias_method :env=, :environment=
18
+
19
+ # Determines if we are in a particular environment
20
+ #
21
+ # @return [Boolean] true if current environment matches, false otherwise
22
+ def environment?(e)
23
+ environment == e.to_s
24
+ end
25
+ alias_method :env?, :environment?
26
+
27
+ # Create methods for the environment shorthands
28
+ [:test, :development, :staging, :production].each do |e|
29
+ # Determines if we are in a particular environment
30
+ #
31
+ # @return [Boolean] true if current environment matches, false otherwise
32
+ define_method "#{e}?" do
33
+ environment? e
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,22 @@
1
+ module MultiSync
2
+ module Extensions
3
+ class Middleman
4
+ MultiSync.info "Middleman -v #{::Middleman::VERSION} auto-detected"
5
+
6
+ class << self
7
+ def source_dir
8
+ File.expand_path(File.join(ENV['MM_ROOT'], 'build'))
9
+ end
10
+
11
+ def destination_dir
12
+ ''
13
+ end
14
+ end
15
+
16
+ MultiSync.source(:middleman,
17
+ type: :local,
18
+ source_dir: MultiSync::Extensions::Middleman.source_dir
19
+ )
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,20 @@
1
+ module MultiSync
2
+ module Extensions
3
+ require 'multi_sync/extensions/rails/railtie' if defined?(::Rails::Railtie)
4
+ require 'multi_sync/extensions/rails/asset_sync'
5
+
6
+ class Rails
7
+ MultiSync.info "Rails -v #{::Rails::VERSION::STRING} auto-detected"
8
+
9
+ class << self
10
+ def source_dir
11
+ ::Rails.root.join('public', destination_dir)
12
+ end
13
+
14
+ def destination_dir
15
+ ::Rails.application.config.assets.prefix.sub(/^\//, '')
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end