require 'spec_helper' describe Omnibus::Library do let(:project) { Omnibus::Project.load(project_path('chefdk')) } let(:library) { Omnibus::Library.new(project) } let(:erchef) { Omnibus::Software.load(software_path('erchef'), project) } let(:zlib) { Omnibus::Software.load(software_path('zlib'), project) } def gen_software(name, deps) software = Omnibus::Software.new('', "#{name}.rb", 'chef-server') software.name(name.to_s) deps.each do |dep| software.dependency(dep) end software end describe '#component_added' do it 'adds the software to the component list' do library.component_added(erchef) expect(library.components).to eql([erchef]) end it 'does not add a component more than once' do library.component_added(erchef) library.component_added(erchef) expect(library.components).to eql([erchef]) end end describe '#build_order' do let(:project) do raw_project = <<-EOH name "chef-server" install_path "/opt/chef-server" build_version "1.0.0" maintainer 'Chef Software, Inc' homepage 'http://getchef.com' dependency 'preparation' dependency 'erchef' dependency 'postgresql' dependency 'chef' EOH Omnibus::Project.new(raw_project, 'chef-server.rb') end let(:library) do library = Omnibus::Library.new(project) library.component_added(preparation) library.component_added(erlang) library.component_added(postgresql) # as a skitch trans dep library.component_added(skitch) library.component_added(erchef) library.component_added(ruby) library.component_added(chef) library end project_deps = [:preparation, :erchef, :postgresql, :chef] erchef_deps = [:erlang, :skitch] chef_deps = [:ruby] [project_deps, erchef_deps, chef_deps].flatten.each do |dep| let(dep) do software = Omnibus::Software.new('', "#{dep}.rb", 'chef-server') software.name(dep.to_s) software.dependency('postgresql') if dep == :skitch software end end it 'returns an array of software descriptions, with all top level deps first, assuming they are not themselves transitive deps' do library.build_order.map { |m| m.name.to_s } expect(library.build_order).to eql([preparation, erlang, postgresql, skitch, ruby, erchef, chef]) end context 'with a complex dep tree' do # rubocop:disable all [ ['preparation', []], ['erchef', ['erlang', 'skitch']], ['postgresql', []], ['erlang', []], ['skitch', ['postgresql']], ['chef', ['ruby', 'bundler', 'ohai']], ['ohai', ['ruby']], ['bundler', ['ruby']], ['ruby', []], ['chefdk', ['ruby', 'bundler']], ].each do |item| name = item[0] deps = item[1] let(name) do gen_software(name, deps) end end let(:project) do raw_project = <<-EOH name "chef-dk" install_path "/opt/chefdk" build_version "1.0.0" maintainer 'Chef Software, Inc' homepage 'http://getchef.com' dependency 'preparation' dependency 'erchef' dependency 'postgresql' dependency 'ruby' dependency 'chef' dependency 'chefdk' EOH Omnibus::Project.new(raw_project, 'chefdk.rb') end let(:library) do # This is the LOAD ORDER library = Omnibus::Library.new(project) library.component_added(preparation) # via project library.component_added(erlang) # via erchef library.component_added(postgresql) # via skitch library.component_added(skitch) # via erchef library.component_added(erchef) # erchef library.component_added(ruby) # via project library.component_added(bundler) # via chef library.component_added(ohai) # via chef library.component_added(chef) # via project library.component_added(chefdk) # via project library end it 'returns an array of software descriptions, with all top level deps first, assuming they are not themselves transitive deps' do expect(library.build_order).to eql( [ preparation, # first erlang, # via erchef project postgresql, # via skitch transitive skitch, # via erchef project ruby, # via bundler transitive bundler, # via chef ohai, # via chef erchef, # project dep chef, # project dep chefdk, # project dep ]) end end context 'with real data' do before do Omnibus.stub(:project_root).and_return(complicated_path) # Ohai stuff stub_const('File::ALT_SEPARATOR', '\\') stub_ohai(platform: 'windows') Omnibus.process_dsl_files end after { Omnibus.reset! } let(:chefdk_windows) do Omnibus.projects.find { |p| p.name.to_s == 'chefdk-windows' } end it 'has the right build order for chefdk-windows on windows' do names = chefdk_windows.library.build_order.map { |m| m.name.to_s } expect(names).to eql([ 'preparation', # via project dep 'ruby-windows', # via libyaml-windows trans dep 'libyaml-windows', # via ruby-windows trans 'ruby-windows-devkit', # via trans dep from chef-windows 'bundler', # via trans dep from chef-windows 'cacerts', # via chef-windows 'chef-windows', # via transitive dep from chefdk 'nokogiri', # via test-kitchen 'test-kitchen', # via chefdk 'appbundler', # via chefdk 'berkshelf', # via chefdk 'chef-vault', # via chefdk 'chefdk', # via project dep 'chef-client-msi', # via top level dep ]) end end end end