+ """
+ Represents a deployment of an autoinstall, e.g. directory in a user's
+ web_scripts that has ``.scripts`` directory or ``.scripts-version``
+ file in it. Supply ``version`` with an :class:`ApplicationVersion` only if
+ you were reading from the :term:`versions store` and care about
+ speed (data from there can be stale).
+ """
+ #: Absolute path to the deployment
+ location = None
+ def __init__(self, location, version=None):
+ self.location = os.path.abspath(location)
+ self._app_version = version
+ # some cache variables
+ self._read_cache = {}
+ self._old_log = None
+ def read(self, file, force = False):
+ """
+ Reads a file's contents, possibly from cache unless ``force``
+ is ``True``.
+ """
+ if force or file not in self._read_cache:
+ f = open(os.path.join(self.location, file))
+ self._read_cache[file] = f.read()
+ f.close()
+ return self._read_cache[file]
+ def extract(self):
+ """
+ Extracts all the values of all variables from deployment.
+ These variables may be used for parametrizing generic parent
+ commits and include things such as database access credentials
+ and local configuration.
+ """
+ return self.application.extract(self)
+ def parametrize(self, dir):
+ """
+ Edits files in ``dir`` to replace WIZARD_* variables with literal
+ instances. This is used for constructing virtual merge bases, and
+ as such dir will generally not equal :attr:`location`.
+ """
+ return self.application.parametrize(self, dir)
+ def prepareConfig(self):
+ """
+ Edits files in the deployment such that any user-specific configuration
+ is replaced with generic WIZARD_* variables.
+ """
+ return self.application.prepareConfig(self)
+ def checkConfig(self, deployment):
+ """
+ Checks if the application is configured.
+ """
+ raise NotImplemented
+ @property
+ def configured(self):
+ """Whether or not an autoinstall has been configured/installed for use."""
+ return self.application.checkConfig(self)
+ @property
+ def migrated(self):
+ """Whether or not the autoinstalls has been migrated."""
+ return os.path.isdir(self.scripts_dir)
+ @property
+ def scripts_dir(self):
+ """The absolute path of the ``.scripts`` directory."""
+ return os.path.join(self.location, '.scripts')
+ @property
+ def old_version_file(self):
+ """
+ The absolute path of either ``.scripts-version`` (for unmigrated
+ installs) or ``.scripts/version``.
+
+ .. note::
+
+ Use of this is discouraged for migrated installs.
+ """
+ return os.path.join(self.location, '.scripts-version')
+ @property
+ def version_file(self):
+ """The absolute path of the ``.scripts/version`` file."""
+ return os.path.join(self.scripts_dir, 'version')
+ @property
+ def application(self):
+ """The :class:`Application` of this deployment."""
+ return self.app_version.application
+ @property
+ def old_log(self):
+ """
+ The :class:`wizard.old_log.Log` of this deployment. This
+ is only applicable to un-migrated autoinstalls.
+ """
+ if not self._old_log:
+ self._old_log = old_log.DeployLog.load(self)
+ return self._old_log
+ @property
+ def version(self):
+ """
+ The :class:`distutils.version.LooseVersion` of this
+ deployment.
+ """
+ return self.app_version.version
+ @property
+ def app_version(self):
+ """The :class:`ApplicationVersion` of this deployment."""
+ if not self._app_version:
+ if os.path.isdir(os.path.join(self.location, ".git")):
+ try:
+ with util.ChangeDirectory(self.location):
+ appname, _, version = git.describe().partition('-')
+ self._app_version = ApplicationVersion.make(appname, version)
+ except shell.CallError:
+ pass
+ if not self._app_version:
+ self._app_version = self.old_log[-1].version
+ return self._app_version