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 %] + + +
+ + [%# The topic text upload button #%] - - + [% END %] +
Topic text upload: + +Topic text upload: (?)
+
+ [%# The repository the review is made against #%] [%# Only display the repository select if there is more than one #%] @@ -221,13 +230,31 @@ it can be easily determined what code fixes have been applied \ to it.')">(?) - + [% END %] [%# The email input field #%] -
+[% IF budid_scmbug_enabled != 0 %] + +Auto-detect files from Bug IDs + + + +[% END %] +
Your email address: + Your email address: Bug [% bug %] + [% IF bugtracker != "" %] + Bug [% bug %] + [% ELSE %] + Bug [% bug %] + [% END %] [% END %]