5 // Joel Reed (joelwreed@gmail.com)
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:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
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.
30 using System
.Reflection
;
31 using System
.Collections
.Generic
;
32 using System
.Collections
.Specialized
;
36 using System
.Security
.Cryptography
.X509Certificates
;
37 using Mono
.GetOptions
;
38 using Microsoft
.TeamFoundation
;
39 using Microsoft
.TeamFoundation
.Client
;
40 using Microsoft
.TeamFoundation
.VersionControl
.Client
;
41 using Microsoft
.TeamFoundation
.Server
;
43 [assembly
: AssemblyTitle ("tf.exe")]
44 [assembly
: AssemblyVersion ("1.0")]
45 [assembly
: AssemblyDescription ("Team Foundation Source Control Tool")]
46 [assembly
: AssemblyCopyright ("(c) Joel W. Reed")]
48 [assembly
: Mono
.UsageComplement ("")]
50 [assembly
: Mono
.About("Team Foundation Source Control Tool")]
51 [assembly
: Mono
.Author ("Joel W. Reed")]
53 partial class Driver
: ICertificatePolicy
55 private TeamFoundationServer _tfs
;
56 private VersionControlServer _versionControl
;
57 private TfOptions Options
;
58 private string[] Commands
;
60 public Driver(TfOptions options
, string[] commands
)
66 static void ConflictEventHandler(Object sender
, ConflictEventArgs e
)
68 Console
.Error
.WriteLine(e
.Message
);
71 static void ExceptionEventHandler(Object sender
, ExceptionEventArgs e
)
73 Console
.Error
.WriteLine(e
.Failure
.Message
);
76 public VersionControlServer
ConnectToServer()
78 if (null != _versionControl
) return _versionControl
;
79 string server
= GetServerUrl();
80 string login
= GetLogin(server
);
85 int comma
= login
.IndexOf(",");
88 userinfo
= login
.Substring(0, comma
);
89 pwd
= login
.Substring(comma
+1);
94 Console
.Write("Password: ");
95 pwd
= Console
.ReadLine();
98 int slash
= userinfo
.IndexOf('\\');
99 if (-1 == slash
) Options
.Username
= userinfo
;
102 Options
.Domain
= userinfo
.Substring(0, slash
);
103 Options
.Username
= userinfo
.Substring(slash
+1);
106 _tfs
= new TeamFoundationServer(server
, new NetworkCredential(Options
.Username
, pwd
, Options
.Domain
));
107 _versionControl
= (VersionControlServer
) _tfs
.GetService(typeof(VersionControlServer
));
109 _versionControl
.Conflict
+= ConflictEventHandler
;
110 _versionControl
.NonFatalError
+= ExceptionEventHandler
;
112 // save credentials if passed
113 bool saveSetting
= Settings
.Current
.GetAsBool("Credentials.Save");
114 if (saveSetting
&& !String
.IsNullOrEmpty(Options
.Login
))
115 TfsKeyring
.SetCredentials(server
, Options
.Domain
, Options
.Username
, pwd
);
117 return _versionControl
;
120 static public void ShowHelp()
122 Console
.WriteLine("usage: tf [subcommand] [arguments]");
124 Console
.WriteLine("Available subcommands:");
126 Console
.WriteLine(" add");
127 Console
.WriteLine(" cache");
128 Console
.WriteLine(" changeset");
129 Console
.WriteLine(" checkin");
130 Console
.WriteLine(" checkout (alias edit)");
131 Console
.WriteLine(" configure (alias config)");
132 Console
.WriteLine(" delete");
133 Console
.WriteLine(" diff");
134 Console
.WriteLine(" dir");
135 Console
.WriteLine(" get");
136 Console
.WriteLine(" history");
137 Console
.WriteLine(" labels");
138 Console
.WriteLine(" ls-files");
139 Console
.WriteLine(" online");
140 Console
.WriteLine(" permission");
141 Console
.WriteLine(" properties");
142 Console
.WriteLine(" rename");
143 Console
.WriteLine(" status");
144 Console
.WriteLine(" treeclean");
145 Console
.WriteLine(" undo");
146 Console
.WriteLine(" view");
147 Console
.WriteLine(" workfold");
148 Console
.WriteLine(" workspace");
149 Console
.WriteLine(" workspaces");
152 public void ProcessBranch() {}
153 public void ProcessBranches() {}
154 public void ProcessDifference() {}
155 public void ProcessLock() {}
156 public void ProcessMerge() {}
157 public void ProcessMerges() {}
158 public void ProcessResolve() {}
159 public void ProcessShelve() {}
160 public void ProcessShelvesets() {}
161 public void ProcessUndelete() {}
162 public void ProcessUnlabel() {}
163 public void ProcessUnshelve() {}
165 public void ProcessAllCommands()
167 // some commands don't need to connect to TFS server
168 string firstCmd
= Commands
[0].ToLower();
174 cmd
= new CacheCommand(Commands
, Options
);
178 cmd
= new ConfigureCommand(Commands
, Options
);
192 VersionControlServer vcs
= ConnectToServer();
194 for (int i
=0; i
< Commands
.Length
; i
++)
196 string scmd
= Commands
[i
].ToLower();
197 List
<string> cmdArgs
= new List
<string>();
201 for (j
=i
+1; j
< Commands
.Length
; j
++)
203 string arg
= Commands
[j
];
204 if (arg
== "%") break;
208 ProcessCommand(vcs
, scmd
, cmdArgs
.ToArray());
213 public void ProcessCommand(VersionControlServer vcs
, string cmd
,
216 Command command
= null;
221 command
= new AddCommand(cmdArgs
, Options
, vcs
);
230 command
= new ChangesetCommand(cmdArgs
, Options
, vcs
);
233 command
= new CheckinCommand(cmdArgs
, Options
, vcs
);
236 command
= new CheckoutCommand(cmdArgs
, Options
, vcs
);
238 case "edit": // command alias
239 command
= new CheckoutCommand(cmdArgs
, Options
, vcs
);
241 case "del": // command alias
242 command
= new DeleteCommand(cmdArgs
, Options
, vcs
);
245 command
= new DeleteCommand(cmdArgs
, Options
, vcs
);
247 case "diff": // command alias
248 command
= new DiffCommand(cmdArgs
, Options
, vcs
);
251 command
= new DiffCommand(cmdArgs
, Options
, vcs
);
254 command
= new DirCommand(cmdArgs
, Options
, vcs
);
257 command
= new GetCommand(cmdArgs
, Options
, vcs
);
262 case "hist": // command alias
263 command
= new HistoryCommand(cmdArgs
, Options
, vcs
);
266 command
= new HistoryCommand(cmdArgs
, Options
, vcs
);
269 command
= new LabelCommand(cmdArgs
, Options
, vcs
);
272 command
= new LabelsCommand(cmdArgs
, Options
, vcs
);
278 command
= new LsFilesCommand(cmdArgs
, Options
, vcs
);
281 command
= new OnlineCommand(cmdArgs
, Options
, vcs
);
290 command
= new RenameCommand(cmdArgs
, Options
, vcs
);
293 command
= new PermissionCommand(cmdArgs
, Options
, vcs
);
296 command
= new PermissionCommand(cmdArgs
, Options
, vcs
);
299 command
= new PropertiesCommand(cmdArgs
, Options
, vcs
);
302 command
= new PropertiesCommand(cmdArgs
, Options
, vcs
);
305 command
= new RenameCommand(cmdArgs
, Options
, vcs
);
308 command
= new RenameCommand(cmdArgs
, Options
, vcs
);
320 command
= new StatusCommand(cmdArgs
, Options
, vcs
);
323 command
= new StatusCommand(cmdArgs
, Options
, vcs
);
326 command
= new TreeCleanCommand(cmdArgs
, Options
, vcs
);
329 command
= new TreeDiffCommand(cmdArgs
, Options
, vcs
);
331 case "undel": // alias for undelete
338 command
= new UndoCommand(cmdArgs
, Options
, vcs
);
341 command
= new UnlabelCommand(cmdArgs
, Options
, vcs
);
347 command
= new ViewCommand(cmdArgs
, Options
, vcs
);
350 command
= new WorkfoldCommand(cmdArgs
, Options
, vcs
);
353 command
= new WorkspaceCommand(cmdArgs
, Options
, vcs
);
356 command
= new WorkspacesCommand(cmdArgs
, Options
, vcs
);
359 Console
.WriteLine("Unknown command: " + cmd
);
363 if (command
!= null) command
.Run();
366 public string GetServerUrl()
368 if (!String
.IsNullOrEmpty(Options
.Server
))
370 if (Options
.Server
.StartsWith("http://") || Options
.Server
.StartsWith("https://"))
371 return Options
.Server
;
373 return String
.Format("http://{0}:8080/", Options
.Server
);
376 WorkspaceInfo info
= Workstation
.Current
.GetLocalWorkspaceInfo(Environment
.CurrentDirectory
);
379 Console
.WriteLine("Unable to determine the team foundation server");
380 Console
.WriteLine(" hint: try adding /server:<ip|name>");
384 return info
.ServerUri
.ToString();
387 public string GetLogin(string server
)
389 if (!String
.IsNullOrEmpty(Options
.Login
))
390 return Options
.Login
;
393 string login
= TfsKeyring
.GetCredentials(server
);
394 if (!String
.IsNullOrEmpty(login
)) return login
;
397 return PromptForLogin();
400 public VersionControlServer VersionControlServer
402 get { return _versionControl; }
405 // ignoring certificate errors
406 public bool CheckValidationResult (ServicePoint sp
,
407 X509Certificate certificate
, WebRequest request
, int error
)
412 public static void Main(string[] args
)
414 if (args
.Length
== 0) {
419 TfOptions options
= new TfOptions();
420 options
.ProcessArgs(args
);
422 Driver driver
= new Driver(options
, options
.RemainingArguments
);
423 ServicePointManager
.CertificatePolicy
= driver
;
425 // basic auth doesn't seem to work well on mono when POSTing
426 // large data sets via a webservice.
427 AuthenticationManager
.Unregister("Basic");
431 driver
.ProcessAllCommands();
433 catch (TeamFoundationServerException e
)
435 Console
.Error
.WriteLine(e
.Message
);
436 // Console.WriteLine(options.Domain + "\\" + options.Username);