Open a document in a Mac app with a rake file - ruby

I have a task in my Rakefile for creating a new post in Jekyll. (I borrowed it from Octopress).
I've tried to hack it so that it will create a new markdown file, add the default header info and then open it in IA Writer. It creates the file and adds the info, but what it opens isn't the file. It looks like the filename variable isn't being passed through to the system command, but I have no idea how I should be writing it.
Here's the code:
# Usage rake new_post['Title of the Post']
desc "Beginning a new post in _posts"
task :new_post, :title do |t, args|
args.with_defaults(:title => 'new-post')
title = args.title
filename = "_posts/#{Time.now.strftime('%Y-%m-%d')}-#{title.to_url}.markdown"
open_filename = "#{Time.now.strftime('%Y-%m-%d')}-#{title.to_url}.markdown"
if File.exist?(filename)
abort("rake aborted!") if ask("#{filename} already exists. Do you want to overwrite?", ['y', 'n']) == 'n'
end
puts "Creating new post: #{filename}"
open(filename, 'w') do |post|
post.puts "---"
post.puts "layout: post"
post.puts "title: \"#{title.gsub(/&/,'&')}\""
post.puts "date: #{Time.now.strftime('%Y-%m-%d %H:%M')}"
post.puts "categories: "
post.puts "---"
end
puts "Opening: #{filename}"
system('open -a IA\ Writer ~/Dropbox/Archive/jdb/#{filename}')
end

In line system... change ' to ". In ' ruby doesn't use variables, example:
001 > filename = "test"
=> "test"
002 > puts '#{filename}'
=> #{filename}
003 > puts "#{filename}"
=> test

Related

Changing Directory by Ruby

I am trying to create a simple script to delete all the files from my Desktop(I am using Ubuntu).
puts "Started at #{Time.now}"
Dir.chdir("/Desktop")
Dir.entries(".").each do |file|
if file.to_s.include?("xlsx")
puts "Deleting file #{file}" unless file == "." || file == ".."
File.delete "#{Dir.pwd}/#{file}" unless file == "." || file == ".."
end
end
puts "Ended on #{Time.now}"
But when I generate the code it throws the below error:
chdir': No such file or directory # dir_chdir - /Desktop
(Errno::ENOENT)
What I am doing wrong?
puts "Started at #{Time.now}"
Dir.chdir("#{ENV['HOME']}/Desktop")
Dir.entries(".").select { |file| file.ends_with?('.xlsx') }.each do |file|
puts "Deleting file #{file}"
File.delete "#{Dir.pwd}/#{file}"
end
puts "Ended on #{Time.now}"

Ruby - 'read': can't convert String into Integer

New to Ruby, and programming in general.
I am trying to write to a file and then print what I wrote to the file in the terminal.
filename = ARGV.first
script = $0
puts "Would you like to read the file?"
puts "If you want to, hit RETURN."
puts "If you don't want to, hit CTRL+C."
prompt = "? "
STDIN.gets
puts "Opening file..."
target = File.open(filename, 'w+')
puts "Reading file..."
puts target.read()
puts "Blank, huh?"
print "Write something: "; line1 = STDIN.gets()
print "A little more: "; line2 = STDIN.gets()
target.write(line1)
target.write(line2)
puts "Let's read it now."
puts target.read()
The code runs until I get to the last line, at which time the following error is thrown:
exl16_2.rb:26:in `read': can't convert String into Integer (TypeError)
from exl16_2.rb:26:in `<main>'
Not sure what this means within the context of what I am trying to do (print out what was written).
Not sure what's causing the error on your side, what Ruby version are you using? I tried w/1.9 and 2.1 and didn't get that. There are however issues with your code, try this:
filename = ARGV.first
script = $0
puts "Would you like to read the file?"
puts "If you want to, hit RETURN."
puts "If you don't want to, hit CTRL+C."
prompt = "? "
STDIN.gets
puts "Opening file..."
target = File.open(filename, 'w+')
puts "Reading file..."
puts target.read()
puts "Blank, huh?"
print "Write something: "; line1 = STDIN.gets()
print "A little more: "; line2 = STDIN.gets()
target.write(line1)
target.write(line2)
target.rewind()
puts "Let's read it now."
puts target.read()
If you read from the file after you wrote it, it will appear empty. The rewind call will make sure you're reading from the beginning of the file.

How to fail erb + json rendering when some keys are missing from the json file

We use this ruby script to render our config files from erb template + json config file. It is basically from an example from http://ruby-doc.org/stdlib-2.1.1/libdoc/erb/rdoc/ERB.html
Recently we accidentally removed something from the json, while we still referenced it in the erb file. The script works, and simply replaces the placeholder with empty string. Is there a way to make it fail?
In the below example
$ render.rb conf.json template2.erb out2 ; echo $?
will fail with 1, because a full block is missing, however if only some key-value pairs are missing, it doesn't warn or fail:
$ render.rb conf.json template1.erb out1 ; echo $?
will exit with 0
conf.json:
{
"block1" : {
"param1": "p1"
}
}
template1.erb:
foo=<%= #config['block1']['param1'] %>:<%= #config['block1']['missing_param'] %>
template2.erb:
foo=<%= #config['block1']['param1'] %>:<%= #config['block1']['missing_param'] %>/<%= #config['missing_block']['anything'] %>
render.rb:
#!/usr/bin/env ruby
# usage: conf_gen.rb config_file.json erb_template output_file
require 'erb'
require 'json'
require 'pathname'
class MyRenderer
def initialize(config_path)
#config = JSON.parse(File.read(config_path))
end
end
if ARGV.size != 3
puts "Hey, missing arguments.\nUsage: conf_gen.rb <json config file> <erb template> <output file>"
exit
end
config_path = ARGV.shift
template_filename = ARGV.shift
output_file = ARGV.shift
erb = ERB.new(File.read(template_filename))
erb.filename = template_filename
ConfigRenderer = erb.def_class(MyRenderer, 'render()')
output = File.new(output_file, 'w')
output.puts(ConfigRenderer.new(config_path).render())
output.close
puts "Finished Successfully"

Ruby cannot open file ( Errno::ENOENT ) but the same path can be opened from IRB

I have a simple Ruby script that is building a list of files from an array of strings, so I have a method a bit like this:
def initialize( rootpath, name )
#content = ""
intermission = ""
if ( ! (rootpath[-1] == "/" || name[0] == "/" ))
intermission="/"
end
#path= "#{rootpath}#{intermission}#{name}"
print "Open JavascriptFile from #{#path}"
if (! File.exists? #path)
print "File does not exist!"
end
File.open( #path ).each do |line|
#content << line
end
end
This is called along the lines of:
files= ['alice.js', 'bob.js', 'claire.js', 'dave.js']
basepath= "/home/glenatron/projects/myJSProject/"
files.each do |filename|
myLoader.new( basepath, filename )
end
When I load in my classes from IRB and run this I get:
Open JavascriptFile from /home/glenatron/projects/myJSProject/alice.js
File does not exist!
Errno::ENOENT: No such file or directory - /home/glenatron/projects/myJSProject/alice.js
As I understand it, this means that the file does not exist.
However not only does the file definitely exist, in IRB I can paste the exact same path and see it's content - a simple File.open("/home/glenatron/projects/myJSProject/alice.js").each { | line | print line } reveals the complete content of the file. So why can I do this from a direct command line request and not from my Ruby class? Is it trying to read a local path instead of the full path I am passing it?
Guard the File.open .. lines with else block:
if (! File.exists? #path)
print "File does not exist!"
else # <---
File.open( #path ).each do |line|
#content << line
end
end # <----
or return earlier in the if block:
if (! File.exists? #path)
print "File does not exist!"
return
endif
Otherwise, the code always try to open the file, even if it does not exist.
Use File::join to join the path components:
File.join("/home/glenatron/projects/myJSProject/", "alice.js")
# => "/home/glenatron/projects/myJSProject/alice.js"
File.join("/home/glenatron/projects/myJSProject", "alice.js")
# => "/home/glenatron/projects/myJSProject/alice.js"
Edit to bring the solution ( in the comments ) into the answer:
To find the exact path, use p #path - this revealed that the path that was trying to open looked like this when it failed: /home/glenatron/projects/myJSProject/alice.js\r which was causing the problem. A simple #path.strip! resolved it once this was clear.
From your code shown in the question,
looks like an end instead of an else, e.g.
if (! File.exists? #path)
print "File does not exist!"
end # <------------ This wasn't valid
File.open( #path ).each do |line|
#content << line
end
end
should be
if (! File.exists? #path)
print "File does not exist!"
else
File.open( #path ).each do |line|
#content << line
end # THIS end is valid as it ends a `.each` block
end

Ruby symlink not working in OS X

The following script creates symlinks as expected, but the original file can never be found. Can someone tell me why? They appear to be valid symlinks because they register as aliases in OS X and File.symlink? returns true once they have been created.
#!/usr/bin/env ruby
case ARGV.first when 'link'
file = ARGV[1]
if !File.exist?(file)
puts "Unfortunately, \"#{file}\" was not found."
exit 0
end
bin = "/usr/local/bin/"
if !File.directory?(bin)
puts "#{bin} does not exist!"
puts "creating #{bin}..."
system "mkdir -p #{bin}"
end
if File.extname(file).empty?
if File.symlink?(bin + file)
puts "Unfortunately, \"#{bin + file}\" already exists."
exit 0
end
name = bin + file
puts "Symlinking #{file} to #{name}..."
File.symlink(file, name)
system "chmod +x #{name}"
else
name = file.split(File.extname(file))
name = bin + name.first
if File.symlink?(name)
puts "Unfortunately, \"#{name}\" already exists."
exit 0
end
puts "Symlinking #{file} to #{name}..."
File.symlink(file, name)
system "chmod +x #{name}"
end
else
puts "try: bin link <file>"
end
The script is run in the following way:
ruby script.rb link myfile.rb
To answer my own question, replacing the instances of
File.symlink(file, name)
with
File.symlink(File.expand_path(file), name)
worked perfectly.

Resources