22"""Create and manage a set of user timetracker projects"""
33
44from os .path import join
5+ from os .path import dirname
6+ from os .path import relpath
57from logging import basicConfig
68from logging import DEBUG
79from collections import namedtuple
810from timetracker .ntcsv import get_ntcsv
911from timetracker .utils import yellow
1012from timetracker .cfg .cfg import Cfg
1113from timetracker .cfg .doc_local import get_docproj
12- #from timetracker.cfg.cfg_global import CfgGlobal
1314from timetracker .cfg .cfg_global import get_cfgglobal
1415from timetracker .cfg .docutils import get_value
1516from timetracker .cmd .init import run_init
2122from tests .pkgtttest .consts import SEP3
2223from tests .pkgtttest .runfncs import proj_setup
2324from tests .pkgtttest .userprojs import UserProjects
24- from tests .pkgtttest .mkprojs import prt_type2files
25+ from tests .pkgtttest .upstream import Upstream
26+ from tests .pkgtttest .mkprojs import get_type2files
27+ from tests .pkgtttest .mkprojs import get_files
28+ from tests .pkgtttest .mkprojs import prt_files
2529from tests .pkgtttest .dts import get_iter_weekday
2630from tests .pkgtttest .dts import td2hours
2731from tests .pkgtttest .dts import I1266 as DT2525
3034class RunProjs :
3135 """Manage all users and their projects"""
3236
33- ##def __init__(self, tmproot, userprojs, fcfg_global=None):
34- def __init__ (self , tmproot , userprojs , fcfg_explicit = None , fcfg_doc = None ):
37+ def __init__ (self , tmproot , userprojs ):
3538 self .tmproot = tmproot
3639 self .dirhome = join (tmproot , 'home' )
3740 self .ups = UserProjects (userprojs )
38- ##self.cfg_global = CfgGlobal(fcfg_global)
39- self .cfg_global = get_cfgglobal (fcfg_explicit , self .dirhome , fcfg_doc )
40- self .cfg = Cfg ("phoneyproj.cfg" , self .cfg_global )
41- self .prj2mgrprj = {e :MngUsrProj (self .dirhome , self .cfg_global , * e ) for e in userprojs }
41+ self .prj2mgrprj = {(usr ,prj ):MngUsrProj (self .dirhome , usr , prj ) for usr , prj in userprojs }
42+ self .upstream = Upstream (join (self .tmproot , 'upstream' ))
43+ self .orig_ntcsvs = self .ups .get_expcsvs (self .tmproot )
44+
45+ def all_push (self ):
46+ """simulate a git-like push"""
47+ for (_ , prj ), obj in self .prj2mgrprj .items ():
48+ dirproj = dirname (dirname (obj .cfg .cfg_loc .filename ))
49+ files = get_files (dirproj )
50+ for absfname in files :
51+ relfname = relpath (absfname , dirproj )
52+ self .upstream .push (prj , absfname , relfname )
53+
54+ def all_pull (self ):
55+ """simulate a git-like pull"""
56+ pull_copies_all = []
57+ for (_ , prj ), obj in self .prj2mgrprj .items ():
58+ dirproj = dirname (dirname (obj .cfg .cfg_loc .filename ))
59+ pull_copies_cur = self .upstream .pull (prj , dirproj )
60+ pull_copies_all .extend (pull_copies_cur )
61+ return pull_copies_all
62+
63+ def prt_userfiles (self , msg = 'FILES FOR ALL USERNAMES' , prefix = 'USERFILE: ' ):
64+ """Print files for each username"""
65+ if prefix :
66+ prefix = f'{ msg } : '
67+ print (f'\n { msg } :' )
68+ for uname in self .ups .usernames :
69+ print (f'FILES FOR USERNAME: { uname } :' )
70+ userhome = join (self .dirhome , uname )
71+ prt_files (userhome , prefix )
4272
4373 def get_user2glbcfg (self ):
4474 """For each username, get their one global config file"""
4575 user2glbcfg = {}
4676 for (usr , _ ), obj in self .prj2mgrprj .items ():
4777 docproj = get_docproj (obj .fcfgproj )
4878 fcfg_doc = get_value (docproj , 'global_config' , 'filename' )
49- cfg_glb = get_cfgglobal (dirhome = self . dirhome , fcfg_doc = fcfg_doc )
79+ cfg_glb = get_cfgglobal (dirhome = obj . home , fcfg_doc = fcfg_doc )
5080 assert cfg_glb is not None
5181 if usr not in user2glbcfg :
5282 user2glbcfg [usr ] = cfg_glb
@@ -58,11 +88,9 @@ def run_setup(self):
5888 """Initialize and fill timeslots for multiple users and projects"""
5989 print (yellow (f"{ SEP1 } `run_init` on each project" ))
6090 basicConfig (level = DEBUG )
61- prt_type2files (self .tmproot )
6291
6392 print (yellow ('`run_start` and `run_stop` to fill each researcher & project' ))
6493 self ._run_start_stop_all ()
65- prt_type2files (self .tmproot )
6694
6795 print (yellow ('Check projects listed in CfgGlobal' ))
6896
@@ -72,12 +100,12 @@ def _run_start_stop_all(self):
72100 mgrprj = self .prj2mgrprj [usrprj ]
73101 mgrprj .add_timeslots (times )
74102
75- def chk_projects (self , exp_projects ):
103+ def chk_proj_configs (self , exp_fcfgprojs ):
76104 """Check the projects"""
77- act_projs = self .cfg_global . get_projects ( )
78- home = self .dirhome
79- exp_projs = [[ prj , join ( home , rcfg )] for prj , rcfg in exp_projects ]
80- assert act_projs == exp_projs , self ._errmsg (act_projs , exp_projs )
105+ type2files = get_type2files ( self .tmproot )
106+ exp_fcfgprojs = set ( join ( self .dirhome , f ) for f in exp_fcfgprojs )
107+ act_fcfgprojs = set ( type2files [ 'config' ])
108+ assert set ( act_fcfgprojs ) == set ( exp_fcfgprojs ) , self ._errmsg (act_fcfgprojs , exp_fcfgprojs )
81109
82110 def run_hoursprojs (self ):
83111 """print hours, iterating through all users & their projects"""
@@ -87,7 +115,7 @@ def run_hoursprojs(self):
87115
88116 print (f'{ SEP3 } run_setup: run_hours project({ usrprj [0 ]} ) username({ usrprj [1 ]} )' )
89117 # run_hours nt: RdCsvs: results errors ntcsvs
90- run1 = run_hours (self .cfg , usr , dirhome = mgrprj .home )
118+ run1 = run_hours (mgrprj .cfg , usr , dirhome = mgrprj .home )
91119 assert td2hours (run1 .results ) == self ._get_total_hours (usr ), (
92120 f'ACT({ td2hours (run1 .results )} ) != EXP({ self ._get_total_hours (usr )} ) '
93121 f'project({ usrprj [0 ]} ) username({ usrprj [1 ]} )' )
@@ -102,13 +130,13 @@ def _get_total_hours(self, usr):
102130 return sum (e for (u , _ ), (_ , e ) in self .ups .userprojs .items () if u == usr )
103131
104132 @staticmethod
105- def _errmsg (act_projs , exp_projs ):
133+ def _errmsg (act_fcfgprojs , exp_fcfgprojs ):
106134 txt = ['\n EXP:' ,]
107- for prj , fcfg in exp_projs :
108- txt .append (f' { prj :14 } { fcfg } ' )
135+ for fcfg in sorted ( exp_fcfgprojs ) :
136+ txt .append (f' { fcfg } ' )
109137 txt .append ('\n ACT:' ,)
110- for prj , fcfg in act_projs :
111- txt .append (f' { prj :14 } { fcfg } ' )
138+ for fcfg in sorted ( act_fcfgprojs ) :
139+ txt .append (f' { fcfg } ' )
112140 return '\n ' .join (txt )
113141
114142
@@ -117,18 +145,20 @@ class MngUsrProj:
117145 """Manage one user and the project"""
118146
119147 # pylint: disable=unknown-option-value,too-many-arguments,too-many-positional-arguments
120- def __init__ (self , tmproot , cfg_global , user , projname , dircsv = None ):
121- self .cfg_global = cfg_global
148+ def __init__ (self , tmproot , user , projname , dircsv = None ):
122149 self .home = join (tmproot , user )
123150 self .user = user
124151 self .projname = projname
152+ self .cfg_global = get_cfgglobal (None , self .home , fcfg_doc = None )
125153 ##print(f'\nMngUsrProj({self.home:29}, {user:7}, {projname})')
126- self .fcfgproj , _ , self .exp = proj_setup (self .home , projname , dircur = 'dirproj' )
127- self .cfg = run_init (self .fcfgproj ,
154+ self .fcfgproj , finder , self .exp = proj_setup (self .home , projname , dircur = 'dirproj' )
155+ self .cfg = Cfg (self .fcfgproj )
156+ run_init (self .cfg ,
157+ finder .dirgit ,
128158 dircsv = dircsv ,
129159 project = self .projname ,
130160 dirhome = self .home ,
131- cfg_global = cfg_global ,
161+ cfg_global = self . cfg_global ,
132162 quiet = True )
133163
134164 def get_args_hours (self ):
0 commit comments