buildr-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From as...@apache.org
Subject svn commit: r645019 - in /incubator/buildr/trunk: ./ lib/ lib/buildr/core/ lib/buildr/java/ spec/
Date Sat, 05 Apr 2008 02:41:03 GMT
Author: assaf
Date: Fri Apr  4 19:41:01 2008
New Revision: 645019

URL: http://svn.apache.org/viewvc?rev=645019&view=rev
Log:
Added experimental support for YAML configuration files:
- settings.yaml found in ~/.buildr for user settings (username, password, etc)
- build.yaml file found next to buildfile for project settings (dependencies, defaults, etc)
- profiles.yaml file found next to buildfile for profile-specific settings
    
You can use build.yaml to force a Gem to be loaded before buildfile, e.g.:
  gems:
  - extra-stuff
  - other-features ~> 2.1

Buildr will offer to install these gems when running interactively.

Added:
    incubator/buildr/trunk/spec/application_spec.rb
Modified:
    incubator/buildr/trunk/CHANGELOG
    incubator/buildr/trunk/lib/buildr.rb
    incubator/buildr/trunk/lib/buildr/core/addon.rb
    incubator/buildr/trunk/lib/buildr/core/application.rb
    incubator/buildr/trunk/lib/buildr/core/common.rb
    incubator/buildr/trunk/lib/buildr/core/environment.rb
    incubator/buildr/trunk/lib/buildr/java/bdd_frameworks.rb
    incubator/buildr/trunk/spec/artifact_spec.rb
    incubator/buildr/trunk/spec/common_spec.rb
    incubator/buildr/trunk/spec/project_spec.rb
    incubator/buildr/trunk/spec/sandbox.rb
    incubator/buildr/trunk/spec/spec_helpers.rb

Modified: incubator/buildr/trunk/CHANGELOG
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/CHANGELOG?rev=645019&r1=645018&r2=645019&view=diff
==============================================================================
--- incubator/buildr/trunk/CHANGELOG (original)
+++ incubator/buildr/trunk/CHANGELOG Fri Apr  4 19:41:01 2008
@@ -24,6 +24,10 @@
 * Added: JRuby 1.1 support (Victor Hugo Borja, Nick Sieger).
 * Added: IDEA 7 task: use buildr idea7x (Shane Witbeck).
 * Added: Experimental support for addons.
+* Added: Experimental support for YAML configurtion files settings.yaml (in
+~/.buildr), build.yaml (next to buildfile) and profiles.yaml.
+* Added: Ability to create a package that is not an artifact and specify the
+target file using the :file argument.
 * Changed: JUnit/TestNG test cases are selected by superClass or annotations,
 not by class-name pattern.
 * Changed: Upgraded to Antwrap 0.7.0, thanks to Caleb Powell for relicensing

Modified: incubator/buildr/trunk/lib/buildr.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/lib/buildr.rb?rev=645019&r1=645018&r2=645019&view=diff
==============================================================================
--- incubator/buildr/trunk/lib/buildr.rb (original)
+++ incubator/buildr/trunk/lib/buildr.rb Fri Apr  4 19:41:01 2008
@@ -29,6 +29,7 @@
   VERSION = '1.3.0'.freeze # unless const_defined?(:VERSION)
 end
 
+
 require 'buildr/core'
 require 'buildr/tasks'
 require 'buildr/java'

Modified: incubator/buildr/trunk/lib/buildr/core/addon.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/lib/buildr/core/addon.rb?rev=645019&r1=645018&r2=645019&view=diff
==============================================================================
--- incubator/buildr/trunk/lib/buildr/core/addon.rb (original)
+++ incubator/buildr/trunk/lib/buildr/core/addon.rb Fri Apr  4 19:41:01 2008
@@ -16,83 +16,11 @@
 
 require 'buildr/core/package'
 require 'buildr/tasks/zip'
-$LOADED_FEATURES << 'rubygems/open-uri.rb' # We already have open-uri, RubyGems loads
a different one
-require 'rubygems/source_info_cache'
-require 'rubygems/doc_manager'
-require 'rubygems/format'
 require 'rubyforge'
 
 
 module Buildr
 
-  # :call-seq:
-  #   addon(name, version?)
-  #   addon(task)
-  #
-  # Use the specified addon, downloading and install it, if necessary.
-  #
-  # Addons are essentially Ruby gems, but installed and loaded differently:
-  # * The addon method downloads and installs the gem, if necessary.
-  # * It requires a Ruby file with the same name as the gem, if it finds one.
-  # * It imports all .rake files found in the Gem's tasks directory.
-  #
-  # The first form takes the gem's name and optional version requirement.  The default
-  # version requirement is '>= 0' (see RubyGem's gem method for more information).
-  # For example:
-  #   addon 'buildr-java', '~> 1.0'
-  #
-  # The second form takes a file task that points to the Gem file.
-  def addon(name_or_path, version = nil)
-    case name_or_path
-    when Rake::FileTask
-      path = name_or_path.to_s
-      spec = Gem::Format.from_file_by_path(path).spec
-    when String
-      dep = Gem::Dependency.new(name_or_path, version)
-      #spec = Gem::SourceIndex.from_installed_gems.search(dep).last || Gem::SourceInfoCache.search(dep).last
-      unless spec = Gem::SourceIndex.from_installed_gems.search(dep).last
-        Gem::SourceInfoCache.search(dep).last
-        Gem::SourceInfoCache.cache.flush
-        fail Gem::LoadError, "Could not find #{name_or_path} locally or in remote repository."
unless spec
-      end
-    else fail "First argument must be Gem name or File task."
-    end
-
-    if Gem::SourceIndex.from_installed_gems.search(spec.name, spec.version).empty?
-      say "Installing #{spec.full_name} ... " if verbose
-      cmd = Config::CONFIG['ruby_install_name'], '-S', 'gem', 'install', name_or_path.to_s
-      cmd << '-v' << spec.version.to_s
-      cmd.unshift 'sudo' unless Gem.win_platform? || RUBY_PLATFORM =~ /java/
-      sh *cmd.push(:verbose=>false)
-      Gem.source_index.load_gems_in Gem::SourceIndex.installed_spec_directories
-      # NOTE:  The nice thing would be to do a Gem install from the process,
-      #        but installing the documenation requires RDoc, and RDoc defines
-      #        one too many top-level classes which mess with our stuff.
-=begin
-      require 'rubygems/dependency_installer'
-      installer = Gem::DependencyInstaller.new(path || name, version.to_s).tap do |installer|
-        installer.install 
-        say 'Installed'
-        installer.installed_gems.each do |spec|
-          # NOTE:  RI documentation must be generated before RDoc.
-          Gem::DocManager.new(spec, nil).generate_ri
-          Gem::DocManager.new(spec, nil).generate_rdoc
-          Gem.source_index.add_spec spec
-        end
-      end
-=end
-    end
-    
-    Gem.activate(spec.name, true, spec.version).tap do
-      FileList[spec.require_paths.map { |path| File.expand_path("#{path}/*.rb", spec.full_gem_path)
}].
-        map { |path| File.basename(path) }.each { |file| require file }
-      FileList[File.expand_path('tasks/*.rake', spec.full_gem_path)].each do |file|
-        Rake.application.add_import file
-      end
-    end
-  end
-
-
   class PackageGemTask < ArchiveTask
 
     def initialize(*args)
@@ -107,13 +35,13 @@
 
     def install
       cmd = Config::CONFIG['ruby_install_name'], '-S', 'gem', 'install', name
-      cmd .unshift 'sudo' unless Gem.win_platform? || RUBY_PLATFORM =~ /java/
+      cmd .unshift 'sudo' unless Gem.win_platform?
       sh *cmd
     end
 
     def uninstall
       cmd = Config::CONFIG['ruby_install_name'], '-S', 'gem', 'uninstall', spec.name, '-v',
spec.version.to_s
-      cmd .unshift 'sudo' unless Gem.win_platform? || RUBY_PLATFORM =~ /java/
+      cmd .unshift 'sudo' unless Gem.win_platform?
       sh *cmd
     end
 

Modified: incubator/buildr/trunk/lib/buildr/core/application.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/lib/buildr/core/application.rb?rev=645019&r1=645018&r2=645019&view=diff
==============================================================================
--- incubator/buildr/trunk/lib/buildr/core/application.rb (original)
+++ incubator/buildr/trunk/lib/buildr/core/application.rb Fri Apr  4 19:41:01 2008
@@ -36,97 +36,205 @@
 
 
 require 'benchmark'
+require 'rake'
+require 'rubygems/source_info_cache'
+require 'buildr/core/application_cli'
+
+
+# Gem::user_home is nice, but ENV['HOME'] lets you override from the environment.
+ENV["HOME"] ||= File.expand_path(Gem::user_home)
+ENV['BUILDR_ENV'] ||= 'development'
+
+# Add a touch of colors (red) to warnings.
+HighLine.use_color = !Gem.win_platform?
 
 
 module Buildr
 
-  # Gem::user_home is nice, but ENV['HOME'] lets you override from the environment.
-  ENV["HOME"] ||= File.expand_path(Gem::user_home)
+  class Application < Rake::Application #:nodoc:
 
-  # When running from +rake+, we already have an Application setup and must plug into it,
-  # since the top-level tasks come from there. When running from +buildr+, we get to load
-  # Rake and set everything up, and we use our own Application full of cool Buildr features.
-  if defined?(Rake)
-    Rake.application.top_level_tasks.unshift task('buildr:initialize')
-  else
-
-    require 'rake'
-
-    class Application < Rake::Application #:nodoc:
-
-      DEFAULT_BUILDFILES = ['buildfile', 'Buildfile'] + DEFAULT_RAKEFILES
-      
-      require 'buildr/core/application_cli'
-      include CommandLineInterface
-
-      attr_reader :rakefiles, :requires
-      private :rakefiles, :requires
-
-      def initialize()
-        super
-        @rakefiles = DEFAULT_BUILDFILES
-        @name = 'Buildr'
-        @requires = []
-        @top_level_tasks = []
-        parse_options
-        collect_tasks
-        top_level_tasks.unshift 'buildr:initialize'
-      end
-
-      def run()
-        times = Benchmark.measure do
-          standard_exception_handling do
-            find_buildfile
-            load_buildfile
-            top_level
-          end
-        end
-        if verbose
-          real = []
-          real << ("%ih" % (times.real / 3600)) if times.real >= 3600
-          real << ("%im" % ((times.real / 60) % 60)) if times.real >= 60
-          real << ("%.3fs" % (times.real % 60))
-          puts "Completed in #{real.join}"
-        end
+    DEFAULT_BUILDFILES = ['buildfile', 'Buildfile'] + DEFAULT_RAKEFILES
+    
+    include CommandLineInterface
+
+    attr_reader :rakefiles, :requires
+    private :rakefiles, :requires
+
+    def initialize
+      super
+      @rakefiles = DEFAULT_BUILDFILES
+      @name = 'Buildr'
+      @requires = []
+      @top_level_tasks = []
+      @home_dir = File.expand_path('.buildr', ENV['HOME'])
+      @environment = ENV['BUILDR_ENV']
+      parse_options
+      collect_tasks
+      top_level_tasks.unshift 'buildr:initialize'
+      mkpath @home_dir unless File.exist?(@home_dir)
+    end
+
+    # Returns list of Gems associated with this buildfile, as listed in build.yaml.
+    # Each entry is of type Gem::Specification.
+    attr_reader :gems
+
+    # Buildr home directory, .buildr under user's home directory.
+    attr_reader :home_dir
+
+    # Copied from BUILD_ENV.
+    attr_reader :environment
+
+    # User settings loaded from settings.yaml (Hash).
+    def settings
+      unless @settings
+        file_name = ['settings.yaml', 'settings.yml'].map { |fn| File.expand_path(fn, home_dir)
}.find { |fn| File.exist?(fn) }
+        @settings = file_name && YAML.load(File.read(file_name)) || {}
+        fail "Expecting #{file_name} to be a hash!" unless Hash === @settings
       end
+      @settings
+    end
 
-      def find_buildfile()
-        here = Dir.pwd
-        while ! have_rakefile
-          Dir.chdir('..')
-          if Dir.pwd == here || options.nosearch
-            error = "No Buildfile found (looking for: #{@rakefiles.join(', ')})"
-            if STDIN.isatty
-              chdir(original_dir) { task('generate').invoke }
-              exit 1
-            else
-              raise error
-            end
-          end
-          here = Dir.pwd
-        end
+    # Configuration loaded from build.yaml (Hash).
+    def configuration
+      unless @config
+        file_name = ['build.yaml', 'build.yml'].map { |fn| File.expand_path(fn, File.dirname(buildfile))
}.find { |fn| File.exist?(fn) }
+        @config = file_name && YAML.load(File.read(file_name)) || {}
+        fail "Expecting #{file_name} to be a hash!" unless Hash === @config
       end
+      @config
+    end
+
+    # :call-seq:
+    #    profile => hash
+    #
+    # Returns the profile for the current environment.
+    def profile
+      profiles[environment] ||= {}
+    end
 
-      def load_buildfile()
-        @requires.each { |name| require name }
-        puts Buildr.environment ? "(in #{Dir.pwd}, #{Buildr.environment})" : "(in #{Dir.pwd})"
-        load File.expand_path(@rakefile) if @rakefile != ''
-        load_imports
+    # :call-seq:
+    #    profiles => hash
+    #
+    # Returns all the profiles loaded from the profiles.yaml file.
+    def profiles
+      unless @profiles
+        file_name = ['profiles.yaml', 'profiles.yml'].map { |fn| File.expand_path(fn, File.dirname(buildfile))
}.find { |fn| File.exist?(fn) }
+        @profiles = file_name && YAML.load(File.read(file_name)) || {}
+        fail "Expecting #{file_name} to be a hash!" unless Hash === @profiles
+        @profiles = profiles.inject({}) { |hash, (name, value)| value ||= {} 
+          raise 'Each profile must be empty or contain name/value pairs.' unless Hash ===
value
+          hash.merge(name=>(value || {})) }
       end
+      @profiles
+    end
+
+    # :call-seq:
+    #   buildfile
+    def buildfile
+      rakefile
+    end
 
+    # :call-seq:
+    #   build_files => files
+    #
+    # Returns a list of build files. These are files used by the build, 
+    def build_files
+      [buildfile].compact + Array(@build_files)
     end
 
-    Rake.application = Buildr::Application.new
-  end
+    # Returns Gem::Specification for every listed and installed Gem, Gem::Dependency
+    # for listed and uninstalled Gem, which is the installed before loading the buildfile.
+    def listed_gems #:nodoc:
+      Array(configuration['gems']).map do |dep|
+        name, trail = dep.scan(/^\s*(\S*)\s*(.*)\s*$/).first
+        versions = trail.scan(/[=><~!]{0,2}\s*[\d\.]+/)
+        versions = ['>= 0'] if versions.empty?
+        dep = Gem::Dependency.new(name, versions)
+        Gem::SourceIndex.from_installed_gems.search(dep).last || dep
+      end
+    end
+    private :listed_gems
 
+    def run
+      times = Benchmark.measure do
+        standard_exception_handling do
+          find_buildfile
+          load_gems
+          load_buildfile
+          top_level
+          load_tasks
+        end
+      end
+      if verbose
+        real = []
+        real << ("%ih" % (times.real / 3600)) if times.real >= 3600
+        real << ("%im" % ((times.real / 60) % 60)) if times.real >= 60
+        real << ("%.3fs" % (times.real % 60))
+        puts "Completed in #{real.join}"
+      end
+    end
 
-  class << self
+    # Load/install all Gems specified in build.yaml file.
+    def load_gems #:nodoc:
+      missing_deps, installed = listed_gems.partition { |gem| gem.is_a?(Gem::Dependency)
}
+      unless missing_deps.empty?
+        remote = missing_deps.map { |dep| Gem::SourceInfoCache.search(dep).last || dep }
+        not_found_deps, install = remote.partition { |gem| gem.is_a?(Gem::Dependency) }
+        fail Gem::LoadError, "Build requires the gems #{not_found_deps.join(', ')}, which
cannot be found in local or remote repository." unless not_found_deps.empty?
+        uses = "This build requires the gems #{install.map(&:full_name).join(', ')}:"
+        fail Gem::LoadError, "#{uses} to install, run Buildr interactively." unless $stdout.isatty
+        unless agree("#{uses} do you want me to install them? [Y/n]", true)
+          fail Gem::LoadError, 'Cannot build without these gems.'
+        end
+        install.each do |spec|
+          say "Installing #{spec.full_name} ... " if verbose
+          cmd = Config::CONFIG['ruby_install_name'], '-S', 'gem', 'install', spec.name, '-v',
spec.version.to_s
+          cmd.unshift 'sudo' unless Gem.win_platform? || RUBY_PLATFORM =~ /java/
+          sh *cmd.push(:verbose=>false)
+          Gem.source_index.load_gems_in Gem::SourceIndex.installed_spec_directories
+        end
+        installed += install
+      end
+
+      installed.each do |spec|
+        if gem(spec.name, spec.version.to_s)
+        #  FileList[spec.require_paths.map { |path| File.expand_path("#{path}/*.rb", spec.full_gem_path)
}].
+        #    map { |path| File.basename(path) }.each { |file| require file }
+        #  FileList[File.expand_path('tasks/*.rake', spec.full_gem_path)].each do |file|
+        #    Rake.application.add_import file
+        #  end
+        end
+      end
+      @gems = installed
+    end
+
+    def find_buildfile
+      here = Dir.pwd
+      while ! have_rakefile
+        Dir.chdir('..')
+        if Dir.pwd == here || options.nosearch
+          error = "No Buildfile found (looking for: #{@rakefiles.join(', ')})"
+          if STDIN.isatty
+            chdir(original_dir) { task('generate').invoke }
+            exit 1
+          else
+            raise error
+          end
+        end
+        here = Dir.pwd
+      end
+    end
+
+    def load_buildfile
+      @requires.each { |name| require name }
+      puts "(in #{Dir.pwd}, #{environment})"
+      load File.expand_path(@rakefile) if @rakefile != ''
+      load_imports
+    end
 
     # Loads buildr.rake files from users home directory and project directory.
     # Loads custom tasks from .rake files in tasks directory.
-    def load_tasks_and_local_files() #:nodoc:
-      return false if @build_files
-      # Load the settings files.
+    def load_tasks #:nodoc:
       @build_files = [ File.expand_path('buildr.rb', ENV['HOME']), 'buildr.rb' ].select {
|file| File.exist?(file) }
       @build_files += [ File.expand_path('buildr.rake', ENV['HOME']), File.expand_path('buildr.rake')
].
         select { |file| File.exist?(file) }.each { |file| warn "Please use '#{file.ext('rb')}'
instead of '#{file}'" }
@@ -140,19 +248,30 @@
       end
       true
     end
+    private :load_tasks
+
+  end
+
+
+  class << self
 
     # :call-seq:
-    #   build_files() => files
+    #   build_files => files
     #
     # Returns a list of build files. These are files used by the build, 
-    def build_files()
-      [Rake.application.rakefile].compact + @build_files
+    def build_files
+      Buildr.application.build_files
     end
 
     task 'buildr:initialize' do
       Buildr.load_tasks_and_local_files
     end
 
+    # Returns the Buildr::Application object.
+    attr_accessor :application
+
   end
+
+  Buildr.application = Rake.application = Buildr::Application.new
 
 end

Modified: incubator/buildr/trunk/lib/buildr/core/common.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/lib/buildr/core/common.rb?rev=645019&r1=645018&r2=645019&view=diff
==============================================================================
--- incubator/buildr/trunk/lib/buildr/core/common.rb (original)
+++ incubator/buildr/trunk/lib/buildr/core/common.rb Fri Apr  4 19:41:01 2008
@@ -309,8 +309,6 @@
 end
 
 
-# Add a touch of colors (red) to warnings.
-HighLine.use_color = !Gem.win_platform?
 module Kernel #:nodoc:
 
   alias :warn_without_color :warn

Modified: incubator/buildr/trunk/lib/buildr/core/environment.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/lib/buildr/core/environment.rb?rev=645019&r1=645018&r2=645019&view=diff
==============================================================================
--- incubator/buildr/trunk/lib/buildr/core/environment.rb (original)
+++ incubator/buildr/trunk/lib/buildr/core/environment.rb Fri Apr  4 19:41:01 2008
@@ -117,50 +117,8 @@
     Buildr.options
   end
 
-  # :call-seq:
-  #   environment => string or nil
-  #
-  # Returns the environment name.  Use this when your build depends on the environment,
-  # for example, development, production, etc.  The value comes from the BUILDR_ENV
-  # environment variable, and defaults to 'development'.
-  # 
-  # For example:
-  #   buildr -e production
-  def environment
-    ENV['BUILDR_ENV'] ||= 'development'
-  end
-
-  # :call-seq:
-  #   environment(env)
-  #
-  # Sets the environment name.
-  def environment=(env)
-    ENV['BUILDR_ENV'] = env
-  end
-
-  # :call-seq:
-  #    profile => hash
-  #
-  # Returns the profile for the current environment.
   def profile
-    profiles[environment] ||= {}
-  end
-
-  # :call-seq:
-  #    profiles => hash
-  #
-  # Returns all the profiles loaded from the profiles.yaml file.
-  def profiles
-    unless @profiles
-      filename = ['Profiles.yaml', 'profiles.yaml'].map { |fn| File.expand_path(fn, File.dirname(Rake.application.rakefile))
}.
-        detect { |filename| File.exist?(filename) }
-      profiles = filename && YAML::load(File.read(filename)) || {}
-      raise 'Profiles file must be a YAML file with a name: structure map.' unless Hash ===
profiles
-      @profiles = profiles.inject({}) { |hash, (name, value)| value ||= {} 
-        raise 'Each profile must be empty or contain name/value pairs.' unless Hash === value
-        hash.merge(name=>(value || {})) }
-    end
-    @profiles
+    application.profile
   end
 
 end

Modified: incubator/buildr/trunk/lib/buildr/java/bdd_frameworks.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/lib/buildr/java/bdd_frameworks.rb?rev=645019&r1=645018&r2=645019&view=diff
==============================================================================
--- incubator/buildr/trunk/lib/buildr/java/bdd_frameworks.rb (original)
+++ incubator/buildr/trunk/lib/buildr/java/bdd_frameworks.rb Fri Apr  4 19:41:01 2008
@@ -78,14 +78,16 @@
     def run(tests, dependencies) #:nodoc:
       cmd_options = task.options.only(:properties, :java_args)
       cmd_options.update :classpath => dependencies, :project => task.project
-      install_gems(cmd_options)
+      # TODO:  Setting up JRuby is something to do before running Buildr.
+      #install_gems(cmd_options)
 
       report_dir = task.report_to.to_s
       FileUtils.rm_rf report_dir
       ENV['CI_REPORTS'] = report_dir
 
       jruby("-Ilib", "-S", "spec",
-      "--require", gem_path(task.project, "ci_reporter", "lib/ci/reporter/rake/rspec_loader"),
+      #"--require", gem_path(task.project, "ci_reporter", "lib/ci/reporter/rake/rspec_loader"),
+      "--require", "ci/reporter/rake/rspec_loader",
       "--format", "CI::Reporter::RSpecDoc", tests,
       cmd_options.merge({:name => "RSpec"}))
       tests
@@ -124,13 +126,13 @@
       Java::Commands.java(*java_args)
     end
 
-    def install_gems(options)
-      unless required_gems(options).all? {|g| gem_path(options[:project], g)}
-        args = ["-S", "maybe_install_gems", *required_gems(options)]
-        args << {:name => "JRuby Setup"}.merge(options)
-        jruby(*args)
-      end
-    end
+    #def install_gems(options)
+    #  unless required_gems(options).all? {|g| gem_path(options[:project], g)}
+    #    args = ["-S", "maybe_install_gems", *required_gems(options)]
+    #    args << {:name => "JRuby Setup"}.merge(options)
+    #    jruby(*args)
+    #  end
+    #end
     
   end
 

Added: incubator/buildr/trunk/spec/application_spec.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/spec/application_spec.rb?rev=645019&view=auto
==============================================================================
--- incubator/buildr/trunk/spec/application_spec.rb (added)
+++ incubator/buildr/trunk/spec/application_spec.rb Fri Apr  4 19:41:01 2008
@@ -0,0 +1,286 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with this
+# work for additional information regarding copyright ownership.  The ASF
+# licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+# License for the specific language governing permissions and limitations under
+# the License.
+
+
+require File.join(File.dirname(__FILE__), 'spec_helpers')
+
+
+describe Buildr::Application do
+  before :each do
+    @app = Buildr.application
+  end
+
+
+  describe 'home_dir' do
+    it 'should point to ~/.buildr' do
+      @app.home_dir.should eql(File.expand_path('.buildr', ENV['HOME']))
+    end
+
+    it 'should point to existing directory' do
+      File.directory?(@app.home_dir).should be_true
+    end
+  end
+
+
+  describe 'settings' do
+    it 'should be empty hash if no settings.yaml file' do
+      @app.settings.should == {}
+    end
+
+    it 'should return loaded settings.yaml file' do
+      write 'home/.buildr/settings.yaml', 'foo: bar'
+      @app.settings.should == { 'foo'=>'bar' }
+    end
+
+    it 'should fail if settings.yaml file is not a hash' do
+      write 'home/.buildr/settings.yaml', 'foo bar'
+      lambda { @app.settings }.should raise_error(RuntimeError, /expecting.*settings.yaml/i)
+    end
+
+    it 'should be empty hash if settings.yaml file is empty' do
+      write 'home/.buildr/settings.yaml'
+      @app.settings.should == {}
+    end
+  end
+  
+
+  describe 'configuration' do
+    it 'should be empty hash if no build.yaml file' do
+      @app.configuration.should == {}
+    end
+
+    it 'should return loaded build.yaml file' do
+      write 'build.yaml', 'foo: bar'
+      @app.configuration.should == { 'foo'=>'bar' }
+    end
+
+    it 'should fail if build.yaml file is not a hash' do
+      write 'build.yaml', 'foo bar'
+      lambda { @app.configuration }.should raise_error(RuntimeError, /expecting.*build.yaml/i)
+    end
+
+    it 'should be empty hash if build.yaml file is empty' do
+      write 'build.yaml'
+      @app.configuration.should == {}
+    end
+  end
+
+
+  describe 'profiles' do
+    it 'should be empty hash if no profiles.yaml file' do
+      @app.profiles.should == {}
+    end
+
+    it 'should return loaded profiles.yaml file' do
+      write 'profiles.yaml', <<-YAML
+        development:
+          foo: bar
+      YAML
+      @app.profiles.should == { 'development'=> { 'foo'=>'bar' } }
+    end
+
+    it 'should fail if profiles.yaml file is not a hash' do
+      write 'profiles.yaml', 'foo bar'
+      lambda { @app.profiles }.should raise_error(RuntimeError, /expecting.*profiles.yaml/i)
+    end
+
+    it 'should be empty hash if profiles.yaml file is empty' do
+      write 'profiles.yaml'
+      @app.profiles.should == {}
+    end
+  end
+
+
+  describe 'profile' do
+    it 'should be empty hash if no profiles.yaml' do
+      @app.profile.should == {}
+    end
+
+    it 'should be empty hash if no matching profile' do
+      write 'profiles.yaml', <<-YAML
+        test:
+          foo: bar
+      YAML
+      @app.profile.should == {}
+    end
+
+    it 'should return profile matching environment name' do
+      write 'profiles.yaml', <<-YAML
+        development:
+          foo: bar
+        test:
+          foo: baz
+      YAML
+      @app.profile.should == { 'foo'=>'bar' }
+    end
+
+  end
+
+
+  describe 'gems' do
+
+    def load_with_yaml
+      write 'build.yaml', <<-YAML
+        gems:
+        - rspec
+        - rake >= 0.8
+      YAML
+      @app.load_gems
+    end
+
+    it 'should return empty array if no gems specified' do
+      @app.load_gems 
+      @app.gems.should be_empty
+    end
+
+    it 'should return one entry for each gem specified in buildr.yaml' do
+      load_with_yaml
+      @app.gems.size.should be(2)
+    end
+
+    it 'should return a Gem::Specification for each installed gem' do
+      load_with_yaml
+      @app.gems.each { |gem| gem.should be_kind_of(Gem::Specification) }
+    end
+
+    it 'should parse Gem name correctly' do
+      load_with_yaml
+      @app.gems.map(&:name).should include('rake', 'rspec')
+    end
+
+    it 'should find installed version of Gem' do
+      load_with_yaml
+      @app.gems.each { |gem| gem.version.should eql(Gem.loaded_specs[gem.name].version) }
+    end
+  end
+
+
+  describe 'load_gems' do
+    before do
+      @spec = Gem::Specification.new do |spec|
+        spec.name = 'foo'
+        spec.version = '1.2'
+      end
+    end
+
+    it 'should do nothing if no gems specified' do
+      lambda { @app.load_gems }.should_not raise_error
+    end
+
+    it 'should install nothing if specified gems already installed' do
+      @app.should_receive(:listed_gems).and_return([Gem.loaded_specs['rspec']])
+      @app.should_not_receive(:sh)
+      lambda { @app.load_gems }.should_not raise_error
+    end
+
+    it 'should fail if required gem not found in remote repository' do
+      @app.should_receive(:listed_gems).and_return([Gem::Dependency.new('foo', '>=1.1')])
+      Gem::SourceInfoCache.should_receive(:search).and_return([])
+      lambda { @app.load_gems }.should raise_error(LoadError, /cannot be found/i)
+    end
+
+    it 'should fail if need to install gem and not running in interactive mode' do
+      @app.should_receive(:listed_gems).and_return([Gem::Dependency.new('foo', '>=1.1')])
+      Gem::SourceInfoCache.should_receive(:search).and_return([@spec])
+      $stdout.should_receive(:isatty).and_return(false)
+      lambda { @app.load_gems }.should raise_error(LoadError, /this build requires the gems/i)
+    end
+
+    it 'should ask permission before installing required gems' do
+      @app.should_receive(:listed_gems).and_return([Gem::Dependency.new('foo', '>=1.1')])
+      Gem::SourceInfoCache.should_receive(:search).and_return([@spec])
+      $terminal.should_receive(:agree).with(/install/, true)
+      lambda { @app.load_gems }.should raise_error
+    end
+
+    it 'should fail if permission not granted to install gem' do
+      @app.should_receive(:listed_gems).and_return([Gem::Dependency.new('foo', '>=1.1')])
+      Gem::SourceInfoCache.should_receive(:search).and_return([@spec])
+      $terminal.should_receive(:agree).and_return(false)
+      lambda { @app.load_gems }.should raise_error(LoadError, /cannot build without/i)
+    end
+
+    it 'should install gem if permission granted' do
+      @app.should_receive(:listed_gems).and_return([Gem::Dependency.new('foo', '>=1.1')])
+      Gem::SourceInfoCache.should_receive(:search).and_return([@spec])
+      $terminal.should_receive(:agree).and_return(true)
+      @app.should_receive(:sh) do |*args|
+        args.should include('-S', 'gem', 'install', 'foo', '-v', '1.2')
+      end
+      @app.should_receive(:gem).and_return(false)
+      @app.load_gems
+    end
+
+    it 'should reload gem cache after installing required gems' do
+      @app.should_receive(:listed_gems).and_return([Gem::Dependency.new('foo', '>=1.1')])
+      Gem::SourceInfoCache.should_receive(:search).and_return([@spec])
+      $terminal.should_receive(:agree).and_return(true)
+      @app.should_receive(:sh)
+      Gem.source_index.should_receive(:load_gems_in).with(Gem::SourceIndex.installed_spec_directories)
+      @app.should_receive(:gem).and_return(false)
+      @app.load_gems
+    end
+
+    it 'should load previously installed gems' do
+      @app.should_receive(:listed_gems).and_return([Gem.loaded_specs['rspec']])
+      @app.should_receive(:gem).with('rspec', Gem.loaded_specs['rspec'].version.to_s)
+      @app.load_gems
+    end
+
+    it 'should load newly installed gems' do
+      @app.should_receive(:listed_gems).and_return([Gem::Dependency.new('foo', '>=1.1')])
+      Gem::SourceInfoCache.should_receive(:search).and_return([@spec])
+      $terminal.should_receive(:agree).and_return(true)
+      @app.should_receive(:sh)
+      @app.should_receive(:gem).with('foo', @spec.version.to_s)
+      @app.load_gems
+    end
+
+    it 'should default to >=0 version requirement if not specified' do
+      write 'build.yaml', 'gems: foo'
+      Gem::SourceInfoCache.should_receive(:search).with(Gem::Dependency.new('foo', '>=0')).and_return([])
+      lambda { @app.load_gems }.should raise_error
+    end
+
+    it 'should parse exact version requirement' do
+      write 'build.yaml', 'gems: foo 2.5'
+      Gem::SourceInfoCache.should_receive(:search).with(Gem::Dependency.new('foo', '=2.5')).and_return([])
+      lambda { @app.load_gems }.should raise_error
+    end
+
+    it 'should parse range version requirement' do
+      write 'build.yaml', 'gems: foo ~>2.3'
+      Gem::SourceInfoCache.should_receive(:search).with(Gem::Dependency.new('foo', '~>2.3')).and_return([])
+      lambda { @app.load_gems }.should raise_error
+    end
+
+    it 'should parse multiple version requirements' do
+      write 'build.yaml', 'gems: foo >=2.0 !=2.1'
+      Gem::SourceInfoCache.should_receive(:search).with(Gem::Dependency.new('foo', ['>=2.0',
'!=2.1'])).and_return([])
+      lambda { @app.load_gems }.should raise_error
+    end
+  end
+
+end
+
+
+describe ENV do
+
+  describe 'BUILDR_ENV' do
+    it 'should default to development' do
+      ENV['BUILDR_ENV'].should eql('development')
+    end
+  end
+end

Modified: incubator/buildr/trunk/spec/artifact_spec.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/spec/artifact_spec.rb?rev=645019&r1=645018&r2=645019&view=diff
==============================================================================
--- incubator/buildr/trunk/spec/artifact_spec.rb (original)
+++ incubator/buildr/trunk/spec/artifact_spec.rb Fri Apr  4 19:41:01 2008
@@ -132,7 +132,7 @@
   it 'should default to .m2 path' do
     # For convenience, sandbox actually sets the local repository to a temp directory
     repositories.local = nil
-    repositories.local.should eql(File.expand_path('~/.m2/repository'))
+    repositories.local.should eql(File.expand_path('.m2/repository', ENV['HOME']))
   end
 
   it 'should be settable' do

Modified: incubator/buildr/trunk/spec/common_spec.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/spec/common_spec.rb?rev=645019&r1=645018&r2=645019&view=diff
==============================================================================
--- incubator/buildr/trunk/spec/common_spec.rb (original)
+++ incubator/buildr/trunk/spec/common_spec.rb Fri Apr  4 19:41:01 2008
@@ -577,80 +577,3 @@
     props.split("\n").should include("name3=double\\\\hash")
   end
 end
-
-
-describe Buildr, 'environment' do
-  it 'should default to development' do
-    environment.should eql('development')
-  end
-  
-  it 'should come from BUILDR_ENV environment variable' do
-    ENV['BUILDR_ENV'] = 'buildr-test'
-    environment.should eql('buildr-test')
-  end
-
-  it 'should change the environment variable' do
-    Buildr.environment = 'buildr-test'
-    ENV['BUILDR_ENV'].should eql('buildr-test')
-  end
-end
-
-
-describe Buildr, 'profiles' do
-  it 'should return empty hash if no profiles file' do
-    Buildr.profiles.should == {}
-  end
-
-  it 'should load profiles from profiles.yaml file' do
-    write 'profiles.yaml', <<-YAML
-dev:
-  foo: bar
-test:
-  bar: baz
-    YAML
-    Buildr.profiles.should == { 'dev'=> { 'foo'=>'bar' }, 'test'=>{ 'bar'=>'baz'
} }
-  end
-
-  it 'should load profiles from Profiles.yaml file' do
-    write 'Profiles.yaml', <<-YAML
-dev:
-  foo: bar
-test:
-  bar: baz
-    YAML
-    Buildr.profiles.should == { 'dev'=> { 'foo'=>'bar' }, 'test'=>{ 'bar'=>'baz'
} }
-  end
-
-  it 'should accept empty profiles file' do
-    write 'Profiles.yaml', "# comment\n\n"
-    Buildr.profiles.should == {}
-  end
-
-  it 'should complain if profiles file is not a map' do
-    write 'Profiles.yaml', 'not_a_map'
-    lambda { Buildr.profiles }.should raise_error
-  end
-end
-
-
-describe Buildr, 'profile' do
-  it 'should return profile for current environment' do
-    Buildr.environment = 'qa'
-    Buildr.profiles['qa'] = { 'foo'=>'bar' }
-    Buildr.profile.should == { 'foo'=>'bar' }
-  end
-
-  it 'should return empty hash if no proflie available' do
-    Buildr.profile.should == {}
-  end
-
-  it 'should accept empty profile' do
-    write 'Profiles.yaml', "development:\n"
-    Buildr.profile.should == {}
-  end
-
-  it 'should complain if profile is not a map' do
-    write 'Profiles.yaml', 'development: not_a_map'
-    lambda { Buildr.profile }.should raise_error
-  end
-end

Modified: incubator/buildr/trunk/spec/project_spec.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/spec/project_spec.rb?rev=645019&r1=645018&r2=645019&view=diff
==============================================================================
--- incubator/buildr/trunk/spec/project_spec.rb (original)
+++ incubator/buildr/trunk/spec/project_spec.rb Fri Apr  4 19:41:01 2008
@@ -701,6 +701,8 @@
 end
 
 
+=begin
+# TODO: how do we test this?
 describe Rake::Task, 'buildr:initialize' do
   it 'should be ready to run as the first task' do
     Rake.application.top_level_tasks.first.should eql('buildr:initialize')
@@ -712,3 +714,4 @@
     lambda { task('buildr:initialize').invoke }.should change { defined }.to(true)
   end
 end
+=end

Modified: incubator/buildr/trunk/spec/sandbox.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/spec/sandbox.rb?rev=645019&r1=645018&r2=645019&view=diff
==============================================================================
--- incubator/buildr/trunk/spec/sandbox.rb (original)
+++ incubator/buildr/trunk/spec/sandbox.rb Fri Apr  4 19:41:01 2008
@@ -20,64 +20,69 @@
 repositories.remote << 'http://repo1.maven.org/maven2'
 Java.load # Anything added to the classpath.
 artifacts(TestFramework.frameworks.map(&:dependencies).flatten).each { |a| file(a).invoke
}
-task('buildr:initialize').invoke
 
-# We need to run all tests inside a sandbox, tacking a snapshot of Rake/Buildr before the
test,
+ENV['HOME'] = File.expand_path('tmp/home')
+
+# We need to run all tests inside a _sandbox, tacking a snapshot of Buildr before the test,
 # and restoring everything to its previous state after the test. Damn state changes.
 module Sandbox
 
-  def self.included(spec)
-    spec.before(:each) { sandbox }
-    spec.after(:each) { reset }
+  class << self
+    attr_reader :tasks, :rules
+
+    def included(spec)
+      spec.before(:each) { sandbox }
+      spec.after(:each) { reset }
+    end
   end
 
-  def sandbox
-    @sandbox = {}
-    # During teardown we get rid of all the tasks and start with a clean slate.
-    # Unfortunately, we also get rid of tasks we need, like build, clean, etc.
-    # Here we capture them in their original form, recreated during teardown.
-    @sandbox[:tasks] = Rake.application.tasks.collect do |original|
-      prerequisites = original.prerequisites.clone
-      actions = original.instance_eval { @actions }.clone
-      lambda do
-        original.class.send(:define_task, original.name=>prerequisites).tap do |task|
-          task.comment = original.comment
-          actions.each { |action| task.enhance &action }
-        end
+  @tasks = Buildr.application.tasks.collect do |original|
+    prerequisites = original.send(:prerequisites).map(&:to_s)
+    actions = original.instance_eval { @actions }.clone
+    lambda do
+      original.class.send(:define_task, original.name=>prerequisites).tap do |task|
+        task.comment = original.comment
+        actions.each { |action| task.enhance &action }
       end
     end
-    @sandbox[:rules] = Rake.application.instance_variable_get(:@rules).clone
+  end
+  @rules = Buildr.application.instance_variable_get(:@rules)
 
+  def sandbox
     # Create a temporary directory where we can create files, e.g,
     # for projects, compilation. We need a place that does not depend
     # on the current directory.
-    @test_dir = File.expand_path('../tmp', File.dirname(__FILE__))
-    FileUtils.mkpath @test_dir
-    # Move to the work directory and make sure Rake thinks of it as the Rakefile directory.
-    @sandbox[:pwd] = Dir.pwd
-    Dir.chdir @test_dir
-    @sandbox[:load_path] = $LOAD_PATH.clone
-    @sandbox[:loaded_features] = $LOADED_FEATURES.clone
-    @sandbox[:original_dir] = Rake.application.original_dir 
-    Rake.application.instance_eval { @original_dir = Dir.pwd }
-    Rake.application.instance_eval { @rakefile = File.expand_path('buildfile') }
+    temp = File.join(File.dirname(__FILE__), '../tmp')
+    FileUtils.mkpath temp
+    Dir.chdir temp
+
+    @_sandbox = {}
+    Buildr.application = Rake.application = Buildr::Application.new
+    Sandbox.tasks.each { |block| block.call }
+    Buildr.application.instance_variable_set :@rules, Sandbox.rules.clone
+    Buildr.application.instance_eval { @rakefile = File.expand_path('buildfile') }
+
+    @_sandbox[:load_path] = $LOAD_PATH.clone
+    @_sandbox[:loaded_features] = $LOADED_FEATURES.clone
     
     # Later on we'll want to lose all the on_define created during the test.
-    @sandbox[:on_define] = Project.class_eval { (@on_define || []).dup }
-    @sandbox[:layout] = Layout.default.clone
+    @_sandbox[:on_define] = Project.class_eval { (@on_define || []).dup }
+    @_sandbox[:layout] = Layout.default.clone
 
     # Create a local repository we can play with. However, our local repository will be void
     # of some essential artifacts (e.g. JUnit artifacts required by build task), so we create
     # these first (see above) and keep them across test cases.
-    @sandbox[:artifacts] = Artifact.class_eval { @artifacts }.clone
-    Buildr.repositories.local = File.join(@test_dir, 'repository')
+    @_sandbox[:artifacts] = Artifact.class_eval { @artifacts }.clone
+    Buildr.repositories.local = File.expand_path('repository')
+    ENV['HOME'] = File.expand_path('home')
 
-    @sandbox[:env_keys] = ENV.keys
+    @_sandbox[:env_keys] = ENV.keys
     ['DEBUG', 'TEST', 'HTTP_PROXY', 'USER'].each { |k| ENV.delete(k) ; ENV.delete(k.downcase)
}
 
     # Don't output crap to the console.
     trace false
     verbose false
+    task('buildr:initialize').invoke
   end
 
   # Call this from teardown.
@@ -91,29 +96,20 @@
 
     # Get rid of all the projects and the on_define blocks we used.
     Project.clear
-    on_define = @sandbox[:on_define]
+    on_define = @_sandbox[:on_define]
     Project.class_eval { @on_define = on_define }
-    Layout.default = @sandbox[:layout].clone
+    Layout.default = @_sandbox[:layout].clone
 
-    # Switch back Rake directory.
-    Dir.chdir @sandbox[:pwd]
-    original_dir = @sandbox[:original_dir]
-    $LOAD_PATH.replace @sandbox[:load_path]
-    $LOADED_FEATURES.replace @sandbox[:loaded_features]
-    Rake.application.instance_eval { @original_dir = original_dir }
-    FileUtils.rm_rf @test_dir
-
-    # Get rid of all the tasks and restore the default tasks.
-    Rake::Task.clear
-    @sandbox[:tasks].each { |block| block.call }
-    Rake.application.instance_variable_set :@rules, @sandbox[:rules]
+    $LOAD_PATH.replace @_sandbox[:load_path]
+    $LOADED_FEATURES.replace @_sandbox[:loaded_features]
+    FileUtils.rm_rf Dir.pwd
 
     # Get rid of all artifacts.
-    @sandbox[:artifacts].tap { |artifacts| Artifact.class_eval { @artifacts = artifacts }
}
+    @_sandbox[:artifacts].tap { |artifacts| Artifact.class_eval { @artifacts = artifacts
} }
 
     # Restore options.
     Buildr.options.test = nil
-    (ENV.keys - @sandbox[:env_keys]).each { |key| ENV.delete key }
+    (ENV.keys - @_sandbox[:env_keys]).each { |key| ENV.delete key }
   end
 
 end

Modified: incubator/buildr/trunk/spec/spec_helpers.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/spec/spec_helpers.rb?rev=645019&r1=645018&r2=645019&view=diff
==============================================================================
--- incubator/buildr/trunk/spec/spec_helpers.rb (original)
+++ incubator/buildr/trunk/spec/spec_helpers.rb Fri Apr  4 19:41:01 2008
@@ -223,43 +223,43 @@
     end
 
     def dryrun
-      Rake.application.options.dryrun = true
+      Buildr.application.options.dryrun = true
       begin
         suppress_stdout { yield }
       ensure
-        Rake.application.options.dryrun = false
+        Buildr.application.options.dryrun = false
       end
     end
 
     # We run tests with tracing off. Then things break. And we need to figure out what went
wrong.
     # So just use trace() as you would use verbose() to find and squash the bug.
     def trace(value = nil)
-      old_value = Rake.application.options.trace
-      Rake.application.options.trace = value unless value.nil?
+      old_value = Buildr.application.options.trace
+      Buildr.application.options.trace = value unless value.nil?
       if block_given?
         begin
           yield
         ensure
-          Rake.application.options.trace = old_value
+          Buildr.application.options.trace = old_value
         end
       end
-      Rake.application.options.trace
+      Buildr.application.options.trace
     end
 
-    # Change the Rakefile original directory, faking invocation from a different directory.
+    # Change the Buildr original directory, faking invocation from a different directory.
     def in_original_dir(dir)
       begin
-        original_dir = Rake.application.original_dir
-        Rake.application.instance_eval { @original_dir = File.expand_path(dir) }
+        original_dir = Buildr.application.original_dir
+        Buildr.application.instance_eval { @original_dir = File.expand_path(dir) }
         yield
       ensure
-        Rake.application.instance_eval { @original_dir = original_dir }
+        Buildr.application.instance_eval { @original_dir = original_dir }
       end 
     end
 
 
     # Buildr's define method creates a project definition but does not evaluate it
-    # (that happens once the Rakefile is loaded), and we include Buildr's define in
+    # (that happens once the buildfile is loaded), and we include Buildr's define in
     # the test context so we can use it without prefixing with Buildr. This just patches
     # define to evaluate the project definition before returning it.
     def define(name, properties = nil, &block) #:yields:project
@@ -279,7 +279,7 @@
     # Make all Buildr methods accessible from test cases, and add various helper methods.
     config.include Buildr, SpecHelpers
 
-    # Sanbdox Rake/Buildr for each test.
+    # Sanbdox Buildr for each test.
     config.include Sandbox
   end
 



Mime
View raw message