Browse Source
git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@2971 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61shortcuts
25 changed files with 1200 additions and 774 deletions
@ -1,282 +0,0 @@
@@ -1,282 +0,0 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Threading; |
||||
using System.Windows.Forms; |
||||
|
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.SharpDevelop.Gui; |
||||
using ICSharpCode.Svn.Gui; |
||||
using NSvn.Core; |
||||
|
||||
namespace ICSharpCode.Svn |
||||
{ |
||||
/// <summary>
|
||||
/// Description of SvnClient.
|
||||
/// </summary>
|
||||
public class SvnClient |
||||
{ |
||||
public static SvnClient Instance = new SvnClient(); |
||||
|
||||
Client client; |
||||
string logMessage = String.Empty; |
||||
|
||||
|
||||
MessageViewCategory svnCategory; |
||||
|
||||
public MessageViewCategory SvnCategory { |
||||
get { |
||||
if (svnCategory == null) { |
||||
svnCategory = new MessageViewCategory("Subversion", "Subversion"); |
||||
CompilerMessageView compilerMessageView = (CompilerMessageView)WorkbenchSingleton.Workbench.GetPad(typeof(CompilerMessageView)).PadContent; |
||||
compilerMessageView.AddCategory(svnCategory); |
||||
} |
||||
return svnCategory; |
||||
} |
||||
} |
||||
|
||||
public NSvn.Core.Client Client { |
||||
get { |
||||
return client; |
||||
} |
||||
} |
||||
|
||||
public string LogMessage { |
||||
get { |
||||
return logMessage; |
||||
} |
||||
set { |
||||
logMessage = value; |
||||
} |
||||
} |
||||
|
||||
string GetKindString(NodeKind kind) |
||||
{ |
||||
switch (kind) { |
||||
case NodeKind.Directory: |
||||
return "directory "; |
||||
case NodeKind.File: |
||||
return "file "; |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public static string GetActionString(ChangedPathAction action) |
||||
{ |
||||
switch (action) { |
||||
case ChangedPathAction.Add: |
||||
return GetActionString(NotifyAction.CommitAdded); |
||||
case ChangedPathAction.Delete: |
||||
return GetActionString(NotifyAction.CommitDeleted); |
||||
case ChangedPathAction.Modify: |
||||
return GetActionString(NotifyAction.CommitModified); |
||||
case ChangedPathAction.Replace: |
||||
return GetActionString(NotifyAction.CommitReplaced); |
||||
default: |
||||
return "unknown"; |
||||
} |
||||
} |
||||
|
||||
public static string GetActionString(NotifyAction action) |
||||
{ |
||||
switch (action) { |
||||
case NotifyAction.Add: |
||||
case NotifyAction.UpdateAdd: |
||||
case NotifyAction.CommitAdded: |
||||
return "added"; |
||||
case NotifyAction.Copy: |
||||
return "copied"; |
||||
case NotifyAction.Delete: |
||||
case NotifyAction.UpdateDelete: |
||||
case NotifyAction.CommitDeleted: |
||||
return "deleted"; |
||||
case NotifyAction.Restore: |
||||
return "restored"; |
||||
case NotifyAction.Revert: |
||||
return "reverted"; |
||||
case NotifyAction.FailedRevert: |
||||
return "revert failed"; |
||||
case NotifyAction.Resolved: |
||||
return "resolved"; |
||||
case NotifyAction.Skip: |
||||
return "skipped"; |
||||
case NotifyAction.UpdateUpdate: |
||||
return "updated"; |
||||
case NotifyAction.CommitPostfixTxDelta: |
||||
case NotifyAction.UpdateCompleted: |
||||
return ""; |
||||
case NotifyAction.UpdateExternal: |
||||
return "updated external"; |
||||
case NotifyAction.CommitModified: |
||||
return "modified"; |
||||
case NotifyAction.CommitReplaced: |
||||
return "replaced"; |
||||
default: |
||||
return "unknown"; |
||||
} |
||||
} |
||||
|
||||
void ReceiveNotification(object sender, NotificationEventArgs e) |
||||
{ |
||||
if (e.Action == NotifyAction.UpdateCompleted) { |
||||
SvnCategory.AppendText(Environment.NewLine + "Updated " + e.Path + " to revision " + e.RevisionNumber + "."); |
||||
return; |
||||
} |
||||
if (e.Action == NotifyAction.CommitPostfixTxDelta) { |
||||
SvnCategory.AppendText("."); |
||||
return; |
||||
} |
||||
|
||||
string kind = GetKindString(e.NodeKind); |
||||
string action = GetActionString(e.Action); |
||||
SvnCategory.AppendText(Environment.NewLine + kind + action + " : " + e.Path); |
||||
} |
||||
|
||||
void SetLogMessage(object sender, LogMessageEventArgs e) |
||||
{ |
||||
if (e.Message == null) { |
||||
e.Message = logMessage; |
||||
} |
||||
} |
||||
|
||||
void WriteMid(string str) |
||||
{ |
||||
const int max = 40; |
||||
string filler = new String('-', max - str.Length / 2); |
||||
SvnCategory.AppendText(Environment.NewLine + filler + " " + str + " " + filler); |
||||
if (str.Length % 2 == 0) { |
||||
SvnCategory.AppendText("-"); |
||||
} |
||||
} |
||||
|
||||
class ThreadStartWrapper |
||||
{ |
||||
ThreadStart innerDelegate; |
||||
|
||||
public ThreadStartWrapper(ThreadStart innerDelegate) |
||||
{ |
||||
this.innerDelegate = innerDelegate; |
||||
} |
||||
|
||||
public void Start() |
||||
{ |
||||
try { |
||||
innerDelegate(); |
||||
} catch (ThreadAbortException) { |
||||
// don't show error message, silently cancel thread
|
||||
} catch (Exception e) { |
||||
SvnClient.Instance.OperationDone(); |
||||
|
||||
MessageService.ShowError(e); |
||||
} finally { |
||||
SvnClient.Instance.OperationDone(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
InOperationDialog inOperationForm; |
||||
bool done = false; |
||||
public void OperationStart(string operationName, ThreadStart threadStart) |
||||
{ |
||||
done = false; |
||||
WriteMid(operationName); |
||||
|
||||
Thread thread = new Thread(new ThreadStart(new ThreadStartWrapper(threadStart).Start)); |
||||
thread.Name = "SvnOperation"; |
||||
thread.IsBackground = true; |
||||
inOperationForm = new InOperationDialog(operationName, thread); |
||||
inOperationForm.Owner = WorkbenchSingleton.MainForm; |
||||
inOperationForm.Show(); |
||||
thread.Start(); |
||||
} |
||||
|
||||
void OperationDone() |
||||
{ |
||||
if (done) { |
||||
return; |
||||
} |
||||
WorkbenchSingleton.SafeThreadCall(WriteMid, "Done"); |
||||
try { |
||||
if (inOperationForm != null) { |
||||
inOperationForm.Operation = null; |
||||
WorkbenchSingleton.SafeThreadCall(inOperationForm.Close); |
||||
inOperationForm = null; |
||||
} |
||||
} catch (Exception e) { |
||||
MessageService.ShowError(e); |
||||
} finally { |
||||
done = true; |
||||
} |
||||
} |
||||
|
||||
public void WaitForOperationEnd() |
||||
{ |
||||
while (!done) { |
||||
Application.DoEvents(); |
||||
} |
||||
} |
||||
|
||||
SvnClient() |
||||
{ |
||||
LoggingService.Info("SVN: SvnClient initialized"); |
||||
client = new Client(); |
||||
client.LogMessage += new LogMessageDelegate(SetLogMessage); |
||||
client.Notification += new NotificationDelegate(ReceiveNotification); |
||||
|
||||
client.AuthBaton.Add(AuthenticationProvider.GetUsernameProvider()); |
||||
client.AuthBaton.Add(AuthenticationProvider.GetSimpleProvider()); |
||||
client.AuthBaton.Add(AuthenticationProvider.GetSimplePromptProvider(new SimplePromptDelegate(this.PasswordPrompt), 3)); |
||||
client.AuthBaton.Add(AuthenticationProvider.GetSslServerTrustFileProvider()); |
||||
client.AuthBaton.Add(AuthenticationProvider.GetSslServerTrustPromptProvider(new SslServerTrustPromptDelegate(this.SslServerTrustPrompt))); |
||||
client.AuthBaton.Add(AuthenticationProvider.GetSslClientCertPasswordFileProvider()); |
||||
client.AuthBaton.Add(AuthenticationProvider.GetSslClientCertPasswordPromptProvider(new SslClientCertPasswordPromptDelegate(this.ClientCertificatePasswordPrompt), 3)); |
||||
client.AuthBaton.Add(AuthenticationProvider.GetSslClientCertFileProvider()); |
||||
client.AuthBaton.Add(AuthenticationProvider.GetSslClientCertPromptProvider(new SslClientCertPromptDelegate(this.ClientCertificatePrompt), 3)); |
||||
} |
||||
|
||||
SimpleCredential PasswordPrompt(string realm, string userName, bool maySave) |
||||
{ |
||||
using (LoginDialog loginDialog = new LoginDialog(realm, userName, maySave)) { |
||||
if (WorkbenchSingleton.SafeThreadFunction<Form, DialogResult>(loginDialog.ShowDialog, WorkbenchSingleton.MainForm) == DialogResult.OK) { |
||||
return loginDialog.Credential; |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
SslServerTrustCredential SslServerTrustPrompt(string realm, SslFailures failures, SslServerCertificateInfo info, bool maySave) |
||||
{ |
||||
using (SslServerTrustDialog sslServerTrustDialog = new SslServerTrustDialog(info, failures, maySave)) { |
||||
if (WorkbenchSingleton.SafeThreadFunction<Form, DialogResult>(sslServerTrustDialog.ShowDialog, WorkbenchSingleton.MainForm) == DialogResult.OK) { |
||||
return sslServerTrustDialog.Credential; |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
SslClientCertificatePasswordCredential ClientCertificatePasswordPrompt(string realm, bool maySave) |
||||
{ |
||||
using (ClientCertPassphraseDialog clientCertPassphraseDialog = new ClientCertPassphraseDialog(realm, maySave)) { |
||||
if (WorkbenchSingleton.SafeThreadFunction<Form, DialogResult>(clientCertPassphraseDialog.ShowDialog, WorkbenchSingleton.MainForm) == DialogResult.OK) { |
||||
return clientCertPassphraseDialog.Credential; |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
SslClientCertificateCredential ClientCertificatePrompt(string realm, bool maySave) |
||||
{ |
||||
using (ClientCertDialog clientCertDialog = new ClientCertDialog(realm, maySave)) { |
||||
if (WorkbenchSingleton.SafeThreadFunction<Form, DialogResult>(clientCertDialog.ShowDialog, WorkbenchSingleton.MainForm) == DialogResult.OK) { |
||||
return clientCertDialog.Credential; |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,748 @@
@@ -0,0 +1,748 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <author name="Daniel Grunwald"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Threading; |
||||
using System.Windows.Forms; |
||||
using System.Text; |
||||
using System.IO; |
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.SharpDevelop.Gui; |
||||
using ICSharpCode.Svn.Gui; |
||||
using PumaCode.SvnDotNet.SubversionSharp; |
||||
using PumaCode.SvnDotNet.AprSharp; |
||||
using System.Runtime.Serialization; |
||||
|
||||
namespace ICSharpCode.Svn |
||||
{ |
||||
using Svn = PumaCode.SvnDotNet.SubversionSharp.Svn; |
||||
|
||||
/// <summary>
|
||||
/// A wrapper around the subversion library.
|
||||
/// </summary>
|
||||
public sealed class SvnClientWrapper : IDisposable |
||||
{ |
||||
#region status->string conversion
|
||||
static string GetKindString(Svn.NodeKind kind) |
||||
{ |
||||
switch (kind) { |
||||
case Svn.NodeKind.Dir: |
||||
return "directory "; |
||||
case Svn.NodeKind.File: |
||||
return "file "; |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public static string GetActionString(char action) |
||||
{ |
||||
switch (action) { |
||||
case 'A': |
||||
return GetActionString(SvnWcNotify.Actions.CommitAdded); |
||||
case 'D': |
||||
return GetActionString(SvnWcNotify.Actions.CommitDeleted); |
||||
case 'M': |
||||
return GetActionString(SvnWcNotify.Actions.CommitModified); |
||||
case 'R': |
||||
return GetActionString(SvnWcNotify.Actions.CommitReplaced); |
||||
default: |
||||
return "unknown"; |
||||
} |
||||
} |
||||
|
||||
public static string GetActionString(SvnWcNotify.Actions action) |
||||
{ |
||||
switch (action) { |
||||
case SvnWcNotify.Actions.Add: |
||||
case SvnWcNotify.Actions.UpdateAdd: |
||||
case SvnWcNotify.Actions.CommitAdded: |
||||
return "added"; |
||||
case SvnWcNotify.Actions.Copy: |
||||
return "copied"; |
||||
case SvnWcNotify.Actions.Delete: |
||||
case SvnWcNotify.Actions.UpdateDelete: |
||||
case SvnWcNotify.Actions.CommitDeleted: |
||||
return "deleted"; |
||||
case SvnWcNotify.Actions.Restore: |
||||
return "restored"; |
||||
case SvnWcNotify.Actions.Revert: |
||||
return "reverted"; |
||||
case SvnWcNotify.Actions.FailedRevert: |
||||
return "revert failed"; |
||||
case SvnWcNotify.Actions.Resolved: |
||||
return "resolved"; |
||||
case SvnWcNotify.Actions.Skip: |
||||
return "skipped"; |
||||
case SvnWcNotify.Actions.UpdateUpdate: |
||||
return "updated"; |
||||
case SvnWcNotify.Actions.UpdateCompleted: |
||||
return ""; |
||||
case SvnWcNotify.Actions.UpdateExternal: |
||||
return "updated external"; |
||||
case SvnWcNotify.Actions.CommitModified: |
||||
return "modified"; |
||||
case SvnWcNotify.Actions.CommitReplaced: |
||||
return "replaced"; |
||||
default: |
||||
return "unknown"; |
||||
} |
||||
} |
||||
#endregion
|
||||
|
||||
#region stuff that does not belong here
|
||||
/* |
||||
void ReceiveNotification(object sender, SvnWcNotify e) |
||||
{ |
||||
if (e.Action == NotifyAction.UpdateCompleted) { |
||||
SvnCategory.AppendText(Environment.NewLine + "Updated " + e.Path.ToString() + " to revision " + e.Revision + "."); |
||||
return; |
||||
} |
||||
|
||||
string kind = GetKindString(e.NodeKind); |
||||
string action = GetActionString(e.Action); |
||||
SvnCategory.AppendText(Environment.NewLine + kind + action + " : " + e.Path); |
||||
} |
||||
|
||||
void WriteMid(string str) |
||||
{ |
||||
const int max = 40; |
||||
string filler = new String('-', max - str.Length / 2); |
||||
SvnCategory.AppendText(Environment.NewLine + filler + " " + str + " " + filler); |
||||
if (str.Length % 2 == 0) { |
||||
SvnCategory.AppendText("-"); |
||||
} |
||||
} |
||||
*/ |
||||
|
||||
/* |
||||
class ThreadStartWrapper |
||||
{ |
||||
ThreadStart innerDelegate; |
||||
|
||||
public ThreadStartWrapper(ThreadStart innerDelegate) |
||||
{ |
||||
this.innerDelegate = innerDelegate; |
||||
} |
||||
|
||||
public void Start() |
||||
{ |
||||
try { |
||||
innerDelegate(); |
||||
} catch (ThreadAbortException) { |
||||
// don't show error message, silently cancel thread
|
||||
} catch (Exception e) { |
||||
SvnClient.Instance.OperationDone(); |
||||
|
||||
MessageService.ShowError(e); |
||||
} finally { |
||||
SvnClient.Instance.OperationDone(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
InOperationDialog inOperationForm; |
||||
bool done = false; |
||||
public void OperationStart(string operationName, ThreadStart threadStart) |
||||
{ |
||||
done = false; |
||||
WriteMid(operationName); |
||||
|
||||
Thread thread = new Thread(new ThreadStart(new ThreadStartWrapper(threadStart).Start)); |
||||
thread.Name = "SvnOperation"; |
||||
thread.IsBackground = true; |
||||
inOperationForm = new InOperationDialog(operationName, thread); |
||||
inOperationForm.Owner = WorkbenchSingleton.MainForm; |
||||
inOperationForm.Show(); |
||||
thread.Start(); |
||||
} |
||||
|
||||
void OperationDone() |
||||
{ |
||||
if (done) { |
||||
return; |
||||
} |
||||
WorkbenchSingleton.SafeThreadCall(WriteMid, "Done"); |
||||
try { |
||||
if (inOperationForm != null) { |
||||
inOperationForm.Operation = null; |
||||
WorkbenchSingleton.SafeThreadCall(inOperationForm.Close); |
||||
inOperationForm = null; |
||||
} |
||||
} catch (Exception e) { |
||||
MessageService.ShowError(e); |
||||
} finally { |
||||
done = true; |
||||
} |
||||
} |
||||
|
||||
public void WaitForOperationEnd() |
||||
{ |
||||
while (!done) { |
||||
Application.DoEvents(); |
||||
} |
||||
} |
||||
*/ |
||||
#endregion
|
||||
|
||||
#region AprPoolHandle
|
||||
sealed class AprPoolHandle : IDisposable |
||||
{ |
||||
AprPool pool; |
||||
|
||||
public AprPool Pool { |
||||
get { return pool; } |
||||
} |
||||
|
||||
public AprPoolHandle() |
||||
{ |
||||
pool = Svn.PoolCreate(); |
||||
} |
||||
|
||||
public void Dispose() |
||||
{ |
||||
if (!pool.IsNull) { |
||||
pool.Destroy(); |
||||
} |
||||
GC.SuppressFinalize(this); |
||||
} |
||||
|
||||
~AprPoolHandle() |
||||
{ |
||||
if (!pool.IsNull) { |
||||
pool.Destroy(); |
||||
} |
||||
} |
||||
} |
||||
#endregion
|
||||
|
||||
AprPoolHandle memoryPool; |
||||
SvnClient client; |
||||
Dictionary<string, Status> statusCache = new Dictionary<string, Status>(); |
||||
|
||||
public SvnClientWrapper() |
||||
{ |
||||
Debug("SVN: Create SvnClient instance"); |
||||
|
||||
memoryPool = new AprPoolHandle(); |
||||
client = new SvnClient(memoryPool.Pool); |
||||
//client.LogMessage += new LogMessageDelegate(SetLogMessage);
|
||||
//client.Notification += new NotificationDelegate(ReceiveNotification);
|
||||
} |
||||
|
||||
public void Dispose() |
||||
{ |
||||
if (memoryPool != null) { |
||||
Debug("SVN: Dispose SvnClient"); |
||||
memoryPool.Dispose(); |
||||
memoryPool = null; |
||||
} |
||||
client = null; |
||||
statusCache = null; |
||||
} |
||||
|
||||
#region Authorization
|
||||
bool authorizationEnabled; |
||||
bool allowInteractiveAuthorization; |
||||
|
||||
public bool AllowInteractiveAuthorization { |
||||
get { |
||||
return allowInteractiveAuthorization; |
||||
} |
||||
set { |
||||
CheckNotDisposed(); |
||||
if (allowInteractiveAuthorization != value) { |
||||
if (authorizationEnabled) |
||||
throw new InvalidOperationException("Cannot change AllowInteractiveAuthorization after an operation was done."); |
||||
allowInteractiveAuthorization = value; |
||||
} |
||||
} |
||||
} |
||||
|
||||
void OpenAuth() |
||||
{ |
||||
if (authorizationEnabled) |
||||
return; |
||||
authorizationEnabled = true; |
||||
|
||||
const int retryLimit = 3; |
||||
client.AddUsernameProvider(); |
||||
client.AddSimpleProvider(); |
||||
if (allowInteractiveAuthorization) { |
||||
client.AddPromptProvider(PasswordPrompt, IntPtr.Zero, retryLimit); |
||||
} |
||||
client.AddSslServerTrustFileProvider(); |
||||
if (allowInteractiveAuthorization) { |
||||
client.AddPromptProvider(SslServerTrustPrompt, IntPtr.Zero); |
||||
} |
||||
client.AddSslClientCertPwFileProvider(); |
||||
if (allowInteractiveAuthorization) { |
||||
client.AddPromptProvider(ClientCertificatePasswordPrompt, IntPtr.Zero, retryLimit); |
||||
} |
||||
client.AddSslClientCertFileProvider(); |
||||
if (allowInteractiveAuthorization) { |
||||
client.AddPromptProvider(ClientCertificatePrompt, IntPtr.Zero, retryLimit); |
||||
} |
||||
client.OpenAuth(); |
||||
} |
||||
|
||||
SvnError PasswordPrompt(out SvnAuthCredSimple cred, IntPtr baton, AprString realm, AprString username, bool maySave, AprPool pool) |
||||
{ |
||||
cred = IntPtr.Zero; |
||||
LoggingService.Debug("PasswordPrompt"); |
||||
try { |
||||
using (LoginDialog loginDialog = new LoginDialog(realm.Value, username.Value, maySave)) { |
||||
if (WorkbenchSingleton.SafeThreadFunction<Form, DialogResult>(loginDialog.ShowDialog, WorkbenchSingleton.MainForm) == DialogResult.OK) { |
||||
cred = loginDialog.CreateCredential(pool); |
||||
} |
||||
} |
||||
} catch (Exception ex) { |
||||
MessageService.ShowError(ex); |
||||
} |
||||
return SvnError.NoError; |
||||
} |
||||
|
||||
SvnError SslServerTrustPrompt(out SvnAuthCredSslServerTrust cred, IntPtr baton, AprString realm, SvnAuthCredSslServerTrust.CertFailures failures, SvnAuthSslServerCertInfo certInfo, bool maySave, IntPtr pool) |
||||
{ |
||||
cred = IntPtr.Zero; |
||||
LoggingService.Debug("SslServerTrustPrompt"); |
||||
try { |
||||
using (SslServerTrustDialog sslServerTrustDialog = new SslServerTrustDialog(certInfo, failures, maySave)) { |
||||
if (WorkbenchSingleton.SafeThreadFunction<Form, DialogResult>(sslServerTrustDialog.ShowDialog, WorkbenchSingleton.MainForm) == DialogResult.OK) { |
||||
cred = sslServerTrustDialog.CreateCredential(pool); |
||||
} |
||||
} |
||||
} catch (Exception ex) { |
||||
MessageService.ShowError(ex); |
||||
} |
||||
return SvnError.NoError; |
||||
} |
||||
|
||||
SvnError ClientCertificatePasswordPrompt(out SvnAuthCredSslClientCertPw cred, IntPtr baton, AprString realm, bool maySave, IntPtr pool) |
||||
{ |
||||
cred = IntPtr.Zero; |
||||
LoggingService.Debug("SslServerTrustPrompt"); |
||||
try { |
||||
using (ClientCertPassphraseDialog clientCertPassphraseDialog = new ClientCertPassphraseDialog(realm.Value, maySave)) { |
||||
if (WorkbenchSingleton.SafeThreadFunction<Form, DialogResult>(clientCertPassphraseDialog.ShowDialog, WorkbenchSingleton.MainForm) == DialogResult.OK) { |
||||
cred = clientCertPassphraseDialog.CreateCredential(pool); |
||||
} |
||||
} |
||||
} catch (Exception ex) { |
||||
MessageService.ShowError(ex); |
||||
} |
||||
return SvnError.NoError; |
||||
} |
||||
|
||||
SvnError ClientCertificatePrompt(out SvnAuthCredSslClientCert cred, IntPtr baton, AprString realm, bool maySave, IntPtr pool) |
||||
{ |
||||
cred = IntPtr.Zero; |
||||
LoggingService.Debug("SslServerTrustPrompt"); |
||||
try { |
||||
using (ClientCertDialog clientCertDialog = new ClientCertDialog(realm.Value, maySave)) { |
||||
if (WorkbenchSingleton.SafeThreadFunction<Form, DialogResult>(clientCertDialog.ShowDialog, WorkbenchSingleton.MainForm) == DialogResult.OK) { |
||||
cred = clientCertDialog.CreateCredential(pool); |
||||
} |
||||
} |
||||
} catch (Exception ex) { |
||||
MessageService.ShowError(ex); |
||||
} |
||||
return SvnError.NoError; |
||||
} |
||||
#endregion
|
||||
|
||||
[System.Diagnostics.ConditionalAttribute("DEBUG")] |
||||
void Debug(string text) |
||||
{ |
||||
LoggingService.Debug(text); |
||||
} |
||||
|
||||
void CheckNotDisposed() |
||||
{ |
||||
if (client == null) |
||||
throw new ObjectDisposedException("SvnClientWrapper"); |
||||
} |
||||
|
||||
void BeforeOperation() |
||||
{ |
||||
// before any subversion operation, ensure the object is not disposed
|
||||
// and register authorization if necessary
|
||||
CheckNotDisposed(); |
||||
OpenAuth(); |
||||
} |
||||
|
||||
void AfterOperation() |
||||
{ |
||||
// after any subversion operation, clear the memory pool
|
||||
client.Clear(); |
||||
} |
||||
|
||||
public void ClearStatusCache() |
||||
{ |
||||
CheckNotDisposed(); |
||||
statusCache.Clear(); |
||||
} |
||||
|
||||
public Status SingleStatus(string filename) |
||||
{ |
||||
Debug("SVN: SingleStatus(" + filename + ")"); |
||||
BeforeOperation(); |
||||
try { |
||||
filename = FileUtility.NormalizePath(filename); |
||||
Status result; |
||||
if (statusCache.TryGetValue(filename, out result)) { |
||||
Debug("SVN: SingleStatus retrieved from cache " + result.TextStatus); |
||||
return result; |
||||
} |
||||
client.Status2( |
||||
filename, Svn.Revision.Working, |
||||
delegate (IntPtr baton, SvnPath path, SvnWcStatus2 status) { |
||||
string dir = path.Value; |
||||
Debug("SVN: SingleStatus.callback(" + dir + "," + status.TextStatus + ")"); |
||||
Status s = new Status { |
||||
Copied = status.Copied, |
||||
TextStatus = ToStatusKind(status.TextStatus) |
||||
}; |
||||
statusCache[dir] = s; |
||||
if (StringComparer.InvariantCultureIgnoreCase.Equals(filename, dir)) { |
||||
result = s; |
||||
} |
||||
}, |
||||
IntPtr.Zero, |
||||
false, true, false, false, false |
||||
); |
||||
return result; |
||||
} catch (SvnException ex) { |
||||
throw new SvnClientException(ex); |
||||
} finally { |
||||
AfterOperation(); |
||||
} |
||||
} |
||||
|
||||
public void Add(string filename, Recurse recurse) |
||||
{ |
||||
Debug("SVN: Add(" + filename + ", " + recurse + ")"); |
||||
BeforeOperation(); |
||||
try { |
||||
client.Add3(filename, recurse == Recurse.Full, false, false); |
||||
} catch (SvnException ex) { |
||||
throw new SvnClientException(ex); |
||||
} finally { |
||||
AfterOperation(); |
||||
} |
||||
} |
||||
|
||||
public string GetPropertyValue(string fileName, string propertyName) |
||||
{ |
||||
Debug("SVN: GetPropertyValue(" + fileName + ", " + propertyName + ")"); |
||||
BeforeOperation(); |
||||
try { |
||||
AprHash hash = client.PropGet2(propertyName, fileName, |
||||
Svn.Revision.Working, Svn.Revision.Working, |
||||
false); |
||||
foreach (AprHashEntry entry in hash) { |
||||
// entry.ValueAsString treats the value as const char*, but it is a svn_string_t*
|
||||
SvnString value = entry.Value; |
||||
Debug("SVN: GetPropertyValue hash entry: (" + entry.KeyAsString + ", " + value + ")"); |
||||
return value.Data.Value; |
||||
} |
||||
Debug("SVN: GetPropertyValue did not find any entries"); |
||||
return null; |
||||
} catch (SvnException ex) { |
||||
throw new SvnClientException(ex); |
||||
} finally { |
||||
AfterOperation(); |
||||
} |
||||
} |
||||
|
||||
public void SetPropertyValue(string fileName, string propertyName, string newPropertyValue) |
||||
{ |
||||
Debug("SVN: SetPropertyValue(" + fileName + ", " + propertyName + ", " + newPropertyValue + ")"); |
||||
BeforeOperation(); |
||||
try { |
||||
SvnString npv; |
||||
if (newPropertyValue != null) |
||||
npv = new SvnString(newPropertyValue, client.Pool); |
||||
else |
||||
npv = IntPtr.Zero; |
||||
client.PropSet2(propertyName, npv, fileName, false, false); |
||||
} catch (SvnException ex) { |
||||
throw new SvnClientException(ex); |
||||
} finally { |
||||
AfterOperation(); |
||||
} |
||||
} |
||||
|
||||
SvnPath[] ToSvnPaths(string[] files) |
||||
{ |
||||
SvnPath[] paths = new SvnPath[files.Length]; |
||||
for (int i = 0; i < files.Length; i++) { |
||||
paths[i] = new SvnPath(files[i], client.Pool); |
||||
} |
||||
return paths; |
||||
} |
||||
|
||||
public void Delete(string[] files, bool force) |
||||
{ |
||||
Debug("SVN: Delete(" + string.Join(",", files) + ", " + force + ")"); |
||||
BeforeOperation(); |
||||
try { |
||||
client.Delete2(ToSvnPaths(files), force); |
||||
} catch (SvnException ex) { |
||||
throw new SvnClientException(ex); |
||||
} finally { |
||||
AfterOperation(); |
||||
} |
||||
} |
||||
|
||||
public void Revert(string[] files, Recurse recurse) |
||||
{ |
||||
Debug("SVN: Revert(" + string.Join(",", files) + ", " + recurse + ")"); |
||||
BeforeOperation(); |
||||
try { |
||||
client.Revert(ToSvnPaths(files), recurse == Recurse.Full); |
||||
} catch (SvnException ex) { |
||||
throw new SvnClientException(ex); |
||||
} finally { |
||||
AfterOperation(); |
||||
} |
||||
} |
||||
|
||||
public void Move(string from, string to, bool force) |
||||
{ |
||||
Debug("SVN: Move(" + from + ", " + to + ", " + force + ")"); |
||||
BeforeOperation(); |
||||
try { |
||||
client.Move3(from, to, force); |
||||
} catch (SvnException ex) { |
||||
throw new SvnClientException(ex); |
||||
} finally { |
||||
AfterOperation(); |
||||
} |
||||
} |
||||
|
||||
public void AddToIgnoreList(string directory, params string[] filesToIgnore) |
||||
{ |
||||
Debug("SVN: AddToIgnoreList(" + directory + ", " + string.Join(",", filesToIgnore) + ")"); |
||||
string propertyValue = GetPropertyValue(directory, "svn:ignore"); |
||||
StringBuilder b = new StringBuilder(); |
||||
if (propertyValue != null) { |
||||
using (StringReader r = new StringReader(propertyValue)) { |
||||
string line; |
||||
while ((line = r.ReadLine()) != null) { |
||||
if (line.Length > 0) { |
||||
b.AppendLine(line); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
foreach (string file in filesToIgnore) |
||||
b.AppendLine(file); |
||||
SetPropertyValue(directory, "svn:ignore", b.ToString()); |
||||
} |
||||
|
||||
public void Log(string[] paths, Revision start, Revision end, |
||||
int limit, bool discoverChangePaths, bool strictNodeHistory, |
||||
Action<LogMessage> logMessageReceiver) |
||||
{ |
||||
Debug("SVN: Log({" + string.Join(",", paths) + "}, " + start + ", " + end + |
||||
", " + limit + ", " + discoverChangePaths + ", " + strictNodeHistory + ")"); |
||||
BeforeOperation(); |
||||
try { |
||||
client.Log2( |
||||
ToSvnPaths(paths), |
||||
start, end, limit, discoverChangePaths, strictNodeHistory, |
||||
delegate (IntPtr baton, AprHash changed_paths, int revision, AprString author, AprString date, AprString message, AprPool pool) { |
||||
Debug("SVN: Log: Got revision " + revision); |
||||
DateTime dateTime = DateTime.MinValue; |
||||
DateTime.TryParse(date.Value, out dateTime); |
||||
LogMessage msg = new LogMessage() { |
||||
Revision = revision, |
||||
Author = author.Value, |
||||
Date = dateTime, |
||||
Message = message.Value |
||||
}; |
||||
if (discoverChangePaths) { |
||||
msg.ChangedPaths = new List<ChangedPath>(); |
||||
foreach (AprHashEntry entry in changed_paths) { |
||||
SvnLogChangedPath changedPath = entry.Value; |
||||
msg.ChangedPaths.Add(new ChangedPath { |
||||
Path = entry.KeyAsString, |
||||
CopyFromPath = changedPath.CopyFromPath.Value, |
||||
CopyFromRevision = changedPath.CopyFromRev, |
||||
Action = changedPath.Action |
||||
}); |
||||
} |
||||
} |
||||
logMessageReceiver(msg); |
||||
return SvnError.NoError; |
||||
}, |
||||
IntPtr.Zero |
||||
); |
||||
Debug("SVN: Log finished"); |
||||
} catch (SvnException ex) { |
||||
throw new SvnClientException(ex); |
||||
} finally { |
||||
AfterOperation(); |
||||
} |
||||
} |
||||
|
||||
static StatusKind ToStatusKind(SvnWcStatus.Kind kind) |
||||
{ |
||||
switch (kind) { |
||||
case SvnWcStatus.Kind.Added: |
||||
return StatusKind.Added; |
||||
case SvnWcStatus.Kind.Conflicted: |
||||
return StatusKind.Conflicted; |
||||
case SvnWcStatus.Kind.Deleted: |
||||
return StatusKind.Deleted; |
||||
case SvnWcStatus.Kind.External: |
||||
return StatusKind.External; |
||||
case SvnWcStatus.Kind.Ignored: |
||||
return StatusKind.Ignored; |
||||
case SvnWcStatus.Kind.Incomplete: |
||||
return StatusKind.Incomplete; |
||||
case SvnWcStatus.Kind.Merged: |
||||
return StatusKind.Merged; |
||||
case SvnWcStatus.Kind.Missing: |
||||
return StatusKind.Missing; |
||||
case SvnWcStatus.Kind.Modified: |
||||
return StatusKind.Modified; |
||||
case SvnWcStatus.Kind.Normal: |
||||
return StatusKind.Normal; |
||||
case SvnWcStatus.Kind.Obstructed: |
||||
return StatusKind.Obstructed; |
||||
case SvnWcStatus.Kind.Replaced: |
||||
return StatusKind.Replaced; |
||||
case SvnWcStatus.Kind.Unversioned: |
||||
return StatusKind.Unversioned; |
||||
default: |
||||
return StatusKind.None; |
||||
} |
||||
} |
||||
} |
||||
|
||||
public class LogMessage |
||||
{ |
||||
public int Revision; |
||||
public string Author; |
||||
public DateTime Date; |
||||
public string Message; |
||||
|
||||
public List<ChangedPath> ChangedPaths; |
||||
} |
||||
|
||||
public class ChangedPath |
||||
{ |
||||
public string Path; |
||||
public string CopyFromPath; |
||||
public int CopyFromRevision; |
||||
/// <summary>
|
||||
/// change action ('A','D','R' or 'M')
|
||||
/// </summary>
|
||||
public char Action; |
||||
} |
||||
|
||||
public class Revision |
||||
{ |
||||
SvnRevision revision; |
||||
|
||||
public static readonly Revision Base = new SvnRevision(Svn.Revision.Base); |
||||
public static readonly Revision Committed = new SvnRevision(Svn.Revision.Committed); |
||||
public static readonly Revision Head = new SvnRevision(Svn.Revision.Head); |
||||
public static readonly Revision Working = new SvnRevision(Svn.Revision.Working); |
||||
public static readonly Revision Unspecified = new SvnRevision(Svn.Revision.Unspecified); |
||||
|
||||
public static Revision FromNumber(int number) |
||||
{ |
||||
return new SvnRevision(number); |
||||
} |
||||
|
||||
public static implicit operator SvnRevision(Revision r) |
||||
{ |
||||
return r.revision; |
||||
} |
||||
|
||||
public static implicit operator Revision(SvnRevision r) |
||||
{ |
||||
return new Revision() { revision = r }; |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
switch (revision.Kind) { |
||||
case Svn.Revision.Base: |
||||
return "base"; |
||||
case Svn.Revision.Committed: |
||||
return "committed"; |
||||
case Svn.Revision.Date: |
||||
return AprTime.ToDateTime(revision.Date).ToString(); |
||||
case Svn.Revision.Head: |
||||
return "head"; |
||||
case Svn.Revision.Number: |
||||
return revision.Number.ToString(); |
||||
case Svn.Revision.Previous: |
||||
return "previous"; |
||||
case Svn.Revision.Unspecified: |
||||
return "unspecified"; |
||||
case Svn.Revision.Working: |
||||
return "working"; |
||||
default: |
||||
return "unknown"; |
||||
} |
||||
} |
||||
} |
||||
|
||||
public class Status |
||||
{ |
||||
public bool Copied { get; set; } |
||||
public StatusKind TextStatus { get; set; } |
||||
} |
||||
|
||||
public enum Recurse |
||||
{ |
||||
None, |
||||
Full |
||||
} |
||||
|
||||
public class SvnClientException : Exception |
||||
{ |
||||
public readonly int ErrorCode; |
||||
|
||||
internal SvnClientException(SvnException ex) : base(ex.Message, ex) |
||||
{ |
||||
LoggingService.Debug(ex); |
||||
ErrorCode = ex.AprErr; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the inner exception of the exception being wrapped.
|
||||
/// </summary>
|
||||
public Exception GetInnerException() |
||||
{ |
||||
return InnerException.InnerException; |
||||
} |
||||
} |
||||
|
||||
public enum StatusKind |
||||
{ |
||||
None, |
||||
Added, |
||||
Conflicted, |
||||
Deleted, |
||||
Modified, |
||||
Replaced, |
||||
External, |
||||
Ignored, |
||||
Incomplete, |
||||
Merged, |
||||
Missing, |
||||
Obstructed, |
||||
Normal, |
||||
Unversioned |
||||
} |
||||
} |
||||
@ -1,15 +0,0 @@
@@ -1,15 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> |
||||
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> |
||||
<description>Updates the assembly version in GlobalAssemblyInfo.cs</description> |
||||
|
||||
<!-- required because Vista otherwise thinks UpdateAssemblyInfo requires admin rights --> |
||||
<!-- because it contains the word "Update" --> |
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> |
||||
<security> |
||||
<requestedPrivileges> |
||||
<requestedExecutionLevel level="asInvoker" uiAccess="false"/> |
||||
</requestedPrivileges> |
||||
</security> |
||||
</trustInfo> |
||||
</assembly> |
||||
@ -0,0 +1,21 @@
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> |
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> |
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"> |
||||
<security> |
||||
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3"> |
||||
<!-- |
||||
The presence of the "requestedExecutionLevel" node will disable |
||||
file and registry virtualization on Vista. |
||||
|
||||
Use the "level" attribute to specify the User Account Control level: |
||||
asInvoker = Never prompt for elevation |
||||
requireAdministrator = Always prompt for elevation |
||||
highestAvailable = Prompt for elevation when started by administrator, |
||||
but do not prompt for administrator password when started by |
||||
standard user. |
||||
--> |
||||
<requestedExecutionLevel level="asInvoker"/> |
||||
</requestedPrivileges> |
||||
</security> |
||||
</trustInfo> |
||||
</assembly> |
||||
Loading…
Reference in new issue