X-Git-Url: http://git.sourceforge.jp/view?p=tortoisegit%2FTortoiseGitJp.git;a=blobdiff_plain;f=contrib%2Fissue-tracker-plugins%2Fissue-tracker-plugins.txt;fp=contrib%2Fissue-tracker-plugins%2Fissue-tracker-plugins.txt;h=aa2b7fc406454d59d06216db808694791623e4d5;hp=0000000000000000000000000000000000000000;hb=07eb255ad84c93ebef333f77c3d746dd4582e203;hpb=44651c11dfc1fb8a7b32e651ffe46b4fbb82110e diff --git a/contrib/issue-tracker-plugins/issue-tracker-plugins.txt b/contrib/issue-tracker-plugins/issue-tracker-plugins.txt new file mode 100644 index 0000000..aa2b7fc --- /dev/null +++ b/contrib/issue-tracker-plugins/issue-tracker-plugins.txt @@ -0,0 +1,309 @@ +Issue Tracker Plugins +===================== + +What is this for? +----------------- + +Imagine the following scenario: + + 1. Marvin the manager assigns a ticket or task to Dave, the developer, using + the issue-tracking or task-management software. + 2. Dave looks at his list of tasks using the issue-tracking software's front + end (i.e. a web-dashboard). He picks something to work on this morning. + 3. Dave fires up Visual Studio; hacks on some code; does some work toward + the task. + 4. Dave brings up TSVN's commit dialog. He types in a comment that lists, + depending on coding standards: + a) The ticket/task number of what he's been working on. + b) Some comments about what he's changed. + 5. He clicks OK, and his changes are committed to the repository. + 6. The issue-tracking software monitors the SVN repository, watching for + commits.It sees Dave's commit message, extracts the information from it, + and updates the ticket appropriately. + 7. Marvin looks in the task-management software, and can monitor the + project's progress. + +As it stands, TSVN supports (most of) this admirably. For example, with the +Trac integration, I can put "See #43" or "Fixes #99" somewhere in the commit +message, and Trac's post-commit hook will update the tickets accordingly. + +However: + 1. Dave has to keep the issue-tracker front-end open in order to look up the + ticket numbers. + 2. Some issue trackers want more information (e.g. time spent, time + remaining), and it needs to be formatted more rigidly. + +So, the user story looks like this: + + "From the TSVN commit dialog, the user should be able to display up a list of + assigned tickets from the issue-tracker associated with that repository. The + user should be able to pick one or more tasks from this list." + + "This will populate the commit message with the information required by the + issue-tracker's SVN server-side post-commit hook." + + "This functionality should be available from the commit dialog, because the + user may wish to choose which files to commit based on which ticket they + select, or he may wish to refresh his memory about what's changed before + selecting the appropriate ticket." + + +Implementing an issue tracker plugin +------------------------------------ + +To write an integration plugin, you implement the IBugTraqProvider COM +interface, and register your object as implementing the "TortoiseSVN BugTraq +Providers" component category. This registration makes it easy for the +settings dialog to find a list of available plugins. + +The IBugTraqProvider interface is documented in the inc\IBugTraqProvider.idl +file. + +The component category is defined (in C++) as follows: + +// {3494FA92-B139-4730-9591-01135D5E7831} +DEFINE_GUID(CATID_BugTraqProvider, + 0x3494fa92, 0xb139, 0x4730, 0x95, 0x91, 0x1, 0x13, 0x5d, 0x5e, 0x78, 0x31); + + +Example Plugins +--------------- + +There are two example plugins in this folder. + + - ExampleAtlPlugin, written in C++, using ATL. + - ExampleCsPlugin, written in C#. + +They get the list of available "issues" from a hard-coded list, rather than a +database or web service, but this should be sufficient to demonstrate the +plugin API. + + +Licensing and GPL compatibility +------------------------------- + +TortoiseSVN is licensed under the GNU General Public License (see the file +LICENSE for details). + +There is a specific exception for plugins that implement the issue tracker +plugin interfaces; these do not need to be GPL-licensed. + + +The IBugTraqProvider interface +------------------------------ + +In the contrib\issue-tracker-plugins\inc directory, you'll find the following +files: + + * IBugTraqProvider.idl + This is a copy of the src\IBugTraqProvider\IBugTraqProvider.idl file; it's + provided for reference; you'll probably use the files below. + + * IBugTraqProvider_h.h, IBugTraqProvider_i.c + These are the files you'll probably use if you implement a plugin in C++. + + * Interop.BugTraqProvider.dll + Interop Assembly for implementing plugins in .NET. It's not a Primary + Interop Assembly (PIA). + The source code for this project is in the Interop.BugTraqProvider folder. + +The interface is documented in the .IDL file. + + +Walkthrough: Creating an issue tracker plugin in C# +--------------------------------------------------- + +(This assumes a basic familiarity with creating Windows Forms applications). + +In Visual Studio 2005 or 2008, create a new "Class Library" project; give it a +name. + +Delete the "Class1" class; we'll create another one in a moment. + +Add a reference to the inc\Interop.BugTraqProvider.dll file. + +Create a new class named "MyPlugin". + +Derive MyPlugin from the Interop.BugTraqProvider.IBugTraqProvider interface, +and then implement the first two methods as follows: + +The ValidateParameters method should look like this: + + public bool ValidateParameters(IntPtr hParentWnd, string parameters) + { + return true; + } + +The GetLinkText method should look like this: + + public string GetLinkText(IntPtr hParentWnd, string parameters) + { + return "Choose Issue"; + } + +We'll come back to GetCommitMessage shortly. + +The class also needs some attributes; it should look like this: + + [ComVisible(true), + Guid("PUT-GUID-HERE"), + ClassInterface(ClassInterfaceType.None)] + public class Provider : IBugTraqProvider + { + // etc. + +(Replace "PUT-GUID-HERE" with a new GUID). + +Add a class to hold our example ticket data: + + internal class TicketItem + { + private readonly int _ticketNumber; + private readonly string _ticketSummary; + + public TicketItem(int ticketNumber, string ticketSummary) + { + _ticketNumber = ticketNumber; + _ticketSummary = ticketSummary; + } + + public int Number + { + get { return _ticketNumber; } + } + + public string Summary + { + get { return _ticketSummary; } + } + } + +We can now implement the GetCommitMessage method as follows: + + public string GetCommitMessage(IntPtr hParentWnd, string parameters, string commonRoot, string[] pathList, string originalMessage) + { + List tickets = new List(); + tickets.Add(new TicketItem(12, "Service doesn't start on Windows Vista")); + tickets.Add(new TicketItem(19, "About box doesn't render correctly in large fonts mode")); + + MyIssuesForm form = new MyIssuesForm(tickets); + if (form.ShowDialog() != DialogResult.OK) + return originalMessage; + + StringBuilder result = new StringBuilder(originalMessage); + if (originalMessage.Length != 0 && !originalMessage.EndsWith("\n")) + result.AppendLine(); + + foreach (TicketItem ticket in form.TicketsFixed) + { + result.AppendFormat("Fixed #{0}: {1}", ticket.Number, ticket.Summary); + result.AppendLine(); + } + + return result.ToString(); + } + +This passes the list of open issues to the MyIssuesForm object, where the +user will be able to check those ones that she's fixed. These are available +through the TicketsFixed property. + +We use these to build a string that looks something like this: + +Fixed #12: Service doesn't start on Windows Vista. + +A commit message formatted like this will cause, (e.g.) Trac's post-commit +hook to close the tickets. + +Anything that the user has already entered into the commit message is left +there. + +Now we need a dialog box that displays the issues assigned to the +current user. + +Add a Windows Form item to your project. Name it "MyIssuesForm". Set the +following properties: + + StartPosition = CenterParent + MaximizeBox = False + MinimizeBox = False + ShowIcon = False + ShowInTaskbar = False + +Put the usual OK and Cancel buttons on it; arrange them and wire them up +properly. + +Add a ListView control to the form and arrange it appropriately. Set the +following properties: + + Checkboxes = True + FullRowSelect = True + View = Details + HeaderStyle = Nonclickable + +Change the class so that it looks like this: + + partial class MyIssuesForm : Form + { + private readonly IEnumerable _tickets; + private readonly List _ticketsAffected = new List(); + + public MyIssuesForm(IEnumerable tickets) + { + InitializeComponent(); + _tickets = tickets; + } + + public IEnumerable TicketsFixed + { + get { return _ticketsAffected; } + } + + // etc. + +Then implement some event handlers in MyIssuesForm as follows: + + private void MyIssuesForm_Load(object sender, EventArgs e) + { + listView1.Columns.Add(""); + listView1.Columns.Add("#"); + listView1.Columns.Add("Summary"); + + foreach(TicketItem ticketItem in _tickets) + { + ListViewItem lvi = new ListViewItem(); + lvi.Text = ""; + lvi.SubItems.Add(ticketItem.Number.ToString()); + lvi.SubItems.Add(ticketItem.Summary); + lvi.Tag = ticketItem; + + listView1.Items.Add(lvi); + } + + listView1.Columns[0].Width = -1; + listView1.Columns[1].Width = -1; + listView1.Columns[2].Width = -1; + } + + private void okButton_Click(object sender, EventArgs e) + { + foreach (ListViewItem lvi in listView1.Items) + { + TicketItem ticketItem = lvi.Tag as TicketItem; + if (ticketItem != null && lvi.Checked) + _ticketsAffected.Add(ticketItem); + } + } + +Registering your new C# class can be done by using RegAsm from the command +line, as follows: + + RegAsm bin\Debug\MyCsPlugin.dll /codebase /regfile:MyCsPlugin.reg + +You'll need to edit the .REG file, by adding another "Implemented Categories" +entry that looks like this: + +[HKEY_CLASSES_ROOT\CLSID\{PUT-GUID-HERE}\Implemented Categories\{3494FA92-B139-4730-9591-01135D5E7831}] + +Replace "PUT-GUID-HERE" with the same value you used earlier. + +Then, merge that .REG file into the registry, and your plugin is ready to go!