Class: Chrysalis::Loader

Inherits:
Object show all
Includes:
Singleton
Defined in:
lib/chrysalis/loader.rb

Overview

Loader is responsible for loading rakefiles.

The loader loads the rakefiles defined by dependencies. The tasks defined within a dependency rakefile are intercepted and re-synthesized as all:* tasks.

Additionally, a hook is declared in order to receive notification that the main rakefile has been loaded. The tasks in the main rakefile serve to seed the all: namespace with tasks, prior to retrieving any dependencies.

Instance Method Summary collapse

Constructor Details

#initializeLoader

Returns a new instance of Loader.



17
18
19
20
21
22
23
24
# File 'lib/chrysalis/loader.rb', line 17

def initialize
  @loading = :main
  @icept_scope = []
  @icept_tasks = []
  @last_comment = nil
  
  Chrysalis.hook :rakefile_loaded, self.method(:on_rakefile_loaded).to_proc
end

Instance Method Details

#desc_intercept(comment) ⇒ Object



92
93
94
95
# File 'lib/chrysalis/loader.rb', line 92

def desc_intercept(comment)
  @last_comment = comment
  yield if @loading == :main
end

#file_task_intercept(name) ⇒ Object



86
87
88
89
90
# File 'lib/chrysalis/loader.rb', line 86

def file_task_intercept(name)
  @icept_tasks << [name, @last_comment]
  @last_comment = nil
  yield if @loading == :main
end

#load(url, working_copy) ⇒ Object

Loads a dependency’s rakefile.

The url is the location of the repository from which the dependency was retrieved. The working_copy is the WorkingCopy retrieved.

This function will search for and load the rakefile found in the working copy’s path, if one exists.



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/chrysalis/loader.rb', line 38

def load(url, working_copy)
  @loading = url
  
  Rake::Application::DEFAULT_RAKEFILES.each do |file|
    path = Pathname.new(working_copy.path).join(file)
    
    if File.exist?(path)
      Kernel.load(path, true)
      return
    end
  end
  
ensure
  # If the manifest does not contain an entry for the URL being loaded, one
  # of two things occured:
  #  1. a project was not instantiated in the rakefile  -- or --
  #  2. no rakefile existed in the working copy's path 
  #
  # In either case, an empty project will be created as a placeholder.
  
  if Chrysalis::Manifest.instance[@loading].nil?
    proj = Project.new
  end
  
  Chrysalis::Manifest.instance[@loading].working_copy = working_copy
  Chrysalis.post :rakefile_loaded
end

#loadingObject

Returns the URL of the project currently being loaded.



27
28
29
# File 'lib/chrysalis/loader.rb', line 27

def loading
  @loading
end

#namespace_intercept(name, orig_block) ⇒ Object

– TODO: If name is nil, Rake generates an anonymous namespace. Chrysalis

currently does not support this feature.  In practice, anonymous
namespaces are rarely used.  However, support should be implemented
for maximum compatibility.


102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/chrysalis/loader.rb', line 102

def namespace_intercept(name, orig_block)
  @icept_scope.push(name)

  # Call the original block given to the namespace.  This allows is to
  # progress deeper, intercepting further tasks within the namespace.
  #
  # TODO: Rake instantiates a NameSpace, which is yeiled as a parameter.
  #       In practice, most code doesn't expect this parameter.  However,
  #       support for it is currently unimplemented, but should be
  #       implemented for maximum compatibility.
  #
  #       Example:
  #         orig_block.call(a_namespace)
  if @loading != :main
    orig_block.call
  else
    yield
  end
  
ensure
  @icept_scope.pop
end

#on_rakefile_loadedObject

:nodoc:



66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/chrysalis/loader.rb', line 66

def on_rakefile_loaded  # :nodoc:
  return if Chrysalis::Manifest.instance[@loading].nil?
  
  @icept_tasks.each do |task|
    Chrysalis::Manifest.instance[@loading].task(task[0], task[1])
    Chrysalis::TaskManager.synthesize_task(task[0], task[1])
  end
  
ensure
  @loading = :main
  @icept_tasks = []
end

#rule_interceptObject



125
126
127
# File 'lib/chrysalis/loader.rb', line 125

def rule_intercept
  yield if @loading == :main
end

#task_intercept(name) ⇒ Object



79
80
81
82
83
84
# File 'lib/chrysalis/loader.rb', line 79

def task_intercept(name)
  scoped_name = (@icept_scope + [name]).join(':')
  @icept_tasks << [scoped_name, @last_comment]
  @last_comment = nil
  yield if @loading == :main
end