-
Notifications
You must be signed in to change notification settings - Fork 0
/
SvnRevision.cs
169 lines (145 loc) · 6.02 KB
/
SvnRevision.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
// NAnt - A .NET build tool
// Copyright (C) 2001-2006 Gerry Shaw
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// Eugen Anghel (eugen@syntactic.org)
// http://schambers.googlecode.com/svn/NAnt.SvnFunctions/trunk/src/
//
// Usage:
//
// svn::get-revision-number(path, username, password)
// svn::get-repository-root(path)
// svn::get-repository-url(path)
// svn::get-last-changed-author(path)
// ${svn::get-revision-number('.', '', '')}
//
using System;
using System.Diagnostics;
using System.Text.RegularExpressions;
using System.ComponentModel;
using NAnt.Core;
using NAnt.Core.Attributes;
using System.Collections.Generic;
namespace Nant.SvnFunctions
{
/// <summary>
/// Provides methods for working with SVN
/// </summary>
[FunctionSet("svn", "SourceControl")]
public class SvnFunctions : FunctionSetBase
{
#region Public Instance Constructors
public SvnFunctions(Project project, PropertyDictionary properties) : base(project, properties) { }
#endregion Public Instance Constructors
#region Public Instance Methods
/// <summary>
/// Gets the revision number for the Subversion repository at the specified path.
/// </summary>
/// <param name="path">The path to a svn repository</param>
/// <param name="username">Username to access the repository</param>
/// <param name="password">Password to access the repository</param>
/// <returns>The revision number of the specified repository</returns>
[Function("get-revision-number")]
public int GetRevisionNumber(string path, string username, string password)
{
IDictionary<string, string> arguments = new Dictionary<string, string>();
arguments.Add("username", username);
arguments.Add("password", password);
return int.Parse(GetInfo(path, arguments)["Revision"]);
}
/// <summary>
/// Gets an url containing the root of the specified repository
/// </summary>
/// <param name="path">The path to a svn repository</param>
/// <returns>The root url of the repository</returns>
[Function("get-repository-root")]
public string GetRepositoryRoot(string path)
{
return GetInfo(path)["Repository Root"];
}
/// <summary>
/// Gets the url of the specified repository
/// </summary>
/// <param name="path">The path to a svn repository</param>
/// <returns>The url of the repository</returns>
[Function("get-repository-url")]
public string GetRepositoryUrl(string path)
{
return GetInfo(path)["URL"];
}
/// <summary>
/// Gets the name of the person who made the last change in the repository
/// </summary>
/// <param name="path">The path to a svn repository</param>
/// <returns>The name of the last committer</returns>
[Function("get-last-changed-author")]
public string GetLastChangedAuthor(string path)
{
return GetInfo(path)["Last Changed Author"];
}
#endregion Public Instance Methods
#region Private Instance Methods
private Dictionary<string, string> GetInfo(string path)
{
return GetInfo(path, null);
}
private Dictionary<string, string> GetInfo(string path, IDictionary<string, string> svnArguments)
{
ProcessStartInfo pinfo = new ProcessStartInfo("svn.exe");
string argumentString = string.Format("info {0}", path);
foreach (string key in svnArguments.Keys)
{
if (svnArguments[key] != "")
argumentString += string.Format(" --{0} {1}", key, svnArguments[key]);
}
pinfo.Arguments = argumentString;
pinfo.UseShellExecute = false;
pinfo.RedirectStandardOutput = true;
Process svnProcess;
try
{
svnProcess = Process.Start(pinfo);
}
catch (Win32Exception win32Ex)
{
throw new Exception("Exception caught executing process: most probably 'svn.exe' was not found", win32Ex);
}
string output = svnProcess.StandardOutput.ReadToEnd();
if (svnProcess.ExitCode == 9009 && output.Contains("is not a working copy"))
throw new ArgumentException("The specified path is not a working copy", "path");
else if (svnProcess.ExitCode != 0)
throw new Exception("Failed while running 'svn.exe'. Error code " + svnProcess.ExitCode);
svnProcess.Dispose();
try
{
return ParseOutput(output);
}
catch (Exception)
{
throw new Exception(string.Format("Key was not found. Output:{0}", output));
}
}
private static Dictionary<string, string> ParseOutput(string output)
{
Dictionary<string, string> values = new Dictionary<string, string>();
Regex regex = new Regex("^(?<key>[^:]*):(?<value>.*)$", RegexOptions.Multiline);
foreach (Match match in regex.Matches(output))
values[match.Groups["key"].Value] = match.Groups["value"].Value.Trim();
return values;
}
#endregion Private Instance Methods
}
}