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

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')
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'
class AbstractPlatform:
 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    ###################################################################################

This is the abstract class for the platform

AbstractPlatform(target: str, **_kwargs: str)
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] = {}

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

Return the target name

Returns: str: The target name

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

Return the name of the underlying platform used

Returns: str: The name of the underlying platform used

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

Return the underlying platform project 's url

Returns: str: Underlying platform project 's url

platform_type_used: crytic_compile.platform.types.Type
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

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

Run the compilation

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

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

Clean compilation artifacts

Args: **kwargs: optional arguments.

@staticmethod
@abc.abstractmethod
def is_supported(target: str, **kwargs: str) -> bool:
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

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

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

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]:
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()

Guess the potential unit tests commands

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