gastlygem  committed 848ea47

Fix logging, cleaner screen output.

  • Participants
  • Parent commits 9c0940d
  • Tags 0.4

Comments (0)

Files changed (7)

 # To avoid Yaml parsing errors on Windows volume names (damn those colons), it 
 # is better to add a single quote to the syncdir group.
+# If the directory list is too long, you can use "\" to continue on the next 
+# line, e.g.,
+# - Group1:
+#     PRJ1: '\\ \\ \\ \\ \
+# \\ \\ \\'
+# Don't forget the trailing quotation mark.
 # ############################################################################ #
 """ -- Monitoring directory change and sync project directories upon
-If CHANGED.FLG is in the project directory, the script will try to commit it,
-then sync (hg push) to other directories of the same project. If any conflict
-files are found, it will create a branch named by date and time, commit the
-conflicts to the branch, then branch to default and update the previous push
+If a file named 'SYNC!' is in the project directory, the script will try to
+read into the file, parse out user name and commit message, then commit the
+project, then sync (hg push) to other directories of the same project. If any
+conflict is found, it will create a branch named by 'date-time-conflictdir',
+record the conflicts to the branch, then branch to default and update the
+previous pushed content.
-If LOCKED.FLG is in the project directory, the script will ignore the directory,
-no change will be pushed or synchronized to the project.
+If a file named 'LOCKED!' is in the project directory, the script will ignore
+the directory, no change will be pushed or synchronized to the project.
-Content format of CHANGED.FLG is "User Message String", e.g.,
-    Joel Changed something.
+Content format of 'SYNC!' is 'User Message String', e.g.,
+    Joel Fixed a bug.
 The first word in the message is treated as user name, other strings are treated
 as commit messages.
 import os, re, shutil, filecmp, yaml
-import logging, logging.handlers
+import logging, logging.config
 from time import sleep
 from datetime import datetime
 from hgcmd import init, commit, autosync
     return grouplist
 def main():
+    logging.config.fileConfig('logconfig.ini')
+    log = logging.getLogger('SyncLog')
     configfile = 'config.yaml'
-    changefile = 'CHANGED.FLG'
-    lockfile = 'LOCKED.FLG'
-    logging.basicConfig(filename=os.path.join(os.getcwd(), 'hgmon.log'),
-                        level=logging.INFO,
-                        format="[%(asctime)s] - %(message)s",)
+    fn_syncflag = 'SYNC!'       # Command sync
+    fn_lockflag = 'LOCKED!'     # Status locked
+    fn_statflag = 'DOING'       # Status synchronizing
     while True:
         grouplist = load_project_config(configfile)
         for group in grouplist:
             for project_dir in group:
-                chflag = os.path.join(project_dir, changefile)
-                hgflag = os.path.join(project_dir, '.hg')
-                lockflag = os.path.join(project_dir, lockfile)
-                if os.path.exists(lockflag): continue
-                if not os.path.exists(hgflag):
+                fd_syncflag = os.path.join(project_dir, fn_syncflag)
+                fd_hgflag = os.path.join(project_dir, '.hg')
+                fd_lockflag = os.path.join(project_dir, fn_lockflag)
+                if os.path.exists(fd_lockflag): continue
+                if not os.path.exists(fd_hgflag):
-                    hg_modify_config(project_dir)
-                if os.path.exists(chflag):
+                hg_modify_config(project_dir)
+                if os.path.exists(fd_syncflag):
-                    user, comment = parse_flag(chflag)
-                    os.remove(chflag)
-          "%s changed %s" % (user, project_dir))
-          "Message: '%s'" % comment)
+                    user, comment = parse_flag(fd_syncflag)
+                    os.remove(fd_syncflag)
+                    fd_statflag = os.path.join(project_dir, fn_statflag)
+                    sf = open(fd_statflag, 'w')
+                    sf.close()
+          "%s changed %s" % (user, project_dir))
+          "Message: '%s'" % comment)
                     os.environ['HGUSER'] = user
-          "Commiting changes for %s" % project_dir)
+          "Commiting changes for %s" % project_dir)
                     commit(project_dir, comment)
                     syncgroup = group.copy()
                     autosync(project_dir, syncgroup)
+                    os.remove(fd_statflag)
+          "Sync completed!")
 if __name__ == '__main__':
+=== hgsync ===
 Synchronizing hg repositories in different locations.
 In my working environment we still use DOS a lot to modify code hosted on 
 changes, then takes action specified by the flags.
 Currently only simple auto committing, synchronizing, and auto branching are 
+=== Files ===
+ -- The main app -- mercurial commands
+Config.yaml -- Project directory configurations
+logconfig.ini -- logging configurations
+hgrc.template -- hgrc used by all repos
+hgignore.template -- .hgignore used by all repos
+=== Usage ===
+1. Modify Config.yaml to set project directories.
+2. Run on sync server
+3. The project directories will be initiated as hg repos.
+4. Now you can put certain flags the repos to control the synchronization.
+Supported flags:
+"SYNC!" -- Command Sync. If the flag is detected, the content of the flag is parsed
+and then removed, then commit and sync will be executed. 
+"LOCKED!" -- Command locked. If the flag is present in the project, the project will
+not be updated or synchronized.
+"DOING" -- Status synchronizing. The flag will appear during program sync, will be
+disappeard after sync finished.
 import os
-import logging, logging.handlers
+import logging, logging.config
 from datetime import datetime
 from functools import wraps
 from mercurial import cmdutil, ui, commands, patch, hg
-logging.basicConfig(filename=os.path.join(os.getcwd(), 'hgmon.log'),
-                    level=logging.DEBUG,
-                    format="[%(asctime)s] - %(message)s",)
-def log_hg(func):
-    "Simple logging decorator."
-    @wraps(func)
-    def wrapper(*args, **kwargs):
-        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
+log = logging.getLogger('SyncLog')
 def auto_branch_name(dest):
     "generates branch name based on"
     for piece in dest.split(os.path.sep):
     return '-'.join([dstr, tstr, piece])
 def init(dest):
     "hg init dest"
     return commands.init(ui.ui(), dest=dest)
 def diff(dest, u=ui.ui()):
     "prints diff log"
     repo = hg.repository(ui, dest)
     it = patch.diff(repo, node1, node2, match=m)
     if len(list(it)) > 0:
         for line in it:
-            print line # TODO: output to mail log
+            log.debug(line) # TODO: output to mail log
         return 1
     else: return 0
 def commit(dest, comment, u=ui.ui()):
     "hg commit"
+"commiting for %s" % dest)
+"Message: %s" % comment)
     repo = hg.repository(u, dest)
     return commands.commit(u, repo, message=comment, addremove=True)
 def push(src, dest, u=ui.ui()):
-    "hg push"
+    "hg push -f"
     src_repo = hg.repository(u, src)
     dest_repo = hg.repository(u, dest)
-    return commands.push(u, src_repo, dest, force=True)
+    return src_repo.push(dest_repo, force=True)
 def update_branch(dest, br_name=None, u=ui.ui()):
     "hg update br_name"
     repo = hg.repository(u, dest)
     return commands.update(u, repo, node=br_name)
 def branch(dest, br_name, u=ui.ui()):
     "hg branch br_name"
     repo = hg.repository(u, dest)
     return commands.branch(u, repo, label=br_name)
 def autobranch(dest, u=ui.ui()):
     "Create new branch if repo is changed"
     if repo_is_changed(dest, u):
         update_branch(dest, br_name='default', u=u)
         return False
 def repo_is_changed(dest, u=ui.ui()):
     "'hg status' stripped down. Return true if the repo is changed."
     repo = hg.repository(u, dest)
     node1, node2 = cmdutil.revpair(repo, 0)
     m = cmdutil.match(repo)
     stat = repo.status(node1, node2, m, False, False, True)
-    print stat
     return len(filter(lambda x: len(x)!=0, stat)) != 0
 def autosync(project_dir, syncgroup, u=ui.ui()):
     for syncdir in syncgroup:
         lockflag = os.path.join(syncdir, 'LOCKED.FLG')
         if os.path.exists(lockflag):
-  "Skipping locked %s" % syncdir)
+  "Skipping locked %s" % syncdir)
-"Synchronizing %s" % syncdir)
+"Synchronizing %s" % syncdir)
         push(project_dir, syncdir, u)
         branched = autobranch(syncdir, u)
         if branched:
-  "Auto branch created on %s" % syncdir)
-  "Synchronizing back..")
+  "Auto branch created on %s" % syncdir)
+  "Synchronizing back..")
             autosync(syncdir, syncgroup, u)

File hgignore.template

 syntax: regexp
 # File extension longer than 3 letters.

File hgrc.template

-verbose = True

File logconfig.ini

+args=('hgmon.log', 'a')
+format=[%(asctime)s] %(message)s