crytic_compile.platform.abstract_platform

Abstract Platform

This gives the skeleton for any platform supported by crytic-compile

  1"""
  2Abstract Platform
  3
  4This gives the skeleton for any platform supported by crytic-compile
  5"""
  6import abc
  7from typing import TYPE_CHECKING, List, Dict, Optional
  8from dataclasses import dataclass, field
  9
 10from crytic_compile.platform import Type
 11from crytic_compile.utils.unit_tests import guess_tests
 12
 13if TYPE_CHECKING:
 14    from crytic_compile import CryticCompile
 15
 16
 17class IncorrectPlatformInitialization(Exception):
 18    """
 19    Exception raises if a platform was not properly defined
 20    """
 21
 22    # pylint: disable=unnecessary-pass
 23    pass
 24
 25
 26# pylint: disable=too-many-instance-attributes
 27@dataclass
 28class PlatformConfig:
 29    """
 30    This class represents a generic platform configuration
 31    """
 32
 33    offline: bool = False
 34    remappings: Optional[str] = None
 35    solc_version: Optional[str] = None
 36    optimizer: bool = False
 37    optimizer_runs: Optional[int] = None
 38    via_ir: bool = False
 39    allow_paths: Optional[str] = None
 40    evm_version: Optional[str] = None
 41    src_path: str = "src"
 42    tests_path: str = "test"
 43    libs_path: List[str] = field(default_factory=lambda: ["lib"])
 44    scripts_path: str = "script"
 45    out_path: str = "out"
 46
 47
 48class AbstractPlatform(metaclass=abc.ABCMeta):
 49    """
 50    This is the abstract class for the platform
 51    """
 52
 53    NAME: str = ""
 54    PROJECT_URL: str = ""
 55    TYPE: Type = Type.NOT_IMPLEMENTED
 56
 57    HIDE = False  # True if the class is not meant for direct user manipulation
 58
 59    def __init__(self, target: str, **_kwargs: str):
 60        """Init the object
 61
 62        Args:
 63            target (str): path to the target
 64            **_kwargs: optional arguments.
 65
 66        Raises:
 67            IncorrectPlatformInitialization: If the Platform was not correctly designed
 68        """
 69        if not self.NAME:
 70            raise IncorrectPlatformInitialization(
 71                f"NAME is not initialized {self.__class__.__name__}"
 72            )
 73
 74        if not self.PROJECT_URL:
 75            raise IncorrectPlatformInitialization(
 76                f"PROJECT_URL is not initialized {self.__class__.__name__}"
 77            )
 78
 79        if self.TYPE == Type.NOT_IMPLEMENTED:
 80            raise IncorrectPlatformInitialization(
 81                f"TYPE is not initialized {self.__class__.__name__}"
 82            )
 83
 84        self._target: str = target
 85        self._cached_dependencies: Dict[str, bool] = {}
 86
 87    # region Properties.
 88    ###################################################################################
 89    ###################################################################################
 90    # The properties might be different from the class value
 91    # For example the archive will return the underlying platform values
 92    @property
 93    def target(self) -> str:
 94        """Return the target name
 95
 96        Returns:
 97            str: The target name
 98        """
 99        return self._target
100
101    @property
102    def platform_name_used(self) -> str:
103        """Return the name of the underlying platform used
104
105        Returns:
106            str: The name of the underlying platform used
107        """
108        return self.NAME
109
110    @property
111    def platform_project_url_used(self) -> str:
112        """Return the underlying platform project 's url
113
114        Returns:
115            str: Underlying platform project 's url
116        """
117        return self.PROJECT_URL
118
119    @property
120    def platform_type_used(self) -> Type:
121        """Return the type of the underlying platform used
122
123        Returns:
124            Type: [description]
125        """
126        return self.TYPE
127
128    # endregion
129    ###################################################################################
130    ###################################################################################
131    # region Abstract methods
132    ###################################################################################
133    ###################################################################################
134
135    @abc.abstractmethod
136    def compile(self, crytic_compile: "CryticCompile", **kwargs: str) -> None:
137        """Run the compilation
138
139        Args:
140            crytic_compile (CryticCompile): CryticCompile object associated with the platform
141            **kwargs: optional arguments.
142        """
143        return
144
145    @abc.abstractmethod
146    def clean(self, **kwargs: str) -> None:
147        """Clean compilation artifacts
148
149        Args:
150            **kwargs: optional arguments.
151        """
152        return
153
154    @staticmethod
155    @abc.abstractmethod
156    def is_supported(target: str, **kwargs: str) -> bool:
157        """Check if the target is a project supported by this platform
158
159        Args:
160            target (str): path to the target
161            **kwargs: optional arguments. Used: "dapp_ignore"
162
163        Returns:
164            bool: True if the target is supported
165        """
166        return False
167
168    @abc.abstractmethod
169    def is_dependency(self, path: str) -> bool:
170        """Check if the target is a dependency
171
172        Args:
173            path (str): path to the target
174
175        Returns:
176            bool: True if the target is a dependency
177        """
178        return False
179
180    @staticmethod
181    def config(working_dir: str) -> Optional[PlatformConfig]:  # pylint: disable=unused-argument
182        """Return configuration data that should be passed to solc, such as version, remappings ecc.
183
184        Args:
185            working_dir (str): path to the target
186
187        Returns:
188            Optional[PlatformConfig]: Platform configuration data such as optimization, remappings...
189        """
190        return None
191
192    # Only _guessed_tests is an abstract method
193    # guessed_tests will call the generic guess_tests and appends to the list
194    # platforms-dependent tests
195    @abc.abstractmethod
196    def _guessed_tests(self) -> List[str]:
197        """Guess the potential unit tests commands
198
199        Returns:
200            List[str]: list of potential unit tests commands
201        """
202        return []
203
204    def guessed_tests(self) -> List[str]:
205        """Guess the potential unit tests commands
206
207        Returns:
208            List[str]: list of potential unit tests commands
209        """
210        return guess_tests(self._target) + self._guessed_tests()
211
212    # endregion
213    ###################################################################################
214    ###################################################################################
class IncorrectPlatformInitialization(builtins.Exception):
18class IncorrectPlatformInitialization(Exception):
19    """
20    Exception raises if a platform was not properly defined
21    """
22
23    # pylint: disable=unnecessary-pass
24    pass

Exception raises if a platform was not properly defined

Inherited Members
builtins.Exception
Exception
builtins.BaseException
with_traceback
args
class PlatformConfig:
29class PlatformConfig:
30    """
31    This class represents a generic platform configuration
32    """
33
34    offline: bool = False
35    remappings: Optional[str] = None
36    solc_version: Optional[str] = None
37    optimizer: bool = False
38    optimizer_runs: Optional[int] = None
39    via_ir: bool = False
40    allow_paths: Optional[str] = None
41    evm_version: Optional[str] = None
42    src_path: str = "src"
43    tests_path: str = "test"
44    libs_path: List[str] = field(default_factory=lambda: ["lib"])
45    scripts_path: str = "script"
46    out_path: str = "out"

This class represents a generic platform configuration

PlatformConfig( offline: bool = False, remappings: Union[str, NoneType] = None, solc_version: Union[str, NoneType] = None, optimizer: bool = False, optimizer_runs: Union[int, NoneType] = None, via_ir: bool = False, allow_paths: Union[str, NoneType] = None, evm_version: Union[str, NoneType] = None, src_path: str = 'src', tests_path: str = 'test', libs_path: List[str] = <factory>, scripts_path: str = 'script', out_path: str = 'out')
offline: bool = False
remappings: Union[str, NoneType] = None
solc_version: Union[str, NoneType] = None
optimizer: bool = False
optimizer_runs: Union[int, NoneType] = None
via_ir: bool = False
allow_paths: Union[str, NoneType] = None
evm_version: Union[str, NoneType] = None
src_path: str = 'src'
tests_path: str = 'test'
libs_path: List[str]
scripts_path: str = 'script'
out_path: str = 'out'
class AbstractPlatform:
 49class AbstractPlatform(metaclass=abc.ABCMeta):
 50    """
 51    This is the abstract class for the platform
 52    """
 53
 54    NAME: str = ""
 55    PROJECT_URL: str = ""
 56    TYPE: Type = Type.NOT_IMPLEMENTED
 57
 58    HIDE = False  # True if the class is not meant for direct user manipulation
 59
 60    def __init__(self, target: str, **_kwargs: str):
 61        """Init the object
 62
 63        Args:
 64            target (str): path to the target
 65            **_kwargs: optional arguments.
 66
 67        Raises:
 68            IncorrectPlatformInitialization: If the Platform was not correctly designed
 69        """
 70        if not self.NAME:
 71            raise IncorrectPlatformInitialization(
 72                f"NAME is not initialized {self.__class__.__name__}"
 73            )
 74
 75        if not self.PROJECT_URL:
 76            raise IncorrectPlatformInitialization(
 77                f"PROJECT_URL is not initialized {self.__class__.__name__}"
 78            )
 79
 80        if self.TYPE == Type.NOT_IMPLEMENTED:
 81            raise IncorrectPlatformInitialization(
 82                f"TYPE is not initialized {self.__class__.__name__}"
 83            )
 84
 85        self._target: str = target
 86        self._cached_dependencies: Dict[str, bool] = {}
 87
 88    # region Properties.
 89    ###################################################################################
 90    ###################################################################################
 91    # The properties might be different from the class value
 92    # For example the archive will return the underlying platform values
 93    @property
 94    def target(self) -> str:
 95        """Return the target name
 96
 97        Returns:
 98            str: The target name
 99        """
100        return self._target
101
102    @property
103    def platform_name_used(self) -> str:
104        """Return the name of the underlying platform used
105
106        Returns:
107            str: The name of the underlying platform used
108        """
109        return self.NAME
110
111    @property
112    def platform_project_url_used(self) -> str:
113        """Return the underlying platform project 's url
114
115        Returns:
116            str: Underlying platform project 's url
117        """
118        return self.PROJECT_URL
119
120    @property
121    def platform_type_used(self) -> Type:
122        """Return the type of the underlying platform used
123
124        Returns:
125            Type: [description]
126        """
127        return self.TYPE
128
129    # endregion
130    ###################################################################################
131    ###################################################################################
132    # region Abstract methods
133    ###################################################################################
134    ###################################################################################
135
136    @abc.abstractmethod
137    def compile(self, crytic_compile: "CryticCompile", **kwargs: str) -> None:
138        """Run the compilation
139
140        Args:
141            crytic_compile (CryticCompile): CryticCompile object associated with the platform
142            **kwargs: optional arguments.
143        """
144        return
145
146    @abc.abstractmethod
147    def clean(self, **kwargs: str) -> None:
148        """Clean compilation artifacts
149
150        Args:
151            **kwargs: optional arguments.
152        """
153        return
154
155    @staticmethod
156    @abc.abstractmethod
157    def is_supported(target: str, **kwargs: str) -> bool:
158        """Check if the target is a project supported by this platform
159
160        Args:
161            target (str): path to the target
162            **kwargs: optional arguments. Used: "dapp_ignore"
163
164        Returns:
165            bool: True if the target is supported
166        """
167        return False
168
169    @abc.abstractmethod
170    def is_dependency(self, path: str) -> bool:
171        """Check if the target is a dependency
172
173        Args:
174            path (str): path to the target
175
176        Returns:
177            bool: True if the target is a dependency
178        """
179        return False
180
181    @staticmethod
182    def config(working_dir: str) -> Optional[PlatformConfig]:  # pylint: disable=unused-argument
183        """Return configuration data that should be passed to solc, such as version, remappings ecc.
184
185        Args:
186            working_dir (str): path to the target
187
188        Returns:
189            Optional[PlatformConfig]: Platform configuration data such as optimization, remappings...
190        """
191        return None
192
193    # Only _guessed_tests is an abstract method
194    # guessed_tests will call the generic guess_tests and appends to the list
195    # platforms-dependent tests
196    @abc.abstractmethod
197    def _guessed_tests(self) -> List[str]:
198        """Guess the potential unit tests commands
199
200        Returns:
201            List[str]: list of potential unit tests commands
202        """
203        return []
204
205    def guessed_tests(self) -> List[str]:
206        """Guess the potential unit tests commands
207
208        Returns:
209            List[str]: list of potential unit tests commands
210        """
211        return guess_tests(self._target) + self._guessed_tests()
212
213    # endregion
214    ###################################################################################
215    ###################################################################################

This is the abstract class for the platform

AbstractPlatform(target: str, **_kwargs: str)
60    def __init__(self, target: str, **_kwargs: str):
61        """Init the object
62
63        Args:
64            target (str): path to the target
65            **_kwargs: optional arguments.
66
67        Raises:
68            IncorrectPlatformInitialization: If the Platform was not correctly designed
69        """
70        if not self.NAME:
71            raise IncorrectPlatformInitialization(
72                f"NAME is not initialized {self.__class__.__name__}"
73            )
74
75        if not self.PROJECT_URL:
76            raise IncorrectPlatformInitialization(
77                f"PROJECT_URL is not initialized {self.__class__.__name__}"
78            )
79
80        if self.TYPE == Type.NOT_IMPLEMENTED:
81            raise IncorrectPlatformInitialization(
82                f"TYPE is not initialized {self.__class__.__name__}"
83            )
84
85        self._target: str = target
86        self._cached_dependencies: Dict[str, bool] = {}

Init the object

Args: target (str): path to the target **_kwargs: optional arguments.

Raises: IncorrectPlatformInitialization: If the Platform was not correctly designed

NAME: str = ''
PROJECT_URL: str = ''
TYPE: crytic_compile.platform.types.Type = <Type.NOT_IMPLEMENTED: 0>
HIDE = False
target: str
 93    @property
 94    def target(self) -> str:
 95        """Return the target name
 96
 97        Returns:
 98            str: The target name
 99        """
100        return self._target

Return the target name

Returns: str: The target name

platform_name_used: str
102    @property
103    def platform_name_used(self) -> str:
104        """Return the name of the underlying platform used
105
106        Returns:
107            str: The name of the underlying platform used
108        """
109        return self.NAME

Return the name of the underlying platform used

Returns: str: The name of the underlying platform used

platform_project_url_used: str
111    @property
112    def platform_project_url_used(self) -> str:
113        """Return the underlying platform project 's url
114
115        Returns:
116            str: Underlying platform project 's url
117        """
118        return self.PROJECT_URL

Return the underlying platform project 's url

Returns: str: Underlying platform project 's url

platform_type_used: crytic_compile.platform.types.Type
120    @property
121    def platform_type_used(self) -> Type:
122        """Return the type of the underlying platform used
123
124        Returns:
125            Type: [description]
126        """
127        return self.TYPE

Return the type of the underlying platform used

Returns: Type: [description]

@abc.abstractmethod
def compile( self, crytic_compile: crytic_compile.crytic_compile.CryticCompile, **kwargs: str) -> None:
136    @abc.abstractmethod
137    def compile(self, crytic_compile: "CryticCompile", **kwargs: str) -> None:
138        """Run the compilation
139
140        Args:
141            crytic_compile (CryticCompile): CryticCompile object associated with the platform
142            **kwargs: optional arguments.
143        """
144        return

Run the compilation

Args: crytic_compile (CryticCompile): CryticCompile object associated with the platform **kwargs: optional arguments.

@abc.abstractmethod
def clean(self, **kwargs: str) -> None:
146    @abc.abstractmethod
147    def clean(self, **kwargs: str) -> None:
148        """Clean compilation artifacts
149
150        Args:
151            **kwargs: optional arguments.
152        """
153        return

Clean compilation artifacts

Args: **kwargs: optional arguments.

@staticmethod
@abc.abstractmethod
def is_supported(target: str, **kwargs: str) -> bool:
155    @staticmethod
156    @abc.abstractmethod
157    def is_supported(target: str, **kwargs: str) -> bool:
158        """Check if the target is a project supported by this platform
159
160        Args:
161            target (str): path to the target
162            **kwargs: optional arguments. Used: "dapp_ignore"
163
164        Returns:
165            bool: True if the target is supported
166        """
167        return False

Check if the target is a project supported by this platform

Args: target (str): path to the target **kwargs: optional arguments. Used: "dapp_ignore"

Returns: bool: True if the target is supported

@abc.abstractmethod
def is_dependency(self, path: str) -> bool:
169    @abc.abstractmethod
170    def is_dependency(self, path: str) -> bool:
171        """Check if the target is a dependency
172
173        Args:
174            path (str): path to the target
175
176        Returns:
177            bool: True if the target is a dependency
178        """
179        return False

Check if the target is a dependency

Args: path (str): path to the target

Returns: bool: True if the target is a dependency

@staticmethod
def config( working_dir: str) -> Union[PlatformConfig, NoneType]:
181    @staticmethod
182    def config(working_dir: str) -> Optional[PlatformConfig]:  # pylint: disable=unused-argument
183        """Return configuration data that should be passed to solc, such as version, remappings ecc.
184
185        Args:
186            working_dir (str): path to the target
187
188        Returns:
189            Optional[PlatformConfig]: Platform configuration data such as optimization, remappings...
190        """
191        return None

Return configuration data that should be passed to solc, such as version, remappings ecc.

Args: working_dir (str): path to the target

Returns: Optional[PlatformConfig]: Platform configuration data such as optimization, remappings...

def guessed_tests(self) -> List[str]:
205    def guessed_tests(self) -> List[str]:
206        """Guess the potential unit tests commands
207
208        Returns:
209            List[str]: list of potential unit tests commands
210        """
211        return guess_tests(self._target) + self._guessed_tests()

Guess the potential unit tests commands

Returns: List[str]: list of potential unit tests commands