====== NervProj: support for dedicated python env ====== {{tag>dev python nervproj}} I'm just about to start working on a new large python project, and I would like to use my **NervProj** to handle the project management part. But the proble now is that I still need to be able to run that new project completely independently from NervProj itself. So this means I should setup a dedicated python environment in this kind of sub project. Let's see here how we should proceed step by step. ====== ====== ==== Regular/embedded sub project ==== * So let's say I'm working on a project called "my_project", and with code name "myp". * My current "regular" process is to do the following: * Create the project repository on my gitlab server (say in sub path /my_group/my_project) * Then add that project in the master **nervproject.config.json** file: { "projects": [ { "names": ["my_project", "myp"], "repository_url": "ssh://git@gitlab.nervtech.org:22002/my_group/my_project.git" } ] } * Then I checkout the project: $ cd /cygdrive/d/Projects $ nvp -p myp git clone * And finally I perform the project init stage: $ nvp -p myp admin init 2022/04/27 14:03:26 [nvp.components.admin] INFO: No change in C:\Users\kenshin\AppData\Roaming\Code\User\settings.json 2022/04/27 14:03:26 [nvp.components.admin] INFO: Wrtting updated vscode settings in D:\Projects\my_project\.vscode\settings.json 2022/04/27 14:03:26 [nvp.components.admin] INFO: Writting python env file D:\Projects\my_project\.vs_env 2022/04/27 14:03:26 [nvp.components.admin] INFO: Writting editor config file D:\Projects\my_project\.editorconfig 2022/04/27 14:03:26 [nvp.components.admin] INFO: Writting .gitignore file D:\Projects\my_project\.gitignore 2022/04/27 14:03:26 [nvp.components.admin] INFO: Writting .gitattributes file D:\Projects\my_project\.gitattributes 2022/04/27 14:03:26 [nvp.components.admin] INFO: Writting nvp_config.json file D:\Projects\my_project\nvp_config.json 2022/04/27 14:03:26 [nvp.components.admin] INFO: Writting nvp_plug.py file D:\Projects\my_project\nvp_plug.py 2022/04/27 14:03:26 [nvp.components.admin] INFO: Adding pull section in git config. ==== Extending the init command ==== * => I think it is in the init command above that I should introduce the required updates: * I need a flag to disable the deployment of the NVP plugin files (nvp_config.json/nvp_plug.py) ? Or maybe not: that is not really important for now so let's not do it. * I need to add a flag to deploy the python packages such as: $ nvp -p myp admin init --with-py-env * **Note** also using the short flag version: $ nvp -p myp admin init -p * And so I've started to update the init command with some special handling whena python env deployment is requested: ignore_elems = [] if with_py: # We deploy the python packages: dest_dir = self.get_path(proj_dir, "tools", "packages") self.make_folder(dest_dir) # get the python version on windows: py_vers = {} sevenzip_vers = {} for plat_name in ["windows", "linux"]: for el in self.config[f'{plat_name}_tools']: if el["name"] == 'python': py_vers[plat_name] = el["version"] if el["name"] == '7zip': sevenzip_vers[plat_name] = el["version"] for plat_name, py_version in py_vers.items(): for ext in [".7z", ".tar.xz"]: file_name = f"python-{py_version}-{plat_name}{ext}" src_file = self.get_path(self.ctx.get_root_dir(), "tools", "packages", file_name) dst_file = self.get_path(dest_dir, file_name) if self.file_exists(src_file) and not self.file_exists(dst_file): logger.info("Adding package file %s", dst_file) self.copy_file(src_file, dst_file) # Next, for the windows part we need to deploy the 7zip package too: folder_name = f"7zip-{sevenzip_vers['windows']}" src_folder = self.get_path(self.ctx.get_root_dir(), "tools", "windows", folder_name) dst_folder = self.get_path(proj_dir, "tools", "windows", folder_name) if not self.dir_exists(dst_folder): logger.info("Adding windows 7zip package at %s", dst_folder) self.copy_folder(src_folder, dst_folder) # Update the ignore elements: ignore_elems += ["", "# Ignore all the windows tools except the 7zip folder:", "tools/windows/*", "!tools/windows/7zip-*", "tools/linux/*"] # Should also install an requirements.txt file: dest_file = self.get_path(proj_dir, "tools", "requirements.txt") if not self.file_exists(dest_file): logger.info("Installing pythong requirements file.") content = ["# List here all the required python packages," "# Then call install_requirements.sh/install_requirements.bat" "pylint", "autopep8", ""] content = "\n".join(content) self.write_text_file(content, dest_file) * Next step at this level is to also deploy some shell scripts to allow running the python app => I can use the NervProj cli.sh/cli.bat as a starting point, but I don't need to support building python from sources here. * => **OK**, so now in the init command I'm also installing the required scripts as follow: # Should install the cli script files: dest_file = self.get_path(proj_dir, "cli.py") if not self.file_exists(dest_file): logger.info("Writting cli python file %s", dest_file) content = DEFAULT_CLI_PY_CONTENT self.write_text_file(content, dest_file) dest_file = self.get_path(proj_dir, "cli.sh") if not self.file_exists(dest_file): logger.info("Writting cli shell file %s", dest_file) content = DEFAULT_CLI_SH_CONTENT content = content.replace("${PROJ_NAME}", proj_name.lower()) # Use the linux python version below: content = content.replace("${PY_VERSION}", py_vers['linux']) self.write_text_file(content, dest_file, newline="\n") dest_file = self.get_path(proj_dir, "cli.bat") if not self.file_exists(dest_file): logger.info("Writting cli batch file %s", dest_file) content = DEFAULT_CLI_BAT_CONTENT content = content.replace("${PROJ_NAME}", proj_name.upper()) # Use the windows versionq below: content = content.replace("${PY_VERSION}", py_vers['windows']) content = content.replace("${ZIP_VERSION}", sevenzip_vers['windows']) self.write_text_file(content, dest_file) => And that is basically all I had to update: with that I can now create subproject with the NervProj framework that have their own python environment 👍!