I'm trying to run a puppet apply and thrown with bunch of errors.
hiera -c /etc/puppet/hiera.yaml classes
generates the following :
/usr/share/ruby/vendor_ruby/2.0/psych.rb:205:in `parse': (<unknown>): found character that cannot start any token while scanning for the next token at line 238 column 3 (Psych::SyntaxError)
from /usr/share/ruby/vendor_ruby/2.0/psych.rb:205:in `parse_stream'
from /usr/share/ruby/vendor_ruby/2.0/psych.rb:153:in `parse'
from /usr/share/ruby/vendor_ruby/2.0/psych.rb:129:in `load'
from /usr/local/share/ruby/gems/2.0/gems/hiera-1.3.4/lib/hiera/backend/yaml_backend.rb:18:in `block (2 levels) in lookup'
from /usr/local/share/ruby/gems/2.0/gems/hiera-1.3.4/lib/hiera/filecache.rb:53:in `read_file'
from /usr/local/share/ruby/gems/2.0/gems/hiera-1.3.4/lib/hiera/backend/yaml_backend.rb:17:in `block in lookup'
from /usr/local/share/ruby/gems/2.0/gems/hiera-1.3.4/lib/hiera/backend.rb:104:in `block in datasourcefiles'
from /usr/local/share/ruby/gems/2.0/gems/hiera-1.3.4/lib/hiera/backend.rb:76:in `block in datasources'
from /usr/local/share/ruby/gems/2.0/gems/hiera-1.3.4/lib/hiera/backend.rb:74:in `map'
from /usr/local/share/ruby/gems/2.0/gems/hiera-1.3.4/lib/hiera/backend.rb:74:in `datasources'
from /usr/local/share/ruby/gems/2.0/gems/hiera-1.3.4/lib/hiera/backend.rb:99:in `datasourcefiles'
from /usr/local/share/ruby/gems/2.0/gems/hiera-1.3.4/lib/hiera/backend/yaml_backend.rb:16:in `lookup'
from /usr/local/share/ruby/gems/2.0/gems/hiera-1.3.4/lib/hiera/backend.rb:206:in `block in lookup'
from /usr/local/share/ruby/gems/2.0/gems/hiera-1.3.4/lib/hiera/backend.rb:203:in `each'
from /usr/local/share/ruby/gems/2.0/gems/hiera-1.3.4/lib/hiera/backend.rb:203:in `lookup'
from /usr/local/share/ruby/gems/2.0/gems/hiera-1.3.4/lib/hiera.rb:60:in `lookup'
from /usr/local/share/ruby/gems/2.0/gems/hiera-1.3.4/bin/hiera:225:in `<top (required)>'
from /usr/local/bin/hiera:23:in `load'
from /usr/local/bin/hiera:23:in `<main>'
contents of the file:
require 'psych.so'
require 'psych/nodes'
require 'psych/streaming'
require 'psych/visitors'
require 'psych/handler'
require 'psych/tree_builder'
require 'psych/parser'
require 'psych/omap'
require 'psych/set'
require 'psych/coder'
require 'psych/core_ext'
require 'psych/deprecated'
require 'psych/stream'
require 'psych/json/tree_builder'
require 'psych/json/stream'
require 'psych/handlers/document_stream'
###
# = Overview
#
# Psych is a YAML parser and emitter.
# Psych leverages libyaml [Home page: http://pyyaml.org/wiki/LibYAML]
# or [Git repo: https://github.com/zerotao/libyaml] for its YAML parsing
# and emitting capabilities. In addition to wrapping libyaml, Psych also
# knows how to serialize and de-serialize most Ruby objects to and from
# the YAML format.
#
# = I NEED TO PARSE OR EMIT YAML RIGHT NOW!
#
# # Parse some YAML
# Psych.load("--- foo") # => "foo"
#
# # Emit some YAML
# Psych.dump("foo") # => "--- foo\n...\n"
# { :a => 'b'}.to_yaml # => "---\n:a: b\n"
#
# Got more time on your hands? Keep on reading!
#
# == YAML Parsing
#
# Psych provides a range of interfaces for parsing a YAML document ranging from
# low level to high level, depending on your parsing needs. At the lowest
# level, is an event based parser. Mid level is access to the raw YAML AST,
# and at the highest level is the ability to unmarshal YAML to ruby objects.
#
# === Low level parsing
#
# The lowest level parser should be used when the YAML input is already known,
# and the developer does not want to pay the price of building an AST or
# automatic detection and conversion to ruby objects. See Psych::Parser for
# more information on using the event based parser.
#
# === Mid level parsing
#
# Psych provides access to an AST produced from parsing a YAML document. This
# tree is built using the Psych::Parser and Psych::TreeBuilder. The AST can
# be examined and manipulated freely. Please see Psych::parse_stream,
# Psych::Nodes, and Psych::Nodes::Node for more information on dealing with
# YAML syntax trees.
#
# === High level parsing
#
# The high level YAML parser provided by Psych simply takes YAML as input and
# returns a Ruby data structure. For information on using the high level parser
# see Psych.load
#
# == YAML Emitting
#
# Psych provides a range of interfaces ranging from low to high level for
# producing YAML documents. Very similar to the YAML parsing interfaces, Psych
# provides at the lowest level, an event based system, mid-level is building
# a YAML AST, and the highest level is converting a Ruby object straight to
# a YAML document.
#
# === Low level emitting
#
# The lowest level emitter is an event based system. Events are sent to a
# Psych::Emitter object. That object knows how to convert the events to a YAML
# document. This interface should be used when document format is known in
# advance or speed is a concern. See Psych::Emitter for more information.
#
# === Mid level emitting
#
# At the mid level is building an AST. This AST is exactly the same as the AST
# used when parsing a YAML document. Users can build an AST by hand and the
# AST knows how to emit itself as a YAML document. See Psych::Nodes,
# Psych::Nodes::Node, and Psych::TreeBuilder for more information on building
# a YAML AST.
#
# === High level emitting
#
# The high level emitter has the easiest interface. Psych simply takes a Ruby
# data structure and converts it to a YAML document. See Psych.dump for more
# information on dumping a Ruby data structure.
module Psych
# The version is Psych you're using
VERSION = '2.0.0'
# The version of libyaml Psych is using
LIBYAML_VERSION = Psych.libyaml_version.join '.'
class Exception < RuntimeError
end
class BadAlias < Exception
end
###
# Load +yaml+ in to a Ruby data structure. If multiple documents are
# provided, the object contained in the first document will be returned.
# +filename+ will be used in the exception message if any exception is raised
# while parsing.
#
# Raises a Psych::SyntaxError when a YAML syntax error is detected.
#
# Example:
#
# Psych.load("--- a") # => 'a'
# Psych.load("---\n - a\n - b") # => ['a', 'b']
#
# begin
# Psych.load("--- `", "file.txt")
# rescue Psych::SyntaxError => ex
# ex.file # => 'file.txt'
# ex.message # => "(file.txt): found character that cannot start any token"
# end
def self.load yaml, filename = nil
result = parse(yaml, filename)
result ? result.to_ruby : result
end
###
# Parse a YAML string in +yaml+. Returns the first object of a YAML AST.
# +filename+ is used in the exception message if a Psych::SyntaxError is
# raised.
#
# Raises a Psych::SyntaxError when a YAML syntax error is detected.
#
# Example:
#
# Psych.parse("---\n - a\n - b") # => #<Psych::Nodes::Sequence:0x00>
#
# begin
# Psych.parse("--- `", "file.txt")
# rescue Psych::SyntaxError => ex
# ex.file # => 'file.txt'
# ex.message # => "(file.txt): found character that cannot start any token"
# end
#
# See Psych::Nodes for more information about YAML AST.
def self.parse yaml, filename = nil
parse_stream(yaml, filename) do |node|
return node
end
false
end
###
# Parse a file at +filename+. Returns the YAML AST.
#
# Raises a Psych::SyntaxError when a YAML syntax error is detected.
def self.parse_file filename
File.open filename, 'r:bom|utf-8' do |f|
parse f, filename
end
end
###
# Returns a default parser
def self.parser
Psych::Parser.new(TreeBuilder.new)
end
###
# Parse a YAML string in +yaml+. Returns the full AST for the YAML document.
# This method can handle multiple YAML documents contained in +yaml+.
# +filename+ is used in the exception message if a Psych::SyntaxError is
# raised.
#
# If a block is given, a Psych::Nodes::Document node will be yielded to the
# block as it's being parsed.
#
# Raises a Psych::SyntaxError when a YAML syntax error is detected.
#
# Example:
#
# Psych.parse_stream("---\n - a\n - b") # => #<Psych::Nodes::Stream:0x00>
#
# Psych.parse_stream("--- a\n--- b") do |node|
# node # => #<Psych::Nodes::Document:0x00>
# end
#
# begin
# Psych.parse_stream("--- `", "file.txt")
# rescue Psych::SyntaxError => ex
# ex.file # => 'file.txt'
# ex.message # => "(file.txt): found character that cannot start any token"
# end
#
# See Psych::Nodes for more information about YAML AST.
def self.parse_stream yaml, filename = nil, &block
if block_given?
parser = Psych::Parser.new(Handlers::DocumentStream.new(&block))
parser.parse yaml, filename
else
parser = self.parser
parser.parse yaml, filename
parser.handler.root
end
end
###
# call-seq:
# Psych.dump(o) -> string of yaml
# Psych.dump(o, options) -> string of yaml
# Psych.dump(o, io) -> io object passed in
# Psych.dump(o, io, options) -> io object passed in
#
# Dump Ruby object +o+ to a YAML string. Optional +options+ may be passed in
# to control the output format. If an IO object is passed in, the YAML will
# be dumped to that IO object.
#
# Example:
#
# # Dump an array, get back a YAML string
# Psych.dump(['a', 'b']) # => "---\n- a\n- b\n"
#
# # Dump an array to an IO object
# Psych.dump(['a', 'b'], StringIO.new) # => #<StringIO:0x000001009d0890>
#
# # Dump an array with indentation set
# Psych.dump(['a', ['b']], :indentation => 3) # => "---\n- a\n- - b\n"
#
# # Dump an array to an IO with indentation set
# Psych.dump(['a', ['b']], StringIO.new, :indentation => 3)
#def self.dump o, io = nil, options = {}
def self.dump o, io = nil, options = {}
if Hash === io
options = io
io = nil
end
visitor = Psych::Visitors::YAMLTree.new options
visitor << o
visitor.tree.yaml io, options
end
###
# Dump a list of objects as separate documents to a document stream.
#
# Example:
#
# Psych.dump_stream("foo\n ", {}) # => "--- ! \"foo\\n \"\n--- {}\n"
def self.dump_stream *objects
visitor = Psych::Visitors::YAMLTree.new {}
objects.each do |o|
visitor << o
end
visitor.tree.yaml
end
###
# Dump Ruby object +o+ to a JSON string.
def self.to_json o
visitor = Psych::Visitors::JSONTree.new
visitor << o
visitor.tree.yaml
end
###
# Load multiple documents given in +yaml+. Returns the parsed documents
# as a list. If a block is given, each document will be converted to ruby
# and passed to the block during parsing
#
# Example:
#
# Psych.load_stream("--- foo\n...\n--- bar\n...") # => ['foo', 'bar']
#
# list = []
# Psych.load_stream("--- foo\n...\n--- bar\n...") do |ruby|
# list << ruby
# end
# list # => ['foo', 'bar']
#
def self.load_stream yaml, filename = nil
if block_given?
parse_stream(yaml, filename) do |node|
yield node.to_ruby
end
else
parse_stream(yaml, filename).children.map { |child| child.to_ruby }
end
end
###
# Load the document contained in +filename+. Returns the yaml contained in
# +filename+ as a ruby object
def self.load_file filename
File.open(filename, 'r:bom|utf-8') { |f| self.load f, filename }
end
# :stopdoc:
#domain_types = {}
def self.add_domain_type domain, type_tag, &block
key = ['tag', domain, type_tag].join ':'
#domain_types[key] = [key, block]
#domain_types["tag:#{type_tag}"] = [key, block]
end
def self.add_builtin_type type_tag, &block
domain = 'yaml.org,2002'
key = ['tag', domain, type_tag].join ':'
#domain_types[key] = [key, block]
end
def self.remove_type type_tag
#domain_types.delete type_tag
end
#load_tags = {}
#dump_tags = {}
def self.add_tag tag, klass
#load_tags[tag] = klass
#dump_tags[klass] = tag
end
class << self
attr_accessor :load_tags
attr_accessor :dump_tags
attr_accessor :domain_types
end
# :startdoc:
end
I have seen some references quoting
require 'yaml'
YAML::ENGINE.yamler = 'syck'
cannot find a config/boot.rb to try this.
I ripped out system wide ruby and the gems. Trying rvm and i still get similar errors :
I'm running hiera in debug mode :
[lame#TTBOX ~]$ hiera -d -c eye
Cannot find config file: eye
[lame#ipTTBOX ~]$ hiera -d eye
DEBUG: 2014-11-25 05:47:37 +0700: Hiera YAML backend starting
DEBUG: 2014-11-25 05:47:37 +0700: Looking up eye in YAML backend
DEBUG: 2014-11-25 05:47:37 +0700: Looking for data source default
/home/lame/.rvm/gems/ruby-2.1.5/gems/psych-2.0.6/lib/psych.rb:370:in `parse': (<unknown>): found character that cannot start any token while scanning for the next token at line 238 column 3 (Psych::SyntaxError)
from /home/lame/.rvm/gems/ruby-2.1.5/gems/psych-2.0.6/lib/psych.rb:370:in `parse_stream'
from /home/lame/.rvm/gems/ruby-2.1.5/gems/psych-2.0.6/lib/psych.rb:318:in `parse'
from /home/lame/.rvm/gems/ruby-2.1.5/gems/psych-2.0.6/lib/psych.rb:245:in `load'
from /home/lame/.rvm/gems/ruby-2.1.5/gems/hiera-1.3.4/lib/hiera/backend/yaml_backend.rb:18:in `block (2 levels) in lookup'
from /home/lame/.rvm/gems/ruby-2.1.5/gems/hiera-1.3.4/lib/hiera/filecache.rb:53:in `read_file'
from /home/lame/.rvm/gems/ruby-2.1.5/gems/hiera-1.3.4/lib/hiera/backend/yaml_backend.rb:17:in `block in lookup'
from /home/lame/.rvm/gems/ruby-2.1.5/gems/hiera-1.3.4/lib/hiera/backend.rb:104:in `block in datasourcefiles'
from /home/lame/.rvm/gems/ruby-2.1.5/gems/hiera-1.3.4/lib/hiera/backend.rb:76:in `block in datasources'
from /home/lame/.rvm/gems/ruby-2.1.5/gems/hiera-1.3.4/lib/hiera/backend.rb:74:in `map'
from /home/lame/.rvm/gems/ruby-2.1.5/gems/hiera-1.3.4/lib/hiera/backend.rb:74:in `datasources'
from /home/lame/.rvm/gems/ruby-2.1.5/gems/hiera-1.3.4/lib/hiera/backend.rb:99:in `datasourcefiles'
from /home/lame/.rvm/gems/ruby-2.1.5/gems/hiera-1.3.4/lib/hiera/backend/yaml_backend.rb:16:in `lookup'
from /home/lame/.rvm/gems/ruby-2.1.5/gems/hiera-1.3.4/lib/hiera/backend.rb:206:in `block in lookup'
from /home/lame/.rvm/gems/ruby-2.1.5/gems/hiera-1.3.4/lib/hiera/backend.rb:203:in `each'
from /home/lame/.rvm/gems/ruby-2.1.5/gems/hiera-1.3.4/lib/hiera/backend.rb:203:in `lookup'
from /home/lame/.rvm/gems/ruby-2.1.5/gems/hiera-1.3.4/lib/hiera.rb:60:in `lookup'
from /home/lame/.rvm/gems/ruby-2.1.5/gems/hiera-1.3.4/bin/hiera:225:in `<top (required)>'
from /home/lame/.rvm/gems/ruby-2.1.5/bin/hiera:23:in `load'
from /home/lame/.rvm/gems/ruby-2.1.5/bin/hiera:23:in `<main>'
from /home/lame/.rvm/gems/ruby-2.1.5/bin/ruby_executable_hooks:15:in `eval'
from /home/lame/.rvm/gems/ruby-2.1.5/bin/ruby_executable_hooks:15:in `<main>'
Are you suggesting me to have a look at the hiera file itself ?
Your error message says to look at line 238, column 3 of your yaml file. Check to see if you have any illegal characters there.
Related
I have written an assertion that collects new records created while it yields to a block. Here's an example, with a failing assertion inside that block:
product =
assert_latest_record Product do # line 337
post :create,
:product => { ... }
assert false # line 340
end
The source of my assertion is below, but I don't think it's relevant. It does not intercept Minitest exceptions, or even call rescue or ensure.
The problem is when an assertion inside that block fails. The fault diagnostic message reports the line number as 337 the line of the outer assertion, not 340, the line of the inner assertion that failed. This is important if, for example, my colleagues have written a run-on test with way too many lines in it; isolating a failing line becomes more difficult.
Why doesn't Minitest report the correct line number?
The source:
##
# When a test case calls methods that write new ActiveModel records to a database,
# sometimes the test needs to assert those records were created, by fetching them back
# for inspection. +assert_latest_record+ collects every record in the given model or
# models that appear while its block runs, and returns either a single record or a ragged
# array.
#
# ==== Parameters
#
# * +models+ - At least 1 ActiveRecord model or association.
# * +message+ - Optional string or ->{block} to provide more diagnostics at failure time.
# * <code>&block</code> - Required block to call and monitor for new records.
#
# ==== Example
#
# user, email_addresses =
# assert_latest_record User, EmailAddress, ->{ 'Need moar records!' } do
# post :create, ...
# end
# assert_equal 'franklyn', user.login # 1 user, so not an array
# assert_equal 2, email_addresses.size
# assert_equal 'franklyn#gmail.com', email_addresses.first.mail
# assert_equal 'franklyn#hotmail.com', email_addresses.second.mail
#
# ==== Returns
#
# The returned value is a set of one or more created records. The set is normalized,
# so all arrays of one item are replaced with the item itself.
#
# ==== Operations
#
# The last argument to +assert_latest_record+ can be a string or a callable block.
# At failure time the assertion adds this string or this block's return value to
# the diagnostic message.
#
# You may call +assert_latest_record+ with anything that responds to <code>.pluck(:id)</code>
# and <code>.where()</code>, including ActiveRecord associations:
#
# user = User.last
# email_address =
# assert_latest_record user.email_addresses do
# post :add_email_address, user_id: user.id, ...
# end
# assert_equal 'franklyn#philly.com', email_address.mail
# assert_equal email_address.user_id, user.id, 'This assertion is redundant.'
#
def assert_latest_record(*models, &block)
models, message = _get_latest_record_args(models, 'assert')
latests = _get_latest_record(models, block)
latests.include?(nil) and _flunk_latest_record(models, latests, message, true)
pass # Increment the test runner's assertion count
return latests.size > 1 ? latests : latests.first
end
##
# When a test case calls methods that might write new ActiveModel records to a
# database, sometimes the test must check that no records were written.
# +refute_latest_record+ watches for new records in the given class or classes
# that appear while its block runs, and fails if any appear.
#
# ==== Parameters
#
# See +assert_latest_record+.
#
# ==== Operations
#
# refute_latest_record User, EmailAddress, ->{ 'GET should not create records' } do
# get :index
# end
#
# The last argument to +refute_latest_record+ can be a string or a callable block.
# At failure time the assertion adds this string or this block's return value to
# the diagnostic message.
#
# Like +assert_latest_record+, you may call +refute_latest_record+ with anything
# that responds to <code>pluck(:id)</code> and <code>where()</code>, including
# ActiveRecord associations.
#
def refute_latest_record(*models, &block)
models, message = _get_latest_record_args(models, 'refute')
latests = _get_latest_record(models, block)
latests.all?(&:nil?) or _flunk_latest_record(models, latests, message, false)
pass
return
end
##
# Sometimes a test must detect new records without using an assertion that passes
# judgment on whether they should have been written. Call +get_latest_record+ to
# return a ragged array of records created during its block, or +nil+:
#
# user, email_addresses, posts =
# get_latest_record User, EmailAddress, Post do
# post :create, ...
# end
#
# assert_nil posts, "Don't create Post records while creating a User"
#
# Unlike +assert_latest_record+, +get_latest_record+ does not take a +message+ string
# or block, because it has no diagnostic message.
#
# Like +assert_latest_record+, you may call +get_latest_record+ with anything
# that responds to <code>.pluck(:id)</code> and <code>.where()</code>, including
# ActiveRecord associations.
#
def get_latest_record(*models, &block)
assert models.any?, 'Call get_latest_record with one or more ActiveRecord models or associations.'
refute_nil block, 'Call get_latest_record with a block.'
records = _get_latest_record(models, block)
return records.size > 1 ? records : records.first
end # Methods should be easy to use correctly and hard to use incorrectly...
def _get_latest_record_args(models, what) #:nodoc:
message = nil
message = models.pop unless models.last.respond_to?(:pluck)
valid_message = message.nil? || message.kind_of?(String) || message.respond_to?(:call)
models.length > 0 && valid_message and return models, message
raise "call #{what}_latest_record(models..., message) with any number\n" +
'of Model classes or associations, followed by an optional diagnostic message'
end
private :_get_latest_record_args
def _get_latest_record(models, block) #:nodoc:
id_sets = models.map{ |model| model.pluck(*model.primary_key) } # Sorry about your memory!
block.call
record_sets = []
models.each_with_index do |model, index|
pk = model.primary_key
set = id_sets[index]
records =
if set.length == 0
model
elsif pk.is_a?(Array)
pks = pk.map{ |k| "`#{k}` = ?" }.join(' AND ')
pks = [ "(#{pks})" ] * set.length
pks = pks.join(' OR ')
model.where.not(pks, *set.flatten)
else
model.where.not(pk => set)
end
records = records.order(pk).to_a
record_sets.push records.size > 1 ? records : records.first
end
return record_sets
end
private :_get_latest_record
def _flunk_latest_record(models, latests, message, polarity) #:nodoc:
itch_list = []
models.each_with_index do |model, index|
records_found = latests[index] != nil
records_found == polarity or itch_list << model.name
end
itch_list = itch_list.join(', ')
diagnostic = "should#{' not' unless polarity} create new #{itch_list} record(s) in block"
message = nil if message == ''
message = message.call.to_s if message.respond_to?(:call)
message = [ message, diagnostic ].compact.join("\n")
raise Minitest::Assertion, message
end
private :_flunk_latest_record
You could try to configure it to log exceptions in test_helper.rb:
def MiniTest.filter_backtrace(backtrace)
backtrace
end
I'm not sure if this is the default, but depending on your configuration, the backtrace might not be shown.
I have a gem I have created that wraps Git as a key:value store (dictionary/hash). The source is here.
The way it works in the process referenced is as follows:
run the function set containing a key and a value argument
hash these with git, have the key point at the hash
return the key if this operation is successful and it is added to the global dictionary holing keys and hashes
Now, if I call something like
db.set('key', {some: 'value'})
# => 'key'
and then try to retrieve this,
db.get('key')
Psych::SyntaxError: (<unknown>): did not find expected node content while parsing a flow node at line 1 column 2
from /home/bobby/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/psych.rb:370:in `parse'
from /home/bobby/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/psych.rb:370:in `parse_stream'
from /home/bobby/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/psych.rb:318:in `parse'
from /home/bobby/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/psych.rb:245:in `load'
from /home/bobby/.rvm/gems/ruby-2.2.1/gems/gkv-0.2.1/lib/gkv/database.rb:21:in `get'
from (irb):6
from /home/bobby/.rvm/rubies/ruby-2.2.1/bin/irb:11:in `<main>'
Now, if I set the key as that same dictionary, but as a string:
db.set('key', "{some: 'value'}")
# => 'key'
db.get('key')
# => {"key"=>"value"}
db.get('key').class
=> Hash
The operation that is performing the git operations' and wrapping them to a kv store source is:
...
def get(key)
if $ITEMS.keys.include? key
YAML.load(Gkv::GitFunctions.cat_file($ITEMS[key].last))
else
raise KeyError
end
end
def set(key, value)
update_items(key, value.to_s)
key
end
...
And the get_items function being referenced here's source is:
...
def update_items(key, value)
if $ITEMS.keys.include? key
history = $ITEMS[key]
history << Gkv::GitFunctions.hash_object(value.to_s)
$ITEMS[key] = history
else
$ITEMS[key] = [Gkv::GitFunctions.hash_object(value.to_s)]
end
end
end
...
hash_object and cat_object simple wrap git hash-object and git cat-file in a method writing the input to a tmpfile, git adding it, and then erasing the tempfile.
I'm really at a loss as to why this works with strings but not true dictionaries. It results in the exact same error if you use the old hashrocket syntax as well:
db.set('a', {:key => 'value'})
=> "a"
db.get('a')
# => Psych::SyntaxError: (<unknown>): did not find expected node content while parsing a flow node at line 1 column 2
from /home/bobby/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/psych.rb:370:in `parse'
from /home/bobby/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/psych.rb:370:in `parse_stream'
from /home/bobby/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/psych.rb:318:in `parse'
from /home/bobby/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/psych.rb:245:in `load'
from /home/bobby/.rvm/gems/ruby-2.2.1/gems/gkv-0.2.1/lib/gkv/database.rb:21:in `get'
from (irb):6
from /home/bobby/.rvm/rubies/ruby-2.2.1/bin/irb:11:in `<main>'
Any ideas?
In your get method you call YAML.load, but in your set method you use .to_s. This means that the YAML parser is trying to read an arbitrary string as if it were YAML. For symmetry YAML.dump should be used in the set method instead.
I've created a pull request with the changes.
I'm looking for some help with my code...
# save text file to string
data = File.read("workdata.txt")
# split string into blocks of text relevant to each journey
journeys = data.split(/\n\s\n/)
# store the amount of journeys as a variable called journeys_size
journeys_size = journeys.length
# split each journey into lines and save to an array called "journey_lines"
#journey_lines = journeys.map { |i| i.split(/\n/) }
# cretae an array called "all_journey_objects" to hold all journeys
all_journey_objects = []
# step through the journey arrays
#journey_lines.each do |line|
next if line[0].include?("position") # skip the journey block of text if it contains position
destinations = []
destination1 = line[12].upcase
destination2 = line[13].scan(/[a-z]+/i).join(" ").upcase
# destination3 = line[14].scan(/[a-z]+/i).join(" ").upcase # <---- When i uncomment this line **
# destination4 = line[15].scan(/[a-z]+/i).join(" ").upcase
# destination5 = line[16].scan(/[a-z]+/i).join(" ").upcase
puts destination1
puts destination2
# puts destination3 # <---- When i uncomment this line **
# puts destination5
# puts destination4
# journey = Journey.new(line[0] , line[1] , line[6] , destinations, etas, windows)
# all_journey_objects << journey
end
The problem I am having is the following error when executed:
watcher.rb:47: in 'block in <main>': undefined method'scan' for nil:NilClass (NoMethodError)
I think the reason is because the "workdata.txt" file that I am working with, contains some journeys which only have two destinations. So, as soon as i uncomment the lines to create a third destination variable it throws an error. Maybe because it is trying to run a method against an object that doesn't exist?
I am stuck with finding a way around this. Any help would be appreciated...
If this is line 47:
destination3 = line[14].scan(/[a-z]+/i).join(" ").upcase
undefined method `scan' for nil:NilClass indicates that you are sending scan to nil. In other words, line[14] is nil.
You could simply add an if statement:
if line[14]
destination3 = line[14].scan(/[a-z]+/i).join(" ").upcase
end
Or an inline if:
destination3 = line[14].scan(/[a-z]+/i).join(" ").upcase if line[14]
I have a map of values, the key is a filename and the value is an array strings.
I have the corresponding files
how would I load the file and create a fixed yaml value which contains the value of the array whether or not the value already exists
e.g.
YAML (file.yaml)
trg::azimuth:
-extra
-intra
-lateral
or
trg::azimuth:
[extra,intra,lateral]
from
RUBY
{"file.yaml" => ["extra","intra","lateral"]}
The YAML documentation doesn't cover its methods very well, but does say
The underlying implementation is the libyaml wrapper Psych.
The Psych documentation, which underlies YAML, covers reading, parsing, and emitting YAML.
Here's the basic process:
require 'yaml'
foo = {"file.yaml" => ["extra","intra","lateral"]}
bar = foo.to_yaml
# => "---\nfile.yaml:\n- extra\n- intra\n- lateral\n"
And here's what the generated, serialized bar variable looks like if written:
puts bar
# >> ---
# >> file.yaml:
# >> - extra
# >> - intra
# >> - lateral
That's the format a YAML parser needs:
baz = YAML.load(bar)
baz
# => {"file.yaml"=>["extra", "intra", "lateral"]}
At this point the hash has gone round-trip, from a Ruby hash, to a YAML-serialized string, back to a Ruby hash.
Writing YAML to a file is easy using Ruby's File.write method:
File.write(foo.keys.first, foo.values.first.to_yaml)
or
foo.each do |k, v|
File.write(k, v.to_yaml)
end
Which results in a file named "file.yaml", which contains:
---
- extra
- intra
- lateral
To read and parse a file, use YAML's load_file method.
foo = YAML.load_file('file.yaml')
# => ["extra", "intra", "lateral"]
"How do I parse a YAML file?" might be of use, as well as the other "Related" links on the right side of this page.
I wanted to write a ruby program to unpackage tar.gz files, and I ran into some issues. After reading the documentation on the ruby-doc site, Zlib::GzipReader and Zlib::Inflate. Then I found this Module someone wrote on GitHub, and that didn't work either. So, using the examples from the Ruby page for Zlib::GzipReader, I these were able to run successfully.
irb(main):027:0* File.open('zlib_inflate.tar.gz') do |f|
irb(main):028:1* gz = Zlib::GzipReader.new(f)
irb(main):029:1> print gz.read
irb(main):030:1> gz.close
irb(main):031:1> end
#
#
#
irb(main):023:0* Zlib::GzipReader.open('zlib_inflate.tar.gz') { |gz|
irb(main):024:1* print gz.read
irb(main):025:1> }
Then, when trying to use the Zlib::Inflate options, I kept running into incorrect header check errors.
irb(main):047:0* zstream = Zlib::Inflate.new
=> #<Zlib::Inflate:0x00000002b15790 #dictionaries={}>
irb(main):048:0> buf = zstream.inflate('zlib_inflate.tar.gz')
Zlib::DataError: incorrect header check
from (irb):48:in `inflate'
from (irb):48
from C:/ruby/Ruby200p353/Ruby200-x64/bin/irb:12:in `<main>'
#
#
#
irb(main):049:0> cf = File.open("zlib_inflate.tar.gz")
=> #<File:zlib_inflate.tar.gz>
irb(main):050:0> ucf = File.open("ruby_inflate.rb", "w+")
=> #<File:ruby_inflate.rb>
irb(main):051:0> zi = Zlib::Inflate.new(Zlib::MAX_WBITS)
=> #<Zlib::Inflate:0x00000002c097f0 #dictionaries={}>
irb(main):052:0> ucf << zi.inflate(cf.read)
Zlib::DataError: incorrect header check
from (irb):52:in `inflate'
from (irb):52
from C:/ruby/Ruby200p353/Ruby200-x64/bin/irb:12:in `<main>'
#
#
#
irb(main):057:0* File.open("zlib_inflate.tar.gz") {|cf|
irb(main):058:1* zi = Zlib::Inflate.new
irb(main):059:1> File.open("zlib_inflate.rb", "w+") {|ucf|
irb(main):060:2* ucf << zi.inflate(cf.read)
irb(main):061:2> }
irb(main):062:1> zi.close
irb(main):063:1> }
Zlib::DataError: incorrect header check
from (irb):60:in `inflate'
from (irb):60:in `block (2 levels) in irb_binding'
from (irb):59:in `open'
from (irb):59:in `block in irb_binding'
from (irb):57:in `open'
from (irb):57
from C:/ruby/Ruby200p353/Ruby200-x64/bin/irb:12:in `<main>'
How would I go about taking a tar.gz file, and extract the contents so the files are not null? I did read this other post about Ruby Zlib from here, but that did not work for me as well. What am I doing wrong?