clone command (WIP) + pull command (WIP): site + pages

did committed Jul 28, 2015
commit 8c9260827d08e89cf833e050ba5516988e189f4d
Showing 25 changed files with 573 additions and 318 deletions
Gemfile +1 -1
@@ @@ -17,7 +17,7 @@ gem 'therubyracer'
# gem 'locomotivecms_coal', github: 'locomotivecms/coal', ref: '32b2844', require: false
# gem 'locomotivecms_common', github: 'locomotivecms/common', ref: '3046b79893', require: false
- # gem 'locomotivecms_coal', path: '../in_progress/coal', require: false
+ gem 'locomotivecms_coal', path: '../in_progress/coal', require: false
# gem 'locomotivecms_steam', path: '../in_progress/steam', require: false
# gem 'locomotivecms_common', path: '../in_progress/common', require: false
generators/blank/config.ru +0 -3
@@ @@ -1,3 +0,0 @@
- require 'locomotive/wagon/standalone_server'
-
- run Locomotive::Wagon::StandaloneServer.new(File.expand_path('.'))
\ No newline at end of file
generators/bootstrap3/config.ru +0 -3
@@ @@ -1,3 +0,0 @@
- require 'locomotive/wagon/standalone_server'
-
- run Locomotive::Wagon::StandaloneServer.new(File.expand_path('.'))
\ No newline at end of file
generators/cloned/config.ru +0 -3
@@ @@ -1,3 +0,0 @@
- require 'locomotive/wagon/standalone_server'
-
- run Locomotive::Wagon::StandaloneServer.new(File.expand_path('.'))
\ No newline at end of file
generators/cloned/config/deploy.yml.tt +3 -2
@@ @@ -1,8 +1,9 @@
production:
host: <%= config[:host] %>
- <% if config[:email] -%>
+ handle: <%= config[:handle] %>
email: <%= config[:email] %>
+ <% if config[:password] -%>
password: <%= config[:password] %>
<% elsif config[:api_key] -%>
api_key: <%= config[:api_key] -%>
- <% end -%>
\ No newline at end of file
+ <% end -%>
generators/foundation5/config.ru +0 -3
@@ @@ -1,3 +0,0 @@
- require 'locomotive/wagon/standalone_server'
-
- run Locomotive::Wagon::StandaloneServer.new(File.expand_path('.'))
\ No newline at end of file
generators/line_case/config.ru +0 -3
@@ @@ -1,3 +0,0 @@
- require 'locomotive/wagon/standalone_server'
-
- run Locomotive::Wagon::StandaloneServer.new(File.expand_path('.'))
\ No newline at end of file
locomotive/wagon.rb b/lib/locomotive/wagon.rb +3 -31
@@ @@ -80,21 +80,9 @@ module Locomotive
# @param [ Hash ] connection_info The information to get connected to the remote site
# @param [ Hash ] options The options passed to the pull process
#
- def self.pull(path, connection_info, options = {})
- raise 'TODO'
- # self.require_mounter(path, false, options[:disable_misc])
-
- # connection_info[:uri] = "#{connection_info.delete(:host)}/locomotive/api"
-
- # _options = { console: true }.merge(options).symbolize_keys
- # _options[:only] = _options.delete(:resources)
-
- # reader = Locomotive::Mounter::Reader::Api.instance
- # self.validate_resources(_options[:only], reader.readers)
- # reader.run!(_options.merge(connection_info))
-
- # writer = Locomotive::Mounter::Writer::FileSystem.instance
- # writer.run!(_options.merge(mounting_point: reader.mounting_point, target_path: path))
+ def self.pull(env, path, options = {}, shell)
+ require_relative 'wagon/commands/pull_command'
+ Locomotive::Wagon::PullCommand.pull(env, path, options, shell)
end
# Clone a site from a remote LocomotiveCMS engine.
@@ @@ -107,22 +95,6 @@ module Locomotive
def self.clone(name, path, options, shell)
require_relative 'wagon/commands/clone_command'
Locomotive::Wagon::CloneCommand.clone(name, path, options, shell)
-
- # raise 'TODO'
- # target_path = File.expand_path(File.join(path, name))
-
- # if File.exists?(target_path)
- # puts "Path already exists. If it's an existing site, you might want to pull instead of clone."
- # return false
- # end
-
- # # generate an almost blank site
- # require 'locomotive/wagon/generators/site'
- # generator = Locomotive::Wagon::Generators::Site::Cloned
- # generator.start [name, path, true, connection_info.symbolize_keys]
-
- # # pull the remote site
- # self.pull(target_path, options.merge(connection_info).with_indifferent_access, { disable_misc: true })
end
# Destroy a remote site
locomotive/wagon/cli.rb b/lib/locomotive/wagon/cli.rb +19 -10
@@ @@ -21,7 +21,9 @@ module Locomotive
path = path == '.' ? Dir.pwd : File.expand_path(path)
- (File.exists?(File.join(path, 'config', 'site.yml')) ? path : nil).tap do |_path|
+ site_or_deploy_file = File.exists?(File.join(path, 'config', 'site.yml')) || File.exists?(File.join(path, 'config', 'deploy.yml'))
+
+ (site_or_deploy_file ? path : nil).tap do |_path|
if _path.nil?
say 'The path does not point to a LocomotiveCMS site', :red
end
@@ @@ -35,7 +37,7 @@ module Locomotive
def force_color_if_asked(options)
if options[:force_color]
# thor
- require 'locomotive/wagon/misc/thor'
+ require 'locomotive/wagon/tools/thor'
self.shell = Thor::Shell::ForceColor.new
# bypass colorize code
@@ @@ -216,8 +218,9 @@ module Locomotive
desc 'clone NAME HOST [PATH]', 'Clone a remote LocomotiveCMS site'
method_option :verbose, aliases: '-v', type: 'boolean', default: false, desc: 'display the full error stack trace if an error occurs'
+ method_option :handle, aliases: '-h', desc: 'handle of your site'
method_option :email, aliases: '-e', desc: 'email of an administrator account'
- method_option :password, aliases: '-p', desc: 'password of an administrator account'
+ method_option :password, aliases: '-p', desc: 'password of an administrator account (use api_key instead)'
method_option :api_key, aliases: '-a', desc: 'api key of an administrator account'
def clone(name, host, path = '.')
begin
@@ @@ -320,14 +323,20 @@ module Locomotive
method_option :verbose, aliases: '-v', type: 'boolean', default: false, desc: 'display the full error stack trace if an error occurs'
def pull(env, path = '.')
if check_path!(path)
- if connection_info = self.retrieve_connection_info(env, path)
- begin
- Locomotive::Wagon.pull(path, connection_info, options)
- rescue Exception => e
- self.print_exception(e, options[:verbose])
- exit(1)
- end
+ begin
+ Locomotive::Wagon.pull(env, path, options, options[:shell] ? shell : nil)
+ rescue Exception => e
+ self.print_exception(e, options[:verbose])
+ exit(1)
end
+ # if connection_info = self.retrieve_connection_info(env, path)
+ # begin
+ # Locomotive::Wagon.pull(path, connection_info, options)
+ # rescue Exception => e
+ # self.print_exception(e, options[:verbose])
+ # exit(1)
+ # end
+ # end
end
end
locomotive/wagon/commands/clone_command.rb b/lib/locomotive/wagon/commands/clone_command.rb +21 -1
@@ @@ -7,7 +7,27 @@ module Locomotive::Wagon
end
def clone
- # TODO
+ # create an empty site with the minimal settings
+ create_site
+
+ # pull the pages, content_types, basically any resources from the remote site
+ pull_site
+ end
+
+ def connection_info
+ options.symbolize_keys.slice(:host, :handle, :email, :api_key, :password)
+ end
+
+ private
+
+ def create_site
+ require 'locomotive/wagon/generators/site'
+ generator = Locomotive::Wagon::Generators::Site::Cloned
+ generator.start [name, path, true, connection_info]
+ end
+
+ def pull_site
+ raise 'TODO: call the pull command'
end
end
locomotive/wagon/commands/loggers/base_logger.rb b/lib/locomotive/wagon/commands/loggers/base_logger.rb +31 -0
@@ @@ -0,0 +1,31 @@
+ module Locomotive::Wagon
+
+ class BaseLogger
+
+ private
+
+ def log(message, color = nil, ident = nil, print = false)
+ ident = ' ' * (ident || 0)
+
+ message = "#{ident}#{message.gsub("\n", "\n" + ident)}"
+ message = message.colorize(color) if color
+
+ if print
+ print message
+ else
+ puts message
+ end
+ end
+
+ def _subscribe(type, action = nil, &block)
+ name = ['wagon', type, [*action]].flatten.compact.join('.')
+
+ ActiveSupport::Notifications.subscribe(name) do |*args|
+ event = ActiveSupport::Notifications::Event.new *args
+ yield(event)
+ end
+ end
+
+ end
+
+ end
locomotive/wagon/commands/loggers/pull_logger.rb b/lib/locomotive/wagon/commands/loggers/pull_logger.rb +43 -0
@@ @@ -0,0 +1,43 @@
+ require_relative 'base_logger'
+
+ module Locomotive::Wagon
+
+ class PullLogger < BaseLogger
+
+ def initialize
+ # subscribe 'site_created' do |event|
+ # log "We created the config/site.yml file", { mode: :bold }
+ # end
+
+ subscribe :start do |event|
+ log "\n"
+ log "Pulling #{event.payload[:name].camelcase}", { color: :black, background: :white }
+ end
+
+ # subscribe :persist do |event|
+ # log "persisting #{event.payload[:label]}", :white, 2, true
+ # end
+
+ # subscribe :skip_persisting do |event|
+ # log ' [' + 'skip'.colorize(:yellow) + ']'
+ # end
+
+ # subscribe :persist_with_success do |event|
+ # log ' [' + 'done'.colorize(:green) + ']'
+ # end
+
+ # subscribe :persist_with_error do |event|
+ # log ' [' + 'failed'.colorize(:red) + ']'
+ # log event.payload[:message], :red, 4
+ # end
+ end
+
+ private
+
+ def subscribe(action = nil, &block)
+ _subscribe('pull', action, &block)
+ end
+
+ end
+
+ end
locomotive/wagon/commands/loggers/push_logger.rb b/lib/locomotive/wagon/commands/loggers/push_logger.rb +23 -17
@@ @@ -1,6 +1,8 @@
+ require_relative 'base_logger'
+
module Locomotive::Wagon
- class PushLogger
+ class PushLogger < BaseLogger
def initialize
subscribe 'site_created' do |event|
@@ @@ -32,28 +34,32 @@ module Locomotive::Wagon
private
- def log(message, color = nil, ident = nil, print = false)
- ident = ' ' * (ident || 0)
+ # def log(message, color = nil, ident = nil, print = false)
+ # ident = ' ' * (ident || 0)
- message = "#{ident}#{message.gsub("\n", "\n" + ident)}"
- message = message.colorize(color) if color
+ # message = "#{ident}#{message.gsub("\n", "\n" + ident)}"
+ # message = message.colorize(color) if color
- if print
- print message
- else
- puts message
- end
- end
+ # if print
+ # print message
+ # else
+ # puts message
+ # end
+ # end
def subscribe(action = nil, &block)
- name = ['wagon', 'push', [*action]].flatten.compact.join('.')
-
- ActiveSupport::Notifications.subscribe(name) do |*args|
- event = ActiveSupport::Notifications::Event.new *args
- yield(event)
- end
+ _subscribe('push', action, &block)
end
+ # def subscribe(action = nil, &block)
+ # name = ['wagon', 'push', [*action]].flatten.compact.join('.')
+
+ # ActiveSupport::Notifications.subscribe(name) do |*args|
+ # event = ActiveSupport::Notifications::Event.new *args
+ # yield(event)
+ # end
+ # end
+
end
end
locomotive/wagon/commands/pull_command.rb b/lib/locomotive/wagon/commands/pull_command.rb +56 -0
@@ @@ -0,0 +1,56 @@
+ require 'locomotive/common'
+
+ require_relative '../tools/styled_yaml'
+
+ require_relative 'loggers/pull_logger'
+
+ require_relative_all 'concerns'
+
+ require_relative 'pull_sub_commands/pull_base_command'
+ require_relative_all 'pull_sub_commands'
+
+ module Locomotive::Wagon
+
+ class PullCommand < Struct.new(:env, :path, :options, :shell)
+
+ # RESOURCES = %w(site pages content_types content_entries snippets theme_assets translations).freeze
+ RESOURCES = %w(pages).freeze
+
+ include ApiConcern
+ include DeployFileConcern
+ include InstrumentationConcern
+
+ def self.pull(env, path, options, shell)
+ self.new(env, path, options, shell).pull
+ end
+
+ def pull
+ PullLogger.new if options[:verbose]
+
+ api_client = api_site_client(connection_information)
+ site = api_client.current_site.get
+
+ each_resource do |klass|
+ klass.pull(api_client, site, path)
+ end
+ end
+
+ private
+
+ def each_resource
+ RESOURCES.each do |name|
+ next if !options[:resources].blank? && !options[:resources].include?(name)
+
+ klass = "Locomotive::Wagon::Pull#{name.camelcase}Command".constantize
+
+ yield klass
+ end
+ end
+
+ def connection_information
+ read_deploy_settings(self.env, self.path)
+ end
+
+ end
+
+ end
locomotive/wagon/commands/pull_sub_commands/concerns/assets_concern.rb b/lib/locomotive/wagon/commands/pull_sub_commands/concerns/assets_concern.rb +64 -0
@@ @@ -0,0 +1,64 @@
+ require 'tempfile'
+
+ module Locomotive::Wagon
+
+ module AssetsConcern
+
+ # The content assets on the remote engine follows the format: /sites/<id>/assets/<type>/<file>
+ # This method replaces these urls by their local representation. <type>/<file>
+ #
+ # @param [ String ] content The text where the assets will be replaced.
+ #
+ def replace_asset_urls(content)
+ return '' if content.blank?
+
+ content.force_encoding('utf-8').gsub(/\/sites\/[0-9a-f]{24}\/(assets|pages)\/(([^;.]+)\/)*([a-zA-Z_\-0-9]+)\.([a-z]{2,3})/) do |url|
+ if filepath = write_asset(url, File.join(path, 'public', 'samples', $1, "#{$4}.#{$5}"))
+ "/samples/#{$1}/#{File.basename(filepath)}"
+ else
+ ''
+ end
+ end
+ end
+
+ private
+
+ def find_unique_filepath(filepath, binary_file, index = 1)
+ if File.exists?(filepath)
+ # required because we need to make sure we use the content of file from its start
+ binary_file.rewind
+
+ return filepath if FileUtils.compare_stream(binary_file, File.open(filepath))
+
+ folder, ext = File.dirname(filepath), File.extname(filepath)
+ basename = File.basename(filepath, ext)
+
+ find_unique_filepath(File.join(folder, "#{basename}-#{index}#{ext}"), binary, index + 1)
+ else
+ filepath
+ end
+ end
+
+ def get_asset_binary(url)
+ unless url =~ /\Ahttp:\/\//
+ base = api_client.uri.dup.tap { |u| u.path = '' }.to_s
+ url = URI.join(base, url).to_s
+ end
+
+ binary = Faraday.get(url).body rescue nil
+ end
+
+ def write_asset(url, filepath)
+ if binary = get_asset_binary(url)
+ FileUtils.mkdir_p(File.dirname(filepath))
+
+ (binary_file = Tempfile.new(File.basename(filepath))).write(binary)
+
+ find_unique_filepath(filepath, binary_file).tap do |filepath|
+ File.open(filepath, 'wb') { |f| f.write(binary) }
+ end
+ else
+ instrument :missing_asset, url: url
+ nil
+ end
+ end
locomotive/wagon/commands/pull_sub_commands/pull_base_command.rb b/lib/locomotive/wagon/commands/pull_sub_commands/pull_base_command.rb +62 -0
@@ @@ -0,0 +1,62 @@
+ require_relative 'concerns/assets_concern'
+
+ module Locomotive::Wagon
+
+ class PullBaseCommand < Struct.new(:api_client, :current_site, :path)
+
+ include Locomotive::Wagon::AssetsConcern
+
+ def self.pull(api_client, current_site, path)
+ new(api_client, current_site, path).pull
+ end
+
+ def pull
+ instrument do
+ instrument :start
+ self._pull_with_timezone
+ instrument :done
+ end
+ end
+
+ def _pull_with_timezone
+ Time.use_zone(current_site.try(:timezone)) do
+ _pull
+ end
+ end
+
+ def instrument(action = nil, payload = {}, &block)
+ name = ['wagon.pull', [*action]].flatten.compact.join('.')
+ ActiveSupport::Notifications.instrument(name, { name: resource_name }.merge(payload), &block)
+ end
+
+ def dump(attributes, options)
+ _attributes = attributes.dup
+
+ [*options[:inline]].each do |name|
+ _attributes[name] = StyledYAML.inline(_attributes[name])
+ end
+
+ StyledYAML.dump(_attributes).gsub(/\A---\n/, '')
+ end
+
+ def write_to_file(filepath, content = nil, &block)
+ File.open(File.join(path, filepath), 'w+') do |file|
+ file.write(content ? content : yield)
+ end
+ end
+
+ def resource_name
+ self.class.name[/::Pull(\w+)Command$/, 1].underscore
+ end
+
+ def default_locale
+ current_site.locales.first
+ end
+
+ def locales
+ current_site.locales
+ end
+
+ end
+
+ end
locomotive/wagon/commands/pull_sub_commands/pull_content_assets_command.rb b/lib/locomotive/wagon/commands/pull_sub_commands/pull_content_assets_command.rb +11 -0
@@ @@ -0,0 +1,11 @@
+ module Locomotive::Wagon
+
+ class PullContentAssetsCommand < PullBaseCommand
+
+ def pull
+ puts 'TODO pulling content assets'
+ end
+
+ end
+
+ end
locomotive/wagon/commands/pull_sub_commands/pull_pages_command.rb b/lib/locomotive/wagon/commands/pull_sub_commands/pull_pages_command.rb +59 -0
@@ @@ -0,0 +1,59 @@
+ module Locomotive::Wagon
+
+ class PullPagesCommand < PullBaseCommand
+
+ attr_reader :fullpaths
+
+ def _pull
+ @fullpaths = {}
+
+ locales.each do |locale|
+ api_client.pages.all(locale).each do |page|
+ fullpaths[page._id] = page.fullpath if locale == default_locale
+ write_page(page, locale)
+ end
+ end
+ end
+
+ def write_page(page, locale = nil)
+ write_to_file(page_filepath(page, locale)) do
+ <<-EOF
+ #{yaml_attributes(page, locale)}---
+ #{replace_asset_urls(page.template)}
+ EOF
+ end
+ end
+
+ private
+
+ def yaml_attributes(page, locale)
+ _attributes = page.attributes.slice('title', 'slug', 'handle', 'position', 'listed', 'published', 'redirect_url', 'is_layout', 'content_type', 'seo_title', 'meta_description', 'meta_keywords')
+
+ if locale != default_locale
+ _attributes.delete_if { |k, _| %w(handle position listed published is_layout content_type).include?(k) }
+ end
+
+ # editable elements
+ _attributes['editable_elements'] = page.editable_elements.inject({}) do |hash, el|
+ hash["#{el['block']}/#{el['slug']}"] = replace_asset_urls(el['content'])
+ hash
+ end
+
+ # remove nil or empty values
+ _attributes.delete_if { |_, v| v.nil? || v == '' || (v.is_a?(Hash) && v.empty?) }
+
+ _attributes.to_yaml
+ end
+
+ def page_filepath(page, locale)
+ fullpath = locale == default_locale ? page.fullpath : "#{fullpaths[page._id]}.#{locale}"
+
+ filepath = File.join('app', 'views', 'pages', fullpath + '.liquid').tap do |filepath|
+ folder = File.dirname(filepath)
+ FileUtils.mkdir_p(folder) unless File.exists?(folder)
+ end
+ end
+
+ end
+
+ end
locomotive/wagon/commands/pull_sub_commands/pull_site_command.rb b/lib/locomotive/wagon/commands/pull_sub_commands/pull_site_command.rb +53 -0
@@ @@ -0,0 +1,53 @@
+ module Locomotive::Wagon
+
+ class PullSiteCommand < PullBaseCommand
+
+ def _pull
+ attributes = current_site.attributes.slice('name', 'locales', 'domains', 'timezone', 'seo_title', 'meta_keywords', 'meta_description', 'picture_thumbnail_url')
+
+ locales.each_with_index do |locale, index|
+ if index == 0
+ transform_in_default_locale(attributes, locale)
+ else
+ add_other_locale(attributes, locale)
+ end
+ end if locales.size > 1
+
+ write_icon(attributes.delete('picture_thumbnail_url'))
+
+ write_to_file(File.join('config', 'site.yml')) do
+ dump(attributes, inline: %w(locales domains))
+ end
+ end
+
+ private
+
+ def write_icon(url)
+ unless url =~ /\Ahttp:\/\//
+ base = api_client.uri.dup.tap { |u| u.path = '' }.to_s
+ url = URI.join(base, url).to_s
+ end
+
+ File.open(File.join(path, 'icon.png'), 'wb') do |file|
+ file.write Faraday.get(url).body
+ end
+ end
+
+ def localized_attributes(&block)
+ %w(seo_title meta_keywords meta_description).each do |name|
+ yield(name)
+ end
+ end
+
+ def transform_in_default_locale(attributes, locale)
+ localized_attributes { |k| attributes[k] = { locale => attributes[k] } }
+ end
+
+ def add_other_locale(attributes, locale)
+ _site = api_client.current_site.get(locale)
+ localized_attributes { |k| attributes[k][locale] = _site.attributes[k] }
+ end
+
+ end
+
+ end
locomotive/wagon/generators/site.rb b/lib/locomotive/wagon/generators/site.rb +0 -2
@@ @@ -110,8 +110,6 @@ module Locomotive
path: path,
icon: icon && File.exists?(icon) ? icon : nil,
options: class_options_to_json(template)
-
-
}
end.to_json
end
locomotive/wagon/generators/site/cloned.rb b/lib/locomotive/wagon/generators/site/cloned.rb +1 -1
@@ @@ -24,4 +24,4 @@ module Locomotive
end
end
end
- end
\ No newline at end of file
+ end
locomotive/wagon/tools/deployment_connection.rb b/lib/locomotive/wagon/tools/deployment_connection.rb +0 -120
@@ @@ -1,120 +0,0 @@
- # require 'locomotive/wagon/misc/hosting_api'
- # require 'active_support/core_ext/hash'
- # require 'netrc'
- # require 'erb'
-
- # module Locomotive
- # module Wagon
-
- # class DeploymentConnection
-
- # # Create a connection for the deployment
- # # from the path of a Wagon site.
- # #
- # # @param [ String ] path Path to a Wagon site
- # #
- # def initialize(path, shell = nil)
- # @path = path
- # @shell = shell
- # end
-
- # # Retrieve information connection from the
- # # config/deploy.yml file and for a specific environment.
- # # If the env is hosting and does not have an entry in that file,
- # # then it looks for an api key in the ~/.netrc file, assuming
- # # that the user authenticates himself previously thanks to the
- # # auth wagon command.
- # #
- # # @param [ String ] env The target environment to deploy the site.
- # #
- # def get_information(env)
- # connection_info = read_from_yaml_file(env)
-
- # # if the user owns a hosting account, then use his credentials
- # # to create a new site.
- # if connection_info.nil? && env == 'hosting'
- # connection_info = read_from_hosting
- # end
-
- # if connection_info.nil?
- # raise "No #{env.to_s} environment found in the config/deploy.yml file"
- # end
-
- # connection_info = connection_info.with_indifferent_access
-
- # if connection_info[:ssl] && !connection_info[:host].start_with?('https')
- # connection_info[:host] = 'https://' + connection_info[:host]
- # end
-
- # connection_info
- # end
-
- # private
-
- # def deploy_file
- # File.join(@path, 'config', 'deploy.yml')
- # end
-
- # def read_from_yaml_file(env)
- # # pre-processing: erb code to parse and render?
- # parsed_deploy_file = ERB.new(File.open(deploy_file).read).result
-
- # # finally, get the hash from the YAML file
- # environments = YAML::load(parsed_deploy_file)
- # (environments.is_a?(Hash) ? environments : {})[env.to_s]
- # rescue Exception => e
- # raise "Unable to read the config/deploy.yml file (#{e.message})"
- # end
-
- # def read_from_hosting
- # hosting_api = new_hosting_api
-
- # # create the site (READ the site.yml file to get the information)
- # site = hosting_api.create_site(site_attributes)
-
- # if site.success?
- # # now we've got the subdomain, build the target host
- # host = [site['subdomain'], hosting_api.domain_with_port].join('.')
-
- # # return the connection information
- # { 'host' => host, 'api_key' => hosting_api.api_key }.tap do |hash|
- # # add ssl only if it is asked
- # hash['ssl'] = true if hosting_api.ssl?
-
- # # insert a new entry for hosting env in the current deploy.yml
- # File.open(deploy_file, 'a+') do |f|
- # f.write({ 'hosting' => hash }.to_yaml.sub(/^---/, ''))
- # end
- # end
- # else
- # raise "We were unable to create a new site on the hosting, reason(s): #{site.error_messages.join(', ')}"
- # end
- # end
-
- # def new_hosting_api
- # Locomotive::HostingAPI.new.tap do |hosting_api|
- # netrc = Netrc.read
- # email, api_key = netrc[hosting_api.domain_with_port]
-
- # # get a new auth token for further API calls
- # hosting_api.authenticate(api_key: api_key)
- # end
- # end
-
- # def config_file
- # File.join(@path, 'config', 'site.yml')
- # end
-
- # def site_attributes
- # YAML::load(File.read(config_file)).tap do |attributes|
- # # ask for the subdomain
- # if attributes['subdomain'].blank? && @shell
- # attributes['subdomain'] = @shell.ask("Please, what's your subdomain? (leave it blank for a random one)")
- # end
- # end
- # end
-
- # end
-
- # end
- # end
locomotive/wagon/tools/hosting_api.rb b/lib/locomotive/wagon/tools/hosting_api.rb +0 -117
@@ @@ -1,117 +0,0 @@
- # require 'httparty'
-
- # module Locomotive
- # class HostingAPI
-
- # include HTTParty
-
- # base_uri ENV['HOSTING_URL'] || 'http://www.locomotivehosting.com'
- # # base_uri ENV['HOSTING_URL'] || 'http://www.locomotivehosting.fr'
- # # base_uri ENV['HOSTING_URL'] || 'http://www.locomotivehosting.dev:3000'
-
- # def initialize(credentials = nil)
- # authenticate(credentials) if credentials
- # end
-
- # def self.host
- # URI(base_uri).host
- # end
-
- # def base_uri; self.class.base_uri; end
- # def host; self.class.host; end
- # def port; URI(self.class.base_uri).port; end
-
- # def domain
- # host.split('.')[1..-1].join('.') # TLD length of 2
- # end
-
- # def domain_with_port
- # if port != 80
- # self.domain + ":#{port}"
- # else
- # self.domain
- # end
- # end
-
- # def ssl?
- # URI(self.class.base_uri).scheme == 'https'
- # end
-
- # def authenticate(credentials)
- # response = self.class.post('/locomotive/api/tokens.json', { body: credentials })
-
- # if response.success?
- # @auth_token = response['token']
- # end
- # end
-
- # def authenticated?
- # !!@auth_token
- # end
-
- # def api_key
- # @api_key ||= api_key!
- # end
-
- # def api_key!
- # return false unless authenticated?
-
- # my_account['api_key']
- # end
-
- # def my_account
- # self.class.get('/locomotive/api/my_account.json', { query: { auth_token: @auth_token }})
- # end
-
- # def create_account(attributes)
- # attributes[:password_confirmation] = attributes[:password]
-
- # _response = self.class.post('/locomotive/api/my_account.json', { body: { account: attributes }})
-
- # Response.new(_response.parsed_response).tap do |response|
- # response.success = _response.success?
- # end
- # end
-
- # def create_site(attributes)
- # _response = self.class.post('/locomotive/api/sites.json', { body: { auth_token: @auth_token, site: attributes }})
-
- # Response.new(_response.parsed_response).tap do |response|
- # response.success = _response.success?
- # end
- # end
-
- # class Response < Hash
-
- # attr_writer :success
-
- # def initialize(attributes = {})
- # replace(attributes)
- # end
-
- # def success?
- # !!@success
- # end
-
- # def errors
- # return nil if success?
-
- # @errors ||= if self['error']
- # [[nil, [self['error']]]]
- # elsif self['errors']
- # self['errors']
- # else
- # self.to_a
- # end.delete_if { |attribute, errors| errors.empty? }
- # end
-
- # def error_messages
- # return nil if success? || errors.nil?
-
- # errors.to_a.map { |attribute, messages| messages.map { |message| [attribute, message].compact.join(' ') } }.flatten
- # end
-
- # end
-
- # end
- # end
locomotive/wagon/tools/styled_yaml.rb b/lib/locomotive/wagon/tools/styled_yaml.rb +122 -0
@@ @@ -0,0 +1,122 @@
+ require 'psych'
+ require 'stringio'
+
+ # Public: A Psych extension to enable choosing output styles for specific
+ # objects.
+ #
+ # Thanks to Tenderlove for help in <http://stackoverflow.com/q/9640277/11687>
+ #
+ # Examples
+ #
+ # data = {
+ # response: { body: StyledYAML.literal(json_string), status: 200 },
+ # person: StyledYAML.inline({ 'name' => 'Stevie', 'age' => 12 }),
+ # array: StyledYAML.inline(%w[ apples bananas oranges ])
+ # }
+ #
+ # StyledYAML.dump data, $stdout
+ #
+ module StyledYAML
+ # Tag strings to be output using literal style
+ def self.literal obj
+ obj.extend LiteralScalar
+ return obj
+ end
+
+ # http://www.yaml.org/spec/1.2/spec.html#id2795688
+ module LiteralScalar
+ def yaml_style() Psych::Nodes::Scalar::LITERAL end
+ end
+
+ # Tag Hashes or Arrays to be output all on one line
+ def self.inline obj
+ case obj
+ when Hash then obj.extend FlowMapping
+ when Array then obj.extend FlowSequence
+ else
+ warn "#{self}: unrecognized type to inline (#{obj.class.name})"
+ end
+ return obj
+ end
+
+ # http://www.yaml.org/spec/1.2/spec.html#id2790832
+ module FlowMapping
+ def yaml_style() Psych::Nodes::Mapping::FLOW end
+ end
+
+ # http://www.yaml.org/spec/1.2/spec.html#id2790320
+ module FlowSequence
+ def yaml_style() Psych::Nodes::Sequence::FLOW end
+ end
+
+ # Custom tree builder class to recognize scalars tagged with `yaml_style`
+ class TreeBuilder < Psych::TreeBuilder
+ attr_writer :next_sequence_or_mapping_style
+
+ def initialize(*args)
+ super
+ @next_sequence_or_mapping_style = nil
+ end
+
+ def next_sequence_or_mapping_style default_style
+ style = @next_sequence_or_mapping_style || default_style
+ @next_sequence_or_mapping_style = nil
+ style
+ end
+
+ def scalar value, anchor, tag, plain, quoted, style
+ if style_any?(style) and value.respond_to?(:yaml_style) and style = value.yaml_style
+ if style_literal? style
+ plain = false
+ quoted = true
+ end
+ end
+ super
+ end
+
+ def style_any?(style) Psych::Nodes::Scalar::ANY == style end
+
+ def style_literal?(style) Psych::Nodes::Scalar::LITERAL == style end
+
+ %w[sequence mapping].each do |type|
+ class_eval <<-RUBY
+ def start_#{type}(anchor, tag, implicit, style)
+ style = next_sequence_or_mapping_style(style)
+ super
+ end
+ RUBY
+ end
+ end
+
+ # Custom tree class to handle Hashes and Arrays tagged with `yaml_style`
+ class YAMLTree < Psych::Visitors::YAMLTree
+ %w[Hash Array Psych_Set Psych_Omap].each do |klass|
+ class_eval <<-RUBY
+ def visit_#{klass} o
+ if o.respond_to? :yaml_style
+ @emitter.next_sequence_or_mapping_style = o.yaml_style
+ end
+ super
+ end
+ RUBY
+ end
+ end
+
+ # A Psych.dump alternative that uses the custom TreeBuilder
+ def self.dump obj, io = nil, options = {}
+ real_io = io || StringIO.new(''.encode('utf-8'))
+ visitor = YAMLTree.new(options, TreeBuilder.new)
+ visitor << obj
+ ast = visitor.tree
+
+ begin
+ ast.yaml real_io
+ rescue
+ # The `yaml` method was introduced in later versions, so fall back to
+ # constructing a visitor
+ Psych::Visitors::Emitter.new(real_io).accept ast
+ end
+
+ io ? io : real_io.string
+ end
+ end
locomotivecms_wagon.gemspec +1 -1
@@ @@ -25,7 +25,7 @@ Gem::Specification.new do |gem|
gem.add_dependency 'rubyzip', '~> 1.1.7'
gem.add_dependency 'netrc', '~> 0.10.3'
- gem.add_dependency 'locomotivecms_coal', '~> 1.0.0-alpha.3'
+ # gem.add_dependency 'locomotivecms_coal', '~> 1.0.0-alpha.3'
gem.add_dependency 'locomotivecms_steam', '~> 1.0.0-alpha.2'
gem.add_dependency 'listen', '~> 2.10.0'