Access config file from any directory? - ruby

I am making a command line tool and I am using yaml to make a config file. But right now I can only access the tool when I am in the same directory as that of myprogram.yml.
private
CONFIG_FILE = 'myprogram.yml'
def write_config
config = {}
config['username']=#username
config['password']=#password
File.open(CONFIG_FILE, 'w') do |f|
f.write config.to_yaml
end
end
def read_config
config = YAML.load_file(CONFIG_FILE)
#username = config['username']
#password = config['password']
end
How can I make this file to be accessed from any directory on my computer?

You'll want to give the absolute directory of the myprogram.yml file. Right now it will look in the directory where you are executing the ruby script from. By making it absolute, the script can run anywhere and know where to find the config file.
Example:
private
CONFIG_FILE = '/Users/myuser/config/myprogram.yml'
def write_config
config = {}
config['username']=#username
config['password']=#password
File.open(CONFIG_FILE, 'w') do |f|
f.write config.to_yaml
end
end
def read_config
config = YAML.load_file(CONFIG_FILE)
#username = config['username']
#password = config['password']
end

Related

Create a plugin that puts text in a .txt file

I am working on creating a plugin in Ruby.
On this moment I am unable to insert the coordinates, that are added to a Sketchup model, in a .txt file.
This is my code:
require 'sketchup.rb'
SKETCHUP_CONSOLE.show rescue Sketchup.send_action("showRubyPanel:")
$stdout = File.new('file.txt', 'w')
module HWmakemyownplug
def self.fileplug
model = Sketchup.active_model
#Make some coordinates.
coordinates = [[2,0,39],[0,0,1],[1,1,0]]
#Add the points in Sketchup. This works!
coordinates.each { |point| model.active_entities.add_cpoint(point) }
#Puts the coordinates to the textfile 'file.txt'. This doesn't work!
$stdout.puts(coordinates)
end #def self.fileplug
end #module makemyownplug
if (!file_loaded?(__FILE__))
#Add to the SketchUp tools menu
extensions_menu = UI.menu("Plugins")
extensions_menu.add_item("testtesttest") { HWmakemyownplug::fileplug }
# Let Ruby know we have loaded this file
file_loaded(__FILE__)
end
The coordinates have to be printed when I click on menu > plugins > testtesttest.
You forgot to close file after $stdout.puts(coordinates)
$stdout.close
Here is an example code for writing data to a JSON file instead of a simple text document.
The code can run outside of SketchUp for testing in the terminal. Just make sure to follow these steps...
Copy the code below and paste it on a ruby file (example: file.rb)
Run the script in terminal ruby file.rb or run with SketchUp.
The script will write data to JSON file and also read the content of JSON file.
The path to the JSON file is relative to the ruby file created in step one. If the script can't find the path it will create the JSON file for you.
module DeveloperName
module PluginName
require 'json'
require 'fileutils'
class Main
def initialize
path = File.dirname(__FILE__)
#json = File.join(path, 'file.json')
#content = { 'hello' => 'hello world' }.to_json
json_create(#content)
json_read(#json)
end
def json_create(content)
File.open(#json, 'w') { |f| f.write(content) }
end
def json_read(json)
if File.exist?(json)
file = File.read(json)
data_hash = JSON.parse(file)
puts "Json content: #{data_hash}"
else
msg = 'JSON file not found'
UI.messagebox(msg, MB_OK)
end
end
# # #
end
DeveloperName::PluginName::Main.new
end
end

how to share a rake variable in the code it invokes?

What I need is basically send a target argument and use it in my RSpec tests, e.g.:
$ rake unistall_and_run[test_spec.rb]
Rakefile:
desc 'uninstall app to run tests'
task :uninstall_and_run, [:arg] do |t, arg|
#note this, i will explain later
start_driver(fullReset: true)
oi = arg.to_s.split('"')[1]
file_dir = (project_home + '/spec/' + oi)
exec "rspec #{file_dir}"
end
start_driver is called on that line, but when I run the tests (exec "rspec ..."), it is called again and the args I passed is overwritten by the default (because its on RSpec config).
What I'd like to do is, on my RSpec file check if it was already called and don't run again.
Here is the start_driver method:
def start_driver(options= {})
if options.empty?
capabilities = caps
else
capabilities = caps(options)
end
$appium = Appium::Driver.new(caps: capabilities)
$browser = $appium.start_driver
Appium.promote_appium_methods RSpec::Core::ExampleGroup
end
So, i found a way to do it. Its not beautiful though. I save a file with the args I want when run rake:
desc 'uninstall app to run tests'
task :uninstall_and_run, [:arg] do |t, arg|
send_custom_caps(fullReset: true)
oi = arg.to_s.split('"')[1]
file_dir = (project_home + '/spec/' + oi)
exec "rspec #{file_dir}"
end
and the send_custom_caps method is:
def send_custom_caps(*opts)
file = File.new(custom_caps_file, "w+")
File.open(file, 'w') do |f|
f.write(opts)
end
end
now the ruby code itself (in this case, my spec config) will check if there is custom args before start_driver. Here is my custom start_driver method (which I renamed):
def start_appium_driver (options= {})
if options.empty?
get_caps
if $custom_args
capabilities = caps($custom_args)
else
capabilities = caps
end
else
capabilities = caps(options)
end
$appium = Appium::Driver.new(caps: capabilities)
$browser = $appium.start_driver
Appium.promote_appium_methods RSpec::Core::ExampleGroup
end
and get_caps
def get_caps
if File.exist?(custom_caps_file) #$custom_args
file = File.read(custom_caps_file)
$custom_args = eval(file)
File.delete (custom_caps_file)
end
$custom_args unless $custom_args.defined?
end
probably this is not the best solution, but it is working ok for me :)

Differentiate between local file or URI

I have an external library that needs to be instantiated differently depending on whether the parameter is a local file or an online file.
Right now I have this (I assume the file is always online):
def initialize(path)
url_image = open(path)
#image = Magick::ImageList.new
#image.from_blob(url_image.read)
end
What would be the best way to differentiate if the file is locally stored? I have thought of doing this:
def initialize(path, is_online = true)
if is_online
url_image = open(path)
#image = Magick::ImageList.new
#image.from_blob(url_image.read)
else
#image = Magick::ImageList.new(path)
end
end
As a general rule if a URI has a host, it's not a local file.
require 'uri'
if URI(path).host.nil?
#local
else
#external
end
Then your interface doesn't need to change.

Thor Reading config yaml file to override options

I am trying to create a executable ruby script using Thor.
I have defined the options for my task. So far I have something like this
class Command < Thor
desc "csv2strings CSV_FILENAME", "convert CSV file to '.strings' file"
method_option :langs, :type => :hash, :required => true, :aliases => "-L", :desc => "languages to convert"
...
def csv2strings(filename)
...
end
...
def config
args = options.dup
args[:file] ||= '.csvconverter.yaml'
config = YAML::load File.open(args[:file], 'r')
end
end
When csv2strings is called without arguments, I would like the config task to be invoked, which would set the option :langs.
I haven't yet found a good way to do it.
Any help will be appreciated.
I think you are looking for a way to set configuration options via the command line and via a configuration file.
Here is an example from the foreman gem.
def options
original_options = super
return original_options unless File.exists?(".foreman")
defaults = ::YAML::load_file(".foreman") || {}
Thor::CoreExt::HashWithIndifferentAccess.new(defaults.merge(original_options))
end
It overrides the options method and merges values from a configuration file into the original options hash.
In your case, the following might work:
def csv2strings(name)
# do something with options
end
private
def options
original_options = super
filename = original_options[:file] || '.csvconverter.yaml'
return original_options unless File.exists?(filename)
defaults = ::YAML::load_file(filename) || {}
defaults.merge(original_options)
# alternatively, set original_options[:langs] and then return it
end
(I recently wrote a post about Foreman on my blog that explains this in more detail.)

Create a file in a specified directory

How can I create a new file in a specific directory. I created this class:
class FileManager
def initialize()
end
def createFile(name,extension)
return File.new(name <<"."<<extension, "w+")
end
end
I would like to specify a directory (path) where to create the file. If this one doesn't exist, he will be created. So do I have to use fileutils as shown here just after file creation or can I specify directly in the creation the place where create the file?
Thanks
The following code checks that the directory you've passed in exists (pulling the directory from the path using File.dirname), and creates it if it does not. It then creates the file as you did before.
require 'fileutils'
def create_file(path, extension)
dir = File.dirname(path)
unless File.directory?(dir)
FileUtils.mkdir_p(dir)
end
path << ".#{extension}"
File.new(path, 'w')
end

Resources