VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/testmanager/batch/vcs_import.py@ 100255

Last change on this file since 100255 was 98103, checked in by vboxsync, 2 years ago

Copyright year updates by scm.

  • Property svn:eol-style set to LF
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 8.5 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3# $Id: vcs_import.py 98103 2023-01-17 14:15:46Z vboxsync $
4
5"""
6Cron job for importing revision history for a repository.
7"""
8
9from __future__ import print_function;
10
11__copyright__ = \
12"""
13Copyright (C) 2012-2023 Oracle and/or its affiliates.
14
15This file is part of VirtualBox base platform packages, as
16available from https://www.virtualbox.org.
17
18This program is free software; you can redistribute it and/or
19modify it under the terms of the GNU General Public License
20as published by the Free Software Foundation, in version 3 of the
21License.
22
23This program is distributed in the hope that it will be useful, but
24WITHOUT ANY WARRANTY; without even the implied warranty of
25MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
26General Public License for more details.
27
28You should have received a copy of the GNU General Public License
29along with this program; if not, see <https://www.gnu.org/licenses>.
30
31The contents of this file may alternatively be used under the terms
32of the Common Development and Distribution License Version 1.0
33(CDDL), a copy of it is provided in the "COPYING.CDDL" file included
34in the VirtualBox distribution, in which case the provisions of the
35CDDL are applicable instead of those of the GPL.
36
37You may elect to license modified versions of this file under the
38terms and conditions of either the GPL or the CDDL or both.
39
40SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
41"""
42__version__ = "$Revision: 98103 $"
43
44# Standard python imports
45import sys;
46import os;
47from optparse import OptionParser; # pylint: disable=deprecated-module
48import xml.etree.ElementTree as ET;
49
50# Add Test Manager's modules path
51g_ksTestManagerDir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))));
52sys.path.append(g_ksTestManagerDir);
53
54# Test Manager imports
55from testmanager.config import g_kdBugTrackers;
56from testmanager.core.db import TMDatabaseConnection;
57from testmanager.core.vcsrevisions import VcsRevisionData, VcsRevisionLogic;
58from testmanager.core.vcsbugreference import VcsBugReferenceData, VcsBugReferenceLogic;
59from common import utils;
60
61# Python 3 hacks:
62if sys.version_info[0] >= 3:
63 long = int; # pylint: disable=redefined-builtin,invalid-name
64
65
66class VcsImport(object): # pylint: disable=too-few-public-methods
67 """
68 Imports revision history from a VSC into the Test Manager database.
69 """
70
71 class BugTracker(object):
72 def __init__(self, sDbName, sTag):
73 self.sDbName = sDbName;
74 self.sTag = sTag;
75
76
77 def __init__(self):
78 """
79 Parse command line.
80 """
81
82 oParser = OptionParser()
83 oParser.add_option('-b', '--only-bug-refs', dest = 'fBugRefsOnly', action = 'store_true',
84 help = 'Only do bug references, not revisions.');
85 oParser.add_option('-e', '--extra-option', dest = 'asExtraOptions', metavar = 'vcsoption', action = 'append',
86 help = 'Adds a extra option to the command retrieving the log.');
87 oParser.add_option('-f', '--full', dest = 'fFull', action = 'store_true',
88 help = 'Full revision history import.');
89 oParser.add_option('-q', '--quiet', dest = 'fQuiet', action = 'store_true',
90 help = 'Quiet execution');
91 oParser.add_option('-R', '--repository', dest = 'sRepository', metavar = '<repository>',
92 help = 'Version control repository name.');
93 oParser.add_option('-s', '--start-revision', dest = 'iStartRevision', metavar = 'start-revision',
94 type = "int", default = 0,
95 help = 'The revision to start at when doing a full import.');
96 oParser.add_option('-t', '--type', dest = 'sType', metavar = '<type>',
97 help = 'The VCS type (default: svn)', choices = [ 'svn', ], default = 'svn');
98 oParser.add_option('-u', '--url', dest = 'sUrl', metavar = '<url>',
99 help = 'The VCS URL');
100
101 (self.oConfig, _) = oParser.parse_args();
102
103 # Check command line
104 asMissing = [];
105 if self.oConfig.sUrl is None: asMissing.append('--url');
106 if self.oConfig.sRepository is None: asMissing.append('--repository');
107 if asMissing:
108 sys.stderr.write('syntax error: Missing: %s\n' % (asMissing,));
109 sys.exit(1);
110
111 assert self.oConfig.sType == 'svn';
112
113 def main(self):
114 """
115 Main function.
116 """
117 oDb = TMDatabaseConnection();
118 oLogic = VcsRevisionLogic(oDb);
119 oBugLogic = VcsBugReferenceLogic(oDb);
120
121 # Where to start.
122 iStartRev = 0;
123 if not self.oConfig.fFull:
124 if not self.oConfig.fBugRefsOnly:
125 iStartRev = oLogic.getLastRevision(self.oConfig.sRepository);
126 else:
127 iStartRev = oBugLogic.getLastRevision(self.oConfig.sRepository);
128 if iStartRev == 0:
129 iStartRev = self.oConfig.iStartRevision;
130
131 # Construct a command line.
132 os.environ['LC_ALL'] = 'en_US.utf-8';
133 asArgs = [
134 'svn',
135 'log',
136 '--xml',
137 '--revision', str(iStartRev) + ':HEAD',
138 ];
139 if self.oConfig.asExtraOptions is not None:
140 asArgs.extend(self.oConfig.asExtraOptions);
141 asArgs.append(self.oConfig.sUrl);
142 if not self.oConfig.fQuiet:
143 print('Executing: %s' % (asArgs,));
144 sLogXml = utils.processOutputChecked(asArgs);
145
146 # Parse the XML and add the entries to the database.
147 oParser = ET.XMLParser(target = ET.TreeBuilder(), encoding = 'utf-8');
148 oParser.feed(sLogXml.encode('utf-8')); # Does its own decoding; processOutputChecked always gives us decoded utf-8 now.
149 oRoot = oParser.close();
150
151 for oLogEntry in oRoot.findall('logentry'):
152 iRevision = int(oLogEntry.get('revision'));
153 sAuthor = oLogEntry.findtext('author', 'unspecified').strip(); # cvs2svn entries doesn't have an author.
154 sDate = oLogEntry.findtext('date').strip();
155 sRawMsg = oLogEntry.findtext('msg', '').strip();
156 sMessage = sRawMsg;
157 if sMessage == '':
158 sMessage = ' ';
159 elif len(sMessage) > VcsRevisionData.kcchMax_sMessage:
160 sMessage = sMessage[:VcsRevisionData.kcchMax_sMessage - 4] + ' ...';
161 if not self.oConfig.fQuiet:
162 utils.printOut(u'sDate=%s iRev=%u sAuthor=%s sMsg[%s]=%s'
163 % (sDate, iRevision, sAuthor, type(sMessage).__name__, sMessage));
164
165 if not self.oConfig.fBugRefsOnly:
166 oData = VcsRevisionData().initFromValues(self.oConfig.sRepository, iRevision, sDate, sAuthor, sMessage);
167 oLogic.addVcsRevision(oData);
168
169 # Analyze the raw message looking for bug tracker references.
170 for oBugTracker in g_kdBugTrackers.values():
171 for sTag in oBugTracker.asCommitTags:
172 off = sRawMsg.find(sTag);
173 while off >= 0:
174 off += len(sTag);
175 while off < len(sRawMsg) and sRawMsg[off].isspace():
176 off += 1;
177
178 if off < len(sRawMsg) and sRawMsg[off].isdigit():
179 offNum = off;
180 while off < len(sRawMsg) and sRawMsg[off].isdigit():
181 off += 1;
182 try:
183 iBugNo = long(sRawMsg[offNum:off]);
184 except Exception as oXcpt:
185 utils.printErr(u'error! exception(r%s,"%s"): -> %s' % (iRevision, sRawMsg[offNum:off], oXcpt,));
186 else:
187 if not self.oConfig.fQuiet:
188 utils.printOut(u' r%u -> sBugTracker=%s iBugNo=%s'
189 % (iRevision, oBugTracker.sDbId, iBugNo,));
190
191 oBugData = VcsBugReferenceData().initFromValues(self.oConfig.sRepository, iRevision,
192 oBugTracker.sDbId, iBugNo);
193 oBugLogic.addVcsBugReference(oBugData);
194
195 # next
196 off = sRawMsg.find(sTag, off);
197
198 oDb.commit();
199
200 oDb.close();
201 return 0;
202
203if __name__ == '__main__':
204 sys.exit(VcsImport().main());
205
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette