def runTest(self): ver = "1.2.3" verpref = "myprefix" versuff = "mysuffix" tcname = "mytc" tcver = "4.1.2" extra_patches = ['t5.patch', 't6.patch'] homepage = "http://www.justatest.com" tweaks = { 'version': ver, 'versionprefix': verpref, 'versionsuffix': versuff, 'toolchain_version': tcver, 'patches': extra_patches } tweak(self.eb_file, self.tweaked_fn, tweaks) eb = EasyConfig(self.tweaked_fn, valid_stops=self.all_stops) self.assertEqual(eb['version'], ver) self.assertEqual(eb['versionprefix'], verpref) self.assertEqual(eb['versionsuffix'], versuff) self.assertEqual(eb['toolchain']['version'], tcver) self.assertEqual(eb['patches'], extra_patches + self.patches) eb = EasyConfig(self.eb_file, valid_stops=self.all_stops) # eb['toolchain']['version'] = tcver does not work as expected with templating enabled eb.enable_templating = False eb['version'] = ver eb['toolchain']['version'] = tcver eb.enable_templating = True eb.dump(self.eb_file) tweaks = { 'toolchain_name': tcname, 'patches': extra_patches[0:1], 'homepage': homepage, 'foo': "bar" } tweak(self.eb_file, self.tweaked_fn, tweaks) eb = EasyConfig(self.tweaked_fn, valid_stops=self.all_stops) self.assertEqual(eb['toolchain']['name'], tcname) self.assertEqual(eb['toolchain']['version'], tcver) self.assertEqual(eb['patches'], extra_patches[0:1] + self.patches) self.assertEqual(eb['version'], ver) self.assertEqual(eb['homepage'], homepage)
def test_tweaking(self): """test tweaking ability of easyconfigs""" fd, tweaked_fn = tempfile.mkstemp(prefix='easybuild-tweaked-', suffix='.eb') os.close(fd) patches = ["t1.patch", ("t2.patch", 1), ("t3.patch", "test"), ("t4.h", "include")] self.contents = '\n'.join([ 'name = "pi"', 'homepage = "http://www.google.com"', 'description = "dummy description"', 'version = "3.14"', 'toolchain = {"name":"GCC", "version": "4.6.3"}', 'patches = %s', ]) % str(patches) self.prep() ver = "1.2.3" verpref = "myprefix" versuff = "mysuffix" tcname = "mytc" tcver = "4.1.2" new_patches = ['t5.patch', 't6.patch'] homepage = "http://www.justatest.com" tweaks = { 'version': ver, 'versionprefix': verpref, 'versionsuffix': versuff, 'toolchain_version': tcver, 'patches': new_patches } tweak(self.eb_file, tweaked_fn, tweaks) eb = EasyConfig(tweaked_fn, valid_stops=self.all_stops) self.assertEqual(eb['version'], ver) self.assertEqual(eb['versionprefix'], verpref) self.assertEqual(eb['versionsuffix'], versuff) self.assertEqual(eb['toolchain']['version'], tcver) self.assertEqual(eb['patches'], new_patches) eb = EasyConfig(self.eb_file, valid_stops=self.all_stops) # eb['toolchain']['version'] = tcver does not work as expected with templating enabled eb.enable_templating = False eb['version'] = ver eb['toolchain']['version'] = tcver eb.enable_templating = True eb.dump(self.eb_file) tweaks = { 'toolchain_name': tcname, 'patches': new_patches[:1], 'homepage': homepage, 'foo': "bar" } tweak(self.eb_file, tweaked_fn, tweaks) eb = EasyConfig(tweaked_fn, valid_stops=self.all_stops) self.assertEqual(eb['toolchain']['name'], tcname) self.assertEqual(eb['toolchain']['version'], tcver) self.assertEqual(eb['patches'], new_patches[:1]) self.assertEqual(eb['version'], ver) self.assertEqual(eb['homepage'], homepage) # specify patches as string, eb should promote it to a list because original value was a list tweaks['patches'] = new_patches[0] eb = EasyConfig(tweaked_fn, valid_stops=self.all_stops) self.assertEqual(eb['patches'], [new_patches[0]]) # cleanup os.remove(tweaked_fn)
def test_tweaking(self): """test tweaking ability of easyconfigs""" fd, tweaked_fn = tempfile.mkstemp(prefix='easybuild-tweaked-', suffix='.eb') os.close(fd) patches = [ "t1.patch", ("t2.patch", 1), ("t3.patch", "test"), ("t4.h", "include") ] self.contents = '\n'.join([ 'name = "pi"', 'homepage = "http://www.google.com"', 'description = "dummy description"', 'version = "3.14"', 'toolchain = {"name":"GCC", "version": "4.6.3"}', 'patches = %s', ]) % str(patches) self.prep() ver = "1.2.3" verpref = "myprefix" versuff = "mysuffix" tcname = "mytc" tcver = "4.1.2" new_patches = ['t5.patch', 't6.patch'] homepage = "http://www.justatest.com" tweaks = { 'version': ver, 'versionprefix': verpref, 'versionsuffix': versuff, 'toolchain_version': tcver, 'patches': new_patches } tweak(self.eb_file, tweaked_fn, tweaks) eb = EasyConfig(tweaked_fn, valid_stops=self.all_stops) self.assertEqual(eb['version'], ver) self.assertEqual(eb['versionprefix'], verpref) self.assertEqual(eb['versionsuffix'], versuff) self.assertEqual(eb['toolchain']['version'], tcver) self.assertEqual(eb['patches'], new_patches) eb = EasyConfig(self.eb_file, valid_stops=self.all_stops) # eb['toolchain']['version'] = tcver does not work as expected with templating enabled eb.enable_templating = False eb['version'] = ver eb['toolchain']['version'] = tcver eb.enable_templating = True eb.dump(self.eb_file) tweaks = { 'toolchain_name': tcname, 'patches': new_patches[:1], 'homepage': homepage, 'foo': "bar" } tweak(self.eb_file, tweaked_fn, tweaks) eb = EasyConfig(tweaked_fn, valid_stops=self.all_stops) self.assertEqual(eb['toolchain']['name'], tcname) self.assertEqual(eb['toolchain']['version'], tcver) self.assertEqual(eb['patches'], new_patches[:1]) self.assertEqual(eb['version'], ver) self.assertEqual(eb['homepage'], homepage) # specify patches as string, eb should promote it to a list because original value was a list tweaks['patches'] = new_patches[0] eb = EasyConfig(tweaked_fn, valid_stops=self.all_stops) self.assertEqual(eb['patches'], [new_patches[0]]) # cleanup os.remove(tweaked_fn)
def main(testing_data=(None, None, None)): """ Main function: @arg options: a tuple: (options, paths, logger, logfile, hn) as defined in parse_options This function will: - read easyconfig - build software """ # disallow running EasyBuild as root if os.getuid() == 0: sys.stderr.write("ERROR: You seem to be running EasyBuild with root privileges.\n" "That's not wise, so let's end this here.\n" "Exiting.\n") sys.exit(1) # steer behavior when testing main testing = testing_data[0] is not None args, logfile, do_build = testing_data # initialise options eb_go = eboptions.parse_options(args=args) options = eb_go.options orig_paths = eb_go.args # set temporary directory to use eb_tmpdir = set_tmpdir(options.tmpdir) # initialise logging for main if options.logtostdout: fancylogger.logToScreen(enable=True, stdout=True) else: if logfile is None: # mkstemp returns (fd,filename), fd is from os.open, not regular open! fd, logfile = tempfile.mkstemp(suffix='.log', prefix='easybuild-') os.close(fd) fancylogger.logToFile(logfile) print_msg('temporary log file in case of crash %s' % (logfile), log=None, silent=testing) global _log _log = fancylogger.getLogger(fname=False) # hello world! _log.info(this_is_easybuild()) # how was EB called? eb_command_line = eb_go.generate_cmd_line() + eb_go.args _log.info("Command line: %s" % (" ".join(eb_command_line))) _log.info("Using %s as temporary directory" % eb_tmpdir) if not options.robot is None: if options.robot: _log.info("Using robot path(s): %s" % options.robot) else: _log.error("No robot paths specified, and unable to determine easybuild-easyconfigs install path.") # do not pass options.robot, it's not a list instance (and it shouldn't be modified) robot_path = None if options.robot: robot_path = list(options.robot) # determine easybuild-easyconfigs package install path easyconfigs_paths = get_paths_for("easyconfigs", robot_path=robot_path) # keep track of paths for install easyconfigs, so we can obtain find specified easyconfigs easyconfigs_pkg_full_paths = easyconfigs_paths[:] if not easyconfigs_paths: _log.warning("Failed to determine install path for easybuild-easyconfigs package.") # specified robot paths are preferred over installed easyconfig files if robot_path: robot_path.extend(easyconfigs_paths) easyconfigs_paths = robot_path[:] _log.info("Extended list of robot paths with paths for installed easyconfigs: %s" % robot_path) # initialise the easybuild configuration config.init(options, eb_go.get_options_by_section('config')) # building a dependency graph implies force, so that all dependencies are retained # and also skips validation of easyconfigs (e.g. checking os dependencies) retain_all_deps = False if options.dep_graph: _log.info("Enabling force to generate dependency graph.") options.force = True retain_all_deps = True build_options = { 'aggregate_regtest': options.aggregate_regtest, 'check_osdeps': not options.ignore_osdeps, 'command_line': eb_command_line, 'debug': options.debug, 'dry_run': options.dry_run, 'easyblock': options.easyblock, 'experimental': options.experimental, 'force': options.force, 'ignore_dirs': options.ignore_dirs, 'modules_footer': options.modules_footer, 'only_blocks': options.only_blocks, 'recursive_mod_unload': options.recursive_module_unload, 'regtest_online': options.regtest_online, 'regtest_output_dir': options.regtest_output_dir, 'retain_all_deps': retain_all_deps, 'robot_path': robot_path, 'sequential': options.sequential, 'silent': testing, 'skip': options.skip, 'skip_test_cases': options.skip_test_cases, 'stop': options.stop, 'valid_module_classes': module_classes(), 'valid_stops': [x[0] for x in EasyBlock.get_steps()], 'validate': not options.force, } # search for easyconfigs if options.search or options.search_short: search_path = [os.getcwd()] if easyconfigs_paths: search_path = easyconfigs_paths query = options.search or options.search_short search_file(search_path, query, build_options=build_options, short=not options.search) # process software build specifications (if any), i.e. # software name/version, toolchain name/version, extra patches, ... (try_to_generate, build_specs) = process_software_build_specs(options) paths = [] if len(orig_paths) == 0: if 'name' in build_specs: paths = [obtain_path(build_specs, easyconfigs_paths, try_to_generate=try_to_generate, exit_on_error=not testing)] elif not any([options.aggregate_regtest, options.search, options.search_short, options.regtest]): print_error(("Please provide one or multiple easyconfig files, or use software build " "options to make EasyBuild search for easyconfigs"), log=_log, opt_parser=eb_go.parser, exit_on_error=not testing) else: # look for easyconfigs with relative paths in easybuild-easyconfigs package, # unless they were found at the given relative paths if easyconfigs_pkg_full_paths: # determine which easyconfigs files need to be found, if any ecs_to_find = [] for idx, orig_path in enumerate(orig_paths): if orig_path == os.path.basename(orig_path) and not os.path.exists(orig_path): ecs_to_find.append((idx, orig_path)) _log.debug("List of easyconfig files to find: %s" % ecs_to_find) # find missing easyconfigs by walking paths with installed easyconfig files for path in easyconfigs_pkg_full_paths: _log.debug("Looking for missing easyconfig files (%d left) in %s..." % (len(ecs_to_find), path)) for (subpath, dirnames, filenames) in os.walk(path, topdown=True): for idx, orig_path in ecs_to_find[:]: if orig_path in filenames: full_path = os.path.join(subpath, orig_path) _log.info("Found %s in %s: %s" % (orig_path, path, full_path)) orig_paths[idx] = full_path # if file was found, stop looking for it (first hit wins) ecs_to_find.remove((idx, orig_path)) # stop os.walk insanity as soon as we have all we need (os.walk loop) if len(ecs_to_find) == 0: break # ignore subdirs specified to be ignored by replacing items in dirnames list used by os.walk dirnames[:] = [d for d in dirnames if not d in options.ignore_dirs] # stop os.walk insanity as soon as we have all we need (paths loop) if len(ecs_to_find) == 0: break # indicate that specified paths do not contain generated easyconfig files paths = [(path, False) for path in orig_paths] _log.debug("Paths: %s" % paths) # run regtest if options.regtest or options.aggregate_regtest: _log.info("Running regression test") if paths: ec_paths = [path[0] for path in paths] else: # fallback: easybuild-easyconfigs install path ec_paths = easyconfigs_pkg_full_paths regtest_ok = regtest(ec_paths, build_options=build_options, build_specs=build_specs) if not regtest_ok: _log.info("Regression test failed (partially)!") sys.exit(31) # exit -> 3x1t -> 31 # read easyconfig files easyconfigs = [] for (path, generated) in paths: path = os.path.abspath(path) if not os.path.exists(path): print_error("Can't find path %s" % path) try: files = find_easyconfigs(path, ignore_dirs=options.ignore_dirs) for f in files: if not generated and try_to_generate and build_specs: ec_file = tweak(f, None, build_specs) else: ec_file = f ecs = process_easyconfig(ec_file, build_options=build_options, build_specs=build_specs) easyconfigs.extend(ecs) except IOError, err: _log.error("Processing easyconfigs in path %s failed: %s" % (path, err))