locomotivecms_wagon 2.0.0.pre.alpha.3 → 2.0.0.pre.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -6
  3. data/bin/wagon +1 -1
  4. data/generators/cloned/config/deploy.yml.tt +3 -2
  5. data/generators/content_type/app/content_types/%slug%.yml.tt +7 -0
  6. data/lib/locomotive/wagon/cli.rb +66 -73
  7. data/lib/locomotive/wagon/commands/clone_command.rb +35 -0
  8. data/lib/locomotive/wagon/commands/destroy_command.rb +29 -0
  9. data/lib/locomotive/wagon/commands/loggers/base_logger.rb +31 -0
  10. data/lib/locomotive/wagon/commands/loggers/pull_logger.rb +23 -0
  11. data/lib/locomotive/wagon/commands/loggers/push_logger.rb +23 -17
  12. data/lib/locomotive/wagon/commands/loggers/sync_logger.rb +23 -0
  13. data/lib/locomotive/wagon/commands/pull_command.rb +55 -0
  14. data/lib/locomotive/wagon/commands/pull_sub_commands/concerns/assets_concern.rb +75 -0
  15. data/lib/locomotive/wagon/commands/pull_sub_commands/pull_base_command.rb +83 -0
  16. data/lib/locomotive/wagon/commands/pull_sub_commands/pull_content_assets_command.rb +24 -0
  17. data/lib/locomotive/wagon/commands/pull_sub_commands/pull_content_entries_command.rb +94 -0
  18. data/lib/locomotive/wagon/commands/pull_sub_commands/pull_content_types_command.rb +42 -0
  19. data/lib/locomotive/wagon/commands/pull_sub_commands/pull_pages_command.rb +54 -0
  20. data/lib/locomotive/wagon/commands/pull_sub_commands/pull_site_command.rb +55 -0
  21. data/lib/locomotive/wagon/commands/pull_sub_commands/pull_snippets_command.rb +29 -0
  22. data/lib/locomotive/wagon/commands/pull_sub_commands/pull_theme_assets_command.rb +29 -0
  23. data/lib/locomotive/wagon/commands/pull_sub_commands/pull_translations_command.rb +24 -0
  24. data/lib/locomotive/wagon/commands/push_command.rb +1 -1
  25. data/lib/locomotive/wagon/commands/push_sub_commands/push_site_command.rb +28 -0
  26. data/lib/locomotive/wagon/commands/serve_command.rb +1 -1
  27. data/lib/locomotive/wagon/commands/sync_command.rb +57 -0
  28. data/lib/locomotive/wagon/commands/sync_sub_commands/concerns/base_concern.rb +41 -0
  29. data/lib/locomotive/wagon/commands/sync_sub_commands/sync_content_entries_command.rb +9 -0
  30. data/lib/locomotive/wagon/commands/sync_sub_commands/sync_pages_command.rb +41 -0
  31. data/lib/locomotive/wagon/commands/sync_sub_commands/sync_translations_command.rb +9 -0
  32. data/lib/locomotive/wagon/decorators/concerns/to_hash_concern.rb +1 -1
  33. data/lib/locomotive/wagon/decorators/content_type_decorator.rb +7 -3
  34. data/lib/locomotive/wagon/decorators/content_type_field_decorator.rb +6 -1
  35. data/lib/locomotive/wagon/decorators/site_decorator.rb +8 -0
  36. data/lib/locomotive/wagon/generators/site/base.rb +1 -1
  37. data/lib/locomotive/wagon/generators/site/cloned.rb +1 -1
  38. data/lib/locomotive/wagon/generators/site.rb +0 -2
  39. data/lib/locomotive/wagon/tools/styled_yaml.rb +122 -0
  40. data/lib/locomotive/wagon/version.rb +1 -1
  41. data/lib/locomotive/wagon.rb +22 -57
  42. data/locomotivecms_wagon.gemspec +2 -2
  43. data/spec/fixtures/cassettes/authenticate.yml +49 -122
  44. data/spec/fixtures/cassettes/push.yml +8960 -9147
  45. data/spec/fixtures/default/icon.png +0 -0
  46. data/spec/integration/commands/push_command_spec.rb +1 -1
  47. metadata +31 -13
  48. data/generators/blank/config.ru +0 -3
  49. data/generators/bootstrap3/config.ru +0 -3
  50. data/generators/cloned/config.ru +0 -3
  51. data/generators/foundation5/config.ru +0 -3
  52. data/generators/line_case/config.ru +0 -3
  53. data/lib/locomotive/wagon/tools/deployment_connection.rb +0 -120
  54. data/lib/locomotive/wagon/tools/hosting_api.rb +0 -117
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a50873f213bdcfed4f2805e3234779843063a592
4
- data.tar.gz: 858be1870e92f8babccc46f1d1e0c9ec45f6cf7f
3
+ metadata.gz: af0162fe63e4c9884c03e7a7265ffb72e30bbb16
4
+ data.tar.gz: 1199659382fb6103c4432ab7127fd897581f2275
5
5
  SHA512:
6
- metadata.gz: ccf20a282732acfb247467c130fe9001b065ef06e60f7d2507f44e3f13a506b8b476d29861167ffc7618fc567f1a04d247a92a828870ca4df14f36ff789e8878
7
- data.tar.gz: c7264b43a72794eb57de873f4eb52e62235dd03a83b65a522f774b893105232d5174c7b5be95a2f66cadc33483bcd94f89f51e5804228dacce7d578119b280fe
6
+ metadata.gz: f76b0ebb45502c6d25dcc88706361c0c0603c845fcd22ebe963e4543efcf5da3e3e68caeedf774503e05d22b149f358d1ee410a83eb5cd0c1459d45676f309a0
7
+ data.tar.gz: e43fa9d4065eb13632e2d1f6fe03f7dd05989f02599af2c7f5985762faeb343b14639835c8d48b874d360a216492acf978ce827e4e8e33cdefa506b92871642f
data/Gemfile CHANGED
@@ -3,20 +3,16 @@ source 'https://rubygems.org'
3
3
  # Specify your gem's dependencies in wagon.gemspec
4
4
  gemspec
5
5
 
6
- # Development
7
- # gem 'locomotivecms-liquid', path: '../gems/liquid', require: false
8
- # gem 'locomotivecms-solid', path: '../gems/solid', require: false
9
- # gem 'locomotivecms_mounter', path: '../gems/mounter', require: false
10
- # gem 'locomotivecms_mounter', github: 'locomotivecms/mounter', ref: '6025c4a', require: false
11
-
12
6
  gem 'rb-fsevent', '~> 0.9.1'
13
7
 
14
8
  gem 'therubyracer'
15
9
 
10
+ # Development
16
11
  # gem 'locomotivecms_steam', github: 'locomotivecms/steam', ref: 'b2de77e', require: false
17
12
  # gem 'locomotivecms_coal', github: 'locomotivecms/coal', ref: '32b2844', require: false
18
13
  # gem 'locomotivecms_common', github: 'locomotivecms/common', ref: '3046b79893', require: false
19
14
 
15
+ # Local development
20
16
  # gem 'locomotivecms_coal', path: '../in_progress/coal', require: false
21
17
  # gem 'locomotivecms_steam', path: '../in_progress/steam', require: false
22
18
  # gem 'locomotivecms_common', path: '../in_progress/common', require: false
data/bin/wagon CHANGED
@@ -9,4 +9,4 @@ $stdout.sync = true
9
9
  require 'locomotive/wagon'
10
10
  require 'locomotive/wagon/cli'
11
11
 
12
- Locomotive::Wagon::CLI::Main.start
12
+ Locomotive::Wagon::CLI::Main.start
@@ -1,8 +1,9 @@
1
1
  production:
2
2
  host: <%= config[:host] %>
3
- <% if config[:email] -%>
3
+ handle: <%= config[:handle] %>
4
4
  email: <%= config[:email] %>
5
+ <% if config[:password] -%>
5
6
  password: <%= config[:password] %>
6
7
  <% elsif config[:api_key] -%>
7
8
  api_key: <%= config[:api_key] -%>
8
- <% end -%>
9
+ <% end -%>
@@ -25,6 +25,13 @@ order_by: manually
25
25
  # Array of emails to be notified of new entries made with the public API
26
26
  # public_submission_accounts: ['john@example.com']
27
27
 
28
+ # Control the display of the content type in the back-office.
29
+ # display_settings:
30
+ # seo: false # display the SEO tab for the content entries
31
+ # advanced: false # display the Advanced tab for the content entries
32
+ # position: 1 # position in the sidebar menu
33
+ # hidden: false # hidden for authors?
34
+
28
35
  # A list describing each field
29
36
  fields: <% config[:fields].each_with_index do |field, index| %>
30
37
  - <%= field.name -%>: # The lowercase, underscored name of the field
@@ -9,21 +9,23 @@ module Locomotive
9
9
 
10
10
  protected
11
11
 
12
- # Check if the path given in option ('.' by default) points to a LocomotiveCMS
12
+ # Check if the path given in option ('.' by default) points to a Locomotive
13
13
  # site. It is also possible to pass a path other than the one from the options.
14
14
  #
15
15
  # @param [ String ] path The optional path of the site instead of options['path']
16
16
  #
17
- # @return [ String ] The fullpath to the LocomotiveCMS site or nil if it is not a valid site.
17
+ # @return [ String ] The fullpath to the Locomotive site or nil if it is not a valid site.
18
18
  #
19
19
  def check_path!(path = nil)
20
20
  path ||= options['path']
21
21
 
22
22
  path = path == '.' ? Dir.pwd : File.expand_path(path)
23
23
 
24
- (File.exists?(File.join(path, 'config', 'site.yml')) ? path : nil).tap do |_path|
24
+ site_or_deploy_file = File.exists?(File.join(path, 'config', 'site.yml')) || File.exists?(File.join(path, 'config', 'deploy.yml'))
25
+
26
+ (site_or_deploy_file ? path : nil).tap do |_path|
25
27
  if _path.nil?
26
- say 'The path does not point to a LocomotiveCMS site', :red
28
+ say 'The path does not point to a Locomotive site', :red
27
29
  end
28
30
  end
29
31
  end
@@ -35,7 +37,7 @@ module Locomotive
35
37
  def force_color_if_asked(options)
36
38
  if options[:force_color]
37
39
  # thor
38
- require 'locomotive/wagon/misc/thor'
40
+ require 'locomotive/wagon/tools/thor'
39
41
  self.shell = Thor::Shell::ForceColor.new
40
42
 
41
43
  # bypass colorize code
@@ -50,7 +52,7 @@ module Locomotive
50
52
  include Locomotive::Wagon::CLI::ForceColor
51
53
  include Locomotive::Wagon::CLI::CheckPath
52
54
 
53
- class_option :path, aliases: '-p', type: :string, default: '.', optional: true, desc: 'if your LocomotiveCMS site is not in the current path'
55
+ class_option :path, aliases: '-p', type: :string, default: '.', optional: true, desc: 'if your Locomotive site is not in the current path'
54
56
 
55
57
  desc 'content_type SLUG FIELDS', 'Creates a content type with the specified slug and fields.'
56
58
  method_option :name, aliases: '-n', type: :string, default: nil, optional: true, desc: 'Name of the content type as it will be displayed in the back-office'
@@ -151,10 +153,10 @@ module Locomotive
151
153
 
152
154
  protected
153
155
 
154
- # Read the YAML config file of a LocomotiveCMS site.
156
+ # Read the YAML config file of a Locomotive site.
155
157
  # The path should be returned by the check_path! method first.
156
158
  #
157
- # @param [ String ] path The full path to a LocomotiveCMS site.
159
+ # @param [ String ] path The full path to a Locomotive site.
158
160
  #
159
161
  # @return [ Hash ] The site
160
162
  #
@@ -171,7 +173,7 @@ module Locomotive
171
173
 
172
174
  class_option :force_color, type: :boolean, default: false, desc: 'Whether or not to use ANSI color in the output.'
173
175
 
174
- desc 'version', 'Version of the LocomotiveCMS Wagon'
176
+ desc 'version', 'Version of the Locomotive Wagon'
175
177
  def version
176
178
  require 'locomotive/wagon/version'
177
179
  say Locomotive::Wagon::VERSION
@@ -214,15 +216,16 @@ module Locomotive
214
216
  end
215
217
  end
216
218
 
217
- desc 'clone NAME HOST [PATH]', 'Clone a remote LocomotiveCMS site'
218
- method_option :verbose, aliases: '-v', type: 'boolean', default: false, desc: 'display the full error stack trace if an error occurs'
219
- method_option :email, aliases: '-e', desc: 'email of an administrator account'
220
- method_option :password, aliases: '-p', desc: 'password of an administrator account'
221
- method_option :api_key, aliases: '-a', desc: 'api key of an administrator account'
222
- def clone(name, host, path = '.')
219
+ desc 'backup NAME HOST [PATH]', 'Backup a remote Locomotive site'
220
+ option :verbose, aliases: '-v', type: 'boolean', default: false, desc: 'display the full error stack trace if an error occurs'
221
+ option :handle, aliases: '-h', desc: 'handle of your site'
222
+ option :email, aliases: '-e', desc: 'email of an administrator account'
223
+ option :password, aliases: '-p', desc: 'password of an administrator account (use api_key instead)'
224
+ option :api_key, aliases: '-a', desc: 'api key of an administrator account'
225
+ def backup(name, host, path = '.')
223
226
  begin
224
- if Locomotive::Wagon.clone(name, path, { host: host }.merge(options))
225
- self.print_next_instructions_when_site_created(name, path)
227
+ if Locomotive::Wagon.clone(name, path, { host: host }.merge(options), shell)
228
+ self.print_next_instructions_when_site_created(name, path, true)
226
229
  end
227
230
  rescue Exception => e
228
231
  self.print_exception(e, options[:verbose])
@@ -230,7 +233,7 @@ module Locomotive
230
233
  end
231
234
  end
232
235
 
233
- desc 'generate RESOURCE ARGUMENTS', 'Generates a content_type, page, or snippet'
236
+ desc 'generate RESOURCE ARGUMENTS [PATH]', 'Generates a content_type, page, or snippet'
234
237
  long_desc <<-LONGDESC
235
238
  Generates a content_type, page, or snippet
236
239
 
@@ -241,8 +244,8 @@ module Locomotive
241
244
  subcommand 'generate', Generate
242
245
 
243
246
  desc 'list_templates', 'List all the templates to create either a site or a content type'
244
- method_option :lib, aliases: '-l', type: 'string', desc: 'Path to an external ruby lib or generator'
245
- method_option :json, aliases: '-j', type: :boolean, default: false, desc: 'Output the list in JSON'
247
+ option :lib, aliases: '-l', type: 'string', desc: 'Path to an external ruby lib or generator'
248
+ option :json, aliases: '-j', type: :boolean, default: false, desc: 'Output the list in JSON'
246
249
  def list_templates
247
250
  force_color_if_asked(options)
248
251
  require 'locomotive/wagon/generators/site'
@@ -260,12 +263,12 @@ module Locomotive
260
263
  end
261
264
 
262
265
  desc 'serve [PATH]', 'Serve a site from the file system'
263
- method_option :host, aliases: '-h', type: 'string', default: '0.0.0.0', desc: 'The host (address) of the Thin server'
264
- method_option :port, aliases: '-p', type: 'string', default: '3333', desc: 'The port of the Thin server'
265
- method_option :daemonize, aliases: '-d', type: 'boolean', default: false, desc: 'Run daemonized Thin server in the background'
266
- method_option :live_reload_port, aliases: '-l', type: 'string', default: false, desc: 'Include the Livereload javascript in each page'
267
- method_option :force, aliases: '-f', type: 'boolean', default: false, desc: 'Stop the current daemonized Thin server if found before starting a new one'
268
- method_option :verbose, aliases: '-v', type: 'boolean', default: false, desc: 'display the full error stack trace if an error occurs'
266
+ option :host, aliases: '-h', type: 'string', default: '0.0.0.0', desc: 'The host (address) of the Thin server'
267
+ option :port, aliases: '-p', type: 'string', default: '3333', desc: 'The port of the Thin server'
268
+ option :daemonize, aliases: '-d', type: 'boolean', default: false, desc: 'Run daemonized Thin server in the background'
269
+ option :live_reload_port, aliases: '-l', type: 'string', default: false, desc: 'Include the Livereload javascript in each page'
270
+ option :force, aliases: '-f', type: 'boolean', default: false, desc: 'Stop the current daemonized Thin server if found before starting a new one'
271
+ option :verbose, aliases: '-v', type: 'boolean', default: false, desc: 'display the full error stack trace if an error occurs'
269
272
  def serve(path = '.')
270
273
  parent_pid = Process.pid
271
274
  force_color_if_asked(options)
@@ -297,12 +300,12 @@ module Locomotive
297
300
  end
298
301
  end
299
302
 
300
- desc 'push ENV [PATH]', 'Push a site to a remote LocomotiveCMS Engine'
301
- method_option :resources, aliases: '-r', type: 'array', default: nil, desc: 'Only push the resource(s) passed in argument'
302
- method_option :data, aliases: '-d', type: 'boolean', default: false, desc: 'Push the content entries and the editable elements (by default, they are not)'
303
- method_option :shell, type: 'boolean', default: true, desc: 'Use shell to ask for missing connection information like the site handle (in this case, take a random one)'
304
- method_option :verbose, aliases: '-v', type: 'boolean', default: false, desc: 'display the full error stack trace if an error occurs'
305
- def push(env, path = '.')
303
+ desc 'deploy ENV [PATH]', 'Deploy a site to a remote Locomotive Engine'
304
+ option :resources, aliases: '-r', type: 'array', default: nil, desc: 'Only push the resource(s) passed in argument'
305
+ option :data, aliases: '-d', type: 'boolean', default: false, desc: 'Push the content entries and the editable elements (by default, they are not)'
306
+ option :shell, type: 'boolean', default: true, desc: 'Use shell to ask for missing connection information like the site handle (in this case, take a random one)'
307
+ option :verbose, aliases: '-v', type: 'boolean', default: false, desc: 'display the full error stack trace if an error occurs'
308
+ def deploy(env, path = '.')
306
309
  force_color_if_asked(options)
307
310
 
308
311
  if check_path!(path)
@@ -315,36 +318,49 @@ module Locomotive
315
318
  end
316
319
  end
317
320
 
318
- desc 'pull ENV [PATH]', 'Pull a site from a remote LocomotiveCMS Engine'
319
- method_option :resources, aliases: '-r', type: 'array', default: nil, desc: 'Only pull the resource(s) passed in argument'
320
- method_option :verbose, aliases: '-v', type: 'boolean', default: false, desc: 'display the full error stack trace if an error occurs'
321
+ desc 'sync ENV [PATH]', 'Synchronize the local content with the one from a remote Locomotive site.'
322
+ option :resources, aliases: '-r', type: 'array', default: nil, desc: 'Only pull the resource(s) passed (pages, content_entries, translations) in argument'
323
+ option :verbose, aliases: '-v', type: 'boolean', default: false, desc: 'display the full error stack trace if an error occurs'
324
+ def sync(env, path = '.')
325
+ if check_path!(path)
326
+ begin
327
+ Locomotive::Wagon.sync(env, path, options)
328
+ rescue Exception => e
329
+ self.print_exception(e, options[:verbose])
330
+ exit(1)
331
+ end
332
+ end
333
+ end
334
+
335
+ desc 'pull ENV [PATH]', '[DEPRECATED, use sync instead] Pull a site from a remote Locomotive Engine.'
336
+ option :resources, aliases: '-r', type: 'array', default: nil, desc: 'Only pull the resource(s) passed in argument'
337
+ option :verbose, aliases: '-v', type: 'boolean', default: false, desc: 'display the full error stack trace if an error occurs'
321
338
  def pull(env, path = '.')
322
339
  if check_path!(path)
323
- if connection_info = self.retrieve_connection_info(env, path)
324
- begin
325
- Locomotive::Wagon.pull(path, connection_info, options)
326
- rescue Exception => e
327
- self.print_exception(e, options[:verbose])
328
- exit(1)
329
- end
340
+ begin
341
+ Locomotive::Wagon.pull(env, path, options, options[:shell] ? shell : nil)
342
+ rescue Exception => e
343
+ self.print_exception(e, options[:verbose])
344
+ exit(1)
330
345
  end
331
346
  end
332
347
  end
333
348
 
334
- desc 'destroy ENV [PATH]', 'Destroy a remote LocomotiveCMS Engine'
349
+ desc 'destroy ENV [PATH]', 'Destroy a remote Locomotive site'
335
350
  def destroy(env, path = '.')
336
351
  if check_path!(path)
337
- if connection_info = self.retrieve_connection_info(env, path)
338
- if ask('Are you sure ?', limited_to: %w(yes no)) == 'yes'
339
- Locomotive::Wagon.destroy(path, connection_info)
340
- else
341
- say 'The destroy operation has been cancelled', :red
342
- exit(1)
343
- end
352
+ if ask('Are you sure?', limited_to: %w(yes no)) == 'yes'
353
+ Locomotive::Wagon.destroy(env, path)
354
+ else
355
+ say 'The destroy operation has been cancelled', :red
356
+ exit(1)
344
357
  end
345
358
  end
346
359
  end
347
360
 
361
+ # aliases
362
+ map push: :deploy, clone: :backup
363
+
348
364
  protected
349
365
 
350
366
  # Print a nice message when a site has been created.
@@ -376,29 +392,6 @@ module Locomotive
376
392
  end
377
393
  end
378
394
 
379
- # # From a site specified by a path, retrieve the information of the connection
380
- # # for a environment located in the config/deploy.yml file of the site.
381
- # #
382
- # # @param [ String ] env The environment (development, staging, production, ...etc)
383
- # # @param [ String ] path The path of the local site
384
- # # @param [ Boolean ] use_shell True by default, use it to ask for missing information (subdomain for instance)
385
- # #
386
- # # @return [ Hash ] The information of the connection or nil if errors
387
- # #
388
- # def retrieve_connection_info(env, path, use_shell = true)
389
- # require 'locomotive/wagon/misc/deployment_connection'
390
-
391
- # begin
392
- # service = Locomotive::Wagon::DeploymentConnection.new(path, use_shell ? shell : nil)
393
-
394
- # service.get_information(env)
395
-
396
- # rescue Exception => e
397
- # self.print_exception(e, options[:verbose])
398
- # nil
399
- # end
400
- # end
401
-
402
395
  end
403
396
 
404
397
  end
@@ -0,0 +1,35 @@
1
+ module Locomotive::Wagon
2
+
3
+ class CloneCommand < Struct.new(:name, :path, :options, :shell)
4
+
5
+ def self.clone(name, path, options, shell)
6
+ new(name, path, options, shell).clone
7
+ end
8
+
9
+ def clone
10
+ # create an empty site with the minimal settings
11
+ create_site
12
+
13
+ # pull the pages, content_types, basically any resources from the remote site
14
+ pull_site
15
+ end
16
+
17
+ def connection_info
18
+ options.symbolize_keys.slice(:host, :handle, :email, :api_key, :password)
19
+ end
20
+
21
+ private
22
+
23
+ def create_site
24
+ require 'locomotive/wagon/generators/site'
25
+ generator = Locomotive::Wagon::Generators::Site::Cloned
26
+ generator.start [name, path, 'true', connection_info]
27
+ end
28
+
29
+ def pull_site
30
+ Locomotive::Wagon.pull('production', File.join(path, name), options.symbolize_keys, shell)
31
+ end
32
+
33
+ end
34
+
35
+ end
@@ -0,0 +1,29 @@
1
+ require_relative 'concerns/api_concern'
2
+ require_relative 'concerns/deploy_file_concern'
3
+
4
+ module Locomotive::Wagon
5
+
6
+ class DestroyCommand < Struct.new(:env, :path, :options)
7
+
8
+ include ApiConcern
9
+ include DeployFileConcern
10
+
11
+ def self.destroy(env, path, options)
12
+ self.new(env, path, options).destroy
13
+ end
14
+
15
+ def destroy
16
+ api_client = api_site_client(connection_information)
17
+
18
+ api_client.current_site.destroy
19
+ end
20
+
21
+ private
22
+
23
+ def connection_information
24
+ read_deploy_settings(self.env, self.path)
25
+ end
26
+
27
+ end
28
+
29
+ end
@@ -0,0 +1,31 @@
1
+ module Locomotive::Wagon
2
+
3
+ class BaseLogger
4
+
5
+ private
6
+
7
+ def log(message, color = nil, ident = nil, print = false)
8
+ ident = ' ' * (ident || 0)
9
+
10
+ message = "#{ident}#{message.gsub("\n", "\n" + ident)}"
11
+ message = message.colorize(color) if color
12
+
13
+ if print
14
+ print message
15
+ else
16
+ puts message
17
+ end
18
+ end
19
+
20
+ def _subscribe(type, action = nil, &block)
21
+ name = ['wagon', type, [*action]].flatten.compact.join('.')
22
+
23
+ ActiveSupport::Notifications.subscribe(name) do |*args|
24
+ event = ActiveSupport::Notifications::Event.new *args
25
+ yield(event)
26
+ end
27
+ end
28
+
29
+ end
30
+
31
+ end
@@ -0,0 +1,23 @@
1
+ require_relative 'base_logger'
2
+
3
+ module Locomotive::Wagon
4
+
5
+ class PullLogger < BaseLogger
6
+
7
+ def initialize
8
+ subscribe :start do |event|
9
+ log "\n"
10
+ log "Pulling #{event.payload[:name].camelcase}", { color: :black, background: :white }
11
+ end
12
+
13
+ end
14
+
15
+ private
16
+
17
+ def subscribe(action = nil, &block)
18
+ _subscribe('pull', action, &block)
19
+ end
20
+
21
+ end
22
+
23
+ end
@@ -1,6 +1,8 @@
1
+ require_relative 'base_logger'
2
+
1
3
  module Locomotive::Wagon
2
4
 
3
- class PushLogger
5
+ class PushLogger < BaseLogger
4
6
 
5
7
  def initialize
6
8
  subscribe 'site_created' do |event|
@@ -32,28 +34,32 @@ module Locomotive::Wagon
32
34
 
33
35
  private
34
36
 
35
- def log(message, color = nil, ident = nil, print = false)
36
- ident = ' ' * (ident || 0)
37
+ # def log(message, color = nil, ident = nil, print = false)
38
+ # ident = ' ' * (ident || 0)
37
39
 
38
- message = "#{ident}#{message.gsub("\n", "\n" + ident)}"
39
- message = message.colorize(color) if color
40
+ # message = "#{ident}#{message.gsub("\n", "\n" + ident)}"
41
+ # message = message.colorize(color) if color
40
42
 
41
- if print
42
- print message
43
- else
44
- puts message
45
- end
46
- end
43
+ # if print
44
+ # print message
45
+ # else
46
+ # puts message
47
+ # end
48
+ # end
47
49
 
48
50
  def subscribe(action = nil, &block)
49
- name = ['wagon', 'push', [*action]].flatten.compact.join('.')
50
-
51
- ActiveSupport::Notifications.subscribe(name) do |*args|
52
- event = ActiveSupport::Notifications::Event.new *args
53
- yield(event)
54
- end
51
+ _subscribe('push', action, &block)
55
52
  end
56
53
 
54
+ # def subscribe(action = nil, &block)
55
+ # name = ['wagon', 'push', [*action]].flatten.compact.join('.')
56
+
57
+ # ActiveSupport::Notifications.subscribe(name) do |*args|
58
+ # event = ActiveSupport::Notifications::Event.new *args
59
+ # yield(event)
60
+ # end
61
+ # end
62
+
57
63
  end
58
64
 
59
65
  end
@@ -0,0 +1,23 @@
1
+ require_relative 'base_logger'
2
+
3
+ module Locomotive::Wagon
4
+
5
+ class SyncLogger < BaseLogger
6
+
7
+ def initialize
8
+ subscribe :start do |event|
9
+ log "\n"
10
+ log "Syncing #{event.payload[:name].camelcase}", { color: :black, background: :white }
11
+ end
12
+
13
+ end
14
+
15
+ private
16
+
17
+ def subscribe(action = nil, &block)
18
+ _subscribe('sync', action, &block)
19
+ end
20
+
21
+ end
22
+
23
+ end
@@ -0,0 +1,55 @@
1
+ require 'locomotive/common'
2
+
3
+ require_relative '../tools/styled_yaml'
4
+
5
+ require_relative 'loggers/pull_logger'
6
+
7
+ require_relative_all 'concerns'
8
+
9
+ require_relative 'pull_sub_commands/pull_base_command'
10
+ require_relative_all 'pull_sub_commands'
11
+
12
+ module Locomotive::Wagon
13
+
14
+ class PullCommand < Struct.new(:env, :path, :options, :shell)
15
+
16
+ RESOURCES = %w(site pages content_types content_entries snippets theme_assets translations content_assets).freeze
17
+
18
+ include ApiConcern
19
+ include DeployFileConcern
20
+ include InstrumentationConcern
21
+
22
+ def self.pull(env, path, options, shell)
23
+ self.new(env, path, options, shell).pull
24
+ end
25
+
26
+ def pull
27
+ PullLogger.new if options[:verbose]
28
+
29
+ api_client = api_site_client(connection_information)
30
+ site = api_client.current_site.get
31
+
32
+ each_resource do |klass|
33
+ klass.pull(api_client, site, path)
34
+ end
35
+ end
36
+
37
+ private
38
+
39
+ def each_resource
40
+ RESOURCES.each do |name|
41
+ next if !options[:resources].blank? && !options[:resources].include?(name)
42
+
43
+ klass = "Locomotive::Wagon::Pull#{name.camelcase}Command".constantize
44
+
45
+ yield klass
46
+ end
47
+ end
48
+
49
+ def connection_information
50
+ read_deploy_settings(self.env, self.path)
51
+ end
52
+
53
+ end
54
+
55
+ end
@@ -0,0 +1,75 @@
1
+ require 'tempfile'
2
+
3
+ module Locomotive::Wagon
4
+
5
+ module AssetsConcern
6
+
7
+ # The content assets on the remote engine follows the format: /sites/<id>/assets/<type>/<file>
8
+ # This method replaces these urls by their local representation. <type>/<file>
9
+ #
10
+ # @param [ String ] content The text where the assets will be replaced.
11
+ #
12
+ def replace_asset_urls(content)
13
+ return '' if content.blank?
14
+
15
+ content.force_encoding('utf-8').gsub(/\/sites\/[0-9a-f]{24}\/(assets|pages|theme|content_entry[0-9a-f]{24})\/(([^;.]+)\/)*([a-zA-Z_\-0-9]+)\.([a-z]{2,3})/) do |url|
16
+ filename = "#{$4}.#{$5}"
17
+ folder = case $1
18
+ when 'assets', 'pages' then File.join('samples', $1)
19
+ when 'theme' then $3
20
+ when /\Acontent_entry/ then File.join('samples', 'content_entries')
21
+ end
22
+
23
+ if filepath = write_asset(url, File.join(path, 'public', folder, filename))
24
+ File.join('', folder, File.basename(filepath))
25
+ else
26
+ ''
27
+ end
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def find_unique_filepath(filepath, binary_file, index = 1)
34
+ if File.exists?(filepath)
35
+ # required because we need to make sure we use the content of file from its start
36
+ binary_file.rewind
37
+
38
+ return filepath if FileUtils.compare_stream(binary_file, File.open(filepath))
39
+
40
+ folder, ext = File.dirname(filepath), File.extname(filepath)
41
+ basename = File.basename(filepath, ext)
42
+
43
+ find_unique_filepath(File.join(folder, "#{basename}-#{index}#{ext}"), binary, index + 1)
44
+ else
45
+ filepath
46
+ end
47
+ end
48
+
49
+ def get_asset_binary(url)
50
+ unless url =~ /\Ahttp:\/\//
51
+ base = api_client.uri.dup.tap { |u| u.path = '' }.to_s
52
+ url = URI.join(base, url).to_s
53
+ end
54
+
55
+ binary = Faraday.get(url).body rescue nil
56
+ end
57
+
58
+ def write_asset(url, filepath)
59
+ if binary = get_asset_binary(url)
60
+ FileUtils.mkdir_p(File.dirname(filepath))
61
+
62
+ (binary_file = Tempfile.new(File.basename(filepath))).write(binary)
63
+
64
+ find_unique_filepath(filepath, binary_file).tap do |filepath|
65
+ File.open(filepath, 'wb') { |f| f.write(binary) }
66
+ end
67
+ else
68
+ instrument :missing_asset, url: url
69
+ nil
70
+ end
71
+ end
72
+
73
+ end
74
+
75
+ end