SVN Commit

The main purpose of SVN Commit is to save you time commiting any file(s) to the target SVN repository. What SVNc does, it parses files within an SVN checkout for a “commit comment”. Once this comment is found, it does certian checks to see if the file has changed, if so, it then commits the file back to it’s SVN repository, otherwise, moves to the next.

It’s a good program to use alone with a task scheduler (Windows) or a Cron job (GNU/Linux).

Programmed in Python, currently in alpha stages. It’s a small bit buggy, and new releases will be posted soon, maybe even a GUI. Feel free to make any suggestions, complaints, bug fixes, patches and what not.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#!/usr/bin/python
 
from optparse import OptionParser
from hashlib import md5
import sys, glob, os, re, MySQLdb, pysvn
 
class svnc:
 
   """
   set default arguments for CLI variables
   """
 
   def __init__ (self):
      self.options = False
      self.list = []
      self.parseCLI()
      self.db = {}
 
      # TODO get connection information from self.parseCLI() CLI args
      db = MySQLdb.connect(host   = 'localhost',
                           user   = 'svnc',
                           passwd = 'svnc',
                           db     = 'svnc')
 
      self.cursor = db.cursor()
 
   """
   parse CLI arguments
   # FIXME looping multiple times
   """
 
   def parseCLI (self):
      parser = OptionParser()
      parser.add_option_version = 'pre-alpha'
      parser.add_option('-d', '--daemon', dest='daemon', default=False, metavar='(yes|no)', help='run as daemon')
      parser.add_option('-c', '--checkout', dest='checkout', metavar='/path/to/checkout/', help='path to repository checkout')
      parser.add_option('-e', '--extensions', dest='extensions', metavar='ext,ext,...', help='extensions to check')
      parser.add_option('-u', '--username', dest='username', metavar='username', help='username for svn repository login')
      parser.add_option('-p', '--password', dest='password', metavar='password', help='password for svn repository login')
      parser.add_option('-q', '--quiet', dest='quiet', metavar='quiet', help='display nothing to stdout')
      (self.options, args) = parser.parse_args()
      try:
         self.options.extensions = self.options.extensions.split(',')
      except AttributeError:
         parser.print_help()
         sys.exit(1)
 
   """
   get value parsed from CLI
   """
 
   def get (self, key):
      return eval("self.options.%s" % key)
 
   def scan (self, path):
      files = []
      for i in os.listdir(path):
         name = os.path.join(path, i)
         if os.path.isfile('%s' % name):
            # check for extensions
            for extension in self.options.extensions:
               if  name[-2:] == extension:
                  files.append(name)
         elif os.path.isdir('%s' % name):
            for j in self.scan(name):
               files.append(j)
      return files
 
   """
   extract @commit comment from filename
   """
 
   def extract (self, filename):
      contents = open(filename).read()
      # regex @commit till and excluding n (raw for r)
      match = re.search(r"@commit(.*)", contents)
      if match:
         return { 'comment' : match.group(1).strip(), 'filename' : filename, 'hash' : md5(contents).hexdigest() }
 
   """
   checks for legit changes within self.list
   removes any non-legit files
   """
 
   def check (self, current):
 
      self.cursor.execute('SELECT hash, comment FROM svnc WHERE filename = "%s"' % current['filename'])
      client = pysvn.Client()
      row = self.cursor.fetchone()
 
      # add file to database
      if self.cursor.rowcount == 0 or row == None:
         print current['filename'], "not currently in database, adding."
         self.cursor.execute('INSERT INTO svnc (filename, hash, comment) VALUES ("%s", "%s", "%s")' % (current['filename'], current['hash'], current['comment']))
         # TODO before adding to svn repository, check if it already belongs to one
         #entry = client.info(current['filename'].rsplit("/", 1)[0])
         if client.add(current['filename']) == pysvn._pysvn_2_5.ClientError:
            print current['filename'], "does not belong to a SVN checkout."
            return
         return
 
      # return if there has been no comment changes
      if row[1] == current['comment']:
         return
 
      # replace new comment with old
      # check md5 checksum
      replacedChecksum = md5(re.sub('@commit %s' % current['comment'], '@commit %s' % row[1], open(current['filename'], 'r').read())).hexdigest()
      currentChecksum = md5(open(current['filename'], 'r').read()).hexdigest()
 
      if replacedChecksum != currentChecksum:
         print current['filename'], "has changed, commiting changes to SVN repository."
         self.cursor.execute('UPDATE svnc SET comment = "%s", hash = "%s" WHERE filename = "%s"' % (current['comment'], replacedChecksum, current['filename']))
         client.checkin([current['filename']], current['comment'])
 
# Let's run it!
sc = svnc
for i in sc().scan(sc().get("checkout")):
   if sc().extract(i) != None:
      sc().check(sc().extract(i))

Feedback