show the difference between two versions for a specified path
[tfs.git] / tools / opentf / Driver.cs
blobbb57b0780cff3f4e078d4aca84f849564a8d8651
1 //
2 // Driver.cs
3 //
4 // Authors:
5 // Joel Reed (joelwreed@gmail.com)
6 //
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 using System;
30 using System.Reflection;
31 using System.Collections.Generic;
32 using System.Collections.Specialized;
33 using System.Net;
34 using System.IO;
35 using System.Text;
36 using System.Net.Security;
37 using System.Security.Cryptography.X509Certificates;
38 using Mono.GetOptions;
39 using Microsoft.TeamFoundation;
40 using Microsoft.TeamFoundation.Client;
41 using Microsoft.TeamFoundation.VersionControl.Client;
42 using Microsoft.TeamFoundation.Server;
43 using OpenTF.Common;
45 [assembly: AssemblyTitle ("tf.exe")]
46 [assembly: AssemblyVersion ("0.6.0")]
47 [assembly: AssemblyDescription ("Team Foundation Source Control Tool")]
48 [assembly: AssemblyCopyright ("(c) Joel W. Reed")]
50 [assembly: Mono.UsageComplement ("")]
52 [assembly: Mono.About("Team Foundation Source Control Tool")]
53 [assembly: Mono.Author ("Joel W. Reed")]
55 public partial class Driver : ICertificatePolicy, ICredentialsProvider
57 private TeamFoundationServer _tfs;
58 private VersionControlServer _versionControl;
59 private DriverOptions Options = new DriverOptions();
60 private string[] Arguments;
62 private CredentialCache credentialCache = new CredentialCache();
63 private List<string> outputBuffer = null;
65 public void Write(string x)
67 if (outputBuffer != null) outputBuffer.Add(x);
68 else Console.Write(x);
71 public void WriteLine(string x)
73 if (outputBuffer != null) outputBuffer.Add(x);
74 else Console.WriteLine(x);
77 public void WriteLine()
79 Console.WriteLine();
82 public string Username
84 get {
85 string serverUrl = GetServerUrl();
86 NetworkCredential creds = credentialCache.GetCredential(new Uri(serverUrl), "NTLM");
87 if (creds == null) return String.Empty;
88 return creds.UserName;
92 public string Domain
94 get {
95 string serverUrl = GetServerUrl();
96 NetworkCredential creds = credentialCache.GetCredential(new Uri(serverUrl), "NTLM");
97 if (creds == null) return String.Empty;
98 return creds.Domain;
102 private string ServerNameToUrl(string server)
104 if (server.StartsWith("http://") || server.StartsWith("https://"))
105 return server;
106 else
107 return String.Format("http://{0}:8080/", server);
110 public string GetServerUrl()
112 if (!String.IsNullOrEmpty(Options.Server))
113 return ServerNameToUrl(Options.Server);
115 WorkspaceInfo info = Workstation.Current.GetLocalWorkspaceInfo(Environment.CurrentDirectory);
116 if (info == null)
118 string server = Settings.Current.Get("Server.Default");
119 if (!String.IsNullOrEmpty(server))
120 return ServerNameToUrl(server);
122 Console.WriteLine("Unable to determine the team foundation server");
123 Console.WriteLine(" hint: try adding /server:<ip|name>");
124 Environment.Exit((int)ExitCode.Failure);
127 return info.ServerUri.ToString();
130 private string GetLogin(string url)
132 if (!String.IsNullOrEmpty(Options.Login))
133 return Options.Login;
135 // check the keyring
136 string login = Keyring.GetCredentials(url);
137 if (!String.IsNullOrEmpty(login)) return login;
139 // finally prompt if permitted
140 if (Options.NoPrompt) return String.Empty;
141 return PromptForLogin(url);
144 public TeamFoundationServer TeamFoundationServer
146 get
148 if (null != _tfs) return _tfs;
150 string url = GetServerUrl();
151 ICredentials credentials = GetCredentials(new Uri(url), null);
152 _tfs = new TeamFoundationServer(url, credentials);
154 return _tfs;
158 // ICredentialsProvider method
159 public ICredentials GetCredentials(Uri uri, ICredentials failedCredentials)
161 NetworkCredential creds = credentialCache.GetCredential(uri, "NTLM");
162 if (creds != null) return creds;
164 string url = uri.ToString();
165 string login = GetLogin(url);
167 if (String.IsNullOrEmpty(login)) return null;
168 creds = new TFCredential(login);
170 if (!(String.IsNullOrEmpty(creds.UserName)) &&
171 String.IsNullOrEmpty(creds.Password) && !Options.NoPrompt)
173 Console.Write("Password: ");
174 creds.Password = Console.ReadLine();
177 // save credentials if passed
178 bool saveSetting = Settings.Current.GetAsBool("Credentials.Save");
179 if (saveSetting && !String.IsNullOrEmpty(Options.Login))
180 Keyring.SetCredentials(url, creds.Domain, creds.UserName, creds.Password);
182 credentialCache.Add(uri, "NTLM", creds);
183 return creds;
186 // ICredentialsProvider method
187 public void NotifyCredentialsAuthenticated (Uri uri)
191 public VersionControlServer VersionControlServer
193 get
195 if (null != _versionControl) return _versionControl;
196 _versionControl = (VersionControlServer) TeamFoundationServer.GetService(typeof(VersionControlServer));
198 _versionControl.Conflict += ConflictEventHandler;
199 _versionControl.NonFatalError += ExceptionEventHandler;
201 return _versionControl;
205 public Driver(string[] args)
207 Arguments = args;
208 Options.ProcessArgs(args);
211 static void ConflictEventHandler(Object sender, ConflictEventArgs e)
213 Console.Error.WriteLine(e.Message);
216 static void ExceptionEventHandler(Object sender, ExceptionEventArgs e)
218 // sometimes e.Failure is null, not sure why yet
219 if (e.Failure != null)
220 Console.Error.WriteLine(e.Failure.Message);
223 private bool IsOption(string arg)
225 if (String.IsNullOrEmpty(arg)) return false;
226 return (arg[0] == '-' || arg[0] == '/');
229 public void ProcessAllCommands()
231 List<string> cmdArgs = new List<string>();
233 for (int i=0; i < Arguments.Length; i++)
235 // a little padding between chained command output
236 if (i > 0) Console.WriteLine();
238 // unknown options are not sub commands
239 string scmd = Arguments[i].ToLower();
240 if (IsOption(scmd))
242 cmdArgs.Add(scmd);
243 continue;
246 if (outputBuffer != null)
248 foreach (string line in outputBuffer)
249 cmdArgs.Add(line);
250 outputBuffer = null;
253 // pull in the rest of the args for this subcommand
254 int j;
255 for (j=i+1; j < Arguments.Length; j++)
257 string arg = Arguments[j];
259 // command chaining options
260 if (arg == "%") break;
261 if (arg == "%%")
263 // buffered output across command chain
264 outputBuffer = new List<string>();
265 break;
268 // read more args from stdin
269 if (arg == "-")
271 string line;
272 if (Console.In.Peek() != -1)
274 while ( (line = Console.ReadLine()) != null )
275 cmdArgs.Add(line);
278 continue;
281 cmdArgs.Add(arg);
284 ProcessCommand(scmd, cmdArgs.ToArray());
285 cmdArgs.Clear();
286 i = j;
290 public void ProcessCommand(string cmd, string[] cmdArgs)
292 Type commandType = CommandRegistry.GetCommandType(cmd);
293 if (commandType == null)
295 Console.WriteLine("Unknown command: " + cmd);
296 Environment.Exit((int)ExitCode.UnrecognizedCommand);
299 Command command = (Command) Activator.CreateInstance(commandType, new object[]{ this, cmdArgs });
300 command.Run();
303 // ignoring certificate errors
304 public bool CheckValidationResult (ServicePoint sp,
305 X509Certificate certificate, WebRequest request,
306 int error)
308 return true;
311 public static void Main(string[] args)
313 Driver driver = new Driver(args);
314 ServicePointManager.CertificatePolicy = driver;
316 if (args.Length == 0) {
317 HelpCommand cmd = new HelpCommand(driver, args);
318 cmd.Run();
319 return;
322 // basic auth doesn't seem to work well on mono when POSTing
323 // large data sets via a webservice.
324 AuthenticationManager.Unregister("Basic");
328 driver.ProcessAllCommands();
329 Environment.Exit((int)ExitCode.Success);
331 catch (TeamFoundationServerException e)
333 Console.Error.WriteLine(e.Message);