Package: task-in-steps
task_in_stepsMany python-automation scripts can be seperated into steps.
This library supports this seperation. You can define steps
with classes. The steps are indepodent as they can implementcan_skipwhich checks if the step can be skipped.ExampleclassConfig:def__init__(self):self.parser=argparse.ArgumentParser()self.parser.add_argument('--projectname',help='Name of the new project',required=True)self.parser.add_argument('--domain',help='Top-Level-Domain (without review.)',required=True)self.parser.add_argument('--template',help='A link to a GitHub-Repo, used as template',required=True)self.parser.add_argument('--username',help='LDAP Username',required=True)self.parser.add_argument('--password',help='LDAP Password (optional)',required=False)self.gerrit_port=29418defload_args(self):args=self.parser.parse_args()self.project_name=args.projectnameself.template_src=args.templateself.gerrit_user=args.usernameself.password=args.passwordself.domain=args.domainself.gerrit_host='review.'+args.domainself.gerrit_url=f'http://{self.gerrit_host}'returnselfif__name__=="__main__":config=Config().load_args()run_steps(config,[CertificateOnThisMachine(),UploadSshKey(),ProjectFromTemplate(),CreateGerritProject(),ConfigureGerritGitHooks(),ConfigureGitPushToGerrit(),CreateJenkinsPipelines(),TriggerTemplateInit(),SendInitialCommit()])### The steps:classCertificateOnThisMachine(Step):name="SSH certificate on this machine"def__init__(self):home=os.path.expanduser('~')self.ssh_path=home+'/.ssh'defcan_skip(self,config):returnos.path.isfile(self.ssh_path+'/id_rsa.pub')defrun(self,config):print('no ssh-certificate: generating one')os.system(f'ssh-keygen -t rsa -N '' -f{self.ssh_path}')returnTrueclassUploadSshKey(Step):name="Upload your SSH-Key"defcan_skip(self,config):ssh_command=f'ssh -p{config.gerrit_port}{config.gerrit_user}@{config.gerrit_host}gerrit version'res=subprocess.run(ssh_command.split(),stdout=subprocess.DEVNULL,stderr=subprocess.DEVNULL).returncodereturnres==0defrun(self,config):home=os.path.expanduser('~')ssh_path=home+'/.ssh'print()print('You did not upload your SSH-Key.')print()print(f'1. Go to: http://{config.gerrit_host}/settings/#SSHKeys')print('2. Paste this in, click "Add Key" and run again:')withopen(f'{ssh_path}/id_rsa.pub','r')asfile:print(file.read())returnFalseclassProjectFromTemplate(Step):name="Create project from template"defcan_skip(self,config):returnos.path.isdir(f'./{config.project_name}')defrun(self,config):os.system(f'git clone{config.template_src}{config.project_name}')os.chdir(f'./{config.project_name}')os.system(f'rm .git -rf')os.system(f'git init')os.chdir('..')returnTrueclassCreateGerritProject(Step):name='Create Gerrit project'defcan_skip(self,config):command=f'ssh -p{config.gerrit_port}{config.gerrit_user}@{config.gerrit_host}gerrit ls-projects'existing_projects=subprocess.check_output(command,shell=True).decode().strip().split('\n')returnconfig.project_nameinexisting_projectsdefrun(self,config):os.chdir(f'./{config.project_name}')os.system(f'ssh -p{config.gerrit_port}{config.gerrit_user}@{config.gerrit_host}gerrit create-project{config.project_name}')os.chdir('..')returnTrueclassConfigureGerritGitHooks(Step):name='Installing Gerrit Git-Hooks'defcan_skip(self,config):path=f'./{config.project_name}/.git/hooks/commit-msg'ifnotos.path.isfile(path):returnFalsewithopen(path,'r')asfile:content=file.read()return'Change-Id:'incontentdefrun(self,config):os.chdir(f'./{config.project_name}')os.system(f'scp -p -P{config.gerrit_port}{config.gerrit_user}@{config.gerrit_host}:hooks/commit-msg ".git/hooks/"')os.chdir('..')returnTrueclassConfigureGitPushToGerrit(Step):name='Configure "git push" to Gerrit'defcan_skip(self,config):path=f'./{config.project_name}/.git/config'ifnotos.path.isfile(path):returnFalsewithopen(path,'r')asfile:content=file.read()return'push = refs/heads/master:refs/for/master'incontentdefrun(self,config):path=f'./{config.project_name}/.git/config'git_config=f'''[core]repositoryformatversion = 0filemode = truebare = falselogallrefupdates = true[remote "origin"]url = ssh://{config.gerrit_user}@{config.gerrit_host}:{config.gerrit_port}/{config.project_name}fetch = +refs/heads/master:refs/remotes/origin/masterpush = refs/heads/master:refs/for/master[branch "master"]remote = originmerge = refs/heads/master'''withopen(path,'w')asf:f.write(git_config)returnTrueclassCreateJenkinsPipelines(Step):name='Creating Jenkins-Pipelines'defcan_skip(self,config):job1=config.project_name+'-code'job2=config.project_name+'-deploy'server=self._get_server(config)jobs=[job['name']forjobinserver.get_all_jobs()]returnjob1injobsandjob2injobsdefrun(self,config):self._create_pipeline(config.project_name,'code',config)self._create_pipeline(config.project_name,'deploy',config)returnTruedef_get_server(self,config):ifhasattr(self,'server'):returnself.serverurl=f'http://ci.{config.domain}'password=config.passwordifnotpassword:print(f'Enter credentials for "{url}"')print(f'User:{config.gerrit_user}')password=getpass()self.server=Jenkins(url,username=config.gerrit_user,password=password)returnself.serverdef_create_pipeline(self,project_name,pipeline_type,config):content=pkg_resources.resource_string('generate_gerrit_jenkins_project',f'jobs/{pipeline_type}.config.xml').decode()content=content.replace('helloworld',project_name)try:self._get_server(config).create_job(project_name+'-'+pipeline_type,content)exceptJenkinsExceptionase:print(e)raiseclassTriggerTemplateInit(Step):name='Trigger Template Init'defcan_skip(self,config):returnnotos.path.isfile(f'./{config.project_name}/init_template.py')defrun(self,config):stdout,stderr,has_error=exec(f'python3 init_template.py',cwd=f'./{config.project_name}')ifnothas_error:exec(f'rm init_template.py',cwd=f'./{config.project_name}')returnnothas_errorclassSendInitialCommit(Step):name='Send initial commit to gerrit'defcan_skip(self,config):stdout,stderr,has_error=exec('git log',cwd=f'./{config.project_name}')returnnothas_error# git log returns error if there are not commits. Skip=True if no error returneddefrun(self,config):stdout,stderr,has_error1=exec('git add .',cwd=f'./{config.project_name}')print(stdout,stderr)stdout,stderr,has_error2=exec('git commit -aminit',cwd=f'./{config.project_name}')print(stdout,stderr)stdout,stderr,has_error3=exec('git push origin master',cwd=f'./{config.project_name}')print(stdout,stderr)returnTrue