def openScratchOrgSpecificBrowser(term): menuFormat = menuHelper.getDefaultFormat() items = [['Chrome', None, menuFormat], ['Firefox', None, menuFormat], ['Opera', None, menuFormat]] if (helper.isMac()): items.append(['Safari', None, menuFormat]) items.append(menuHelper.getReturnButton(2)) selection = menuHelper.giveUserChoices(term=term, showHeader=True, showFooter=True, items=items, selection=0, subtitle='Open Scratch Org (specify browser)', middleText=None, printAtBottom=False) if (selection == len(items) - 1): return browserName = items[selection][0] browserChoice = browserName.lower() helper.startLoading("Opening Scratch Org in {}".format(browserName)) output = helper.tryCommand(term=term, commands=["sfdx force:org:open -r --json"], clearBeforeShowingError=False, stopSpinnerAfterSuccess=False, printOutputAfterSuccess=False) if (not output[0]): # not failing jsonOutput = helper.loadJson(output[1][0]) url = helper.ifKeyExists("url", jsonOutput["result"]) res = webbrowser.get(browserChoice).open_new_tab(url) if (res): helper.spinnerSuccess() else: menuHelper.clear(term, True, True, title, 'Open Scratch Org (specify browser)', None) helper.startLoading("Opening Scratch Org") helper.spinnerError() print("Either {} is not running, or it's not installed.".format(browserName)) helper.pressToContinue(term)
def login(term): subtitle = 'Login to Org' menuFormat = menuHelper.getDefaultFormat() items = [["Production Org / Developer Edition / DevHub", None, menuFormat], ["Sandbox", None, menuFormat], menuHelper.getReturnButton(2)] selection = menuHelper.giveUserChoices(term=term, showHeader=True, showFooter=True, items=items, selection=0, subtitle=subtitle, middleText="Choose Org type", printAtBottom=False) if (selection == 2): return param = "" if (selection == 0): setAsDefault = menuHelper.askUserYesOrNo(term, True, True, subtitle, ['Set this org as default DevHub? (scratch orgs will be made using this org)'], True, False, False, True) if (not setAsDefault): return if (setAsDefault): param = "-d" if (selection == 1): param = "-r https://test.salesforce.com" menuHelper.clear(term, True, True, title, subtitle, None) orgName = helper.askForInput( [ ["Enter name for org", [ helper.c.y ]] ] ) if (orgName): param += " -a " + orgName menuHelper.clear(term, True, True, title, subtitle, None) helper.startLoading("Waiting for login in browser") helper.tryCommand(term, ["sfdx force:auth:web:login " + param], True, True, False)[0] helper.pressToContinue(term)
def tryCommand(term, commands, clearBeforeShowingError, stopSpinnerAfterSuccess, printOutputAfterSuccess): try: outputs = [] for cmd in commands: log(cmd, 'RUNNING COMMAND\n', 'INFO') output = runCommand(cmd).decode('UTF-8') outputs.append(output) log(cmd, output, 'INFO') if (stopSpinnerAfterSuccess): spinnerSuccess() if (printOutputAfterSuccess): menuHelper.clear(term, False, False, None, None, None) for x in outputs: print (x) return False, outputs # return error = False except subprocess.CalledProcessError as e: output = e.output.decode('UTF-8') spinnerError() if (clearBeforeShowingError): menuHelper.clear(term, False, False, None, None, None) print(output) log(cmd, output, 'ERROR') return True, [output] # return error = True return False # return error = False
def askUserForOrgs(term, lookingForRegularOrgs, text, subtitle, selectMultiple): root = "scratchOrgs" kind = "Scratch Orgs" if (lookingForRegularOrgs): root = "nonScratchOrgs" kind = "orgs" helper.startLoading("Loading {}".format(kind)) output = helper.tryCommand(term=term, commands=["sfdx force:org:list --json"], clearBeforeShowingError=False, stopSpinnerAfterSuccess=True, printOutputAfterSuccess=False) if (output[0]): helper.pressToContinue(term) return jsonOutput = helper.loadJson(output[1][0]) menuFormat = menuHelper.getDefaultFormat() items = [] originalItems = [] for row in jsonOutput['result'][root]: alias = helper.ifKeyExists('alias', row) username = helper.ifKeyExists('username', row) orgId = helper.ifKeyExists('orgId', row) expirationDate = helper.ifKeyExists('expirationDate', row) defaultMarker = helper.ifKeyExists('defaultMarker', row).replace('(U)', 'X').replace('(D)', 'X') if (defaultMarker != ''): if (helper.isMac()): defaultMarker = "✅ " else: defaultMarker = "✓" if (expirationDate != ''): expirationDate = '({})'.format(expirationDate) if (alias == ""): alias = username line = " ".join([alias, defaultMarker, expirationDate]) items.append([line, None, menuFormat]) originalItems.append(alias) if (len(items) == 0): menuHelper.clear(term, True, True, title, subtitle, None) print(helper.col("You have no active {}!".format(kind), [helper.c.r])) helper.pressToContinue(term) return True items.append(menuHelper.getReturnButton(2)) if (selectMultiple): selected = menuHelper.giveUserChoicesWithMultipleAnswers(term=term, showHeader=True, showFooter=True, items=items, subtitle=subtitle, middleText=text, printAtBottom=False) values = [] for item in selected: values.append(originalItems[item]) return values else: selection = menuHelper.giveUserChoices(term=term, showHeader=True, showFooter=True, items=items, selection=0, subtitle=subtitle, middleText=text, printAtBottom=False) if (selection == len(originalItems)): return None return originalItems[selection]
def retry(term, results): if (results[0]): helper.spinnerError() text = results[1] # TODO separate output and question for x in range(4): text.append('') text.append('Would you like to retry?') retry = menuHelper.askUserYesOrNo(term, False, False, 'Create scratch org', text, False, False, True, False) if (retry): menuHelper.clear(term, True, True, title, 'Create scratch org', None) return retry return False
def seeScratchOrgStatus(term): helper.startLoading("Loading Scratch Org details") output = helper.tryCommand(term=term, commands=["sfdx force:org:display --json --verbose", "sfdx force:org:open --json -r"], clearBeforeShowingError=False, stopSpinnerAfterSuccess=True, printOutputAfterSuccess=False) if (output[0]): helper.pressToContinue(term) return jsonOutput = json.loads(output[1][0]) jsonOutputLoginUrl = json.loads(output[1][1]) helper.stopLoading() pre = helper.c.BOLD post = helper.c.ENDC rows = [] if ("alias" in jsonOutput['result']): rows.append(["Alias", jsonOutput['result']['alias']]) rows.append(["Username", jsonOutput['result']['username']]) days = ("{} days (next {}, on {})".format( helper.convertDateToDaysRemaining(jsonOutput['result']['expirationDate']), helper.convertDateToDay(jsonOutput['result']['expirationDate']), helper.convertDateFormat(jsonOutput['result']['expirationDate']))) rows.append(["Days left", days]) rows.append(["Status", jsonOutput['result']['status']]) rows.append(["",""]) rows.append(["ID", jsonOutput['result']['id']]) rows.append(["Created Date", jsonOutput['result']['createdDate']]) rows.append(["Edition", jsonOutput['result']['edition']]) rows.append(["Dev Hub ID", jsonOutput['result']['devHubId']]) rows.append(["Org Name", jsonOutput['result']['orgName']]) rows.append(["Access Token", jsonOutput['result']['accessToken']]) rows.append(["SFDX Auth Url", jsonOutput['result']['sfdxAuthUrl']]) rows.append(["Instance Url", jsonOutput['result']['instanceUrl']]) rows.append(["Login Url", jsonOutputLoginUrl['result']['url']]) menuHelper.clear(term, False, False, None, None, None) helper.createTable([], rows) helper.pressToContinue(term)
def runSelection(term, items, selection): item = items[selection] # call function if item is function if (callable(item[1])): menuHelper.clear(term, True, True, title, item[0], None) with term.location(0, 5): item[1](term) return True # open list sub menu if item is list if isinstance(item[1], list): showMenuItems(term, item[1], 0, True, item[0]) return True # return value if item is bool (used for returning from a sub-menu) if isinstance(item[1], bool): return item[1] # fallback of doing nothing, but staying in same submenu return True
def deleteScratchOrg(term): text = helper.col("Which Scratch Org do you want to delete?", [helper.c.r, helper.c.BOLD]) orgs = orgHelper.askUserForOrgs(term, False, text, 'Delete Scratch Orgs', selectMultiple=True) helper.debug(orgs) if not orgs: menuHelper.clear(term, False, False, title, 'Delete Scratch Orgs', None) print("Did not delete any scratch orgs") helper.pressToContinue(term) return elif (len(orgs) > 1): text = 'Are you sure you want to delete these orgs?' else: text = 'Are you sure you want to delete this org?' deleteScratchOrg = menuHelper.askUserYesOrNo(term, True, True, 'Main menu', [text + ' ({})'.format(', '.join(orgs))], True, False, False, False) if (deleteScratchOrg): menuHelper.clear(term, False, False, title, 'Delete Scratch Orgs', None) for org in orgs: helper.startLoading("Deleting Org: {}".format(org)) error = helper.tryCommand(term, ["sfdx force:org:delete -p -u " + org], True, True, False)[0] if (error): return helper.pressToContinue(term)
def createScratchOrg(term): scratchOrgName = helper.askForInput( [ ["Enter Scratch Org name (non-unique names replaces old ones)", [ helper.c.y ]] ] ) while (not scratchOrgName): menuHelper.clear(term, True, True, title, 'Create scratch org', None) scratchOrgName = helper.askForInput( [ ["Enter Scratch Org name (non-unique names replaces old ones)", [ helper.c.y ]], ["Please enter a name", [ helper.c.r ]] ] ) deletePrevious = False if (helper.getDefaultScratchOrg() != '[none]'): deletePrevious = menuHelper.askUserYesOrNo(term, True, True, 'Creating scratch org', ['Do you want to delete the old scratch org? ({})'.format(helper.getDefaultScratchOrg())], False, False, False, True) if (deletePrevious == 2): return menuHelper.clear(term, True, True, title, 'Creating scratch org', None) orgHelper.createScratchOrg_deletePreviousScratchOrg(term, deletePrevious) results, retry = [True, []], True while results[0] and retry: results = orgHelper.createScratchOrg_createOrg(term, scratchOrgName) retry = orgHelper.retry(term, results) if (results[0] and not retry): return True results, retry = [True, []], True while results[0] and retry: results = orgHelper.createScratchOrg_installManagedPackages(term) retry = orgHelper.retry(term, results) if (results[0] and not retry): return True results, retry = [True, []], True while results[0] and retry: results = orgHelper.createScratchOrg_installUnlockedPackages(term) retry = orgHelper.retry(term, results) if (results[0] and not retry): return True results, retry = [True, []], True while results[0] and retry: results = orgHelper.createScratchOrg_pushMetadata(term) retry = orgHelper.retry(term, results) if (results[0] and not retry): return True results, retry = [True, []], True while results[0] and retry: results = orgHelper.createScratchOrg_pushNonDeployedMetadata(term) retry = orgHelper.retry(term, results) if (results[0] and not retry): return True helper.startLoading("Opening Scratch Org") error = helper.tryCommand(term, ["sfdx force:org:open"], False, True, False)[0] results, retry = [True, []], True while results[0] and retry: results = orgHelper.createScratchOrg_assignPermsets(term) retry = orgHelper.retry(term, results) if (results[0] and not retry): return True results, retry = [True, []], True while results[0] and retry: results = orgHelper.createScratchOrg_importDummyData() retry = orgHelper.retry(term, results) if (results[0] and not retry): return True # helper.startLoading("Running Apex code from ./scripts/apex") # commands = [] # for apexCode in helper.fetchFilesFromFolder("./scripts/apex/", True): # commands.append("sfdx force:apex:execute --apexcodefile " + apexCode) # error = helper.tryCommand(term, commands, True, True, False)[0] # if (error): return helper.pressToContinue(term)
def create(term): path = helper.getConfig('locations.users') if (path is None): print( helper.col( "\nEdit ./config/ssdx-config.json to add a default path for user configs", [helper.c.r])) helper.pressToContinue(term) return path = path + '/' text = "Which user definition to you want to user as baseline? (see {})".format( path) try: userTypes = helper.fetchFilesFromFolder(path, False) except Exception as e: print("Make sure users are configured in " + path) helper.pressToContinue(term) menuFormat = menuHelper.getDefaultFormat() items = [] for userType in userTypes: items.append([userType.replace(".json", ""), None, menuFormat]) items.append(menuHelper.getReturnButton(2)) selection = menuHelper.giveUserChoices(term=term, showHeader=True, showFooter=True, items=items, selection=0, subtitle='Create user', middleText=text, printAtBottom=False) if (selection == len(items) - 1): return file = path + userTypes[selection] d = datetime.datetime.now().strftime('%d%m%y_%f') username = "******".format(userTypes[selection].replace(".json", ""), d) email = "{}{}@fake.no".format(userTypes[selection].replace(".json", ""), d) menuHelper.clear(term, True, True, title, 'Create user', None) helper.startLoading("Creating user") error = helper.tryCommand(term, [ "sfdx force:user:create -f {} username={} email={}".format( file, username, email) ], False, True, False)[0] if (not error): helper.startLoading("Fetching password") res = helper.tryCommand( term, ["sfdx force:user:display -u {} --json".format(username)], False, False, False) if (not res[0]): jsonOutput = json.loads(res[1][0]) if ("password" in jsonOutput['result']): password = jsonOutput['result']['password'] if ("instanceUrl" in jsonOutput['result']): url = jsonOutput['result']['instanceUrl'].replace( 'https://', '').split('.cs')[0] login = helper.tryCommand( term, ["sfdx force:org:open -u {} -r --json".format(username)], False, True, False) if (not login[0]): loginJsonOutput = json.loads(login[1][0]) if ("url" in loginJsonOutput['result']): loginUrl = loginJsonOutput['result']['url'] pyperclip.copy(loginUrl) print( "\n URL: {}\n Username: {}\n Password: {}\n\n Instant login (copied to clipboard): \n{}\n" .format(url, username, password, loginUrl)) helper.pressToContinue(term)