Ejemplo n.º 1
0
def contract_file(contract_dir_hint, contract_file_hint):
    ''' Given contract dir and contract file hints, determine the file.

    Contract files are those extended with ``wast``, ``wasm`` and ``abi``.

    First, the ``contract_file_hint`` may be an absolute path.
    Next, it may be relative to the contract directory.

    The contract directory is the container for the project of a contract. This 
    directory is determined with the ``contract_dir`` function, basing on the 
    ``contract_dir_hint``.

    Any contract directory contains directories and files structured according 
    to few schemes:
    flat structure with all the files in this directory as in the ``eos/contracts/*`` contract directories in the EOS repository;
    structure with a directory named ``build`` as resulting from the EOSFactory templates;
    '''
    contract_dir_hint = utils.wslMapWindowsLinux(contract_dir_hint)
    contract_file_hint = utils.wslMapWindowsLinux(contract_file_hint)

    # ? ``contract_file_hint`` may be an absolute path to a file
    trace = contract_file_hint + "\n"
    if os.path.isabs(contract_file_hint) \
                                    and os.path.isfile(contract_file_hint):
        return contract_file_hint

    # ? it may be relative to the contract directory.
    contract_dir_ = contract_dir(contract_dir_hint)

    # ? flat structure with all the files in this directory
    contract_file = os.path.join(contract_dir_, contract_file_hint)
    trace = trace + contract_file + "\n"
    if os.path.isfile(contract_file):
        return contract_file

    # ? structure with a directory named ``build``
    # and ``contract_file_hint`` is relative file
    contract_file = os.path.join(contract_dir_, "build", contract_file_hint)
    trace = trace + contract_file + "\n"
    if os.path.isfile(contract_file):
        return contract_file

    # ? structure with a directory named ``build``
    # and ``contract_file_hint`` is a file extension merely
    build_dir = os.path.join(contract_dir_, "build")
    trace = trace + build_dir + "\n"
    files = os.listdir(build_dir)
    for file in files:
        if os.path.splitext(file)[1] == contract_file_hint:
            return os.path.join(build_dir, file)

    raise errors.Error('''
        Cannot determine the contract file basing on hints:
        contract dir hint: {}
        contract file hint: {}
        Tried path list:
        {}
    '''.format(contract_dir_hint, contract_file_hint, trace))
Ejemplo n.º 2
0
def contract_source_files(contract_dir_hint):
    '''List files CPP/C and ABI files from directory given with a hint.

    Args:
        contract_dir_hint (str): An argument to the function 
            :func:`.contract_dir`

    Raises:
        .core.errors.Error: If the list is empty.
    '''
    contract_dir_ = contract_dir(utils.wslMapWindowsLinux(contract_dir_hint))
    trace = contract_dir_ + "\n"

    source_dir = contract_dir_
    srcs = source_files(source_dir)
    if srcs:
        return (source_dir, srcs)

    source_dir = os.path.join(contract_dir_, "src")
    trace = trace + source_dir + "\n"
    srcs = source_files(source_dir)
    if srcs:
        return (source_dir, srcs)

    raise errors.Error('''
        Cannot find any contract source directory.
        Tried path list:
        {}
    '''.format(trace))
Ejemplo n.º 3
0
def update_vscode(c_cpp_properties_path):
    c_cpp_properties_path = utils.wslMapWindowsLinux(c_cpp_properties_path)
    with open(c_cpp_properties_path) as f:
        c_cpp_properties = f.read()

    pattern = re.compile(EOSIO_CDT_PATTERN)

    if re.findall(pattern, c_cpp_properties):
        new = c_cpp_properties.replace(
            re.findall(pattern, c_cpp_properties)[0],
            eosio_cdt_version()[0])

        if not new == c_cpp_properties:
            with open(c_cpp_properties_path, 'w') as f:
                f.write(new)

    pattern = re.compile(UBUNTU_PATTERN)
    root = wsl_root()
    if root:
        if re.findall(pattern, c_cpp_properties):
            new = c_cpp_properties.replace(
                re.findall(pattern, c_cpp_properties)[0], root)

        if not new == c_cpp_properties:
            with open(c_cpp_properties_path, 'w') as f:
                f.write(new)
Ejemplo n.º 4
0
def contract_workspace_dir(dont_set_workspace=False):
    '''The absolute path to the contract workspace.

    The contract workspace is a directory where automatically created projects
    are placed by default. It is set while EOSFactory is installed. 

    If not set, the projects are stored in the `.config.CONTRACTS_DIR` 
    subdirectory (typically *contracts/*) of the EOSFActory installation, if 
    EOSFactory is installed from its GitHub repository, otherwise, they go to 
    a directory specified as 
    `join(.config.TMP, .config.CONTRACTS_DIR)`. 

    The setting may be changed with 
    *EOSIO_CONTRACT_WORKSPACE* entry in the *config.json* file, 
    see :func:`.current_config`.

    Args:
        dont_set_workspace (bool): If set, do not query for empty workspace 
            directory.
    '''
    if dont_set_workspace:
        return config_map()[contract_workspace_dir_[0]]

    if not contract_workspace_dir_[0] in config_map():
        set_contract_workspace_dir()

    workspace_dir = config_value(contract_workspace_dir_)
    path = utils.wslMapWindowsLinux(workspace_dir)

    if os.path.isabs(path):
        if os.path.exists(path):
            return path
        else:
            raise errors.Error('''
The path
'{}',
set as the contract workspace directory, does not exist.
            '''.format(path),
                               translate=False)
    else:
        if not is_site_package():
            path = os.path.join(eosf_dir(), path)
        else:
            path = os.path.join(TMP, path)
            if not os.path.exists(path):
                os.makedirs(path)

        if os.path.exists(path):
            return path
        else:
            raise errors.Error('''
The path
'{}'
resolved as the contract workspace directory directory does not exist.
            '''.format(workspace_dir, translate=False))
    return path
Ejemplo n.º 5
0
    def set(contract_workspace_dir):
        if contract_workspace_dir:
            path = utils.wslMapWindowsLinux(contract_workspace_dir)
            if os.path.exists(path) and os.path.isdir(path):
                map = config_map()
                map[contract_workspace_dir_[0]] = path
                write_config_map(map)
                return True

        return False
Ejemplo n.º 6
0
def update_eosio_cpp_includes(c_cpp_properties_path, root=""):
    c_cpp_properties_path = utils.wslMapWindowsLinux(c_cpp_properties_path)
    with open(c_cpp_properties_path) as f:
        c_cpp_properties = f.read()
    dir_pattern = re.compile(
        '^.*{}(/.+/eosio\.cdt/\d\.\d\.\d/).+'.format(root), re.M)

    dir = eosio_cpp_dir()
    if re.findall(dir_pattern, c_cpp_properties):
        new = c_cpp_properties.replace(
            re.findall(dir_pattern, c_cpp_properties)[0], dir)
        if not new == c_cpp_properties:
            with open(c_cpp_properties_path, 'w') as f:
                f.write(new)
Ejemplo n.º 7
0
def contract_dir(contract_dir_hint):
    '''Given a hint, determine the contract root directory.

    The ``contract_dir_hint`` is tested to be either
        - an absolute path, or
        - a path relative to either
            - the directory given with :func:`contract_workspace`, or
            - the directory given with :func:`eosf_dir` ``/contracts``.

    Args:
        contract_dir_hint (path): A directory path, may be not absolute.
        
    Raises:
        .core.errors.Error: If the result is not defined.
    '''
    contract_dir_hint = utils.wslMapWindowsLinux(contract_dir_hint)
    # ? the absolute path to a contract directory
    trace = contract_dir_hint + "\n"
    if os.path.isfile(contract_dir_hint):
        contract_dir_hint = os.path.dirname(contract_dir_hint)
    if os.path.isabs(contract_dir_hint):
        if os.path.exists(contract_dir_hint):
            return os.path.realpath(contract_dir_hint)

    # ? the relative path to a contract directory, relative to the directory
    # set with the 'contract_workspace_dir()' function
    contract_dir_ = os.path.join(contract_workspace_dir(), contract_dir_hint)
    trace = trace + contract_dir_ + "\n"
    if os.path.isdir(contract_dir_):
        if os.path.exists(contract_dir_):
            return os.path.realpath(contract_dir_)

    # ? the relative path to a contract directory, relative to
    # 'eosfactory_data()/contracts'
    contract_dir_ = os.path.join(eosfactory_data(), CONTRACTS_DIR,
                                 contract_dir_hint)

    trace = trace + contract_dir_ + "\n"
    if os.path.isdir(contract_dir_):
        if os.path.exists(contract_dir_):
            return os.path.realpath(contract_dir_)

    raise errors.Error('''
Cannot determine the contract directory.
Tried:
    {}
    '''.format(trace),
                       translate=False)
Ejemplo n.º 8
0
def contract_dir(contract_dir_hint):
    '''Given a hint, determine the contract directory.
    The contract directory is the container for the project of a contract.
    The hint is probed to be one of the following pieces of information:
    the absolute path to a contract directory;
    the relative path to a contract directory, relative to the directory set with the ``contract_workspace_`` variable;
    the relative path to a contract directory, relative to the ``contracts`` directory in the repository of EOSFactory;
    the relative path to a contract directory, relative to the ``contracts`` directory in the repository of EOSIO.
    '''
    contract_dir_hint = utils.wslMapWindowsLinux(contract_dir_hint)

    # ? the absolute path to a contract directory
    trace = contract_dir_hint + "\n"
    if os.path.isfile(contract_dir_hint):
        contract_dir_hint = os.path.dirname(contract_dir_hint)
    if os.path.isabs(contract_dir_hint):
        return contract_dir_hint

    # ? the relative path to a contract directory, relative to the directory
    # set with the 'contract_workspace_' variable
    contract_dir_ = os.path.join(config_value(contract_workspace_),
                                 contract_dir_hint)
    trace = trace + contract_dir_ + "\n"
    if os.path.isdir(contract_dir_):
        return contract_dir_

    # ? the relative path to a contract directory, relative to the
    # ``contracts`` directory in the repository of EOSFactory
    contract_dir_ = os.path.join(eosf_dir(), CONTRACTS_DIR, contract_dir_hint)
    trace = trace + contract_dir_ + "\n"
    if os.path.isdir(contract_dir_):
        return contract_dir_

    # ? the relative path to a contract directory, relative to the
    # ``contracts`` directory in the repository of EOSIO
    contract_dir_ = os.path.join(config_value(eosio_repository_dir_),
                                 EOSIO_CONTRACT_DIR, contract_dir_hint)
    trace = trace + contract_dir_ + "\n"
    if os.path.isdir(contract_dir_):
        return contract_dir_

    raise errors.Error('''
        Cannot determine the contract directory.
        Tried path list:
        {}
    '''.format(trace))
Ejemplo n.º 9
0
def get_c_cpp_properties(contract_dir, c_cpp_properties_path):
    if not c_cpp_properties_path:
        c_cpp_properties_path = os.path.join(contract_dir,
                                             ".vscode/c_cpp_properties.json")
    else:
        c_cpp_properties_path = utils.wslMapWindowsLinux(c_cpp_properties_path)
        if not os.path.exists(c_cpp_properties_path):
            raise errors.Error('''
                The given path does not exist:
                ${}       
            '''.format(c_cpp_properties_path))

    if os.path.exists(c_cpp_properties_path):
        try:
            with open(c_cpp_properties_path, "r") as input:
                return json.loads(input.read())
        except Exception as e:
            raise errors.Error(str(e))
    else:
        return json.loads(replace_templates(vscode.c_cpp_properties))
Ejemplo n.º 10
0
def contract_source_files(contract_dir_hint):
    contract_dir_ = contract_dir(utils.wslMapWindowsLinux(contract_dir_hint))
    trace = contract_dir_ + "\n"

    source_path = contract_dir_
    srcs = source_files(source_path)
    if srcs:
        return (source_path, srcs)

    source_path = os.path.join(contract_dir_, "src")
    trace = trace + source_path + "\n"
    srcs = source_files(source_path)
    if srcs:
        return (source_path, srcs)

    raise errors.Error('''
        Cannot find any contract source directory.
        Tried path list:
        {}
    '''.format(trace))
Ejemplo n.º 11
0
def project_from_template(
        project_name, template=None, workspace_dir=None,
        c_cpp_prop_path=None,
        include=None,
        libs=None, 
        remove_existing=False, 
        open_vscode=False, throw_exists=False, 
        verbosity=None):
    '''Given the project name and template name, create a smart contract project.

    - **parameters**::

        project_name: The name of the project, or an existing path to 
            a directory.
        template: The name of the template used.
        workspace_dir: If set, the folder for the work-space. Defaults to the 
            value returned by the config.contract_workspace() function.
        include: If set, comma-separated list of include folders.
        libs: If set, comma-separated list of libraries.
        remove_existing: If set, overwrite any existing project.
        visual_studio_code: If set, open the ``VSCode``, if available.
        verbosity: The logging configuration.
    '''
    project_name = utils.wslMapWindowsLinux(project_name.strip())
    template = template.strip()

    template_dir = utils.wslMapWindowsLinux(template)
    if not os.path.isdir(template_dir):
        template_dir = os.path.join(
            config.eosf_dir(), TEMPLATE_CONTRACTS_DIR, template) 
    if not os.path.isdir(template_dir):
        raise errors.Error('''
        TemplateCreate '{}' does not exist.
        '''.format(template_dir)) 

    if c_cpp_prop_path:
        c_cpp_prop_path = utils.wslMapWindowsLinux(c_cpp_prop_path)
        if os.path.exists(c_cpp_prop_path):
            try:
                with open(c_cpp_prop_path, "r") as input:
                    c_cpp_properties = input.read()
            except Exception:
                c_cpp_properties = vscode.c_cpp_properties()
    else:
        c_cpp_properties = vscode.c_cpp_properties()

    c_cpp_properties = replace_templates(c_cpp_properties)

    if include:
        c_cpp_properties_json = json.loads(c_cpp_properties)
        c_cpp_properties_json[CONFIGURATIONS][0][INCLUDE_PATH].extend(
                                                        include.split(", "))
        c_cpp_properties_json[CONFIGURATIONS][0][BROWSE]["path"].extend(
                                                        include.split(", "))
        c_cpp_properties = json.dumps(c_cpp_properties_json, indent=4)

    if libs:
        c_cpp_properties_json = json.loads(c_cpp_properties)
        c_cpp_properties_json[CONFIGURATIONS][0]["libs"].extend(
                                                        libs.split(", "))
        c_cpp_properties = json.dumps(c_cpp_properties_json, indent=4)


    split = os.path.split(project_name)
    if os.path.isdir(split[0]):
        project_dir = project_name
        project_name = split[1]
    else:
        if not workspace_dir \
                                or not os.path.isabs(workspace_dir) \
                                or not os.path.exists(workspace_dir):
            workspace_dir = config.contract_workspace()
        workspace_dir = workspace_dir.strip()        
        project_dir = os.path.join(workspace_dir, project_name)

    if os.path.isdir(project_dir):
        if os.listdir(project_dir):
            if remove_existing:
                try:
                    shutil.rmtree(project_dir)
                except Exception as e:
                    raise errors.Error('''
Cannot remove the directory {}.
error message:
==============
{}
                    '''.format(project_dir, str(e)))
            else:
                msg = '''
                NOTE:
                Contract workspace
                '{}'
                already exists. Cannot overwrite it.
                '''.format(project_dir)
                if throw_exists:
                    raise errors.Error(msg)
                else:
                    raise errors.Error(msg)
                    return

    try:    # make contract directory and its build directory:
        os.makedirs(os.path.join(project_dir, "build"))
    except Exception as e:
            raise errors.Error(str(e))

    def copy_dir_contents(
            project_dir, template_dir, directory, project_name):
        contents = os.listdir(os.path.join(template_dir, directory))
        
        for item in contents:
            path = os.path.join(directory, item)
            template_path = os.path.join(template_dir, path)
            contract_path = os.path.join(
                project_dir, path.replace(
                                        TEMPLATE_NAME, project_name))
                          
            if os.path.isdir(template_path):
                os.mkdir(contract_path)
                copy_dir_contents(
                            project_dir, template_dir, path, project_name)
            elif os.path.isfile(template_path):

                copy(template_path, contract_path, project_name)

    def copy(template_path, contract_path, project_name):
        with open(template_path, "r") as input:
            template = input.read()

        if TEMPLATE_HOME in template or TEMPLATE_ROOT in template:
            home = os.environ["HOME"]
            root = ""
            if is_windows_ubuntu():
                replace_templates(template)

        template = template.replace("${" + TEMPLATE_NAME + "}", project_name)
        template = template.replace(C_CPP_PROP, c_cpp_properties)
        template = template.replace(TASK_JSON, vscode.TASKS)

        with open(contract_path, "w") as output:
            output.write(template)

    copy_dir_contents(project_dir, template_dir, "", project_name)

    logger.TRACE('''
    * Contract project '{}' created from template 
        '{}'
    '''.format(project_name, template_dir), verbosity)    

    if open_vscode:
        if is_windows_ubuntu():
            command_line = "cmd.exe /C code {}".format(
                utils.wslMapLinuxWindows(project_dir))
        elif uname() == "Darwin":
            command_line = "open -n -b com.microsoft.VSCode --args {}".format(
                project_dir)
        else:
            command_line = "code {}".format(project_dir)

        os.system(command_line)

    logger.INFO('''
    ######### Created contract project ``{}``, 
        originated from template 
        ``{}``.
    '''.format(project_name, template_dir), verbosity)

    return project_dir
Ejemplo n.º 12
0
def contract_file(contract_dir_hint, contract_file_hint):
    ''' Given contract directory and contract file hints, determine a contract 
    file.

    The contract directory is determined with the function 
    :func:`.contract_dir`, basing on the *contract_dir_hint* argument.

    Contract files are ABI or WASM ones. Contract file hint is an absolute path
    to a contract file, or it is relative to the contract dir, ir it is 
    a file extension.

    Any contract directory considered to be structured according to one of the 
    following patterns:

        - all the files in the contract directory,
        - contract files in the *build* subdirectory.  

    Args:
        contract_dir_hint (path): A directory path, may be not absolute.
        contract_file_hint (str or path): A file extension, or file path, 
            may be not absolute.

    Raises:
        .core.errors.Error: If the result is not defined.
    '''
    contract_dir_hint = utils.wslMapWindowsLinux(contract_dir_hint)
    contract_file_hint = utils.wslMapWindowsLinux(contract_file_hint)

    # Contract file hint is an absolute path to a contract file:
    trace = contract_file_hint + "\n"
    if os.path.isabs(contract_file_hint) \
                                    and os.path.isfile(contract_file_hint):
        return contract_file_hint

    contract_dir_ = contract_dir(contract_dir_hint)

    # All the files in the contract directory:
    contract_file = os.path.join(contract_dir_, contract_file_hint)
    trace = trace + contract_file + "\n"
    if os.path.isfile(contract_file):
        return contract_file

    # Contract files in the *build* subdirectory,
    # and *contract_file_hint* is a relative file
    contract_file = os.path.join(contract_dir_, "build", contract_file_hint)
    trace = trace + contract_file + "\n"
    if os.path.isfile(contract_file):
        return contract_file

    # Contract files in the *build* subdirectory,
    # and *contract_file_hint* is a file extension merely
    build_dir = os.path.join(contract_dir_, "build")
    trace = trace + build_dir + "\n"
    files = os.listdir(build_dir)
    for file in files:
        if os.path.splitext(file)[1] == contract_file_hint:
            return os.path.join(build_dir, file)

    raise errors.Error('''
        Cannot determine the contract file basing on hints:
        contract dir hint: {}
        contract file hint: {}
        Tried path list:
        {}
    '''.format(contract_dir_hint, contract_file_hint, trace))
Ejemplo n.º 13
0
def linuxize_path(path):
    return utils.wslMapWindowsLinux(path.replace(ROOT, ""))
Ejemplo n.º 14
0
def build(
        contract_dir_hint, c_cpp_properties_path=None,
        compile_only=False, is_test_mode=False, is_execute=False, 
        verbosity=None):
    '''Produce ABI and WASM files.

    Compiler options come with the argument 'c_cpp_properties_path', as 
    components of 'compilerOptions' list. Option can be any of the 'eosio-cpp'
    options, plus the following ones:

    * --src - list of the source files, absolute or relative to 'src' or
        project directories, for example:
        --src hello.cpp tests/hello_test.cpp
    * -o - the same as the corresponding eosio-cpp option, but may be relative
        to 'build' directory

    Without any option set, the only source file is determined as a result of the function :func:`.core.config.contract_source_files`, if the result is a 
    single file. If it is not, an error is thrown, stating that the source file has to be specified with the '--src' option.

    The ABI and WASM targets are named after the contract source file. 

    Args:
        contract_dir_hint (str): Path, may be partial, to the project directory.
        c_cpp_properties_path (str): If set, the path to a c_cpp_properties json 
            file in '.vscode' folder in the project directory.
        compile_only (bool): If set, do not link.
        verbosity (([.core.logger.Verbosity])): Verbosity parameter, used in 
            loggers.
    '''
    contract_dir = config.contract_dir(contract_dir_hint)
    # contract_source_files[0] is directory, contract_source_files[1] is contents:
    contract_source_files = config.contract_source_files(contract_dir)
    c_cpp_properties = get_c_cpp_properties(
                                        contract_dir, c_cpp_properties_path)
    build_dir = get_target_dir(contract_dir)
    target_path = None
    compile_options = []
    source_files = []
    
    ############################################################################
    # begin compiler option logics
    ############################################################################
    recardian_dir = "-R=" + get_recardian_dir(contract_source_files[0])

    if is_test_mode \
                and vscode.TEST_OPTIONS in c_cpp_properties[CONFIGURATIONS][0]:
        compile_options_ = c_cpp_properties[CONFIGURATIONS][0]\
                                                        [vscode.TEST_OPTIONS]
    elif not is_test_mode \
                and vscode.CODE_OPTIONS in c_cpp_properties[CONFIGURATIONS][0]:
        compile_options_ = c_cpp_properties[CONFIGURATIONS][0]\
                                                        [vscode.CODE_OPTIONS]
    else:
        compile_options_ = []

    contract_src_name = None
    is_verbose = False

    if not "-abigen" in compile_options_:
        compile_options.append("-abigen")
    if is_test_mode and not "-fnative" in compile_options_:
        compile_options.append("-fnative")
    
    for i in range(0, len(compile_options_)):
        entry = compile_options_[i]
        if "-R=" in entry:
            recardian_dir = entry
        elif "-contract=" in entry:
            contract_src_name = entry.replace("-contract=", "").strip()
            compile_options.append(entry)
        elif "--verbose" in entry:
            is_verbose = True
        elif "-o" in entry:
            target_path = utils.wslMapWindowsLinux(
                                            entry.replace("-o", "").strip())
            if not target_path:
                if i + 1 < len(compile_options_):
                    target_path = compile_options_[i + 1]
                else:
                    raise errors.Error('''
The option '-o' does not has its value set:
{}
                    '''.format(compile_options_))

            if not os.path.isabs(target_path):
                target_path = os.path.join(build_dir, target_path)
                target_dir = os.path.dirname(target_path)
                if not os.path.exists(target_dir):
                    try:
                        os.makedirs(target_dir)
                    except Exception as e:
                        raise errors.Error('''
Cannot make directory set with the option '-o'.
{}
                        '''.format(str(e)))
        
        elif "-abigen_output" in entry:
            abigen_path = utils.wslMapWindowsLinux(
                                    entry.replace("-abigen_output=", "").strip())

            if not os.path.isabs(abigen_path):
                abigen_path = os.path.join(build_dir, abigen_path)
                abigen_dir = os.path.dirname(abigen_path)
                if not os.path.exists(abigen_dir):
                    try:
                        os.makedirs(abigen_dir)
                    except Exception as e:
                        raise errors.Error('''
Cannot make directory set with the option '-abigen_output'.
{}
                        '''.format(str(e)))

            compile_options.append("-abigen_output={}".format(abigen_path))
        elif "--src" in entry:
            input_files_ = utils.wslMapWindowsLinux(
                                            entry.replace("--src", "").strip())
            if not input_files_:
                next_index = i + 1
                while True:
                    if next_index >= len(compile_options_):
                        break

                    next_item = compile_options_[next_index]
                    if "-" in next_item:
                        break
                    
                    input_files_ = input_files_ + " " + next_item
                    
            if not input_files_:
                raise errors.Error('''
The option '--src' does not has its value set:
{}
                '''.format(compile_options_))

            for input_file in input_files_.split(" "):
                temp = input_file
                if not os.path.isabs(temp):
                    temp = os.path.join(contract_source_files[0], input_file)
                    if not contract_src_name:
                        contract_src_name = os.path.splitext(
                                                    os.path.basename(temp))[0]
                    if not os.path.exists(temp):
                        temp = os.path.join(contract_dir, input_file)

                if not os.path.exists(temp):
                    raise errors.Error('''
The source file
{} 
cannot be found. It is neither absolute nor relative to the contract directory
or relative to the 'src' directory.
                    '''.format(input_file))

                temp = os.path.normpath(temp)
                if not temp in source_files:
                    source_files.append(temp)
        else:
            compile_options.append(entry)

    compile_options.append(recardian_dir)

    if not source_files:
        source_files = contract_source_files[1]
    
    if not source_files:
        raise errors.Error('''
Cannot find any source file (".c", ".cpp",".cxx", ".c++") in the contract folder.
        ''')

    if not is_test_mode and len(source_files) > 1: 
            raise errors.Error('''
Cannot determine the source file of the contract. There is many files in 
the 'src' directory, namely:
{}
Specify the file with the compiler option '--src', for
example:
--src src_dir/hello.cpp
The file path is to be absolute or relative to the project directory.
            '''.format("\n".join(source_files)))

    if not contract_src_name:
        contract_src_name = os.path.splitext(
                                        os.path.basename(source_files[0]))[0]

    if not contract_src_name and len(source_files) == 1:
            contract_src_name = os.path.splitext(
                                        os.path.basename(source_files[0]))[0]
        
    ############################################################################
    # end compiler option logics
    ############################################################################

    if not target_path:
        target_path = os.path.normpath(
                        os.path.join(build_dir, contract_src_name  + ".wasm"))
        abigen_path = os.path.normpath(
                        os.path.join(build_dir, contract_src_name  + ".abi"))
    if is_execute:
        logger.TRACE('''
            Executing target
                {}
        '''.format(target_path))
        command_line = [target_path]

        if setup.is_print_command_lines and setup.is_save_command_lines:
            setup.add_to__command_line_file(" ".join(command_line))
        if setup.is_print_command_lines or is_verbose:
            logger.DEBUG('''
                ######## command line:
                {}
                '''.format(" ".join(command_line)), [logger.Verbosity.DEBUG])
        utils.long_process(command_line, build_dir, is_verbose=True, 
                                                            prompt=target_path)
        return

    command_line = [config.eosio_cpp()]

    if compile_only:
        command_line.append("-c")
    else:
        command_line.extend(["-o", target_path])

    for entry in c_cpp_properties[CONFIGURATIONS][0][vscode.INCLUDE_PATH]:
        if WORKSPACE_FOLDER in entry:
            entry = entry.replace(WORKSPACE_FOLDER, contract_dir)
            command_line.append("-I=" + linuxize_path(entry))
        else:
            path = linuxize_path(entry)
            if not path in config.eosio_cpp_includes():
                command_line.append(
                    "-I=" + path)

    for entry in c_cpp_properties[CONFIGURATIONS][0][vscode.LIBS]:
        command_line.append(
            "-l=" + linuxize_path(entry))

    for entry in compile_options:
        command_line.append(entry)

    for input_file in source_files:
        command_line.append(input_file)

    if setup.is_print_command_lines and setup.is_save_command_lines:
        setup.add_to__command_line_file(" ".join(command_line))
    if setup.is_print_command_lines or is_verbose:
        logger.DEBUG('''
            ######## command line:
            {}
            '''.format(" ".join(command_line)), [logger.Verbosity.DEBUG])
        
    utils.long_process(command_line, build_dir, is_verbose=True, 
                                                            prompt="eosio-cpp")
    if not compile_only:
        if "wasm" in target_path:
            logger.TRACE('''
                ABI file writen to file: 
                    {}
                '''.format(os.path.normpath(abigen_path)), verbosity)        
            logger.TRACE('''
                WASM file writen to file: 
                    {}
                '''.format(os.path.normpath(target_path)), verbosity)
        else:
            logger.TRACE('''
                terget writen to file: 
                    {}
                '''.format(os.path.normpath(target_path)), verbosity)
    print("eosio-cpp: OK")            
Ejemplo n.º 15
0
def unpack(contract_dir=None, zip_file=None):
    '''Unack a contract project folder.

    Make a new contract project folder from a zip file produced with the 
    function :func:`pack`.

    If the given zip file is an arbitrary one, expands it with omiting files 
    matching the `config.IGNORE_LIST`, and localizes the 
    '.vscode.c_cpp_properties.json' file, if found.

    Args:
        contract_dir (str): The contract project directory to be created.
        zip_file (str): The zip file to be extracted.
    '''

    if not contract_dir:
        raise errors.Error('''
            The directory of the new contract has to be specified.
        ''')
    contract_dir = utils.wslMapWindowsLinux(contract_dir)

    if os.path.exists(contract_dir) and os.listdir(contract_dir):
        raise errors.Error('''
            The directory
                {}
            is not empty. Cannot overwrite it.
        '''.format(os.path.realpath(contract_dir)))

    if not zip_file:
        raise errors.Error('''
            The zip file, defining the new directory, has to be specified.
        ''')

    zip_file = utils.wslMapWindowsLinux(zip_file)
    if not os.path.exists(zip_file):
        raise errors.Error('''
            The zip file
                {}
            does not exists
        '''.format(os.path.realpath(zip_file)))

    def convert_c_cpp_properties(member, zipfile_object):
        if "c_cpp_properties.json" in member.filename:
            c_cpp_properties = zipfile_object.read(member).decode("utf-8")
            eosio_cdt_include = re.compile(EOSIO_CDT_INCLUDE)
            if re.findall(eosio_cdt_include, c_cpp_properties):
                c_cpp_properties = c_cpp_properties.replace(
                    re.findall(eosio_cdt_include, c_cpp_properties)[0],
                    EOSIO_CDT_HOME)

            eosio_cdt_root = config.wsl_root() + config.eosio_cdt_root()
            c_cpp_properties = c_cpp_properties.replace(
                EOSIO_CDT_HOME, eosio_cdt_root)

            if not os.path.exists(os.path.join(contract_dir, ".vscode")):
                os.makedirs(os.path.join(contract_dir, ".vscode"))

            with open(os.path.join(contract_dir, member.filename), "w+") as f:
                f.write(c_cpp_properties)
            return True
        return False

    try:
        with zipfile.ZipFile(zip_file) as zf:
            info_list = zf.infolist()
            for member in info_list:
                if is_valid(member.filename, config.IGNORE_LIST):
                    if not convert_c_cpp_properties(member, zf):
                        zf.extract(member, contract_dir)

    except Exception as e:
        raise errors.Error('''
            Cannot extract the zip file
                {}
            to the directory
                {}
            The error message is
            {}
        '''.format(os.path.realpath(zip_file), os.path.realpath(contract_dir),
                   str(e)))

    create_ignore_list_file(contract_dir)
    create_utils(contract_dir)
    create_task_json(contract_dir)
Ejemplo n.º 16
0
def pack(contract_dir=None, zip_file=None):
    '''Pack a contract project folder.

    If an EOSIO contract project which is a VSCode folder is to be passed by 
    e-mail, it has to be compressed. However, this should not be done in 
    a straightforward way, because of the following issues:
        
        There are volume binaries there.
        There are local configuring files in the .vscode folder.
        There are your private notes and scratchpads there.
        The paths in the .vscode/c_cpp_properties.json are localized according 
        to the local operating system.

    Make compression automatically, solving the issues. 
    With default arguments, produce a zip file, in the project folder. The 
    file is named after the folder name.

    Args:
        contract_dir (str): If set, the contract project directory, otherwise cwd.
        zip_file (str): If set, the name of the zip file, 
                otherwise <project directory>/<project directory name>.zip 
    '''

    if not contract_dir:
        contract_dir = os.getcwd()
    else:
        contract_dir = utils.wslMapWindowsLinux(contract_dir)

    if not os.path.exists(contract_dir):
        raise errors.Error('''
            The given contract directory
                {}
            does not exist.
                    ''')

    if not os.path.isdir(contract_dir):
        raise errors.Error('''
            The given contract path
                {}
            is not a directory.
        ''')

    if not zip_file:
        zip_file = os.path.realpath(
            os.path.join(os.getcwd(),
                         os.path.basename(contract_dir) + ".zip"))
    else:
        zip_file = utils.wslMapWindowsLinux(zip_file)

    if os.path.exists(zip_file):
        try:
            os.remove(zip_file)
        except Exception as e:
            raise errors.Error('''
                Cannot remove the project zip file
                    {}
                The error message is
                    {}
            '''.format(zip_file, str(e)))

    ignore_file = create_ignore_list_file(contract_dir, True)

    ignore_list = []
    with open(ignore_file, "r") as f:
        for l in f:
            line = l.strip()
            if not line[0] == "#":
                ignore_list.append(line)
    if not zip_file in ignore_list:
        ignore_list.append(zip_file)
    if not config.IGNORE_FILE in ignore_list:
        ignore_list.append(config.IGNORE_FILE)

    def convert_c_cpp_properties(path, path_rel, zipfile_object):
        if "c_cpp_properties.json" in path:
            with open(path, "r") as f:
                c_cpp_properties = f.read()
                eosio_cdt_include = re.compile(EOSIO_CDT_INCLUDE)
                if re.findall(eosio_cdt_include, c_cpp_properties):
                    c_cpp_properties = c_cpp_properties.replace(
                        re.findall(eosio_cdt_include, c_cpp_properties)[0],
                        EOSIO_CDT_HOME)
                print("adding {}".format(path_rel))
                zipfile_object.writestr(path_rel, c_cpp_properties)
            return True
        return False

    def project_files(search_dir, zipfile_object):
        files = []
        paths = os.listdir(search_dir)
        for file in paths:
            path = os.path.join(search_dir, file)
            if os.path.isfile(path):
                if not path == zip_file:
                    path_rel = os.path.relpath(path, contract_dir)
                    if is_valid(path_rel, ignore_list):
                        if not convert_c_cpp_properties(
                                path, path_rel, zipfile_object):
                            print("adding {}".format(path_rel))
                            zipfile_object.write(path, path_rel)
            else:
                project_files(path, zipfile_object)

    try:
        with zipfile.ZipFile(zip_file, mode='w') as zf:
            project_files(contract_dir, zf)
    except:
        raise errors.Error('''
            Cannot zip the directory
                {}
            to the zip file
                {}
            The error message is
            {}
        '''.format(os.path.realpath(contract_dir), os.path.realpath(zip_file),
                   str(e)))
Ejemplo n.º 17
0
def ABI(
        contract_dir_hint=None, c_cpp_properties_path=None,
        verbosity=None):
    '''Given a hint to a contract directory, produce ABI file.
    '''
    contract_dir = config.contract_dir(contract_dir_hint)
    # source_files[0] is directory, source_files[1] is contents:
    contract_source_files = config.contract_source_files(contract_dir)

    source_files = []
    source_ext = [".c", ".cpp",".cxx", ".c++"]
    for file in contract_source_files[1]:
        if os.path.splitext(file)[1].lower() in source_ext:
            source_files.append(file)

    if not source_files:
        raise errors.Error('''
        "The source is empty. The assumed contract dir is   
        {}
        '''.format(contract_dir))
        return

    code_name = os.path.splitext(os.path.basename(source_files[0]))[0]
    target_dir = get_target_dir(contract_source_files[0])
    target_path = os.path.normpath(
                        os.path.join(target_dir, code_name  + ".abi"))

    for file in contract_source_files[1]:
        if os.path.splitext(file)[1].lower() == ".abi":
            logger.INFO('''
            NOTE:
            An ABI exists in the source directory. Cannot overwrite it:
            {}
            Just copying it to the target directory.
            '''.format(file), verbosity)
            shutil.move(file, target_path)
            return

    command_line = [
        config.eosio_cpp(),
        "-contract=" + code_name,
        "-R=" + get_resources_dir(contract_source_files[0]),
        "-abigen",
        "-abigen_output=" + target_path]

    c_cpp_properties = get_c_cpp_properties(
                                    contract_dir, c_cpp_properties_path)

    for entry in c_cpp_properties[CONFIGURATIONS][0][INCLUDE_PATH]:
        if WORKSPACE_FOLDER in entry:
            entry = entry.replace(WORKSPACE_FOLDER, contract_dir)
            command_line.append(
                "-I" + utils.wslMapWindowsLinux(entry))
        else:
            if not EOSIO_CPP_INCLUDE in entry:
                command_line.append(
                    "-I" + utils.wslMapWindowsLinux(
                        strip_wsl_root(entry)))

    for file in source_files:
        command_line.append(file)

    try:
        eosio_cpp(command_line, target_dir)
    except Exception as e:
        raise errors.Error(str(e))

    logger.TRACE('''
    ABI file writen to file: 
        {}
    '''.format(target_path), verbosity)
Ejemplo n.º 18
0
def template_create(project_name,
                    template_dir=None,
                    workspace_dir=None,
                    remove_existing=False,
                    open_vscode=False,
                    throw_exists=False):
    '''Given the project name and template name, create a smart contract project.
    '''
    project_name = project_name.strip()

    template_dir = template_dir.strip()
    template_dir = utils.wslMapWindowsLinux(template_dir)
    if not template_dir:
        template_dir = config.DEFAULT_TEMPLATE
    if not os.path.isdir(template_dir):
        template_dir = os.path.join(config.eosf_dir(), TEMPLATE_CONTRACTS_DIR,
                                    template_dir)
    if not os.path.isdir(template_dir):
        raise errors.Error('''
        TemplateCreate '{}' does not exist.
        '''.format(template_dir))

    if not workspace_dir \
                            or not os.path.isabs(workspace_dir) \
                            or not os.path.exists(workspace_dir):
        workspace_dir = config.contract_workspace()
    workspace_dir = workspace_dir.strip()

    project_name = utils.wslMapWindowsLinux(project_name.strip())
    split = os.path.split(project_name)
    if os.path.isdir(split[0]):
        project_dir = project_name
        project_name = split[1]
    else:
        project_dir = os.path.join(workspace_dir, project_name)
    if os.path.isdir(project_dir):
        if os.listdir(project_dir):
            if remove_existing:
                try:
                    shutil.rmtree(project_dir)
                except Exception as e:
                    raise errors.Error(str(e))
            else:
                msg = '''
                NOTE:
                Contract workspace
                '{}'
                already exists. Cannot overwrite it.
                '''.format(project_dir)
                if throw_exists:
                    raise errors.Error(msg)
                else:
                    logger.ERROR(msg)
                    return

    try:  # make contract directory and its build directory:
        os.makedirs(os.path.join(project_dir, "build"))
    except Exception as e:
        raise errors.Error(str(e))

    def copy_dir_contents(project_dir, template_dir, directory, project_name):
        contents = os.listdir(os.path.join(template_dir, directory))

        for item in contents:
            path = os.path.join(directory, item)
            template_path = os.path.join(template_dir, path)
            contract_path = os.path.join(
                project_dir, path.replace(TEMPLATE_NAME, project_name))
            if os.path.isdir(template_path):
                os.mkdir(contract_path)
                copy_dir_contents(project_dir, template_dir, path,
                                  project_name)
            elif os.path.isfile(template_path):
                copy(template_path, contract_path, project_name)

    def copy(template_path, contract_path, project_name):
        with open(template_path, "r") as input:
            template = input.read()

        if TEMPLATE_HOME in template or TEMPLATE_ROOT in template:
            home = os.environ["HOME"]
            root = ""
            eosio_dir = config.eosio_repository_dir()
            if is_windows_ubuntu():
                home = config.wsl_root() + home
                root = config.wsl_root()
                eosio_dir = config.wsl_root() + eosio_dir

            template = template.replace(TEMPLATE_HOME, home)
            template = template.replace(TEMPLATE_ROOT, root)
            template = template.replace(TEMPLATE_EOSIO_DIR, eosio_dir)

        template = template.replace("@" + TEMPLATE_NAME + "@", project_name)
        with open(contract_path, "w") as output:
            output.write(template)

    copy_dir_contents(project_dir, template_dir, "", project_name)
    logger.TRACE('''
    * Contract project '{}' created from template '{}'
    '''.format(project_name, project_dir))

    if open_vscode:
        if is_windows_ubuntu():
            command_line = "cmd.exe /C code {}".format(
                utils.wslMapLinuxWindows(project_dir))
        elif uname() == "Darwin":
            command_line = "open -n -b com.microsoft.VSCode --args {}".format(
                project_dir)
        else:
            command_line = "code {}".format(project_dir)

        os.system(command_line)

    return project_dir
Ejemplo n.º 19
0
def WASM(
        contract_dir_hint, c_cpp_properties_path=None,
        compile_only=False, verbosity=None):
    '''Produce WASM code.
    '''
    contract_dir = config.contract_dir(contract_dir_hint)
    # source_files[0] is directory, source_files[1] is contents:
    contract_source_files = config.contract_source_files(contract_dir)

    source_files = []
    source_ext = [".c", ".cpp",".cxx", ".c++"]
    for file in contract_source_files[1]:
        if os.path.splitext(file)[1].lower() in source_ext:
            source_files.append(file)

    if not source_files:
        raise errors.Error('''
        "The source is empty. The assumed contract dir is   
            {}
        '''.format(contract_dir))
        return

    code_name = os.path.splitext(os.path.basename(source_files[0]))[0]
    target_dir = get_target_dir(contract_source_files[0])
    target_path = os.path.normpath(
                        os.path.join(target_dir, code_name  + ".wasm"))

    c_cpp_properties = get_c_cpp_properties(
                                        contract_dir, c_cpp_properties_path)

    command_line = [config.eosio_cpp()]

    for entry in c_cpp_properties[CONFIGURATIONS][0][INCLUDE_PATH]:
        if WORKSPACE_FOLDER in entry:
            entry = entry.replace(WORKSPACE_FOLDER, contract_dir)
            command_line.append("-I=" + utils.wslMapWindowsLinux(entry))
        else:
            if not EOSIO_CPP_INCLUDE in entry:
                command_line.append(
                    "-I=" + utils.wslMapWindowsLinux(strip_wsl_root(entry)))

    for entry in c_cpp_properties[CONFIGURATIONS][0]["libs"]:
        command_line.append(
            "-l=" + utils.wslMapWindowsLinux(strip_wsl_root(entry)))

    for entry in c_cpp_properties[CONFIGURATIONS][0]["compilerOptions"]:
        command_line.append(entry)
    
    for file in source_files:
        command_line.append(file)

    if setup.is_print_command_line:
        print("######## \n{}:".format(" ".join(command_line)))


    if compile_only:
        command_line.append("-c=")

    command_line.append("-o=" + target_path)

    try:
        eosio_cpp(command_line, target_dir)
    except Exception as e:                       
        raise errors.Error(str(e))

    if not compile_only:
        logger.TRACE('''
            WASM file writen to file: 
                {}
            '''.format(os.path.normpath(target_path)), verbosity)