def show_my_commits(self, show_sha, since_days): list_of_repos = self.config.getlist('git_repo', 'repo') for repo in list_of_repos: current_repo_path = self.path_to_workspace + os.sep + repo if os.path.exists(current_repo_path): if since_days is None: commit_since_days = self.config.getint( 'git_repo', 'commit_since_days') else: commit_since_days = int(since_days) since_date = datetime.now() - timedelta(days=commit_since_days) show_commit = '' if not show_sha: show_commit = '\|commit ' cmd_commits = 'cd ' + current_repo_path + ';git log --author="$(git config user.name)" --since "{0} {1} {2}"|grep -v "Author:\|Date:{3}"'.\ format(since_date.strftime("%B"), since_date.day, since_date.year, show_commit) commits_output = EnvironmentBuilder.handle_command( cmd_commits, False, True, self.print_cmd_output, self.print_cmd) p_status, output, err = commits_output if p_status == 0 and not (output.rstrip('\n').isspace()): output = os.linesep.join( ['\t' + s.strip() for s in output.splitlines() if s]) ColorPrint.blue_highlight( "Commits for repository [{0}]".format(repo.upper())) ColorPrint.info(output) unpushed_commits = self.get_unpushed_commits(current_repo_path) if unpushed_commits and not unpushed_commits.rstrip( '\n').isspace(): ColorPrint.err("\tUnpushed commits!!!") ColorPrint.warn(unpushed_commits)
def print_list_avalable_versions(): base_dir = SncConfig().getstring('git_repo', 'base_dir') ColorPrint.blue_highlight("***** Avalable versions ****:") for dir in os.listdir(base_dir): if os.path.isdir(base_dir + os.sep + dir) and not dir.startswith('.'): if EnvironmentBuilder.is_release_direcrory(dir): ColorPrint.info('[' + dir + ']')
def run_git_unstash(self, repo_path): if os.path.exists(repo_path): ColorPrint.blue_highlight( "Unstashing the repository [{0}]".format(repo_path)) self.handle_command('cd {0};git stash pop'.format(repo_path)) else: ColorPrint.warn( "The repository path [{0}] is not available".format(repo_path))
def run_git_stash(self, repo_path): if os.path.exists(repo_path): ColorPrint.blue_highlight( "Stashing the repository [{0}]".format(repo_path)) self.run_command_and_collect_errors( 'cd {0};git stash'.format(repo_path)) else: ColorPrint.warn( "The repository path [{0}] is not available".format(repo_path))
def copy_local_env(self, new_release_name): path_to_new_release = self.base_dir + os.sep + new_release_name copy_cmdb = 'cp -rp ' + self.path_to_workspace + ' ' + path_to_new_release ColorPrint.blue_highlight("Copying environment [{0}] to [{1}] ".format( self.release, new_release_name)) if os.path.exists(self.path_to_workspace): self.run_command_and_collect_errors(copy_cmdb) else: ColorPrint.err("Can't copy due to invalid path: [{0}] ".format( self.path_to_workspace))
def _git_custom(self, git_command, repo): ColorPrint.blue_highlight( "Running custom git command on repository [{0}]".format(repo)) repo_path = self.path_to_workspace + os.sep + repo if os.path.exists(repo_path): self.run_command_and_collect_errors('cd {0};git {1}'.format( repo_path, git_command)) else: ColorPrint.warn( "The repository path [{0}] is not available".format(repo))
def mvn_build(self): project_per_repo = self.config.getsection('projects') for repo_name, projects in project_per_repo: ColorPrint.blue_highlight( "Starting mvn install for repository {0}".format(repo_name)) for project_name in projects.split(','): project_path = self.path_to_workspace + os.sep + repo_name + os.sep + project_name java_env = 'source ~/.bash_profile' cmd = java_env + ';cd {0};mvn clean install -DskipTests'.format( project_path) self.handle_command(cmd)
def print_execution_error_summary(self): if not os.path.exists("errors.txt"): exit(0) with open('errors.txt', 'r') as error_file: all_errors = error_file.read() if all_errors: ColorPrint.blue_highlight("Fix the following errors and run again") ColorPrint.err('\n' + all_errors) else: ColorPrint.blue_highlight("Execution complited without errors")
def import_projects(self): project_per_repo = self.config.getsection('projects') for repo_name, projects in project_per_repo: ColorPrint.blue_highlight( "Importing {0} repository projects".format(repo_name)) for project_name in projects.split(','): project_path = self.path_to_workspace + os.sep + repo_name + os.sep + project_name if os.path.exists(project_path): java_env = 'source ~/.bash_profile' cmd = java_env + ';{2} -nosplash -data "{0}" -application org.eclipse.cdt.managedbuilder.core.headlessbuild -import {1}'.format( self.path_to_workspace, project_path, self.eclipse) self.handle_command(cmd)
def _is_branch_up_to_date(self, repo_path): ColorPrint.blue_highlight( "Checking repository status [{0}]".format(repo_path)) self.handle_command('cd {0};git remote update'.format(repo_path)) if self._is_ready_to_pull(repo_path): return True else: repo = os.path.basename(os.path.normpath(repo_path)) if repo in self.repo_status and self.repo_status[repo]: return True else: return False
def run_git_pull(self): now = time.time() list_of_repos = self.config.getlist('git_repo', 'repo') if (self.parallel_run): pool = Pool(len(list_of_repos)) pool.map(self._git_pull, list_of_repos) else: for repo in list_of_repos: self._git_pull(repo) later = time.time() difference = int(later - now) ColorPrint.blue_highlight( "Pull operation for release [{0}] took [{1}] seconds".format( self.release, difference))
def switch_track(self, track_name): now = time.time() list_of_repos = self.config.getlist('git_repo', 'repo') if (self.parallel_run): pool = Pool(len(list_of_repos)) pool.map(self._switch_repo, zip(list_of_repos, repeat(track_name))) else: for repo in list_of_repos: self._switch_repo([repo, track_name]) later = time.time() difference = int(later - now) ColorPrint.blue_highlight( "Switch operation for release [{0}] took [{1}] seconds".format( self.release, difference))
def _is_ready_to_pull(self, repo_path): ColorPrint.blue_highlight( "Checking repository status [{0}]".format(repo_path)) p_status, cmd_out, err = self.handle_command( 'cd {0};git status -uno'.format(repo_path), True, True) ColorPrint.info(cmd_out) repo = os.path.basename(os.path.normpath(repo_path)) if 'Your branch is up-to-date' in str(cmd_out): self.repo_status[repo] = True else: self.repo_status[repo] = False if 'nothing to commit' in str(cmd_out): return True else: return False
def _switch_repo(self, args): repo, track_name = args ColorPrint.blue_highlight( "Trying to switch the repository to [{0}]".format(track_name)) if os.path.exists(self.path_to_workspace + os.sep + repo): p_status, out, err = self.handle_command( 'cd {0};git rev-parse --abbrev-ref HEAD'.format( self.path_to_workspace + os.sep + repo)) if out == track_name: ColorPrint.warn( "The current repository already switched to [{0}], skipping" .format(track_name)) else: self.handle_command( 'cd {0};git fetch && git checkout {1}'.format( self.path_to_workspace + os.sep + repo, track_name))
def print_list_avalable_versions(current_release): base_dir = SncConfig().getstring('git_repo', 'base_dir') if current_release is not None: ColorPrint.blue_highlight('================' + current_release.upper() + '================') EnvironmentBuilder.print_release_branch_per_repository( current_release) exit(0) for dir in os.listdir(base_dir): if os.path.isdir(base_dir + os.sep + dir) and not dir.startswith('.'): if EnvironmentBuilder.is_release_direcrory(dir): ColorPrint.blue_highlight('================' + dir.upper() + '================') EnvironmentBuilder.print_release_branch_per_repository(dir)
def mvn_clean(self): if not os.path.exists(self.path_to_workspace): ColorPrint.err("Invalid release name: [{0}]".format(self.release)) exit(1) project_per_repo = self.config.getsection('projects') for repo_name, projects in project_per_repo: ColorPrint.blue_highlight( "Starting mvn clean for repository {0}".format(repo_name)) for project_name in projects.split(','): project_path = self.path_to_workspace + os.sep + repo_name + os.sep + project_name java_env = 'source ~/.bash_profile' cmd = java_env + ';cd {0};mvn clean'.format(project_path) self.run_command_and_collect_errors(cmd) log_message = "Maven clean operation for release completed".format( self.release) ColorPrint.blue_highlight(log_message) self.notif_mgr.send_notification(True, 'Maven Clean', log_message)
def clone_env(self, user, password): now = time.time() if not os.path.exists(self.path_to_workspace): os.makedirs(self.path_to_workspace) list_of_repos = self.config.getlist('git_repo', 'repo') if (self.parallel_run): pool = Pool(len(list_of_repos)) pool.map(self._clone_env, zip(list_of_repos, repeat(user), repeat(password))) else: for repo in list_of_repos: self._clone_env([repo, user, password]) later = time.time() difference = int(later - now) ColorPrint.blue_highlight( "Clone operation for release [{0}] took [{1}] seconds".format( self.release, difference))
def clone_env(self): now = time.time() if not os.path.exists(self.path_to_workspace): os.makedirs(self.path_to_workspace) list_of_repos = self.config.getlist('git_repo', 'repo') if self.parallel_run: pool = Pool(len(list_of_repos)) pool.map(self._clone_env, list_of_repos) else: for repo in list_of_repos: self._clone_env(repo) later = time.time() difference = int(later - now) log_message = "Clone operation for release [{0}] took [{1}] seconds".format( self.release, difference) ColorPrint.blue_highlight(log_message) self.notif_mgr.send_notification(True, 'clone_env', log_message)
def run_git_pull(self): if not os.path.exists(self.path_to_workspace): ColorPrint.err("Invalid release name: [{0}]".format(self.release)) exit(1) now = time.time() list_of_repos = self.config.getlist('git_repo', 'repo') if self.parallel_run: pool = Pool(len(list_of_repos)) pool.map(self._git_pull, list_of_repos) else: for repo in list_of_repos: self._git_pull(repo) later = time.time() difference = int(later - now) log_message = "Pull operation for release [{0}] took [{1}] seconds".format( self.release, difference) ColorPrint.blue_highlight(log_message) self.notif_mgr.send_notification(True, 'git pull', log_message)
def switch_track(self, track_name): if not os.path.exists(self.path_to_workspace): ColorPrint.err("Invalid release name: [{0}]".format(self.release)) exit(1) now = time.time() list_of_repos = self.config.getlist('git_repo', 'repo') if self.parallel_run: pool = Pool(len(list_of_repos)) pool.map(self._switch_repo, zip(list_of_repos, repeat(track_name))) else: for repo in list_of_repos: self._switch_repo([repo, track_name]) later = time.time() difference = int(later - now) log_message = "Switch operation for release [{0}] took [{1}] seconds".format( self.release, difference) ColorPrint.blue_highlight(log_message) self.notif_mgr.send_notification(True, "Switch branch", log_message)
def _git_pull(self, repo): ColorPrint.blue_highlight("Pulling the repository [{0}]".format(repo)) repo_path = self.path_to_workspace + os.sep + repo is_git_pull_ran = False if os.path.exists(repo_path): current_branch = self.get_branch_name(repo_path) if self._is_branch_up_to_date(repo_path): if repo in self.repo_status and self.repo_status[repo]: ColorPrint.blue_highlight( 'Your repository [{0}] is up-to-date, skipping [git pull]' .format(repo)) else: p_status, output, error = self.run_command_and_collect_errors( 'cd {0};git pull origin {1}'.format( repo_path, current_branch)) is_git_pull_ran = True else: self.run_git_stash(repo_path) if self._is_ready_to_pull(repo_path): if repo in self.repo_status and self.repo_status[repo]: ColorPrint.blue_highlight( 'Your repository [{0}] is up-to-date, skipping [git pull]' .format(repo)) else: p_status, output, error = self.run_command_and_collect_errors( 'cd {0};git pull origin {1}'.format( repo_path, current_branch)) is_git_pull_ran = True self.run_git_unstash(repo_path) else: ColorPrint.warn( "The repository path [{0}] is not available".format(repo)) if is_git_pull_ran and p_status == 0: if 'up to date' in output or 'Successfully rebased and updated' or 'Fast-forward' in output: ColorPrint.blue_highlight( "Pull for repository {0} finished successfully".format( repo)) else: current_error = "Your repository {0} is broken, try to run 'git gc --prune=now' and 'git remote prune origin' to fix it".format( repo) ColorPrint.err(current_error) filename = 'errors.txt' if os.path.exists(filename): append_write = 'a' # append if already exists else: append_write = 'w' # make a new file if not error_file = open(filename, append_write) error_file.write(current_error + '\n') error_file.close()
def _git_pull(self, repo): ColorPrint.blue_highlight("Pulling the repository [{0}]".format(repo)) repo_path = self.path_to_workspace + os.sep + repo if os.path.exists(repo_path): if self._is_branch_up_to_date(repo_path): if repo in self.repo_status and self.repo_status[repo]: ColorPrint.blue_highlight( 'Your repository [{0}] is up-to-date, skipping [git pull]' .format(repo)) else: self.handle_command('cd {0};git pull'.format(repo_path)) else: self.run_git_stash(repo_path) if self._is_ready_to_pull(repo_path): if repo in self.repo_status and self.repo_status[repo]: ColorPrint.blue_highlight( 'Your repository [{0}] is up-to-date, skipping [git pull]' .format(repo)) else: self.handle_command( 'cd {0};git pull'.format(repo_path)) self.run_git_unstash(repo_path) else: ColorPrint.warn( "The repository path [{0}] is not available".format(repo))
def create_mid_config(self, port='0'): current_port = int(port) if not (current_port > 0 and current_port < 65536): current_port = self.instance_port path_to_work_config = self.path_to_workspace + os.sep + 'mid/mid/work/config.xml' path_to_orig_config = self.path_to_workspace + os.sep + 'mid/mid/config.xml' path_to_key_store = self.path_to_workspace + os.sep + 'mid/mid/keystore/agent_keystore.jks' if not os.path.exists(path_to_work_config): ColorPrint.blue_highlight( "Configuring the local mid server with instance port [{0}]". format(current_port)) tree = ET.parse(path_to_orig_config) root = tree.getroot() for parameter in root.findall('parameter'): parameter_name = parameter.get('name') if parameter_name == 'url': parameter.set( 'value', '{0}:{1}/'.format(self.instance_host, current_port)) if parameter_name == 'mid.instance.username': parameter.set('value', self.instance_user) if parameter_name == 'mid.instance.password': parameter.set('value', self.instance_password) if parameter_name == 'name': parameter.set('value', 'eclipse01') tree.write(path_to_work_config) if os.path.exists(path_to_key_store): ColorPrint.info( "Found keystore file, deleting it to prevent crash on mid start [{0}]" .format(path_to_key_store)) os.remove(path_to_key_store) ColorPrint.blue_highlight("Mid server is ready to start") else: ColorPrint.err( "Configuration file for mid server already exist in [{0}] directory" .format(path_to_work_config))
if self.abort_on_error and p_status != 0: ColorPrint.err( "EnvironmentBuilder: Execution aborted due to error[s]") exit(1) return p_status, out, err if __name__ == '__main__': #Font Name: Big #http://patorjk.com/software/taag ColorPrint.blue_highlight(""" # ______ ____ _ _ _ __ ___ # | ____| | _ \ (_| | | | /_ | |__ \\ # | |__ _ ____ _| |_) |_ _ _| | __| | ___ _ __ __ _____ _ __ | | ) | # | __| | '_ \ \ / | _ <| | | | | |/ _` |/ _ | '__| \ \ / / _ | '__| | | / / # | |____| | | \ V /| |_) | |_| | | | (_| | __| | \ V | __| | | |_ / /_ # |______|_| |_|\_/ |____/ \__,_|_|_|\__,_|\___|_| \_/ \___|_| |_(_|____| # """ ) parser = argparse.ArgumentParser( prog='envbuilder', description='ServiceNow build environemnt tool', epilog= './envbuilder.py -u some.user -p password -t trackname -r release') parser.add_argument('-u', help='git user name', nargs='?', dest="username") parser.add_argument('-p', help='git password', nargs='?', dest="password") parser.add_argument( '-pull', help=
if abort_on_error and p_status != 0: ColorPrint.err( "EnvironmentBuilder: Execution aborted due to error[s]") exit(1) return p_status, out, err if __name__ == '__main__': #Font Name: Big #http://patorjk.com/software/taag ColorPrint.blue_highlight(""" # ______ ____ _ _ _ __ _ _ # | ____| | _ \ (_) | | | /_ | || | # | |__ _ ____ _| |_) |_ _ _| | __| | ___ _ __ | | || |_ # | __| | '_ \ \ / / _ <| | | | | |/ _` |/ _ \ '__| | |__ _| # | |____| | | \ V /| |_) | |_| | | | (_| | __/ | | |_ | | # |______|_| |_|\_/ |____/ \__,_|_|_|\__,_|\___|_| |_(_)|_| #""") parser = argparse.ArgumentParser(prog='envbuilder.py', description='Build environment tool', formatter_class=RawTextHelpFormatter) parser.add_argument( '-clone', help= 'Clone defined repositories in the conf file to the specifed release directory', action="store_true") parser.add_argument( '-pull', help=