def InitializeNewGitRepo(sim_name): Print.new_step("Initialize new git repository") sp.check_output(["git", "init"], cwd=sim_name) # check if user name and email are set try: out = sp.check_output(["git", "config", "user.name"], cwd=sim_name).decode("utf-8") except sp.CalledProcessError as err: # User name not set print("Your git user name is not set.") response = input("Please enter your name (e.g. Mona Lisa): ") out = sp.check_output(["git", "config", "user.name", response], cwd=sim_name) try: out = sp.check_output(["git", "config", "user.email"], cwd=sim_name).decode("utf-8") except sp.CalledProcessError as err: # User name not set print("Your git user e-mail is not set.") response = input( "Please enter your e-mail address that you have used to sign-up for github: " ) out = sp.check_output(["git", "config", "user.email", response], cwd=sim_name) sp.check_output(["git", "add", "."], cwd=sim_name) sp.check_output(["git", "commit", "-m", "\"Initial commit\""], cwd=sim_name)
def CustomizeFiles(sim_name): Print.new_step("Customize files") try: # README.md ModifyFileContent(sim_name + "/README.md", lambda content: "# " + sim_name + "\n") # CMakelists.txt ModifyFileContent( sim_name + "/CMakeLists.txt", lambda content: content.replace("my-simulation", sim_name)) # source files include_guard = sim_name.upper().replace("-", "_") + "_H_" ModifyFileContent( sim_name + "/src/my-simulation.h", lambda c: c.replace("MY_SIMULATION_H_", include_guard)) ModifyFileContent(sim_name + "/src/my-simulation.cc", lambda c: c.replace("my-simulation", sim_name)) # rename os.rename(sim_name + "/src/my-simulation.h", sim_name + "/src/" + sim_name + ".h") os.rename(sim_name + "/src/my-simulation.cc", sim_name + "/src/" + sim_name + ".cc") except: Print.error("Error: File customizations failed") CleanupOnError(sim_name)
def DemoCommand(demo_name, destination=None): if not demo_name: print("Usage: biodynamo demo <demo name> [target directory]") print("Known demos:\n {}".format("\n ".join(KNOWN_DEMOS))) return if demo_name not in KNOWN_DEMOS: Print.error("Demo name \"{}\" is not known.".format(demo_name)) print("Known demos:\n {}".format("\n ".join(KNOWN_DEMOS))) sys.exit(1) if destination is None: destination = "." if os.path.exists(destination): destination = os.path.join(destination, demo_name) if os.path.exists(destination): Print.error("Destination directory \"{}\" exists.".format(destination)) Print.error( "Please remove it or create the demo in a different place.") Print.error("Abort \"biodynamo demo {}\".".format(demo_name)) sys.exit(2) src_dir = os.path.join(DEMO_DIR, demo_name) print("Copying files from \"{}\" to \"{}\"...".format( src_dir, destination)) shutil.copytree(src_dir, destination) CopySupportFiles(destination) InitializeNewGitRepo(destination) Print.success("The demo \"{}\" has been created in \"{}\".".format( demo_name, destination))
def CopySupportFiles(sim_name): SUPPORT_DIR = os.path.join(os.environ['BDM_INSTALL_DIR'], 'share', 'util', 'support_files') Print.new_step("Copy additional support files") for filename in os.listdir(SUPPORT_DIR): full_file_name = os.path.join(SUPPORT_DIR, filename) if os.path.isfile(full_file_name): shutil.copy(full_file_name, sim_name)
def CopySupportFiles(sim_name): SUPPORT_DIR = os.path.join(os.environ["BDMSYS"], "share", "util", "support_files") Print.new_step("Copy additional support files") for filename in os.listdir(SUPPORT_DIR): full_file_name = os.path.join(SUPPORT_DIR, filename) if os.path.isfile(full_file_name): shutil.copy(full_file_name, sim_name)
def GenerateDebugOutput(sim_name): Print.new_step("Generate debug output") # generates cmake_output.log and / or make_output.log (depends if cmake # ran sucessfully or not) if BuildCommand(debug=True): # generates runtime_output.log RunCommand(debug=True) # generates root dictionary log(s) CopyRootDictionaries() # generates system_info.log GenerateSystemInfoLog()
def CopyTemplate(sim_name): Print.new_step("Copy simulation template") try: src_path = "{0}/simulation-template".format(os.environ['BDMSYS']) sp.check_output(["cp", "-R", src_path, "./{0}".format(sim_name)]) except sp.CalledProcessError as err: Print.error("Error while copying the template project.") # Do not use CleanupOnError here # One failure could be an already existing directory # we must not remove it sys.exit(1)
def DownloadTemplateRepository(sim_name): Print.new_step("Download template repository") try: sp.check_output([ "git", "clone", "https://github.com/BioDynaMo/simulation-templates.git", sim_name ]) sp.check_output(["rm", "-rf", sim_name + "/.git"]) except sp.CalledProcessError as err: Print.error( "Error while downloading the template project from BioDynaMo") # Do not use CleanupOnError here # One failure could be an already existing directory # we must not remove it sys.exit(1)
def NewCommand(sim_name, no_github): print("Info: This command requires a Github.com account.") print(" Please have your account details ready, or ") print(" go over to https://github.com/join to sign up.") ValidateSimName(sim_name) DownloadTemplateRepository(sim_name) CustomizeFiles(sim_name) InitializeNewGitRepo(sim_name) if (not no_github): CreateNewGithubRepository(sim_name) Print.success(sim_name + " has been created successfully!") print( 'To compile and run this simulation, change the directory by calling ' '"cd %s"' % (sim_name))
def DemoCommand(demo_name, destination=None): if not demo_name: print('Usage: biodynamo demo <demo name> [target directory]') print('Known demos:\n {}'.format('\n '.join(KNOWN_DEMOS))) return if demo_name not in KNOWN_DEMOS: Print.error('Demo name "{}" is not known.'.format(demo_name)) print('Known demos:\n {}'.format('\n '.join(KNOWN_DEMOS))) sys.exit(1) if destination is None: destination = '.' if os.path.exists(destination): destination = os.path.join(destination, demo_name) if os.path.exists(destination): Print.error('Destination directory "{}" exists.'.format(destination)) sys.exit(2) src_dir = os.path.join(DEMO_DIR, demo_name) print('Copying files from "{}" to "{}"...'.format(src_dir, destination)) shutil.copytree(src_dir, destination) CopySupportFiles(destination) InitializeNewGitRepo(destination) Print.success('The demo "{}" has been created in "{}".'.format( demo_name, destination))
def ValidateSimName(sim_name): pattern = re.compile("^[a-zA-Z]+[a-zA-Z0-9\-_]+$") if not pattern.match(sim_name): Print.error("Error: simulation name '{0}' is not valid.".format(sim_name)) Print.error(" Allowed characters are a-z A-Z 0-9 - and _") Print.error(" Must start with a-z or A-Z") sys.exit(1)
def CreateDebugBranch(sim_name): Print.new_step("Create debug branch") original_branch = sp.check_output( ["git", "rev-parse", "--abbrev-ref", "HEAD"]).decode('ascii').split("\n")[0] branch_name = "bdm-assist-" + time.strftime("%Y%m%d_%H%M") sp.check_output(["git", "checkout", "-b", branch_name]) sp.check_output(["git", "add", "debug"]) sp.check_output(["git", "commit", "-m", '"Add debug information"']) sp.check_output(["git", "push", "origin", branch_name]) remote_url = sp.check_output( ["git", "remote", "get-url", "origin"]).decode('ascii').split("\n")[0] branch_url = remote_url[:-4] + "/tree/" + branch_name print("An assistance branch has been created, called '%s'" % (branch_name)) print( "Send the following URL to the developers when requesting assistance:") print("") print(branch_url) print("Switching back to the previous branch...") sp.check_output(["git", "checkout", original_branch])
def GenerateSystemInfoLog(): Print.new_step("Generate system info log") try: sfile = open('debug/system_info.log', 'w+') except sp.CalledProcessError as err: print("Error: could not create system_info.log in directory 'debug'") sys.exit(1) my_os = platform.system() distro, version = "", "" architecture = platform.architecture() if my_os == "Linux": distro = platform.linux_distribution()[0] my_os = my_os + " " + distro + " " + platform.linux_distribution()[1] elif my_os == "Darwin": version = platform.mac_ver()[0] cmake_version = sp.check_output(["cmake", "--version"]).decode('ascii') cmake_version = cmake_version.split("\n")[0].split(" ")[-1].strip() # root_info = sp.check_output( # ["cat", "$ROOTSYS/include/RVersion.h", "|", "grep", "'ROOT_RELEASE '"]) # root_version = root_info.split('"')[1::2][0] sfile.write("%-20s %10s\n" % ("Platform:", my_os)) sfile.write("%-20s %10s\n" % ("Architecture:", architecture)) sfile.write("") # sfile.write("%-20s %10s" % ("BioDynaMo version:", bdm_version)) sfile.write("%-20s %10s\n" % ("CMake version:", cmake_version)) # sfile.write("%-20s %10s" % ("ROOT version:", root_version)) # sfile.write("%-20s %10s" % ("ParaView version:", paraview_version)) sfile.close()
def CreateNewGithubRepository(sim_name): Print.new_step("Create Github repository") gh_user = input("Please enter your Github username: "******"Please enter your Github password: "******"name": sim_name, "description": "Simulation powered by BioDynaMo" } headers = {'Content-Type': 'application/json'} bytes = json.dumps(data).encode('utf-8') url = "https://api.github.com/user/repos" request = urllib.request.Request(url, data=bytes, headers=headers) credentials = ('%s:%s' % (gh_user, gh_pass)) encoded_credentials = base64.b64encode(credentials.encode('ascii')) request.add_header('Authorization', 'Basic %s' % encoded_credentials.decode("ascii")) result = urllib.request.urlopen(request) except urllib.error.HTTPError as err: Print.error("Github repository creation failed.") Print.error(err) CleanupOnError(sim_name) # Connect github repository with local try: repo_url = "https://github.com/" + gh_user + "/" + sim_name + ".git" sp.check_output(["git", "remote", "add", "origin", repo_url], cwd=sim_name) except sp.CalledProcessError as err: Print.error( "Error: Setting remote github url ({0}) failed.".format(repo_url)) CleanupOnError(sim_name)
def UncommittedFiles(): staged_files, unstaged_files = 0, 0 untracked_files = "" Print.new_step("Check for uncommited files") try: sp.check_output(["git", "diff", "--cached", "--quiet"]) except sp.CalledProcessError as err: staged_files = err.returncode try: sp.check_output(["git", "diff", "--quiet"]) except sp.CalledProcessError as err: unstaged_files = err.returncode if not staged_files or not unstaged_files: try: untracked_files = sp.check_output( ["git", "ls-files", "--exclude-standard", "--others"]).decode('ascii') except sp.CalledProcessError as err: Print.warning( "Could not perform check on untracked files. Continuing anyway..." ) pass if staged_files or unstaged_files: if staged_files: print("You have staged files that need to be committed") if unstaged_files: print("You have unstaged files that need to be commited") print("") Print.warning( "Rerun biodynamo assistance once you have resolved these issues") return 1 if untracked_files != "": sp.call(["git", "status"]) return not query_yes_no( "You have untracked files. Are you sure they can be ignored?") return 0
def RunCommand(args, debug=False): sim_name = GetBinaryName() args_str = ' '.join(args) cmd = "./build/" + sim_name try: BuildCommand() Print.new_step("Run " + sim_name + ' ' + args_str) if debug: sp.check_output([cmd, "&>", "debug/runtime_output.log"]) else: print( sp.check_output([cmd, args_str], stderr=sp.STDOUT).decode('utf-8')) Print.success("Finished successfully") except sp.CalledProcessError as err: print(err.output.decode("utf-8")) Print.error("Error during execution of {0}".format(cmd))
def RunCommand(args, debug=False): sim_name = GetBinaryName() args_str = " ".join(args) cmd = "./build/" + sim_name if platform.system() == "Darwin": launcher = os.environ["BDMSYS"] + "/bin/launcher.sh" else: launcher = "" try: BuildCommand() Print.new_step("Run " + sim_name + " " + args_str) if debug: sp.check_output( [launcher + " " + cmd, "&>", "debug/runtime_output.log"]) else: print( sp.check_output([launcher + " " + cmd, args_str], stderr=sp.STDOUT, shell=True).decode("utf-8")) Print.success("Finished successfully") except sp.CalledProcessError as err: print(err.output.decode("utf-8")) Print.error("Error during execution of {0}".format(cmd))
def CleanupOnError(sim_name): try: sp.check_output(["rm", "-rf", sim_name]) except: Print.error("Error: Failed to remove folder {0}".format(sim_name)) sys.exit(1)
def ValidateSimName(sim_name): pattern = re.compile("^[a-zA-Z]+[a-zA-Z0-9\-_]+$") if not pattern.match(sim_name): Print.error( "Error: simulation name \"{}\" is not valid.".format(sim_name)) Print.error(" Allowed characters are a-z A-Z 0-9 - and _") Print.error(" Must start with a-z or A-Z") sys.exit(1) if os.path.isdir(sim_name): Print.error("The directory \"{}\" already exists.".format(sim_name)) Print.error("Please remove it or choose a different name.") Print.error("Abort \"biodynamo new {}\".".format(sim_name)) sys.exit(1)
def BuildCommand(clean=False, debug=False, build=True): build_dir = "build" debug_dir = "debug" Print.new_step("Build") if clean or debug: Print.new_step("Clean build directory") sp.check_output(["rm", "-rf", build_dir]) sp.check_output(["mkdir", build_dir]) else: if not os.path.exists(build_dir): sp.check_output(["mkdir", build_dir]) if debug: if not os.path.exists(debug_dir): sp.check_output(["mkdir", debug_dir]) with open(debug_dir + '/cmake_output.log', "w") as file: try: sp.check_call( ["cmake", "-B./" + build_dir, "-H."], stdout=file, stderr=file) except sp.CalledProcessError as err: Print.error( "Failed to run CMake. Generating debug/cmake_output.log..." ) return with open(debug_dir + '/make_output.log', "w") as file: try: sp.check_call( ["make", "-C", build_dir], stdout=file, stderr=file) except sp.CalledProcessError as err: Print.error( "Compilation failed. Generating debug/make_output.log..." ) return elif build: # if CMakeCache.txt does not exist, run cmake if not Path(build_dir + "/CMakeCache.txt").is_file(): try: sp.check_output(["cmake", "-B./" + build_dir, "-H."]) except sp.CalledProcessError as err: Print.error("Failed to run CMake. Check the debug output above.") sys.exit(1) try: sp.check_output(["make", "-j4", "-C", build_dir]) except: Print.error("Compilation failed. Check the debug output above.") sys.exit(1)