I have some cucumber tests that I'm writing, and to test different scenarios I setup a config.yml file. I load it in in my env.rb using:
require 'calabash-cucumber/cucumber'
require 'yaml'
# Config file to hold user settings
#CONFIG = YAML::load_file(File.join(File.dirname(File.expand_path(__FILE__)), 'config.yml'))
CONFIG = YAML.load_file("features/support/config.yml")
The commented out line is another variation I've tried to load the file.
When I call the data, I do so like this:
#userName = CONFIG[env.to_sym][side.to_sym][type.to_sym][:username]
Yet, when it gets to this line, it gives me the following error:
"undefined method '[]' for nil:NilClass (NoMethodError)"
(The [] is an empty square box in the console.)
I'm not sure how to rectify this issue, I'm 99% sure I'm loading the YAML file correctly and using it correctly.
Any ideas or suggestions would be great!
Edit: Sample YAML data:
:env:
:side:
type:
:username: "username"
Say you have config.yml file:
env:
side:
type:
username: 'User'
YAML.load_file() won't symbolize hash by default, so you need to access values using string, not symbols.
puts #userName = CONFIG['env']['side']['type']['username']
#=> User
Update:
As mentioned by the Tin Man, it depends what is your YML file look like.
Loading this yml file would produce symbolized hash:
:env:
:side:
:type:
:username: 'User'
So if you want to access username key:
#userName = CONFIG[:env][:side][:type][:username]
Related
I would like to access Rails.application.secrets as an object till its deeper length.
Example: ../config/secrets.yml
development:
secret_key_base: ""
my_data:
user_email: "abc#example.io"
external_service:
remote:
password: ""
local:
password: ""
Presently Remote password of an external service is fetched using:
Rails.application.secrets.my_data[:external_service][:remote][:password]
Instead I would like to access it as below:
Rails.application.secrets.my_data.external_service.remote.password
Is there a way that I can configure my application to behave in above format?
Note:
Only config/secrets.yml must be affected
Please specify the file path/name where the configurations must be changed/added
Also suggest if there is an alternate way(gem, etc)
You might be able to put this in an initializer and achieve what you're looking for:
Rails.application.secrets = JSON.parse(Rails.application.secrets.to_json, object_class: OpenStruct)
In this blog post he gives this example of a Ruby config file.
config do
allow ['server.com', `hostname`.strip]
vhost 'api.server.com' do
path ‘/usr/local/api’
end
vhost 'www.server.com' do
path '/usr/local/web'
end
%w{wiki blog support}.each do |host|
vhost "#{host}.server.com" do
path "/usr/local/#{host}"
end
end
end
I think of a hash after a config file have been loaded, but maybe that is not how this type of configs are intended for...
Update
If I execute it, I get
$ ruby config.rb
config.rb:2:in `<main>': undefined method `config' for main:Object (NoMethodError)
Question
What Ruby code is needed to parse and dump the content of this config file?
That config example is not directly loadable and, if I understand the blog post author correctly, it's not meant to be either so there's no easy way of loading/parsing that example.
The key part is in the blog post where he states "build simple DSLs to design semantically robust config files without the underlying ruby being conspicuous" (my emphasis). The 'underlying ruby' I take to mean the code that enables the DSL elements you're seeing such as 'config' and 'vhost'.
Your original question was, however, what code is required to load that config - below is a sample of something would work, full implementation is up to you and tbh I'm pretty sure there are cleaner, "better" ways of doing the same.
class AppConfig
attr_accessor :hosts
def allow(hosts)
#hosts = hosts
end
def vhost(hostname)
end
def process_config(&block)
instance_eval(&block)
end
end
def config(&block)
config = AppConfig.new
config.process_config &block
puts "Hosts are: #{config.hosts}"
end
load 'config.rb'
I am trying to create an LWRP that will call the resource that is defined within itself. My cookbook's structure is as follows:
In the machine cookbook's provider, I have a code snippet as follows:
require 'chef/provisioning' # driver for creating machines
require '::File'
def get_environment_json
##environment_template = JSON.parse(File::read(new_resource.template_path + "environment.json"))
return ##environment_template
end
The code is only trying to read a json file and I am using File::read for it.
I keep getting an error as follows:
LoadError
cannot load such file -- ::File
Does anyone know how I can use File::read inside my LWRP's provider?
OK, so the prior two answers are both half right. You have two problems.
First, you can't require ::File as it's already part of Ruby. This is the cause of your error.
Second, if you call File.read you will grab Chef's File not ruby's. You need to do a ::File.read to use Ruby's File class.
require '::File'
Is incorrect and is causing the LoadError. Delete this line. You don't need it. File is part of the Ruby core and doesn't need to be required.
To further explain, the string argument to require represents the file name of the library you want to load. So, it should look like require "file", or require "rack/utils".
It happens becuase Chef already has a file resource. We have to use the Ruby File class in a recipe.We use ::File to use the Ruby File class to fix this issue. For example:
execute 'apt-get-update' do
command 'apt-get update'
ignore_failure true
only_if { apt_installed? }
not_if { ::File.exist?('/var/lib/apt/periodic/update-success-stamp') }
end
Source: https://docs.chef.io/ruby.html#ruby-class
config/database.yml
default: &default
adapter: sqlite3
encoding: unicode
development:
<<: *default
database: development.sqlite3
username: admin
password: wsxqaz
server: localhost
# port:
ruby code:
require "yaml"
require "active_record"
# shorten lines with this namespace
include ActiveRecord::Tasks
# trying to use db folder
DatabaseTasks.db_dir = './db'
db_config_file = "./config/database.yml"
db_config = YAML.load_file(db_config_file)
db_type = db_config['development']
#sldbtask = SQLiteDatabaseTasks.new(db_type, root = './')
#sldbtask.create
I've tried changing the root argument but that doesn't make any difference either.
What do I need to get my db file into the db directory? It creates it okay and the table stuff is pending. First things first.
I believe that the database is supposed to be generated in the root directory. The db folder is used for activerecord's schema and migration files. Why is it so important that the database generates in the db directory?
EDIT
I just found an easier way to do this. After you require all of the files you want, then enter set :database, {database:"./db/myDatabase.db"}. If you already have the line set :database in your code, just add that to it. Good luck!
I'm currently working on a script (command line tool) for work to help me manage expose consoles.
At first I was passing three arguments to the script each time I used it to login into the consoles, for example:
$ nexose-magic.rb -u user -p password -i 192.168.1.2 --display-scans
It's not very efficient, so I created a config.yml file that stores console information in a hash.
$ nexpose-magic.rb -c console --display-scans
I believe the tool will be useful to admins out there, so I'd like to share it in a gem. I can't figure out how to get my config.yml file to work with a gem install..It can't find the config.yml file! It's easy to point it at the relative path in my development directory, but once I create a gem that relative path isn't so relative anymore. How do I point nexpose-magic.rb at the config.yml file?
Is there a better way to handle something like this?
You can create a gem that include a configure class. This class has a load method that will take a directory as an argument. Then, you can pass the directory where you are currently working.
A nice way of preparing your gem is to create a Configuration singleton class in your gem:
require 'singleton'
class Configuration
include Singleton
attr_accessor :config, :app_path
def load(app_path)
#app_path = app_path
#load the config file and store the data
#config = YAML.load_file( File.join(#app_path,'config','config.yml'))
end
end
In your main class :
module MyFancyGem
class << self
#define a class method that configure the gem
def configure(app_path)
# Call load method with given path
config.load(app_path)
end
# MyFancyGem.config will refer to the singleton Configuration class
def config
MyFancyGem::Configuration.instance
end
end
end
Usage:
-Working directory
- my_new_script
- Gemfile
- config/
- config.yml
In my_new_script :
require 'bundler'
Bundler.setup(:default)
require 'my_fancy_gem'
MyFancyGem.configure(File.join(File.dirname(__FILE__),"./")) #here, you define the path
MyFancyGem.hello_world
I hope that's clear enough. I was actually about to write a blog post to explain this particular point (I hope in a more complete version of it). Let me know if you're interested !