compass/sass remote themeing via sftp/scp with alternate port - sass

I am trying to get compass/sass to watch changes on my local computer and reflect those changes remotely using a custom config.rb script. net::sftp works but my server requires a custom ssh port. I couldn't find any mods to make sftp work with an alternate port so im trying net:scp now, the problem is I dont know the proper command structure to upload using net:scp and wanted to see if someone can help me. Here is my code:
# Require any additional compass plugins here.
require 'net/ssh'
require 'net/scp'
# SFTP Connection Details - Does not support alternate ports os SSHKeys, but could with mods
remote_theme_dir_absolute = '/home2/trinsic/public_html/scottrlarson.com/sites/all/themes/ gateway_symbology_zen/css'
sftp_host = 'xxx.xxx.xxx.xxx' # Can be an IP
sftp_user = 'user' # SFTP Username
sftp_pass = 'password' # SFTP Password
# Callback to be used when a file change is written. This will upload to a remote WP install
on_stylesheet_saved do |filename|
$local_path_to_css_file = css_dir + '/' + File.basename(filename)
Net::SSH.start( sftp_host, sftp_user, {:password => sftp_pass,:port => 2222} ) do ssh.scp.upload! $local_path_to_css_file, remote_theme_dir_absolute + '/' + File.basename(filename)
end
puts ">>>> Compass is polling for changes. Press Ctrl-C to Stop"
end
#
# This file is only needed for Compass/Sass integration. If you are not using
# Compass, you may safely ignore or delete this file.
#
# If you'd like to learn more about Sass and Compass, see the sass/README.txt
# file for more information.
#
# Change this to :production when ready to deploy the CSS to the live server.
environment = :development
#environment = :production
# In development, we can turn on the FireSass-compatible debug_info.
firesass = false
#firesass = true
# Location of the theme's resources.
css_dir = "css"
sass_dir = "sass"
extensions_dir = "sass-extensions"
images_dir = "images"
javascripts_dir = "js"
# Require any additional compass plugins installed on your system.
#require 'ninesixty'
#require 'zen-grids'
# Assuming this theme is in sites/*/themes/THEMENAME, you can add the partials
# included with a module by uncommenting and modifying one of the lines below:
#add_import_path "../../../default/modules/FOO"
#add_import_path "../../../all/modules/FOO"
#add_import_path "../../../../modules/FOO"
##
## You probably don't need to edit anything below this.
##
# You can select your preferred output style here (can be overridden via the command line):
# output_style = :expanded or :nested or :compact or :compressed
output_style = (environment == :development) ? :expanded : :compressed
# To enable relative paths to assets via compass helper functions. Since Drupal
# themes can be installed in multiple locations, we don't need to worry about
# the absolute path to the theme from the server root.
relative_assets = true
# To disable debugging comments that display the original location of your selectors. Uncomment:
# line_comments = false
# Pass options to sass. For development, we turn on the FireSass-compatible
# debug_info if the firesass config variable above is true.
sass_options = (environment == :development && firesass == true) ? {:debug_info => true} : {}
I get an error when I run the command: compass watch:
NoMethodError on line ["17"] of K: undefined method `upload!' for #<Net::SSH::Co
nnection::Session:0x000000036bb220>
Run with --trace to see the full backtrace

I needed a solution for this too but did not find any satisfying answer anywhere.
After reading the Ruby Net::ssh documentation and some source of Compass, this is my solution to upload CSS and sourcemap to a remote SSH server with non-standard port and forced public-key authorisation:
First make sure you have the required gems installed
sudo gem install net-ssh net-sftp
then add this to your config.rb
# Add this to the first lines of your config.rb
require 'net/ssh'
require 'net/sftp'
...
# Your normal compass config comes here
...
# At the end of your config.rb add the config for the upload code
remote_theme_dir_absolute = '/path/to/my/remote/stylesheets'
sftp_host = 'ssh_host' # Can be an IP
sftp_user = 'ssh_user' # SFTP Username
on_stylesheet_saved do |filename|
# You can use the ssh-agent for authorisation.
# In this case you can remove the :passphrase from the config and set :use_agent => true.
Net::SFTP.start(
sftp_host,
sftp_user ,
:port => 10022,
:keys_only => true,
:keys => ['/path/to/my/private/id_rsa'],
:auth_methods => ['publickey'],
:passphrase => 'my_secret_passphrase',
:use_agent => false,
:verbose => :warn
) do |sftp|
puts sftp.upload! css_dir + '/app.css', remote_theme_dir_absolute + '/' + 'app.css'
end
end
on_sourcemap_saved do |filename|
# You can use the ssh-agent for authorisation.
# In this case you can remove the :passphrase from the config and set :use_agent true.
Net::SFTP.start(
sftp_host,
sftp_user ,
:port => 10022,
:keys_only => true,
:keys => ['/path/to/my/private/id_rsa'],
:auth_methods => ['publickey'],
:passphrase => 'my_secret_passphrase',
:use_agent => false,
:verbose => :warn
) do |sftp|
puts sftp.upload! css_dir + '/app.css.map', remote_theme_dir_absolute + '/' + 'app.css.map'
end
end
It was quite some trial and error until this worked for me.
Some points of failure were:
If no ssh-agent is available connection will fail until you set :ssh_agent => false explicitly
If you do not limit the available keys with :keys all available keys will be tried one after another. If you use the ssh-agent and have more than 3 keys installed chanches are high that the remote server will close the connection if you try too much keys that are not valid for the server you currently connect.
On any connection issue set verbosity level to :verbose => :debug to see what is going on. Remember to stop the compass watch and restart to ensure configuration changes apply.

Related

Rails 4.2: image paths have no fingerprint in production, Capistrano deployment

In development my all of my images, CSS and JS are loading fine. In production, my CSS and JS are loading fine. Background images load fine through CSS, and images written as:
image_tag "foo.png"
also load fine and show a fingerprint. However, images written as:
image_tag #test_question.question.image
are not fingerprinted in production (the image name is recorded in the database). However, this works fine in development.
In development I see:
<img src="/assets/picture1-a2bac24ba737cf267b5cc29f9fdaea33.jpg">
In production I see:
<img src="/images/picture1.jpg">
Assets including the images are compiled and fingerprinted in appropriate directories on my production server, they are just not fingerprinted or called correctly in the view. I am using Rails 4.2, nginx and unicorn, and deploying with Capistrano 3.2.
Edit:
I have image subdirectories. The following is in my initializers:
initializers/assets.rb
Dir.glob("#{Rails.root}/app/assets/images/**/").each do |path|
Rails.application.config.assets.paths << path
end
When I comment this out, the behaviour is the same in development as in production. So, I suppose that the problem is that this code is not working / being read in the production environment. Any suggestions?
environments/production.rb
config.cache_classes = true
config.eager_load = true
config.consider_all_requests_local = false
config.action_controller.perform_caching = true
config.assets.js_compressor = :uglifier
config.assets.css_compressor = :sass
config.assets.compile = false
config.assets.digest = true
config.assets.version = Digest::MD5.hexdigest(Date.new.to_s)
config.assets.initialize_on_precompile = true
config.i18n.fallbacks = true
deploy.rb
lock '3.2.1'
set :application, 'foobar'
set :deploy_user, 'deploy'
# Default branch is :master
# ask :branch, proc { `git rev-parse --abbrev-ref HEAD`.chomp }.call
# Default deploy_to directory is /var/www/my_app
# set :deploy_to, '/var/www/my_app'
set :deploy_to, "/home/#{fetch(:deploy_user)}/apps/#{fetch(:full_app_name)}"
# Default value for :scm is :git
set :scm, :git
set :repo_url, 'git#github.com:foobar/baz.git'
set :rbenv_type, :system
set :rbenv_ruby, '2.2.2'
set :rbenv_prefix, "RBENV_ROOT=#{fetch(:rbenv_path)} RBENV_VERSION=#{fetch(:rbenv_ruby)} #{fetch(:rbenv_path)}/bin/rbenv exec"
set :rbenv_map_bins, %w{rake gem bundle ruby rails}
set :keep_releases, 2
set :linked_files, %w{config/database.yml config/secrets.yml config/application.yml}
set :linked_dirs, %w{bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system}
# Default value for :format is :pretty
set :format, :pretty
# what specs should be run before deployment is allowed to
# continue, see lib/capistrano/tasks/run_tests.cap
set :tests, []
# which config files should be copied by deploy:setup_config
# see documentation in lib/capistrano/tasks/setup_config.cap
# for details of operations
set(:config_files, %w(
nginx.conf
log_rotation
monit
unicorn.rb
unicorn_init.sh
application.yml
database.yml
))
# which config files should be made executable after copying
# by deploy:setup_config
set(:executable_config_files, %w(
unicorn_init.sh
))
# files which need to be symlinked to other parts of the
# filesystem. For example nginx virtualhosts, log rotation
# init scripts etc.
set(:symlinks, [
{
source: "nginx.conf",
link: "/etc/nginx/sites-enabled/{{full_app_name}}"
},
{
source: "unicorn_init.sh",
link: "/etc/init.d/unicorn_{{full_app_name}}"
},
{
source: "log_rotation",
link: "/etc/logrotate.d/{{full_app_name}}"
},
{
source: "monit",
link: "/etc/monit/conf.d/{{full_app_name}}.conf"
}
])
namespace :deploy do
before :deploy, "deploy:check_revision"
# compile assets locally then rsync
#after 'deploy:symlink:shared', 'deploy:compile_assets_locally'
#after :finishing, 'deploy:cleanup'
# remove the default nginx configuration as it will tend
# to conflict with our configs.
before 'deploy:setup_config', 'nginx:remove_default_vhost'
# reload nginx to it will pick up any modified vhosts from
# setup_config
after 'deploy:setup_config', 'nginx:reload'
# Restart monit so it will pick up any monit configurations
# we've added
after 'deploy:setup_config', 'monit:restart'
# As of Capistrano 3.1, the `deploy:restart` task is not called
# automatically.
after 'deploy:publishing', 'deploy:restart'
after "deploy:restart", "deploy:cleanup"
end
I really can't see what the problem is here. Any suggestions?

rails mimic production asset precompile in development to resolve css compilation fail

I am trying to figure out why my application.css.scss file is not precompiling correctly on my staging environment. I have tried to replicate the error locally by replacing my local environments file to be the same as my staging one. Everything still works on development after precompiling (but not uglified which is not expected) even though I am using the staging environments settings for my local.
My settings are below
Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.
# Code is not reloaded between requests.
config.cache_classes = true
# Eager load code on boot. This eager loads most of Rails and
# your application in memory, allowing both threaded web servers
# and those relying on copy on write to perform better.
# Rake tasks automatically ignore this option for performance.
config.eager_load = true
# Full error reports are disabled and caching is turned on.
config.consider_all_requests_local = false
config.action_controller.perform_caching = true
# Enable Rack::Cache to put a simple HTTP cache in front of your application
# Add `rack-cache` to your Gemfile before enabling this.
# For large-scale production use, consider using a caching reverse proxy like nginx, varnish or squid.
# config.action_dispatch.rack_cache = true
# Disable Rails's static asset server (Apache or nginx will already do this).
config.serve_static_assets = false
# Compress JavaScripts and CSS.
config.assets.js_compressor = :uglifier
# config.assets.css_compressor = :sass
# Do not fallback to assets pipeline if a precompiled asset is missed.
config.assets.compile = false
# Generate digests for assets URLs.
config.assets.digest = true
# `config.assets.precompile` has moved to config/initializers/assets.rb
# Specifies the header that your server uses for sending files.
# config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
# config.force_ssl = true
# Set to :debug to see everything in the log.
config.log_level = :info
# Prepend all log lines with the following tags.
# config.log_tags = [ :subdomain, :uuid ]
# Use a different logger for distributed setups.
# config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new)
# Use a different cache store in production.
# config.cache_store = :mem_cache_store
# Enable serving of images, stylesheets, and JavaScripts from an asset server.
# config.action_controller.asset_host = "http://assets.example.com"
# Precompile additional assets.
# application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
# config.assets.precompile += %w( search.js )
# Ignore bad email addresses and do not raise email delivery errors.
# Set this to true and configure the email server for immediate delivery to raise delivery errors.
config.action_mailer.raise_delivery_errors = false
config.action_mailer.default_url_options = { :host => '' }
config.action_mailer.perform_deliveries = true
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
:address => "smtp.gmail.com",
:port => 587,
:user_name => '',
:password => '',
:authentication => 'plain',
:enable_starttls_auto => true }
# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
# the I18n.default_locale when a translation cannot be found).
config.i18n.fallbacks = true
# Send deprecation notices to registered listeners.
config.active_support.deprecation = :notify
# Disable automatic flushing of the log to improve performance.
# config.autoflush_log = false
# Use default logging formatter so that PID and timestamp are not suppressed.
config.log_formatter = ::Logger::Formatter.new
# Do not dump schema after migrations.
config.active_record.dump_schema_after_migration = false
end
My application.html file
doctype html
html
head
meta[name="viewport" content="width=device-width, initial-scale=1.0"]
title
= content_for?(:title) ? yield(:title) : 'Phoenix'
meta name="description" content="#{content_for?(:description) ? yield(:description) : 'Phoenix'}"
= stylesheet_link_tag "application", :media => 'all'
= stylesheet_link_tag 'http://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,400,300,600,700'
= javascript_include_tag 'vendor/modernizr'
= javascript_include_tag 'application'
= csrf_meta_tags
body
.off-canvas-wrap data-offcanvas=""
.inner-wrap
nav.tab-bar
- if user_signed_in?
section.left-small
a.left-off-canvas-toggle.menu-icon
span
section.middle.tab-bar-section
span.left
= link_to 'Phoenix', root_path
- if user_signed_in?
.right
= link_to current_user.email, user_path(current_user.id)
= " ".html_safe
= link_to fa_icon("sign-out"), destroy_user_session_path, id:"sign-out", method: :delete
- else
span.right
= link_to 'Sign in', new_user_session_path
- if user_signed_in?
aside.left-off-canvas-menu
ul.off-canvas-list
= render 'layouts/navigation'
section.main-section
.full-width-row
.columns class=(user_signed_in? ? 'medium-10 small-centered' : 'medium-5 small-centered')
main[role="main"]
= render 'layouts/messages'
= yield
a.exit-off-canvas
My application.css.scss file
/*
* This is a manifest file that'll be compiled into application.css, which will include all the files
* listed below.
*
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
* or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
*
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
* compiled file so the styles you add here take precedence over styles defined in any styles
* defined in the other CSS/SCSS files in this directory. It is generally better to create a new
* file per style scope.
*
*= require_self
*= require_tree ../../../vendor/assets/stylesheets/.
*= require selectize
*= require selectize.default
*= require chosen
*/
#import 'foundation_and_overrides';
#import 'mixins';
#import 'font-awesome';
#import 'layout';
#import 'shame';
Note
I have cleared my assets using rake assets:clean RAILS_ENV=[environment] and rake assets:clobber RAILS_ENV=[environment]
I have also tried to delete the files manually
I have restarted the server on multiple occasions
This has been an intermitted error that seems to have popped up a couple of times, but it randomly disappears
So I guess I have two questions
Why can't I replicate this locally? (this would be a huge help)
Why is it happening in the first
place?
Any input appreciated.
After more investigation and looking into the public/assets more it seems the css file was being generated, but the URL was incorrect to the file. It seems I needed to update the default css_compressor to sass
config.assets.css_compressor = :sass
I would have thought this would be defaulted already, but I guess not.
Still not sure why I can't replicate this locally though

Ruby compass config file overrides

I'm looking for a way to override the compass config.rb variables / constants by checking for a local file and including it.
Using this method (rather than the current option of defining the config file to use when calling compass) would mean we could have a set of defaults for all developers and build system and allow devs to override these if necessary for their own local setup.
Unfortunately I don't know Ruby at all and a simple check for a file and requiring it in config.rb doesn't seem to override the original settings. My current coding attempts are below. Please could someone explain to me what I'm doing wrong here?
config.rb
# Compass configuration file.
# Require any additional compass plugins here.
# Sass / Compass paths
http_path = "/"
css_dir = "../../web/stylesheets"
sass_dir = "sass"
images_dir = "../../web/images"
javascripts_dir = "javascript"
fonts_dir = "fonts"
# Output style environment can be forced on build using -e
output_style = (environment == :production) ? :compressed : :expanded
# To enable relative paths to assets via compass helper functions. Uncomment:
# relative_assets = true
# Disable the compass cache method - we use our own methods.
asset_cache_buster = :none
line_comments = false
color_output = false
preferred_syntax = :scss
# Define the location of a the compass / sass cache directory.
cache_path = "/tmp/compass-cache"
# Add shared sass path to make it easier to include assets.
add_import_path = "../shared/sass"
# TODO: Check for a local config file - use this to extend/override this config file.
$localConfig = File.join(File.dirname(__FILE__), "config.local.rb")
require $localConfig if File.exist?($localConfig) and File.file?($localConfig)
config.local.rb
# Additional custom Compass Configuration file.
# Require any additional compass plugins here.
line_comments = true
cache_path = "/Users/jwestbrook/Sites/compass-cache"
sass_options = {
:debug_info => true,
:sourcemap => true
}
enable_sourcemaps = true
So I'm no Ruby developer but the following should work...
The idea is we have the standard config.rb file and a config.production.rb file with all our standard production settings as a hash/associative array. We then reference these hash keys as the compass constants in config.rb.
If a developer wants to override any settings then they just add a config.development.rb file in the same location as config.rb and config.production.rb and define their overrides.
Example
config.rb
require 'compass/import-once/activate'
# Require any additional compass plugins here.
# Define the paths for config files.
productionSettings = File.join(File.dirname(__FILE__), "config.production.rb")
developmentSettings = File.join(File.dirname(__FILE__), "config.development.rb")
# Include the production config
require productionSettings if File.exist?(productionSettings) and File.file?(productionSettings)
# Set the compass settings to productionSettings $configSettings
compassSettings = $configSettings
# If a development config file exists include it and merge it's $configSettings
# with the current compassSettings
if File.exist?(developmentSettings) and File.file?(developmentSettings)
require developmentSettings
compassSettings = compassSettings.merge($configSettings)
end
# Compass settings. If statements to prevent errors if a key doesn't exist.
# Note that any additional settings you add to production or development
# will need to be referenced here else compass won't pick them up.
http_path = compassSettings['http_path'] if compassSettings.key?('http_path')
css_dir = compassSettings['css_dir'] if compassSettings.key?('css_dir')
sass_dir = compassSettings['sass_dir'] if compassSettings.key?('sass_dir')
images_dir = compassSettings['images_dir'] if compassSettings.key?('images_dir')
javascripts_dir = compassSettings['javascripts_dir'] if compassSettings.key?('javascripts_dir')
fonts_dir = compassSettings['fonts_dir'] if compassSettings.key?('fonts_dir')
output_style = compassSettings['output_style'] if compassSettings.key?('output_style')
relative_assets = compassSettings['relative_assets'] if compassSettings.key?('relative_assets')
line_comments = compassSettings['line_comments'] if compassSettings.key?('line_comments')
color_output = compassSettings['color_output'] if compassSettings.key?('color_output')
preferred_syntax = compassSettings['preferred_syntax'] if compassSettings.key?('preferred_syntax')
sourcemap = compassSettings['sourcemap'] if compassSettings.key?('sourcemap')
cache_path = compassSettings['cache_path'] if compassSettings.key?('cache_path')
config.production.rb
$configSettings = {
'http_path' => "/",
'css_dir' => "css",
'sass_dir' => "sass",
'images_dir' => "images",
'javascripts_dir' => "scripts",
'fonts_dir' => "fonts",
'preferred_syntax' => :scss,
'color_output' => false,
'output_style' => :compressed,
'sourcemap' => false,
}
config.development.rb
$configSettings = {
'cache_path' => '/tmp/sass-cache',
'output_style' => :expanded,
'sourcemap' => true,
}

Bundler configuration to compile sass files

I am getting an error with compass watching my directory correctly but fails to generate my output. I am thinking it has to do with either my GEMFILE or compass.rb config file.
ERROR: Guard::Compass failed to achieve its <run_on_change>, exception was:
Compass::Error: Nothing to compile. If you're trying to start a new project, you have left off the directory argument.
Guardfile
# More info at
# https://github.com/guard/guard#readme
# https://github.com/guard/guard/wiki/Guardfile-examples
# Launch Guard like this: [bundle exec] guard -g ui
group :ui do
# guard :bundler,
# :hide_success => true do
# watch('Gemfile')
# end
guard 'compass',
:output => 'client/css',
:workdir => 'source/sass',
:configuration_file => 'config/compass.rb',
:hide_success => true do
#watch('source/sass/(.*)\.scss')
watch(/source\/sass\/(.*)\.s[ac]ss/)
end
end
And my compass.rb file
require 'sass'
require 'compass'
# Require any additional compass plugins here.
# Get the directory that this configuration file exists in
dir_src = File.dirname(__FILE__)
# Set this to the root of your project when deployed:
http_path = "/"
project_path = File.join(dir_src, "../", "")
sass_dir = "source/sass"
sass_path = sass_dir
css_dir = "client/css"
#css_path = File.join(dir_src, "client", "css")
#images_dir = "img"
#images_path = File.join(dir_src, "../public", "img")
#javascripts_dir = "js"
#javascripts_path = File.join(dir_src, "../public", "js")
#Environment
#environment = :development
# You can select your preferred output style here (can be overridden via the command line):
# output_style = :expanded or :nested or :compact or :compressed
output_style = :expanded
# To enable relative paths to assets via compass helper functions. Uncomment:
relative_assets = true
# To disable debugging comments that display the original location of your selectors. Uncomment:
line_comments = false
# If you prefer the indented syntax, you might want to regenerate this
# project again passing --syntax sass, or you can uncomment this:
#preferred_syntax = :sass
# and then run:
# sass-convert -R --from scss --to sass sass scss && rm -rf sass && mv scss sass
debug_info = false
My folder structure is as follows with my top level directory.
project/
client/
css
source/
sass/
Not sure why compass fails to compile?
Edit:
The sass_path should be an absolute path. In your configuration, it's relative.
Try commenting it out, you already have sass_dir.
If this doesn't help, please share your project directory structure.

Carrierwave Gem - Heroku - Fog Gem configuration - Giving name error

I am a little lost with Heroku and Carrierwave Gem. I have read the WIKI, Read me and searched the net and i admit, i need help. Everything well on local but Heroku crushes the application.
///ERROR MESSAGE FROM HEROKU LOGS
2012-01-03T17:33:26+00:00 app[web.1]: /app/vendor/bundle/ruby/1.9.1/gems/carrierwave-0.5.8/lib/carrierwave/uploader/configuration.rb:91:in `eval': uninitialized constant CarrierWave::Storage::Fog (NameError
///GEM FILE
gem "fog"
gem 'carrierwave'
/app/uploaders/avatar_uploader.rb
storage :fog
/config/initializers/carrierwave.rb
CarrierWave.configure do |config|
config.fog_credentials = {
:provider => 'AWS',
:aws_access_key_id => 'XXXX',
:aws_secret_access_key => 'XXXX',
:region => 'eu-west-1' # optional, defaults to 'us-east-1'
}
config.fog_directory = 'site_images' # required
config.fog_public = true # optional, defaults to true
config.fog_attributes = {'Cache-Control'=>'max-age=315576000'} # optional, defaults to {}
end
When i change the storage to file not fog, then i do not get errors. Are there any other fog settings i am skipping or missing. Any help greatly appreciated. Do i need to create a separate document with fog settings?
It might not be the solution to your problem but it is worth a try adding
config.cache_dir = "#{Rails.root}/tmp/uploads". That will help keep the files around until they are uploaded to you S3 bucket.
If that does not help can you also post your uploader file?

Resources