Class: SC::Project
- Inherits:
-
Object
- Object
- SC::Project
- Defined in:
- lib/sproutcore/models/project.rb
Overview
A project describes a collection of targets that you can build. Normally you instantiate a project by calling Project.load() method. You should pass in the path of the project and the project type. The project type will determine the namespace used in the buildfile to detect and load tasks.
Examples
Load a SproutCore-style project:
Project.load('myproject', :sproutcore)
Load a standard gcc-build project:
Project.load('myproject', :cc)
How a Project is Loaded
When you load a project, here is what happens:
-
Locate and load Buildfiles, if any are found
-
Run project_type:target:find for all targets defined for the project.
this will locate and define the targets for the project
-
If you request a build of a particular resource, a manifest will be built for the target. This manifest contains a series of rules that can be invoked in order to build the named resource.
Instance Attribute Summary collapse
-
#parent_project ⇒ Object
readonly
Parent project this project shoud inherit build rules and targets from.
-
#project_root ⇒ Object
readonly
the path of this project.
Class Method Summary collapse
-
.load(project_root, opts = {}) ⇒ Object
Returns a new project loaded from the specified path.
-
.load_nearest_project(path, opts = {}) ⇒ Object
Attempts to find the nearest project root.
Instance Method Summary collapse
-
#add_target(target_name, target_type, options = {}) ⇒ Object
Adds a new target to the project with the passed target name.
-
#buildfile ⇒ Object
The current buildfile for the project.
-
#config ⇒ Object
The config for the current project.
-
#find_targets_for(root_path, root_name, config) ⇒ Object
Called by project to discover any targets within the project itself.
-
#generator_for(generator_name, opts = {}) ⇒ Object
Attempts to discover and load a generator with the specified name from the current project.
-
#initialize(project_root, opts = {}) ⇒ Project
constructor
When a new project is created, you may optionally pass either a :parent option or a :paths options.
- #inspect ⇒ Object
- #reload! ⇒ Object
-
#target_for(target_name) ⇒ Object
Returns the target with the specified target name.
-
#targets ⇒ Object
A hash of the known targets for this project, including any targets inherited from a parent project.
Constructor Details
#initialize(project_root, opts = {}) ⇒ Project
When a new project is created, you may optionally pass either a :parent option or a :paths options. If you pass the paths option, then this class will search the paths for projects and initialize them as parent projects to this one.
If you pass a parent project, then this project will start out with a clone of the parent project’s buildfile and targets.
57 58 59 60 61 |
# File 'lib/sproutcore/models/project.rb', line 57 def initialize(project_root, opts ={}) @project_root = project_root @parent_project = opts[:parent] @buildfile = @targets = nil end |
Instance Attribute Details
#parent_project ⇒ Object (readonly)
Parent project this project shoud inherit build rules and targets from
43 44 45 |
# File 'lib/sproutcore/models/project.rb', line 43 def parent_project @parent_project end |
#project_root ⇒ Object (readonly)
the path of this project
40 41 42 |
# File 'lib/sproutcore/models/project.rb', line 40 def project_root @project_root end |
Class Method Details
.load(project_root, opts = {}) ⇒ Object
Returns a new project loaded from the specified path
82 83 84 |
# File 'lib/sproutcore/models/project.rb', line 82 def self.load(project_root, opts={}) new project_root, opts end |
.load_nearest_project(path, opts = {}) ⇒ Object
Attempts to find the nearest project root
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/sproutcore/models/project.rb', line 64 def self.load_nearest_project(path, opts={}) candidate = nil while path if Buildfile.has_buildfile?(path) candidate = path # If we find a buildfile and the buildfile explicitly states # that it is a project, then just stop here.. break if Buildfile.load(path).project? end new_path = File.dirname(path) path = (new_path == path) ? nil : new_path end (candidate) ? self.new(candidate, opts) : nil end |
Instance Method Details
#add_target(target_name, target_type, options = {}) ⇒ Object
Adds a new target to the project with the passed target name. Include the source_root for the target as well as any additional options you want copied onto the target. If a previous target was defined by the same name it will be replaced by this one.
Params
target_name:: the name of the target.
target_type:: the type of target
Options (any others allowed also)
source_root:: the absolute path to the target source
Returns
new target
183 184 185 186 |
# File 'lib/sproutcore/models/project.rb', line 183 def add_target(target_name, target_type, ={}) targets[target_name] = Target.new(target_name.to_sym, target_type.to_sym, .merge(:project => self)) end |
#buildfile ⇒ Object
The current buildfile for the project. The buildfile is calculated by merging any parent project buildfile with the contents of any buildfiles found in the current project. Buildfiles include any file named “Buildfile”, “sc-config”, or “sc-config.rb”. You can also specify your own buildfile names with the “buildfile_names” config in the SC.env.
Returns
Buildfile instance
100 101 102 |
# File 'lib/sproutcore/models/project.rb', line 100 def buildfile @buildfile ||= (parent_project.nil? ? Buildfile.new : parent_project.buildfile.dup).load!(project_root) end |
#config ⇒ Object
The config for the current project. The config is computed by merging the config settings from the current buildfile and then the current environment in the following order:
config for all modes, all targets +
config for current mode, all targets +
Current environment defined in SC.env
This is the config hash you should access to determine general project wide settings that cannot be overridden by individual targets.
Returns
merged HashStruct
118 119 120 |
# File 'lib/sproutcore/models/project.rb', line 118 def config return @config ||= buildfile.config_for(:all, SC.build_mode).merge(SC.env) end |
#find_targets_for(root_path, root_name, config) ⇒ Object
Called by project to discover any targets within the project itself.
The default implementation will search the project root directory for any directories matching those named in the “target_types” config. (See Buildfile for documentation). It will then recursively descend into each target looking for further nested targets unless you’ve set the “allow_nested_targets” config to false.
If you need to change the way the project autodiscovers its own targets you can either change the “target_types” and “allow_nested_targets” configs or you can override this method in your own ruby code to do whatever kind of changes you want.
Params
root_path:: The path to search for targets.
root_name:: The root target name
config:: The config hash to use for this. Should come from target
Returns
self
208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
# File 'lib/sproutcore/models/project.rb', line 208 def find_targets_for(root_path, root_name, config) # look for directories matching the target_types keys and create target # with target_types value as type. -- normalize to lowercase string target_types = {} (config.target_types || {}).each do |key, value| target_types[key.to_s.downcase] = value end # look for directories matching a target type Dir.glob(File.join(root_path, '*')).each do |dir_name| target_type = target_types[File.basename(dir_name).to_s.downcase] next if target_type.nil? next unless File.directory?(dir_name) # loop through each item in the directory. Dir.glob(File.join(dir_name,'*')).each do |source_root| next unless File.directory?(source_root) # compute target name and create target target_name = [root_name, File.basename(source_root)] * '/' target = self.add_target target_name, target_type, :source_root => source_root # if target's config allows nested targets, then call recursively # asking the target's config allows the target's Buildfile to # override the default. if target.config.allow_nested_targets find_targets_for(source_root, target_name, target.config) end end # Dir.glob end # target_type.each return self end |
#generator_for(generator_name, opts = {}) ⇒ Object
Attempts to discover and load a generator with the specified name from the current project. If the generator cannot be found, this method will return nil.
250 251 252 253 |
# File 'lib/sproutcore/models/project.rb', line 250 def generator_for(generator_name, opts={}) opts[:target_project] = self return SC::Generator.load(generator_name, opts) end |
#inspect ⇒ Object
45 46 47 |
# File 'lib/sproutcore/models/project.rb', line 45 def inspect "SC::Project(#{File.basename(project_root || '')})" end |
#reload! ⇒ Object
86 87 88 |
# File 'lib/sproutcore/models/project.rb', line 86 def reload! @buildfile = @targets = nil end |
#target_for(target_name) ⇒ Object
Returns the target with the specified target name. The target name may be absolute path or not, both will lookup from the top.
Params
target_name:: the target to lookup
Returns
a Target instance or nil if no matching target could be found
163 164 165 166 |
# File 'lib/sproutcore/models/project.rb', line 163 def target_for(target_name) ret = (targets[target_name.to_s.sub(/^([^\/])/,'/\1')]) ret.nil? ? nil : ret end |
#targets ⇒ Object
A hash of the known targets for this project, including any targets inherited from a parent project. Each target is stored in the hash by target_name.
The first time this method is called, the project will automatically clone any targets from a parent project, and then calls find_targets_for() on itself to recursively discover any targets in the project.
If you need to change the way the project discovers project, override find_targets_for() instead of this method.
Returns
Hash of targets keyed by target_name
141 142 143 144 145 146 147 148 149 150 151 152 |
# File 'lib/sproutcore/models/project.rb', line 141 def targets return @targets unless @targets.nil? # Create an empty targets hash or clone from parent project @targets = HashStruct.new dup_targets(parent_project.targets) if parent_project # find targets inside project. find_targets_for(project_root, nil, self.config) return @targets end |