File: C:/Users/fred/anaconda3/Lib/site-packages/anaconda_project/local_state_file.py
# -*- coding: utf-8 -*-
# -----------------------------------------------------------------------------
# Copyright (c) 2016, Anaconda, Inc. All rights reserved.
#
# Licensed under the terms of the BSD 3-Clause License.
# The full license is in the file LICENSE.txt, distributed with this software.
# -----------------------------------------------------------------------------
"""Project "local state" file loading and manipulation."""
from __future__ import absolute_import
import os
from anaconda_project.yaml_file import YamlFile
# these are in the order we'll use them if multiple are present
possible_local_state_file_names = ("anaconda-project-local.yml", "anaconda-project-local.yaml")
DEFAULT_LOCAL_STATE_FILENAME = possible_local_state_file_names[0]
SERVICE_RUN_STATES_SECTION = "service_run_states"
class LocalStateFile(YamlFile):
"""Represents the locally-configured/user-specific state of the project directory.
Project config that you might want in source control should be
in ``ProjectFile`` instead.
Be careful with creating your own instance of this class,
because you have to think about when other code might load or
save in a way that conflicts with your loads and saves.
"""
# The dummy entry works around a bug/quirk in ruamel.yaml that drops the
# top comment for an empty dictionary
template = '''
# Anaconda local project state (specific to this user/machine)
__dummy__: dummy
'''
@classmethod
def load_for_directory(cls, directory, scan_parents=True):
"""Load the project local state file from the given directory, even if it doesn't exist.
If the directory has no project file, the loaded
``LocalStateFile`` will be empty. It won't actually be
created on disk unless you call ``save()``.
If the local state file has syntax problems, the
``corrupted`` and ``corrupted_error_message`` properties
will be set and attempts to modify or save the file will
raise an exception.
Args:
directory (str): path to the project directory
Returns:
a new ``LocalStateFile``
"""
current_dir = directory
while current_dir != os.path.realpath(os.path.dirname(current_dir)):
for name in possible_local_state_file_names:
path = os.path.join(current_dir, name)
if os.path.isfile(path):
return LocalStateFile(path)
if scan_parents:
current_dir = os.path.dirname(os.path.abspath(current_dir))
continue
else:
break
# No file was found, create a new one
return LocalStateFile(os.path.join(directory, DEFAULT_LOCAL_STATE_FILENAME))
def set_service_run_state(self, service_name, state):
"""Set a dict value in the ``service_run_states`` section.
This is used to save the state of a running service, such as
its port or process ID.
Conventionally the state can also include a
``shutdown_commands`` property with a list of list of
strings value. The lists of strings are args to pass to
exec. In order to shut down a service, we run all
``shutdown_commands`` and then delete the entire service
run state dict.
This method does not save the file, call ``save()`` to do that.
Args:
service_name (str): environment variable identifying the service
state (dict): state for the running service process
"""
if not isinstance(state, dict):
raise ValueError("service state should be a dict")
self.set_value([SERVICE_RUN_STATES_SECTION, service_name], state)
def get_service_run_state(self, service_name):
"""Get the running instance state for a service.
Args:
service_name (str): environment variable identifying the service
Returns:
The state dict (empty dict if no state was saved)
"""
return self.get_value([SERVICE_RUN_STATES_SECTION, service_name], default=dict())
def get_all_service_run_states(self):
"""Get all saved service run states.
Returns the entire ``service_run_states`` section.
Returns:
a dict from service name to service state dict
"""
return self.get_value(SERVICE_RUN_STATES_SECTION, default=dict())