File: loginfo-handler

package info (click to toggle)
viewcvs 0.9.2-4woody1
  • links: PTS
  • area: main
  • in suites: woody
  • size: 752 kB
  • ctags: 655
  • sloc: python: 6,591; sh: 80; makefile: 68
file content (190 lines) | stat: -rwxr-xr-x 6,049 bytes parent folder | download
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
#!/usr/bin/python
# -*- Mode: python -*-
#
# Copyright (C) 2000 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewCVS
# distribution or at http://www.lyra.org/viewcvs/license-1.html.
#
# Contact information:
#   Greg Stein, PO Box 760, Palo Alto, CA, 94302
#   gstein@lyra.org, http://www.lyra.org/viewcvs/
#
# -----------------------------------------------------------------------
#
# updates SQL database with new commit records
#
# -----------------------------------------------------------------------
#

#########################################################################
#
# INSTALL-TIME CONFIGURATION
#
# These values will be set during the installation process. During
# development, they will remain None.
#

LIBRARY_DIR = None
CONF_PATHNAME = None

# Adjust sys.path to include our library directory
import sys

if LIBRARY_DIR:
  sys.path.insert(0, LIBRARY_DIR)
else:
  sys.path[:0] = ['../lib']	# any other places to look?

#########################################################################

import os
import string
import getopt
import re
import cvsdb
import rlog
import config


DEBUG_FLAG = 0

## pre-compiled regular expressions
_re_fileversion = re.compile("([^,]+)\,([^,]+)\,([^,]+)")

## output functions
def debug(text):
    if DEBUG_FLAG:
        print 'DEBUG(loginfo): %s' % (text)

def warning(text):
    print 'WARNING(loginfo): %s' % (text)

def error(text):
    print 'ERROR(loginfo): %s' % (text)
    sys.exit(1)

class FileData:
    def __init__(self, file, directory, old_version, new_version):
        self.file = file
        self.directory = directory
        self.old_version = old_version
        self.new_version = new_version

        ## set the state of this file from the
        ## old_version and new_version information
        if self.old_version == 'NONE':
            self.ctype = "added"
        elif self.new_version == 'NONE':
            self.ctype = "removed"
        else:
            self.ctype = "changed"

def CommitFromFileData(cfg, repository, file_data):
    ## construct the full path for the RCS file
    filename = os.path.join(repository, file_data.directory, file_data.file)

    ## get the 'rlog' output for just this revision, and then convert
    ## to a commit object
    rlog_data = rlog.GetRLogData(cfg, filename, file_data.new_version)
    commit_list = cvsdb.RLogDataToCommitList(repository, rlog_data)
    commit = commit_list[0]

    ## set the type of commit from the file_data setting
    if file_data.ctype == "changed":
        commit.SetTypeChange()
    elif file_data.ctype == "added":
        commit.SetTypeAdd()
    elif file_data.ctype == "removed":
        commit.SetTypeRemove()
        
    return commit

def GetUnrecordedCommitList(repository, file_data):
    filename = os.path.join(repository, file_data.directory, file_data.file)
    return cvsdb.GetUnrecordedCommitList(repository, filename)

def ProcessLoginfo(repository, stdin_list):
    ## XXX This is a somewhat dirty hack:
    ## cvsdb already loads the configuration file and provides a cfg
    ## instance.  Pick it from there in order to be able to pass it down
    ## to rlog (see below).
    cfg = cvsdb.cfg

    ## the first line in stdin is a space-separated list; the first
    ## item in the list is the directory path being updated this run;
    ## the rest of the items are the files being updated
    list = string.split(stdin_list[0])

    ## clean up the directory the following way: we don't want it
    ## to begin with a path seperator, and we don't want it to end
    ## with a path seperator
    directory = list[0]
    while directory[0] == os.sep:
        directory = directory[1:]
    while directory[-1] == os.sep:
        directory = directory[:-1]

    ## NOTE: SPECIAL HANDLING FOR NEW DIRECTORIES
    ##       new directories have the first line form
    ##       path/of/dir - New directory
    if len(list) == 4:
        if list[1] == '-' and list[2] == 'New' and list[3] == 'directory':
            debug('new directory')
            return

    ## each file in the file list _should_ be of the form:
    ## file-name,<old-ver>,<new-ver>
    ## a new file has the keyword 'NONE' for old-ver
    file_data_list = []
    for item in list[1:]:
        temp = _re_fileversion.match(item)
        if not temp:
            debug('failed match %s' % (item))
            continue

        filename = temp.group(1)
        old_version = temp.group(2)
        new_version = temp.group(3)
        file_data =  FileData(filename, directory, old_version, new_version)
        file_data_list.append(file_data)

    ## convert FileData objects into Commit objects so we can insert them
    ## into the database
    commit_list = []
    for file_data in file_data_list:
        ## XXX: this is nasty: in the case of a removed file, we are not
        ##      given enough information to find it in the rlog output!
        ##      So instead, we rlog everything in the removed file, and
        ##      add any commits not already in the database
        if file_data.ctype == "removed":
            temp = GetUnrecordedCommitList(repository, file_data)
            commit_list = commit_list + temp
        else:
            commit_list.append(CommitFromFileData(cfg, repository, file_data))

    ## add to the database
    db = cvsdb.ConnectDatabase()
    db.AddCommitList(commit_list)


## MAIN
if __name__ == '__main__':
    ## get the repository from the environment
    try:
        repository = os.environ['CVSROOT']
    except KeyError:
        error('CVSROOT not in environment')

    ## clean up the repository string: remove any trailing path seperater
    while repository[-1] == os.sep:
        repository = repository[:-1]

    ## read all the lines from stdin
    stdin_list = []
    for line in sys.stdin.readlines():
        stdin_list.append(string.rstrip(line))

    ProcessLoginfo(repository, stdin_list)
    sys.exit(0)