def createScratchOrg_installUnlockedPackages(term): packages = None try: packages = helper.getDataFromJson("sfdx-project.json") if ("packageDirectories" not in packages): return False, [] packages = packages["packageDirectories"][0] if ("dependencies" not in packages): return False, [] packages = packages["dependencies"] except Exception as e: return True, [e] if (len(packages) == 0): return False, [] helper.startLoading("Installing unlocked packages from 'sfdx-project.json'") results = helper.tryCommand(None, ["echo y | sfdx plugins:install sfpowerkit"], False, False, False) if (results[0]): return results keysParam = '' path = helper.getConfig('locations.package-key') if (path is not None): packageKey = helper.getContentOfFile(path) if (packageKey == None): return True, ["{} file does not exists. Without it, packages cannot be installed. See Main Menu > Other > Add Package Key to add it.".format(path)] keys = getPackageKeys(packages, packageKey) keysParam = ' --installationkeys "{}"'.format(keys) cmd = 'sfdx sfpowerkit:package:dependencies:install -r -a -w 10' + keysParam results = helper.tryCommand(term, [cmd], True, True, False) return results
def createScratchOrg_importDummyData(): path = helper.getConfig('locations.dummy-data') if (path is None): return False, [] if (not helper.folderExists(path)): return True, ['Folder \'{}\' does not exists'.format(path)] path = path + '/' helper.startLoading("Importing dummy data") results = helper.tryCommand(None, ["echo y | sfdx plugins:install [email protected]"], False, False, False) if (results[0]): return results try: for folder in next(os.walk(path))[1]: if (folder.endswith(".out")): shutil.rmtree(path + folder) for folder in next(os.walk(path))[1]: cmd = 'sfdx wry:file:replace -i {} -o {}'.format(path + folder, path + folder + ".out") results = helper.tryCommand(None, [cmd], False, False, False) if (results[0]): return results for folder in next(os.walk(path))[1]: if (folder.endswith(".out")): cmd = 'sfdx force:data:tree:import --plan {}{}/plan.json'.format(path, folder) results = helper.tryCommand(None, [cmd], False, False, False) if (results[0]): return results helper.spinnerSuccess() except Exception as e: helper.log(cmd, e, 'ERROR') return True, [e] return False, []
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 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 createScratchOrg_assignPermsets(term): permsets = helper.getConfig('permsets_to_assign') if (permsets is None or not permsets): return False, [] helper.startLoading("Assigning configured permission sets") commands = [] for permset in permsets: commands.append("sfdx force:user:permset:assign -n " + permset) trysLeft = 12 while(permsetGroupsAreNotComplete(term)): trysLeft -= 1 if (trysLeft == 0): break helper.changeLoadingText("Assigning configured permission sets (waiting for groups to be updated. Trys left: {})".format(trysLeft)) time.sleep(20) results = helper.tryCommand(term, commands, True, False, False) helper.changeLoadingText("Assigned permission sets: {}".format(', '.join(permsets))) helper.spinnerSuccess() return results
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 createScratchOrg_createOrg(term, scratchOrgName): helper.startLoading("Creating new Scratch Org") results = helper.tryCommand(term, ["sfdx force:org:create " + "-f ./config/project-scratch-def.json " + "--setalias {} ".format(scratchOrgName) + "--durationdays 5 " + "--setdefaultusername"], True, True, False) return results
def createScratchOrg_pushNonDeployedMetadata(term): path = helper.getConfig('locations.unpackagable') if (path is None): return False, [] if (not helper.folderExists(path)): return True, ['Folder \'{}\' does not exists'.format(path)] helper.startLoading("Pushing unpackagable metadata") return helper.tryCommand(term, ["sfdx force:source:deploy -p " + path], True, True, False)
def permsetGroupsAreNotComplete(term): res = helper.tryCommand(term, ["sfdx force:apex:execute -f ./.ssdx/apex/validatePermsetGroups.cls --json"], False, False, False) if (not res[0]): try: jsonOutput = json.loads(res[1][0]) except: time.sleep(20) return True if ("logs" in jsonOutput['result']): log = jsonOutput['result']['logs'] amount = re.split("BEFORE(.*)AFTER", log)[3] return amount != '0' return false
def createScratchOrg_installManagedPackages(term): packages = helper.getConfig('managed_packages') if (packages is None or not packages): return False, [] if (len(packages) == 0): return False, [] helper.startLoading("Installing managed packages from 'ssdx-config.json'") commands = [] for package in packages: commands.append('sfdx force:package:install -r --publishwait 60 --wait 60 -p ' + package) results = helper.tryCommand(term, commands, True, True, False) return results
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 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)
def createScratchOrg_deletePreviousScratchOrg(term, deletePrevious): if (deletePrevious): helper.startLoading("Deleting default Scratch Org") error = helper.tryCommand(term, ["sfdx force:org:delete -p"], False, True, False)[0]
def openScratchOrg(term): helper.startLoading("Opening Scratch Org") helper.tryCommand(term, ["sfdx force:org:open"], True, True, False)[0] helper.pressToContinue(term)
def createScratchOrg_pushMetadata(term): helper.startLoading("Pushing metadata") return helper.tryCommand(term, ["sfdx force:source:push"], True, True, False)