push command: create a site to the engine if no entry in the deploy.yml file
did
committed Apr 13, 2015
commit b3e22db1defaee8d53611d37b7cc141103cb5ffc
Showing 17
changed files with
569 additions
and 391 deletions
Gemfile
+2
-2
| @@ | @@ -14,10 +14,10 @@ gem 'rb-fsevent', '~> 0.9.1' |
| gem 'therubyracer' | |
| gem 'locomotivecms_steam', github: 'locomotivecms/steam', ref: 'b2de77e', require: false | |
| - | # gem 'locomotivecms_coal', github: 'locomotivecms/coal', ref: '6ae10e3684', require: false |
| + | gem 'locomotivecms_coal', github: 'locomotivecms/coal', ref: '32b2844', require: false |
| gem 'locomotivecms_common', github: 'locomotivecms/common', ref: '1895573', 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 | |
Rakefile
+3
-20
| @@ | @@ -25,23 +25,8 @@ task release: :gem do |
| sh "gem push pkg/locomotivecms_wagon-#{gemspec.version}.gem" | |
| end | |
| - | namespace :development do |
| - | desc 'create vcr cassettes' |
| - | task :bootstrap do |
| - | VCR.configure do |c| |
| - | c.cassette_library_dir = File.expand_path(File.dirname(__FILE__) + '/spec/integration/cassettes') |
| - | c.hook_into :webmock # or :fakeweb |
| - | c.allow_http_connections_when_no_cassette = true |
| - | end |
| - | |
| - | FileUtils.rm_rf(File.join(File.dirname(__FILE__), 'site')) |
| - | VCR.use_cassette('pull') do |
| - | exit unless Locomotive::Wagon.clone('site', '.', { host: 'sample.example.com:3000', email: 'admin@locomotivecms.com', password: 'locomotive' }) |
| - | end |
| - | |
| - | Locomotive::Wagon.push('site', {host: 'sample.example.com:3000', email: 'admin@locomotivecms.com', password: 'locomotive'}, force: true, translations: false, data: true) |
| - | end |
| - | end |
| + | require 'rspec/core/rake_task' |
| + | RSpec::Core::RakeTask.new('spec') |
| RSpec::Core::RakeTask.new('spec:unit') do |spec| | |
| spec.pattern = 'spec/unit/**/*_spec.rb' | |
| @@ | @@ -52,6 +37,4 @@ RSpec::Core::RakeTask.new('spec:integration') do |spec| |
| spec.pattern = 'spec/integration/**/*_spec.rb' | |
| end | |
| - | task spec: ['spec:integration'] |
| - | |
| - | task default: :spec |
| \ No newline at end of file | |
| + | task default: :spec |
locomotive/wagon/commands/authenticate_command.rb b/lib/locomotive/wagon/commands/authenticate_command.rb
+3
-22
| @@ | @@ -1,12 +1,12 @@ |
| - | require 'netrc' |
| - | |
| require_relative 'concerns/api_concern' | |
| + | require_relative 'concerns/netrc_concern' |
| module Locomotive::Wagon | |
| class AuthenticateCommand < Struct.new(:platform_url, :email, :password, :shell) | |
| include ApiConcern | |
| + | include NetrcConcern |
| def self.authenticate(platform_url, email, password, shell) | |
| self.new(platform_url, email, password, shell).authenticate | |
| @@ | @@ -14,7 +14,7 @@ module Locomotive::Wagon |
| def authenticate | |
| if api_key = fetch_api_key | |
| - | record_credentials(api_key) |
| + | write_credentials_to_netrc(api_host, email, api_key) |
| else | |
| shell.say "Sorry, we were unable to authenticate you on \"#{platform_url}\"", :red | |
| end | |
| @@ | @@ -50,15 +50,6 @@ module Locomotive::Wagon |
| end | |
| end | |
| - | def record_credentials(api_key) |
| - | uri = URI(platform_url) |
| - | key = "#{uri.host}:#{uri.port}" |
| - | |
| - | netrc = Netrc.read |
| - | netrc[key] = email, api_key |
| - | netrc.save |
| - | end |
| - | |
| private | |
| def my_account | |
| @@ | @@ -69,16 +60,6 @@ module Locomotive::Wagon |
| end | |
| end | |
| - | # def client |
| - | # @client ||= Locomotive::Coal::Client.new(api_url, email: email, password: password) |
| - | # end |
| - | |
| - | # def api_url |
| - | # uri = URI(platform_url) |
| - | # uri.merge!('/locomotive/api/v3') if uri.path == '/' || uri.path == '' |
| - | # uri.to_s |
| - | # end |
| - | |
| end | |
| end | |
locomotive/wagon/commands/concerns/api_concern.rb b/lib/locomotive/wagon/commands/concerns/api_concern.rb
+30
-7
| @@ | @@ -4,10 +4,29 @@ module Locomotive::Wagon |
| module ApiConcern | |
| - | private |
| - | |
| + | # Instance of the API client to request an account or his/her list of sites. |
| def api_client | |
| - | @api_client ||= Locomotive::Coal::Client.new(api_url, api_credentials) |
| + | @api_client ||= Locomotive::Coal::Client.new(api_uri, api_credentials) |
| + | end |
| + | |
| + | # Instance of the API client to request resources of a site: pages, theme_assets, ...etc. |
| + | def api_site_client(site) |
| + | @api_site_client = api_client.scope_by(site) |
| + | end |
| + | |
| + | # Host (+ port) extracted from the platform_url instance variable. |
| + | # If port equals 80, do not add it to the host. |
| + | # |
| + | # Examples: |
| + | # |
| + | # www.myengine.com |
| + | # localhost:3000 |
| + | # |
| + | def api_host |
| + | uri = api_uri |
| + | host, port = uri.host, uri.port |
| + | |
| + | port == 80 ? uri.host : "#{uri.host}:#{uri.port}" |
| end | |
| def api_credentials | |
| @@ | @@ -18,10 +37,14 @@ module Locomotive::Wagon |
| end | |
| end | |
| - | def api_url |
| - | uri = URI(platform_url) |
| - | uri.merge!('/locomotive/api/v3') if uri.path == '/' || uri.path == '' |
| - | uri.to_s |
| + | private |
| + | |
| + | def api_uri |
| + | if (self.platform_url =~ /^https?:\/\//).nil? |
| + | self.platform_url = 'http://' + self.platform_url |
| + | end |
| + | |
| + | URI(platform_url) |
| end | |
| end | |
locomotive/wagon/commands/concerns/deploy_file_concern.rb b/lib/locomotive/wagon/commands/concerns/deploy_file_concern.rb
+32
-0
| @@ | @@ -0,0 +1,32 @@ |
| + | require 'locomotive/coal' |
| + | |
| + | module Locomotive::Wagon |
| + | |
| + | module DeployFileConcern |
| + | |
| + | def write_deploy_setings(env, path, settings) |
| + | File.open(deploy_file(path), 'a+') do |f| |
| + | f.write({ env => settings }.to_yaml.sub(/^---/, '')) |
| + | end |
| + | |
| + | settings |
| + | end |
| + | |
| + | def read_deploy_settings(env, path) |
| + | # pre-processing: erb code to parse and render? |
| + | parsed_deploy_file = ERB.new(File.open(deploy_file(path)).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 deploy_file(path) |
| + | File.join(path, 'config', 'deploy.yml') |
| + | end |
| + | |
| + | end |
| + | |
| + | end |
locomotive/wagon/commands/concerns/netrc_concern.rb b/lib/locomotive/wagon/commands/concerns/netrc_concern.rb
+21
-0
| @@ | @@ -0,0 +1,21 @@ |
| + | require 'netrc' |
| + | |
| + | module Locomotive::Wagon |
| + | |
| + | module NetrcConcern |
| + | |
| + | def write_credentials_to_netrc(host, email, api_key) |
| + | netrc = Netrc.read |
| + | netrc[host] = email, api_key |
| + | netrc.save |
| + | end |
| + | |
| + | def read_credentials_from_netrc(host) |
| + | if entry = Netrc.read[host] |
| + | { email: entry.login, api_key: entry.password } |
| + | end |
| + | end |
| + | |
| + | end |
| + | |
| + | end |
locomotive/wagon/commands/concerns/steam_concern.rb b/lib/locomotive/wagon/commands/concerns/steam_concern.rb
+24
-0
| @@ | @@ -0,0 +1,24 @@ |
| + | require 'locomotive/coal' |
| + | |
| + | module Locomotive::Wagon |
| + | |
| + | module SteamConcern |
| + | |
| + | def steam_services |
| + | return @steam_services if @steam_services |
| + | |
| + | Locomotive::Steam.configure do |config| |
| + | config.mode = :test |
| + | config.adapter = { name: :filesystem, path: path } |
| + | config.asset_path = File.expand_path(File.join(path, 'public')) |
| + | end |
| + | |
| + | @steam_services = Locomotive::Steam::Services.build_instance.tap do |services| |
| + | repositories = services.repositories |
| + | repositories.current_site = repositories.site.all.first |
| + | services.locale = repositories.current_site.default_locale |
| + | end |
| + | end |
| + | |
| + | end |
| + | end |
locomotive/wagon/commands/push_command.rb b/lib/locomotive/wagon/commands/push_command.rb
+40
-72
| @@ | @@ -1,13 +1,19 @@ |
| require 'locomotive/steam' | |
| - | require 'netrc' |
| require_relative 'concerns/api_concern' | |
| + | require_relative 'concerns/netrc_concern' |
| + | require_relative 'concerns/deploy_file_concern' |
| + | require_relative 'concerns/steam_concern' |
| + | require_relative '../decorators/site_decorator' |
| module Locomotive::Wagon | |
| class PushCommand < Struct.new(:env, :path, :options) | |
| include ApiConcern | |
| + | include NetrcConcern |
| + | include DeployFileConcern |
| + | include SteamConcern |
| attr_accessor :platform_url, :credentials | |
| @@ | @@ -21,43 +27,49 @@ module Locomotive::Wagon |
| end | |
| def connection_information | |
| - | if information = read_from_yaml_file |
| + | if information = read_deploy_settings(self.env, self.path) |
| # the deployment env exists and contains all the information we need to move on | |
| information | |
| else | |
| - | # 1. ask for the platform URL (or LOCOMOTIVE_PLATFORM_URL env variable) [DONE] |
| - | self.platform_url = ask_for_platform_url |
| - | |
| - | # 2. retrieve email + api_key. If no entry present in the .netrc, raise an error [DONE] |
| - | self.credentials = read_from_netrc(self.platform_url) |
| - | |
| - | raise 'You need to run wagon authenticate before going further' if self.credentials.nil? |
| + | # mandatory to sign in |
| + | load_credentials_from_netrc |
| + | |
| + | # create the remote site on the platform |
| + | site = create_remote_site |
| + | |
| + | # update the deploy.yml by adding the new env since we've got all the information |
| + | write_deploy_setings(self.env, self.path, { |
| + | 'host' => api_host, |
| + | 'handle' => site.handle, |
| + | 'email' => credentials[:email], |
| + | 'api_key' => credentials[:api_key] |
| + | }) |
| + | end |
| + | end |
| - | # 3. get an instance of the Steam services in order to load the information about the site (SiteRepository) |
| - | site = steam_services.current_site |
| + | private |
| - | # 4. ask for a handle if not found (blank: random one) |
| + | def create_remote_site |
| + | # get an instance of the Steam services in order to load the information about the site (SiteRepository) |
| + | steam_services.current_site.tap do |site| |
| + | # ask for a handle if not found (blank: random one) |
| site[:handle] ||= ask_for_the_site_handle | |
| - | # 5. create the site |
| - | create_remote_site(site) |
| - | |
| - | 'TODO' |
| - | |
| - | # 6. update the deploy.yml |
| + | # create the site |
| + | attributes = SiteDecorator.new(site).to_hash |
| + | _site = api_client.sites.create(attributes) |
| + | site[:handle] = _site.handle |
| end | |
| - | |
| - | # clean the URI (ssl, without scheme?) |
| - | # assign the site to the Steam services and repositories |
| - | # build an instance of the Coal client class |
| end | |
| - | private |
| + | def load_credentials_from_netrc |
| + | # ask for the platform URL (or LOCOMOTIVE_PLATFORM_URL env variable) |
| + | ask_for_platform_url |
| - | def create_remote_site(site) |
| - | api_client.sites.create(site.attributes).tap do |_site| |
| - | puts _site.inspect |
| - | end |
| + | # retrieve email + api_key. If no entry present in the .netrc, raise an error |
| + | self.credentials = read_credentials_from_netrc(self.api_host) |
| + | |
| + | raise 'You need to run wagon authenticate before going further' if self.credentials.nil? |
| end | |
| def ask_for_platform_url | |
| @@ | @@ -65,7 +77,7 @@ module Locomotive::Wagon |
| url = shell.ask "What is the URL of your platform? (default: #{default})" | |
| - | url.blank? ? default : url |
| + | self.platform_url = url.blank? ? default : url |
| end | |
| def ask_for_the_site_handle | |
| @@ | @@ -75,50 +87,6 @@ module Locomotive::Wagon |
| end | |
| end | |
| - | def read_from_yaml_file |
| - | # 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_netrc(platform_url) |
| - | uri = URI(platform_url) |
| - | host_with_port = "#{uri.host}:#{uri.port}" |
| - | |
| - | if credentials = Netrc.read[host_with_port] |
| - | { url: uri.to_s, email: credentials.email, api_key: credentials.api_key } |
| - | end |
| - | end |
| - | |
| - | def steam_services |
| - | return @steam_services if @steam_services |
| - | |
| - | Locomotive::Steam.configure do |config| |
| - | config.mode = :test |
| - | config.adapter = { name: :filesystem, path: path } |
| - | config.asset_path = File.expand_path(File.join(path, 'public')) |
| - | end |
| - | |
| - | @steam_services = Locomotive::Steam::Services.build_instance.tap do |services| |
| - | repositories = services.repositories |
| - | repositories.current_site = repositories.site.all.first |
| - | services.locale = repositories.current_site.default_locale |
| - | end |
| - | end |
| - | |
| - | def client |
| - | @client ||= Locomotive::Coal::Client.new(api_url, credentials) |
| - | end |
| - | |
| - | def deploy_file |
| - | File.join(path, 'config', 'deploy.yml') |
| - | end |
| - | |
| def shell | |
| options[:shell] | |
| end | |
locomotive/wagon/decorators/site_decorator.rb b/lib/locomotive/wagon/decorators/site_decorator.rb
+27
-0
| @@ | @@ -0,0 +1,27 @@ |
| + | module Locomotive |
| + | module Wagon |
| + | |
| + | class SiteDecorator < SimpleDelegator |
| + | |
| + | def domains |
| + | (__getobj__.domains || []) - ['localhost'] |
| + | end |
| + | |
| + | def to_hash |
| + | {}.tap do |hash| |
| + | %i(name handle robots_txt locales domains timezone seo_title meta_keywords meta_description).each do |name| |
| + | if value = self[name] |
| + | if value.respond_to?(:translations) |
| + | hash[name] = value.translations unless value.translations.empty? |
| + | else |
| + | hash[name] = value |
| + | end |
| + | end |
| + | end |
| + | end |
| + | end |
| + | |
| + | end |
| + | |
| + | end |
| + | end |
locomotive/wagon/tools/deployment_connection.rb b/lib/locomotive/wagon/tools/deployment_connection.rb
+120
-120
| @@ | @@ -1,120 +1,120 @@ |
| - | 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 |
| + | # 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
+86
-86
| @@ | @@ -1,117 +1,117 @@ |
| - | require 'httparty' |
| + | # require 'httparty' |
| - | module Locomotive |
| - | class HostingAPI |
| + | # module Locomotive |
| + | # class HostingAPI |
| - | include HTTParty |
| + | # 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' |
| + | # 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 initialize(credentials = nil) |
| + | # authenticate(credentials) if credentials |
| + | # end |
| - | def self.host |
| - | URI(base_uri).host |
| - | 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 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 |
| + | # 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 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 ssl? |
| + | # URI(self.class.base_uri).scheme == 'https' |
| + | # end |
| - | def authenticate(credentials) |
| - | response = self.class.post('/locomotive/api/tokens.json', { body: credentials }) |
| + | # def authenticate(credentials) |
| + | # response = self.class.post('/locomotive/api/tokens.json', { body: credentials }) |
| - | if response.success? |
| - | @auth_token = response['token'] |
| - | end |
| - | end |
| + | # if response.success? |
| + | # @auth_token = response['token'] |
| + | # end |
| + | # end |
| - | def authenticated? |
| - | !!@auth_token |
| - | end |
| + | # def authenticated? |
| + | # !!@auth_token |
| + | # end |
| - | def api_key |
| - | @api_key ||= api_key! |
| - | end |
| + | # def api_key |
| + | # @api_key ||= api_key! |
| + | # end |
| - | def api_key! |
| - | return false unless authenticated? |
| + | # def api_key! |
| + | # return false unless authenticated? |
| - | my_account['api_key'] |
| - | end |
| + | # my_account['api_key'] |
| + | # end |
| - | def my_account |
| - | self.class.get('/locomotive/api/my_account.json', { query: { auth_token: @auth_token }}) |
| - | 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] |
| + | # def create_account(attributes) |
| + | # attributes[:password_confirmation] = attributes[:password] |
| - | _response = self.class.post('/locomotive/api/my_account.json', { body: { account: attributes }}) |
| + | # _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 |
| + | # 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 }}) |
| + | # 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 |
| + | # Response.new(_response.parsed_response).tap do |response| |
| + | # response.success = _response.success? |
| + | # end |
| + | # end |
| - | class Response < Hash |
| + | # class Response < Hash |
| - | attr_writer :success |
| + | # attr_writer :success |
| - | def initialize(attributes = {}) |
| - | replace(attributes) |
| - | end |
| + | # def initialize(attributes = {}) |
| + | # replace(attributes) |
| + | # end |
| - | def success? |
| - | !!@success |
| - | end |
| + | # def success? |
| + | # !!@success |
| + | # end |
| - | def errors |
| - | return nil if success? |
| + | # 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 |
| + | # @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? |
| + | # def error_messages |
| + | # return nil if success? || errors.nil? |
| - | errors.to_a.map { |attribute, messages| messages.map { |message| [attribute, message].compact.join(' ') } }.flatten |
| - | end |
| + | # errors.to_a.map { |attribute, messages| messages.map { |message| [attribute, message].compact.join(' ') } }.flatten |
| + | # end |
| - | end |
| + | # end |
| - | end |
| - | end |
| + | # end |
| + | # end |
spec/fixtures/cassettes/push.yml
+132
-0
| @@ | @@ -0,0 +1,132 @@ |
| + | --- |
| + | http_interactions: |
| + | - request: |
| + | method: post |
| + | uri: http://localhost:3000/locomotive/api/v3/tokens.json?api_key=d49cd50f6f0d2b163f48fc73cb249f0244c37074&email=admin@locomotivecms.com&url=http://localhost:3000 |
| + | body: |
| + | encoding: UTF-8 |
| + | string: '' |
| + | headers: |
| + | Accept: |
| + | - application/json |
| + | Content-Length: |
| + | - '0' |
| + | Accept-Encoding: |
| + | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 |
| + | User-Agent: |
| + | - Ruby |
| + | response: |
| + | status: |
| + | code: 201 |
| + | message: Created |
| + | headers: |
| + | Content-Type: |
| + | - application/json |
| + | Content-Length: |
| + | - '32' |
| + | Etag: |
| + | - W/"1fe908e55e46275a5704935dac02818a" |
| + | Cache-Control: |
| + | - max-age=0, private, must-revalidate |
| + | X-Request-Id: |
| + | - 0a49ccde-4b0c-4982-8355-7b458011889c |
| + | X-Runtime: |
| + | - '0.017965' |
| + | Connection: |
| + | - keep-alive |
| + | Server: |
| + | - thin |
| + | body: |
| + | encoding: UTF-8 |
| + | string: '{"token":"i3Pws38yeUQ4Cp58xjSk"}' |
| + | http_version: |
| + | recorded_at: Mon, 13 Apr 2015 09:15:18 GMT |
| + | - request: |
| + | method: post |
| + | uri: http://localhost:3000/locomotive/api/v3/sites.json?auth_token=i3Pws38yeUQ4Cp58xjSk&site%5Bdomains%5D%5B0%5D=wagon.example.com&site%5Bdomains%5D%5B1%5D=localhost&site%5Blocales%5D%5B0%5D=en&site%5Blocales%5D%5B1%5D=fr&site%5Blocales%5D%5B2%5D=nb&site%5Bmeta_keywords%5D%5Ben%5D=some%20meta%20keywords&site%5Bmeta_keywords%5D%5Bfr%5D=quelques%20mots%20cles&site%5Bname%5D=Sample%20website&site%5Bseo_title%5D%5Ben%5D=A%20simple%20LocomotiveCMS%20website&site%5Bseo_title%5D%5Bfr%5D=Un%20simple%20LocomotiveCMS%20site%20web |
| + | body: |
| + | encoding: UTF-8 |
| + | string: '' |
| + | headers: |
| + | Accept: |
| + | - application/json |
| + | X-Locomotive-Account-Email: |
| + | - admin@locomotivecms.com |
| + | X-Locomotive-Account-Token: |
| + | - i3Pws38yeUQ4Cp58xjSk |
| + | Content-Length: |
| + | - '0' |
| + | Accept-Encoding: |
| + | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 |
| + | User-Agent: |
| + | - Ruby |
| + | response: |
| + | status: |
| + | code: 201 |
| + | message: Created |
| + | headers: |
| + | Content-Type: |
| + | - application/json |
| + | Content-Length: |
| + | - '589' |
| + | Etag: |
| + | - W/"32617c88a703d2c4b6bc7a1710ea7181" |
| + | Cache-Control: |
| + | - max-age=0, private, must-revalidate |
| + | X-Request-Id: |
| + | - d2366b32-e8df-4c1c-89cf-047b2f64a1ba |
| + | X-Runtime: |
| + | - '0.050050' |
| + | Connection: |
| + | - keep-alive |
| + | Server: |
| + | - thin |
| + | body: |
| + | encoding: UTF-8 |
| + | string: '{"_id":"552b892764696406eb110000","created_at":"2015-04-13T09:15:19Z","updated_at":"2015-04-13T09:15:19Z","name":"Sample |
| + | website","handle":"warm-leaves-4626","seo_title":"A simple LocomotiveCMS website","meta_keywords":"some |
| + | meta keywords","meta_description":null,"robots_txt":null,"locales":["en","fr","nb"],"domains":["wagon.example.com","localhost"],"memberships":[{"_id":"552b892764696406eb120000","created_at":null,"updated_at":null,"role":"admin","account_id":"552b88fe64696412ec000000","name":"Admin","role_name":"Administrator","email":"admin@locomotivecms.com"}],"timezone":"UTC"}' |
| + | http_version: |
| + | recorded_at: Mon, 13 Apr 2015 09:15:19 GMT |
| + | - request: |
| + | method: post |
| + | uri: http://localhost:3000/locomotive/api/v3/tokens.json?api_key=d49cd50f6f0d2b163f48fc73cb249f0244c37074&email=admin@locomotivecms.com |
| + | body: |
| + | encoding: UTF-8 |
| + | string: '' |
| + | headers: |
| + | Accept: |
| + | - application/json |
| + | Content-Length: |
| + | - '0' |
| + | Accept-Encoding: |
| + | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 |
| + | User-Agent: |
| + | - Ruby |
| + | response: |
| + | status: |
| + | code: 201 |
| + | message: Created |
| + | headers: |
| + | Content-Type: |
| + | - application/json |
| + | Content-Length: |
| + | - '32' |
| + | Etag: |
| + | - W/"1fe908e55e46275a5704935dac02818a" |
| + | Cache-Control: |
| + | - max-age=0, private, must-revalidate |
| + | X-Request-Id: |
| + | - d781ed41-6dc7-4706-a1b2-24155fbe9f0e |
| + | X-Runtime: |
| + | - '0.118848' |
| + | Connection: |
| + | - keep-alive |
| + | Server: |
| + | - thin |
| + | body: |
| + | encoding: UTF-8 |
| + | string: '{"token":"i3Pws38yeUQ4Cp58xjSk"}' |
| + | http_version: |
| + | recorded_at: Mon, 13 Apr 2015 11:44:53 GMT |
| + | recorded_with: VCR 2.9.3 |
spec/fixtures/default/config/site.yml
+2
-4
| @@ | @@ -1,8 +1,6 @@ |
| name: Sample website | |
| - | subdomain: sample |
| - | |
| - | domains: ['sample.example.com'] |
| + | domains: ['wagon.example.com'] |
| locales: ['en', 'fr', 'nb'] | |
| @@ | @@ -12,4 +10,4 @@ seo_title: |
| meta_keywords: | |
| en: some meta keywords | |
| fr: quelques mots cles | |
| - | meta_description: some meta description |
| \ No newline at end of file | |
| + | meta_description: some meta description |
spec/integration/commands/push_command_spec.rb
+5
-3
| @@ | @@ -6,8 +6,8 @@ require 'thor' |
| describe Locomotive::Wagon::PushCommand do | |
| - | # before { VCR.insert_cassette 'push', record: :new_episodes, match_requests_on: [:method, :query, :body] } |
| - | # after { VCR.eject_cassette } |
| + | before { VCR.insert_cassette 'push', record: :new_episodes, match_requests_on: [:method, :query, :body] } |
| + | after { VCR.eject_cassette } |
| let(:env) { 'production' } | |
| let(:path) { default_site_path } | |
| @@ | @@ -21,7 +21,7 @@ describe Locomotive::Wagon::PushCommand do |
| context 'unknown env' do | |
| - | let(:credentials) { instance_double('Credentials', email: TEST_API_EMAIL, api_key: TEST_API_KEY) } |
| + | let(:credentials) { instance_double('Credentials', login: TEST_API_EMAIL, password: TEST_API_KEY) } |
| let(:env) { 'hosting' } | |
| before do | |
| @@ | @@ -29,6 +29,8 @@ describe Locomotive::Wagon::PushCommand do |
| allow(Thor::LineEditor).to receive(:readline).and_return(TEST_PLATFORM_URL.dup, 'acme') | |
| end | |
| + | after { restore_deploy_file(default_site_path) } |
| + | |
| it { is_expected.to eq true } | |
| context 'no previous authentication' do | |
spec/support/helpers.rb
+8
-11
| @@ | @@ -13,12 +13,16 @@ module Spec |
| FileUtils.rm_rf(File.expand_path('../../fixtures/default/log', __FILE__)) | |
| end | |
| - | def clone_site |
| - | VCR.use_cassette('pull') do |
| - | Locomotive::Wagon.clone('site', '.', { host: 'sample.example.com:3000', email: 'admin@locomotivecms.com', password: 'locomotive' }) |
| - | end |
| + | def restore_deploy_file(path) |
| + | FileUtils.cp(File.join(path, 'config', 'deploy_example.yml'), File.join(path, 'config', 'deploy.yml')) |
| end | |
| + | # def clone_site |
| + | # VCR.use_cassette('pull') do |
| + | # Locomotive::Wagon.clone('site', '.', { host: 'sample.example.com:3000', email: 'admin@locomotivecms.com', password: 'locomotive' }) |
| + | # end |
| + | # end |
| + | |
| def working_copy_of_site(name) | |
| tmp_path = File.expand_path('../../tmp', __FILE__) | |
| tmp_path = FileUtils.mkdir_p(tmp_path) | |
| @@ | @@ -37,12 +41,5 @@ module Spec |
| FileUtils.rm_rf(path) | |
| end | |
| - | def open_in_browser |
| - | path = File.join(File.dirname(__FILE__), '..', 'tmp', "wagon-#{Time.new.strftime("%Y%m%d%H%M%S")}#{rand(10**10)}.html") |
| - | FileUtils.mkdir_p(File.dirname(path)) |
| - | File.open(path,'w') { |f| f.write last_response.body } |
| - | Launchy.open(path) |
| - | end |
| - | |
| end | |
| end | |
spec/unit/commands/authenticate_command_spec.rb
+0
-44
| @@ | @@ -1,44 +0,0 @@ |
| - | # encoding: utf-8 |
| - | |
| - | require 'spec_helper' |
| - | require 'locomotive/wagon/commands/authenticate_command' |
| - | |
| - | describe Locomotive::Wagon::AuthenticateCommand do |
| - | |
| - | let(:platform_url) { nil } |
| - | let(:email) { nil } |
| - | let(:password) { nil } |
| - | let(:shell) { nil } |
| - | let(:command) { described_class.new(platform_url, email, password, shell) } |
| - | |
| - | describe '#api_url' do |
| - | |
| - | subject { command.send(:api_url) } |
| - | |
| - | context 'naked domain' do |
| - | let(:platform_url) { 'http://www.myengine.com:3000/' } |
| - | it { is_expected.to eq('http://www.myengine.com:3000/locomotive/api/v3') } |
| - | end |
| - | |
| - | context 'localhost' do |
| - | let(:platform_url) { 'http://localhost:3000' } |
| - | it { is_expected.to eq('http://localhost:3000/locomotive/api/v3') } |
| - | end |
| - | |
| - | context 'including the official route to the API' do |
| - | |
| - | let(:platform_url) { 'http://www.myengine.com:3000/locomotive/api/v3' } |
| - | it { is_expected.to eq('http://www.myengine.com:3000/locomotive/api') } |
| - | |
| - | end |
| - | |
| - | context 'including another route to the API' do |
| - | |
| - | let(:platform_url) { 'http://www.myengine.com/admin/api' } |
| - | it { is_expected.to eq('http://www.myengine.com/admin/api') } |
| - | |
| - | end |
| - | |
| - | end |
| - | |
| - | end |
spec/unit/decorators/site_decorator_spec.rb
+34
-0
| @@ | @@ -0,0 +1,34 @@ |
| + | # encoding: utf-8 |
| + | |
| + | require 'spec_helper' |
| + | require 'ostruct' |
| + | require 'locomotive/wagon/decorators/site_decorator' |
| + | |
| + | describe Locomotive::Wagon::SiteDecorator do |
| + | |
| + | let(:site) { instance_double('Site', attributes) } |
| + | let(:decorator) { described_class.new(site) } |
| + | |
| + | describe '#domains' do |
| + | |
| + | let(:attributes) { { domains: ['acme.com', 'localhost'] } } |
| + | |
| + | subject { decorator.domains } |
| + | |
| + | it { is_expected.to eq ['acme.com'] } |
| + | |
| + | end |
| + | |
| + | describe '#to_hash' do |
| + | |
| + | let(:seo_title) { instance_double('I18nField', translations: { en: 'Hi', fr: 'Bonjour' }) } |
| + | let(:attributes) { { name: 'Acme', handle: nil, seo_title: seo_title } } |
| + | let(:site) { OpenStruct.new(attributes) } |
| + | |
| + | subject { decorator.to_hash } |
| + | |
| + | it { is_expected.to eq(name: 'Acme', seo_title: { en: 'Hi', fr: 'Bonjour' }) } |
| + | |
| + | end |
| + | |
| + | end |