require 'spec_helper' require 'trip_advisor/build' require 'ostruct' require 'fileutils' # Alias out Pod::Spec as an OpenStruct so that we can access its fields module Pod class Spec < OpenStruct def initialize super yield self if block_given? end end end module BuildHelpers def project_path File.join(root_path, 'project.git') end end class TestSpecRepo attr_reader :path, :name, :repo def initialize @path = Dir.mktmpdir @repo = Rugged::Repository.init_at(@path, :bare) make_initial_commit @name = File.basename(path) end def url "file://#{path}" end def user_path File.expand_path(File.join("~/.cocoapods/repos", name)) end private def make_initial_commit oid = repo.write("This is a test Spec Repository.", :blob) index = Rugged::Index.new index.add(:path => "README.md", :oid => oid, :mode => 0100644) options = {} options[:tree] = index.write_tree(repo) options[:author] = { :email => "testuser@github.com", :name => 'Test Author', :time => Time.now } options[:committer] = { :email => "testuser@github.com", :name => 'Test Author', :time => Time.now } options[:message] = "Making a commit via Rugged!" options[:parents] = [] options[:update_ref] = 'HEAD' Rugged::Commit.create(repo, options) end end describe TripAdvisor::AdHocBuild do include BuildHelpers before(:each) do # Initialize a new empty repository to add as a remote @remote_dir = Dir.mktmpdir Rugged::Repository.init_at(@remote_dir, :bare) # Sync the fixture project into a temporary path to work with @project_dir = Dir.mktmpdir repo = Rugged::Repository.clone_at(project_path, @project_dir) podfile_path = File.join(@project_dir, 'Project.podspec') podfile_contents = File.read(podfile_path) podfile_contents.gsub!('$GIT_URL', "file://#{@remote_dir}") File.open(podfile_path, 'w') { |f| f << podfile_contents } # Configure the project under test config = repo.config config['user.name'] = 'Project Builder' config['user.email'] = 'builder@example.com' # Add the empty repository as a remote on the project under test repo = Rugged::Repository.new(@project_dir) remote = Rugged::Remote.lookup(repo, 'origin') remote.url = @remote_dir remote.save end after(:each) do FileUtils.remove_entry_secure(@project_dir) FileUtils.remove_entry_secure(@remote_dir) end it "generates build info" do build = TripAdvisor::AdHocBuild.new(@project_dir) info = build.info end it "generates a version based on the release version and timestamp" do time = Time.at(1381331500) Time.stub(:now).and_return(time) build = TripAdvisor::AdHocBuild.new(@project_dir) build.version.should == "1.0.0-b20131009151140" end it "generates the correct tag name" do time = Time.at(1381331500) Time.stub(:now).and_return(time) build = TripAdvisor::AdHocBuild.new(@project_dir) build.tag_name.should == "builds/v1.0.0-b20131009151140" end it "has a proper default for remotes" do build = TripAdvisor::AdHocBuild.new(@project_dir) build.remotes.should == ['origin'] end it "only calls `git remote` once when access remotes" do build = TripAdvisor::AdHocBuild.new(@project_dir) build.should_receive(:`).with('git remote').once.and_return('origin') build.remotes build.remotes end it "has a proper default for pod_repo" do build = TripAdvisor::AdHocBuild.new(@project_dir) build.pod_repo.should == 'tripadvisor-mobile-ta-specs' end it "has a proper default for version_prefix" do build = TripAdvisor::AdHocBuild.new(@project_dir) build.version_prefix.should == 'v' end context 'when building' do before(:each) do time = Time.at(1381331500) Time.stub(:now).and_return(time) @spec_repo = TestSpecRepo.new system("pod repo add #{@spec_repo.name} #{@spec_repo.url}") @build = TripAdvisor::AdHocBuild.new(@project_dir) @build.pod_repo = @spec_repo.name @build.build! end after(:each) do FileUtils.remove_entry_secure(@spec_repo.path) system("pod repo remove #{@spec_repo.name}") end it "updates the BUILD.json file" do build_info = File.join(@project_dir, 'BUILD.json') info = Oj.load(File.read(build_info)) info['version'].should == '1.0.0-b20131009151140' info['branch'].should == 'master' info['sha1'].should_not be_nil info['author'].should == 'Project Builder ' info['date'].should == '2013-10-09T15:11:40Z' end it "updates the Project.podspec file" do podspec_path = File.join(@project_dir, 'Project.podspec') spec = eval(File.read(podspec_path), nil, podspec_path) spec.version.should == '1.0.0-b20131009151140' spec.source[:tag].should == 'builds/v1.0.0-b20131009151140' end it "pushes the tag to the remote repository" do repo = Rugged::Repository.new(@remote_dir) ref = Rugged::Reference.lookup(repo, "refs/tags/builds/v1.0.0-b20131009151140") ref.should_not be_nil end it "pushes the podspec to the spec repository" do path = File.join(@spec_repo.user_path, 'Project', @build.version, 'Project.podspec') File.exists?(path).should be_true end end describe TripAdvisor::ReleaseBuild do include BuildHelpers it "generates build info" do build = TripAdvisor::ReleaseBuild.new(@project_dir, "1.0.1") info = build.info end it "generates a version based on the release version" do build = TripAdvisor::ReleaseBuild.new(@project_dir, "1.0.1") build.version.should == "1.0.1" end it "generates the correct tag name" do build = TripAdvisor::ReleaseBuild.new(@project_dir, "1.0.1") build.tag_name.should == "v1.0.1" end it "has a proper default for remotes" do build = TripAdvisor::ReleaseBuild.new(@project_dir, "1.0.1") build.remotes.should == ['origin'] end it "only calls `git remote` once when access remotes" do build = TripAdvisor::ReleaseBuild.new(@project_dir, "1.0.1") build.should_receive(:`).with('git remote').once.and_return('origin') build.remotes build.remotes end it "has a proper default for pod_repo" do build = TripAdvisor::ReleaseBuild.new(@project_dir, "1.0.1") build.pod_repo.should == 'tripadvisor-mobile-ta-specs' end it "has a proper default for version_prefix" do build = TripAdvisor::ReleaseBuild.new(@project_dir, "1.0.1") build.version_prefix.should == 'v' end context 'when building' do before(:each) do time = Time.at(1381331500) Time.stub(:now).and_return(time) @spec_repo = TestSpecRepo.new system("pod repo add #{@spec_repo.name} #{@spec_repo.url}") @build = TripAdvisor::ReleaseBuild.new(@project_dir, "1.0.1") @build.pod_repo = @spec_repo.name @build.build! end after(:each) do FileUtils.remove_entry_secure(@spec_repo.path) system("pod repo remove #{@spec_repo.name}") end it "updates the BUILD.json file" do build_info = File.join(@project_dir, 'BUILD.json') info = Oj.load(File.read(build_info)) info['version'].should == '1.0.1' info['branch'].should == 'master' info['sha1'].should_not be_nil info['author'].should == 'Project Builder ' info['date'].should == '2013-10-09T15:11:40Z' end it "updates the Project.podspec file" do podspec_path = File.join(@project_dir, 'Project.podspec') spec = eval(File.read(podspec_path), nil, podspec_path) spec.version.should == '1.0.1' spec.source[:tag].should == 'v1.0.1' end it "pushes the tag to the remote repository" do repo = Rugged::Repository.new(@remote_dir) ref = Rugged::Reference.lookup(repo, "refs/tags/v1.0.1") ref.should_not be_nil end it "pushes the podspec to the spec repository" do path = File.join(@spec_repo.user_path, 'Project', @build.version, 'Project.podspec') File.exists?(path).should be_true end end end end