Rake Namespace Alias - namespaces

Is it possible to alias a namespace in Rake?
I like how you can alias tasks:
task :commit => :c
Would love to be able to do something like this:
namespace :git => :g

With
task :commit => :c
you don't define an alias, you set a prerequisite.
When you call :commit the prerequsite :c is called first.
As long as there is only one prerequsite and :commit does not contain own code, it may look like an alias, but it is not.
Knowing that, you may 'alias' your namespace, if you define a default task for your namespace and set a prerequisite for this task (and the prerequisite may be again a default task of another namespace).
But I think, there is no need of aliasing namespaces. It would be enough, if you define a default task for namepsaces and perhaps 'alias' that task.
After reading the question again I have an alternative idea, based on Is there a “method_missing” for rake tasks?:
require 'rake'
namespace :long_namespace do
task :a do |tsk|
puts "inside #{tsk.name}"
end
end
rule "" do |tsk|
aliastask = tsk.name.sub(/short:/, 'long_namespace:')
Rake.application[aliastask].invoke
end
Rake.application['short:a'].invoke
The rule defines a task_missing-rule and tries to replace the namespace (in the example it replaces 'short' with 'long_namespace').
Disadvantage: An undefined task returns no error. So you need an adapted version:
require 'rake'
namespace :long_namespace do
task :a do |tsk|
puts "inside #{tsk.name}"
end
end
rule "" do |tsk|
aliastask = tsk.name.sub(/short:/, 'long_namespace:')
if Rake.application.tasks.map{|tsk| tsk.name }.include?( aliastask )
Rake.application[aliastask].invoke
else
raise RuntimeError, "Don't know how to build task '#{tsk.name}'"
end
end
Rake.application['short:a'].invoke
Rake.application['short:undefined'].invoke
And a more generalized version with a new method aliasnamespace to define the alias-namespaces:
require 'rake'
#Extend rake by aliases for namespaces
module Rake
ALIASNAMESPACES = {}
end
def aliasnamespace(alias_ns, original_ns)
Rake::ALIASNAMESPACES[alias_ns] = original_ns
end
rule "" do |tsk|
undefined = true
Rake::ALIASNAMESPACES.each{|aliasname, origin|
aliastask = tsk.name.sub(/#{aliasname}:/, "#{origin}:")
if Rake.application.tasks.map{|tsk| tsk.name }.include?( aliastask )
Rake.application[aliastask].invoke
undefined = false
end
}
raise RuntimeError, "Don't know how to build task '#{tsk.name}'" if undefined
end
#And now the usage:
namespace :long_namespace do
task :a do |tsk|
puts "inside #{tsk.name}"
end
end
aliasnamespace :short, 'long_namespace'
Rake.application['short:a'].invoke
#~ Rake.application['short:undefined'].invoke

Related

Prevent jekyll from cleaning up generated JSON file?

I've written a simple plugin that generates a small JSON file
module Jekyll
require 'pathname'
require 'json'
class SearchFileGenerator < Generator
safe true
def generate(site)
output = [{"title" => "Test"}]
path = Pathname.new(site.dest) + "search.json"
FileUtils.mkdir_p(File.dirname(path))
File.open(path, 'w') do |f|
f.write("---\nlayout: null\n---\n")
f.write(output.to_json)
end
# 1/0
end
end
end
But the generated JSON file gets deleted every time Jekyll runs to completion. If I uncomment the division by zero line and cause it to error out, I can see that the search.json file is being generated, but it's getting subsequently deleted. How do I prevent this?
I found the following issue, which suggested adding the file to keep_files: https://github.com/jekyll/jekyll/issues/5162 which worked:
The new code seems to avoid search.json from getting deleted:
module Jekyll
require 'pathname'
require 'json'
class SearchFileGenerator < Generator
safe true
def generate(site)
output = [{"title" => "Test"}]
path = Pathname.new(site.dest) + "search.json"
FileUtils.mkdir_p(File.dirname(path))
File.open(path, 'w') do |f|
f.write("---\nlayout: null\n---\n")
f.write(output.to_json)
end
site.keep_files << "search.json"
end
end
end
Add your new page to site.pages :
module Jekyll
class SearchFileGenerator < Generator
def generate(site)
#site = site
search = PageWithoutAFile.new(#site, site.source, "/", "search.json")
search.data["layout"] = nil
search.content = [{"title" => "Test 32"}].to_json
#site.pages << search
end
end
end
Inspired by jekyll-feed code.

ruby sketchup scene serialization

I am very new on Sketchup and ruby , I have worked with java and c# but this is the first time with ruby.
Now I have one problem, I need to serialize all scene in one json (scene hierarchy, object name, object material and position this for single object) how can I do this?
I have already done this for unity3D (c#) without a problem.
I tried this:
def main
avr_entities = Sketchup.active_model.entities # all objects
ambiens_dictionary = {}
ambiens_list = []
avr_entities.each do |root|
if root.is_a?(Sketchup::Group) || root.is_a?(Sketchup::ComponentInstance)
if root.name == ""
UI.messagebox("this is a group #{root.definition.name}")
if root.entities.count > 0
root.entities.each do |leaf|
if leaf.is_a?(Sketchup::Group) || leaf.is_a?(Sketchup::ComponentInstance)
UI.messagebox("this is a leaf #{leaf.definition.name}")
end
end
end
else
# UI.messagebox("this is a leaf #{root.name}")
end
end
end
end
Have you tried the JSON library
require 'json'
source = { a: [ { b: "hello" }, 1, "world" ], c: 'hi' }.to_json
source.to_json # => "{\"a\":[{\"b\":\"hello\"},1,\"world\"],\"c\":\"hi\"}"
Used the code below to answer a question Here, but it might also work here.
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.
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

RSpec - how to exclude spec files in subdirectory?

Say I have the following spec subdirectories:
lib
models
observers
workers
In the spec_helper.rb file, how do I tell rspec to exclude all spec files in the lib subdirectory?
Spork.prefork do
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
RSpec.configure do |config|
config.mock_with :rspec
config.use_transactional_fixtures = false
config.before(:suite) do
DatabaseCleaner.clean_with :truncation
DatabaseCleaner.strategy = :transaction
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
config.treat_symbols_as_metadata_keys_with_true_values = true
config.filter_run :focus => true
end
end
Spork.each_run do
FactoryGirl.reload
end
FYI - I'm using guard to auto-reload tests.
Not sure how to exclude but you can include a list in guard like this:
guard 'rspec', :spec_paths => ['spec/models', 'spec/workers', 'spec/observers'] do
# ...
end
One solution is Exclusion Filters:
RSpec.configure do |c|
# declare an exclusion filter
c.filter_run_excluding :broken => true
end
describe "something" do
it "does one thing" do
end
# tag example for exclusion by adding metadata
it "does another thing", :broken => true do
end
end
exclusion flag can be applied to describe and context too.
Also, this is useful config option:
RSpec.configure do |c|
c.run_all_when_everything_filtered = true
end
So if everything in /lib is excluded, you will still be able
to run specs manually with rspec spec/lib/

java.lang.Object.equals and java.lang.Object.hashCode have trouble with jruby object after serialization

I have some trouble using jruby objects into java
java side
package com.pp;
public interface ZeroI {
boolean equals(Object o);
int hashCode();
int hash();
}
package com.pp;
public class Tester {
public Object[] compare(ZeroI one, ZeroI two) {
return new Object[] {one.hashCode(), two.hashCode(), one.equals(two), one == two};
}
}
jruby side
include Java
import com.pp.Tester
import com.pp.ZeroI
module MMM
module Zero
def hash= value
#hash = value
end
def hash
#hash
end
def hashCode
#hash
end
def equals other
false
end
def == other
true
end
end
class OneClass
include ZeroI
include Zero
end
class TwoClass
include ZeroI
include Zero
end
def self.create clazz
begin
dump = IO.readlines("C:/#{clazz.to_s.rpartition('::')[2]}.txt", '').to_s
instance = Marshal.load dump
rescue => err
puts err.message
instance = clazz.new
dump = Marshal.dump instance
File.open("C:/#{clazz.to_s.rpartition('::')[2]}.txt", 'w') { |f| f.write dump }
end
instance
end
tester = Tester.new
one = create OneClass
two = create TwoClass
puts one
puts two
one.hash = 22
two.hash = 22
puts one.hashCode
puts two.hashCode
puts one.equals two
puts one == two
tester.compare(one, two).each { |value| puts value }
end
First pass result:
No such file or directory - C:/OneClass.txt
No such file or directory - C:/TwoClass.txt
#<MMM::OneClass:0x1971eb3>
#<MMM::TwoClass:0x1408a75>
22
22
false
true
22
22
true
false
true # it's OK because JAVA.equals works with JRUBY.==
false # it's OK because org.pp.ZeroI can't declare == method and JAVA.== is used
Second pass result (with deserialized objects)
#<MMM::OneClass:0xd510e8>
#<MMM::TwoClass:0x490342>
22
22
false
true
13046738 # but what is it?
31877484 # but what is it?
false # but what is it?
false
Can anybody explain it?
I don't know all the details about why this happens like it happens but I have a solution/workaround for you. (I've seen similar behaviour when passing objects that are created on the ruby side to the Java side.)
As far as I can tell JRuby needs to have already "seen" an instance of the class it is trying to unmarshal before it can get the Java-inheritance side of things right. It's almost as if creating an object within JRuby has an undocumented side-effect that registers the required inheritance hierarchy. If that isn't well worded it's because I don't understand it myself!
So the workaround is to simply create an instance of OneClass and TwoClass before doing the unmarshal. If I change the self.create method to the following:
def self.create clazz
begin
clazz.new # <<< just create an instance and throw it away!
dump = IO.readlines("C:/#{clazz.to_s.rpartition('::')[2]}.txt", '').to_s
instance = Marshal.load dump
rescue => err
puts err.message
instance = clazz.new
dump = Marshal.dump instance
File.open("C:/#{clazz.to_s.rpartition('::')[2]}.txt", 'w') { |f| f.write dump }
end
instance
end
Then the output of the two passes are as follows:
First pass
No such file or directory - C:/OneClass.txt
No such file or directory - C:/TwoClass.txt
#<MMM::OneClass:0x4de6f0ef>
#<MMM::TwoClass:0x4526ba64>
22
22
false
true
22
22
true
false
Second pass
#<MMM::OneClass:0x4858cca9>
#<MMM::TwoClass:0x3de4905a>
22
22
false
true
22
22
true
false
According to this bug report this is scheduled to be fixed in JRuby 1.7. It's worth noting that while the comments in the report say that the workaround is to call a method, passing an object instance in, it seems to be that the prior creation of the object is enough.

Attribute mysteriously getting set to id of 1

I have an object that is apparently randomly getting set to an id of 1 and the source of where this is happening is unknown in the codebase. Could be on an update attributes for a user for which school is associated.
How can I raise an error or otherwise log when this happens so I can track it down and resolve it?
Below is a first attempt but doesn't seem to take into account update_attributes
belongs_to :foo_school, :foreign_key => 'school_id'
def foo_school=(foo_school)
begin
raise "Found" if foo_school == FooSchool.find(1)
rescue Exception => e
# Track it down through the stack trace
Rails.logger.error e
ensure
write_attribute(:foo_school, foo_school)
end
end
An observer can do this for you. What you do with this observer is up to you.
$ rails g observer Oddity
Add this in config/application.rb (search for "observer" in that file, there's an example by default).
config.active_record.observers = :oddity_observer
class OddityObserver < ActiveRecord::Observer
observe :foo
def after_update(record)
raise "Boom" if record.id == 1
end
end