def do(args): """Main entry point """ if "--name" in sys.argv: ui.warning("--name is deprecated, use --feed-name instead") feed = args.feed # Normalize feed path: if feed and os.path.exists(feed): feed = qisys.sh.to_native_path(feed) tc_name = args.name # Validate the name: must be a valid filename: bad_chars = r'<>:"/\|?*' for bad_char in bad_chars: if bad_char in tc_name: mess = "Invalid toolchain name: '%s'\n" % tc_name mess += "A valid toolchain name should not contain any " mess += "of the following chars:\n" mess += " ".join(bad_chars) raise Exception(mess) if tc_name in qitoolchain.get_tc_names(): toolchain = qitoolchain.Toolchain(tc_name) # pylint: disable=unused-variable ui.info(tc_name, "already exists,", "updating without removing") toolchain = qitoolchain.Toolchain(tc_name) if feed: toolchain.update(feed, branch=args.branch, name=args.feed_name) return toolchain
def do(args): """Main entry point """ feed = args.feed tc_name = args.name # Validate the name: must be a valid filename: bad_chars = r'<>:"/\|?*' for bad_char in bad_chars: if bad_char in tc_name: mess = "Invalid toolchain name: '%s'\n" % tc_name mess += "A valid toolchain name should not contain any " mess += "of the following chars:\n" mess += " ".join(bad_chars) raise Exception(mess) if tc_name == "system": raise Exception("'system' is a reserved name") build_worktree = None if args.default: try: build_worktree = qibuild.parsers.get_build_worktree(args) except qisys.worktree.NotInWorkTree: mess = "You need to be in a worktree to use --default" raise Exception(mess) if tc_name in qitoolchain.get_tc_names(): toolchain = qitoolchain.Toolchain(tc_name) if feed and toolchain.feed_url != feed: ui.warning(tc_name, "already exists but points to a different feed,", "removing previous toolchain and creating a new one") toolchain.remove() else: ui.info(tc_name, "already exists,", "updating without removing") toolchain = qitoolchain.Toolchain(tc_name) if feed: ui.info(ui.green, "Updating toolchain", tc_name, "with feed:", feed) toolchain.update(feed) if args.default: build_worktree.set_default_config(tc_name) ui.info("Now using toolchain", ui.blue, tc_name, ui.reset, "by default") else: ui.info(ui.green, "Now try using", "\n" " qibuild configure -c", ui.blue, tc_name, ui.green, "\n" " qibuild make -c", ui.blue, tc_name) return toolchain
def test_feed_is_stored(self): self.setup_srv() buildfarm_xml = os.path.join(self.srv, "buildfarm.xml") tc = qitoolchain.Toolchain("buildfarm") tc.parse_feed(buildfarm_xml) self.assertEquals(tc.feed, buildfarm_xml) # Create a new object, and check that feed storing # is persistent tc2 = qitoolchain.Toolchain("buildfarm") self.assertEquals(tc2.feed, buildfarm_xml)
def do(args): """ Main method """ tc_names = qitoolchain.get_tc_names() tc_name = args.name if tc_name: if not tc_name in qitoolchain.get_tc_names(): print "No such toolchain: ", tc_name return toolchain = qitoolchain.Toolchain(tc_name) print toolchain else: for tc_name in tc_names: toolchain = qitoolchain.Toolchain(tc_name) print toolchain print
def test_relative_url(self): os.mkdir(self.srv) feeds = os.path.join(self.srv, "feeds") packages = os.path.join(self.srv, "packages") os.mkdir(feeds) os.mkdir(packages) # Create a fake package a_package = os.path.join(packages, "a_package") os.mkdir(a_package) a_file = os.path.join(a_package, "a_file") with open(a_file, "w") as fp: fp.write("This file is not empty\n") archive = qibuild.archive.zip(a_package) package_name = os.path.basename(archive) # Create a fake feed: a_feed = os.path.join(feeds, "a_feed.xml") to_write = """<toolchain> <package name="a_package" url="{rel_url}" /> </toolchain> """ rel_url = "../packages/" + package_name to_write = to_write.format(rel_url=rel_url) with open(a_feed, "w") as fp: fp.write(to_write) tc = qitoolchain.Toolchain("test") feed_url = "file://" + qibuild.sh.to_posix_path(a_feed) tc.parse_feed(feed_url)
def do(args): """ Main entry point """ tc_name = args.name toolchain = qitoolchain.Toolchain(tc_name) LOGGER.info("Removing toolchain %s", tc_name) toolchain.remove() LOGGER.info("Done removing toolchain %s", tc_name)
def test_ctc_nonfree(self): self.setup_srv() # Generate a fake ctc in self.tmp ctc_path = os.path.join(self.tmp, "ctc") ctc_xml = self.configure_xml("ctc-nonfree.xml", ctc_path) tc = qitoolchain.Toolchain("ctc") tc.parse_feed(ctc_xml) package_names = [p.name for p in tc.packages] self.assertTrue("nuance" in package_names) self.assertTrue("naoqi-geode-ctc" in package_names) nuance_path = tc.get("nuance") nuance_geode = os.path.join(nuance_path, "nuance-42-geode") self.assertTrue(os.path.exists(nuance_geode)) ctc_path = tc.get("naoqi-geode-ctc") cross_tc_path = os.path.join(ctc_path, "toolchain-geode.cmake") cross_tc_path = qibuild.sh.to_posix_path(cross_tc_path) self.assertTrue(os.path.exists(cross_tc_path)) expected = 'include("%s")' % cross_tc_path tc_file = get_tc_file_contents(tc) self.assertTrue(expected in tc_file, "Did not find %s\n in\n %s" % (expected, tc_file))
def test_add_package_with_tc_file(self): tc = qitoolchain.Toolchain("test") naoqi_ctc = qitoolchain.Package("naoqi-ctc", "/path/to/ctc", "toolchain-geode.cmake") tc.add_package(naoqi_ctc) tc_file = get_tc_file_contents(tc) self.assertTrue('include("toolchain-geode.cmake")' in tc_file, tc_file)
def test_parse_feed_twice(self): self.setup_srv() tc = qitoolchain.Toolchain("test") full = os.path.join(self.srv, "full.xml") minimal = os.path.join(self.srv, "minimal.xml") tc.parse_feed(full) package_names = [p.name for p in tc.packages] package_names.sort() self.assertEquals(["boost", "python"], package_names) self.assertTrue("python" in get_tc_file_contents(tc)) tc2 = qitoolchain.Toolchain("test") tc2.parse_feed(minimal) package_names = [p.name for p in tc2.packages] package_names.sort() self.assertEquals(["boost"], package_names) self.assertFalse("python" in get_tc_file_contents(tc2))
def do(args): """ Main entry point """ if "--name" in sys.argv: ui.warning("--name is deprecated, use --feed-name instead") feed = args.feed # Normalize feed path: if feed and os.path.exists(feed): feed = qisys.sh.to_native_path(feed) tc_name = args.name qitoolchain.ensure_name_is_valid(tc_name) if tc_name in qitoolchain.get_tc_names(): toolchain = qitoolchain.Toolchain(tc_name) ui.info(tc_name, "already exists,", "updating without removing") toolchain = qitoolchain.Toolchain(tc_name) if feed: toolchain.update(feed, branch=args.branch, name=args.feed_name) return toolchain
def test_remove_package_with_tc_file(self): tc = qitoolchain.Toolchain("test") naoqi_ctc = qitoolchain.Package("naoqi-ctc", "/path/to/ctc", "toolchain-geode.cmake") tc.add_package(naoqi_ctc) tc.remove_package("naoqi-ctc") tc_file = get_tc_file_contents(tc) self.assertFalse("toolchain-geode.cmake" in tc_file)
def test_remove_package(self): tc = qitoolchain.Toolchain("test") error = None try: tc.remove_package("foo") except Exception, e: error = e
def test_master_maint(self): self.setup_srv() master_xml = os.path.join(self.srv, "master.xml") maint_xml = os.path.join(self.srv, "maint.xml") tc_master = qitoolchain.Toolchain("master") tc_maint = qitoolchain.Toolchain("maint") tc_master.parse_feed(master_xml) tc_maint.parse_feed(maint_xml) boost_master = tc_master.get("boost") boost_maint = tc_maint.get("boost") boost_44 = os.path.join(boost_master, "boost-1.44-linux32") boost_42 = os.path.join(boost_maint, "boost-1.42-linux32") self.assertTrue(os.path.exists(boost_44)) self.assertTrue(os.path.exists(boost_42))
def test_buildfarm(self): self.setup_srv() buildfarm_xml = os.path.join(self.srv, "buildfarm.xml") tc = qitoolchain.Toolchain("buildfarm") tc.parse_feed(buildfarm_xml) package_names = [p.name for p in tc.packages] self.assertTrue("boost" in package_names) self.assertTrue("naoqi" in package_names)
def test_sdk(self): # Generate a fake SDK in self.tmp sdk_path = os.path.join(self.tmp, "sdk") sdk_xml = self.configure_xml("sdk.xml", sdk_path) tc = qitoolchain.Toolchain("sdk") tc.parse_feed(sdk_xml) tc_file = get_tc_file_contents(tc) package_names = [p.name for p in tc.packages] self.assertTrue("naoqi-sdk" in package_names) self.assertTrue(qibuild.sh.to_posix_path(sdk_path) in tc_file)
def do(args): """Main entry point """ feed = args.feed if feed and not "://" in feed: feed = qisys.sh.to_native_path(feed) tc_name = args.name # Validate the name: must be a valid filename: bad_chars = r'<>:"/\|?*' for bad_char in bad_chars: if bad_char in tc_name: mess = "Invalid toolchain name: '%s'\n" % tc_name mess += "A valid toolchain name should not contain any " mess += "of the following chars:\n" mess += " ".join(bad_chars) raise Exception(mess) if tc_name == "system": raise Exception("'system' is a reserved name") build_worktree = None if tc_name in qitoolchain.get_tc_names(): toolchain = qitoolchain.Toolchain(tc_name) if feed and toolchain.feed_url != feed: ui.warning(tc_name, "already exists but points to a different feed,", "removing previous toolchain and creating a new one") toolchain.remove() else: ui.info(tc_name, "already exists,", "updating without removing") toolchain = qitoolchain.Toolchain(tc_name) if feed: toolchain.update(feed) return toolchain
def do(args): """Main entry point """ feed = args.feed tc_name = args.name dry_run = args.dry_run known_tc_names = qitoolchain.toolchain.get_tc_names() if tc_name: if not tc_name in known_tc_names: mess = "No such toolchain: '%s'\n" % tc_name mess += "Known toolchains are: %s" % known_tc_names raise Exception(mess) if not feed: feed = qitoolchain.toolchain.get_tc_feed(tc_name) if not feed: mess = "Could not find feed for toolchain %s\n" % tc_name mess += "Pleas check configuration or specifiy a feed on the command line\n" raise Exception(mess) LOGGER.info("Updating toolchain %s using %s", tc_name, feed) toolchain = qitoolchain.Toolchain(tc_name) toolchain.parse_feed(feed, dry_run=dry_run) else: for tc_name in qitoolchain.get_tc_names(): tc_feed = qitoolchain.toolchain.get_tc_feed(tc_name) if not tc_feed: LOGGER.info("No feed found for %s, skipping", tc_name) print continue LOGGER.info("###\n## Updating toolchain %s using %s\n##\n", tc_name, tc_feed) toolchain = qitoolchain.Toolchain(tc_name) toolchain.parse_feed(tc_feed, dry_run=dry_run) print
def test_add_package(self): tc = qitoolchain.Toolchain("test") self.assertEquals(tc.packages, list()) foo_package = qitoolchain.Package("foo", "/path/to/foo") tc.add_package(foo_package) self.assertEquals(tc.packages, [foo_package]) # Check that generated toolchain file is correct tc_file = get_tc_file_contents(tc) self.assertTrue( 'list(INSERT CMAKE_FIND_ROOT_PATH 0 "%s")' % "/path/to/foo" in tc_file, tc_file) # Check that adding the package twice does nothing tc.add_package(foo_package) self.assertEquals(tc.packages, [foo_package]) # Create a new toolchain object and check that toolchain # file contents did not change other_tc = qitoolchain.Toolchain("test") other_tc_file = get_tc_file_contents(other_tc) self.assertEquals(other_tc_file, tc_file)
def do(args): """ Main entry point """ tc_name = args.name dry_run = args.dry_run toc = None try: toc = qibuild.toc.toc_open(args.work_tree) except qibuild.toc.TocException: pass if not tc_name: if toc: tc_name = toc.active_config if not tc_name: mess = "Could not find which toolchain to update\n" mess += "Please specify a toolchain name from command line\n" mess += "Or edit your qibuild.cfg to set a default config\n" raise Exception(mess) known_tc_names = qitoolchain.toolchain.get_tc_names() if not tc_name in known_tc_names: mess = "No such toolchain: '%s'\n" % tc_name mess += "Known toolchains are: %s" % known_tc_names raise Exception(mess) toolchain = qitoolchain.Toolchain(tc_name) tc_cache = toolchain.cache dirs_to_rm = os.listdir(tc_cache) dirs_to_rm = [os.path.join(tc_cache, x) for x in dirs_to_rm] dirs_to_rm = [x for x in dirs_to_rm if os.path.isdir(x)] num_dirs = len(dirs_to_rm) LOGGER.info("Cleaning cache for %s", tc_name) if dry_run: print "Would remove %i packages" % num_dirs print "Use -f to proceed" return for (i, dir_to_rm) in enumerate(dirs_to_rm): sys.stdout.write("Removing package %i / %i\r" % ((i + 1), num_dirs)) sys.stdout.flush() qibuild.sh.rm(dir_to_rm) LOGGER.info("Done cleaning cache for %s", tc_name)
def test_tc_order(self): tc = qitoolchain.Toolchain("test") a_path = "/path/to/a" b_path = "/path/to/b" a_cmake = "a-config.cmake" b_cmake = "b-config.cmake" a_package = qitoolchain.Package("a", a_path, a_cmake) b_package = qitoolchain.Package("b", b_path, b_cmake) tc.add_package(a_package) tc.add_package(b_package) tc_file = get_tc_file_contents(tc) tc_file_lines = tc_file.splitlines() a_path_index = 0 b_path_index = 0 a_cmake_index = 0 b_cmake_index = 0 for (i, line) in enumerate(tc_file_lines): if a_cmake in line: a_cmake_index = i if b_cmake in line: b_cmake_index = i if a_path in line: a_path_index = i if b_path in line: b_path_index = i self.assertTrue(a_path_index != 0) self.assertTrue(b_path_index != 0) self.assertTrue(a_cmake_index != 0) self.assertTrue(b_cmake_index != 0) # Check that toolchain files are always written before # CMAKE_FIND_ROOT_PATH self.assertTrue(a_cmake_index < a_path_index) self.assertTrue(a_cmake_index < b_path_index) self.assertTrue(b_cmake_index < a_path_index) self.assertTrue(b_cmake_index < b_path_index)
def test_ctc(self): # Generate a fake ctc in self.tmp ctc_path = os.path.join(self.tmp, "ctc") ctc_xml = self.configure_xml("ctc.xml", ctc_path) qibuild_cfg = qibuild.config.QiBuildConfig() tc = qitoolchain.Toolchain("ctc") qitoolchain.feed.parse_feed(tc, ctc_xml, qibuild_cfg) # Check that configuration is correctly set: self.assertFalse(qibuild_cfg.configs.get("ctc") is None) self.assertEquals(qibuild_cfg.configs["ctc"].cmake.generator, "Unix Makefiles") # Check that generated toolchain file is correct: tc_file = get_tc_file_contents(tc) package_names = [p.name for p in tc.packages] self.assertTrue("naoqi-geode-ctc" in package_names) cross_tc_path = os.path.join(ctc_path, "toolchain-geode.cmake") cross_tc_path = qibuild.sh.to_posix_path(cross_tc_path) expected = 'include("%s")' % cross_tc_path self.assertTrue(expected in tc_file, "Did not find %s\n in\n %s" % (expected, tc_file))
def __init__(self, work_tree, path_hints=None, config=None, qibuild_cfg=None, build_type="Debug", cmake_flags=None, cmake_generator=None, active_projects=None, solve_deps=True): """ Create a new Toc object. Most of the keyargs come directly from the command line. (--wortree, --debug, -c, etc.) :param work_tree: see :py:meth:`qibuild.worktree.WorkTree.__init__` :param path_hints: see :py:meth:`qibuild.worktree.WorkTree.__init__` :param qibuild_cfg: a :py:class:`qibuild.config.QiBuildConfig` instance if not given, a new one will be created :param build_type: a build type, could be debug or release (defaults to debug) :param cmake_flags: optional additional cmake flags :param cmake_generator: optional cmake generator (defaults to Unix Makefiles) :param active_projects: the projects excplicitely specified by user """ WorkTree.__init__(self, work_tree, path_hints=path_hints) # The local config file in which to write self.config_path = os.path.join(self.work_tree, ".qi", "qibuild.xml") # When you are running toc actions for a qibuild project, sometimes # a Toc object is created on the fly (Using toc_open with a non # empty path_hints) variable. # In this case, the .qi directory may not even exists, nor the # .qi directory, so create it: if not os.path.exists(self.config_path): to_create = os.path.dirname(self.config_path) qibuild.sh.mkdir(to_create, recursive=True) with open(self.config_path, "w") as fp: fp.write("<qibuild />\n") # Perform format conversion if necessary handle_old_qibuild_cfg(self.work_tree) handle_old_qibuild_xml(self.work_tree) # Handle config: if not qibuild_cfg: self.config = qibuild.config.QiBuildConfig(config) self.config.read() else: self.config = config self.config.read_local_config(self.config_path) self.active_config = self.config.active_config # Special case if "--system" was used: if config == "system": self.active_config = None self.build_type = build_type if not self.build_type: self.build_type = "Debug" self.cmake_generator = cmake_generator self.build_folder_name = None # Set build environment envsetter = qibuild.envsetter.EnvSetter() envsetter.read_config(self.config) self.build_env = envsetter.get_build_env() # List of objects of type qibuild.project.Project, # this is updated using WorkTree.buildable_projects self.projects = list() # The list of projects the user asked for from command # line. # Set by toc_open() if not active_projects: self.active_projects = list() else: self.active_projects = active_projects self.solve_deps = solve_deps # Set cmake generator if user has not set if in Toc ctor: if not self.cmake_generator: self.cmake_generator = self.config.cmake.generator if not self.cmake_generator: self.cmake_generator = "Unix Makefiles" # Read the current config, create toolchain and pacakges object # if necessary self.packages = list() self.toolchain = None if self.active_config is not None: if self.active_config in qitoolchain.get_tc_names(): self.toolchain = qitoolchain.Toolchain(self.active_config) self.packages = self.toolchain.packages else: # The config does not match a toolchain local_dir = os.path.join(self.work_tree, ".qi") local_cmake = os.path.join(local_dir, "%s.cmake" % self.active_config) if not os.path.exists(local_cmake): mess = """Invalid configuration {active_config} * No toolchain named {active_config}. Known toolchains are: {tc_names} * No custom cmake file for config {active_config} found. (looked in {local_cmake}) """ mess = mess.format(active_config=self.active_config, local_cmake=local_cmake, tc_names=qitoolchain.get_tc_names()) if self.active_config == self.config.local.defaults.config: mess += """Note: this is your default config You may want to run: * `qibuild init --force` (to re-initialize your worktree and not use any toolchain) * `qibuild init --force` --config=<config> (to use a different toolchain by default) """ raise WrongDefaultException(mess) else: raise Exception(mess) # Useful vars to cope with Visual Studio quirks self.using_visual_studio = "Visual Studio" in self.cmake_generator self.vc_version = self.cmake_generator.split()[-1] # The actual list of cmake flags we are going to use # will be computed during self.update_projects # Right now, we will just store the flags passed in ctor # in self.user_cmake_flags, to be sure they are always added # at the end of the list of flags if cmake_flags: self.user_cmake_flags = cmake_flags[:] else: self.user_cmake_flags = list() # Finally, update the build configuration of all the projects # (this way we are sure that the build configuration is the same for # every project) self.update_projects()
toc = None if args.default: try: toc = qibuild.toc.toc_open(args.work_tree) except qibuild.toc.TocException, e: mess = "You need to be in a valid toc worktree to use --default\n" mess += "Exception was:\n" mess += str(e) raise Exception(mess) if tc_name in qitoolchain.get_tc_names(): LOGGER.info( "%s already exists, removing previous " "toolchain and creating a new one", tc_name) toolchain = qitoolchain.Toolchain(tc_name) toolchain.remove() toolchain = qitoolchain.Toolchain(tc_name) if feed: toolchain.parse_feed(feed, dry_run=dry_run) if args.default: toc.config.set_default_config(tc_name) toc.save_config() LOGGER.info("Now using toolchain %s by default", tc_name) else: mess = """Now try using: qibuild configure -c {tc_name} qibuild make -c {tc_name} """
def test_remove_toolchain(self): tc = qitoolchain.Toolchain("foo") self.assertEquals(qitoolchain.get_tc_names(), ["foo"]) tc.remove() self.assertEquals(qitoolchain.get_tc_names(), list())
def test_create_toolchain(self): qitoolchain.Toolchain("foo") self.assertEquals(qitoolchain.get_tc_names(), ["foo"])