Ruby Gem: Install configuration files to the user-home directory - ruby

I have to make a REST-Client in Ruby.
The client must be runnable from the command-line like a binary and also it must be "requirable" in a ruby script and provide different functions.
My gemspec does exactly what it should.
But i have no idea how to install a configuration file (YAML) in the user-home folder?
The config file should be in the user directory to provide easy access for the user.
Is this even possible?
Should i check on the first run if there is a config file and create it?
Can i execute an own installation routine while installing a gem?
I did exactly the same thing in Python and it worked fine, so the Ruby client should behave similar.

For such decisions, I wrote gem persey. If you look at the description of the use of this gem, you can see that it provides what you expect:
# Rails.root are not initialized here
app_path = File.expand_path('../../', __FILE__)
# ...
# config with secret keys
# you don't want store this config in repository and copy to secret folder on host machine
my_secret_key_config = '/home/user/secret/keys.yml'
# ...
# Persey.init ENV["environment"] do # set current environment
Persey.init Rails.env do # set current environment
source :yaml, my_secret_key_config, :secret # no comments. It's secret!
env :production do
# ...
end
env :development, :parent => :production do
# ...
end
end

Related

Mina Deploy uses wrong user

I got some issue with the gem 'mina'. If I do set :user, 'username', he tries to connect to the server via Username#xxx.... wich is not working if the user is not existing. My PC is name Username. So mina setup and mina deploy are not working.
Does someone know a solution?.
Thanks
Best regards
Matze
EDIT:
Gemfile:
gem 'mina'
After that I run bundle install and mina init
deploy.rb:
require 'mina/rails'
require 'mina/git'
# require 'mina/rbenv' # for rbenv support. (https://rbenv.org)
require 'mina/rvm' # for rvm support. (https://rvm.io)
# Basic settings:
# domain - The hostname to SSH to.
# deploy_to - Path to deploy into.
# repository - Git repo to clone from. (needed by mina/git)
# branch - Branch name to deploy. (needed by mina/git)
set :user, "user"
set :application_name, 'appname'
set :domain, 'xx.xxx.xxx.xxx'
set :deploy_to, '/var/www/user/appname'
set :repository, 'user#xx.xxx.xxx.xxx:/home/user/git/appname.git'
set :branch, 'master'
# Optional settings:
# set :user, 'user' # Username in the server to SSH to.
# set :port, '30000' # SSH port number.
# set :forward_agent, true # SSH forward_agent.
# Shared dirs and files will be symlinked into the app-folder by the 'deploy:link_shared_paths' step.
# Some plugins already add folders to shared_dirs like `mina/rails` add `public/assets`, `vendor/bundle` and many more
# run `mina -d` to see all folders and files already included in `shared_dirs` and `shared_files`
# set :shared_dirs, fetch(:shared_dirs, []).push('public/assets')
set :shared_files, fetch(:shared_files, []).push('config/database.yml', 'config/secrets.yml')
# This task is the environment that is loaded for all remote run commands, such as
# `mina deploy` or `mina rake`.
task :remote_environment do
# If you're using rbenv, use this to load the rbenv environment.
# Be sure to commit your .ruby-version or .rbenv-version to your repository.
# invoke :'rbenv:load'
# For those using RVM, use this to load an RVM version#gemset.
# invoke :'rvm:use', 'ruby-1.9.3-p125#default'
end
# Put any custom commands you need to run at setup
# All paths in `shared_dirs` and `shared_paths` will be created on their own.
task :setup do
# command %{rbenv install 2.3.0 --skip-existing}
end
desc "Deploys the current version to the server."
task :deploy do
# uncomment this line to make sure you pushed your local branch to the remote origin
# invoke :'git:ensure_pushed'
deploy do
# Put things that will set up an empty directory into a fully set-up
# instance of your project.
invoke :'git:clone'
invoke :'deploy:link_shared_paths'
invoke :'bundle:install'
invoke :'rails:db_migrate'
invoke :'rails:assets_precompile'
invoke :'deploy:cleanup'
on :launch do
in_path(fetch(:current_path)) do
command %{mkdir -p tmp/}
command %{touch tmp/restart.txt}
end
end
end
# you can use `run :local` to run tasks on local machine before of after the deploy scripts
# run(:local){ say 'done' }
end
# For help in making your deploy script, see the Mina documentation:
#
# - https://github.com/mina-deploy/mina/tree/master/docs
set :execution_mode, :exec if RbConfig::CONFIG['host_os'] =~ /mswin|mingw/
When I run now mina setup he print that:
$ mina setup
User#xx.xxx.xxx.xxx's password:
SSH Auth key working fine and git working fine he just puts User instead of user before the ip, what is not working because the user just exists with small letter. But my working machine is named User.

Figaro - Rails Missing secret_key_base for development

I've just switched to using the Figaro gem v1.0.0 with Rails 4.1.6.
Since deleting my secrets.yml file I now get the error:
Unexpected error while processing request: Missing secret_key_base for 'development' environment, set this value in config/secrets.yml
Do i still need the secrets.yml file - isn't this the job of Figaro's application.yml file?
My application.yml file is like
development:
secret_key_base: 56....
Looking into the Railties gem at https://github.com/rails/rails/blob/master/railties/lib/rails/application.rb you can see the secrets method defined which includes a fallback for secret_key_base
def secrets #:nodoc:
#secrets ||= begin
secrets = ActiveSupport::OrderedOptions.new
yaml = config.paths["config/secrets"].first
if File.exist?(yaml)
require "erb"
all_secrets = YAML.load(ERB.new(IO.read(yaml)).result) || {}
env_secrets = all_secrets[Rails.env]
secrets.merge!(env_secrets.symbolize_keys) if env_secrets
end
# Fallback to config.secret_key_base if secrets.secret_key_base isn't set
secrets.secret_key_base ||= config.secret_key_base
secrets
end
end
In config/application.rb adding the following resolves the issue
config.secret_key_base = Figaro.env.secret_key_base
I have never used Figaro gem but try these, create the config/secret.yml file and inside write:
development:
secret_key_base: <%= ENV['secret_key_base'] %>
I was just informed that as of Rails 4.1.x, config/secrets.yml does need to be uploaded to heroku. Rails will no longer look directly at its ENV in order to find its secret_key_base.
So secrets.yml needs to come off of the .gitignore file, and your project would need to be recommited and re-pushed to heroku.
(secrets.yml would still get its values from heroku's ENV, which would still be loaded up via Figaro the same way as before - figaro heroku:set -e production. Use heroku config to get a nice quick look at your ENV variables to confirm they are there)

Environment variables locally and Heroku

I have a sinatra app in which i have a yml file to set environment variables, i call them using this method
module MyConfig
def config
environment = ENV["RACK_ENV"] || "development"
YAML.load_file("./config/config.yml")[environment]
end
end
so when i want to use a variable i do this for example
aws_access_key_id = config['aws_access_key']
I have a .gitignore file that ignores config.yml when pushing to github for example.So when I push to heroku these environment variables will not be accessible?
So this leaves me with using the heroku way of setting them like so
heroku config:add aws_access_key= myapikey
but heroku accesses these like
aws_access_key_id = ENV['aws_access_key']
How can i set my dev environment to use method config and heroku use ENV, am i looking at this the wrong way? or does my config method do this for me?
Any help appreciated
RAKEFILE
require 'active_support/core_ext'
require './config/config.rb'
require 'bundler/setup'
Bundler.require(:default)
include MyConfig
AssetSync.configure do |con|
con.fog_provider = 'AWS'
con.fog_region = 'eu-west-1'
con.fog_directory = config['fog_directory']
con.aws_access_key_id = config['aws_access_key']
con.aws_secret_access_key = config['aws_secret_key']
con.prefix = "assets"
con.public_path = Pathname("./public")
end
namespace :assets do
desc "Precompile assets"
task :precompile do
AssetSync.sync
end
end
Update:
I now use the dotenv gem instead of the example below. So instead of ignoring the env.rb file, I now ignore the .env file with Git.
Original post:
Try this,
# /env.rb
ENV['aws_bucket'] = 'my_bucket'
ENV['aws_access_key'] = 'my_access_key'
ENV['aws_access_secret'] = 'my_access_secret'
This file sets the same ENV values as heroku config would do.
# /config.rb
require './env' if File.exists?('env.rb')
The env.rb will only get required if it exists.
# /.gitignore
/env.rb
The env.rb has been added to the .gitignore file so it isn't kept in Git.
You would then access the values using ENV['key'] instead of config['key'].
You might need to change the path to the env.rb if it's not in the same directory as the config.rb file.
EDIT:
From looking at your Rakefile in the previous question, you need to change it to this:
# Rakefile
require 'bundler/setup'
Bundler.require(:default)
require './env' if File.exists?('env.rb')
AssetSync.configure do |con|
con.fog_provider = 'AWS'
con.fog_region = 'eu-west-1'
con.fog_directory = ENV['aws_bucket']
con.aws_access_key_id = ENV['aws_access_key']
con.aws_secret_access_key = ENV['aws_access_secret']
con.prefix = "assets"
con.public_path = Pathname("./public")
end
namespace :assets do
desc "Precompile assets"
task :precompile do
AssetSync.sync
end
end
I've assumed that the only method in /config/config.rb was the config method so I've removed the,
require './config/config.rb'
include MyConfig
And swapped the config[key] for the ENV[key] values defined in env.rb. You may need to change the key names to match up.
You could delete the yaml, and describe the environment variables in a .env file then start your app with foreman start. See https://devcenter.heroku.com/articles/config-vars#local-setup
Or keep your hybrid system, where you load a yaml in dev, and use environment variables on heroku.
I do something similar to Sam's suggestion, but a little bit different. I have a YAML config file too, but I wrap the reading of it in a Rake task, which then runs the app.
# in the Rakefile
require 'yaml'
def set_connstring
s = %Q!postgres://#{ENV["DB_APP"]}#localhost/#{ENV["DB_APP"]}!
ENV['DATABASE_URL'] ||= ENV["RACK_ENV"] == "test" ? "#{s}.test" : s
end
def basic_environment
warn " Setting up environment..."
file = File.expand_path( File.join File.dirname(__FILE__), "./config.yml" )
if File.exist? file
YAML.load_file(file).each do |k,v|
warn "-> #{k}"
ENV[k.upcase] = v
end
end
set_connstring()
end
namespace :app do
desc "Set up the environment locally"
task :environment do
basic_environment()
end
desc "Run the app locally"
task :run_local => "app:environment" do
exec "bin/rackup config.ru -p #{ENV['RUN_LOCAL_PORT']}"
end
end
It means I can run it locally without any code inside the app to deal with this.
Edit: a quick aside, I notice you have Bundler.require(:default) in your Rakefile. If you use bundle install --binstubs then Bundler installs all executables into a dir named "bin/" within the project. Then, if you run any of those executables they automatically use the libraries installed by Bundler, no need to require via Bundler. See http://gembundler.com/v1.2/man/bundle-exec.1.html.
Exporting directly from heroku admin:
Settings -> Reveal Config Vars
Then open browser js console, paste this and type enter...
k=[];
$(".config-var-list input").map(function(y, x){k.push($(x).val())});
v=[];
$(".config-var-list textarea").map(function(y, x){v.push($(x).val())});
ret="";
k.map(function(x, i){ret+=k[i]+"\t"+v[2*i]+"\n"});
console.info(ret);

JRUBY - RAILS 3 - TOMCAT 7 Deploy failed

I have my rails 3 app. This work fine in netbeans with webrick.
I create this application with:
Jruby jruby 1.6.5.1 (ruby-1.8.7-p330)
Rails 3.1.3
My bundle work fine.
Mi gemfile:
gem 'rails', '3.1.3'
gem 'dynamic_form'
gem 'activerecord-jdbcmysql-adapter'
gem 'jruby-openssl'
gem 'json'
group :assets do
gem 'sass', '~> 3.1.12'
gem 'sass-rails', '~> 3.1.5'
gem 'coffee-rails', '~> 3.1.1'
gem 'uglifier', '>= 1.0.3'
end
gem 'jquery-rails'
For create .war file from application, I have installed with bundle all gem required.
I have installed wrable and run
wrable config
and then
wrable
This create the .war file.
I put this file on the webapps tomcat7 directory and start the server.
Server starting fine, catalina.out logs no errors but...
When I try to go at the address when tomcat manager says is my application, I have more time to attendo for view just a withe page. the application name is "cameraAccreditiGiornalisti". So, the address is localhost:8080/cameraAccreditiGiornalisti => white page!
I read all guides in the web but I not say where is the problem!! Not have a log to look and the white page... no error!
Please help!
I have the same problem, I found out that war file does not include web.xml file, which is necessary for Tomcat to start up the webapp. I did not found any info why warble does not generate that file, as it should.
my problem solved... I read a wrong log file.... Maybe for your problem check the file warble.rb in projectdirectory/config. This is my and work:
# Disable Rake-environment-task framework detection by uncommenting/setting to false
# Warbler.framework_detection = false
# Warbler web application assembly configuration file
Warbler::Config.new do |config|
# Features: additional options controlling how the jar is built.
# Currently the following features are supported:
# - gemjar: package the gem repository in a jar file in WEB-INF/lib
# - executable: embed a web server and make the war executable
# - compiled: compile .rb files to .class files
# config.features = %w(gemjar)
# Application directories to be included in the webapp.
config.dirs = %w(app config lib log vendor tmp)
# Additional files/directories to include, above those in config.dirs
# config.includes = FileList["db"]
# Additional files/directories to exclude
# config.excludes = FileList["lib/tasks/*"]
# Additional Java .jar files to include. Note that if .jar files are placed
# in lib (and not otherwise excluded) then they need not be mentioned here.
# JRuby and JRuby-Rack are pre-loaded in this list. Be sure to include your
# own versions if you directly set the value
# config.java_libs += FileList["lib/java/*.jar"]
# Loose Java classes and miscellaneous files to be included.
# config.java_classes = FileList["target/classes/**.*"]
#config.java_classes = FileList["log4j.properties"]
# One or more pathmaps defining how the java classes should be copied into
# the archive. The example pathmap below accompanies the java_classes
# configuration above. See http://rake.rubyforge.org/classes/String.html#M000017
# for details of how to specify a pathmap.
# config.pathmaps.java_classes << "%{target/classes/,}p"
# Bundler support is built-in. If Warbler finds a Gemfile in the
# project directory, it will be used to collect the gems to bundle
# in your application. If you wish to explicitly disable this
# functionality, uncomment here.
# config.bundler = false
# An array of Bundler groups to avoid including in the war file.
# Defaults to ["development", "test"].
# config.bundle_without = []
# Other gems to be included. If you don't use Bundler or a gemspec
# file, you need to tell Warbler which gems your application needs
# so that they can be packaged in the archive.
# For Rails applications, the Rails gems are included by default
# unless the vendor/rails directory is present.
# config.gems += ["activerecord-jdbcmysql-adapter", "jruby-openssl"]
# config.gems << "tzinfo"
config.gems += ["activerecord-jdbcmysql-adapter", "jruby-openssl"]
# Uncomment this if you don't want to package rails gem.
# config.gems -= ["rails"]
# The most recent versions of gems are used.
# You can specify versions of gems by using a hash assignment:
#
config.gems["rails"] = "3.2.1"
# You can also use regexps or Gem::Dependency objects for flexibility or
# finer-grained control.
# config.gems << /^merb-/
# config.gems << Gem::Dependency.new("merb-core", "= 0.9.3")
# Include gem dependencies not mentioned specifically. Default is
# true, uncomment to turn off.
# config.gem_dependencies = false
# Array of regular expressions matching relative paths in gems to be
# excluded from the war. Defaults to empty, but you can set it like
# below, which excludes test files.
# config.gem_excludes = [/^(test|spec)\//]
# Pathmaps for controlling how application files are copied into the archive
# config.pathmaps.application = ["WEB-INF/%p"]
# Name of the archive (without the extension). Defaults to the basename
# of the project directory.
# config.jar_name = "mywar"
# Name of the MANIFEST.MF template for the war file. Defaults to a simple
# MANIFEST.MF that contains the version of Warbler used to create the war file.
# config.manifest_file = "config/MANIFEST.MF"
# When using the 'compiled' feature and specified, only these Ruby
# files will be compiled. Default is to compile all \.rb files in
# the application.
# config.compiled_ruby_files = FileList['app/**/*.rb']
# === War files only below here ===
# Path to the pre-bundled gem directory inside the war file. Default
# is 'WEB-INF/gems'. Specify path if gems are already bundled
# before running Warbler. This also sets 'gem.path' inside web.xml.
# config.gem_path = "WEB-INF/vendor/bundler_gems"
# Files for WEB-INF directory (next to web.xml). This contains
# web.xml by default. If there is an .erb-File it will be processed
# with webxml-config. You may want to exclude this file via
# config.excludes.
# config.webinf_files += FileList["jboss-web.xml"]
# Files to be included in the root of the webapp. Note that files in public
# will have the leading 'public/' part of the path stripped during staging.
# config.public_html = FileList["public/**/*", "doc/**/*"]
# Pathmaps for controlling how public HTML files are copied into the .war
# config.pathmaps.public_html = ["%{public/,}p"]
# Value of RAILS_ENV for the webapp -- default as shown below
config.webxml.rails.env = ENV['RAILS_ENV'] || 'production'
# Application booter to use, one of :rack, :rails, or :merb (autodetected by default)
# config.webxml.booter = :rails
# Set JRuby to run in 1.9 mode.
# config.webxml.jruby.compat.version = "1.9"
# When using the :rack booter, "Rackup" script to use.
# - For 'rackup.path', the value points to the location of the rackup
# script in the web archive file. You need to make sure this file
# gets included in the war, possibly by adding it to config.includes
# or config.webinf_files above.
# - For 'rackup', the rackup script you provide as an inline string
# is simply embedded in web.xml.
# The script is evaluated in a Rack::Builder to load the application.
# Examples:
# config.webxml.rackup.path = 'WEB-INF/hello.ru'
# config.webxml.rackup = %{require './lib/demo'; run Rack::Adapter::Camping.new(Demo)}
# config.webxml.rackup = require 'cgi' && CGI::escapeHTML(File.read("config.ru"))
# Control the pool of Rails runtimes. Leaving unspecified means
# the pool will grow as needed to service requests. It is recommended
# that you fix these values when running a production server!
# config.webxml.jruby.min.runtimes = 2
# config.webxml.jruby.max.runtimes = 4
config.webxml.jruby.min.runtimes = 2
config.webxml.jruby.max.runtimes = 4
# JNDI data source name
# config.webxml.jndi = 'jdbc/rails'
end

Is there a better way to run a capistrano task from within rake?

I have a set of rake tasks where I need to invoke capistrano at some point. Edwin Goei's blog suggests shelling out to capistrano via "sh".
Is there a simpler way? It would seem you should be able to call the appropriate tasks programmatically. Thanks in advance.
Yes, Capistrano has programmatic access to the command-line components. If you want to call them from a rake task, though, you need to do a little extra work.
task :deploy
require 'rubygems'
require 'capistrano'
require 'capistrano/cli'
parameters = ["deploy"] # this is an array of the strings that come after
# cap on the command line. e.g.,
# ["deploy", "-S", "revision=1024"] gives you local var
# revision in your deploy.rb.
# The following is required ONLY when you run Capistrano 2+ from Rake,
# because Rake adds the methods from FileUtils to Object. FileUtils includes
# a method called symlink which interferes with Capistrano's symlink task.
Capistrano::Configuration::Namespaces::Namespace.class_eval { undef :symlink }
Capistrano::CLI.parse(parameters).execute!
end
For capistrano 3:
http://capistranorb.com/documentation/advanced-features/capistrano-pure-ruby/
require 'capistrano/all'
stages = "production"
set :application, 'my_app_name'
set :repo_url, 'git#github.com:capistrano/capistrano.git'
set :deploy_to, '/var/www/'
set :stage, :production
role :app, %w{}
require 'capistrano/setup'
require 'capistrano/deploy'
Dir.glob('capistrano/tasks/*.cap').each { |r| import r }
Capistrano::Application.invoke("production")
Capistrano::Application.invoke("deploy")
Jonathan, your mileage may vary by doing something like set(:shell, false) to stop capistrano running tasks in a sub-sh-shell.
Just a thought, feel free to ping me if you need a hand though.

Resources