Commits

gastlygem  committed bbcdca4

Added logging, changed config format

  • Participants
  • Parent commits 9c0938b
  • Branches testing

Comments (0)

Files changed (4)

 # Format is as follows:
 #
 # - Group_NAME:
-#     prjname: Project_Name
-#     syncdirs: 'SyncDir1, SyncDir2, Syncdir3'
+#     Project_Name: 'SyncDir1, SyncDir2, Syncdir3'
 #
 # To avoid Yaml parsing errors on Windows volume names (damn those colons), it 
 # is better to add a single quote to the syncdir group.
 #
-# Group names should be unique, or the latter ones will overwrite earlier ones.
-#
 # ############################################################################ #
 
-- Group0:
-    prjname: 4CX01P
-    syncdirs: U:\ V:\ X:\ Y:\ Z:\
-- BTOA_For_Win7:
-    prjname: BTOA
-    syncdirs: 'U: V: X: Y: Z: P: S: D: A:'
+#- Group0:
+#    4CX01P: 'U:\ V:\ X:\ Y:\ Z:\'
+#- BTOA_For_Win7:
+#    BTOA: 'U: V: X: Y: Z: P: S: D: A:'
+
+- Test Sync Group:
+    4CX01P: 'E:\1 E:\2 E:\3 E:\4 E:\5'

File Config2.yaml

-- Group1:
-	project: SYNC
-	paths: B: E: G: H: I: J: K: L: M: N: O: P: Q: R: S: T: U: V: X: Y: Z: \\192.168.200.224\VOL1\PDLINE
-- Group2:
-	project: 4BK01C
-	paths: K: M: O: R: B: J: Y: I: H: U: E: V:
-- Group3:
-	project: INTEL
-	paths: O:\4X701 R:\4X701 B:\4X701 M:\4X701 K:\4X701 J:\4X701 Z:\4X701 V:\4X701 Y:\4X701 S:\4X701 P:\4X701 U:\4X701 T:\4X701 N:\4X701 I:\4X701 H:\4X701 G:\4X701 E:\4X701 X:\4X701 L:\4X701 \\192.168.200.31\NETWARE\PDLINE\4X701
-- Group4:
-	project: DISCRETE
-	paths: O:\4X701 R:\4X701 B:\4X701 M:\4X701 K:\4X701 J:\4X701 Z:\4X701 V:\4X701 Y:\4X701 S:\4X701 P:\4X701 U:\4X701 T:\4X701 N:\4X701 I:\4X701 H:\4X701 G:\4X701 E:\4X701 X:\4X701 L:\4X701 \\192.168.200.31\NETWARE\PDLINE\4X701
-- Group5:
-	project: 4X701PAI
-	paths: R: B: Y: Z: U: Q: V: S: P: X:
-- Group6:
-	project: 4X701C
-	paths: K: M: O: R: B: J: Y: H: E: U:
-- Group7:
-	project: 4AQ01FG
-	paths: A: D: F: M: K: O: V: Y: J: Z: U: B: S: P: R: T: N: X: H: I: G: E: L:
-- Group8:
-	project: 4AQ01PAI
-	paths: X: Y: V: Q: S: P: Z: A: D: U: T: F: N: \\192.168.200.224\VOL1\PDLINE \\192.168.200.31\NETWARE\PDLINE
-- Group9:
-	project: 4AQ01
-	paths: R: B: U: V: O: M: Z: I: H: S: Y: P: X: G:
-- Group10:
-	project: 4AQ01C
-	paths: M: K: U: V: R: B: H: E: Y: Z:
-- Group11:
-	project: 4R601
-	paths: K: M: O: I: E: H:
-- Group12:
-	project: 4C301
-	paths: K: M: J: O: Y: Z: U: I: H: G: E:
-- Group13:
-	project: 4V101
-	paths: R: B: K: O: M: I: H: E:
-- Group14:
-	project: 4S701
-	paths: O: M: K: I: H: E:
-- Group15:
-	project: 4V601
-	paths: M: O: K: I: H: E:
-- Group16:
-	project: 4Q101F
-	paths: M: O: R: B: I: H:
-- Group17:
-	project: 4Q601
-	paths: K: M: O: J: I: H: G: E:
-- Group18:
-	project: 4Q601FG
-	paths: K: M: O: I: H: E:
-- Group19:
-	project: 4W101
-	paths: O: K: J: U: M: I: H: G: E:
-- Group21:
-	project: 4GN01PAI
-	paths: U: Y: V:  A: F:
-- Group22:
-	project: 4W001FG
-	paths: M: O: V: J: Y: Z: U: S: P: I: H:  G: T: X:
-- Group23:
-	project: 4W001
-	paths: V: Y: Z: Q: U: S: P: X:
-- Group24:
-	project: PAID
-	paths: V: R: B: Z: Y: U: S: P: X: A: D: Q:
-- Group25:
-	project: RUN4W101
-	paths: R: B: M: O: K: J: U: I: H: G: E:
-- Group26:
-	project: 4X201FG
-	paths: M: O: V: I: H:
-- Group27:
-	project: 4Q601V
-	paths: K: M: J: O: I: H: G: E:
-- Group28:
-	project: 4J601FG
-	paths: M: O: V: R: B: J: Z: Y: U: S: P: N: T: I: H: G: X: L:
-- Group29:
-	project: 4J601PAI
-	paths: R: B: Z: Y: U: Q: V: S: P: X:
-- Group30:
-	project: 4AR01
-	paths: R: B: O: K: J: M: U: I: H: G: E:
-- Group31:
-	project: 4AE01
-	paths: O:  U: Y: Z: I: X:
-- Group32:
-	project: 4S701
-	paths: V: R: B:
-- Group33:
-	project: POTOMAC
-	paths: R: Z: Y: Q: U: S: P: X: V:
-- Group34:
-	project: 4W001CA
-	paths: U: Y: Z:
-- Group35:
-	project: RUN4AR01
-	paths: R: B: O: K: J: M: U: I: H: G: E:
-- Group36:
-	project: 4BK01FG
-	paths: M: O: V: J: Z: Y: U: S: P: N: T: R: B: I: H: G: E: X: L: A: F: D: \\192.168.200.31\NETWARE\PDLINE
-- Group37:
-	project: 4BK01PAI
-	paths: R: B: Y: Q: V: S: P: X: Z: U: A: D:
-- Group38:
-	project: 4CX01FG
-	paths: R: B: N: T: U: O: M: I: H: Z: V: P: S: Y: X: L: G: A: D: F: \\192.168.200.224\VOL1\PDLINE
-- Group39:
-	project: 4CN01FG
-	paths: R: B: N: T: U: O: M: I: H: Z: V: P: S: Y: X: L: G: A: D: F: \\192.168.200.224\VOL1\PDLINE
-- Group40:
-	project: 4CN01PAI
-	paths: X: V: U: Z: Y: S: P: Q:  A:  D:  N: T: F: \\192.168.200.224\VOL1\PDLINE
-- Group41:
-	project: 4CN01
-	paths: B: N: Z: H: I: U: Y: X: S: G: T:
-- Group42:
-	project: 4CX01
-	paths: R: B: N: T: U: O: M: I: H: Z: V: P: S: Y: X: L: G:
-- Group43:
-	project: 4CX01PAI
-	paths: Z: Y: U: Q: A: V: S: P: N: T: F: X: D: \\192.168.200.224\VOL1\PDLINE
-- Group44:
-	project: 4CX01P
-	paths: Z: Y: U: Q: V: S: P: X:
-- Group45:
-	project: BTOA
-	paths: Y: Q: V: S: P: X: Z: U: A: D: \\192.168.200.224\VOL1\PDLINE
-- Group46:
-	project: 4EX01C
-	paths: K: M: O: R: B: J: Y: I: H: U: E: V:
-- Group47:
-	project: 4EX01FG
-	paths: M: O: V: J: Z: Y: U: S: P: N: T: R: B: I: H: G: E: X: L: A: F: D:
-- Group48:
-	project: 4EX01PAI
-	paths: R: B: Y: Q: V: S: P: X: Z: U: A: D:
-- Group49:
-	project: 4GN01
-	paths: B: H: I: U: A:  F:  T:
-- Group50:
-	project: 4HH01
-	paths: H: I: U: T: N: Z: F: D: A:
-- Group51:
-	project: 4DA01
-	paths: B: E: H: V:
-- Group52:
-	project: 4HH01PAI
-	paths: U: V: X: Y: Z: P:
-- Group53:
-	project: 4EK01
-	paths: B: T: I: U: H: V: F: D: A:
-- Group54:
-	project: 4EK01FG
-	paths: B: T: I: U: H: V: F: D: A:
-- Group55:
-	project: 4EK01PAI
-	paths: B: T: I: U: H: V: F: D: A:
-- Group56:
-	project: 4EM01
-	paths: B: T: I: U: H: V:
-- Group57:
-	project: 4EM01FG
-	paths: B: T: I: U: H: V:
-- Group58:
-	project: 4EM01PAI
-	paths: B: T: I: U: H: V:
-- Group59:
-	project: 4EN01
-	paths: B: T: I: U: H: V:
-- Group60:
-	project: 4EN01FG
-	paths: B: T: I: U: H: V:
-- Group61:
-	project: 4EN01PAI
-	paths: B: T: I: U: H: V:
 import os
 import time
 import yaml
+import shutil
 import logging
 import logging.handlers
 from datetime import datetime
 from subprocess import Popen, PIPE
-# from functools import wraps
+from functools import wraps
 from mercurial import ui, hg, commands
 
 def log_hg(func):
     "Simple logging decorator."
     @wraps(func)
     def wrapper(*args, **kwargs):
-        logging.basicConfig(filename=os.path.join(os.getcwd(), 'hgmon.log'),
-                            level=logging.DEBUG,
-                            format="[%(asctime)s] - %(message)s",)
-        logging.info("%s run with args %s" % (func.__name__, args))
+        #logging.basicConfig(filename=os.path.join(os.getcwd(), 'hgmon.log'),
+        #                    level=logging.INFO,
+        #                    format="[%(asctime)s] - %(message)s",)
+        str_args = filter(lambda x: not isinstance(x, ui.ui), args)
+        logging.debug("%s run with args %s" % (func.__name__, str_args))
         return func(*args, **kwargs)
     return wrapper
 
-def confirm_project(project_dir):
+def confirm_project_exists(project_dir):
     "Make sure project directory actually exists and create one if it doesn't."
     if os.path.exists(project_dir):
         if not os.path.isdir(project_dir): 
                     str(t.second).zfill(2)])
     return dstr + '/' + tstr
     
-def modify_config(project_dir):
+def hg_modify_config(project_dir):
     "Writes config to do auto update after hg push."
-    config_file = os.path.join(project_dir, '.hg', 'hgrc')
-    with open(config_file, 'a') as cfg:
-        cfg.write('[hooks]\n')
-        cfg.write('changegroup = hg update >&2\n')
+    hgrc_src = 'hgrc_template'
+    hginnore_src = 'hgignore_template'
+    hgrc_dst = os.path.join(project_dir, '.hg', 'hgrc')
+    hgignore_dst = os.path.join(project_dir, '.hg', 'hgignore')
+    configpairs = [(hgrc_src, hgrc_dst), (hgignore_src, hgignore_dst)]
+    for src, dst in configpairs:
+        if os.path.exists(src) and not os.path.exists(dst):
+            shutil.copy(src, dst)
 
-def loadconfig(configfile):
+def load_project_config(configfile):
     "Project_dir_group_config_file -> dir group list"
     with open(configfile) as f:
         y = yaml.load(f)
     grouplist = []
     for entry in y:
-        for k, v in entry.iteritems():
-            sdirs = v['syncdirs'].split()
-            pname = v['prjname']
-            grouplist.append(set(map(lambda x: os.path.join(x, pname), sdirs)))
+        for group in entry.itervalues():
+            for k, v in group.iteritems():
+                grouplist.append(set(map(lambda x: os.path.join(x, k),
+                                         v.split())))
     return grouplist
 
+@log_hg
 def hg_init(dest):
     return commands.init(ui.ui(), dest=dest)
 
+@log_hg
 def hg_commit(u, dest, comment):
     repo = hg.repository(u, dest)
     return commands.commit(u, repo, message=comment, addremove=True)
 
+@log_hg
 def hg_push(u, src, dest):
     src_repo = hg.repository(u, src)
     dest_repo = hg.repository(u, dest)
     return commands.push(u, src_repo, dest, force=True)
 
+@log_hg
 def hg_update_branch(u, dest, br_name=None):
     repo = hg.repository(u, dest)
     return commands.update(u, repo, node=br_name)
 
+@log_hg
 def hg_update_c(u, dest):
     repo = hg.repository(u, dest)
     return commands.update(u, repo, check=True)
-    
+
+@log_hg
 def hg_branch(u, dest, br_name):
     repo = hg.repository(u, dest)
     return commands.branch(u, repo, label=br_name)
 
+@log_hg
 def hg_autobranch(u, dest):
-    if hg_status_is_modified(u, dest):
+    if hg_status_is_changed(u, dest):
         hg_branch(u, dest, auto_branch_name())
         hg_commit(u, dest, 'auto commit')
         return hg_update_branch(u, dest, br_name='default')
     else:
         hg_update_branch(u, dest, br_name='default')
 
-def hg_status_is_modified(u, dest):
+@log_hg
+def hg_status_is_changed(u, dest):
     repo = hg.repository(u, dest)
     return not commands.status(u, repo)
     # Patched commands.py to get this working.
     ## else: return False
     # I heard it's always good to return something in your function.
 
-if __name__ == '__main__':
+def main():
     configfile = 'config.yaml'
-    flagfile = 'CHANGED.FLG'
-    lockfile = 'LOCK.FLG'
+    changefile = 'CHANGED.FLG'
+    lockfile = 'LOCKED.FLG'
+    logging.basicConfig(filename=os.path.join(os.getcwd(), 'hgmon.log'),
+                        level=logging.INFO,
+                        format="[%(asctime)s] - %(message)s",)
     while True:
-        grouplist = loadconfig(configfile)
+        grouplist = load_project_config(configfile)
         for group in grouplist:
             for project_dir in group:
-                confirm_project(project_dir)
-                chflag = os.path.join(project_dir, flagfile)
+                confirm_project_exists(project_dir)
+                chflag = os.path.join(project_dir, changefile)
                 hgflag = os.path.join(project_dir, '.hg')
-                lockfile = os.path.join(project_dir, lockfile)
-                if os.path.exists(lockfile): continue
+                lockflag = os.path.join(project_dir, lockfile)
+                if os.path.exists(lockflag): continue
                 if not os.path.exists(hgflag):
                     hg_init(project_dir)
+                    hg_modify_config(project_dir)
                 if os.path.exists(chflag):
                     time.sleep(0.2)
                     user, comment = parse_flag(chflag)
+                    logging.info("User %s changed %s" % (user, project_dir))
                     os.environ['HGUSER'] = user
                     u = ui.ui()
                     os.remove(chflag)
+                    logging.info("Commiting changes for %s" % project_dir)
+                    logging.info("Message: '%s'" % comment)
                     hg_commit(u, project_dir, comment)
                     syncgroup = group.copy()
                     syncgroup.remove(project_dir)
                     for syncdir in syncgroup:
-                        if os.path.exists(lockfile):
+                        if os.path.exists(lockflag):
+                            logging.info("Skipping locked %s" % syncdir)
                             continue
+                        logging.info("Pushing to dir %s" % syncdir)
                         hg_push(u, project_dir, syncdir)
+                        logging.info("Updating files in dir %s" % syncdir)
                         hg_autobranch(u, syncdir)
         time.sleep(10)
+
+if __name__ == '__main__':
+    main()
 different servers, and has to be synchronized to each other. All the projects 
 are shared with Samba service. There is a Windows server connecting to all the 
 Samba shares. The synchronizing script runs on the Windows Server. Currently we 
-use a simple copy-to-all method to keep the project directories synchronized.
+use a simple copy-to-all method to keep the projects synchronized.
 
 This script is an attempt to integrate version control with directory 
 synchronizing . It provides a simple way to turn the project directories into 
 Currently only simple auto committing, synchronizing, and auto 
 branching are supported.
 
+Simple logging is also supported.