<commit_before>from __future__ import unicode_literals
import datetime
import json
import os
import re

import sarge
from simple_salesforce import Salesforce

from cumulusci.utils import get_git_config
from cumulusci.core.sfdx import sfdx
from cumulusci.core.config import FAILED_TO_CREATE_SCRATCH_ORG
from cumulusci.core.config import OrgConfig
from cumulusci.core.exceptions import ScratchOrgException


class ScratchOrgConfig(OrgConfig):
    """ Salesforce DX Scratch org configuration """

    @property
    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")

        username = self.config.get("username")
        if not username:
            raise ScratchOrgException(
                "SFDX claimed to be successful but there was no username "
                "in the output...maybe there was a gack?"
            )

        # Call force:org:display and parse output to get instance_url and
        # access_token
        p = sfdx("force:org:display --json", self.username)

        org_info = None
        stderr_list = [line.strip() for line in p.stderr_text]
        stdout_list = [line.strip() for line in p.stdout_text]

        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:
            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

    @property
    def access_token(self):
        return self.scratch_info["access_token"]

    @property
    def instance_url(self):
        return self.config.get("instance_url") or self.scratch_info["instance_url"]

    @property
    def org_id(self):
        org_id = self.config.get("org_id")
        if not org_id:
            org_id = self.scratch_info["org_id"]
        return org_id

    @property
    def user_id(self):
        if not self.config.get("user_id"):
            sf = Salesforce(
                instance=self.instance_url.replace("https://", ""),
                session_id=self.access_token,
                version="38.0",
            )
            result = sf.query_all(
                "SELECT Id FROM User WHERE UserName='{}'".format(self.username)
            )
            self.config["user_id"] = result["records"][0]["Id"]
        return self.config["user_id"]

    @property
    def username(self):
        username = self.config.get("username")
        if not username:
            username = self.scratch_info["username"]
        return username

    @property
    def password(self):
        password = self.config.get("password")
        if not password:
            password = self.scratch_info["password"]
        return password

    @property
    def email_address(self):
        email_address = self.config.get("email_address")
        if not email_address:
            email_address = get_git_config("user.email")
            self.config["email_address"] = email_address

        return email_address

    @property
    def days(self):
        return self.config.setdefault("days", 1)

    @property
    def alive(self):
        """Check if an org is alive"""
        return self.date_created and not self.expired

    @property
    def expired(self):
        """Check if an org has already expired"""<commit_msg>Rename method per PR comment<commit_after>from __future__ import unicode_literals
import datetime
import json
import os
import re

import sarge
from simple_salesforce import Salesforce

from cumulusci.utils import get_git_config
from cumulusci.core.sfdx import sfdx
from cumulusci.core.config import FAILED_TO_CREATE_SCRATCH_ORG
from cumulusci.core.config import OrgConfig
from cumulusci.core.exceptions import ScratchOrgException


class ScratchOrgConfig(OrgConfig):
    """ Salesforce DX Scratch org configuration """

    @property
    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")

        username = self.config.get("username")
        if not username:
            raise ScratchOrgException(
                "SFDX claimed to be successful but there was no username "
                "in the output...maybe there was a gack?"
            )

        # Call force:org:display and parse output to get instance_url and
        # access_token
        p = sfdx("force:org:display --json", self.username)

        org_info = None
        stderr_list = [line.strip() for line in p.stderr_text]
        stdout_list = [line.strip() for line in p.stdout_text]

        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:
            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.<PASSWORD>("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

    @property
    def access_token(self):
        return self.scratch_info["access_token"]

    @property
    def instance_url(self):
        return self.config.get("instance_url") or self.scratch_info["instance_url"]

    @property
    def org_id(self):
        org_id = self.config.get("org_id")
        if not org_id:
            org_id = self.scratch_info["org_id"]
        return org_id

    @property
    def user_id(self):
        if not self.config.get("user_id"):
            sf = Salesforce(
                instance=self.instance_url.replace("https://", ""),
                session_id=self.access_token,
                version="38.0",
            )
            result = sf.query_all(
                "SELECT Id FROM User WHERE UserName='{}'".format(self.username)
            )
            self.config["user_id"] = result["records"][0]["Id"]
        return self.config["user_id"]

    @property
    def username(self):
        username = self.config.get("username")
        if not username:
            username = self.scratch_info["username"]
        return username

    @property
    def password(self):
        password = self.config.get("password")
        if not password:
            password = self.scratch_info["password"]
        return password

    @property
    def email_address(self):
        email_address = self.config.get("email_address")
        if not email_address:
            email_address = get_git_config("user.email")
            self.config["email_address"] = email_address

        return email_address

    @property
    def days(self):
        return self.config.setdefault("days", 1)

    @property
    def active(self):
        """Check if an org is alive"""
        return self.date_created and not self.expired

    @property
    def expired(self):
        """Check if an org has already expired"""
{'fraction_non_alphanumeric': 0.10571369636963697, 'fraction_numerical': 0.0012376237623762376, 'mean_word_length': 2.1220218931101096, 'pattern_counts': {'":': 10, '<': 4, '<?xml version=': 0, '>': 4, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '239282', 'n_tokens_mistral': 2745, 'n_tokens_neox': 2653, 'n_words': 645}