def main(): global remove_files global executable_files global verbose_mode global remove_extensions global src_extensions global lib_extensions global modules global extras list_modules = False list_extra = False binary_keep = False src_strip = False extra_strip = False aparser = argparse.ArgumentParser(description="Weenix repository generator from support code") aparser.add_argument("--list-modules", action="store_true", help="list available Weenix modules") aparser.add_argument("--list-extra", action="store_true", help="list available extra Weenix features") aparser.add_argument("--verbose", action="store_true", help="enable verbose output mode") aparser.add_argument("--binary", type=str, metavar="module_list", help="enable binary keeping for Weenix modules") aparser.add_argument("--cutsource", type=str, metavar="module_list", help="enable source stripping for Weenix modules") aparser.add_argument("--cutextra", type=str, metavar="extra_list", help="enable source stripping for extra Weenix features") if len(sys.argv) < 2: aparser.print_help() sys.exit(1) args = vars(aparser.parse_args()) if args["verbose"]: verbose_mode = True setVerbose(True) if args["list_modules"]: list_modules = True if args["list_extra"]: list_extra = True if args["binary"]: binary_keep = True if args["binary"] == "all": binary_list = set(modules.keys()) else: binary_list = set(args["binary"].split(",")) if args["cutsource"]: src_strip = True if args["cutsource"] == "all": src_list = set(modules.keys()) else: src_list = set(args["cutsource"].split(",")) if args["cutextra"]: extra_strip = True if args["cutextra"] == "all": extra_list = set(extras.keys()) else: extra_list = set(args["cutextra"].split(",")) root_dir = findRoot(".") os.umask(0007) os.chdir(root_dir) # List modules if list_modules or list_extra: if binary_keep or src_strip: sys.stderr.write("ERROR: Listing, binary-keeping, and source-stripping are mutually-exclusive operations.\n") sys.exit(1) if list_modules: listModules("Modules: ", modules.keys()) if list_extra: listModules("Extras: ", extras.keys()) sys.exit() elif not binary_keep and not src_strip: sys.stderr.write("ERROR: Please define operation: module-listing, binary-keeping or source-stripping.\n") sys.exit(1) dbgPrint("Generating student tree...\n") # Make sure we are only working with supported modules if src_strip: diff = src_list - set(modules.keys()) if len(diff) > 0: sys.stderr.write("ERROR: The following modules are not supported: %s\n" % str(diff)) sys.exit(1) # Make sure we are only working with supported extras if extra_strip: diff = extra_list - set(extras.keys()) if len(diff) > 0: sys.stderr.write("ERROR: The following extras are not supported: %s\n" % str(diff)) sys.exit(1) # Make sure we are only working with supported modules if binary_keep: diff = binary_list - set(modules.keys()) if len(diff) > 0: sys.stderr.write("ERROR: The following modules are not supported: %s\n" % str(diff)) sys.exit(1) # Finally make sure we are not applying multiple operations to the # same module if (binary_keep and src_strip) and len(set(binary_list).intersection(src_list)) > 0: sys.stderr.write("ERROR: We can't apply multiple operations to the same modules\n") sys.exit(1) # Compile code first to make sure that there are no errors. Also # needed for keeping binaries dbgPrint("Compiling code...\n") # If you don't use redo, substitute the following clode block subprocess.call(["make", "-j", "8"]) dbgPrint("Removing .git if it exists...\n") try: shutil.rmtree(os.path.join(root_dir, ".git")) except OSError: pass dbgPrint("Removing staff-only files...\n") for rfile in remove_files: path = os.path.join(root_dir, rfile) if (os.path.isdir(path)): dbgPrint("\tRemoving %s\n" % path, dbg_msg.DEBUG) shutil.rmtree(path) else: dbgPrint("\tRemoving %s\n" % path, dbg_msg.DEBUG) os.remove(path) dbgPrint("Creating student weenix git repository...\n") subprocess.call(["git", "init"]) if src_strip: diff = set(modules.keys()) - src_list # Remove support code and produce stencil for students dbgPrint("Generating stencil code for modules %s...\n" % args["cutsource"]) module_dirs = [] for m in src_list: if m in modules.keys(): module_dirs.extend([os.path.join(kernel_dir_prefix, m) for m in modules[m]["dirs"]["src"]]) srcCutdir(root_dir, module_dirs, diff.union(extras.keys())) if len(diff) > 0: dbgPrint("The following modules were left intact: %s\n" % (", ".join(m for m in diff)), dbg_msg.WARNING) if extra_strip: diff = set(extras.keys()) - extra_list # Remove support code and produce stencil for students dbgPrint("Generating stencil code for extras %s...\n" % args["cutextra"]) extras_dirs = [] for m in extra_list: if m in extras.keys(): extras_dirs.extend([os.path.join(kernel_dir_prefix, e) for e in extras[m]["dirs"]]) srcCutdir(root_dir, extras_dirs, diff.union(modules.keys())) if len(diff) > 0: dbgPrint("The following extras were left intact: %s\n" % (", ".join(m for m in diff)), dbg_msg.WARNING) if binary_keep: # Do not include library source code for non-lab students dbgPrint("Ignoring source from modules %s...\n" % args["binary"]) module_dirs = [] module_names = [] for m in binary_list: if m in modules.keys(): module_dirs.extend(modules[m]["dirs"]["lib"]) module_names.extend(modules[m]["names"]) binKeepdir(root_dir, os.path.join(root_dir, kernel_dir_prefix), module_dirs, module_names, lib_extensions) diff = set(modules.keys()) - binary_list if len(diff) > 0: dbgPrint("The following modules were left intact: %s\n" % (", ".join(m for m in diff)), dbg_msg.WARNING) dbgPrint("Setting correct file/dir permissions...\n") os.chmod(root_dir, 0770) for root, dirs, files, in os.walk(root_dir): for file in files: dbgPrint("\tSetting %s permissions to 0664\n" %(os.path.join(root, file)), dbg_msg.DEBUG) os.chmod(os.path.join(root, file), 0664) for dir in dirs: dbgPrint("\tSetting %s permissions to 0775\n" %(os.path.join(root, dir)), dbg_msg.DEBUG) os.chmod(os.path.join(root, dir), 0775 | stat.S_ISGID) dbgPrint("Setting executable files...\n") for efile in executable_files: path = os.path.join(root_dir, efile) dbgPrint("\tMaking %s executable\n" % path, dbg_msg.DEBUG) os.chmod(path, 0775) subprocess.call(["git", "add", "."]) subprocess.call(["git", "commit", "-m", "Created student weenix repository"]) dbgPrint("DONE.\n")
def main(): global remove_files global executable_files global verbose_mode global remove_extensions global src_extensions global lib_extensions global modules global extras list_modules = False list_extra = False binary_keep = False src_strip = False extra_strip = False aparser = argparse.ArgumentParser(description="Weenix repository generator from TA code") aparser.add_argument("--list-modules", action="store_true", help="list available Weenix modules") aparser.add_argument("--list-extra", action="store_true", help="list available extra Weenix features") aparser.add_argument("--verbose", action="store_true", help="enable verbose output mode") aparser.add_argument("--binary", type=str, metavar="module_list", help="enable binary keeping for Weenix modules") aparser.add_argument("--cutsource", type=str, metavar="module_list", help="enable source stripping for Weenix modules") aparser.add_argument("--cutextra", type=str, metavar="extra_list", help="enable source stripping for extra Weenix features") if len(sys.argv) < 2: aparser.print_help() sys.exit(1) args = vars(aparser.parse_args()) if args["verbose"]: verbose_mode = True setVerbose(True) if args["list_modules"]: list_modules = True if args["list_extra"]: list_extra = True if args["binary"]: binary_keep = True if args["binary"] == "all": binary_list = set(modules.keys()) else: binary_list = set(args["binary"].split(",")) if args["cutsource"]: src_strip = True if args["cutsource"] == "all": src_list = set(modules.keys()) else: src_list = set(args["cutsource"].split(",")) if args["cutextra"]: extra_strip = True if args["cutextra"] == "all": extra_list = set(extras.keys()) else: extra_list = set(args["cutextra"].split(",")) root_dir = findRoot(".") os.umask(0007) os.chdir(root_dir) # List modules if list_modules or list_extra: if binary_keep or src_strip: sys.stderr.write("ERROR: Listing, binary-keeping, and source-stripping are mutually-exclusive operations.\n") sys.exit(1) if list_modules: listModules("Modules: ", modules.keys()) if list_extra: listModules("Extras: ", extras.keys()) sys.exit() elif not binary_keep and not src_strip: sys.stderr.write("ERROR: Please define operation: module-listing, binary-keeping or source-stripping.\n") sys.exit(1) dbgPrint("Generating student tree...\n") # Make sure we are only working with supported modules if src_strip: diff = src_list - set(modules.keys()) if len(diff) > 0: sys.stderr.write("ERROR: The following modules are not supported: %s\n" % str(diff)) sys.exit(1) # Make sure we are only working with supported extras if extra_strip: diff = extra_list - set(extras.keys()) if len(diff) > 0: sys.stderr.write("ERROR: The following extras are not supported: %s\n" % str(diff)) sys.exit(1) # Make sure we are only working with supported modules if binary_keep: diff = binary_list - set(modules.keys()) if len(diff) > 0: sys.stderr.write("ERROR: The following modules are not supported: %s\n" % str(diff)) sys.exit(1) # Finally make sure we are not applying multiple operations to the # same module if (binary_keep and src_strip) and len(set(binary_list).intersection(src_list)) > 0: sys.stderr.write("ERROR: We can't apply multiple operations to the same modules\n") sys.exit(1) # Compile code first to make sure that there are no errors. Also # needed for keeping binaries dbgPrint("Compiling code...\n") # If you don't use redo, substitute the following clode block subprocess.call([os.path.join(root_dir, "tools/setup")]) subprocess.call(["redo", "-j", "8"]) dbgPrint("Removing .git...\n") shutil.rmtree(os.path.join(root_dir, ".git")) dbgPrint("Removing TA-only files...\n") for rfile in remove_files: path = os.path.join(root_dir, rfile) if (os.path.isdir(path)): dbgPrint("\tRemoving %s\n" % path, dbg_msg.DEBUG) shutil.rmtree(path) else: dbgPrint("\tRemoving %s\n" % path, dbg_msg.DEBUG) os.remove(path) dbgPrint("Creating student weenix git repository...\n") subprocess.call(["git", "init"]) if src_strip: diff = set(modules.keys()) - src_list # Remove TA code and produce stencil for students dbgPrint("Generating stencil code for modules %s...\n" % args["cutsource"]) modules_dirs = [] for m in src_list: if m in modules.keys(): modules_dirs.extend(modules[m]["dirs"]["src"]) srcCutdir(root_dir, modules_dirs, diff.union(extras.keys())) if len(diff) > 0: dbgPrint("The following modules were left intact: %s\n" % (", ".join(m for m in diff)), dbg_msg.WARNING) if extra_strip: diff = set(extras.keys()) - extra_list # Remove TA code and produce stencil for students dbgPrint("Generating stencil code for extras %s...\n" % args["cutextra"]) extras_dirs = [] for m in extra_list: if m in extras.keys(): extras_dirs.extend(extras[m]["dirs"]) srcCutdir(root_dir, extras_dirs, diff.union(modules.keys())) if len(diff) > 0: dbgPrint("The following extras were left intact: %s\n" % (", ".join(m for m in diff)), dbg_msg.WARNING) if binary_keep: # Do not include library source code for non-lab students dbgPrint("Ignoring source from modules %s...\n" % args["binary"]) modules_dirs = [] for m in binary_list: if m in modules.keys(): modules_dirs.extend(modules[m]["dirs"]["lib"]) binKeepdir(root_dir, modules_dirs, lib_extensions) diff = set(modules.keys()) - binary_list if len(diff) > 0: dbgPrint("The following modules were left intact: %s\n" % (", ".join(m for m in diff)), dbg_msg.WARNING) # For those modules that only have binaries available, let's modify # redo rules, so that the .a files are not deleted when 'redo clean' is # called from the new repository if binary_keep: dbgPrint("Modifying redo files...\n") with open(os.path.join(root_dir, "kernel/Kernel.sh"), "r") as fin: lines = fin.readlines() # A line starting with CLEAN_MODULES= defines the list of # subdirectories available in kernel. Let's remove those who # have a binary-only file, so that it is not deleted. for n, line in enumerate(lines): match = re.match(r"\ACLEAN_MODULES=.*", line) if match: for m in binary_list: # I hate doing this, but it's necessary if m == "VFS" or m == "S5FS": m = "fs" line = re.sub(r"\s%s\s" % m.lower(), " ", line) lines[n] = line break with open(os.path.join(root_dir, "kernel/Kernel.sh"), "w") as fin: fin.writelines(lines) # Clean compile-created files. This is a necessary step to create a # working repo. If not, things won't compile next again (blame redo # for this). If you don't use redo, erase the code block below dbgPrint("Cleaning object files...\n") subprocess.call(["redo", "clean"]) dbgPrint("Setting correct file/dir permissions...\n") os.chmod(root_dir, 0770) for root, dirs, files, in os.walk(root_dir): for file in files: dbgPrint("\tSetting %s permissions to 0664\n" %(os.path.join(root, file)), dbg_msg.DEBUG) os.chmod(os.path.join(root, file), 0664) for dir in dirs: dbgPrint("\tSetting %s permissions to 0775\n" %(os.path.join(root, dir)), dbg_msg.DEBUG) os.chmod(os.path.join(root, dir), 0775 | stat.S_ISGID) dbgPrint("Setting executable files...\n") for efile in executable_files: path = os.path.join(root_dir, efile) dbgPrint("\tMaking %s executable\n" % path, dbg_msg.DEBUG) os.chmod(path, 0775) subprocess.call(["git", "add", "."]) subprocess.call(["git", "commit", "-m", "Created student weenix repository"]) dbgPrint("DONE.\n")