def wsl_root(): '''The root directory of the Windows WSL, or empty string if not Windows. The root directory of the Ubuntu file system, owned by the installation, if any, of the Windows Subsystem Linux (WSL). It may be changed with *WSL_ROOT* entry in the *config.json* file, see :func:`.current_config`. ''' if not utils.is_windows_ubuntu(): return "" wsl_root_sh = "wsl_root.sh" wsl_root_sh = os.path.join(eosfactory_data(), wsl_root_sh) if wsl_root_[1][0] is None: path = "" path, error = utils.spawn([wsl_root_sh, path], raise_exception=False) if error: while True: if not os.path.exists(wsl_root_sh): path = "" logger.ERROR(''' Cannot find the bash command: '{}' The intelisense feature of Visual Studio Code will be disabled. '''.format(wsl_root_sh), translate=False) break path = input( logger.error(''' Error message is {} Cannot find the root of the WSL file system which was tried to be '{}' Please, find the path in your computer and enter it. Enter nothing, if you do not care about having efficient the intelisense of Visual Studio Code. '''.format(error, path), translate=False) + "\n<<< ") if not path: break path, error = utils.spawn([wsl_root_sh, path], raise_exception=False) if not error: break path = path.replace("\\", "/") path = path.replace(path[0:2], path[0:2].lower()) wsl_root_[1][0] = path return wsl_root_[1][0]
def project_from_template( project_name, template=None, workspace_dir=None, c_cpp_prop_path=None, includes=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_dir() function. includes: 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 = linuxize_path(project_name.strip()) template = linuxize_path(template.strip()) template_dir = template if os.path.isdir(template) else \ os.path.join(config.template_dir(), template) if not os.path.isdir(template_dir): raise errors.Error(''' The contract project template '{}' does not exist. '''.format(template_dir)) if c_cpp_prop_path: c_cpp_prop_path = linuxize_path(c_cpp_prop_path) if os.path.exists(c_cpp_prop_path): try: with open(c_cpp_prop_path, "r") as f: c_cpp_properties = f.read() except Exception: c_cpp_properties = vscode.c_cpp_properties() else: c_cpp_properties = vscode.c_cpp_properties() c_cpp_properties_json = json.loads(c_cpp_properties) if includes: temp = includes.split(", ") temp_ = [] for entry in temp: path = naturalize_path(entry) if not path in c_cpp_properties_json[CONFIGURATIONS][0]\ [vscode.INCLUDE_PATH]: temp_.append(path) c_cpp_properties_json[CONFIGURATIONS][0][vscode.INCLUDE_PATH]\ .extend(temp_) c_cpp_properties_json[CONFIGURATIONS][0][BROWSE]["path"].extend(temp_) path = config.eoside_includes_dir() if path: path = naturalize_path(path) if not path in c_cpp_properties_json[CONFIGURATIONS][0]\ [vscode.INCLUDE_PATH]: c_cpp_properties_json[CONFIGURATIONS][0]\ [vscode.INCLUDE_PATH].append(path) c_cpp_properties_json[CONFIGURATIONS][0][BROWSE]["path"]\ .append(path) if libs: temp = libs.split(", ") temp_ = [] for entry in libs: path = naturalize_path(entry) if not path in c_cpp_properties_json[CONFIGURATIONS][0]\ [vscode.LIBS]: temp_.append(path) c_cpp_properties_json[CONFIGURATIONS][0][vscode.LIBS].extend(temp_) eoside_libs = config.eoside_libs_dir() if(eoside_libs): eoside_libs = os.listdir(config.eoside_libs_dir()) for lib in eoside_libs: path = naturalize_path(lib) if not path in c_cpp_properties_json[CONFIGURATIONS][0]\ [vscode.LIBS]: c_cpp_properties_json[CONFIGURATIONS][0]\ [vscode.LIBS].append(path) c_cpp_properties = json.dumps(c_cpp_properties_json, indent=4) c_cpp_properties = resolve_home(c_cpp_properties) 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_dir() 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) try: os.makedirs(os.path.join(project_dir, "build")) os.makedirs(os.path.join(project_dir, "tests")) os.makedirs(os.path.join(project_dir, "include")) 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) \ and not "__pycache__" in template_path: if not os.path.exists(contract_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 f: template = f.read() if TEMPLATE_HOME in template: resolve_home(template) template = template.replace(C_CPP_PROP, c_cpp_properties) template = template.replace(TASK_JSON, vscode.TASKS) template = template.replace("${" + TEMPLATE_NAME + "}", project_name) with open(contract_path, "w") as output: output.write(template) copy_dir_contents(project_dir, PROJECT_0_DIR, "", project_name) if not template_dir == PROJECT_0_DIR: copy_dir_contents(project_dir, template_dir, "", project_name) if open_vscode: if utils.is_windows_ubuntu(): command_line = "cmd.exe /C code {}".format( utils.wslMapLinuxWindows(project_dir)) elif utils.os_version() == utils.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_dir, template_dir), verbosity) return project_dir
def __init__(self, is_html=False, error_codes=""): self.is_html = is_html self.html_text = "" self.is_error = False self.is_warning = False self.IS_WINDOWS = utils.is_windows_ubuntu() self.os_version = utils.os_version() self.print_msg("EOSFactory version {}".format(config.VERSION)) ################################################################################ # psutil ################################################################################ try: if "psutil" in error_codes: import psutil1 else: import psutil except ImportError: command = "pip3 install --user psutil" button = ''' <button style="text-align:left;" class="btn ${{BASH_COMMAND}}"; class="btn"; id="Install psutil"; title="Install psutil. Click the button then ENTER in a newly created bash terminal window, to go." > {} </button> '''.format(command) self.error_msg(''' Module 'psutil' is not installed. Install it: {} '''.format(button)) self.print_error('''Module 'psutil' is not installed. Install it: ''') self.print_code("`{}`\n".format(command)) ################################################################################ # termcolor ################################################################################ try: if "termcolor" in error_codes: import termcolor1 else: import termcolor except ImportError: command = "pip3 install --user termcolor" button = ''' <button style="text-align:left;" class="btn ${{BASH_COMMAND}}"; class="btn"; id="Install termcolor"; title="Install termcolor. Click the button then ENTER in a newly created bash terminal window, to go." > {} </button> '''.format(command) self.error_msg(''' Module 'termcolor' is not installed. Install it: {} '''.format(button)) self.print_error('''Module 'termcolor' is not installed. Install it: ''') self.print_code("`{}`\n".format(command)) if self.IS_WINDOWS: ################################################################################ # Ubuntu version ################################################################################ lsb_release, error = utils.spawn(["lsb_release", "-r", "-s"], raise_exception=False) if error: self.error_msg(error) else: if "ubuntuversion" in error_codes: lsb_release = "16.4.1" ubuntu_version = int(lsb_release.split(".")[0]) if ubuntu_version < config.UBUNTU_VERSION_MIN: msg = \ ''' WSL Ubuntu version is {}. EOSIO nodeos can fail with Windows WSL Ubuntu below version 16. '''.format(lsb_release) self.status_msg(self.warning(msg)) self.print_warning(msg) ################################################################################ # WSL root ################################################################################ root = config.wsl_root() if not root or "wslroot" in error_codes: self.error_msg( '''Cannot determine the root of the WSL. Set it: <button class="btn ${FIND_WSL}"; id=""; title="Click the button to open file dialog. Navigate to a directory containing the Ubuntu file system." > Indicate WSL root </button> ''') self.print_error( '''Cannot determine the root of the WSL. To indicate it, use the command:''' ) self.print_code("`python3 -m eosfactory.config --wsl_root`\n") ################################################################################ # eosio ################################################################################ eosio_version = config.eosio_version() if "eosio" in error_codes: eosio_version = ["", "1.8.0"] # eosio_version = ["1.3.3", "1.8.0"] if eosio_version[0]: self.status_msg("Found eosio version {}".format(eosio_version[0])) self.print_status("Found eosio version {}".format( eosio_version[0])) if not eosio_version[0] or len(eosio_version) > 1\ and not self.equal(eosio_version[0], eosio_version[1]): command = "" if self.os_version == utils.UBUNTU: ubuntu_version = utils.spawn( ["lsb_release", "-r", "-s"], raise_exception=False)[0].split(".")[0] if ubuntu_version and ubuntu_version == 16: command = \ '''sudo apt remove eosio &&\\ wget https://github.com/eosio/eos/releases/download/v1.8.0/eosio_1.8.0-1-ubuntu-16.04_amd64.deb &&\\ sudo apt install ./eosio_1.8.0-1-ubuntu-16.04_amd64.deb ''' else: command = \ '''sudo apt remove eosio &&\\ wget https://github.com/eosio/eos/releases/download/v1.8.0/eosio_1.8.0-1-ubuntu-18.04_amd64.deb &&\\ apt install ./eosio_1.8.0-1-ubuntu-18.04_amd64.deb ''' elif self.os_version == utils.DARWIN: command = \ '''brew remove eosio &&\\ brew tap eosio/eosio &&\\ brew install eosio ''' button = ''' <button style="text-align:left;" class="btn ${{BASH_COMMAND}}"; class="btn"; id="Install eosio v{0}"; title="Install eosio v{0}. Click the button then ENTER in a newly created bash terminal window, to go." > {1} </button> '''.format(eosio_version[1], command) instructions = '<a href="https://github.com/EOSIO/eos">EOSIO installation instructions</a>' if eosio_version[0] and len(eosio_version) > 1: self.warning_msg(''' NOTE: EOSFactory was tested with version {0} while installed is {1}. Install eosio v{0}:<br> {2} '''.format(eosio_version[1], eosio_version[0], button if command else instructions)) self.print_warning( '''NOTE: EOSFactory was tested with version {0} while installed is {1}. Install eosio v{0}: '''.format(eosio_version[1], eosio_version[0])) self.print_code('''``` {} ``` '''.format(command if command else instructions)) else: if not "ignoreeoside" in error_codes: self.warning_msg(''' Cannot determine that eosio is installed as nodeos does not response.<br> It hangs up sometimes.<br> EOSFactory expects eosio version {}. Install eosio, if not installed:<br> {}<br> '''.format(eosio_version[1], button if command else instructions)) self.print_warning( '''Cannot determine that eosio is installed as nodeos does not response. It hangs up sometimes. EOSFactory expects eosio version {}. Install eosio, if not installed: '''.format(eosio_version[1])) self.print_code('''``` {} ``` '''.format(command if command else instructions)) ################################################################################ # eosio_cdt ################################################################################ eosio_cdt_version = config.eosio_cdt_version() if "eosio_cdt" in error_codes: eosio_cdt_version = ["", "1.6.0"] # eosio_cdt_version = ["1.6.1", "1.6.0"] if eosio_cdt_version[0]: self.status_msg("Found eosio.cdt version {}.".format( eosio_cdt_version[0])) self.print_status("Found eosio.cdt version {}.".format( eosio_cdt_version[0])) if not eosio_cdt_version[0] or len(eosio_cdt_version) > 1\ and not self.equal(eosio_cdt_version[0], eosio_cdt_version[1]): command = "" if self.os_version == utils.UBUNTU: command = \ '''sudo apt remove eosio.cdt &&\\ wget https://github.com/eosio/eosio.cdt/releases/download/v1.6.1/eosio.cdt_1.6.1-1_amd64.deb &&\\ sudo apt install ./eosio.cdt_1.6.1-1_amd64.deb ''' elif self.os_version == utils.DARWIN: command = \ '''brew remove eosio.cdt &&\\ brew tap eosio/eosio.cdt && \\ brew install eosio.cdt ''' button = ''' <button style="text-align:left;" class="btn ${{BASH_COMMAND}}"; class="btn"; id="Install eosio.cdt v{0}"; title="Install eosio.cdt v{0}. Click the button then ENTER in a newly created bash terminal window, to go." > {1} </button> '''.format(eosio_cdt_version[1], command) instructions = '<a href="https://github.com/EOSIO/eosio.cdt">EOSIO.cdt installation instructions</a>' if eosio_cdt_version[0] and len(eosio_cdt_version) > 1 \ and not eosio_cdt_version[0] == eosio_cdt_version[1]: self.warning_msg(''' NOTE: EOSFactory was tested with version {0} while installed is {1}. Install eosio.cdt v{0}:<br> {2} '''.format(eosio_cdt_version[1], eosio_cdt_version[0], button if command else instructions)) self.print_warning( '''NOTE: EOSFactory was tested with version {0} while installed is {1}. Install eosio v{0}: '''.format(eosio_cdt_version[1], eosio_cdt_version[0])) self.print_code('''``` {} ``` '''.format(command if command else instructions)) else: self.error_msg(''' Cannot determine that eosio.cdt is installed as eosio-cpp does not response.<br> EOSFactory expects eosio.cdt version {}. Install it, if not installed. {}<br> '''.format(eosio_cdt_version[1], button if command else instructions)) self.print_error( '''Cannot determine that eosio.cdt is installed as eosio-cpp does not response. EOSFactory expects eosio.cdt version {}. Install it, if not installed. '''.format(eosio_cdt_version[1])) self.print_code('''``` {} ``` '''.format(command if command else instructions)) ################################################################################ # Default workspace ################################################################################ try: contract_workspace_dir = config.contract_workspace_dir() except: contract_workspace_dir = None button = ''' <button class="btn ${CHANGE_WORKSPACE}"; id="${CHANGE_WORKSPACE}"; title="Set workspace" > Set workspace. </button> ''' if not contract_workspace_dir or "workspace" in error_codes: self.error_msg(''' Default workspace is not set, or it does not exist.{} '''.format(button)) else: self.status_msg('''Default workspace is {}.{} '''.format(contract_workspace_dir, button))