crytic_compile.platform.archive

Archive platform. It is similar to the standard platform, except that the file generated contains a "source_content" field Which is a map: filename -> sourcecode

  1"""
  2Archive platform.
  3It is similar to the standard platform, except that the file generated
  4contains a "source_content" field
  5Which is a map: filename -> sourcecode
  6"""
  7import json
  8import os
  9from pathlib import Path
 10from typing import TYPE_CHECKING, Dict, List, Tuple, Type, Any
 11
 12from crytic_compile.platform import Type as TypePlatform
 13from crytic_compile.platform import standard
 14
 15# Cycle dependency
 16from crytic_compile.platform.abstract_platform import AbstractPlatform
 17
 18if TYPE_CHECKING:
 19    from crytic_compile import CryticCompile
 20
 21
 22def export_to_archive(crytic_compile: "CryticCompile", **kwargs: Any) -> List[str]:
 23    """Export the archive
 24
 25    Args:
 26        crytic_compile (CryticCompile): CryticCompile containing the compilation units to export
 27        **kwargs: optional arguments. Used: "export_dir"
 28
 29    Returns:
 30        List[str]: List of the generated archive files
 31    """
 32    # Obtain objects to represent each contract
 33
 34    output, target = generate_archive_export(crytic_compile)
 35
 36    export_dir: str = kwargs.get("export_dir", "crytic-export")
 37
 38    if not os.path.exists(export_dir):
 39        os.makedirs(export_dir)
 40
 41    path = os.path.join(export_dir, target)
 42    with open(path, "w", encoding="utf8") as f_path:
 43        json.dump(output, f_path)
 44
 45    return [path]
 46
 47
 48class Archive(AbstractPlatform):
 49    """
 50    Archive platform. It is similar to the Standard platform, but contains also the source code
 51    """
 52
 53    NAME = "Archive"
 54    PROJECT_URL = "https://github.com/crytic/crytic-compile"
 55    TYPE = TypePlatform.ARCHIVE
 56
 57    HIDE = True
 58
 59    def __init__(self, target: str, **kwargs: str):
 60        """Initializes an object which represents solc standard json
 61
 62        Args:
 63            target (str): The path to the standard json
 64            **kwargs: optional arguments.
 65        """
 66        super().__init__(target, **kwargs)
 67        self._underlying_platform: Type[AbstractPlatform] = Archive
 68        self._unit_tests: List[str] = []
 69
 70    def compile(self, crytic_compile: "CryticCompile", **_kwargs: str) -> None:
 71        """Run the compilation
 72
 73        Args:
 74            crytic_compile (CryticCompile): associated CryticCompile object
 75            **_kwargs: unused
 76        """
 77        # pylint: disable=import-outside-toplevel
 78        from crytic_compile.crytic_compile import get_platforms
 79
 80        try:
 81            if isinstance(self._target, str) and os.path.isfile(self._target):
 82                with open(self._target, encoding="utf8") as f_target:
 83                    loaded_json = json.load(f_target)
 84            else:
 85                loaded_json = json.loads(self._target)
 86        except (OSError, ValueError):
 87            # Can happen if the target is a very large string, isfile will throw an exception
 88            loaded_json = json.loads(self._target)
 89
 90        (underlying_type, unit_tests) = standard.load_from_compile(crytic_compile, loaded_json)
 91        underlying_type = TypePlatform(underlying_type)
 92        platforms: List[Type[AbstractPlatform]] = get_platforms()
 93        platform = next((p for p in platforms if p.TYPE == underlying_type), Archive)
 94        self._underlying_platform = platform
 95        self._unit_tests = unit_tests
 96        self._target = "tmp.zip"
 97
 98        crytic_compile.src_content = loaded_json["source_content"]
 99
100    def clean(self, **_kwargs: str) -> None:
101        pass
102
103    @staticmethod
104    def is_supported(target: str, **kwargs: str) -> bool:
105        """Check if the target is an archive
106
107        Args:
108            target (str): path to the target
109            **kwargs: optional arguments. Used: "standard_ignore"
110
111        Returns:
112            bool: True if the target is an archive
113        """
114        archive_ignore = kwargs.get("standard_ignore", False)
115        if archive_ignore:
116            return False
117        if not Path(target).parts:
118            return False
119        return Path(target).parts[-1].endswith("_export_archive.json")
120
121    def is_dependency(self, _path: str) -> bool:
122        """Check if the _path is a dependency. Always false
123
124        Args:
125            _path (str): path to the target
126
127        Returns:
128            bool: Always false - the archive checks are handled by crytic_compile_dependencies
129        """
130        # TODO: check if its correctly handled by crytic_compile_dependencies
131        return False
132
133    def _guessed_tests(self) -> List[str]:
134        """Return the list of guessed unit tests commands
135
136        Returns:
137            List[str]: Guessed unit tests commands
138        """
139        return self._unit_tests
140
141
142def generate_archive_export(crytic_compile: "CryticCompile") -> Tuple[Dict, str]:
143    """Generate the archive export
144
145    Args:
146        crytic_compile (CryticCompile): CryticCompile object to export
147
148    Returns:
149        Tuple[Dict, str]: The dict is the exported archive, and the str the filename
150    """
151    output = standard.generate_standard_export(crytic_compile)
152    output["source_content"] = crytic_compile.src_content
153
154    target = crytic_compile.target
155    target = "contracts" if os.path.isdir(target) else Path(target).parts[-1]
156    target = f"{target}_export_archive.json"
157
158    return output, target
def export_to_archive( crytic_compile: crytic_compile.crytic_compile.CryticCompile, **kwargs: Any) -> List[str]:
23def export_to_archive(crytic_compile: "CryticCompile", **kwargs: Any) -> List[str]:
24    """Export the archive
25
26    Args:
27        crytic_compile (CryticCompile): CryticCompile containing the compilation units to export
28        **kwargs: optional arguments. Used: "export_dir"
29
30    Returns:
31        List[str]: List of the generated archive files
32    """
33    # Obtain objects to represent each contract
34
35    output, target = generate_archive_export(crytic_compile)
36
37    export_dir: str = kwargs.get("export_dir", "crytic-export")
38
39    if not os.path.exists(export_dir):
40        os.makedirs(export_dir)
41
42    path = os.path.join(export_dir, target)
43    with open(path, "w", encoding="utf8") as f_path:
44        json.dump(output, f_path)
45
46    return [path]

Export the archive

Args: crytic_compile (CryticCompile): CryticCompile containing the compilation units to export **kwargs: optional arguments. Used: "export_dir"

Returns: List[str]: List of the generated archive files

 49class Archive(AbstractPlatform):
 50    """
 51    Archive platform. It is similar to the Standard platform, but contains also the source code
 52    """
 53
 54    NAME = "Archive"
 55    PROJECT_URL = "https://github.com/crytic/crytic-compile"
 56    TYPE = TypePlatform.ARCHIVE
 57
 58    HIDE = True
 59
 60    def __init__(self, target: str, **kwargs: str):
 61        """Initializes an object which represents solc standard json
 62
 63        Args:
 64            target (str): The path to the standard json
 65            **kwargs: optional arguments.
 66        """
 67        super().__init__(target, **kwargs)
 68        self._underlying_platform: Type[AbstractPlatform] = Archive
 69        self._unit_tests: List[str] = []
 70
 71    def compile(self, crytic_compile: "CryticCompile", **_kwargs: str) -> None:
 72        """Run the compilation
 73
 74        Args:
 75            crytic_compile (CryticCompile): associated CryticCompile object
 76            **_kwargs: unused
 77        """
 78        # pylint: disable=import-outside-toplevel
 79        from crytic_compile.crytic_compile import get_platforms
 80
 81        try:
 82            if isinstance(self._target, str) and os.path.isfile(self._target):
 83                with open(self._target, encoding="utf8") as f_target:
 84                    loaded_json = json.load(f_target)
 85            else:
 86                loaded_json = json.loads(self._target)
 87        except (OSError, ValueError):
 88            # Can happen if the target is a very large string, isfile will throw an exception
 89            loaded_json = json.loads(self._target)
 90
 91        (underlying_type, unit_tests) = standard.load_from_compile(crytic_compile, loaded_json)
 92        underlying_type = TypePlatform(underlying_type)
 93        platforms: List[Type[AbstractPlatform]] = get_platforms()
 94        platform = next((p for p in platforms if p.TYPE == underlying_type), Archive)
 95        self._underlying_platform = platform
 96        self._unit_tests = unit_tests
 97        self._target = "tmp.zip"
 98
 99        crytic_compile.src_content = loaded_json["source_content"]
100
101    def clean(self, **_kwargs: str) -> None:
102        pass
103
104    @staticmethod
105    def is_supported(target: str, **kwargs: str) -> bool:
106        """Check if the target is an archive
107
108        Args:
109            target (str): path to the target
110            **kwargs: optional arguments. Used: "standard_ignore"
111
112        Returns:
113            bool: True if the target is an archive
114        """
115        archive_ignore = kwargs.get("standard_ignore", False)
116        if archive_ignore:
117            return False
118        if not Path(target).parts:
119            return False
120        return Path(target).parts[-1].endswith("_export_archive.json")
121
122    def is_dependency(self, _path: str) -> bool:
123        """Check if the _path is a dependency. Always false
124
125        Args:
126            _path (str): path to the target
127
128        Returns:
129            bool: Always false - the archive checks are handled by crytic_compile_dependencies
130        """
131        # TODO: check if its correctly handled by crytic_compile_dependencies
132        return False
133
134    def _guessed_tests(self) -> List[str]:
135        """Return the list of guessed unit tests commands
136
137        Returns:
138            List[str]: Guessed unit tests commands
139        """
140        return self._unit_tests

Archive platform. It is similar to the Standard platform, but contains also the source code

Archive(target: str, **kwargs: str)
60    def __init__(self, target: str, **kwargs: str):
61        """Initializes an object which represents solc standard json
62
63        Args:
64            target (str): The path to the standard json
65            **kwargs: optional arguments.
66        """
67        super().__init__(target, **kwargs)
68        self._underlying_platform: Type[AbstractPlatform] = Archive
69        self._unit_tests: List[str] = []

Initializes an object which represents solc standard json

Args: target (str): The path to the standard json **kwargs: optional arguments.

NAME: str = 'Archive'
PROJECT_URL: str = 'https://github.com/crytic/crytic-compile'
TYPE: crytic_compile.platform.types.Type = <Type.ARCHIVE: 101>
HIDE = True
def compile( self, crytic_compile: crytic_compile.crytic_compile.CryticCompile, **_kwargs: str) -> None:
71    def compile(self, crytic_compile: "CryticCompile", **_kwargs: str) -> None:
72        """Run the compilation
73
74        Args:
75            crytic_compile (CryticCompile): associated CryticCompile object
76            **_kwargs: unused
77        """
78        # pylint: disable=import-outside-toplevel
79        from crytic_compile.crytic_compile import get_platforms
80
81        try:
82            if isinstance(self._target, str) and os.path.isfile(self._target):
83                with open(self._target, encoding="utf8") as f_target:
84                    loaded_json = json.load(f_target)
85            else:
86                loaded_json = json.loads(self._target)
87        except (OSError, ValueError):
88            # Can happen if the target is a very large string, isfile will throw an exception
89            loaded_json = json.loads(self._target)
90
91        (underlying_type, unit_tests) = standard.load_from_compile(crytic_compile, loaded_json)
92        underlying_type = TypePlatform(underlying_type)
93        platforms: List[Type[AbstractPlatform]] = get_platforms()
94        platform = next((p for p in platforms if p.TYPE == underlying_type), Archive)
95        self._underlying_platform = platform
96        self._unit_tests = unit_tests
97        self._target = "tmp.zip"
98
99        crytic_compile.src_content = loaded_json["source_content"]

Run the compilation

Args: crytic_compile (CryticCompile): associated CryticCompile object **_kwargs: unused

def clean(self, **_kwargs: str) -> None:
101    def clean(self, **_kwargs: str) -> None:
102        pass

Clean compilation artifacts

Args: **kwargs: optional arguments.

@staticmethod
def is_supported(target: str, **kwargs: str) -> bool:
104    @staticmethod
105    def is_supported(target: str, **kwargs: str) -> bool:
106        """Check if the target is an archive
107
108        Args:
109            target (str): path to the target
110            **kwargs: optional arguments. Used: "standard_ignore"
111
112        Returns:
113            bool: True if the target is an archive
114        """
115        archive_ignore = kwargs.get("standard_ignore", False)
116        if archive_ignore:
117            return False
118        if not Path(target).parts:
119            return False
120        return Path(target).parts[-1].endswith("_export_archive.json")

Check if the target is an archive

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

Returns: bool: True if the target is an archive

def is_dependency(self, _path: str) -> bool:
122    def is_dependency(self, _path: str) -> bool:
123        """Check if the _path is a dependency. Always false
124
125        Args:
126            _path (str): path to the target
127
128        Returns:
129            bool: Always false - the archive checks are handled by crytic_compile_dependencies
130        """
131        # TODO: check if its correctly handled by crytic_compile_dependencies
132        return False

Check if the _path is a dependency. Always false

Args: _path (str): path to the target

Returns: bool: Always false - the archive checks are handled by crytic_compile_dependencies

def generate_archive_export( crytic_compile: crytic_compile.crytic_compile.CryticCompile) -> Tuple[Dict, str]:
143def generate_archive_export(crytic_compile: "CryticCompile") -> Tuple[Dict, str]:
144    """Generate the archive export
145
146    Args:
147        crytic_compile (CryticCompile): CryticCompile object to export
148
149    Returns:
150        Tuple[Dict, str]: The dict is the exported archive, and the str the filename
151    """
152    output = standard.generate_standard_export(crytic_compile)
153    output["source_content"] = crytic_compile.src_content
154
155    target = crytic_compile.target
156    target = "contracts" if os.path.isdir(target) else Path(target).parts[-1]
157    target = f"{target}_export_archive.json"
158
159    return output, target

Generate the archive export

Args: crytic_compile (CryticCompile): CryticCompile object to export

Returns: Tuple[Dict, str]: The dict is the exported archive, and the str the filename