def _start(self): """Start work task running in the background. User should not need to call this directly. Work with your subclasses `run` method instead. """ self._results = None if not self.command: raise ValueError('command not defined') # Pre-existing process ID? if self.is_running: if self.verbose: print('\nProcess already running with PID: {:d}'.format( self.pid)) return self.pid # Instantiate command and run it self._proc = sarge.Command(self.command, stdout=sarge.Capture(), stderr=sarge.Capture(), shell=True) self._proc.run(async=True) if not self.is_running: raise ValueError('Problem starting process: {}'.format( self.fname_exe))
def delete_org(self): """ Uses sfdx force:org:delete to delete the org """ if not self.created: self.logger.info( "Skipping org deletion: the scratch org has not been created") return command = sarge.shell_format("sfdx force:org:delete -p -u {0}", self.username) self.logger.info( "Deleting scratch org with command {}".format(command)) p = sarge.Command(command, stdout=sarge.Capture(buffer_size=-1), shell=True) p.run() org_info = None stdout = [] for line in p.stdout: stdout.append(line) if line.startswith("An error occurred deleting this org"): self.logger.error(line) else: self.logger.info(line) if p.returncode: message = "Failed to delete scratch org: \n{}".format( "".join(stdout)) raise ScratchOrgException(message) # Flag that this org has been created self.config["created"] = False self.config["username"] = None
def delete_org(self): """ Uses sfdx force:org:delete to create the org """ if not self.created: self.logger.info( 'Skipping org deletion: the scratch org has not been created') return command = 'sfdx force:org:delete -p -u {}'.format(self.username) self.logger.info( 'Deleting scratch org with command {}'.format(command)) p = sarge.Command(command, stdout=sarge.Capture(buffer_size=-1)) p.run() org_info = None stdout = [] for line in p.stdout: stdout.append(line) if line.startswith('An error occurred deleting this org'): self.logger.error(line) else: self.logger.info(line) if p.returncode: message = 'Failed to delete scratch org: \n{}'.format( ''.join(stdout)) raise ScratchOrgException(message) # Flag that this org has been created self.config['created'] = False self.config['username'] = None
def create_org(self): """ Uses heroku force:org:create to create the org """ if not self.config_file: # FIXME: raise exception return if not self.scratch_org_type: self.config['scratch_org_type'] = 'workspace' command = 'heroku force:org:create -t {} -f {}'.format( self.scratch_org_type, self.config_file) self.logger.info( 'Creating scratch org with command {}'.format(command)) p = sarge.Command(command, stdout=sarge.Capture(buffer_size=-1)) p.run() org_info = None re_obj = re.compile( 'Successfully created workspace org: (.+), username: (.+)') for line in p.stdout: match = re_obj.search(line) if match: self.config['org_id'] = match.group(1) self.config['username'] = match.group(2) self.logger.info(line) if p.returncode: # FIXME: raise exception raise ConfigError('Failed to create scratch org: {}'.format( '\n'.join(p.stdout))) # Flag that this org has been created self.config['created'] = True
def generate_password(self): """Generates an org password with the sfdx utility. """ if self.password_failed: self.logger.warn( "Skipping resetting password since last attempt failed") return # Set a random password so it's available via cci org info command = sarge.shell_format( "sfdx force:user:password:generate -u {0}", self.username) self.logger.info( "Generating scratch org user password with command {}".format( command)) p = sarge.Command( command, stdout=sarge.Capture(buffer_size=-1), stderr=sarge.Capture(buffer_size=-1), shell=True, ) p.run() stdout = [] for line in p.stdout: stdout.append(line) stderr = [] for line in p.stderr: stderr.append(line) if p.returncode: self.config["password_failed"] = True # Don't throw an exception because of failure creating the # password, just notify in a log message self.logger.warn("Failed to set password: \n{}\n{}".format( "\n".join(stdout), "\n".join(stderr)))
def scratch_info(self): if hasattr(self, '_scratch_info'): return self._scratch_info # Create the org if it hasn't already been created if not self.created: self.create_org() self.logger.info('Getting scratch org info from Salesforce DX') # Call force:org:display and parse output to get instance_url and access_token command = 'sfdx force:org:display -u {} --json'.format(self.username) p = sarge.Command(command, stdout=sarge.Capture(buffer_size=-1)) p.run() org_info = None stdout_list = [] for line in p.stdout: stdout_list.append(line.strip()) if p.returncode: self.logger.error('Return code: {}'.format(p.returncode)) for line in stdout_list: self.logger.error(line) message = 'Message: {}'.format('\n'.join(stdout_list)) raise ScratchOrgException(message) else: json_txt = ''.join(stdout_list) try: org_info = json.loads(''.join(stdout_list)) except Exception as e: raise ScratchOrgException( 'Failed to parse json from output. This can happen if ' 'your scratch org gets deleted.\n ' 'Exception: {}\n Output: {}'.format( e.__class__.__name__, ''.join(stdout_list), ) ) org_id = org_info['result']['accessToken'].split('!')[0] if org_info['result'].get('password', None) is None: self.generate_password() return self.scratch_info self._scratch_info = { 'instance_url': org_info['result']['instanceUrl'], 'access_token': org_info['result']['accessToken'], 'org_id': org_id, 'username': org_info['result']['username'], 'password': org_info['result'].get('password',None), } self.config.update(self._scratch_info) self._scratch_info_date = datetime.datetime.utcnow() return self._scratch_info
def scratch_info(self): if hasattr(self, '_scratch_info'): return self._scratch_info # Create the org if it hasn't already been created if not self.created: self.create_org() self.logger.info('Getting scratch org info from Salesforce DX') # Call force:org:open and parse output to get instance_url and access_token command = 'heroku force:org:open -d -u {}'.format(self.username) p = sarge.Command(command, stdout=sarge.Capture(buffer_size=-1)) p.run() org_info = None stdout_list = [] for line in p.stdout: if line.startswith('Access org'): org_info = line.strip() stdout_list.append(line.strip()) if p.returncode: message = 'Return code: {}\nstdout: {}\nstderr: {}'.format( p.returncode, '\n'.join(stdout_list), p.stderr, ) self.logger.error(message) raise ScratchOrgException(message) if not org_info: message = 'Did not find org info in command output:\n{}'.format(p.stdout) self.logger.error(message) raise ScratchOrgException(message) # OrgID is the third word of the output org_id = org_info.split(' ')[2] # Username is the sixth word of the output username = org_info.split(' ')[5] info_parts = org_info.split('following URL: ') if len(info_parts) == 1: message = 'Did not find org info in command output:\n{}'.format(p.stdout) self.logger.error(message) raise ScratchOrgException(message) instance_url, access_token = info_parts[1].split('/secur/frontdoor.jsp?sid=') self._scratch_info = { 'instance_url': instance_url, 'access_token': access_token, 'org_id': org_id, 'username': username, } self._scratch_info_date = datetime.datetime.now() return self._scratch_info
def create_org(self): """ Uses sfdx force:org:create to create the org """ if not self.config_file: # FIXME: raise exception return if not self.scratch_org_type: self.config["scratch_org_type"] = "workspace" options = { "config_file": self.config_file, "devhub": " --targetdevhubusername {}".format(self.devhub) if self.devhub else "", "namespaced": " -n" if not self.namespaced else "", "days": " --durationdays {}".format(self.days) if self.days else "", "alias": sarge.shell_format(' -a "{0!s}"', self.sfdx_alias) if self.sfdx_alias else "", "extraargs": os.environ.get("SFDX_ORG_CREATE_ARGS", ""), } # This feels a little dirty, but the use cases for extra args would mostly # work best with env vars command = "sfdx force:org:create -f {config_file}{devhub}{namespaced}{days}{alias} {extraargs}".format( **options) self.logger.info( "Creating scratch org with command {}".format(command)) p = sarge.Command(command, stdout=sarge.Capture(buffer_size=-1), shell=True) p.run() re_obj = re.compile( "Successfully created scratch org: (.+), username: (.+)") stdout = [] for line in p.stdout: match = re_obj.search(line) if match: self.config["org_id"] = match.group(1) self.config["username"] = match.group(2) stdout.append(line) self.logger.info(line) self.config["date_created"] = datetime.datetime.now() if p.returncode: message = "{}: \n{}".format(FAILED_TO_CREATE_SCRATCH_ORG, "".join(stdout)) raise ScratchOrgException(message) if self.config.get("set_password"): self.generate_password() # Flag that this org has been created self.config["created"] = True
def create_org(self): """ Uses sfdx force:org:create to create the org """ if not self.config_file: # FIXME: raise exception return if not self.scratch_org_type: self.config['scratch_org_type'] = 'workspace' options = { 'config_file': self.config_file, 'devhub': ' --targetdevhubusername {}'.format(self.devhub) if self.devhub else '', 'namespaced': ' -n' if not self.namespaced else '', 'days': ' --durationdays {}'.format(self.days) if self.days else '', 'alias': ' -a "{}"'.format(self.sfdx_alias) if self.sfdx_alias else '', 'extraargs': os.environ.get('SFDX_ORG_CREATE_ARGS', ''), } # This feels a little dirty, but the use cases for extra args would mostly # work best with env vars command = 'sfdx force:org:create -f {config_file}{devhub}{namespaced}{days}{alias} {extraargs}'.format( **options) self.logger.info( 'Creating scratch org with command {}'.format(command)) p = sarge.Command(command, stdout=sarge.Capture(buffer_size=-1)) p.run() org_info = None re_obj = re.compile( 'Successfully created scratch org: (.+), username: (.+)') stdout = [] for line in p.stdout: match = re_obj.search(line) if match: self.config['org_id'] = match.group(1) self.config['username'] = match.group(2) stdout.append(line) self.logger.info(line) self.config['date_created'] = datetime.datetime.now() if p.returncode: message = '{}: \n{}'.format( FAILED_TO_CREATE_SCRATCH_ORG, ''.join(stdout), ) raise ScratchOrgException(message) if self.config.get('set_password'): self.generate_password() # Flag that this org has been created self.config['created'] = True
def run_ant_target(target, env, config, check_credentials=None, no_exit=None, verbose=None): if check_credentials: try: check_salesforce_credentials(env) except SalesforceCredentialsException as e: click.echo('BUILD FAILED: %s' % e) sys.exit(4) # Set max heap size for ant call env["ANT_OPTS"] = '-Xmx512m' # Execute the command if verbose: cmd = 'ant %s' % target else: cmd = '%s/ci/ant_wrapper.sh %s' % (config.cumulusci_path, target) p = sarge.Command(cmd, stdout=sarge.Capture(buffer_size=-1), env=env) p.run(async=True) # Print the stdout buffer until the command completes and capture all lines in log for reference in exceptions log = [] while p.returncode is None: for line in p.stdout: log.append(line.rstrip()) click.echo(line.rstrip()) p.poll() # Check the return code, raise the appropriate exception if needed if p.returncode: logtxt = '\n'.join(log) try: if logtxt.find('All Component Failures:') != -1: raise DeploymentException(logtxt) elif logtxt.find('[exec] Failing Tests') != -1: raise ApexTestException(logtxt) else: raise AntTargetException(logtxt) except DeploymentException as e: click.echo('BUILD FAILED: One or more deployment errors occurred') if no_exit: raise e else: sys.exit(2) except ApexTestException as e: click.echo('BUILD FAILED: One or more Apex tests failed') if no_exit: raise e else: sys.exit(3) except AntTargetException as e: click.echo('BUILD FAILED: One or more Ant target errors occurred') if no_exit: raise e else: sys.exit(1) return p
def get_git_config(config_key): p = sarge.Command( sarge.shell_format('git config --get "{0!s}"', config_key), stderr=sarge.Capture(buffer_size=-1), stdout=sarge.Capture(buffer_size=-1), shell=True, ) p.run() config_value = io.TextIOWrapper(p.stdout).read().strip() return config_value if config_value and not p.returncode else None
def scratch_info(self): if hasattr(self, '_scratch_info'): return self._scratch_info # Create the org if it hasn't already been created if not self.created: self.create_org() self.logger.info('Getting scratch org info from Salesforce DX') # Call force:org:open and parse output to get instance_url and access_token command = 'sfdx force:org:describe -u {} --json'.format(self.username) p = sarge.Command(command, stdout=sarge.Capture(buffer_size=-1)) p.run() org_info = None stdout_list = [] for line in p.stdout: stdout_list.append(line.strip()) if p.returncode: self.logger.error('Return code: {}'.format(p.returncode)) for line in stdout_list: self.logger.error(line) raise ScratchOrgException(message) else: json_txt = ''.join(stdout_list) try: org_info = json.loads(''.join(stdout_list)) except Exception as e: raise ScratchOrgException( 'Failed to parse json from output: {}\n{}'.format( ''.join(stdout_list), e)) org_id = org_info['accessToken'].split('!')[0] self._scratch_info = { 'instance_url': org_info['instanceUrl'], 'access_token': org_info['accessToken'], 'org_id': org_id, 'username': org_info['username'], } self._scratch_info_date = datetime.datetime.now() return self._scratch_info
def sfdx( command, username=None, log_note=None, access_token=None, args=None, env=None, capture_output=True, check_return=False, ): """Call an sfdx command and capture its output. Be sure to quote user input that is part of the command using `shell_quote`. Returns a `sarge` Command instance with returncode, stdout, stderr """ command = f"sfdx {command}" if args is not None: for arg in args: command += " " + shell_quote(arg) if username: command += f" -u {shell_quote(username)}" if log_note: logger.info(f"{log_note} with command: {command}") # Avoid logging access token if access_token: command += f" -u {shell_quote(access_token)}" p = sarge.Command( command, stdout=sarge.Capture(buffer_size=-1) if capture_output else None, stderr=sarge.Capture(buffer_size=-1) if capture_output else None, shell=True, env=env, ) p.run() if capture_output: p.stdout_text = io.TextIOWrapper(p.stdout, encoding=sys.stdout.encoding) p.stderr_text = io.TextIOWrapper(p.stderr, encoding=sys.stdout.encoding) if check_return and p.returncode: message = f"Command exited with return code {p.returncode}" if capture_output: message += f":\n{p.stderr_text.read()}" raise Exception(message) return p
def command(self) -> sarge.Command: """ Returns sarge.Command instance, creating it if necessary :return: sarge.Command object :rtype: sarge.Command """ if not hasattr(self, '_command'): command = sarge.Command( [self.exe_path_as_str] + self.args_list, stdout=self.capture, stderr=self.capture, shell=False, cwd=self.cwd, ) setattr(self, '_command', command) return getattr(self, '_command')
def run_python_script(script, env, config, required_env=None): if required_env: check_required_env(env, required_env) # Execute the command p = sarge.Command('python %s/ci/%s' % (config.cumulusci_path, script), stdout=sarge.Capture(buffer_size=-1), env=env) p.run(async=True) # Print the stdout buffer until the command completes and capture all lines in log for reference in exceptions log = [] while p.returncode is None: for line in p.stdout: log.append(line.rstrip()) click.echo(line.rstrip()) p.poll() return p
def force_refresh_oauth_token(self): # Call force:org:display and parse output to get instance_url and access_token command = 'sfdx force:org:open -r -u {}'.format(self.username) self.logger.info('Refreshing OAuth token with command: {}'.format(command)) p = sarge.Command(command, stdout=sarge.Capture(buffer_size=-1)) p.run() stdout_list = [] for line in p.stdout: stdout_list.append(line.strip()) if p.returncode: self.logger.error('Return code: {}'.format(p.returncode)) for line in stdout_list: self.logger.error(line) message = 'Message: {}'.format('\n'.join(stdout_list)) raise ScratchOrgException(message)
def setup(): global server, driver if not have_selenium: raise SkipTest("Tests require Selenium") default_setup() for step in setup_steps: if callable(step): step() else: print(step[0]) # description run_test(*step[1:]) server = sarge.Command("smtweb -p 8765 --no-browser", cwd=utils.working_dir, stdout=sarge.Capture(), stderr=sarge.Capture()) server.run(async=True) driver = webdriver.Firefox()
def sfdx( command, username=None, log_note=None, access_token=None, args=None, env=None, capture_output=True, check_return=False, ): """Call an sfdx command and capture its output. Be sure to quote user input that is part of the command using `sarge.shell_format`. Returns a `sarge` Command instance with returncode, stdout, stderr """ command = "sfdx {}".format(command) if args is not None: for arg in args: command += " " + sarge.shell_quote(arg) if username: command += sarge.shell_format(" -u {0}", username) if log_note: logger.info("{} with command: {}".format(log_note, command)) # Avoid logging access token if access_token: command += sarge.shell_format(" -u {0}", access_token) p = sarge.Command( command, stdout=sarge.Capture(buffer_size=-1) if capture_output else None, stderr=sarge.Capture(buffer_size=-1) if capture_output else None, shell=True, env=env, ) p.run() if capture_output: p.stdout_text = io.TextIOWrapper(p.stdout, encoding=sys.stdout.encoding) p.stderr_text = io.TextIOWrapper(p.stderr, encoding=sys.stdout.encoding) if check_return and p.returncode: raise Exception(f"Command exited with return code {p.returncode}") return p
def _call_salesforce_dx(self, command, options=None): full_command = 'heroku ' + command if options: full_command += ' {}'.format(options) full_command += ' -u {}'.format(self.org_config.username) self.logger.info('Running: {}'.format(full_command)) p = sarge.Command(full_command, stdout=sarge.Capture(buffer_size=-1)) p.run() output = [] for line in p.stdout: self.logger.info(line) if p.returncode: message = '{}: {}'.format(p.returncode, p.stdout) self.logger.error(message) raise SalesforceDXException(message)
def create_org(self): """ Uses sfdx force:org:create to create the org """ if not self.config_file: # FIXME: raise exception return if not self.scratch_org_type: self.config['scratch_org_type'] = 'workspace' devhub = '' if self.devhub: devhub = ' --targetdevhubusername {}'.format(self.devhub) # This feels a little dirty, but the use cases for extra args would mostly # work best with env vars extraargs = os.environ.get('SFDX_ORG_CREATE_ARGS', '') command = 'sfdx force:org:create -f {}{} {}'.format( self.config_file, devhub, extraargs) self.logger.info( 'Creating scratch org with command {}'.format(command)) p = sarge.Command(command, stdout=sarge.Capture(buffer_size=-1)) p.run() org_info = None re_obj = re.compile( 'Successfully created scratch org: (.+), username: (.+)') stdout = [] for line in p.stdout: match = re_obj.search(line) if match: self.config['org_id'] = match.group(1) self.config['username'] = match.group(2) stdout.append(line) self.logger.info(line) if p.returncode: message = 'Failed to create scratch org: \n{}'.format( ''.join(stdout)) raise ScratchOrgException(message) self.generate_password() # Flag that this org has been created self.config['created'] = True
def _run_command(self, env, command=None, output_handler=None, return_code_handler=None): if not command: command = self._get_command() interactive_mode = process_bool_arg(self.options["interactive"]) self.logger.info("Running command: %s", command) p = sarge.Command( command, stdout=sys.stdout if interactive_mode else sarge.Capture( buffer_size=-1), stderr=sys.stderr if interactive_mode else sarge.Capture( buffer_size=-1), shell=True, env=env, cwd=self.options.get("dir"), ) if interactive_mode: p.run(input=sys.stdin) else: p.run(async_=True) # Handle output lines if not output_handler: output_handler = self._process_output while True: line = p.stdout.readline(timeout=1.0) if line: output_handler(line) elif p.poll() is not None: break p.wait() # Handle return code if not return_code_handler: return_code_handler = self._handle_returncode return_code_handler(p.returncode, None if interactive_mode else p.stderr)
def sfdx(command, username=None, log_note=None): """Call an sfdx command and capture its output. Be sure to quote user input that is part of the command using `sarge.shell_format`. Returns a `sarge` Command instance with returncode, stdout, stderr """ command = "sfdx {}".format(command) if username: command += sarge.shell_format(" -u {0}", username) if log_note: logger.info("{} with command: {}".format(log_note, command)) p = sarge.Command( command, stdout=sarge.Capture(buffer_size=-1), stderr=sarge.Capture(buffer_size=-1), shell=True, ) p.run() return p
def force_refresh_oauth_token(self): # Call force:org:display and parse output to get instance_url and # access_token command = sarge.shell_format("sfdx force:org:open -r -u {0}", self.username) self.logger.info( "Refreshing OAuth token with command: {}".format(command)) p = sarge.Command(command, stdout=sarge.Capture(buffer_size=-1), shell=True) p.run() stdout_list = [line.strip() for line in io.TextIOWrapper(p.stdout)] if p.returncode: self.logger.error("Return code: {}".format(p.returncode)) for line in stdout_list: self.logger.error(line) message = "Message: {}".format("\n".join(stdout_list)) raise ScratchOrgException(message)
def delete_org(self): """ Uses heroku force:org:delete to create the org """ if not self.created: self.logger.info( 'Skipping org deletion: the scratch org has not been created') return command = 'heroku force:org:delete --force -u {}'.format(self.username) self.logger.info( 'Deleting scratch org with command {}'.format(command)) p = sarge.Command(command, stdout=sarge.Capture(buffer_size=-1)) p.run() org_info = None for line in p.stdout: self.logger.info(line) if p.returncode: # FIXME: raise exception raise ConfigError('Failed to delete scratch org') # Flag that this org has been created self.config['created'] = False self.config['username'] = False
def start(self): """Run task process via Sarge package. """ self._results = None if not self.command: raise ValueError('command not defined') # Pre-existing process ID? if self.running: if self.verbose: print('\nProcess already running with PID: {:d}'.format( self.pid)) return self.pid # Instantiate command and run it self._proc = sarge.Command(self.command, stdout=sarge.Capture(), stderr=sarge.Capture()) self._proc.run(async=True) if not self.running: raise ValueError('Problem starting process: {}'.format( self.fname_exe))
def run_heuristic_solver_interactive(data, callback, callback_delay=0.5, command='./tw-heuristic', cwd=None, extra_args=None): """ Runs the heuristic tamaki solver and allows to interactively process output Requires sarge to be installed Tamaki Python | | | <-- start---------------------| | | |-> if exist new line data -->---callback(info), wait(callback_delay) | | | <-- send interrupt <------- if callback raised | | |-> output solution *format2 -->| process solution | |terminate Parameters ---------- data : str String with gr representation of a graph callback: callable Function to handle new info data. Info format: (time, tw). Should handle [None, None] properly. Raise to stop iteration callback_delay : float Waiting time between checking for output command : str, optional Deafults to "./tw-heuristic" extra_args : str, optional Optional commands to the solver Returns ------- output : str Process output """ sh = command + " " if extra_args is not None: sh += extra_args width_pattern = re.compile('^c width =(?P<width>.+)') time_pattern = re.compile('^c time =(?P<time>.+) ms') import sarge p = sarge.Command(sh.split(), cwd=cwd, stdout=sarge.Capture(), stderr=sarge.Capture()) update_info = [None, None] p.run(input=data, async_=True) try: while True: """ This wierd order is to skip sleep in case of update """ try: callback(update_info) except Exception as e: print(f'Exception: {e}. Stoppnig tamaki', file=sys.stderr) break err = p.stderr.read().decode() if err: raise Exception("Java Error:\n" + err) line = p.stdout.readline().decode() maybe_width = width_pattern.search(line) if maybe_width: width = int(maybe_width.group('width')) update_info[1] = width line = p.stdout.readline().decode() maybe_time = time_pattern.search(line) if maybe_time: time_ = int(maybe_time.group('time')) update_info[0] = time_ continue time.sleep(callback_delay) except BaseException as e: print('Stopping tamaki', file=sys.stderr) raise finally: p.terminate() p.wait() data = p.stdout.read().decode() return data
def scratch_info(self): if hasattr(self, "_scratch_info"): return self._scratch_info # Create the org if it hasn't already been created if not self.created: self.create_org() self.logger.info("Getting scratch org info from Salesforce DX") # Call force:org:display and parse output to get instance_url and # access_token command = sarge.shell_format("sfdx force:org:display -u {0} --json", self.username) p = sarge.Command( command, stderr=sarge.Capture(buffer_size=-1), stdout=sarge.Capture(buffer_size=-1), shell=True, ) p.run() org_info = None stderr_list = [line.strip() for line in p.stderr] stdout_list = [line.strip() for line in p.stdout] if p.returncode: self.logger.error("Return code: {}".format(p.returncode)) for line in stderr_list: self.logger.error(line) for line in stdout_list: self.logger.error(line) message = "\nstderr:\n{}".format("\n".join(stderr_list)) message += "\nstdout:\n{}".format("\n".join(stdout_list)) raise ScratchOrgException(message) else: json_txt = "".join(stdout_list) try: org_info = json.loads("".join(stdout_list)) except Exception as e: raise ScratchOrgException( "Failed to parse json from output. This can happen if " "your scratch org gets deleted.\n " "Exception: {}\n Output: {}".format( e.__class__.__name__, "".join(stdout_list))) org_id = org_info["result"]["accessToken"].split("!")[0] if "password" in org_info["result"] and org_info["result"]["password"]: password = org_info["result"]["password"] else: password = self.config.get("password") self._scratch_info = { "instance_url": org_info["result"]["instanceUrl"], "access_token": org_info["result"]["accessToken"], "org_id": org_id, "username": org_info["result"]["username"], "password": password, } self.config.update(self._scratch_info) self._scratch_info_date = datetime.datetime.utcnow() return self._scratch_info
def create_org(self): """ Uses sfdx force:org:create to create the org """ if not self.config_file: # FIXME: raise exception return if not self.scratch_org_type: self.config['scratch_org_type'] = 'workspace' devhub = '' if self.devhub: devhub = ' --targetdevhubusername {}'.format(self.devhub) # This feels a little dirty, but the use cases for extra args would mostly # work best with env vars extraargs = os.environ.get('SFDX_ORG_CREATE_ARGS', '') command = 'sfdx force:org:create -f {}{} {}'.format( self.config_file, devhub, extraargs) self.logger.info( 'Creating scratch org with command {}'.format(command)) p = sarge.Command(command, stdout=sarge.Capture(buffer_size=-1)) p.run() org_info = None re_obj = re.compile( 'Successfully created scratch org: (.+), username: (.+)') stdout = [] for line in p.stdout: match = re_obj.search(line) if match: self.config['org_id'] = match.group(1) self.config['username'] = match.group(2) stdout.append(line) self.logger.info(line) if p.returncode: message = 'Failed to create scratch org: \n{}'.format( ''.join(stdout)) raise ScratchOrgException(message) # Set a random password so it's available via cci org info command = 'sfdx force:user:password:generate -u {}'.format( self.username) self.logger.info( 'Generating scratch org user password with command {}'.format( command)) p = sarge.Command(command, stdout=sarge.Capture(buffer_size=-1), stderr=sarge.Capture(buffer_size=-1)) p.run() stdout = [] for line in p.stdout: stdout.append(line) stderr = [] for line in p.stderr: stderr.append(line) if p.returncode: # Don't throw an exception because of failure creating the password, just notify in a log message self.logger.warn('Failed to set password: \n{}\n{}'.format( '\n'.join(stdout), '\n'.join(stderr))) # Flag that this org has been created self.config['created'] = True
def create_org(self): """ Uses sfdx force:org:create to create the org """ if not self.config_file: # FIXME: raise exception return if not self.scratch_org_type: self.config["scratch_org_type"] = "workspace" # If the scratch org definition itself contains an `adminEmail` entry, # we don't want to override it from our own configuration, which may # simply come from the user's Git config. with open(self.config_file, "r") as org_def: org_def_data = json.load(org_def) org_def_has_email = "adminEmail" in org_def_data options = { "config_file": self.config_file, "devhub": " --targetdevhubusername {}".format(self.devhub) if self.devhub else "", "namespaced": " -n" if not self.namespaced else "", "days": " --durationdays {}".format(self.days) if self.days else "", "alias": sarge.shell_format(' -a "{0!s}"', self.sfdx_alias) if self.sfdx_alias else "", "email": sarge.shell_format('adminEmail="{0!s}"', self.email_address) if self.email_address and not org_def_has_email else "", "extraargs": os.environ.get("SFDX_ORG_CREATE_ARGS", ""), } # This feels a little dirty, but the use cases for extra args would mostly # work best with env vars command = "sfdx force:org:create -f {config_file}{devhub}{namespaced}{days}{alias} {email} {extraargs}".format( **options) self.logger.info( "Creating scratch org with command {}".format(command)) p = sarge.Command( command, stdout=sarge.Capture(buffer_size=-1), stderr=sarge.Capture(buffer_size=-1), shell=True, ) p.run() stderr = [line.strip() for line in io.TextIOWrapper(p.stderr)] stdout = [line.strip() for line in io.TextIOWrapper(p.stdout)] if p.returncode: message = "{}: \n{}\n{}".format(FAILED_TO_CREATE_SCRATCH_ORG, "\n".join(stdout), "\n".join(stderr)) raise ScratchOrgException(message) re_obj = re.compile( "Successfully created scratch org: (.+), username: (.+)") for line in stdout: match = re_obj.search(line) if match: self.config["org_id"] = match.group(1) self.config["username"] = match.group(2) self.logger.info(line) for line in stderr: self.logger.error(line) self.config["date_created"] = datetime.datetime.now() if self.config.get("set_password"): self.generate_password() # Flag that this org has been created self.config["created"] = True
def start(self): self.feeder = sarge.Feeder() self.reader = sarge.Capture() self.p = sarge.Command(self.text_cmd, stdout=self.reader) self.p.run(input=self.feeder, async=True)