#!/usr/bin/env python # TODO use venv.EnvBuilder api # TODO write all to stderr import enum import os from pdb import run import re import sys from dataclasses import KW_ONLY, dataclass, field from operator import itemgetter from time import sleep import defl from defl import CLIError, Path, cl, log from defl._typing_ import * from dataclasses import dataclass, field import sys, re, os, enum, itertools from functools import partial, partialmethod from time import sleep from subprocess import Popen, PIPE, DEVNULL from operator import itemgetter from defl import log, cl, Path, Undefined, Null, Assert, Time, Obj, Dunder, IterableType, isIterableType, Run, checkType from defl import CLIError from defl._typing_ import * import defl @dataclass(slots=True, kw_only=True, frozen=False) class CLI: scriptDir: str | Path = None deflRoot: str | Path = None deflDevRoot: str | Path = None pipEnv: str | Path = None pipEnvPipfile: str | Path = None def __post_init__(_): _.scriptDir = Path(__file__).parent log.debug('_.scriptDir', lambda x: x._.scriptDir) cmd = ['git', '-C', _.scriptDir, 'rev-parse', '--show-toplevel'] _.deflRoot = Path(Run(cmd).log().run(T, T).wait().assSuc().outStr()[0]) log.debug('_.deflRoot', lambda x: x._.deflRoot) _.deflDevRoot = (_.deflRoot / '..' / 'deflDev').resolve() _.pipEnv = _.deflDevRoot / 'deflDev' _.pipEnvPipfile = _.pipEnv / 'Pipfile' if not _.deflDevRoot.isDir(): msg = f'Path does not exist {_.deflDevRoot}\n' msg += f' cp -R {_.deflRoot.absolute()} {_.deflDevRoot.absolute()}\n' msg += f' git -C {_.deflDevRoot.absolute()} checkout development' defl.exitWithError(msg) _.pipEnv.chdir() log.debug('Change dir', _.pipEnv) def merge(_): ddRoot = ['git', '-C', _.deflDevRoot] dRoot = ['git', '-C', _.deflRoot] Run([*ddRoot, 'checkout', 'development']).log().run(T, T).wait().assSuc() Run([*ddRoot, 'fetch', 'origin', 'master']).log().run(T, T).wait().assSuc() Run([*ddRoot, 'merge', 'origin/master']).log().run(T, T).wait().assSuc() if Run([*ddRoot, 'diff', '--name-only']).log().run(T, T).wait().assSuc().out.bytz: log.error('dirty branch', _.deflDevRoot) sys.exit(1) Run([*ddRoot, 'push']).log().run(T, T).wait().assSuc() Run([*dRoot, 'fetch', 'origin', 'development']).log().run(T, T).wait().assSuc() Run([*dRoot, 'checkout', 'master']).log().run(T, T).wait().assSuc() Run([*dRoot, 'merge', 'origin/development']).log().run(T, T).wait().assSuc() Run([*dRoot, 'add', '.']).log().run(T, T).wait().assSuc() Run([*dRoot, 'pull']).log().run(T, T).wait().assSuc() if Run([*dRoot, 'diff', '--name-only']).log().run(T, T).wait().assSuc().out.bytz: Run([*dRoot, 'commit', '-m', str(sys.argv)]).log().run(T, T).wait().assSuc() else: log.info('No changes in', _.deflRoot) Run([*dRoot, 'pull']).log().run(T, T).wait().assSuc() Run([*dRoot, 'push']).log().run(T, T).wait().assSuc() Run([*dRoot, 'checkout', 'development']).log().run(T, T).wait().assSuc() def rm(_): if _.pipEnvPipfile: log.debug(f'rm {_.pipEnv.q}') else: log.warning(f'No pipfile', _.pipEnv) def _tryToInstall(_): # envRoot = _.deflRoot / 'deflDev' # if envRoot.glob('*'): # log.error('clear the env folder', envRoot) log.error('try to install the env', sys.argv[0] + ' install') sys.exit(1) def virtEnvRoot(_): def getVirtEnvRoot(): log.debug('Creating VirtEnvRoot cache') pythonBin = Run(['pipenv', 'run', 'which', 'python']).log().run(F, T).wait().assSuc().outStr()[0] return str(Path(pythonBin).parent.parent) virtEnvCache = defl.LoadOrNew('virtEnvRoot') virtEnvRoot = virtEnvCache.load(getVirtEnvRoot) res = Path(virtEnvRoot) if defl.amCliEntryPoint(): log.info(res) return res def activationFile( _, printOut=True ): # TODO remove print true by somehow setting the subparser in argfromobj res = _.virtEnvRoot() / 'bin/activate' if printOut: log.info(res) return res def default(_, *extra): if not _.deflDevRoot.isDir(): remoteUrl = oneLineRet(['git', '-C', _.scriptDir, 'remote', 'get-url', 'origin']) log.debug('remoteUrl', lambda x: x.remoteUrl) Run(['git', 'clone', '--', remoteUrl, _.deflDevRoot]).log().run(F, T).wait().assSuc() curBranch = oneLineRet(['git', '-C', _.deflDevRoot, 'rev-parse', '--abbrev-ref', 'HEAD']) log.debug('curBranch', lambda x: x.curBranch) devBranch = 'development' if curBranch != devBranch: Run(['git', '-C', _.deflDevRoot, 'checkout', devBranch]).log().run(F, T).wait().assSuc() if not _.pipEnvPipfile.isfile(): _._tryToInstall() with defl.suppressStackTraceCM(defl.CommandFailedException): virtEnvRoot = _.virtEnvRoot() activateFile = _.activationFile() log.debug('pipenv root', virtEnvRoot) log.debug('activation file', activateFile) cmd = '' if not activateFile.isfile(): log.error('does not exist', activateFile) _._tryToInstall() cmd += defl.shlexQuoteList(['source', activateFile]) cmd += " ; " cmd += defl.shlexQuoteList(extra) cmd = ['bash', '-c', cmd] res = Run(cmd).log().run(F, T).wait().assSuc() log.debug(defl.shlexQuoteList(sys.argv), 'exitcode', res.status) def install(_): _.pipEnv.mkdirForce() install = ['python', '-m', 'pip', 'install', '-e', f'{_.deflDevRoot}[all]'] Run(['pipenv', 'run'] + install).log().run(F, T).wait().assSuc() if __name__ == '__main__': defl.cliAutoParse(CLI, parseExtraArgs=True, runIfNoSubParserSelected='-', mapSubParsers={'-': 'default'})