#! /usr/bin/env ruby if !defined?(ORIGINAL_ARGV) ORIGINAL_ARGV = ARGV.dup end if RUBY_VERSION < "1.9.2" STDERR.puts "autoproj requires Ruby >= 1.9.2" exit 1 end require 'autoproj' require 'autoproj/autobuild' require 'open-uri' require 'autoproj/cmdline' include Autoproj InputError = Autoproj::InputError def color(*args) Autoproj.color(*args) end Encoding.default_internal = Encoding::UTF_8 Encoding.default_external = Encoding::UTF_8 Autoproj::OSDependencies.autodetect_ruby # Check the first element of ARGV. If a tool called autoproj-VALUE exists, just # pass the hand to it prefix = File.expand_path(__FILE__) if File.file?("#{prefix}-#{ARGV.first}") binary = "#{prefix}-#{ARGV.shift}" # RubyGems have a BIG performance problem when $LOADED_PATH starts to be # big. # # So, if the sub-script is Ruby-based, just load it and exit if File.readlines(binary).first =~ /ruby/ load binary exit else exec(binary, *ARGV) end end # Find the autoproj root dir Autoproj::CmdLine.report do selected_packages = Autoproj::CmdLine.parse_arguments(ARGV.dup) # Expand directories in the selected_packages set, before we chdir to the # autoproj root root_dir = Autoproj.root_dir selected_packages.map! do |name| if File.directory?(name) File.expand_path(name) + File::SEPARATOR else name end end needs_update_config = false selected_packages.delete_if do |name| if name =~ /^#{Regexp.quote(Autoproj.config_dir + File::SEPARATOR)}/ || name =~ /^#{Regexp.quote(Autoproj.remotes_dir + File::SEPARATOR)}/ needs_update_config = true elsif (Autoproj.config_dir + File::SEPARATOR) =~ /^#{Regexp.quote(name)}/ needs_update_config = true false end end Dir.chdir(root_dir) # Basic initialization Autoproj::CmdLine.initialize if needs_update_config Autoproj::CmdLine.update_configuration if selected_packages.empty? exit 0 end elsif selected_packages.empty? Autoproj::CmdLine.update_myself Autoproj::CmdLine.update_configuration else begin old_value = Autobuild.do_update Autobuild.do_update = false Autoproj::CmdLine.update_configuration ensure Autobuild.do_update = old_value end end Autoproj::CmdLine.load_configuration manifest = Autoproj.manifest Autoproj::CmdLine.setup_all_package_directories # resolve_user_selection auto-adds packages present on disk but not listed # in the manifest. However, since we have not yet loaded overrides / # package blocks, it is possible that it contains excluded / ignored # packages # # First do the resolution to get auto-add, finalize the package # configuration, and then re-resolve Autoproj::CmdLine.resolve_user_selection(selected_packages) # Now load the rest of the configuration Autoproj::CmdLine.finalize_package_setup # Finally, filter out exclusions resolved_selected_packages = Autoproj::CmdLine.resolve_user_selection(selected_packages) Autoproj::CmdLine.validate_user_selection(selected_packages, resolved_selected_packages) if !selected_packages.empty? command_line_selection = resolved_selected_packages.dup else command_line_selection = Array.new end Autoproj.manifest.explicit_selection = resolved_selected_packages selected_packages = resolved_selected_packages if other_root = Autoproj::CmdLine.update_from Autobuild::Package.each do |_, pkg| if pkg.importer.respond_to?(:pick_from_autoproj_root) if !pkg.importer.pick_from_autoproj_root(pkg, other_root) pkg.update = false end else pkg.update = false end end end # If in verbose mode, or if we only update sources, list the sources if Autoproj.verbose || Autoproj::CmdLine.display_configuration? Autoproj::CmdLine.display_configuration(manifest, selected_packages.packages) end if Autoproj::CmdLine.only_config? || Autoproj::CmdLine.reconfigure? exit(0) end if Autoproj::CmdLine.only_status? all_enabled_packages = Autoproj::CmdLine.import_packages(selected_packages) result = Autoproj::CmdLine.status(all_enabled_packages) if Autoproj::CmdLine.status_exit_code? code = 0 if result.uncommitted code |= 1 end if result.local code |= 2 end if result.remote code |= 4 end exit(code) else exit(0) end elsif Autoproj::CmdLine.check? all_enabled_packages = Autoproj::CmdLine.import_packages(selected_packages) Autoproj::CmdLine.check(all_enabled_packages) exit(0) elsif Autoproj::CmdLine.manifest_update? all_enabled_packages = Autoproj::CmdLine.import_packages(selected_packages) Autoproj::CmdLine.manifest_update(all_enabled_packages) exit(0) elsif Autoproj::CmdLine.snapshot? all_enabled_packages = Autoproj::CmdLine.import_packages(selected_packages) Autoproj::CmdLine.snapshot(Autoproj::CmdLine.snapshot_dir, all_enabled_packages) exit(0) elsif Autoproj::CmdLine.revshow_osdeps? all_enabled_packages = Autoproj::CmdLine.import_packages(selected_packages) Autoproj::CmdLine.revshow_osdeps(all_enabled_packages) exit(0) elsif Autoproj::CmdLine.show_osdeps? all_enabled_packages = Autoproj::CmdLine.import_packages(selected_packages) Autoproj::CmdLine.show_osdeps(all_enabled_packages) exit(0) elsif Autoproj::CmdLine.list_unused? all_enabled_packages = Autoproj::CmdLine.import_packages(selected_packages) Autoproj::CmdLine.list_unused(all_enabled_packages) exit(0) end STDERR.puts STDERR.puts color("autoproj: importing and loading selected packages", :bold) # Install prepackaged dependencies needed to import and build the packages. # The required information is in the package sets configuration. if Autoproj::CmdLine.update_os_dependencies? Autoproj.osdeps.install(Autoproj.build_system_dependencies) end # Now, we actually do the import. Unfortunately, at this stage, we need to # import the package and its dependencies ourselves so that we are able to # build the list of packages that have actually been selected on the command # line. all_enabled_packages = Autoproj::CmdLine.import_packages(selected_packages) Autoproj::CmdLine.load_all_available_package_manifests(false) Autoproj::CmdLine.export_installation_manifest if Autoproj::CmdLine.update_os_dependencies? && !all_enabled_packages.empty? begin update_mode = Autobuild.do_update Autobuild.do_update ||= Autoproj::CmdLine.osdeps? manifest.install_os_dependencies(all_enabled_packages) ensure Autobuild.do_update = update_mode end end if all_enabled_packages.empty? STDERR.puts color("autoproj: nothing to do", :bold) elsif Autoproj::CmdLine.build? Autoproj.message("autoproj: building and installing packages", :bold) Autoproj::CmdLine.build_packages(command_line_selection, all_enabled_packages) end if Autoproj::CmdLine.update_envsh? Autoproj.export_env_sh Autoproj.message "autoproj: updated #{Autoproj.root_dir}/#{Autoproj::ENV_FILENAME}", :green end if Autoproj::CmdLine.show_statistics? per_phase = Hash.new per_type = Hash.new Autoproj.message Autoproj.message "statistics about the build", :bold Autoproj.manifest.each_autobuild_package.sort_by(&:name).each do |pkg| next if pkg.statistics.empty? if per_phase.empty? Autoproj.message "detailed per package" end puts " #{pkg.name}: %.1fs" % [pkg.statistics.values.inject(&:+)] pkg.statistics.each_key.sort.each do |phase| per_phase[phase] ||= 0 per_phase[phase] += pkg.statistics[phase] per_type[pkg.class] ||= Hash.new per_type[pkg.class][phase] ||= 0 per_type[pkg.class][phase] += pkg.statistics[phase] puts " #{phase}: %.1fs" % [pkg.statistics[phase]] end end if !per_type.empty? Autoproj.message Autoproj.message "detailed per package type" per_type.each do |pkg_type, phases| Autoproj.message " #{pkg_type.name}: %.1fs" % [phases.values.inject(&:+)] phases.each_key.sort.each do |phase_name| Autoproj.message " #{phase_name}: %.1fs" % [phases[phase_name]] end end end if !per_phase.empty? Autoproj.message Autoproj.message "summary per phase" per_phase.keys.sort.each do |phase_name| Autoproj.message " #{phase_name}: %.1fs" % [per_phase[phase_name]] end end end end