5

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
Chris Kempson
  • 319
  • 1
  • 3
  • 13

1 Answers1

6

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
Community
  • 1
  • 1
knut
  • 27,320
  • 6
  • 84
  • 112
  • 2
    Simple example for a "need" of a namespace alias. I'm using AR without Rails, and I wanted to recreate some Rails commands as Rake tasks. Having `rake generate:migration` and `rake g:migration` would be great. – Jerska Dec 26 '13 at 10:52
  • 2
    @Jerska You made me to think again for this question: I added a 2nd answer. – knut Dec 26 '13 at 20:03
  • Wow, really awesome answer ! Thanks ! May your name be honored, your kingdom come soon, etc. ! – Jerska Dec 29 '13 at 19:32