def test_config(): pc = PathConfig(root_envi, ROOT_CONFIG_DIR) x = pc.get_all_platform_data_roots() assert pc.is_site_configuration() assert 'primary' in x assert 'secondary' in x x = template.read_templates(pc) assert x apackdir = os.path.join(root_envi,BaseEnv.envi_iddir(),BaseEnv.pack_tag()) aconfdir = os.path.join(root_envi,BaseEnv.envi_iddir(),BaseEnv.config_tag()) envi_info = os.path.join(os.environ.get('DSKENVPATH'), 'configs_and_packs/envi_info.yml') bad_envi_info = '/mnt1/dev/dsk_configuration/envi/configs_and_packs/envi_info.yml' #d = {'Config': root_envi} d = {'Config': ('envi'),'name' : ('info')} a = x["envi_info"].apply_fields(d) assert a == envi_info a = x["envi_info"].missing_keys({}) assert set(a) == set(d.keys()) assert aconfdir == x["config_path"].apply_fields(d) assert apackdir == x["pack_path"].apply_fields(d) assert x['envi_info'].validate_and_get_fields(bad_envi_info) == None
def reduce_current(self, envDic): """Use the meta to shorten the path # should manage a date... for now use current """ metafile = BaseEnv.compiled_json(self.name) if not os.path.isfile(metafile): return False try: f = open(metafile, "r") except: return False try: metadata = json.load(f) except: f.close() return False f.close() if BaseEnv.COMPILED_ENVDATA not in metadata: return False envData = metadata[BaseEnv.COMPILED_ENVDATA] for envKey in envData: if envKey in envDic: lensaveLen = len(envDic[envKey]) for p in envData[envKey]: envDic[envKey] = [x for x in envDic[envKey] if x != p] if lensaveLen != len(envDic[envKey]): insertPath = BaseEnv.short_path(self.name, envKey) if insertPath not in envDic[envKey]: envDic[envKey].insert(0, insertPath) return True
def execute_dict_only(self, argvs, envp=""): """This is a way to get the final result of couple envi command return as a dictionary. os.environ is fully restore :param argvs: a list of list envi command :returns dict: True if success """ result = dict() # take a snapshot SAVE_OS = dict() SAVE_OS.update(os.environ) if envp != "": BaseEnv._reset(envp) os.environ[dskenv_constants.DSK_ENV_PATH_KEY] = envp for argv in argvs: dolist = ['dict_only'] dolist.extend(argv) dolist.append("-Dodict") if self.execute(dolist, True): local_res = self.get_environ(withRemoveCmd=False) os.environ.update(local_res) self.expand_vars(os.environ) result.update(os.environ) self.reset() dd = list(os.environ.keys()) for i in dd: os.environ.pop(i) # restore os.environ os.environ.update(SAVE_OS) BaseEnv._reset("") return result
def reset(self, envplace=""): """overwrite the class instance file_location :param envplace: path (str) to the envi location :return None: """ if envplace != "": EnviApi.__file_location = os.path.join(envplace, BaseEnv.envi_iddir(), BaseEnv.envi_file_name()) self.dev_user = list()
def get_asset_publish_area(self, atype=""): if atype == "": return ProxyShow.usep( os.path.join(self.get_publish_area(), BaseEnv.MAIN_ASSET)) assert atype in BaseEnv.get_asset_publish_type() return ProxyShow.usep( os.path.join(self.get_publish_area(), BaseEnv.MAIN_ASSET, atype))
def build_command_history(self): cmdlist = self.get_commands() # sys.stderr.write("commd %s\n" % cmdlist) cmd = " ".join(cmdlist) cmd = cmd.strip() prev = os.environ.get(BaseEnv.get_command_info(), "") if prev == "": self.setPath(BaseEnv.get_command_info(), cmd) else: # don't add if the last is the same sprev = prev.split(BaseEnv.commandsep) if len(sprev) > 0: if cmd != sprev[-1].replace("envi ", "").replace(";", ""): # don't add if the last command is the same self.setPath(BaseEnv.get_command_info(), prev + BaseEnv.commandsep + cmd)
def owner(self): """Return the owner name """ if self.path: return BaseEnv.is_env_user(self.path) return ""
def get_normal_path(self, apath): ''' to convert from real to normalized path returns: norm path ''' apath = apath.replace(ProxyShow.__realbase, BaseEnv.studio_root()) return apath
def get_all_envlaunch(self, project_name="", users=None): """Return all possible config path :param project_name: str default "" :param users: default None :return config launch information: :rtype: ResultConfigInstall """ result = list() if project_name == "": for ch in self.project_list: for pp in ch.path_configs: if os.path.isdir(pp): result.append(ResultConfigInstall( pp, False, ch.get_name())) else: for ch in self.project_list: if ch.get_name() == DSK_DEV_SHOW: for pp in ch.path_configs: if os.path.isdir(pp): result.append(ResultConfigInstall( pp, False, "studio")) elif project_name == ch.get_name(): for pp in ch.path_configs: if os.path.isdir(pp): result.append(ResultConfigInstall( pp, False, ch.get_name())) all_users = list() if users: if users == "all": all_users = self.get_all_user_login() else: if isinstance(users, str): users = [users] all_users = users for user in all_users: pprojets = self.get_userdev_project(user) ppaths = self.get_userdev_config_path(user) if project_name in pprojets or project_name == "": for index, pp in enumerate(ppaths): pp = os.path.expandvars(os.path.expanduser(pp)) if os.path.isdir(pp): result.append(ResultConfigInstall( pp, True, user + "_xonfig%d" % index)) if len(result) == 0: for x in BaseEnv.user_envi_home(): result.append(ResultConfigInstall(x, True, "dev")) return result
def store(self): """Create an pack file with define environment """ file_init = self.pack_system() file_init = file_init+".py" a_file = os.path.join(BaseEnv.base_pack(), file_init) try: with open(a_file, "w") as fh: for x in os.environ: if x in BaseEnv.LIST_OF_KEY: fh.write("set_path(%r,%r)\n" % (x, os.environ.get(x))) except Exception as e: raise Exception("Cannot store file: %s" % e)
def test_add_user(): x = dsk_release_lib.DskReleaseLib() x.load_data() user = "******" newu = DevUser() newu.setdata( **{ 'login': user, 'email': '*****@*****.**', 'shotgun_name': 'fakeuser blah', 'dev_path': '/asdjad/asdjkasd', 'dev_path_configs': ['fooo', 'fsdf'], 'projects': ['dev_show'] }) assert not user in x.get_all_user_login() file_location = BaseEnv.envi_info_location() ei = EnviInfoHelper() assert ei.add_user(file_location, afile, newu)
def test_add_repo(): x = dsk_release_lib.DskReleaseLib() x.load_data() reponame = "fakerepo" newrepo = RepoInstall() newrepo.setdata( **{ 'name': reponame, 'new_version': 'true', 'do_version': 'true', 'pack_update': 'true', 'shortname': 'shortfake', 'path': '*****@*****.**', 'type': 'git', 'branch': '' }) assert "" == x.name_repo(reponame) file_location = BaseEnv.envi_info_location() print(file_location, afile2) ei = EnviInfoHelper() assert ei.add_repo(file_location, afile2, newrepo)
def get_history_command(cls, with_app=False, remove_app=True, index=0): """Return all the envi commands sent :param with_app: default=False if true don't add command containing '-a app' :param remove_app: default=False :param index: default 0. if 1 remove the last statement 2 two last statement etc... :returns list: a list of envi command """ x = BaseEnv.command_history() paternapp = re.compile(r'-a\s*[\w\d\.\%s-]*' % os.sep) envcmd = list() for xx in x: m = paternapp.search(xx) if with_app is True: # remove -a appname for cmd if m: if remove_app is True: stringfound = m.group() envarg = xx.replace(stringfound, "") xx = envarg.strip() else: continue # no adding else: if m: xx = [] if len(xx) > 0: envcmd.append([xx]) if index != 0: try: envcmd = envcmd[:-index] except: pass # remove last indexes return envcmd
def write_bash_history(self): """Export only l'historic store in _BASE_COMMAND """ global cmdout write = None ret = "" if hasattr(cmdout, "info"): write = cmdout.info else: if hasattr(cmdout, "write"): write = cmdout.write ret = "\n" if write is None: comment.error("cannot print this object in echo\n") return key = BaseEnv.get_command_info() if key in self._storeLocalEnv: if len(self._storeLocalEnv[key]) > 0: value = self._storeLocalEnv[key][0] write(MiniEnv._shellFormatSetEnv.format(key, value)) if ret != "": write(ret) return True return False
def build_history_variable(self, withRemoveCmd=False): self._storeLocalEnv[BaseEnv.get_key_pack_info()] = [ os.path.join(x.path, x.format()) for x in self.packsObject ] self._storeLocalEnv[BaseEnv.get_key_pack_info()] = BaseEnv.shorten( self._storeLocalEnv[BaseEnv.get_key_pack_info()]) if withRemoveCmd is False: # since no history is of with don't rebuild # from scratch so here with merge with current older = os.environ.get(BaseEnv.get_key_pack_info(), "") older = older.split(os.pathsep) for o in reversed(older): if o not in self._storeLocalEnv[BaseEnv.get_key_pack_info()]: self._storeLocalEnv[BaseEnv.get_key_pack_info()].insert( 0, o) self._storeLocalEnv[BaseEnv.get_key_config_info()] = [ os.path.join(x.path, x.format()) for x in self.configsObject ] self._storeLocalEnv[BaseEnv.get_key_config_info()] = BaseEnv.shorten( self._storeLocalEnv[BaseEnv.get_key_config_info()]) if withRemoveCmd is False: # since no history is of with don't rebuild from scratch # so here with merge with current older = os.environ.get(BaseEnv.get_key_config_info(), "") older = older.split(os.pathsep) for o in reversed(older): if o not in self._storeLocalEnv[BaseEnv.get_key_config_info()]: self._storeLocalEnv[BaseEnv.get_key_config_info()].insert( 0, o)
def parse_cmd(self, argListOrStr): # to support 2.6 and 2.7 if sys.version_info.major > 2 or sys.version_info.minor >= 7: args = self.parse_cmd_base(argListOrStr) else: args = self.parse_cmd_base26(argListOrStr) # args = self.parse_cmd_base(argListOrStr) opt = args[0] clip_time = -1 if opt.date != "": res = opt.date.split("%s" % MiniEnv._sepDateTime) # separator / if len(res) == 2: clip_time = EnviUtils.convert_date_and_time_to_float_time( res[0], res[1]) else: clip_time = EnviUtils.convert_date_and_time_to_float_time( opt.date) configDir = "" for c in opt.configs: # check if the file has been check out a = ConfigInfo(BaseEnv.clean(c), None) if configDir != "": rc = a.real_version_file(ConfigInfo, None) else: rc = a.real_version_file(ConfigInfo, self._searchPath) if rc is None or rc.is_valid() is False: if configDir != "": comment.error("no config %r found in %s" % (c, configDir)) self.logfile("parse_cmd: no config %r found %s" % ( c, configDir)) else: comment.error("no config %r found in %s" % ( c, self._searchPath)) self.logfile("no config %r found in %s" % ( c, self._searchPath)) else: if self.load_config_or_pack(rc.get_fullname()) is False: comment.error("couldn't load successfully %s" % ( rc.get_fullname())) self.logfile("couldn't load successfully %s" % ( rc.get_fullname())) else: self._configFound[rc.name] = rc.path for p in opt.packs: # comment.error("----> pack %r" % p) self.addPack(BaseEnv.clean(p)) for pc in self._packListName: # comment.error("----> pack %r %r" % (pc,self._searchPath)) pf = PackInfo(pc, None) rc = pf.real_version_file(PackInfo, self._searchPath, clip_time) if rc is None or rc.is_valid() is False: # pc maybe with the all name try: # comment.error("pc = %s" % (pc)) xx = BaseEnv.pack_info(replaceMain=False) search = "" for x in xx: if x[0].startswith(pc): search = os.path.dirname(x[1]) break if search != "": rc = PackInfo(pc, search) if rc is None or rc.is_valid() is False: comment.error("===>no pack %r found in %s" % ( pf, [search])) self.logfile("===>no pack %r found in %s" % ( pf, [search])) else: self._packFound[rc.name] = rc.path else: comment.error("no pack1 %r found in %s" % ( pc, self._searchPath)) self.logfile("no pack %r found in %s" % ( pc, self._searchPath)) except Exception as e: comment.error("no pack2 %r found in %s" % ( pc, self._searchPath)) comment.error(str(e)) self.logfile("no pack %r found in %s" % ( pc, self._searchPath)) self.logfile(str(e)) else: self._packFound[rc.name] = rc.path
def clean_environ(self, removeList=None, exceptionStartwith=None): # load environ with clean the _INDOP so we save them first self.load_environ(removeList, exceptionStartwith) cmdRemove = BaseEnv.get_cleanup_cmd() for cmd in cmdRemove: self._evalCmd(cmd)
import traceback import getpass import logging import platform from pprint import pformat from collections import OrderedDict from dskenv import base_env from dskenv.base_env import BaseEnv from dskenv.config_info import ConfigInfo from dskenv.pack_info import PackInfo from dskenv.version_helper import VersionHelper from dskenv.envi_utils import EnviUtils # don't remove, this is use for some config evaluation BASE_PACKAGE_DIR = BaseEnv.get_package_dir() # create a logger to csh comment out message logFormat = logging.Formatter('#%(levelname)-10s: %(message)-10s') h = logging.StreamHandler() h.setFormatter(logFormat) comment = logging.getLogger("comment") comment.addHandler(h) comment.setLevel(logging.DEBUG) cmdout = sys.stdout class MiniEnv(object): # csh and tcsh default to bash """Command to be use to build the evaluation dictionary
def parse_cmd_base(self, argListOrStr): from argparse import ArgumentParser # parser setup parser = ArgumentParser() parser.add_argument("-c", dest="configs", action="append", default=list(), help="config(s) to load") parser.add_argument("-p", dest="packs", action="append", default=list(), help="pack(s) to load") parser.add_argument("-d", dest="d", action="store_true", default=False, help="first look in current area") parser.add_argument("-D", dest="D", action="store", default="", help="other username") parser.add_argument("-f", dest="fromDir", action="store", default="", help="from a given directory") parser.add_argument("-r", dest="revision", action="store", default="", help="(not supported yet) for config") parser.add_argument("-t", dest="date", action="store", default="", help="use for packs") argList = argListOrStr if type(argListOrStr) in (str,): # split appropriately if argListOrStr.find(" ") == -1: argList = [argListOrStr] else: argList = argListOrStr.split() if type(argList) != list: return False (opt, args) = parser.parse_known_args(argList) # opt.configs.extend(args) # extra arguments # are interpreted as configs baseSearch = BaseEnv.base() if opt.fromDir != "": baseSearch = opt.fromDir if opt.D != "": self._devName = opt.D elif opt.d is True: self._devName = getpass.getuser() if self._devName != "": self._searchPath = [BaseEnv.user_home(self._devName), baseSearch] else: self._searchPath = [baseSearch] opt.configs = [x for x in opt.configs if x != ""] opt.packs = [x for x in opt.packs if x != ""] return (opt, args)
def test_pack_commit(): from dskenv.base_env import BaseEnv from dskenv.pack_info import PackInfo from dsk.base.lib.base_fileproc import BaseFileProc run_dry = True packname = "dsk" repo_name = "devsoftkit" top_release_path = "/mnt/dev/install" version = "v0.0.8" searchPath1 = [BaseEnv.base()] searchPath2 = [BaseEnv.user_home('eric')] print("SEARCHPATH",searchPath1,searchPath2) pi = PackInfo(packname) rcHome = pi.real_version_file(PackInfo,searchPath2) fromFile = rcHome.get_fullname() rcRelease = pi.real_version_file(PackInfo,searchPath1) assert rcHome.is_versioned() == False import tempfile import uuid import re pat1 = re.compile("base_release\s*=") pat2 = re.compile("version\s*=") tmp = os.path.join(tempfile.gettempdir(), "pack_%s" % uuid.uuid4().hex) with open(fromFile, "rt") as fin: with open(tmp, "wt") as fout: for line in fin: m = pat1.search(line) if m: release_path = os.path.join(top_release_path,repo_name) fout.write('base_release = "%s"\n' % release_path) else: m = pat2.search(line) if m: fout.write('version = "%s"\n' % version) else: fout.write(line) print(tmp) todolist = BaseFileProc() if rcRelease == None: print("first creation") rcHome.version_up_minor() toFile = rcHome.get_fullname() # repath toFile = toFile.replace(searchPath2[0],searchPath1[0]) print("from %s to %s" % (tmp,toFile)) todolist.copy_envifile(tmp, toFile) else: print(rcRelease.get_fullname()) rcRelease.version_up_minor() toFile = rcRelease.get_fullname() todolist.copy_envifile(tmp, toFile) todolist.delete_file(tmp) #todolist.delete_file(fromFile) res_copy = todolist.execute_stop_first_failed(run_dry=run_dry, with_log = True) print(res_copy.success,res_copy.log)
def test_pack_checkout(): from dskenv.base_env import BaseEnv from dskenv.pack_info import PackInfo from dsk.base.lib.base_fileproc import BaseFileProc run_dry = True dev_path = "/mnt/dev/eric/packages" packname = "dsk" repo_name = "devsoftkit" searchPath1 = [BaseEnv.base()] searchPath2 = [BaseEnv.user_home('eric')] print "SEARCHPATH",searchPath1,searchPath2 pi = PackInfo(packname) import tempfile import uuid tmp = os.path.join(tempfile.gettempdir(), "pack_%s" % uuid.uuid4().hex) todolist = BaseFileProc() rcRelease = pi.real_version_file(PackInfo,searchPath1) if rcRelease != None: toFile = os.path.join(searchPath2[0],pi.get_label(),packname+".py") fromFile = rcRelease.get_fullname() import re pat1 = re.compile("base_release\s*=") pat2 = re.compile("version\s*=") with open(fromFile, "rt") as fin: with open(tmp, "wt") as fout: for line in fin: m = pat1.search(line) if m: x = line.split("=")[1] x = x.strip() x = x.split(os.sep)[-1] x = x.replace("'","") x = x.replace('"',"") source_dev_path = os.path.join(dev_path,x) fout.write("base_release = %r\n" % source_dev_path) else: m = pat2.search(line) if m: fout.write('version = ""\n') else: fout.write(line) print(tmp) print("TOHOME",toFile) todolist.copy_envifile(tmp, toFile) todolist.delete_file(tmp) else: # make a blank from dsk.templates.template_envi import repo_pack toFile = os.path.join(searchPath2[0],pi.get_label(),packname+".py") print(tmp) print("TOHOME",toFile) data = repo_pack.DATA_PACK % {'rootname': os.path.join(dev_path,repo_name)} with open(tmp, "wt") as fout: fout.write(data) todolist.copy_envifile(tmp, toFile) todolist.delete_file(tmp) res_copy = todolist.execute_stop_first_failed(run_dry=run_dry, with_log = True) print(res_copy.success,res_copy.log)
def is_dev(self): """Return True is the path is under envi userpath """ if self.path: return BaseEnv.is_env_user(self.path) != "" return False
class ProxyShow(object): ''' helper to find out couple area not necessary the current show ''' __realbase = os.path.realpath(BaseEnv.studio_root()) @classmethod def usep(cls, apath): return apath.replace(r'\\\\', '/').replace('\\', '/') def __init__(self, showname): self.show_name = showname self.project_path = ProxyShow.usep( os.path.join(BaseEnv.studio_root(), self.show_name)) def get_project_path(self): return self.project_path def get_normal_path(self, apath): ''' to convert from real to normalized path returns: norm path ''' apath = apath.replace(ProxyShow.__realbase, BaseEnv.studio_root()) return apath def get_prod_area(self): return ProxyShow.usep( os.path.join(self.project_path, BaseEnv.MAIN_PROD)) def get_publish_area(self): return ProxyShow.usep( os.path.join(self.project_path, BaseEnv.MAIN_PUBLISH)) def get_asset_prod_area(self, atype=""): if atype == "": return ProxyShow.usep( os.path.join(self.get_prod_area(), BaseEnv.MAIN_ASSET)) assert atype in BaseEnv.get_asset_type() return ProxyShow.usep( os.path.join( os.path.join(self.get_prod_area(), BaseEnv.MAIN_ASSET, atype))) def get_asset_publish_area(self, atype=""): if atype == "": return ProxyShow.usep( os.path.join(self.get_publish_area(), BaseEnv.MAIN_ASSET)) assert atype in BaseEnv.get_asset_publish_type() return ProxyShow.usep( os.path.join(self.get_publish_area(), BaseEnv.MAIN_ASSET, atype)) def get_shot_prod_area(self, sequence=""): if sequence == "": return os.path.join(self.get_prod_area(), BaseEnv.MAIN_SHOT) return os.path.join(self.get_prod_area(), BaseEnv.MAIN_SHOT, sequence) def get_shot_publish_area(self, sequence=""): if sequence == "": return ProxyShow.usep( os.path.join(self.get_publish_area(), BaseEnv.MAIN_SHOT)) return ProxyShow.usep( os.path.join(self.get_publish_area(), BaseEnv.MAIN_SHOT, sequence)) def get_shot_publish_thumbcache_area(self): return ProxyShow.usep( os.path.join(self.get_publish_area(), BaseEnv.THUMBCACH, BaseEnv.THUMB_SHOT)) def get_asset_publish_thumbcache_area(self): return ProxyShow.usep( os.path.join(self.get_publish_area(), BaseEnv.THUMBCACH, BaseEnv.THUMB_ASSET))
def execute(self, argv, fromPython=True): """This module is mainly to be used from shell in progress :param argv: a list of envi command :param fromPython: default True. the result of the function is in os.environ :returns bool: True if success """ import subprocess # argument to remove opt = dict() opt["List"] = ["-L", False] opt["Reset"] = ["-Reset", False] # no undo implemented opt["Info"] = ["-h", False] opt["Deamon"] = ['-Deamon', False] opt['Print'] = ["-Print", False] opt['Debug'] = ["-Debug", False] opt['Store'] = ["-Store", False] opt['DictOnly'] = ["-Dodict", False] opt['Clean'] = ["-Clean", False] opt['ExistOnly'] = ["-ExistOnly", False] cmdLines = " ".join(argv[1:]).split("--") if len(cmdLines) > 2: sys.stderr.write("Envi.execute: don't support multiple launch\n") return False cmdLines = [x for x in cmdLines if x != ''] # remove the blank if len(cmdLines) == 0: sys.stderr.write("Envi.execute: no arguments\n") return False cleanArg = list() envCmd = cmdLines[0] for i in opt: tempLine = envCmd.replace(opt[i][0], "") if tempLine != envCmd: opt[i] = [opt[i][0], not opt[i][1]] # toggle the opt envCmd = tempLine # return False if opt["Debug"][1] is True: self.set_debug(True) # self._printall = True else: self.set_debug(False) # self._printall = False if opt["Print"][1] is True: for x in os.environ: sys.stderr.write(x + ":\n") for y in os.environ[x].split(os.pathsep): sys.stderr.write("\t" + y + "\n") # sys.stdout.write("") return True if fromPython is False: if opt["Clean"][1] is True or opt["ExistOnly"][1] is True: self.main_cleanup(clean_double=opt["Clean"][1], exist_only=opt["ExistOnly"][1]) return True if opt["Store"][1] is True: # build a pack file to store initial state self.store() return True if opt["Info"][1] is True: import dskenv c = BaseEnv.base_config() p = BaseEnv.base_pack() sys.stderr.write("config in: {}\npacks in: {}\n".format(c, p)) if 'dev' in dskenv.__file__: sys.stderr.write("envi: dev dskenv\n") else: sys.stderr.write("envi: released code\n") sys.stderr.write("envi: released code\n") helplist = self.get_help() sys.stderr.write("\n".join(helplist)) return True app = "" logfile = "" writefile = "" # search if app and logfile envArgs = envCmd.split(",") # split per config paternapp = re.compile(r'-a\s*[\w\d\.\%s-]*' % os.sep) paternlog = re.compile(r'-l\s*[\w\d\.\%s-]*' % os.sep) paterncache = re.compile(r'-w\s*[\w\d\.\%s-]*' % os.sep) for envarg in envArgs: # app m = paternapp.search(envarg) if m: stringfound = m.group() envarg = envarg.replace(stringfound, "") app = stringfound.replace("-a", "") app = app.strip() # log aclean = envarg.strip() m = paternlog.search(aclean) if m: stringfound = m.group() envarg = envarg.replace(stringfound, "") logfile = stringfound.replace("-l", "") logfile = logfile.strip() # write aclean = envarg.strip() m = paterncache.search(aclean) if m: stringfound = m.group() envarg = envarg.replace(stringfound, "") writefile = stringfound.replace("-w", "") writefile = writefile.strip() aclean = envarg.strip() if aclean != "": cleanArg.append(aclean) if opt["List"][1] is True: import dskenv import getpass # if self.info_from_environment(): # for obj in self.get_commands(): if writefile != "": is_d = False for x in cleanArg: # sys.stderr.write("---> %r\n" % x) if '-d' in x: # sys.stderr.write("---> hellp\n") is_d = True break try: f = open(writefile, "w") except: traceback.print_exc() return False # for obj in BaseEnv.pack_history( # os.environ.get('DSKENVPATH')): for obj in BaseEnv.command_history(): if is_d is False: # sys.stderr.write("---> %s\n" % obj) """FOR LATER IF NEEDED""" # paternd = re.compile("-D\s*[\w\d\.\-]*") # m = paternd.search(obj) # sys.stderr.write("-- %s" % m) # if m: # obj = obj.replace(m.group(),"") # obj = obj.strip() # sys.stderr.write("envi "+ obj + ";\n") f.write("envi " + obj + ";\n") else: # sys.stderr.write("--------> %s\n" % obj) f.write("envi " + obj + " -D %s;\n" % (getpass.getuser())) else: for obj in BaseEnv.command_history(): sys.stderr.write("envi " + obj + ";\n") c = BaseEnv.base_config() p = BaseEnv.base_pack() sys.stderr.write("#config in {}\n#packs in {}\n".format(c, p)) if 'dev' in dskenv.__file__: sys.stderr.write("#envi code dev\n") else: sys.stderr.write("#envi code released\n") return True if writefile != "" and len(cleanArg) == 0 and app == "": res = self.dump_os_as_shell(writefile) if res is True: sys.stderr.write("DONE\n") else: sys.stderr.write("ERROR: couldn't create %s\n" % writefile) return True if logfile != "" and os.path.exists(os.path.dirname(logfile)): self.startlog(logfile) self.setPath("ENVI_LOG", logfile) else: self.unsetPath("ENVI_LOG") # take a snapshot SAVE_OS = dict() SAVE_OS.update(os.environ) self.init_with_cmd(cleanArg) self.do_eval_pack() if opt["Reset"][1] is True: # self.unsetPath(BaseEnv.get_key_pack_info()) # self.unsetPath(BaseEnv.get_key_config_info()) self.unsetPath(BaseEnv.get_command_info()) else: if app != "": self.add_command("-a %s" % app) self.build_command_history() if app == "": if writefile == "": if fromPython is True: if opt['DictOnly'][1] is True: self.reset_cache() self.endlog() return True os.environ.update(self.get_environ(withRemoveCmd=False)) self.expand_vars(os.environ) newpath = list() for p in sys.path: if p.startswith(sys.prefix): newpath.append(p) if 'PYTHONPATH' in os.environ: newpath.extend(os.environ['PYTHONPATH'].split( os.pathsep)) sys.path = newpath # reset the sys.path self.reset_cache() self.endlog() return True else: self.echo_environ_diff_only(SAVE_OS) self.endlog() return True else: sys.stderr.write("write file %s\n" % writefile) self.write_environ(SAVE_OS, writefile) self.endlog() return True if fromPython is False: self.write_bash_history() # we still need to update the calling # shell with the command history cmd = [app] if len(cmdLines) == 2: apparg = cmdLines[1] cmd.extend(apparg.split()) # self.logfile("2") os.environ.update(self.get_environ(withRemoveCmd=False)) self.expand_vars(os.environ) self.reset_cache() # self.logfile("3") self.logfile("execute: %s" % " ".join(cmd)) thelog = self.getlog() p = None if thelog and opt["Deamon"][1] is True: sys.stderr.write("IN SUBProcess start\n") self.endlog() thelog = open(logfile, "a+") x = LaunchApp(cmd, thelog) x.start() else: if thelog: sys.stderr.write("IN SUBProcess start2\n") p = subprocess.Popen(" ".join(cmd), stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True, close_fds=True) if p.wait() != 0: self.logfile("ERROR: %s" % " ".join(cmd)) result = p.stdout.readlines() p.stdout.close() thelog.write("\n".join(result)) else: sys.stderr.write("IN SUBProcess start3\n") # sys.stderr.write("%s\n" % sys.stdout) # sys.stderr.write("err %s\n" % sys.stderr) p = subprocess.Popen(cmd, stdout=None, stderr=None, shell=True, close_fds=True) # import time # time.sleep(30) if p: self.logfile("Launched %r with processid %d" % (app, p.pid)) self.endlog()
def info_from_environment(self): """Read the environment and find a sequence of cmd to create it the result is not unique """ self.reset() ################################ # read from environment helper = BaseEnv() # read configs from environment variable configsEnv = [ConfigInfo(x[0], x[1]) for x in helper.config_info()] # packs pack packsEnv = [ PackInfo(x[0], x[1]) for x in helper.pack_info(replaceMain=True) ] initData = [[ x, ] for x in packsEnv] packsDict = OrderedDict(list(zip([x.name for x in packsEnv], initData))) ################################ # raw config dict rawConfig = OrderedDict() # loading empty config so we see the type of pack available # we also build a list of founded file to get the real version from # disk and deal with wild version in pack name -?.? for cfg in configsEnv: newC = MiniEnv() rawConfig[cfg.name] = newC fullPathName = cfg.get_file(cfg.path, -1) newC.set_dev_name(cfg.owner()) if fullPathName != "": newC.load_config_or_pack(fullPathName) else: log.error("cannot figure out the path for %r" % cfg.name) for pa in newC.get_pack_name_list(): v = VersionHelper(pa) for rv in packsDict: rvp = packsDict[rv][0] if v.is_similar(rvp): pp = v.get_file(rvp.path, -1) if pp != "": p, realname = os.path.split(pp) newC._packFound[realname.replace(".py", "")] = p else: # comment.debug("could not find the file %s" % pa) # we take the name of the file newC._packFound[rvp.name] = rvp.path break # we read the config in reversed order and # mark the pack with the config that loaded them for rcn, conf in reversed(list(rawConfig.items())): llp = list() for x in conf.get_pack_name_list(): llp.append(VersionHelper(x)) for lp in llp: for i in packsDict: if lp.is_similar(packsDict[i][0]): packsDict[i].append(rcn) break currentConfig = list() lateAddPack = list() # NOTES: it seems that when configs and pack get loaded at # the same time, the config take precedence # i don't think it should, but this code consider it # by adding extra command for keyPack in packsDict: theConfigs = packsDict[keyPack][1:] for c in theConfigs: if c not in currentConfig: currentConfig.append(c) if len(theConfigs) == 0: # no config where adding this lateAddPack.append( ('', keyPack, packsDict[keyPack][0].owner())) else: # here we check the validity to detect late 'addPack' # check if the last enter current config is compatible: # check ownership needExtraPack = False curConfName = currentConfig[-1] aconf = rawConfig[curConfName] # -1 for last in if keyPack not in aconf._packFound: needExtraPack = True owner = packsDict[keyPack][0].owner() cowner = conf.dev_name() if owner != '': if owner != cowner: if cowner == '' and needExtraPack is False: # we mark the config as needing the -d flag # we don't do this for now, since we have # to split the commandLine # aconf.setDevName(owner) lateAddPack.append((curConfName, keyPack, owner)) else: lateAddPack.append((curConfName, keyPack, owner)) elif needExtraPack: lateAddPack.append((curConfName, keyPack, '')) # build the command line CmdLine = OrderedDict() for rcn, conf in list(rawConfig.items()): CmdLine[rcn] = list() dv = conf.dev_name() if dv != "": CmdLine[rcn].append('-D %s' % dv) CmdLine[rcn].append('-c %s' % rcn) # add the pack into a new command self.do_extra_pack(rcn, lateAddPack, CmdLine) if len(lateAddPack) > 0: # just to keep the orphane pack at the end self.do_extra_pack('', lateAddPack, CmdLine, pickup=True) CmdLineFinal = OrderedDict() for i in CmdLine: if len(CmdLine[i]) > 0: CmdLineFinal[i] = " ".join(CmdLine[i]) # init the basic to stay consistent with a state self.configsObject = configsEnv # remove the dummy pack self.packsObject = packsEnv self._commands = list(CmdLineFinal.values()) return True
def get_label(): return BaseEnv.config_tag()
def get_history_from_key(): return os.environ.get(BaseEnv.get_command_info(), "")
def get_label(): return BaseEnv.pack_tag()
class EnviApi(object): """Read the main envi_info_location for query """ __file_location = BaseEnv.envi_info_location() __devuser = "******" def __init__(self): super(EnviApi, self).__init__() self.dev_user = list() def reset(self, envplace=""): """overwrite the class instance file_location :param envplace: path (str) to the envi location :return None: """ if envplace != "": EnviApi.__file_location = os.path.join(envplace, BaseEnv.envi_iddir(), BaseEnv.envi_file_name()) self.dev_user = list() def is_valid(self): """Basic method to overload """ try: return len(self.site['name']) > 0 except: pass return False def load_data(self): """Build object list DevUser (found in envi_info) :param None: :returns data: the content of the envi_info as dict """ if not os.path.isfile(EnviApi.__file_location): return dict() data = YamlUtils.load_data(EnviApi.__file_location) if 'site' in data: self.site = data['site'] if self.__devuser in data: for x in data[self.__devuser]: a = DevUser() a.setdata(**x) # only update valid dev_user if a.is_valid(): self.dev_user.append(a) else: print("user not valid", a) return data @staticmethod def generic_launch_log_file(appname): """Create a generic logfile in tmp are with date, time and app name :param appname: appname used as tagname of the log :return log_file: str """ day, hour = datetime.today().strftime("%Y-%m-%d %Hh%Mm%S").split(" ") log_dir = os.path.join(os.sep, 'tmp', 'envi_log', appname, day) log_file = os.path.join( log_dir, "log_%s_%s-%s_%s.log" % (appname, day, hour, getpass.getuser())) # create log dir cmd = ['mkdir', '-p', log_dir] p = subprocess.Popen(cmd) error = "" if p.wait() != 0: import tempfile log_file = os.path.join( "%s" % tempfile.mkdtemp(), "log_%s_%s-%s_%s.log" % (appname, day, hour, getpass.getuser())) sys.stderr.write("Couldn't create log directory: %s\n" % log_dir) sys.stderr.write("Using: %s\n" % log_file) error = "ERROR: %s" % " ".join(cmd) open(log_file, "w").write(error + "\n") else: open(log_file, "a").write("BEFORE LAUNCH\n") return log_file @staticmethod def _valid_command_syntax(x): """For ease to build envi command its use list of list of envi option and tag, this function check which form x is and return the correct envi commands -- internally used """ need_join = False for i in x: if isinstance(i, str): return x assert isinstance(i, list) for ii in i: if " " not in ii: need_join = True break if need_join: envi_command = list() for i in x: envi_command.append(" ".join(i)) return envi_command return x @staticmethod def do_log(x, log_file=""): """Add log argument to all list of envi: :param x: list of envi command as single option or pack :param log_file: name of the log file :return x: the modified x :example: x = [['-c', 'dev_show'],['-c', 'inhouse_maya']] return [['-c', 'dev_show','-l',log_file], ['-c', 'inhouse_maya','-l',log_file]] """ if log_file == "": return x for i in x: i.extend(["-l", log_file]) return x @staticmethod def do_debug(x, loginname=""): """Add a user config lock up to all envi statement :param x: list of envi command as single option or pack :param loginname: a user login name. if "" set to the current user :return x: the modified x :example: Ex: x = [['-c', 'dev_show'],['-c', 'inhouse_maya']] return [['-c', 'dev_show',"D",loginname], ['-c', 'inhouse_maya','-D',loginname]] """ if loginname == "": loginname = getpass.getuser() for i in x: i.extend(["-D", loginname]) return x @staticmethod def do_platform(x): x.insert(0, ['-p', Envi().pack_system()]) return x @staticmethod def do_app(x, app_name, do_deamon=True): """Add an app statement to the last statement :param x: list of envi command as single option or pack :param app_name: app to launch :param do_deamon: bool (default True), to daemonize the process :example: Ex: x = [['-c', 'dev_show'],['-c', 'inhouse_maya']] return [['-c', 'dev_show'], ['-c', 'inhouse_maya','-a',app_name]] :return x: list of envi command as single option or pack """ if app_name == "": return x x[-1].extend(["-a", app_name]) if do_deamon: x[-1].append("-Deamon") return x @staticmethod def do_arguments(x, argument_list): """Add argument to x :param x: list of envi command as single option or pack :param argument_list: argument list to add :return x: list of envi command as single option or pack """ x[-1].append("--") x[-1].extend(argument_list) return x @staticmethod def do_extrapackage(x, extra_package): """Add argument to x :param x: list of envi command as single option or pack :param argument_list: list of envi command as single option or pack :return x: list of envi command as single option or pack """ if isinstance(extra_package, str): extra_package = [extra_package] if len(x) > 0 and isinstance(x, list): x[-1].extend(extra_package) return x return [extra_package] @staticmethod def do_execute(x, dskenvpath): """Execute envi command in a specific environment :param x: list of envi command as single option or pack :param dskenvpath: envi config root """ pr = ProdEnv(dskenvpath) for xx in x: xx.insert(0, "do_execute") Envi().execute(xx, True) pr.back_to_global() @classmethod def build_launch_bash(cls, envicommands, env_root=None, app_tag="", add_default_env=None, add_history=True, envi_dump_file="", split_launch=False): """Dump the envicommands into a file, good for execution :param envicommands: is a list of valid envi command (list) :param app_tag: (str) use to document this launch. (store in DSK_ENGINE) :param add_default_env: (dict or list of key)support for extra export statement, ex: tank... :param add_history: bool default True, add the history envi config :returns launchfile: the name of the file ready for execution see launch_batch_file and launch_batch_file_with_console """ if env_root is None: env_root = os.environ.get(dskenv_constants.DSK_ENV_PATH_KEY) if envi_dump_file != "": launchfile = envi_dump_file else: launchpath = Envi.get_temp_dir("envizlaunch") launchfile = os.path.join(launchpath, "doenvi.sh") try: with open(launchfile, "w") as fh: scmd = list() scmd.append("#!/bin/bash -l") # reset the python path # ideally we will want to source system and init studio shell if add_default_env: if isinstance(add_default_env, dict): for x in add_default_env: value = add_default_env[x] if x == 'SGTK_CONTEXT' or x == 'TANK_CONTEXT': value = value.replace('"', r'\"') value = '"' + value + '"' scmd.append('export %s=%s' % (x, value)) else: if x in ['PYTHONPATH']: scmd.append("export %s=%s:${%s}" % (x, value, x)) else: scmd.append("export %s=%s" % (x, value)) elif isinstance(add_default_env, list): for x in add_default_env: value = os.environ.get(x, "") if x == 'SGTK_CONTEXT' or x == 'TANK_CONTEXT': value = value.replace('"', r'\"') value = '"' + value + '"' # f.write("value %s\n" % value) scmd.append('export %s=%s' % (x, value)) else: if x in ['PYTHONPATH']: # we cannot erase this one scmd.append("export %s=%s:${%s}" % (x, value, x)) else: scmd.append("export %s=%s" % (x, value)) scmd.append("unset PYTHONHOME") scmd.append("export %s=%s" % (dskenv_constants.DSK_ENV_PATH_KEY, env_root)) scmd.append("export DSK_ENGINE=%s" % app_tag) scmd.append("type envi &> /dev/null") scmd.append("if [ ! -z $? ] ; then") scmd.append("\tenvi() {") scmd.append("\t\tsource $DSKENV/bin/linux/envi_bsh $*\n\t}") scmd.append("\texport -f envi") scmd.append("fi") if add_history: for obj in cls.get_history_command(with_app=False, remove_app=True): # BaseEnv.command_history(): if obj and len(obj) > 0: scmd.append("envi " + obj[0] + ";") envicommands = cls._valid_command_syntax(envicommands) if split_launch is False: for cmds in envicommands: scmd.append("envi %s" % cmds) else: for cmds in envicommands: if "-a" not in cmds: scmd.append("envi %s" % cmds) else: X = cls.split_launch_command(cmds) app, arg, cmds, alog = X scmd.append("set -o pipefail") scmd.append("envi %s" % cmds) if alog != "": scmd.append("%s %s |& tee -a %s" % (app, arg, alog)) else: scmd.append("%s %s" % (app, arg)) fh.write("\n".join(scmd)) if sys.version_info[0] == 3: os.chmod(launchfile, 0o775) else: os.chmod(launchfile, 0o775) except Exception as e: print("ERROR: build_launch_bash: %s" % str(e)) return launchfile @staticmethod def split_launch_command(cmd): """Extract the value to of an envi commnand with app, arg and log :param cmd: envi command :returns app,arg,cmd,alog """ arg = "" app = "" alog = "" if "--" in cmd: cmd, arg = cmd.split("--") cmd = cmd.strip() arg = arg.strip() paternapp = re.compile(r'-a\s*[\w\d\.\%s-]*' % os.sep) paternlog = re.compile(r'-l\s*[\w\d\.\%s-]*' % os.sep) m = paternapp.search(cmd) if m: stringfound = m.group() cmd = cmd.replace(stringfound, "") app = stringfound.replace("-a", "") app = app.strip() cmd = cmd.replace("-Deamon", "") m = paternlog.search(cmd) if m: stringfound = m.group() alog = stringfound.replace("-l", "") alog = alog.strip() return app, arg, cmd, alog else: return "", "", cmd, "" @staticmethod def launch_batch_file(filetoexecute, clean_tmp_dir=False): """Exec the given file. :param filetoexecute: a valid batch file :type filetoexecute: a valid executable file on disk :param clean_tmp_dir: option to remove the file :type clean_tmp_dir: bool, default = False (NOT SUPPORTED, IGNORED) :return None: """ if clean_tmp_dir: process_get_output(filetoexecute) Envi.cleanup_temp_dir() else: subprocess.Popen(filetoexecute, close_fds=True, env=get_dict_environ_envi()) @staticmethod def launch_batch_file_with_console(filetoexecute, console='gnome-terminal', clean_tmp_dir=False, hold=True): """Same as launch_batch_file, with an optional console :param filetoexecute: a valid batch file :type filetoexecute: a valid executable file on disk :param console: (str) default = xterm :type console: (str) xterm or konsole or gnome-terminal :param clean_tmp_dir: option to remove the file :type clean_tmp_dir: bool, default = False :param hold: option keep the window up :type hold: bool, default = True :returns None: no return value """ # console = 'gnome-terminal' # hold = False # assert console in ['xterm','konsole','gnome-terminal'] ''' cmds = list() cmds.append("gnome-terminal") cmds.append("-x") cmds.append("bash") cmds.append("-ic") #cmds.append("-e") cmds.append(filetoexecute) #cmds.append('-x bash') #cmds.append("-e %s" % filetoexecute) process_get_output(cmds) #subprocess.Popen(cmds, # close_fds=True, # env=get_dict_environ_envi()) ''' os.system("gnome-terminal -x bash -ic %r" % filetoexecute) return if hold: cmds = [console, '-hold', '-e', filetoexecute] else: cmds = [console, '-e', filetoexecute] if clean_tmp_dir: process_get_output(cmds) Envi.cleanup_temp_dir() else: subprocess.Popen(cmds, close_fds=True, env=get_dict_environ_envi()) @staticmethod def get_history_from_key(): return os.environ.get(BaseEnv.get_command_info(), "") @classmethod def get_history_command(cls, with_app=False, remove_app=True, index=0): """Return all the envi commands sent :param with_app: default=False if true don't add command containing '-a app' :param remove_app: default=False :param index: default 0. if 1 remove the last statement 2 two last statement etc... :returns list: a list of envi command """ x = BaseEnv.command_history() paternapp = re.compile(r'-a\s*[\w\d\.\%s-]*' % os.sep) envcmd = list() for xx in x: m = paternapp.search(xx) if with_app is True: # remove -a appname for cmd if m: if remove_app is True: stringfound = m.group() envarg = xx.replace(stringfound, "") xx = envarg.strip() else: continue # no adding else: if m: xx = [] if len(xx) > 0: envcmd.append([xx]) if index != 0: try: envcmd = envcmd[:-index] except: pass # remove last indexes return envcmd ########################################################################### def get_userdev_path(self, user): """Each dev user can have a directory under which is clone its repo (found in envi_info) :param user: (str) a login name :return user_path: (str) not found = "" """ for u in self.dev_user: if u.login == user: return u.dev_path return "" def get_userdev_project(self, user): """Each dev user can be on a list of current project (found in envi_info) :param user: (str) a login name :return project_list: (list). list of project, empty [] if not found """ for u in self.dev_user: if u.login == user: return u.projects return [] def get_userdev_config_path(self, user): """Each dev user can be on a list of envi config (found in envi_info) :param user: (str) a login name :return project_list: (list). list of directory with config empty [] if not found """ for u in self.dev_user: if u.login == user: return u.dev_path_configs return list() def get_all_user_login(self): """Return all user loginname (found in envi_info) :param None: :return list: list of login : (list). list of login name empty [] if not found """ return [u.login for u in self.dev_user]
def __init__(self, showname): self.show_name = showname self.project_path = ProxyShow.usep( os.path.join(BaseEnv.studio_root(), self.show_name))