Browse files

Merge branch 'master' of https://github.com/drouchy/bigtuna into drou…

…chy-master

Conflicts:
	db/schema.rb
	test/unit/build_test.rb
	test/unit/project_test.rb
  • Loading branch information...
2 parents 749967e + a0a94db commit bb54fd9167b3572e86e75a860b394ca3b3def43f @antekpiechnik antekpiechnik committed Apr 13, 2011
View
55 app/models/build.rb
@@ -26,7 +26,7 @@ def perform
self.started_at = Time.now
project = self.project
begin
- out = project.vcs.clone(self.build_dir)
+ out = fetch_project_sources(project)
self.update_attributes!(vcs.head_info[0].merge(:output => [out]))
vcs_ok = true
rescue BigTuna::Runner::Error => e
@@ -86,16 +86,18 @@ def update_part(part)
private
def remove_build_dir
- if File.directory?(self.build_dir)
- FileUtils.rm_rf(self.build_dir)
- else
- BigTuna.logger.info("Couldn't find build dir to remove: %p" % [self.build_dir])
+ if project.fetch_type == :clone
+ if File.directory?(self.build_dir)
+ FileUtils.rm_rf(self.build_dir)
+ else
+ BigTuna.logger.info("Couldn't find build dir to remove: %p" % [self.build_dir])
+ end
end
end
def set_build_values
project_dir = project.build_dir
- self.build_dir = File.join(project_dir, "build_#{self.build_no}_#{self.scheduled_at.strftime("%Y%m%d%H%M%S")}")
+ self.build_dir = compute_build_dir
self.status = STATUS_IN_QUEUE
self.scheduled_at = Time.now
self.output = []
@@ -145,4 +147,45 @@ def after_finished
hook.build_finished(self)
end
end
+
+ def compute_build_dir
+ if project.fetch_type == :incremental
+ File.join(project.build_dir, "checkout")
+ else
+ File.join(project.build_dir, "build_#{self.build_no}_#{self.scheduled_at.strftime("%Y%m%d%H%M%S")}")
+ end
+ end
+
+ def fetch_project_sources(project)
+ case project.fetch_type
+ when :clone
+ fetch_project_sources_by_cloning
+ when :incremental
+ fetch_project_sources_incrementally
+ end
+ end
+
+ def fetch_project_sources_incrementally
+ if project_sources_already_present?
+ update_project
+ else
+ fetch_project_sources_by_cloning
+ end
+ end
+
+ def fetch_project_sources_by_cloning
+ clone_project
+ end
+
+ def clone_project
+ project.vcs.clone(self.build_dir)
+ end
+
+ def update_project
+ project.vcs.update(self.build_dir)
+ end
+
+ def project_sources_already_present?
+ File.directory? self.build_dir
+ end
end
View
20 app/models/project.rb
@@ -8,13 +8,15 @@ class Project < ActiveRecord::Base
before_update :rename_build_folder
before_create :set_default_build_counts
after_save :update_hooks
-
+
validates :hook_name, :uniqueness => {:allow_blank => true}
validates :name, :presence => true, :uniqueness => true
validates :vcs_type, :inclusion => BigTuna.vcses.map { |e| e::VALUE }
validates :vcs_source, :presence => true
validates :vcs_branch, :presence => true
-
+
+ validate :validate_vcs_incremental_support
+
acts_as_list
def self.ajax_reload?
@@ -97,7 +99,15 @@ def stability
def hooks=(hooks)
@_hooks = hooks
end
-
+
+ def fetch_type
+ if self[:fetch_type]
+ self[:fetch_type].to_sym
+ else
+ :clone
+ end
+ end
+
private
def build_dir_from_name(name)
if BigTuna.build_dir[0] == '/'[0]
@@ -151,4 +161,8 @@ def remove_project_jobs_in_queue
end
jobs_to_destroy.each { |job| job.destroy }
end
+
+ def validate_vcs_incremental_support
+ errors.add(:fetch_type, " #{fetch_type} not support by the vcs") if fetch_type == :incremental && !vcs.support_incremental_build?
+ end
end
View
7 app/views/projects/_form.html.haml
@@ -15,6 +15,13 @@
%br
= f.text_field(:vcs_branch, :class => 'textfield')
%div
+ = f.label(:fetch_type)
+ %br
+ = f.label(:clone)
+ = f.radio_button(:fetch_type, :clone)
+ = f.label(:incremental)
+ = f.radio_button(:fetch_type, :incremental)
+%div
= f.label(:max_builds)
%br
= f.text_field(:max_builds, :class => 'textfield')
View
9 db/migrate/20110326142448_add_fetch_type_to_project.rb
@@ -0,0 +1,9 @@
+class AddFetchTypeToProject < ActiveRecord::Migration
+ def self.up
+ add_column :projects, :fetch_type, :string, :default => :clone
+ end
+
+ def self.down
+ remove_column :projects, :fetch_type
+ end
+end
View
9 db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended to check this file into your version control system.
-ActiveRecord::Schema.define(:version => 20110315133903) do
+ActiveRecord::Schema.define(:version => 20110326142448) do
create_table "build_parts", :force => true do |t|
t.integer "build_id", :null => false
@@ -68,9 +68,9 @@
end
create_table "projects", :force => true do |t|
- t.string "name", :null => false
- t.string "vcs_type", :null => false
- t.string "vcs_source", :null => false
+ t.string "name", :null => false
+ t.string "vcs_type", :null => false
+ t.string "vcs_source", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.integer "max_builds"
@@ -79,6 +79,7 @@
t.string "vcs_branch"
t.integer "total_builds"
t.integer "failed_builds"
+ t.string "fetch_type", :default => "clone"
end
create_table "shared_variables", :force => true do |t|
View
4 lib/big_tuna/vcs/base.rb
@@ -15,5 +15,9 @@ def self.inherited(klass)
BigTuna.vcses << klass
BigTuna.logger.info("Registered VCS: %s" % [klass])
end
+
+ def support_incremental_build?
+ respond_to?(:update)
+ end
end
end
View
5 lib/big_tuna/vcs/git.rb
@@ -54,5 +54,10 @@ def clone(where_to)
end
BigTuna::Runner.execute(Dir.pwd, command)
end
+
+ def update(where_to)
+ command = 'git clean -fd && git pull'
+ BigTuna::Runner.execute(where_to, command)
+ end
end
end
View
1 test/test_helper.rb
@@ -75,6 +75,7 @@ def create_test_repo
def destroy_test_repo
FileUtils.rm_rf 'test/files/repo'
+ FileUtils.rm_rf 'test/files/build'
end
module WithTestRepo
View
82 test/unit/build_test.rb
@@ -144,4 +144,86 @@ class BuildTest < ActiveSupport::TestCase
assert build.to_param.include?(project.name.to_url)
assert build.to_param.include?(build.display_name.to_url)
end
+
+ test 'in clone fetch type, the build should always clone' do
+ vcs = mock_vcs
+ project = mock_project(vcs)
+ build = mock_build(project, vcs)
+
+ project.fetch_type = :clone
+
+ vcs.expects(:clone).once
+ vcs.expects(:update).never
+
+ build.perform
+ end
+
+ test 'in incremental fetch type, the build shoud update ios clone' do
+ vcs = mock_vcs
+ project = mock_project(vcs)
+ build = mock_build(project, vcs)
+
+ project.fetch_type = :incremental
+ build.stubs(:project_sources_already_present?).returns(true)
+
+ vcs.expects(:update).once
+ vcs.expects(:clone).never
+
+ build.perform
+ end
+
+ test 'in incremental fetch type, if the build dir is not present, it should clone' do
+ vcs = mock_vcs
+ project = mock_project(vcs)
+ build = mock_build(project, vcs)
+
+ project.fetch_type = :incremental
+ build.stubs(:project_sources_already_present?).returns(false)
+
+ vcs.expects(:clone).once
+
+ build.perform
+ end
+
+ test 'in incremental fetch type, destroying a build should not remove the build dir' do
+ vcs = mock_vcs
+ project = mock_project(vcs)
+ build = mock_build(project, vcs)
+
+ build.build_dir = 'test/files/build'
+ `mkdir test/files/build`
+
+ project.fetch_type = :incremental
+
+ build.save!
+ build.destroy
+
+ assert File.directory?('test/files/build')
+ end
+
+ private
+
+ def mock_vcs
+ vcs = mocha
+ vcs.stubs(:head_info).returns([{},nil])
+ vcs
+ end
+
+ def mock_project(vcs)
+ project = project_with_steps({
+ :name => "Atom project",
+ :vcs_source => "no/such/repo",
+ }, "echo 'ha'")
+
+ project.stubs(:vcs).returns(vcs)
+ project
+ end
+
+ def mock_build(project, vcs)
+ build = Build.make(:project => project)
+ build.project = project
+ build.stubs(:vcs).returns(vcs)
+ build
+ end
+
end
View
17 test/unit/git_vcs_test.rb
@@ -45,6 +45,23 @@ def teardown
assert File.file?("test/files/repo_clone/new_file")
end
+ test "git should support incremental_build" do
+ vcs = init_repo
+
+ assert vcs.support_incremental_build?
+ end
+
+ test "git update should get commit in the clone" do
+ `cd test/files/repo; echo "new file" > new_file; git add new_file; git commit -m "new file"`
+ vcs = init_repo("test/files/repo", "master")
+ vcs.clone("test/files/repo_clone")
+
+ `cd test/files/repo; echo "new file" > new_file_2; git add new_file_2; git commit -m "new second file"`
+ vcs.update("test/files/repo_clone")
+
+ assert File.file?("test/files/repo_clone/new_file_2"), "The file has not been pulled"
+ end
+
private
def init_repo(dir = "test/files/repo", branch = "master")
BigTuna::VCS::Git.new(dir, branch)
View
42 test/unit/project_fetch_type_test.rb
@@ -0,0 +1,42 @@
+require 'test_helper'
+
+class ProjectFetchTypeTest < ActiveSupport::TestCase
+
+ test 'by default a project should build by cloning' do
+ project = project_with_steps({:name => "Atom project", :vcs_source => "no/such/repo", }, "echo 'ha'")
+ project.save!
+
+ assert_equal :clone, project.fetch_type, 'by default a project should build by cloning'
+ end
+
+ test 'should persist the fetch_type' do
+ project = project_with_steps({:name => "Atom project", :vcs_source => "no/such/repo", }, "echo 'ha'")
+ project.fetch_type = :incremental
+ project.save!
+
+ assert_equal :incremental, project.fetch_type, 'should persist the fetch_type'
+ end
+
+ test 'should validate a incremental build project if the vcs supports it' do
+ vcs = mocha
+ vcs.expects(:support_incremental_build?).returns(true)
+
+ project = project_with_steps({:name => "Atom project", :vcs_source => "no/such/repo", }, "echo 'ha'")
+ project.expects(:vcs).returns(vcs)
+ project.fetch_type = :incremental
+
+ assert project.valid?
+ end
+
+ test 'should not validate a incremental build project if the vcs does not support it' do
+ vcs = mocha
+ vcs.expects(:support_incremental_build?).returns(false)
+
+ project = project_with_steps({:name => "Atom project", :vcs_source => "no/such/repo", }, "echo 'ha'")
+ project.expects(:vcs).returns(vcs)
+ project.fetch_type = :incremental
+
+ assert !project.valid?
+ end
+
+end
View
16 test/unit/project_test.rb
@@ -455,6 +455,22 @@ def assert_project_lifecycle(project)
assert_equal "new name", project.name
end
+ test 'by default a project should build by cloning' do
+ project = project_with_steps({:vcs_source => "test/files/repo"}, "true", "true\nfalse")
+
+ project.save!
+
+ assert_equal :clone, project.fetch_type, 'by default a project should build by cloning'
+ end
+
+ test 'should persist the fetch_type' do
+ project = project_with_steps({:vcs_source => "test/files/repo", :fetch_type => :incremental}, "true", "true\nfalse")
+
+ project.save!
+
+ assert_equal :incremental, project.fetch_type, 'should persist the fetch_type'
+ end
+
private
def create_project_builds(project, *statuses)
statuses.reverse.each do |status|

0 comments on commit bb54fd9

Please sign in to comment.