<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>app/controllers/builds_controller.rb</filename>
    </added>
    <added>
      <filename>app/helpers/builds_helper.rb</filename>
    </added>
    <added>
      <filename>app/views/builds/no_builds_yet.rhtml</filename>
    </added>
    <added>
      <filename>app/views/builds/show.rhtml</filename>
    </added>
    <added>
      <filename>test/functional/builds_controller_test.rb</filename>
    </added>
    <added>
      <filename>test/unit/routing_test.rb</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -25,3 +25,4 @@ RUBY_FORGE_USER    = &quot;stellsmi&quot;
 
 
 require 'tasks/rails'
+</diff>
      <filename>Rakefile</filename>
    </modified>
    <modified>
      <diff>@@ -4,4 +4,14 @@
 class ApplicationController &lt; ActionController::Base
   # Pick a unique cookie name to distinguish our session data from others'
   session :session_key =&gt; '_ci_session_id'
+
+  private
+  
+  def load_projects
+    Projects.load_all
+  end
+
+  def find_project(projects)
+    projects.find {|p| p.name == params[:project] }
+  end
 end</diff>
      <filename>app/controllers/application.rb</filename>
    </modified>
    <modified>
      <diff>@@ -7,17 +7,6 @@ class ProjectsController &lt; ApplicationController
     @build_states = get_build_states(@projects)
   end
 
-  def show
-    @project = find_project(load_projects)
-
-    if params.has_key? :build
-      @build = @project.builds.find { |build| build.label.to_s == params[:build] }
-    end
-    @build ||= @project.last_build
-    
-    render :action =&gt; 'no_builds_yet' unless @build
-  end
-
   def refresh_projects
     current_projects = load_projects
     changed_projects = []
@@ -48,14 +37,6 @@ class ProjectsController &lt; ApplicationController
   
   private
 
-  def load_projects
-    Projects.load_all
-  end
-
-  def find_project(projects)
-    projects.find {|p| p.name == params[:id] }
-  end
-
   def get_build_states(projects)
     states = ''
     projects.each do |project|
@@ -63,5 +44,4 @@ class ProjectsController &lt; ApplicationController
     end
     states
   end
-
 end
\ No newline at end of file</diff>
      <filename>app/controllers/projects_controller.rb</filename>
    </modified>
    <modified>
      <diff>@@ -40,5 +40,11 @@ module ApplicationHelper
   def link_to_documentation(text = 'Documentation')
     '&lt;a href=&quot;http://cruisecontrolrb.rubyforge.org&quot;&gt;' + h(text) + '&lt;/a&gt;'
   end
+  
+  def link_to_build(project, build)
+    text = &quot;#{build.label} (#{format_time(build.time, :human)})&quot;
+    text += &quot; &lt;span class='error'&gt;FAILED&lt;/span&gt;&quot; if build.failed?
+    link_to text, {:controller =&gt; 'builds', :action =&gt; 'show', :project =&gt; project.name, :build =&gt; build.label}, :class =&gt; build.status
+  end
 
 end</diff>
      <filename>app/helpers/application_helper.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,42 +1,2 @@
-def format_changeset_log(log)
-  log.strip
-end
-
-def link_to_build(project, build)
-  text = &quot;#{build.label} (#{format_time(build.time, :human)})&quot;
-  text += &quot; &lt;span class='error'&gt;FAILED&lt;/span&gt;&quot; if build.failed?
-  link_to text, {:action =&gt; 'show', :id =&gt; project.name, :build =&gt; build.label}, :class =&gt; build.status
-end
-
-def format_build_log(log)
-  convert_new_lines(log.gsub(/(\d+ tests, \d+ assertions, \d+ failures, \d+ errors)/, '&lt;div class=&quot;test-results&quot;&gt;\1&lt;/div&gt;'))
-end
-
-def display_test_failures_and_errors_if_any(log)
-  output = String.new
-  
-  testFailures = TestFailureParser.new.get_test_failures(log)
-  testFailures.each {|testFailure| output &lt;&lt; format_test_error_output(testFailure)}
-    
-  testErrors = TestErrorParser.new.get_test_errors(log)
-  testErrors.each {|testError| output &lt;&lt; format_test_error_output(testError)}
-    
-  if output != String.new
-    output.strip
-  else
-    &quot;None&quot;
-  end
-end
-
-def format_test_error_output(testError)
-  message = testError.message.gsub(/\\n/, &quot;\n&quot;);
-
-  &quot;Name: #{testError.test_name}\n&quot; +
-  &quot;Type: #{testError.type}\n&quot; +
-  &quot;Message: #{message}\n\n&quot; +
-  &quot;&lt;span class=\&quot;error\&quot;&gt;#{testError.stacktrace}&lt;/span&gt;\n\n\n&quot;
-end
-
-def convert_new_lines(value)
-  value.gsub(/\n/, &quot;&lt;br/&gt;\n&quot;)
+module ProjectsHelper
 end
\ No newline at end of file</diff>
      <filename>app/helpers/projects_helper.rb</filename>
    </modified>
    <modified>
      <diff>@@ -2,6 +2,7 @@ class Build
   include CommandLine
 
   attr_reader :project, :label
+  IGNORE_ARTIFACTS = /^(\..*|build_status\..+|build.log|changeset.log)$/
 
   def initialize(project, label)
     @project, @label = project, label
@@ -10,6 +11,10 @@ class Build
     @status = Status.new(artifacts_directory)
   end
   
+  def publish_name
+    &quot;/builds/#{@project.name}/#{label}&quot;
+  end
+
   def run
     build_log = artifact 'build.log'
     # build_command must be set before doing chdir, because there may be some relative paths
@@ -22,6 +27,10 @@ class Build
     CruiseControl::Log.verbose? ? CruiseControl::Log.debug(e) : CruiseControl::Log.info(e.message)    
     @status.fail!
   end
+
+  def additional_artifacts
+    Dir.entries(artifacts_directory).find_all {|artifact| !(artifact =~ IGNORE_ARTIFACTS) }
+  end
   
   def status
     @status.to_s
@@ -88,7 +97,4 @@ class Build
       ENV['RAILS_ENV'] = old_rails_env
     end
   end
-
-  private
-  
 end</diff>
      <filename>app/models/build.rb</filename>
    </modified>
    <modified>
      <diff>@@ -129,6 +129,11 @@ class Project
   def last_build
     builds.last
   end
+
+  def find_build(label)
+    # this could be optimized a lot
+    builds.find { |build| build.label.to_s == label }
+  end
     
   def last_build_status
     builds.empty? ? :never_built : last_build.status</diff>
      <filename>app/models/project.rb</filename>
    </modified>
    <modified>
      <diff>@@ -6,7 +6,7 @@
 
     &lt;div&gt;
       &lt;span class=&quot;project_name&quot;&gt;
-        &lt;%= link_to project.name, :action =&gt; 'show', :id =&gt; project.name %&gt;
+        &lt;%= link_to project.name, :controller =&gt; 'builds', :action =&gt; 'show', :project =&gt; project.name %&gt;
       &lt;/span&gt;
       &lt;span class=&quot;builder_status&quot;&gt;&lt;%= project.builder_state_and_activity %&gt;&lt;/span&gt;
       &lt;span class=&quot;buttons&quot;&gt;</diff>
      <filename>app/views/projects/_project.rhtml</filename>
    </modified>
    <modified>
      <diff>@@ -17,6 +17,12 @@ ActionController::Routing::Routes.draw do |map|
   
   # map.connect 'build', :controller =&gt; 'build', :action =&gt; &quot;index&quot;
   map.connect '', :controller =&gt; 'projects', :action =&gt; 'index'   
+
+  map.connect 'builds/:project', :controller =&gt; 'builds', :action =&gt; 'show'
+  map.connect 'builds/:project/:build', :controller =&gt; 'builds', :action =&gt; 'show', :build =&gt; /[^\/]+/
+  map.connect 'builds/:project/:build/*artifact_path', :controller =&gt; 'builds', :action =&gt; 'artifact', :build =&gt; /[^\/]+/
+  
+  map.connect 'projects/:action/:project', :controller =&gt; 'projects'
   
   # You can have the root of your site routed with map.root
   # map.root '', :controller =&gt; &quot;builds&quot;, :action =&gt; &quot;index&quot;</diff>
      <filename>config/routes.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,2 +1,6 @@
 desc 'Continuous build target'
-task :cruise =&gt; :test
\ No newline at end of file
+task :cruise =&gt; ['test:units:rcov', 'test:functionals:rcov', 'test:integration'] do 
+  out = ENV[CC_BUILD_ARTIFACTS] || 'out'
+  mv 'coverage/units', &quot;#{out}/unit test coverage&quot;
+  mv 'coverage/functionals', &quot;#{out}/functional test coverage&quot;
+end
\ No newline at end of file</diff>
      <filename>lib/tasks/cruise.rake</filename>
    </modified>
    <modified>
      <diff>@@ -41,41 +41,13 @@ class ProjectsControllerTest &lt; Test::Unit::TestCase
     assert_equal @projects, assigns(:projects)
   end
 
-  def test_show_with_build
-    @sandbox.new :file =&gt; &quot;two/build-24/build_status.pingpong&quot;
-    @sandbox.new :file =&gt; &quot;two/build-25/build_status.pingpong&quot;
-
-    get :show, :id =&gt; 'two'
-
-    assert_equal @two, assigns(:project)
-    assert_equal '25', assigns(:build).label
-  end
-
-  def test_show_specific_build
-    @sandbox.new :file =&gt; &quot;two/build-24/build_status.pingpong&quot;
-    @sandbox.new :file =&gt; &quot;two/build-25/build_status.pingpong&quot;
-
-    get :show, :id =&gt; 'two', :build =&gt; 24
-
-    assert_equal @two, assigns(:project)
-    assert_equal '24', assigns(:build).label
-  end
-
-  def test_show_with_no_build
-    get :show, :id =&gt; &quot;two&quot;
-
-    assert_response :success
-
-    assert_equal @two, assigns(:project)
-    assert_nil assigns(:build)
-    assert_template 'no_builds_yet'
-  end
-
   def test_should_refresh_projects_if_builder_and_build_states_tag_changed
     @controller.load_projects = new_project(&quot;one&quot;), new_project(&quot;two&quot;)
     @sandbox.new :file =&gt; &quot;one/build-24/build_status.pingpong&quot;
     @sandbox.new :file =&gt; &quot;two/build-24/build_status.new_status&quot;
+
     post :refresh_projects, :build_states =&gt; 'one:notstarted24pingpong;two:notstarted24old_status;'
+
     assert_equal [@two], assigns(:projects)   
   end
   
@@ -83,7 +55,9 @@ class ProjectsControllerTest &lt; Test::Unit::TestCase
     @controller.load_projects = new_project(&quot;one&quot;), new_project(&quot;two&quot;)
     @sandbox.new :file =&gt; &quot;one/build-24/build_status.pingpong&quot;
     @sandbox.new :file =&gt; &quot;two/build-24/build_status.new_status&quot;
+  
     post :refresh_projects, :build_states =&gt; 'one:NotStarted24pingpong;two:NotStarted24old_status;'
+  
     assert_equal 'one:notstarted24pingpong;two:notstarted24new_status;', assigns(:build_states)
   end
   
@@ -91,7 +65,9 @@ class ProjectsControllerTest &lt; Test::Unit::TestCase
     @controller.load_projects = new_project(&quot;one&quot;), new_project(&quot;two&quot;)
     @sandbox.new :file =&gt; &quot;one/build-24/build_status.pingpong&quot;
     @sandbox.new :file =&gt; &quot;two/build-24/build_status.some_status&quot;
+  
     get :index
+  
     assert_equal 'one:notstarted24pingpong;two:notstarted24some_status;', assigns(:build_states)
   end
   
@@ -99,7 +75,9 @@ class ProjectsControllerTest &lt; Test::Unit::TestCase
     @sandbox.new :file =&gt; &quot;one/build-24/build_status.pingpong&quot;
     @sandbox.new :file =&gt; &quot;two/build-24/build_status.pingpong&quot;
     @sandbox.new :file =&gt; &quot;three/build-24/build_status.pingpong&quot;
+  
     post :refresh_projects, :build_states =&gt; 'one:notstarted24pingpong;three:notstarted24pingpong;'
+  
     assert_equal 'one:notstarted24pingpong;two:notstarted24pingpong;three:notstarted24pingpong;', assigns(:build_states)
     assert_equal [@two], assigns(:new_projects)
     assert_equal [], assigns(:projects)
@@ -110,7 +88,9 @@ class ProjectsControllerTest &lt; Test::Unit::TestCase
     @controller.load_projects = new_project(&quot;one&quot;), new_project(&quot;two&quot;)
     @sandbox.new :file =&gt; &quot;one/build-24/build_status.pingpong&quot;
     @sandbox.new :file =&gt; &quot;two/build-24/build_status.pingpong&quot;
+  
     post :refresh_projects, :build_states =&gt; 'one:notstarted24pingpong;two:notstarted24pingpong;three:notstarted24pingpong;'
+  
     assert_equal 'one:notstarted24pingpong;two:notstarted24pingpong;', assigns(:build_states)
     assert_equal ['three'], assigns(:deleted_projects)
     assert_equal [], assigns(:projects)
@@ -122,12 +102,12 @@ class ProjectsControllerTest &lt; Test::Unit::TestCase
     @controller.project= @two
     @controller.expects(:redirect_to).times(1).with({:action =&gt; :index})
     @two.expects(:request_force_build).times(1).returns(&quot;result&quot;)
-    post :force_build, :id =&gt; &quot;two&quot; 
+  
+    post :force_build, :project =&gt; &quot;two&quot; 
+
     assert_equal &quot;result&quot;, flash[:projects_flash]
   end
 
-  private
-
   def new_project(name)
     project = Project.new(name)
     project.path = &quot;#{@sandbox.root}/#{name}&quot;</diff>
      <filename>test/functional/projects_controller_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -11,7 +11,7 @@ silence_warnings { RAILS_ENV = &quot;test&quot; }
 require 'test/unit'
 require 'action_controller/test_process'
 require 'action_controller/integration'
-require 'action_web_service/test_invoke'
+#require 'action_web_service/test_invoke'
 require 'breakpoint'
 require 'mocha'
 require 'stubba'</diff>
      <filename>test/test_helper.rb</filename>
    </modified>
    <modified>
      <diff>@@ -141,4 +141,26 @@ class BuildTest &lt; Test::Unit::TestCase
     assert_equal 3.2, Build.new(project, 3.2).label
   end
 
+  def test_build_should_know_about_additional_artifacts
+    with_sandbox_project do |sandbox, project|
+      sandbox.new :file =&gt; &quot;build-1/coverage/index.html&quot;
+      sandbox.new :file =&gt; &quot;build-1/coverage/units/index.html&quot;
+      sandbox.new :file =&gt; &quot;build-1/coverage/functionals/index.html&quot;
+      sandbox.new :file =&gt; &quot;build-1/foo&quot;
+      sandbox.new :file =&gt; &quot;build-1/foo.txt&quot;
+      sandbox.new :file =&gt; &quot;build.log&quot;
+      sandbox.new :file =&gt; &quot;build_status.failure&quot;
+      sandbox.new :file =&gt; &quot;changeset.log&quot;
+      
+      build = Build.new(project, 1)
+      assert_equal(%w(coverage foo foo.txt), build.additional_artifacts.sort)
+    end
+  end
+
+  def test_build_should_know_its_publish_name
+    with_sandbox_project do |sandbox, project|
+      build = Build.new(project, 1)
+      assert_equal &quot;/builds/my_project/1&quot;, build.publish_name 
+    end
+  end
 end</diff>
      <filename>test/unit/build_test.rb</filename>
    </modified>
  </modified>
  <removed type="array">
    <removed>
      <filename>app/views/projects/no_builds_yet.rhtml</filename>
    </removed>
    <removed>
      <filename>app/views/projects/show.rhtml</filename>
    </removed>
  </removed>
  <parents type="array">
    <parent>
      <id>ccd34d8440c43e5959b15d5709c2ba2d88deac7c</id>
    </parent>
  </parents>
  <author>
    <name>Jeremy Stell-Smith</name>
    <email>jeremystellsmith@gmail.com</email>
  </author>
  <url>http://github.com/willbryant/cruisecontrolrb/commit/0b525fa69fe97c06398982fa6a6ffe71529f8f29</url>
  <id>0b525fa69fe97c06398982fa6a6ffe71529f8f29</id>
  <committed-date>2007-02-09T16:24:07-08:00</committed-date>
  <authored-date>2007-02-09T16:24:07-08:00</authored-date>
  <message>r174: moved builds to /build/&lt;proj&gt;/&lt;label&gt;
checking in patch for coverage reports w/ many changes
added rcov to our project, and (hopefully) to our cruise</message>
  <tree>60f4a05d47641aa63ed975e57bcb9c9c4906498c</tree>
  <committer>
    <name>Jeremy Stell-Smith</name>
    <email>jeremystellsmith@gmail.com</email>
  </committer>
</commit>
