diff -uNPr codestriker-1.9.2/codestriker.conf codestriker-1.9.2_TestDirector_scmbug/codestriker.conf
--- codestriker-1.9.2/codestriker.conf 2006-08-20 18:02:28.000000000 +0100
+++ codestriker-1.9.2_TestDirector_scmbug/codestriker.conf 2006-12-21 16:11:21.617062500 +0000
@@ -352,6 +352,7 @@
$bug_db = '';
#$bug_db = 'bugzilla';
#$bug_db = 'flyspray';
+#$bug_db = 'testdirector';
# Bugzilla database connection details.
#$bug_db_host = 'localhost';
@@ -367,6 +368,14 @@
#$flyspray_db_dbname = 'flyspray_dev';
#$flyspray_db_user_id = 50;
+# TestDirector connection details
+$testdirector_url = 'http://emea-testdir:8080/qcbin';
+$testdirector_user_id = 'robh';
+$testdirector_password = '';
+$testdirector_domain = 'DEFAULT';
+$testdirector_project = 'BPM33';
+$testdirector_file_list = 'BG_USER_29';
+
# The URL to the bug tracking system. The bug number is appended to the
# end of this string when URLs are generated. This can be left blank if
# there is no need for bug-tracking integration. Below are some example
@@ -375,6 +384,12 @@
#$bugtracker = 'http://localhost.localdomain/bugzilla/show_bug.cgi?id=';
#$bugtracker = '/flyspray_dev/?do=details&id=';
+# Some bug tracking systems store details of the files changed under each bug
+# ID. A generic plugin for bugzilla is scmbug which can be used to link
+# with source control systems such as subversion. The following flag enables/disables
+# the ability to a user to create a topic just using a Bug ID
+$bugdb_scmbug_link = 1;
+
# LXR database. Each repository can be optionally mapped to a
# different LXR deployment. If a repository has an associated LXR
# mapping, then create a new entry where the repository string is the
diff -uNPr codestriker-1.9.2/codestriker.conf.bak codestriker-1.9.2_TestDirector_scmbug/codestriker.conf.bak
--- codestriker-1.9.2/codestriker.conf.bak 1970-01-01 00:00:00.000000000 +0000
+++ codestriker-1.9.2_TestDirector_scmbug/codestriker.conf.bak 2006-12-21 15:52:10.000000000 +0000
@@ -0,0 +1,526 @@
+# -*-perl-*-
+# Configuration file for codestriker.pl.
+
+# Database to use for storing codestriker data. Examples given are
+# MySQL, Oracle, SQL Server, and PostgreSQL Refer to the
+# documentation on how to create the Codestriker database.
+
+# Example of a MySQL database URL residing on the same machine as the webserver.
+$db = 'DBI:mysql:dbname=codestrikerdb';
+
+# Example of a MySQL database on host dbhost. In this situation, you need to
+# ensure that the webserver host has permission to connect to the database on
+# dbhost. Check the MySQL documentation for further details.
+#$db = 'DBI:mysql:dbname=codestrikerdb;host=dbhost';
+
+# Example of an oracle database URL.
+#$db = 'DBI:Oracle:host=127.0.0.1;sid=local';
+
+# Example of an SQL Server ODBC database URL.
+#$db = 'DBI:ODBC:Codestriker';
+
+# Example of a PostgreSQL database URL using the native Pg driver.
+#$db = 'DBI:Pg:dbname=codestrikerdb';
+
+# Example of a SQLite database URL. Not fully supported yet.
+#$db = 'DBI:SQLite:dbname=/var/www/codestrikerdb';
+
+# Database user.
+#$dbuser = 'system';
+$dbuser = 'codestriker';
+
+# Database password.
+#$dbpasswd = 'manager';
+$dbpasswd = 'cspasswd';
+
+# Location of the mailing host. This is used when sending out codestriker
+# comments.
+$mailhost = 'smtp.tibco.com';
+
+# Set the user and password parameters if $mailhost requires SMTP
+# authentication. If commented out, it is assumed authentication is
+# not required.
+#$mailuser = 'smtpuser';
+#$mailpasswd = 'smtppasswd';
+
+# Indicate whether to try and compress output if the client browser
+# supports it. This can make a tremendous difference in bandwidth,
+# especially over slow links.
+$use_compression = 0;
+
+# Location of gzip. Gzip is used only if you don't have Compress::Zlib
+# installed. Note, if running with mod_perl, you _must_ have Compress:Zlib
+# installed. If gzip is not available, this can be set to "".
+$gzip = '/bin/gzip';
+
+# Location of the cvs binary.
+#$cvs = 'c:/Program Files/GNU/WinCvs 1.3/CVSNT/cvs.exe';
+$cvs = '/usr/bin/cvs';
+
+# Location of the svn binary.
+$svn = 'C:/Program Files/Subversion/bin/svn.exe';
+#$svn = '/usr/bin/svn';
+
+# Location of the ssh binary. This is only required if a CVS :ext
+# type repository is used.
+$ssh = '/usr/local/bin/ssh';
+
+# Location of the p4 (Perforce client) binary. This does not need to be set
+# if you are bot using any Perforce repositories.
+$p4 = '/usr/local/bin/p4';
+
+# Location of the vss binary. This can be ignored for deployments which don't
+# use VSS (Visual Source Safe).
+$vss = 'C:/Program Files/Microsoft Visual Studio/VSS/win32/ss.exe';
+
+# Temporary directory Codestriker can use. For *NIX platforms, this will
+# /tmp by default, for Windows 2000 c:\winnt\temp and for XP, c:\windows\temp.
+# For Win32 deployments, these temp directories may not be accessible to
+# the user running IIS or Apache, so explicitly specify an apprioriate
+# directory here that exists on the system. For *NIX platforms, there is
+# usually no need to do anything here.
+#$tmpdir = '/tmp/codestriker';
+$tmpdir = 'c:/codestriker/temp';
+
+# If codestriker is installed differently to that described in the README file
+# (for example on the sourceforge servers), it may be necessary to explicitly
+# specify the location of the codestriker_css as a URL.
+$codestriker_css = '';
+
+# Valid repositories which may be selected at the create topic screen.
+# The order shown here is the order presented in the option list. Most
+# deployments will only require a single repository to be specified.
+# Comment out / modify entries appropriate for your deployment.
+#
+# If this list is empty it won't be possible to view the entire contents of a
+# file before the proposed change and/or after. All of the places
+# in the application that ask for, or display repository information will
+# be hidden and lastly, it will be impossible to make a diff review topic
+# on files that already checked in.
+#
+# You also need to make sure that the user running your webserver has
+# permission to run the client SCM program (eg, cvs, p4, svn), and to
+# connect to the repository.
+@valid_repositories =
+ (
+ # Example CVSROOT of a CVS repository on the same machine as the
+ # codestriker server.
+ #'/home/sits/cvs',
+
+ # Example of a CVS repository which contains the URL to a viewcvs
+ # installation (CVS web is also supported), followed by the
+ # CVSROOT of the repository.
+ #'http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi /cvsroot',
+
+ # The next example is the syntax used for specifying a Subversion
+ # repository, which is simply the subversion repository URL
+ # prefixed # by svn:
+ #'svn:http://svn.collab.net/repos/svn/trunk',
+ 'svn:http://localhost/svn/source/',
+
+ # Subversion server with authentication. The user name and
+ # password should be added to the end and separated by
+ # semicolons.
+ #'svn:http://svn.collab.net/repos/svn/trunk;username;password',
+
+ # Example CVS pserver config with username and password
+ # specified.
+ #':pserver:sits:password@cvs.sourceforge.net:/cvsroot',
+
+ # Example CVS pserver config with proxy options.
+ #':pserver;proxy=abc.com;proxyport=8080:sits:pwd@cvs.dev.net',
+
+ # Example CVS pserver with empty password.
+ #':pserver:anonymous:@cvs.sourceforge.net:/cvsroot',
+
+ # Example CVS server which will be connected to with SSH. This
+ # assumes the appropriate ssh keys have been created so that the
+ # process running the Codestriker application can connect to the
+ # CVS server without requiring a password to be entered.
+ #':ext:sits@localhost:/home/sits/cvs',
+
+ # Visual SourceSafe repository on same machine at default
+ # location. Username "admin", password "password".
+ #'vss:admin;password',
+
+ # Visual SourceSafe repository on same machine, but with specific
+ # repository location specified.
+ #'vss:c:\\Program Files\\Microsoft Visual Studio\\VSS;admin;password',
+
+ # Visual SourceSafe repository located on a network fileshare.
+ #'vss:\\\\VisualSourceSafeMachineName\\SharedRepositoryPath;admin;password',
+ # Example Win32 CVS repository on the same machine.
+ #':local:c:\\cvsrep',
+
+ # Another Win32 CVS repository on the same machine.
+ #'c:/cvsrep2',
+
+ # The next example is for a Perforce repository. After the
+ # leading :perforce identifier, the next two components are the
+ # Perforce user and password parameters. The last two parameters
+ # after the '@' symbol represent the host and port number of
+ # the Perforce server.
+ #'perforce:sits:password@localhost:1666',
+
+ # Same as previous example, but with no password specified.
+ #'perforce:sits@localhost:1666',
+
+ # The next example is a ClearCase repository, where the path is
+ # the location of a shared snapshot view. From this view, it
+ # should be possible to a file of any version can be
+ # retrieved from the vob using the "cleartool get" command. It
+ # is important that this snapshot view is accessible with the
+ # same path specification for all developers. This is because
+ # a diff file created by a developer will refer to the snapshot
+ # view, and will allow Codestriker to retrieve specific files
+ # and versions mentioned in the review text, when necessary.
+ # It is also important that the user account running the
+ # webserver process has permission to access to the snapshot
+ # view.
+ #'clearcase:c:\\stuff\\view_name\\vob_name'
+
+ # The next example is a repository based off a ClearCase dynamic view.
+ # The clearcase identifier is followed by the dyn indicator,
+ # followed by the view name, followed by the location where the
+ # view is loaded.
+ # 'clearcase:dyn:viewname:/vobs'
+ );
+
+# A mapping of repository URLs to names. In any screen where a
+# repository is displayed, if there is a mapping for the repository
+# defined here, then the symbolic name will be displayed instead of
+# its raw URL. This is useful when the URL contains sensitive
+# username/password information, or the symbolic name is more
+# meaningful to the end-user. If there is no mapping defined for a
+# specific repository, its URL will be displayed.
+$repository_name_map =
+{
+ #'/home/sits/cvs' => 'Local CVS',
+ #':pserver:sits:password@cvs.sourceforge.net:/cvsroot' => 'SF CVS'
+ 'svn:http://localhost/svn/source/' => 'Subversion Source Repository'
+};
+
+# A mapping of repositories to filename viewers. Examples of such systems
+# would be CVSweb and ViewCVS, for local repositories. Mappings are
+# not required for remote CVSweb and ViewCVS repositories, as they are
+# viewers themselves. When viewing reviews, links from filenames will be
+# mapped to these URLs, to obtain revision log information for that file.
+$file_viewer =
+{
+# '/home/sits/cvs' => 'http://localhost/cgi-bin/cvsweb.cgi'
+ 'svn:http://localhost/svn/source/' => 'http://localhost:8080/svnwebclient/fileContent.jsp?url='
+};
+
+# Exclude these file types from review topics.
+# You will generally want to exclude any non-human-readable files.
+@exclude_file_types = ('rtf', 'doc', 'gif', 'bmp', 'jpeg', 'jpg', 'mdb',
+ 'ppt', 'vsd', 'xls', 'zip', 'tgz', 'tar', 'gz',
+ 'opt', 'aps', 'ncb', 'a', 'so', 'dll', 'lib',
+ 'exe', 'png', 'pdf', 'bin', 'out', 'ld', 'fm',
+ 'indd', 'wav', 'o', 'obj', 'mpp', 'vsw', 'jfif',
+ 'tif', 'tiff', 'xbm', 'fnt', 'ttf', 'pfm', 'pfb',
+ 'eps', 'wpj', 'sxi');
+
+# The number of problems found per line drops if the size of the
+# topic is too large. A common inspection pitfall is for authors to
+# attempt to review too much material and then miss problems.
+# These two options allow the Codestriker administrator to limit
+# the length of the topics. Topics that have more lines than
+# $maximum_topic_size_lines are rejected when they are created.
+# Topics that are larger than $suggested_topic_size_lines generate
+# a warning displayed in the topic page, but are accepted into the
+# system. Codestriker measures that length of the topic by counting
+# the number of lines in the topic text.
+#
+# The codestriker default of not enforcing any limits is specified by
+# settings either option to an empty string. If you are not sure
+# what a reasonable limit would be, start with a suggested_topic_size_lines
+# set to 350, and adjust with experience.
+$maximum_topic_size_lines = '';
+$suggested_topic_size_lines = '';
+
+# The default viewing mode to use in the URL when creating a topic. Can
+# be either ($NORMAL_MODE, $COLOURED_MODE or $COLOURED_MONO_MODE). These
+# values should not be changed.
+$NORMAL_MODE = 0;
+$COLOURED_MODE = 1;
+$COLOURED_MONO_MODE = 2;
+
+$default_topic_create_mode = $COLOURED_MODE;
+
+# The default line break viewing mode to use in the URL when viewing a
+# topic. Can be either $LINE_BREAK_NORMAL_MODE or $LINE_BREAK_ASSIST_MODE.
+# Using $LINE_BREAK_ASSIST_MODE indicates that extra line breaks may be
+# used in the topic display if the review has very long code lines. Using
+# $LINE_BREAK_NORMAL_MODE will ensure that the display matches the line
+# breaks present in the code. The line break mode can also be changed
+# dynamically in the view topic screen. There is usually no need to
+# change this setting unless you regularly review code with very long
+# lines.
+$LINE_BREAK_NORMAL_MODE = 1;
+$LINE_BREAK_ASSIST_MODE = 2;
+
+$default_topic_br_mode = $LINE_BREAK_NORMAL_MODE;
+
+# When displaying a topic, if this value is -1, then all files in the
+# topic are displayed in the one page (default old Codestriker
+# behaviour). If the value is 0, then only the first file is shown,
+# with links to display the other files. This is useful for those
+# deployments that review a large amount of code.
+$default_file_to_view = 0;
+
+# List of valid topic states. Note these values are mapped to the database
+# depending on their position in the list. ie, Open -> 0, Closed -> 1, etc.
+# There is no problem added new states dynamically, or changing the textual
+# names. Note, the initial topic state must be the first element. If
+# the 'Obsoleted' state is removed, then it will not be possible to obsolete
+# topics. If the 'Deleted' state is removed, then it will not be possible
+# to delete topics.
+@topic_states = ('Open', 'Closed', 'Committed', 'Obsoleted', 'Deleted');
+
+# Which states (in topic_states, above) represent a 'readonly' state.
+# If a topic is in a readonly state, then certain activities are disabled, such
+# as adding new comments, editing the metrics of existing comments, etc.
+@readonly_states = ('Closed', 'Committed', 'Obsoleted', 'Deleted');
+
+# Indicate if topics can be listed/searched. Turning this to false can be
+# useful for "anonymous" installations of codestriker.
+$allow_searchlist = 1;
+
+# The following controls project configuration. Each Codestriker topic is
+# a member of a specific project. Uncomment the option you want
+# below. Note the textual state names below cannot be changed.
+
+# Default option, projects are enabled, but they have no state
+# changing operations (ie, projects are always in state 'Open').
+@project_states = ('Open');
+
+# Don't use projects at all. Effectively, an implicit "default
+# project" is created and associated with all topics behind the scenes.
+# @project_states = ();
+#
+# Allow for projects to be closed. Closing a project will
+# not allow new topics to be created in that project.
+# @project_states = ('Open', 'Closed');
+#
+# Allow for projects to be deleted. This is potentially a dangerous
+# option to allow, as deleting a project will delete all of its member
+# topics as well. Use with caution.
+# @project_states = ('Open', 'Deleted');
+#
+# Allow for projects to be closed and deleted. Use with caution.
+# @project_states = ('Open', 'Closed', 'Deleted');
+
+# If true, don't display any email addresses in their true form, but
+# truncate them, to beat SPAM harvesters.
+$antispam_email = 0;
+
+
+# If comments_sent_to_topic_author is true, codestriker will send
+# out email to the topic owner and when a comment is added. If this
+# option is false, no email will be sent the topic owner.
+#
+# If comments_sent_to_commenter is set to true, codestriker will
+# blind cc (bcc) the comment author on all comments. The preceding
+# comments_sent_to_topic_author must be true in order for the blind
+# cc of emails to be enabled.
+#
+# If topic_state_change_sent_to_reviewers is set to true, codestriker
+# will send email to the reviewer list when a topic state is changed.
+#
+# Emails about each comment may not be needed if a meeting
+# is planned to discuss the topic. If the comment submitter specifies
+# a cc user, an email is always sent out, regardless of any email
+# settings.
+$email_send_options =
+ {
+ comments_sent_to_topic_author => 1,
+ comments_sent_to_commenter => 0,
+ topic_state_change_sent_to_reviewers => 0
+ };
+
+# Default width of tabs. Most developers expect this to be 8, but
+# some expect to see 4. This is also stored in the user's cookie, and
+# can be changed dynamically on the view topic screen.
+$default_tabwidth = 8;
+
+# Bug database to update. Currently, Bugzilla and Flyspray are
+# supported, but it is straight-forward to support other bug
+# databases. To enable Bugzilla, set $bug_db to "bugzilla", and set
+# the following parameters to your setup. To enable Flysprat, set
+# $bug_db to "flyspray", and set the relevant parameters.
+# if the $bug_db is an empty string, all bug-tracking related
+# features will be disabled.
+
+#$bug_db = '';
+$bug_db = 'bugzilla';
+#$bug_db = 'flyspray';
+#$bug_db = 'testdirector';
+
+# Bugzilla database connection details.
+$bug_db_host = 'localhost';
+$bug_db_name = 'bugs';
+$bug_db_password = 'staff123';
+$bug_db_dbname = 'bugs';
+$bug_db_user_id = '2';
+
+# Flyspray database connection details
+#$flyspray_db_host = 'localhost';
+#$flyspray_db_name = 'flyspray';
+#$flyspray_db_password = 'flyspray_password';
+#$flyspray_db_dbname = 'flyspray_dev';
+#$flyspray_db_user_id = 50;
+
+# TestDirector connection details
+$testdirector_url = 'http://emea-testdir:8080/qcbin';
+$testdirector_user_id = 'robh';
+$testdirector_password = '';
+$testdirector_domain = 'DEFAULT';
+$testdirector_project = 'BPM33';
+$testdirector_file_list = 'BG_USER_29';
+
+# The URL to the bug tracking system. The bug number is appended to the
+# end of this string when URLs are generated. This can be left blank if
+# there is no need for bug-tracking integration. Below are some example
+# URLs for Bugzilla and Flyspray.
+$bugtracker = '';
+#$bugtracker = 'http://localhost/show_bug.cgi?id=';
+#$bugtracker = '/flyspray_dev/?do=details&id=';
+
+# Some bug tracking systems store details of the files changed under each bug
+# ID. A generic plugin for bugzilla is scmbug which can be used to link
+# with source control systems such as subversion. The following flag enables/disables
+# the ability to a user to create a topic just using a Bug ID
+$bugdb_scmbug_link = 1;
+
+# LXR database. Each repository can be optionally mapped to a
+# different LXR deployment. If a repository has an associated LXR
+# mapping, then create a new entry where the repository string is the
+# key, and the value is another map, where "db" is the LXR database
+# URL, "user" is the database user, "password" is the data password,
+# and "url" is the base LXR URL for viewing where an identifier is
+# defined/used.
+$lxr_map =
+{
+# '/home/sits/cvs' => { db => 'DBI:Pg:dbname=lxr',
+# user => 'lxr',
+# password => '',
+# url => 'http://localhost.localdomain/lxr/ident?i='
+# },
+#
+# 'svn:http://svn.collab.net/repos/svn/trunk' =>
+# { db => 'DBI:Pg:dbname=lxr2',
+# user => 'lxr',
+# password => '',
+# url => 'http://localhost.localdomain/lxr2/ident?i='
+# }
+};
+
+# Character encoding to use when reading topic text. Default is utf8
+# (compatible with ASCII) if not set, but this can be over-ridden here.
+# List of example encoding names can be retrieved from the following
+# URL: http://perldoc.perl.org/Encode/Supported.html.
+#$topic_text_encoding = 'utf8';
+#$topic_text_encoding = 'gb2312';
+
+# Each comment thread (or issue) that is created against a specific
+# code line in Codestriker can have a configurable number of
+# user-defined metrics recorded against it.
+#
+# Every site has their own requirements, below are a number of example
+# configurations. The "name" attribute refers to the name of the
+# metric being recorded. The "values" attribute is a list of values
+# that this metric can be assigned to. The "default_value" attribute
+# is optional, and indicates what the default value of the metric is
+# assigned to. If this attribute is not specified, then the user will
+# be required to specify a value for a metric when creating a new
+# comment thread. This is recommended, so that users think about what
+# these values should be, rather than blindly accepting default
+# values. For the "Status" metric below however, it is recording the
+# "state" of the thread, so an initial state of "Submitted" is reasonable.
+# For the other metrics below, an initial value makes no sense.
+# Metric items can have an optional show_on_main_page list that will
+# force the numbers of comments with the metric settings to be reported
+# on the main page of codestriker.
+$comment_state_metrics =
+ [
+ { name => 'Status',
+ values => ['Submitted', 'Invalid', 'Completed'],
+ default_value => 'Submitted',
+ show_on_mainpage => ['Submitted' ]
+ }
+ ];
+
+# Two metrics defined: Status and Type.
+#$comment_state_metrics =
+# [
+# { name=>'Status', values=>['Submitted', 'Invalid', 'Completed'],
+# default_value=>'Submitted' },
+# { name=>'Type', values=>['Style', 'Minor', 'Major', 'Severe'] }
+# ];
+
+# Four metrics defined: Status, Level, Mode and Type.
+#$comment_state_metrics =
+# [
+# { name=>'Status', values=>['Submitted', 'Invalid', 'Completed'],
+# default_value=>'Submitted' },
+# { name=>'Level', values=>['Major', 'Minor'] },
+# { name=>'Mode', values=>['Missing', 'Wrong', 'Unclear', 'Suggestion'] },
+# { name=>'Type', values=>['Logic', 'Data Handling', 'Interface',
+# 'Error Handling', 'Performance', 'Comments',
+# 'Standards'] }
+# ];
+#
+# Case where no comment thread metrics are to be used.
+#$comment_state_metrics = [];
+
+
+# Allows you to override the default title of "Codestriker %version%".
+$title = "TIBCO BPM Code Review Tool $Codestriker::VERSION + Updates";
+
+# This options configures the metric support in codestriker. You have
+# the following options:
+#
+# $metric_config = "none", "basic", "all", "metric name, metric name, etc"
+#
+# "none" - turns off all extra metric support in the application. The
+# metric page will only display and manage data that is strictly
+# required to perform the review. Codestriker will not require any
+# addition data input from the reviewers and authors. This is the
+# default. However, you still get basic data like how many topics are
+# being created and how problems are being found.
+#
+# "basic" - Turns on the metrics that are considered to be essential
+# for a metric program. It will require that reviewers and authors
+# enter the time spent reviewing the topic, the time spent in the
+# review meeting, and the time spent preparing for the review. The
+# metric selection assumes that you are following a formal review
+# process with a preparation meeting, and a defect review meeting.
+#
+# kickoff time - time spent preparing for the review
+# checking time - time spent actually reviewing the topic.
+# logging meeting duration - the time spent in the logging meeting.
+#
+# "all" - Turns on all of the metrics that one could possibly want to
+# track. The list of metrics is from the book "Software Inspection" by
+# Gilb and Graham. You should probably not use this unless you are
+# using a formal process that is well established. You may want to
+# enable this temporally to get a idea of the types of metrics that
+# are supported.
+#
+# "name,name" - Lastly, you can pick and chose what metrics you would
+# like to enable. just list the metric names in a comma separated
+# list. You can see all of the build in metrics in the
+# lib/Codestriker.pm file. For example, if you don't hold a kick off
+# meeting, and but do hold a logging meeting, the basic option will not
+# quit fit. You should set the $metric_config as:
+# $metric_config = "checking time,logging meeting duration".
+#
+# If you don't like our choices of metrics, the names, descriptions,
+# etc feel free to edit the lib/Codestriker.pm. It contains
+# documentations on how to add your own metrics into codestriker. It
+# is easy to do, and does not require any coding.
+
+$metric_config = "none";
+
+
diff -uNPr codestriker-1.9.2/lib/Codestriker/Action/ListTopics.pm codestriker-1.9.2_TestDirector_scmbug/lib/Codestriker/Action/ListTopics.pm
--- codestriker-1.9.2/lib/Codestriker/Action/ListTopics.pm 2004-12-22 10:02:56.000000000 +0000
+++ codestriker-1.9.2_TestDirector_scmbug/lib/Codestriker/Action/ListTopics.pm 2006-12-21 09:53:42.000000000 +0000
@@ -147,9 +147,12 @@
# bug ids
my @accum_bugs = split /, /, $topic->{bug_ids};
for ( my $index = 0; $index < scalar(@accum_bugs); ++$index) {
- $accum_bugs[$index] =
- $query->a({href=>"$Codestriker::bugtracker$accum_bugs[$index]"},
- $accum_bugs[$index]);
+ # Allow for no direct web link to a bug
+ if( "$Codestriker::bugtracker" ne "" ) {
+ $accum_bugs[$index] =
+ $query->a({href=>"$Codestriker::bugtracker$accum_bugs[$index]"},
+ $accum_bugs[$index]);
+ }
}
$template_topic->{'bugids'} = join ', ', @accum_bugs;
diff -uNPr codestriker-1.9.2/lib/Codestriker/Action/SubmitNewTopic.pm codestriker-1.9.2_TestDirector_scmbug/lib/Codestriker/Action/SubmitNewTopic.pm
--- codestriker-1.9.2/lib/Codestriker/Action/SubmitNewTopic.pm 2006-06-09 18:17:04.000000000 +0100
+++ codestriker-1.9.2_TestDirector_scmbug/lib/Codestriker/Action/SubmitNewTopic.pm 2006-12-21 16:04:27.320187500 +0000
@@ -46,6 +46,8 @@
my $obsoletes = $http_input->get('obsoletes');
my $default_to_head = $http_input->get('default_to_head');
+ my $files_from_bugids = join("", $query->param('files_from_bugids') );
+
my $feedback = "";
my $topic_text = "";
@@ -63,6 +65,12 @@
"Can't create topic text usings tags.\n";
}
}
+ else
+ {
+ if( $files_from_bugids eq "yes" ) {
+ $retrieve_text_from_rep = 1;
+ }
+ }
if ($topic_title eq "") {
$feedback .= "No topic title was entered.\n";
@@ -73,6 +81,9 @@
if ($email eq "") {
$feedback .= "No email address was entered.\n";
}
+ if (($files_from_bugids eq "yes") && ($bug_ids eq "")) {
+ $feedback .= "No Bug IDs entered with generate from Bug IDs set.\n";
+ }
if (!defined $fh && $retrieve_text_from_rep == 0) {
$feedback .= "No filename or module/tags were entered.\n";
}
@@ -189,10 +200,19 @@
}
binmode $temp_topic_fh;
binmode $temp_error_fh;
-
- my $rc = $repository->getDiff($start_tag, $end_tag, $module,
+
+ my $rc;
+ if( $files_from_bugids eq "yes" )
+ {
+ $rc = $repository->getDiffFromBugId($bug_ids,
+ $temp_topic_fh, $temp_error_fh);
+ }
+ else
+ {
+ $rc = $repository->getDiff($start_tag, $end_tag, $module,
$temp_topic_fh, $temp_error_fh,
$default_to_head);
+ }
# Make sure the data has been flushed to disk.
$temp_topic_fh->flush;
diff -uNPr codestriker-1.9.2/lib/Codestriker/Action/SubmitNewTopic.pm.bak codestriker-1.9.2_TestDirector_scmbug/lib/Codestriker/Action/SubmitNewTopic.pm.bak
--- codestriker-1.9.2/lib/Codestriker/Action/SubmitNewTopic.pm.bak 1970-01-01 00:00:00.000000000 +0000
+++ codestriker-1.9.2_TestDirector_scmbug/lib/Codestriker/Action/SubmitNewTopic.pm.bak 2006-11-14 12:08:38.000000000 +0000
@@ -0,0 +1,393 @@
+###############################################################################
+# Codestriker: Copyright (c) 2001, 2002 David Sitsky. All rights reserved.
+# sits@users.sourceforge.net
+#
+# This program is free software; you can redistribute it and modify it under
+# the terms of the GPL.
+
+# Action object for handling the submission of a new topic.
+
+package Codestriker::Action::SubmitNewTopic;
+
+use strict;
+
+use File::Temp qw/ tempfile /;
+use FileHandle;
+
+use Codestriker::Model::Topic;
+use Codestriker::Http::Render;
+use Codestriker::Repository::RepositoryFactory;
+use Codestriker::FileParser::Parser;
+use Codestriker::Model::Project;
+use Codestriker::TopicListeners::Manager;
+
+# If the input is valid, create the appropriate topic into the database.
+sub process($$$) {
+ my ($type, $http_input, $http_response) = @_;
+
+ my $query = $http_response->get_query();
+
+ # Check that the appropriate fields have been filled in.
+ my $topic_title = $http_input->get('topic_title');
+ my $topic_description = $http_input->get('topic_description');
+ my $reviewers = $http_input->get('reviewers');
+ my $email = $http_input->get('email');
+ my $cc = $http_input->get('cc');
+ my $fh = $http_input->get('fh');
+ my $topic_file = $http_input->get('fh_filename');
+ my $fh_mime_type = $http_input->get('fh_mime_type');
+ my $bug_ids = $http_input->get('bug_ids');
+ my $repository_name = $http_input->get('repository');
+ my $projectid = $http_input->get('projectid');
+ my $project_name = $http_input->get('project_name');
+ my $start_tag = $http_input->get('start_tag');
+ my $end_tag = $http_input->get('end_tag');
+ my $module = $http_input->get('module');
+ my $obsoletes = $http_input->get('obsoletes');
+ my $default_to_head = $http_input->get('default_to_head');
+
+ my $files_from_bugids = join("", $query->param('files_from_bugids') );
+
+ my $feedback = "";
+ my $topic_text = "";
+
+ my $url_builder = Codestriker::Http::UrlBuilder->new($query);
+
+ # Indicate whether the topic text needs to be retrieved by the repository
+ # object.
+ my $retrieve_text_from_rep = 0;
+ if (($start_tag ne "" || $end_tag ne "") && $module ne "") {
+ $retrieve_text_from_rep = 1;
+
+ # Check if this action is permitted.
+ if (scalar(@Codestriker::valid_repositories) == 0) {
+ $feedback .= "Repository functionality has been disabled. " .
+ "Can't create topic text usings tags.\n";
+ }
+ }
+ else
+ {
+ if( $files_from_bugids eq "yes" ) {
+ $retrieve_text_from_rep = 1;
+ }
+ }
+
+ if ($topic_title eq "") {
+ $feedback .= "No topic title was entered.\n";
+ }
+ if ($topic_description eq "") {
+ $feedback .= "No topic description was entered.\n";
+ }
+ if ($email eq "") {
+ $feedback .= "No email address was entered.\n";
+ }
+ if (($files_from_bugids eq "yes") && ($bug_ids eq "")) {
+ $feedback .= "No Bug IDs entered with generate from Bug IDs set.\n";
+ }
+ if (!defined $fh && $retrieve_text_from_rep == 0) {
+ $feedback .= "No filename or module/tags were entered.\n";
+ }
+ if ($reviewers eq "") {
+ $feedback .= "No reviewers were entered.\n";
+ }
+ if ($retrieve_text_from_rep && defined $fh) {
+ $feedback .= "Topic text specified using tags and uploaded file.\n";
+ $feedback .= "Please choose one topic text method, and try again.\n";
+ }
+
+
+ $http_response->generate_header(topic_title=>"Create New Topic",
+ email=>$email, reviewers=>$reviewers,
+ cc=>$cc, repository=>$repository_name,
+ projectid=>$projectid,
+ reload=>0, cache=>0);
+
+ # Set the error_vars in case of any errors that will require forwarding
+ # to the create topic screen again.
+ my $error_vars = {};
+ $error_vars->{'version'} = $Codestriker::VERSION;
+ $error_vars->{'feedback'} = $feedback;
+ $error_vars->{'email'} = $email;
+ $error_vars->{'reviewers'} = $reviewers;
+ $error_vars->{'cc'} = $cc;
+ $error_vars->{'topic_file'} = $topic_file;
+ $error_vars->{'topic_description'} = $topic_description;
+ $error_vars->{'topic_title'} = $topic_title;
+ $error_vars->{'bug_ids'} = $bug_ids;
+ $error_vars->{'default_repository'} = $repository_name;
+ $error_vars->{'repositories'} = \@Codestriker::valid_repository_names;
+ $error_vars->{'start_tag'} = $start_tag;
+ $error_vars->{'end_tag'} = $end_tag;
+ $error_vars->{'module'} = $module;
+ $error_vars->{'obsoletes'} = $obsoletes;
+ $error_vars->{'default_to_head'} = $default_to_head;
+ $error_vars->{'default_projectid'} = $projectid;
+
+ my $repository = undef;
+ my $repository_url = undef;
+ if (scalar(@Codestriker::valid_repositories)) {
+ # Set the repository to the default if it is not entered.
+ if ($repository_name eq "" || scalar(@Codestriker::valid_repository_names) == 1) {
+ $repository_name = $Codestriker::valid_repository_names[0];
+ }
+
+ # Check if the repository argument is in fact a configured
+ # repository.
+ $repository_url = $Codestriker::repository_url_map->{$repository_name};
+
+ if (defined $repository_url) {
+ $repository =
+ Codestriker::Repository::RepositoryFactory->get($repository_url);
+ }
+
+ if (! defined $repository) {
+ $feedback .=
+ "The repository value set for \"$repository_name\" is invalid.\n" .
+ "Please correct this value in your codestriker.conf file, " .
+ "and try again.\n";
+ }
+ }
+
+ # Set the projectid to the first (default) if it is invalid.
+ my @projects = Codestriker::Model::Project->list();
+ my $found_project = 0;
+ foreach my $project (@projects) {
+ if ((defined $projectid && $project->{id} == $projectid) ||
+ (defined $project_name && $project->{name} eq $project_name)) {
+ $projectid = $project->{id};
+ $found_project = 1;
+ last;
+ }
+ }
+ if ($found_project == 0) {
+ $projectid = $projects[0]->{id};
+ }
+
+ # Make sure all the conditions from the topic listeners are satisified.
+ $feedback .= Codestriker::TopicListeners::Manager::topic_pre_create
+ ($email, $topic_title, $topic_description,
+ $bug_ids, $reviewers, $cc,
+ $repository_url, $projectid);
+
+ # If there is a problem with the input, redirect to the create screen
+ # with the message.
+ if ($feedback ne "") {
+ if (defined $fh) {
+ $feedback .=
+ "For security reasons, please re-enter the " .
+ "file name to upload, if required.\n";
+ }
+ _forward_create_topic($error_vars, $feedback, $url_builder);
+ $http_response->generate_footer();
+ return;
+ }
+
+ my $topicid = Codestriker::Model::Topic::create_new_topicid();
+
+ # If the topic text needs to be retrieved from the repository object,
+ # create a temporary file to store the topic text.
+ my $temp_topic_fh;
+ my $temp_error_fh;
+
+ if ($retrieve_text_from_rep && defined $repository) {
+ # Store the topic text into temporary files.
+ if (defined $Codestriker::tmpdir && $Codestriker::tmpdir ne "") {
+ $temp_topic_fh = tempfile(DIR => $Codestriker::tmpdir);
+ $temp_error_fh = tempfile(DIR => $Codestriker::tmpdir);
+ }
+ else {
+ $temp_topic_fh = tempfile();
+ $temp_error_fh = tempfile();
+ }
+ binmode $temp_topic_fh;
+ binmode $temp_error_fh;
+
+ my $rc;
+ if( $files_from_bugids eq "yes" )
+ {
+ $rc = $repository->getDiffFromBugId($bug_ids,
+ $temp_topic_fh, $temp_error_fh);
+ }
+ else
+ {
+ $rc = $repository->getDiff($start_tag, $end_tag, $module,
+ $temp_topic_fh, $temp_error_fh,
+ $default_to_head);
+ }
+
+ # Make sure the data has been flushed to disk.
+ $temp_topic_fh->flush;
+ $temp_error_fh->flush;
+
+ # Check if the generated diff was too big, and if so, throw an error
+ # message on the screen.
+ if ($rc == $Codestriker::DIFF_TOO_BIG) {
+ $feedback .= "Generated diff file is too big.\n";
+ } elsif ($rc == $Codestriker::UNSUPPORTED_OPERATION) {
+ $feedback .= "Repository \"" . $repository_name .
+ "\" does not support tag retrieval, you have to use the text file upload.\n";
+ } elsif ($rc != $Codestriker::OK) {
+ $feedback .= "Unexpected error $rc retrieving diff text.\n";
+ }
+
+ # Seek to the beginning of the temporary file so it can be parsed.
+ seek($temp_topic_fh, 0, 0);
+
+ # Set $fh to this file reference which contains the topic data.
+ $fh = $temp_topic_fh;
+ }
+
+ my @deltas = ();
+ if ($feedback eq "") {
+ # Try to parse the topic text into its diff chunks.
+ @deltas =
+ Codestriker::FileParser::Parser->parse($fh, "text/plain", $repository,
+ $topicid, $topic_file);
+ if ($#deltas == -1) {
+ # Nothing in the file, report an error.
+ $feedback .= "Reviewable text in topic is empty.\n";
+ }
+ }
+
+ if ($feedback ne "") {
+ # If there was a problem generating the diff file, remove the
+ # temporary files, and direct control to the create screen again.
+ $temp_topic_fh->close if defined $temp_topic_fh;
+ $temp_error_fh->close if defined $temp_error_fh;
+ _forward_create_topic($error_vars, $feedback, $url_builder);
+ $http_response->generate_footer();
+ return;
+ }
+
+ # If the topic text has been uploaded from a file, read from it now.
+ if (defined $fh) {
+ while (<$fh>) {
+ $topic_text .= Codestriker::decode_topic_text($_);
+ }
+ if ($topic_text eq "") {
+ if (defined $temp_error_fh) {
+ seek($temp_error_fh, 0, 0);
+ $feedback .= "Problem generating topic text:\n\n";
+ my $buf = "";
+ while (read $temp_error_fh, $buf, 16384) {
+ $feedback .= $buf;
+ }
+ }
+ else {
+ $feedback = "Uploaded file doesn't exist or is empty.\n";
+ }
+
+ # Remove the temporary files if required, and forward control
+ # back to the create topic page.
+ $temp_topic_fh->close if defined $temp_topic_fh;
+ $temp_error_fh->close if defined $temp_error_fh;
+ _forward_create_topic($error_vars, $feedback, $url_builder);
+ $http_response->generate_footer();
+ return;
+ }
+ }
+
+ # Remove the temporary files if required.
+ $temp_topic_fh->close if defined $temp_topic_fh;
+ $temp_error_fh->close if defined $temp_error_fh;
+
+ # Remove \r from the topic text.
+ $topic_text =~ s/\r//g;
+
+ # Make sure the topic is not too large, count the number of \n
+ # in the topic content text.
+ my $new_topic_length = 0;
+ ++$new_topic_length while ($topic_text =~ /\n/g);
+
+ if (defined($Codestriker::maximum_topic_size_lines) &&
+ $Codestriker::maximum_topic_size_lines ne "" &&
+ $Codestriker::maximum_topic_size_lines < $new_topic_length)
+ {
+ $feedback .=
+ "The topic length of $new_topic_length lines is too long. " .
+ "Topics cannot exceed $Codestriker::maximum_topic_size_lines " .
+ "lines long. Please remove content from topic, or break the " .
+ "topic into several independent topics.\n";
+
+ _forward_create_topic($error_vars, $feedback, $url_builder);
+ $http_response->generate_footer();
+ return;
+ }
+
+ # Make sure the specified topicids to be obsoleted are in fact valid.
+ if (defined $obsoletes && $obsoletes ne '') {
+ my @data = split ',', $obsoletes;
+ for (my $i = 0; $i <= $#data; $i+=2) {
+ my $id = $data[$i];
+ my $version = $data[$i+1];
+
+ if (! Codestriker::Model::Topic::exists($id)) {
+ $feedback .= "Obsoleted topics specified do not exist.\n";
+ _forward_create_topic($error_vars, $feedback, $url_builder);
+ $http_response->generate_footer();
+ return;
+ }
+ }
+ }
+
+ # Create the topic in the model.
+ my $topic = Codestriker::Model::Topic->new($topicid);
+ $topic->create($topicid, $email, $topic_title,
+ $bug_ids, $reviewers, $cc,
+ $topic_description, $topic_text,
+ $start_tag, $end_tag, $module,
+ $repository_url, $projectid,
+ \@deltas, $obsoletes);
+
+ # Obsolete any required topics.
+ if (defined $obsoletes && $obsoletes ne '') {
+ my @data = split ',', $obsoletes;
+ for (my $i = 0; $i <= $#data; $i+=2) {
+ my $id = $data[$i];
+ my $version = $data[$i+1];
+ Codestriker::Action::SubmitEditTopicsState
+ ->update_state($id, $version, 'Obsoleted', $email);
+ }
+ }
+
+ # Tell all of the topic listener classes that a topic has
+ # just been created.
+ $feedback = Codestriker::TopicListeners::Manager::topic_create($topic);
+
+ # Obtain a URL builder object and determine the URL to the topic.
+ my $topic_url = $url_builder->view_url_extended($topicid, -1, "", "", "",
+ $query->url(), 0);
+
+ # Indicate to the user that the topic has been created and an email has
+ # been sent.
+ my $vars = {};
+ $vars->{'topic_title'} = $topic->{title};
+ $vars->{'email'} = $email;
+ $vars->{'topic_url'} = $topic_url;
+ $vars->{'reviewers'} = $reviewers;
+ $vars->{'cc'} = (defined $cc) ? $cc : "";
+ $vars->{'feedback'} = $feedback;
+
+ my $template = Codestriker::Http::Template->new("submitnewtopic");
+ $template->process($vars);
+
+ $http_response->generate_footer();
+}
+
+# Direct output to the create topic screen again, with the appropriate feedback
+# message.
+sub _forward_create_topic($$$) {
+ my ($vars, $feedback, $url_builder) = @_;
+
+ $feedback =~ s/\n/
/g;
+ $vars->{'feedback'} = $feedback;
+ my @projects = Codestriker::Model::Project->list();
+ $vars->{'projects'} = \@projects;
+ Codestriker::Action::CreateTopic->
+ set_obsoleted_topics_parameter($vars, $url_builder);
+
+ my $template = Codestriker::Http::Template->new("createtopic");
+ $template->process($vars);
+}
+
+1;
diff -uNPr codestriker-1.9.2/lib/Codestriker/Action/ViewTopicProperties.pm.bak codestriker-1.9.2_TestDirector_scmbug/lib/Codestriker/Action/ViewTopicProperties.pm.bak
--- codestriker-1.9.2/lib/Codestriker/Action/ViewTopicProperties.pm.bak 1970-01-01 00:00:00.000000000 +0000
+++ codestriker-1.9.2_TestDirector_scmbug/lib/Codestriker/Action/ViewTopicProperties.pm.bak 2006-12-21 10:03:58.000000000 +0000
@@ -0,0 +1,138 @@
+###############################################################################
+# Codestriker: Copyright (c) 2001, 2002 David Sitsky. All rights reserved.
+# sits@users.sourceforge.net
+#
+# This program is free software; you can redistribute it and modify it under
+# the terms of the GPL.
+
+# Action object for handling the viewing of a topic's properties.
+
+package Codestriker::Action::ViewTopicProperties;
+
+use strict;
+
+use Codestriker::Model::Topic;
+use Codestriker::Model::Comment;
+use Codestriker::Http::UrlBuilder;
+use Codestriker::Http::Render;
+use Codestriker::Repository::RepositoryFactory;
+use HTML::Entities ();
+
+# If the input is valid, display the topic.
+sub process($$$) {
+ my ($type, $http_input, $http_response) = @_;
+
+ my $query = $http_response->get_query();
+ my $topicid = $http_input->get('topic');
+ my $mode = $http_input->get('mode');
+ my $tabwidth = $http_input->get('tabwidth');
+ my $email = $http_input->get('email');
+ my $feedback = $http_input->get('feedback');
+
+ if (Codestriker::Model::Topic::exists($topicid) == 0) {
+ # Topic no longer exists, most likely its been deleted.
+ $http_response->error("Topic no longer exists.");
+ }
+
+ # Retrieve the appropriate topic details.
+ my $topic = Codestriker::Model::Topic->new($topicid);
+
+ # Retrieve the comment details for this topic.
+ my @topic_comments = $topic->read_comments();
+
+ $http_response->generate_header(topic=>$topic,
+ topic_title=>"Topic Properties: $topic->{title}",
+ mode=>$mode, tabwidth=>$tabwidth,
+ reload=>0, cache=>1);
+
+ # Retrieve the repository object, if repository functionality is enabled.
+ my $repository;
+ if (scalar(@Codestriker::valid_repositories)) {
+ $repository =
+ Codestriker::Repository::RepositoryFactory->get($topic->{repository});
+ } else {
+ # Indicate not to activate any repository-related links.
+ $topic->{repository} = "";
+ }
+
+ # Create the hash for the template variables.
+ my $vars = {};
+ $vars->{'feedback'} = $feedback;
+
+ # Obtain a new URL builder object.
+ my $url_builder = Codestriker::Http::UrlBuilder->new($query);
+
+ Codestriker::Action::ViewTopic::ProcessTopicHeader($vars, $topic,
+ $url_builder);
+
+ my @projectids = ($topic->{project_id});
+
+ $vars->{'view_topic_url'} =
+ $url_builder->view_url($topicid, -1, $mode);
+
+ $vars->{'view_topicinfo_url'} = $url_builder->view_topicinfo_url($topicid);
+ $vars->{'view_comments_url'} = $url_builder->view_comments_url($topicid);
+ $vars->{'list_projects_url'} = $url_builder->list_projects_url();
+
+ # Display the "update" message if the topic state has been changed.
+ $vars->{'updated'} = $http_input->get('updated');
+ $vars->{'rc_ok'} = $Codestriker::OK;
+ $vars->{'rc_stale_version'} = $Codestriker::STALE_VERSION;
+ $vars->{'rc_invalid_topic'} = $Codestriker::INVALID_TOPIC;
+
+ # Store the bug id information, and any linking URLs.
+ $vars->{'bug_db'} = $Codestriker::bug_db;
+ $vars->{'bug_ids'} = $topic->{bug_ids};
+ if (defined $topic->{bug_ids} && $topic->{bug_ids} ne "" &&
+ defined $Codestriker::bugtracker ) {
+ my @bug_id_array = split ',', $topic->{bug_ids};
+ $vars->{'bug_id_array'} = \@bug_id_array;
+ $vars->{'bugtracker'} = $Codestriker::bugtracker;
+ }
+
+ $vars->{'document_reviewers'} =
+ Codestriker->filter_email($topic->{reviewers});
+
+ # Indicate what repositories are available, and what the topic's
+ # repository is.
+ $vars->{'topic_repository'} = $Codestriker::repository_name_map->{$topic->{repository}};
+ $vars->{'repositories'} = \@Codestriker::valid_repository_names;
+
+ # Indicate what projects are available, and what the topic's project is.
+ my @projects = Codestriker::Model::Project->list();
+ $vars->{'projects'} = \@projects;
+ $vars->{'project_states'} = \@Codestriker::project_states;
+ $vars->{'projects_enabled'} = Codestriker->projects_disabled() ? 0 : 1;
+ $vars->{'topic_projectid'} = $topic->{project_id};
+
+ $vars->{'number_of_lines'} = $topic->get_topic_size_in_lines();
+
+ $vars->{'suggested_topic_size_lines'} =
+ $Codestriker::suggested_topic_size_lines eq "" ? 0 :
+ $Codestriker::suggested_topic_size_lines;
+
+ # Prepare the data for displaying the state update option.
+ # Make sure the old mode setting is no longer used.
+ if ((! defined $mode) || $mode == $Codestriker::NORMAL_MODE) {
+ $mode = $Codestriker::COLOURED_MODE;
+ }
+ $vars->{'mode'} = $mode;
+ $vars->{'topicid'} = $topic->{topicid};
+ $vars->{'topic_version'} = $topic->{version};
+ $vars->{'states'} = \@Codestriker::topic_states;
+ $vars->{'default_state'} = $topic->{topic_state};
+ $vars->{'description'} = $topic->{description};
+ $vars->{'start_tag'} = $topic->{start_tag};
+ $vars->{'end_tag'} = $topic->{end_tag};
+ $vars->{'module'} = $topic->{module};
+
+ my $template = Codestriker::Http::Template->new("viewtopicproperties");
+ $template->process($vars);
+
+ $http_response->generate_footer();
+
+ # Fire the topic listener to indicate that the user has viewed the topic.
+ Codestriker::TopicListeners::Manager::topic_viewed($email, $topic);
+}
+
+1;
diff -uNPr codestriker-1.9.2/lib/Codestriker/BugDB/BugDBConnectionFactory.pm codestriker-1.9.2_TestDirector_scmbug/lib/Codestriker/BugDB/BugDBConnectionFactory.pm
--- codestriker-1.9.2/lib/Codestriker/BugDB/BugDBConnectionFactory.pm 2005-05-22 21:46:32.000000000 +0100
+++ codestriker-1.9.2_TestDirector_scmbug/lib/Codestriker/BugDB/BugDBConnectionFactory.pm 2006-12-20 14:50:50.000000000 +0000
@@ -12,6 +12,7 @@
use strict;
use Codestriker::BugDB::BugzillaConnection;
use Codestriker::BugDB::FlysprayConnection;
+use Codestriker::BugDB::TestDirectorConnection;
# Factory method for retrieving a BugDBConnection object.
sub getBugDBConnection ($) {
@@ -22,6 +23,8 @@
return Codestriker::BugDB::BugzillaConnection->get_connection();
} elsif ($dbtype eq "flyspray") {
return Codestriker::BugDB::FlysprayConnection->get_connection();
+ } elsif ($dbtype eq "testdirector") {
+ return Codestriker::BugDB::TestDirectorConnection->get_connection();
} else {
die "Unsupported bug database type: $dbtype";
}
diff -uNPr codestriker-1.9.2/lib/Codestriker/BugDB/BugzillaConnection.pm codestriker-1.9.2_TestDirector_scmbug/lib/Codestriker/BugDB/BugzillaConnection.pm
--- codestriker-1.9.2/lib/Codestriker/BugDB/BugzillaConnection.pm 2006-01-17 08:22:58.000000000 +0000
+++ codestriker-1.9.2_TestDirector_scmbug/lib/Codestriker/BugDB/BugzillaConnection.pm 2006-12-21 16:05:31.585812500 +0000
@@ -11,6 +11,7 @@
use strict;
use DBI;
+use Codestriker::BugDB::ScmBugUtils;
# Static method for building a database connection.
sub get_connection($) {
@@ -60,6 +61,81 @@
# Execute the statements.
$insert_comment->execute($bugid, $Codestriker::bug_db_user_id, $comment);
$update_bug->execute($bugid);
+
+}
+
+
+# Method for getting the list of files changed when flagged on a fault
+# this reads the format left by bugscm
+sub get_bug_file_list($$$) {
+ my ($self, $bugids) = @_;
+
+ my @MasterAffectedFileList;
+
+ my @ids = split( ",", $bugids);
+
+ for( my $k = 0; $k <= $#ids; $k++) {
+ # Create the necessary prepared statements.
+ my $select_comments =
+ $self->{dbh}->prepare_cached('SELECT thetext FROM longdescs ' .
+ 'WHERE bug_id = ?');
+
+ # Execute the statements.
+ $select_comments->execute($ids[$k]);
+
+ # Now get the comments one at a time
+ my $aComment;
+ my $comment_set_counter = 1;
+
+ while( ($aComment) = $select_comments->fetchrow_array() ) {
+
+ my ($is_an_integration_comment,
+ @affected_files_list) = Codestriker::BugDB::ScmBugUtils->extract_affected_files( $aComment, $ids[$k], $comment_set_counter );
+
+ if ($is_an_integration_comment != 1) {
+ next;
+ }
+
+ for( my $i = 0; $i <= $#affected_files_list; $i++ ) {
+ my $filename = $affected_files_list[$i]->{ file };
+ my $new_ver = $affected_files_list[$i]->{ new_version };
+ my $old_ver = $affected_files_list[$i]->{ old_version };
+
+ my $valueFoundAt = -1;
+
+ for( my $j = 0; $j <= $#MasterAffectedFileList; $j++ ) {
+ if( "$MasterAffectedFileList[$j]->{ file }" eq "$filename" ) {
+ $valueFoundAt = $j;
+ last;
+ }
+ }
+
+ if( $valueFoundAt == -1 ) {
+ push( @MasterAffectedFileList, $affected_files_list[$i] );
+ }
+ else {
+ if( $MasterAffectedFileList[$valueFoundAt]->{ old_version } > $old_ver ) {
+ $MasterAffectedFileList[$valueFoundAt]->{ old_version } = $old_ver;
+ }
+ if( $new_ver eq "0" ) {
+ $MasterAffectedFileList[$valueFoundAt]->{ new_version } = 0;
+ }
+ else {
+ if( $MasterAffectedFileList[$valueFoundAt]->{ new_version } ne "0" ) {
+ if( $MasterAffectedFileList[$valueFoundAt]->{ new_version } < $new_ver ) {
+ $MasterAffectedFileList[$valueFoundAt]->{ new_version } = $new_ver;
+ }
+ }
+ }
+ }
+ }
+
+ $comment_set_counter++;
+ }
+ $select_comments->finish();
+ }
+
+ return @MasterAffectedFileList;
}
1;
diff -uNPr codestriker-1.9.2/lib/Codestriker/BugDB/BugzillaConnection.pm.bak codestriker-1.9.2_TestDirector_scmbug/lib/Codestriker/BugDB/BugzillaConnection.pm.bak
--- codestriker-1.9.2/lib/Codestriker/BugDB/BugzillaConnection.pm.bak 1970-01-01 00:00:00.000000000 +0000
+++ codestriker-1.9.2_TestDirector_scmbug/lib/Codestriker/BugDB/BugzillaConnection.pm.bak 2006-12-21 15:54:36.000000000 +0000
@@ -0,0 +1,142 @@
+###############################################################################
+# Codestriker: Copyright (c) 2001, 2002 David Sitsky. All rights reserved.
+# sits@users.sourceforge.net
+#
+# This program is free software; you can redistribute it and modify it under
+# the terms of the GPL.
+
+# Bugzilla connection class, for appending comments to a bug report.
+
+package Codestriker::BugDB::BugzillaConnection;
+
+use strict;
+use DBI;
+use Codestriker::BugDB::ScmBugUtils;
+
+# Static method for building a database connection.
+sub get_connection($) {
+ my ($type) = @_;
+
+ # Return a connection with the bugzilla database.
+ my $self = {};
+ my $dbname = $Codestriker::bug_db_dbname;
+ $dbname = "bugs" if ($dbname eq "");
+ $self->{dbh} =
+ DBI->connect("DBI:mysql:dbname=$dbname;host=$Codestriker::bug_db_host",
+ $Codestriker::bug_db_name, $Codestriker::bug_db_password,
+ { RaiseError => 1, AutoCommit => 1 });
+ bless $self, $type;
+}
+
+# Method for releasing a bugzilla database connection.
+sub release_connection($) {
+ my ($self) = @_;
+
+ $self->{dbh}->disconnect;
+}
+
+# Return true if the specified bugid exists in the bug database,
+# false otherwise.
+sub bugid_exists($$) {
+ my ($self, $bugid) = @_;
+
+ return $self->{dbh}->selectrow_array('SELECT COUNT(*) FROM bugs ' .
+ 'WHERE bug_id = ?', {}, $bugid) != 0;
+}
+
+# Method for updating the bug with information that a code review has been
+# created/closed/committed against this bug.
+sub update_bug($$$$) {
+ my ($self, $bugid, $comment) = @_;
+
+ # Create the necessary prepared statements.
+ my $insert_comment =
+ $self->{dbh}->prepare_cached('INSERT INTO longdescs ' .
+ '(bug_id, who, bug_when, thetext) ' .
+ 'VALUES (?, ?, now(), ?)');
+ my $update_bug =
+ $self->{dbh}->prepare_cached('UPDATE bugs SET delta_ts = now() ' .
+ 'WHERE bug_id = ?');
+
+ # Execute the statements.
+ $insert_comment->execute($bugid, $Codestriker::bug_db_user_id, $comment);
+ $update_bug->execute($bugid);
+
+}
+
+
+# Method for getting the list of files changed when flagged on a fault
+# this reads the format left by bugscm
+sub get_bug_file_list($$$) {
+ my ($self, $bugids) = @_;
+
+ my @MasterAffectedFileList;
+
+ my @ids = split( ",", $bugids);
+
+ for( my $k = 0; $k <= $#ids; $k++) {
+ # Create the necessary prepared statements.
+ my $select_comments =
+ $self->{dbh}->prepare_cached('SELECT thetext FROM longdescs ' .
+ 'WHERE bug_id = ?');
+
+ # Execute the statements.
+ $select_comments->execute($ids[$k]);
+
+ # Now get the comments one at a time
+ my $aComment;
+ my $comment_set_counter = 1;
+
+ while( ($aComment) = $select_comments->fetchrow_array() ) {
+
+ my ($is_an_integration_comment,
+ @affected_files_list) = Codestriker::BugDB::ScmBugUtils->extract_affected_files( $aComment, $ids[$k], $comment_set_counter );
+
+ if ($is_an_integration_comment != 1) {
+ next;
+ }
+
+ for( my $i = 0; $i <= $#affected_files_list; $i++ ) {
+ my $filename = $affected_files_list[$i]->{ file };
+ my $new_ver = $affected_files_list[$i]->{ new_version };
+ my $old_ver = $affected_files_list[$i]->{ old_version };
+
+ my $valueFoundAt = -1;
+
+ for( my $j = 0; $j <= $#MasterAffectedFileList; $j++ ) {
+ if( "$MasterAffectedFileList[$j]->{ file }" eq "$filename" ) {
+ $valueFoundAt = $j;
+ last;
+ }
+ }
+
+ if( $valueFoundAt == -1 ) {
+ push( @MasterAffectedFileList, $affected_files_list[$i] );
+ }
+ else {
+ if( $MasterAffectedFileList[$valueFoundAt]->{ old_version } > $old_ver ) {
+ $MasterAffectedFileList[$valueFoundAt]->{ old_version } = $old_ver;
+ }
+ if( $new_ver eq "0" ) {
+ $MasterAffectedFileList[$valueFoundAt]->{ new_version } = 0;
+ }
+ else {
+ if( $MasterAffectedFileList[$valueFoundAt]->{ new_version } ne "0" ) {
+ if( $MasterAffectedFileList[$valueFoundAt]->{ new_version } < $new_ver ) {
+ $MasterAffectedFileList[$valueFoundAt]->{ new_version } = $new_ver;
+ }
+ }
+ }
+ }
+ }
+
+ $comment_set_counter++;
+ }
+ $select_comments->finish();
+ }
+
+ return @MasterAffectedFileList;
+}
+
+
+1;
diff -uNPr codestriker-1.9.2/lib/Codestriker/BugDB/FlysprayConnection.pm codestriker-1.9.2_TestDirector_scmbug/lib/Codestriker/BugDB/FlysprayConnection.pm
--- codestriker-1.9.2/lib/Codestriker/BugDB/FlysprayConnection.pm 2006-01-23 09:47:14.000000000 +0000
+++ codestriker-1.9.2_TestDirector_scmbug/lib/Codestriker/BugDB/FlysprayConnection.pm 2006-11-14 14:04:00.000000000 +0000
@@ -66,4 +66,15 @@
$insert_history->execute($bugid, $Codestriker::bug_db_user_id, time()) or die $insert_history->errstr;
}
+# Method for getting the list of files changed when flagged on a fault
+# this reads the format left by bugscm
+# This has not currently been implemented for Flyspray
+sub get_bug_file_list($$$) {
+ my ($self, $bugids) = @_;
+
+ my @changeFileList;
+
+ return @changeFileList;
+}
+
1;
diff -uNPr codestriker-1.9.2/lib/Codestriker/BugDB/ScmBugUtils.pm codestriker-1.9.2_TestDirector_scmbug/lib/Codestriker/BugDB/ScmBugUtils.pm
--- codestriker-1.9.2/lib/Codestriker/BugDB/ScmBugUtils.pm 1970-01-01 00:00:00.000000000 +0000
+++ codestriker-1.9.2_TestDirector_scmbug/lib/Codestriker/BugDB/ScmBugUtils.pm 2006-12-21 15:53:54.000000000 +0000
@@ -0,0 +1,122 @@
+###############################################################################
+# Codestriker: Copyright (c) 2001, 2002 David Sitsky. All rights reserved.
+# sits@users.sourceforge.net
+#
+# This program is free software; you can redistribute it and modify it under
+# the terms of the GPL.
+
+# Utilities to parse SCM Bug Output
+
+package Codestriker::BugDB::ScmBugUtils;
+
+use strict;
+
+
+my $PRODUCT_BRANCH_NAME_TOKEN = "Branch:";
+my $PRODUCT_AFFECTED_FILES_TOKEN = "Affected files:\n---------------\n";
+my $PRODUCT_AFFECTED_FILES_PRODUCT_FILE_TOKEN = ":";
+
+# Token used to indicate transition from older to newer version of a
+# file
+my $OLD_VERSION_TO_NEW_VERSION_TOKEN = " --> ";
+
+# Token used to separate between the new version and the filename
+my $NEW_VERSION_TO_FILENAME_TOKEN = " ";
+
+
+sub extract_affected_files {
+ my $self = shift;
+ my ($comment, $bug_id, $comment_id) = ( @_ );
+ my $is_an_integration_comment = 0;
+
+ my @affected_file_list;
+
+ if ( $comment =~ m/$PRODUCT_AFFECTED_FILES_TOKEN/s ) {
+ my $changeset_list = $comment;
+ $changeset_list =~ s/(.*)$PRODUCT_AFFECTED_FILES_TOKEN//s;
+ my $comment_and_branch = $1;
+
+ if ($comment_and_branch =~ m/(.*)$PRODUCT_BRANCH_NAME_TOKEN/s ) {
+ my $comment_only = $1;
+
+ # Remove a newline from the comment, since one was added
+ # when the comment was created by us.
+ $comment_only =~ s/\n$//s;
+
+ my ( @changeset_line_groups ) = split( "\n", $changeset_list );
+ foreach my $changeset_line ( @changeset_line_groups ) {
+ if ( $changeset_line =~ m/(.*)?$OLD_VERSION_TO_NEW_VERSION_TOKEN(.*)?$NEW_VERSION_TO_FILENAME_TOKEN(.*)?$PRODUCT_AFFECTED_FILES_PRODUCT_FILE_TOKEN(.*)/ ) {
+ my $affected_files_description;
+
+ $affected_files_description->{ file } = $4;
+ $affected_files_description->{ product_name } = $3;
+ $affected_files_description->{ new_version } = $2;
+ $affected_files_description->{ old_version } = $1;
+
+ # Set the old version for new files to 0
+ if( "$affected_files_description->{ old_version }" eq "NONE" ) {
+ $affected_files_description->{ old_version } = 0;
+ }
+ if( "$affected_files_description->{ new_version }" eq "NONE" ) {
+ $affected_files_description->{ new_version } = 0;
+ }
+
+ push @affected_file_list, $affected_files_description;
+ }
+ }
+ $is_an_integration_comment = 1;
+ }
+ }
+
+ return $is_an_integration_comment, @affected_file_list;
+}
+
+
+
+#
+# Takes a set of comments all combined into one long string and
+# seperates them out to individual commit sections
+#
+sub split_comment_sections {
+ my $self = shift;
+ my ($comments) = ( @_ );
+
+ # Store the tag used to tell where the changed files are
+ my @affected_files_tags = split( "\n", $PRODUCT_AFFECTED_FILES_TOKEN );
+
+ my @comment_lines = split( "\n", $comments );
+ my $number_of_comment_lines = scalar @comment_lines;
+ my $comment_lines_counter = 0;
+ my @comment_sets;
+ my $current_comment = "";
+ my $comment_progress = 0;
+
+ while ( $comment_lines_counter <= $number_of_comment_lines ) {
+
+ # Add this line to the current comment (Putting the newline
+ # again)
+ $current_comment .= $comment_lines[ $comment_lines_counter ];
+ $current_comment .= "\n";
+
+ # Flag if an affected files section was found
+ if ( ( $comment_lines[ $comment_lines_counter] eq $affected_files_tags[0] ) &&
+ ( $comment_lines[ ($comment_lines_counter + 1 ) ] eq $affected_files_tags[1] ) ) {
+ $comment_progress = 1;
+ }
+
+ # Check if the end off a section has been found and add it
+ # to the list
+ if ( ( ( $comment_lines[ $comment_lines_counter ] eq "") || ($comment_lines_counter == $number_of_comment_lines) ) &&
+ ( $comment_progress == 1 ) ) {
+ push( @comment_sets, $current_comment );
+ $comment_progress = 0;
+ $current_comment = "";
+ }
+ $comment_lines_counter++;
+ }
+
+ return @comment_sets;
+}
+
+
+1;
diff -uNPr codestriker-1.9.2/lib/Codestriker/BugDB/TestDirectorConnection.pm codestriker-1.9.2_TestDirector_scmbug/lib/Codestriker/BugDB/TestDirectorConnection.pm
--- codestriker-1.9.2/lib/Codestriker/BugDB/TestDirectorConnection.pm 1970-01-01 00:00:00.000000000 +0000
+++ codestriker-1.9.2_TestDirector_scmbug/lib/Codestriker/BugDB/TestDirectorConnection.pm 2006-12-21 15:54:02.000000000 +0000
@@ -0,0 +1,193 @@
+###############################################################################
+# Codestriker: Copyright (c) 2001, 2002 David Sitsky. All rights reserved.
+# sits@users.sourceforge.net
+#
+# This program is free software; you can redistribute it and modify it under
+# the terms of the GPL.
+
+# TestDirector connection class, for appending comments to a bug report.
+
+package Codestriker::BugDB::TestDirectorConnection;
+
+use strict;
+
+use Win32::OLE;
+use Codestriker::BugDB::ScmBugUtils;
+
+
+
+# Static method for building a database connection.
+sub get_connection($) {
+ my ($type) = @_;
+ my $self = {};
+
+
+ # Return a connection with Test Director
+
+ # Connect to the TD Object
+ my $Conn = Win32::OLE->new('TDapiole80.TDconnection');
+
+ if( !$Conn ) {
+ my $errorstr = "Cannot start TestDirector object";
+ return 0;
+ }
+
+ # Connect to server
+ $Conn->InitConnectionEx($Codestriker::testdirector_url);
+
+ # Connect to project
+ $Conn->Login($Codestriker::testdirector_user_id, $Codestriker::testdirector_password);
+ $Conn->Connect($Codestriker::testdirector_domain, $Codestriker::testdirector_project);
+
+ $self->{dbh} = $Conn;
+
+ bless $self, $type;
+}
+
+# Method for releasing a Test Director connection.
+sub release_connection($) {
+ my ($self) = @_;
+
+ # Close the TD connection
+ # Disconnect the project and release the server
+ $self->{dbh}->Disconnect();
+ $self->{dbh}->Logout();
+ $self->{dbh}->ReleaseConnection();
+}
+
+# Return true if the specified bugid exists in the bug database,
+# false otherwise.
+sub bugid_exists($$) {
+ my ($self, $bugid) = @_;
+
+
+ my $bgf = $self->{dbh}->bugfactory;
+ my $bug;
+
+
+ if( $bgf ) {
+ $bug = $bgf->item($bugid);
+ }
+
+ if( $bug ) {
+ return 1;
+ }
+
+ return 0;
+}
+
+# Method for updating the bug with information that a code review has been
+# created/closed/committed against this bug.
+sub update_bug($$$$) {
+ my ($self, $bugid, $comment) = @_;
+
+ # Now get the bug out of Test Director
+ my $bgf = $self->{dbh}->bugfactory;
+
+ if( ! $bgf ) {
+ return;
+ }
+
+ my $bug = $bgf->item($bugid);
+
+ # Test director stores comments as html so do some conversion
+ my $parsed_comment = $comment;
+ $parsed_comment =~ s/\n/
/g;
+
+ $$bug{"BG_DEV_COMMENTS"} .= "\n
";
+ $$bug{"BG_DEV_COMMENTS"} .= "";
+ $$bug{"BG_DEV_COMMENTS"} .= "________________________________________
";
+ $$bug{"BG_DEV_COMMENTS"} .= "Code Review, ";
+ $$bug{"BG_DEV_COMMENTS"} .= localtime;
+ $$bug{"BG_DEV_COMMENTS"} .= ":
";
+
+ $$bug{"BG_DEV_COMMENTS"} .= $parsed_comment;
+
+ #Post the bug
+ $bug->post();
+}
+
+
+# Method for getting the list of files changed when flagged on a fault
+# this reads the format left by bugscm
+sub get_bug_file_list($$$) {
+ my ($self, $bugids) = @_;
+
+ my @MasterAffectedFileList;
+
+
+ my @ids = split( ",", $bugids);
+
+ for( my $k = 0; $k <= $#ids; $k++) {
+
+ # get the comments from test director
+ my $bgf = $self->{dbh}->bugfactory;
+
+ if( ! $bgf ) {
+ next;
+ }
+
+ my $bug = $bgf->item($ids[$k]);
+ my $bug_file_comments = $$bug{$Codestriker::testdirector_file_list};
+
+ my @comment_sets = Codestriker::BugDB::ScmBugUtils->split_comment_sections($bug_file_comments);
+ my $number_of_comment_sets = scalar @comment_sets;
+ my $comment_set_counter = 0;
+
+
+ # Now get the comments one at a time
+ while ( $comment_set_counter < $number_of_comment_sets ) {
+ my $aComment = $comment_sets[ $comment_set_counter ];
+
+ my ($is_an_integration_comment,
+ @affected_files_list) = Codestriker::BugDB::ScmBugUtils->extract_affected_files( $comment_sets[ $comment_set_counter ], $ids[$k], ($comment_set_counter + 1) );
+
+ if ($is_an_integration_comment != 1) {
+ next;
+ }
+
+ for( my $i = 0; $i <= $#affected_files_list; $i++ ) {
+ my $filename = $affected_files_list[$i]->{ file };
+ my $new_ver = $affected_files_list[$i]->{ new_version };
+ my $old_ver = $affected_files_list[$i]->{ old_version };
+
+ my $valueFoundAt = -1;
+
+ for( my $j = 0; $j <= $#MasterAffectedFileList; $j++ ) {
+ if( "$MasterAffectedFileList[$j]->{ file }" eq "$filename" ) {
+ $valueFoundAt = $j;
+ last;
+ }
+ }
+
+
+ if( $valueFoundAt == -1 ) {
+ push( @MasterAffectedFileList, $affected_files_list[$i] );
+ }
+ else {
+ if( $MasterAffectedFileList[$valueFoundAt]->{ old_version } > $old_ver ) {
+ $MasterAffectedFileList[$valueFoundAt]->{ old_version } = $old_ver;
+ }
+ if( $new_ver eq "0" ) {
+ $MasterAffectedFileList[$valueFoundAt]->{ new_version } = 0;
+ }
+ else {
+ if( $MasterAffectedFileList[$valueFoundAt]->{ new_version } ne "0" ) {
+ if( $MasterAffectedFileList[$valueFoundAt]->{ new_version } < $new_ver ) {
+ $MasterAffectedFileList[$valueFoundAt]->{ new_version } = $new_ver;
+ }
+ }
+ }
+ }
+ }
+
+ $comment_set_counter++;
+ }
+ }
+
+ return @MasterAffectedFileList;
+
+}
+
+
+1;
diff -uNPr codestriker-1.9.2/lib/Codestriker/Http/Template.pm codestriker-1.9.2_TestDirector_scmbug/lib/Codestriker/Http/Template.pm
--- codestriker-1.9.2/lib/Codestriker/Http/Template.pm 2006-08-12 12:03:12.000000000 +0100
+++ codestriker-1.9.2_TestDirector_scmbug/lib/Codestriker/Http/Template.pm 2006-11-13 16:05:42.000000000 +0000
@@ -82,6 +82,11 @@
$vars->{'bugdb_enabled'} =
(defined $Codestriker::bug_db && $Codestriker::bug_db ne "") ? 1 : 0;
+ # Indicate if bug db integration with SCM is enabled.
+ $vars->{'budid_scmbug_enabled'} =
+ (defined $Codestriker::bugdb_scmbug_link && $Codestriker::bugdb_scmbug_link ne "") ? 1 : 0;
+
+
# Indicate if antispam_email is enabled.
$vars->{'antispam_email'} = $Codestriker::antispam_email;
diff -uNPr codestriker-1.9.2/lib/Codestriker/Repository/ClearCaseDynamic.pm codestriker-1.9.2_TestDirector_scmbug/lib/Codestriker/Repository/ClearCaseDynamic.pm
--- codestriker-1.9.2/lib/Codestriker/Repository/ClearCaseDynamic.pm 2006-08-10 22:11:42.000000000 +0100
+++ codestriker-1.9.2_TestDirector_scmbug/lib/Codestriker/Repository/ClearCaseDynamic.pm 2006-11-14 14:09:06.000000000 +0000
@@ -124,4 +124,14 @@
return $Codestriker::UNSUPPORTED_OPERATION;
}
+# The getDiffFromBugId operation, pull out a change set based on the Bug ID
+# linkage
+# This has not been implemented for this repository type yet
+sub getDiffFromBugId ($$$) {
+ my ($self, $bugids, $stdout_fh, $stderr_fh) = @_;
+
+ return $Codestriker::UNSUPPORTED_OPERATION;
+}
+
+
1;
diff -uNPr codestriker-1.9.2/lib/Codestriker/Repository/ClearCaseSnapshot.pm codestriker-1.9.2_TestDirector_scmbug/lib/Codestriker/Repository/ClearCaseSnapshot.pm
--- codestriker-1.9.2/lib/Codestriker/Repository/ClearCaseSnapshot.pm 2006-08-10 22:11:44.000000000 +0100
+++ codestriker-1.9.2_TestDirector_scmbug/lib/Codestriker/Repository/ClearCaseSnapshot.pm 2006-11-14 14:07:02.000000000 +0000
@@ -127,4 +127,13 @@
return $Codestriker::UNSUPPORTED_OPERATION;
}
+# The getDiffFromBugId operation, pull out a change set based on the Bug ID
+# linkage
+# This has not been implemented for this repository type yet
+sub getDiffFromBugId ($$$) {
+ my ($self, $bugids, $stdout_fh, $stderr_fh) = @_;
+
+ return $Codestriker::UNSUPPORTED_OPERATION;
+}
+
1;
diff -uNPr codestriker-1.9.2/lib/Codestriker/Repository/Cvs.pm codestriker-1.9.2_TestDirector_scmbug/lib/Codestriker/Repository/Cvs.pm
--- codestriker-1.9.2/lib/Codestriker/Repository/Cvs.pm 2006-06-11 19:34:56.000000000 +0100
+++ codestriker-1.9.2_TestDirector_scmbug/lib/Codestriker/Repository/Cvs.pm 2006-11-14 14:07:22.000000000 +0000
@@ -147,4 +147,13 @@
return $Codestriker::OK;
}
+# The getDiffFromBugId operation, pull out a change set based on the Bug ID
+# linkage
+# This has not been implemented for this repository type yet
+sub getDiffFromBugId ($$$) {
+ my ($self, $bugids, $stdout_fh, $stderr_fh) = @_;
+
+ return $Codestriker::UNSUPPORTED_OPERATION;
+}
+
1;
diff -uNPr codestriker-1.9.2/lib/Codestriker/Repository/CvsWeb.pm codestriker-1.9.2_TestDirector_scmbug/lib/Codestriker/Repository/CvsWeb.pm
--- codestriker-1.9.2/lib/Codestriker/Repository/CvsWeb.pm 2006-06-09 18:17:24.000000000 +0100
+++ codestriker-1.9.2_TestDirector_scmbug/lib/Codestriker/Repository/CvsWeb.pm 2006-11-14 14:07:34.000000000 +0000
@@ -68,4 +68,13 @@
return $Codestriker::UNSUPPORTED_OPERATION;
}
+# The getDiffFromBugId operation, pull out a change set based on the Bug ID
+# linkage
+# This has not been implemented for this repository type yet
+sub getDiffFromBugId ($$$) {
+ my ($self, $bugids, $stdout_fh, $stderr_fh) = @_;
+
+ return $Codestriker::UNSUPPORTED_OPERATION;
+}
+
1;
diff -uNPr codestriker-1.9.2/lib/Codestriker/Repository/Perforce.pm codestriker-1.9.2_TestDirector_scmbug/lib/Codestriker/Repository/Perforce.pm
--- codestriker-1.9.2/lib/Codestriker/Repository/Perforce.pm 2006-06-09 18:17:24.000000000 +0100
+++ codestriker-1.9.2_TestDirector_scmbug/lib/Codestriker/Repository/Perforce.pm 2006-11-14 14:07:44.000000000 +0000
@@ -81,4 +81,13 @@
return $Codestriker::UNSUPPORTED_OPERATION;
}
+# The getDiffFromBugId operation, pull out a change set based on the Bug ID
+# linkage
+# This has not been implemented for this repository type yet
+sub getDiffFromBugId ($$$) {
+ my ($self, $bugids, $stdout_fh, $stderr_fh) = @_;
+
+ return $Codestriker::UNSUPPORTED_OPERATION;
+}
+
1;
diff -uNPr codestriker-1.9.2/lib/Codestriker/Repository/Subversion.pm codestriker-1.9.2_TestDirector_scmbug/lib/Codestriker/Repository/Subversion.pm
--- codestriker-1.9.2/lib/Codestriker/Repository/Subversion.pm 2006-08-10 22:11:44.000000000 +0100
+++ codestriker-1.9.2_TestDirector_scmbug/lib/Codestriker/Repository/Subversion.pm 2006-12-21 15:40:46.000000000 +0000
@@ -218,4 +218,121 @@
return $Codestriker::OK;
}
+
+# The getDiffFromBugId operation, pull out a change set based on the Bug ID
+# linkage
+sub getDiffFromBugId ($$$) {
+ my ($self, $bugids, $stdout_fh, $stderr_fh) = @_;
+
+ my @changeFileList;
+
+ # If Codestriker is linked to a bug database, and this topic is associated
+ # with some bugs, update them with an appropriate message.
+ if ($bugids ne "" && $Codestriker::bug_db ne "") {
+
+ my $bug_db_connection =
+ Codestriker::BugDB::BugDBConnectionFactory->getBugDBConnection();
+
+ @changeFileList = $bug_db_connection->get_bug_file_list($bugids);
+
+ $bug_db_connection->release_connection();
+ }
+
+
+ for( my $i = 0; $i <= $#changeFileList; $i++ ) {
+ # The following section gets the version numbers and name
+ my $fromVer = $changeFileList[$i]->{ old_version };
+ my $toVer = $changeFileList[$i]->{ new_version };
+ my $justFileName = $changeFileList[$i]->{ file };
+
+ my @elements = split( "/", $justFileName);
+ pop(@elements);
+ my $directoryPath = join("/", @elements);
+
+ # Don't diff deleted files
+ if( $toVer eq "0" ) {
+ next;
+ }
+
+ my $write_stdin_fh = new FileHandle;
+ my $read_stdout_fh = new FileHandle;
+ my $read_stderr_fh = new FileHandle;
+
+ my @args = ();
+
+ # If the from version is 0 then it is a new file
+ if( $fromVer eq "0" ) {
+ # for a new file we do a diff on the directory between
+ # the given version and the previous one.
+ $fromVer = $toVer - 1;
+
+ push @args, 'diff';
+ push @args, '--non-interactive';
+ push @args, '--no-auth-cache';
+ push @args, @{ $self->{userCmdLine} };
+ push @args, '-r';
+ push @args, $fromVer . ':' . $toVer;
+ push @args, '--old';
+ push @args, $self->{repository_url};
+ push @args, $directoryPath;
+ }
+ else
+ {
+ push @args, 'diff';
+ push @args, '--non-interactive';
+ push @args, '--no-auth-cache';
+ push @args, @{ $self->{userCmdLine} };
+ push @args, '-r';
+ push @args, $fromVer . ':' . $toVer;
+ push @args, '--old';
+ push @args, $self->{repository_url};
+ push @args, $justFileName;
+ }
+
+ my $pid = open3($write_stdin_fh, $read_stdout_fh, $read_stderr_fh,
+ $Codestriker::svn, @args);
+
+ while(<$read_stdout_fh>) {
+ my $line = $_;
+
+ # If the user specifies a path (a branch in Subversion), the
+ # diff file does not come back with a path rooted from the
+ # repository base making it impossible to pull the entire file
+ # back out. This code attempts to change the diff file on the
+ # fly to ensure that the full path is present. This is a bug
+ # against Subversion, so eventually it will be fixed, so this
+ # code can't break when the diff command starts returning the
+ # full path.
+ if ($line =~ /^--- / || $line =~ /^\+\+\+ / || $line =~ /^Index: /) {
+ # Check if the bug has been fixed.
+ if ($line =~ /^\+\+\+ $directoryPath/ == 0 &&
+ $line =~ /^--- $directoryPath/ == 0 &&
+ $line =~ /^Index: $directoryPath/ == 0) {
+
+ $line =~ s/^--- /--- $directoryPath\// or
+ $line =~ s/^Index: /Index: $directoryPath\// or
+ $line =~ s/^\+\+\+ /\+\+\+ $directoryPath\//;
+ }
+ }
+
+ print $stdout_fh $line;
+ }
+
+ my $buf;
+ while (read($read_stderr_fh, $buf, 16384)) {
+ print $stderr_fh $buf;
+ }
+
+ # Wait for the process to terminate.
+ waitpid($pid, 0);
+
+ # Flush the output file handles.
+ $stdout_fh->flush;
+ $stderr_fh->flush;
+ }
+
+ return $Codestriker::OK;
+}
+
+
1;
diff -uNPr codestriker-1.9.2/lib/Codestriker/Repository/ViewCvs.pm codestriker-1.9.2_TestDirector_scmbug/lib/Codestriker/Repository/ViewCvs.pm
--- codestriker-1.9.2/lib/Codestriker/Repository/ViewCvs.pm 2006-06-09 18:17:24.000000000 +0100
+++ codestriker-1.9.2_TestDirector_scmbug/lib/Codestriker/Repository/ViewCvs.pm 2006-11-14 14:08:04.000000000 +0000
@@ -69,4 +69,13 @@
return $Codestriker::UNSUPPORTED_OPERATION;
}
+# The getDiffFromBugId operation, pull out a change set based on the Bug ID
+# linkage
+# This has not been implemented for this repository type yet
+sub getDiffFromBugId ($$$) {
+ my ($self, $bugids, $stdout_fh, $stderr_fh) = @_;
+
+ return $Codestriker::UNSUPPORTED_OPERATION;
+}
+
1;
diff -uNPr codestriker-1.9.2/lib/Codestriker/Repository/Vss.pm codestriker-1.9.2_TestDirector_scmbug/lib/Codestriker/Repository/Vss.pm
--- codestriker-1.9.2/lib/Codestriker/Repository/Vss.pm 2006-06-09 18:17:24.000000000 +0100
+++ codestriker-1.9.2_TestDirector_scmbug/lib/Codestriker/Repository/Vss.pm 2006-11-14 14:08:24.000000000 +0000
@@ -274,4 +274,13 @@
return $Codestriker::OK;
}
+# The getDiffFromBugId operation, pull out a change set based on the Bug ID
+# linkage
+# This has not been implemented for this repository type yet
+sub getDiffFromBugId ($$$) {
+ my ($self, $bugids, $stdout_fh, $stderr_fh) = @_;
+
+ return $Codestriker::UNSUPPORTED_OPERATION;
+}
+
1;
diff -uNPr codestriker-1.9.2/README.bak codestriker-1.9.2_TestDirector_scmbug/README.bak
--- codestriker-1.9.2/README.bak 1970-01-01 00:00:00.000000000 +0000
+++ codestriker-1.9.2_TestDirector_scmbug/README.bak 2006-11-10 15:44:48.000000000 +0000
@@ -0,0 +1,12 @@
+Codestriker
+Copyright (c) 2001 - 2006 David Sitsky. All rights reserved.
+sits@users.sourceforge.net
+
+*** Please read the CHANGELOG file for details on changes ***
+-------------------------------------------------------------
+
+All documentation is now in the Codestriker guide. The HTML and PDF
+versions of this guide are present in the html directory, and are
+available from the online help when Codestriker is deployed.
+
+Version: 1.9.2
diff -uNPr codestriker-1.9.2/template/en/default/createtopic.html.tmpl codestriker-1.9.2_TestDirector_scmbug/template/en/default/createtopic.html.tmpl
--- codestriker-1.9.2/template/en/default/createtopic.html.tmpl 2006-08-10 22:16:10.000000000 +0100
+++ codestriker-1.9.2_TestDirector_scmbug/template/en/default/createtopic.html.tmpl 2006-11-14 14:32:38.000000000 +0000
@@ -61,9 +61,15 @@
[% END %]
[% END %]
+
+
+
+