class Shell: PIPE: _Pipe = _Pipe SHEXE: str = ('powershell ' if Settings.get('core', 'system') == System.WINDOWS else '/bin/bash ') SEP: str = ('; ' if Settings.get('core', 'system') == System.WINDOWS else ' && ') def __init__(self, stdout: TextIO = PIPE.SYSOUT): self._processes: List[str] = [] self._stdin: TextIO = None self._stdout: TextIO = stdout self._stderr: TextIO = self.PIPE.SUBPROC @property def _cmd(self) -> str: return self.SHEXE + self.SEP.join(self._processes) def write_process(self, cmd: str) -> Shell: self._processes += [cmd] return self def run(self) -> int: process: subprocess.Popen = subprocess.Popen( self._cmd, stdin=self._stdin, stdout=self._stdout, stderr=self._stderr, ) if stderr := process.communicate()[1] \ .decode(Settings.get('core', 'encoding')) \ .strip(): raise ProcessExecError(stderr) return process.returncode
def init_venv(cls) -> None: Settings.set( 'venv', "home", val=str( Path(Settings.get('venv', 'home')) / f'{Settings.get("project", "name")}-{Virtualenv.gen_hash()}'), ) Virtualenv.deploy()
def __init__( self, pname: str = None, wkdir: Path = Path('.'), ): self._pname: str = pname or Settings.get('project', 'name') self._wkdir: Path = wkdir
def _find_in_reqs(cls, pkg: str, *req_files: Tuple) -> Path: for req_file in req_files: if not req_file.exists(): continue for line in req_file.read_text( encoding=Settings.get('core', 'encoding')).split('\n'): if pkg.lower() == line.lower(): return req_file return None
def run(self) -> int: process: subprocess.Popen = subprocess.Popen( self._cmd, stdin=self._stdin, stdout=self._stdout, stderr=self._stderr, ) if stderr := process.communicate()[1] \ .decode(Settings.get('core', 'encoding')) \ .strip(): raise ProcessExecError(stderr)
def init_requirements(cls, root: Path = None) -> None: is_dev: bool = False for env, pkgs in cls._BASIC_PACKAGES.items(): for pkg in pkgs: if env == 'dev': is_dev = True cls.install( pkg, is_dev=is_dev, root=root or Path(Settings.get('project', 'name')), )
def _init(nolock: bool = True, dev: bool = False) -> None: # If not, consider that the project has not been initialized. if not Settings.FILE.exists(): Settings.set('project', 'name', val=Path('.').resolve().name) click.secho('Deploying settings...', fg=Main._INFO_COLOR) Pipa.init_settings(root=Path('.')) click.secho('Deploying venv...', fg=Main._INFO_COLOR) Pipa.init_venv() click.secho('Installing basic packages...', fg=Main._INFO_COLOR) Pipa.init_requirements(root=Path('.')) if nolock or not Packager.REQUIREMENTS_LOCK_FILE.exists(): has_req: bool = False click.secho('Installing requirements...', fg=Main._INFO_COLOR) if not Pipa.req_install(): click.secho('No requirements file found.', fg=Main._INFO_COLOR) else: has_req = True if dev: click.secho('Installing dev requirements...', fg=Main._INFO_COLOR) if not Pipa.req_install(dev=True): click.secho('No dev requirements file found.', fg=Main._INFO_COLOR) if has_req: click.secho('Locking packages...', fg=Main._INFO_COLOR) Pipa.lock() else: click.secho('Installing locked dependencies...', fg=Main._INFO_COLOR) if not Pipa.req_install(from_lock=True): click.secho('No locked file found.', fg=Main._INFO_COLOR)
def _register(cls, path: Path, pkg: str) -> None: with path.open('a', encoding=Settings.get('core', 'encoding')) as fh: fh.write(f'{pkg}\n')
def _unregister(cls, path: Path, pkg: str) -> None: req_pkgs: List[str] = path.read_text( encoding=Settings.get('core', 'encoding')).split('\n') req_pkgs.remove(pkg) path.write_text('\n'.join(req_pkgs), encoding=Settings.get('core', 'encoding'))
def _get_activate_cmd(cls) -> str: return (f'{Settings.get("venv", "home")}\\Scripts\\activate.ps1' if Settings.get('core', 'system') == System.WINDOWS else f'source {Settings.get("venv", "home")}/bin/activate')
def init_settings(cls, root: Path = None) -> None: Settings.init(root=root or Path(Settings.get('project', 'name')))
def init_template(cls, pname: str) -> None: Settings.set('project', 'name', val=pname) Template().deploy()