Permalink
Browse files

Added further unit tests for target; cleaned up left over files. bund…

…le class still needs to be removed once everything useful is out of it. Also roughed in Tool::Manifest
  • Loading branch information...
Charles Jolley
Charles Jolley committed Jan 9, 2009
1 parent 19a032a commit 4957ea3a04e04c44b9c9c2a00568c612ba98a63b
View
@@ -1,5 +1,10 @@
config :all,
- :url_prefix => 'static',
+
+ # REQUIRED CONFIGS
+ # You will not usually need to override these configs, but the code assumes
+ # they will be present, so you must support them.
+ :public_prefix => 'public',
+ :url_prefix => 'static',
# Defines the directories that may contain targets, and maps them to a
# target type. When a project tries to find all of the targets in a
View
@@ -21,6 +21,14 @@ def deep_clone
sibling
end
+ # Returns true if the receiver has all of the options set
+ def has_options?(opts = {})
+ opts.each do |key, value|
+ return false if self[key] != value
+ end
+ return true
+ end
+
######################################################
# INTERNAL SUPPORT
#
View
@@ -7,16 +7,19 @@ module Abbot
#
class Manifest < HashStruct
- attr_reader :bundle
+ attr_reader :target
attr_reader :entries
- def initialize(bundle, language)
- super()
- @bundle = bundle
+ def initialize(target, opts)
+ super(opts)
+ @target = target
@entries = []
- @needs_build = true
+ @is_prepared = NO
end
+ def prepared?; @is_prepared; end
+ def prepared!; @is_prepared = YES; end
+
# Reset the manifest. This will clear out the existing manifest and set
# it to need another build. The next time you call build!, the manifest
# will be rebuilt.
View
@@ -45,6 +45,10 @@ def initialize(target_name, target_type, opts={})
end
attr_reader :project
+
+ ######################################################
+ # CONFIG
+ #
# Returns the buildfile for this target. The buildfile is a clone of
# the parent target buildfile with any buildfile found in the current
@@ -66,6 +70,64 @@ def buildfile
def config
return @config ||= buildfile.config_for(target_name, Abbot.build_mode).merge(Abbot.env)
end
+
+ # Clears the cached config, reloading it from the buildfile again. This
+ # is mostly used for unit testing.
+ def reload_config!
+ @config= nil
+ return self
+ end
+
+
+ ######################################################
+ ## COMPUTED HELPER PROPERTIES
+ ##
+
+ # Returns all of the targets required by this target. This will use the
+ # "required" config, resolving the target names using target_for().
+ #
+ # === Returns
+ # Array of Targets
+ #
+ def required_targets
+ @required_target ||= [config.required || []].flatten.compact.map { |target_name| target_for(target_name) }.compact
+ end
+
+ # Returns the expanded list of required targets, ordered as they actually
+ # need to be loaded.
+ def expand_required_targets
+ seen = []
+ ret = []
+ required_targets.each do |target|
+ next if seen.include?(target)
+ seen << target # avoid loading again
+
+ # add required targets, if not already seend...
+ target.expand_required_targets.each do |required|
+ next if seen.include?(required)
+ ret << required
+ seen << required
+ end
+ end
+ return ret
+ end
+
+ # Returns the root url that should prefix every built manifest entry
+ # This is composed from the target name and the global url prefix.
+ def url_root
+ self[:url_root] || config.url_root || ['/', config.url_prefix, target_name].join('')
+ end
+
+ # The full path to the build root of the bundle. Unless you specify the
+ # build_root + bundle_build_root options, this will be computed from the
+ # public_root + url_prefix + bundle_name
+ def build_root
+ self[:build_root] || config.build_root || File.join(project.project_root.to_s, config.public_prefix.to_s, config.url_prefix.to_s, target_name.to_s)
+ end
+
+ ######################################################
+ # MANIFEST
+ #
# An array of manifests for the target. You can retrieve the manifest
# for a particular variation using the method manifest_for().
@@ -76,13 +138,13 @@ def manifests; @manifests ||= []; end
def manifest_for(variation={})
ret = manifests.find { |m| m.has_options?(variation) }
if ret.nil?
- ret = Manifest.new(variation.merge(:target => self)).prepare!
+ ret = Manifest.new(self, variation)
@manifests << ret
end
return ret
end
- ########################################################################
+ ######################################################
# TARGET METHODS
#
@@ -46,6 +46,33 @@ def self.prepare(manifest)
return manifest
end
+ # Entry point for a command line tool.
+ desc "prepare TARGET", "generates a manifest file for the target"
+ method_options :language => :optional, :project => :optional, :output => :optional
+ def prepare(target)
+ self.project = Abbot::Project.load_nearest_project(options.project || Dir.pwd)
+ raise "You do not appear to be in a project" if self.project.nil?
+
+ self.target = project.target_for(target_name = target)
+ raise "#{target_name} could not be found in project" if self.target.nil?
+
+ if options.language
+ languages = options.language.split(',')
+ else
+ languages = target.installed_languages
+ end
+ manifests = languages.map do |language|
+ self.manifest = target.manifest_for(:language => language)
+ prepare!
+ self.manifest
+ end
+
+ output = options.output.nil? ? STDOUT : File.open(options.output, 'w+')
+ output.write manifests.to_yaml
+ output.close
+ return 0
+ end
+
# main entry point. This method is called right after any options are
# processed to actually perform transforms on the manifest. The
# default behavior simply calls out to several other transform methods
@@ -1 +0,0 @@
-Generic Readme -- should be excluded from final build
@@ -1 +0,0 @@
-// ENGLISH - localized javascript
@@ -1 +0,0 @@
-<!-- ENGLISH - Localized RHTML -->
@@ -1 +0,0 @@
-// FRENCH - localized javascript
@@ -1 +0,0 @@
-// ITALIAN - localized javascript
@@ -1 +0,0 @@
-<!-- ITALIAN - Localized RHTML -->
@@ -1 +0,0 @@
-test1
@@ -1 +0,0 @@
-// Unlocalized JavaScript File
@@ -1,7 +0,0 @@
-config :all,
- # required by bundle/environment_spec
- :key3 => 'nested_app1'
-
-config 'lib1/nested_app1',
- # required by bundle/environment_spec
- :key6 => 'nested:nested_app1'
@@ -1,9 +0,0 @@
-config :all,
- # required by bundle/environment_spec
- :key2 => 'lib1',
- :key3 => 'lib1'
-
-config 'lib1/nested_app1',
- # required by bundle/environment_spec
- :key5 => 'nested:lib1'
-
@@ -1,16 +0,0 @@
-config :all do |c|
- # required by bundle/environment_spec
- %w(key1 key2 key3 key4 key5 key6).each { |k| c[k] = :basic_library }
- c.is_production = false
-end
-
-config 'lib1/nested_app1',
- # required by bundle/environment_spec
- :key4 => 'nested:basic_library',
- :key5 => 'nested:basic_library',
- :key6 => 'nested:basic_library'
-
-mode :production do
- config :all, :is_production => true
-end
-
@@ -1 +0,0 @@
-This directory should NOT contain a buildfile. Used in project/buildfile_spec
@@ -1,89 +0,0 @@
-# This is a sample buildfile for a GCC driven project. The project will find
-# all .c files and compile them to a target matching the name of the parent
-# directory by default. The output will be stored in 'builds' and staging in
-# 'staging'
-
-####################################
-# CONFIGURATION
-#
-
-# Set the name and type for this project. If this is not defined here it will
-# be assumed from the global environment settings
-project :hello_world => :cc
-
-# Setup some default configuration
-config :all, :build_path => './builds',
- :staging_path => './staging',
- :compiler => 'gcc',
- :linker => 'ln'
-
-####################################
-# DESCRIBE A CC PROJECT
-#
-project :cc do
-
- # Describe the target type
- target :default do
-
- # Finding the target is easy...it's just the project root.
- task :find do
- PROJECT.add_target :source_root => PROJECT.project_root
- end
-
- # The default target has a manifest:prepare task that catalogs
- # entires. Let's now go through and hide all .h files
- manifest :hide_headers => :catalog_entries do
- MANIFEST.entries.each { |e| e.hide! if e.ext == 'h' }
- end
- manifest :prepare => :hide_headers
-
- # Next we need synthesize entries that will compile objects for anything
- # with a '.c' extension. Also find includes and match those.
- manifest :to_objects => :catalog_entries do
- MANIFEST.entries.each do |entry|
- next if entry.ext != 'c'
-
- # find headers that are referenced in this file via #include "foo.h"
- src = entry.search_source(/^\s*#include\s+"(.+)"/)
- src.map do |header|
- header = header.to_a[1] # get match
- MANIFEST.entry_for(header) # look for matching entry
- end
- src.compact!
- src << entry # add original entry
-
- MANIFEST.add_composite entry.filename.ext('o'),
- :build_task => :compile_cc,
- :from => src
- end
- end
-
- # Finally, we need to add a composite that will produce the final
- # target.
- manifest :final => :to_objects do
- entries = MANIFEST.entries.reject { |e| e.ext != 'o' }
- MANIFEST.add_composite File.basename(TARGET.target_name),
- :build_task => :link,
- :from => entries
- end
- end
-
- end
-
- # Thus ends the targets.
- # Now let's define some useful build tasks. You can add any others
- # that you want. Note that the default build task only runs if the dst
- # file is older than src files.
- build_task :compile_cc do
- sh "#{CONFIG.compiler} #{SRC_PATHS * ' '} -o #{DST_PATH} #{CONFIG.build_flags}"
- end
-
- build_task :link do
- sh "#{CONFIG.linker} #{SRC_PATHS} -o #{DST_PATH}"
- end
-
-end
-
-
-
-
@@ -1 +0,0 @@
-config :all, :installed_lib1 => true
@@ -1,2 +0,0 @@
-# used by environment_spec
-config :all, :installed_key => :installed_library
@@ -3,4 +3,6 @@
# This is the generic requirement for most apps. Of course SproutCore will
# override this for itself, so you don't have to worry about it causing
# trouble.
-config :all, :required => :sproutcore
+config :all, :required => :sproutcore
+
+config :mobile_photos, :required => 'sproutcore/mobile'
Oops, something went wrong.

0 comments on commit 4957ea3

Please sign in to comment.