Source code for solitude.factory

# Copyright (c) 2019, Solitude Developers
#
# This source code is licensed under the BSD-3-Clause license found in the
# COPYING file in the root directory of this source tree

from solitude.common.config_util import (
    parse_server_account, parse_path)
from solitude.errors import SetupError


class ToolsManager:
    def __init__(self, cfg: dict):
        from solitude.tools import Tool, GanacheCli, Solc, EthLint
        self._cfg = cfg
        self._tooldir = parse_path(self._cfg["Tools.Directory"])
        self._tools = {tool_name: None for tool_name in self._cfg["Tools.Required"]}

        self._create_tool_if_required(
            "Solc", Solc, "Tools.Solc.Version")
        self._create_tool_if_required(
            "GanacheCli", GanacheCli, "Tools.GanacheCli.Version")
        self._create_tool_if_required(
            "EthLint", EthLint, "Tools.EthLint.Version")

    def _create_tool_if_required(self, tool_name, tool_class, tool_version_field):
        if tool_name in self._tools:
            tool_version = self._cfg[tool_version_field]
            tool = tool_class(self._tooldir, version=tool_version)
            if not tool.have():
                raise SetupError(
                    "Tool '%s-%s' is required but not installed. Run 'solitude install'" % (
                        tool_name, tool_version))
            self._tools[tool_name] = tool

    def get(self, tool_name):
        try:
            return self._tools[tool_name]
        except KeyError:
            raise SetupError(
                "Tool '%s' is not in the requirements for this project" % tool_name)

    def get_required(self):
        return list(self._tools)

    def have(self, name):
        return name in self._tools


[docs]class Factory: """Create a Factory object The Factory object can be used to create pre-configured objects from a solitude configuration dictionary. :param cfg: solitude configuration dictionary """
[docs] def __init__(self, cfg): self._cfg = cfg self._tools = ToolsManager(cfg)
[docs] def create_compiler(self) -> "Compiler": from solitude.compiler import Compiler """Create a Compiler object, used to compile contracts with solc. :param add_contract_dir: whether to load contracts from the directory specified in Compiler.ContractDir or not """ compiler = Compiler( executable=self._tools.get("Solc").get("solc"), optimize=self._cfg["Compiler.Optimize"]) return compiler
[docs] def create_server(self) -> "ETHTestServer": """Create a ETHTestServer object, used to start a ganache test node. """ from solitude.server import ETHTestServer return ETHTestServer( executable=self._tools.get("GanacheCli").get("ganache-cli"), port=self._cfg["Server.Port"], host=self._cfg["Server.Host"], gasprice=self._cfg["Server.GasPrice"], gaslimit=self._cfg["Server.GasLimit"], accounts=[parse_server_account(account) for account in self._cfg["Server.Accounts"]])
[docs] def create_client(self, endpoint=None) -> "ETHClient": """Create a ETHClient object, used to interact with an ethereum node. :param endpoint: if set, it overrides the Client.Endpoint setting in the configuration """ from solitude.client import ETHClient if endpoint is None: endpoint = self._cfg["Client.Endpoint"] client = ETHClient(endpoint=endpoint) client.set_default_gaslimit(self._cfg["Client.GasLimit"]) client.set_default_gasprice(self._cfg["Client.GasPrice"]) return client
[docs] def create_linter(self, add_contract_dir=False) -> "Linter": """Create a Linter object, used to invoke solium. :param add_contract_dir: whether to load contracts from the directory specified in Compiler.ContractDir or not """ from solitude.linter import Linter linter = Linter( executable=self._tools.get("EthLint").get("solium"), plugins=self._cfg["Linter.Plugins"], rules=self._cfg["Linter.Rules"]) return linter
[docs] def get_sourcelist(self) -> "ContractSourceList": from solitude.common.contract_sourcelist import ContractSourceList source_dir = self._cfg["Project.SourceDir"] sources = ContractSourceList() if source_dir is not None: sources.add_directory(source_dir) return sources
[docs] def get_objectlist(self) -> "ContractObjectList": from solitude.common.contract_objectlist import ContractObjectList object_dir = self._cfg["Project.ObjectDir"] objects = ContractObjectList() if object_dir is not None: objects.add_directory(object_dir) return objects
[docs] def get_project_name(self): return self._cfg["Project.Name"]
[docs] def get_required(self): return self._tools.get_required()