show the difference between two versions for a specified path
[tfs.git] / tools / opentf / Command.cs
bloba6582cdd9154692ea2edcb0a02d3f500833b7953
1 //
2 // Command.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.IO;
31 using System.Text;
32 using System.Text.RegularExpressions;
33 using System.Collections.Generic;
34 using Microsoft.TeamFoundation.Client;
35 using Microsoft.TeamFoundation.VersionControl.Client;
36 using Microsoft.TeamFoundation.VersionControl.Common;
37 using OpenTF.Common;
39 abstract class Command : CommandOptions
41 private static bool runningOnUnix = true;
42 private string[] arguments;
43 private Driver driver;
44 private static Regex fileExcludes;
45 private static Regex dirExcludes;
47 public bool RunningOnUnix
49 get { return runningOnUnix; }
52 public Driver Driver
54 get { return driver; }
57 public string[] Arguments
59 get { return arguments; }
62 static Command()
64 int p = (int) Environment.OSVersion.Platform;
65 if (!((p == 4) || (p == 128))) runningOnUnix = false;
67 ReadFileExcludes();
70 public static StringComparer PathComparer
72 get {
73 if (!runningOnUnix) return StringComparer.CurrentCultureIgnoreCase;
74 return StringComparer.CurrentCulture;
78 public Command(Driver driver, string[] args)
80 this.driver = driver;
81 ProcessArgs(args);
82 this.arguments = RemainingArguments;
85 public Workspace GetWorkspaceFromServer()
87 string name = OptionWorkspace;
89 // if option passed use it
90 if (String.IsNullOrEmpty(name))
92 // guess based on current working directory
93 WorkspaceInfo info = Workstation.Current.GetLocalWorkspaceInfo(Environment.CurrentDirectory);
94 if (info != null) name = info.Name;
97 if (String.IsNullOrEmpty(name))
98 name = Settings.Current.Get("Workspace.Default");
100 if (String.IsNullOrEmpty(name))
102 Console.WriteLine("Unable to determine the workspace");
103 Console.WriteLine(" hint: try adding /workspace:<name>");
104 Environment.Exit((int)ExitCode.Failure);
107 return VersionControlServer.GetWorkspace(name, Driver.Username);
110 public WorkspaceInfo GetWorkspaceInfoFromCache()
112 string path = Environment.CurrentDirectory;
113 if (Arguments.Length > 0)
115 path = Path.GetFullPath(Arguments[0]);
118 WorkspaceInfo info = Workstation.Current.GetLocalWorkspaceInfo(path);
119 if (info != null) return info;
121 if (String.IsNullOrEmpty(OptionWorkspace))
122 OptionWorkspace = Settings.Current.Get("Workspace.Default");
124 if (String.IsNullOrEmpty(OptionWorkspace))
126 Console.WriteLine("Unable to determine the workspace.");
127 Console.WriteLine(" Path: " + path);
128 return null;
131 string ownerName = String.Format("{0}\\{1}", Driver.Domain, Driver.Username).ToUpper();
132 info = Workstation.Current.GetLocalWorkspaceInfo(Driver.VersionControlServer,
133 OptionWorkspace, ownerName);
135 if (info == null)
137 Console.WriteLine("Unable to determine the workspace.");
138 Console.WriteLine(" Workspace Name: " + OptionWorkspace);
139 Console.WriteLine(" Workspace Owner: " + ownerName);
142 return info;
145 public Workspace GetWorkspaceFromCache()
147 WorkspaceInfo info = GetWorkspaceInfoFromCache();
149 if (info == null)
151 Console.WriteLine();
152 Console.WriteLine("Hints:");
153 Console.WriteLine(" Try adding /workspace:<name>");
154 Console.WriteLine(" Review command options prefixed with '/'. Invalid options are mistaken for paths.");
155 Environment.Exit((int)ExitCode.Failure);
158 return VersionControlServer.GetWorkspace(info);
161 public VersionSpec VersionFromString(string version)
163 if (!String.IsNullOrEmpty(version))
164 return VersionSpec.ParseSingleSpec(version, Driver.Username);
165 else
166 return VersionSpec.Latest;
169 static public string ChangeTypeToString(ChangeType change)
171 string ctype = "edit";
173 if ((change & ChangeType.Add) == ChangeType.Add) ctype = "add";
174 else if ((change & ChangeType.Delete) == ChangeType.Delete) ctype = "delete";
175 else if ((change & ChangeType.Rename) == ChangeType.Rename) ctype = "rename";
177 return ctype;
180 public int WindowWidth
182 get {
183 // if output piped to a file, we don't want 0!
184 // this also throws on weird terminals on msclr
187 int w = Console.WindowWidth;
188 if (w != 0) return w - 1;
190 catch (IOException) {}
191 return 143;
195 public string OwnerFromString(string owner)
197 if (String.IsNullOrEmpty(owner)) return Driver.Username;
198 if (owner == "*") return null;
199 return owner;
202 public VersionControlServer VersionControlServer
204 get { return Driver.VersionControlServer; }
207 public List<string> UnVerifiedFullPaths(string[] args)
209 List<string> paths = new List<string>();
210 for (int i = 0; i < args.Length; i++)
212 string fullPath = Path.GetFullPath(args[i]);
213 paths.Add(fullPath);
216 return paths;
219 public List<string> VerifiedFullPaths(string[] args)
221 List<string> paths = UnVerifiedFullPaths(args);
222 char[] wildcards = { '*', '?' };
224 foreach (string path in paths)
226 // skip wildcarded paths
227 if (-1 != path.IndexOfAny(wildcards)) continue;
229 if (!File.Exists(path) && !Directory.Exists(path))
231 Console.WriteLine("{0}: No such file or directory.", path);
232 Environment.Exit((int)ExitCode.Failure);
236 return paths;
239 public void DeleteReadOnlyFile(string fullName)
241 File.SetAttributes(fullName, FileAttributes.Normal);
242 File.Delete(fullName);
245 static public void ReadFileExcludes()
247 string exclusionList = Settings.Current.Get("File.Excludes");
248 if (String.IsNullOrEmpty(exclusionList)) return;
250 string separatorChar = Path.DirectorySeparatorChar.ToString();
251 string[] wildcards = exclusionList.Split(',');
253 StringBuilder dirRegexs = new StringBuilder();
254 StringBuilder fileRegexs = new StringBuilder();
256 foreach (string wildcard in wildcards)
258 if (-1 == wildcard.IndexOf(separatorChar))
260 if (0 != fileRegexs.Length) fileRegexs.Append("|");
262 fileRegexs.Append("^");
263 fileRegexs.Append(Regex.Escape(wildcard).Replace("\\*", ".*").Replace("\\?", "."));
264 fileRegexs.Append("$");
266 else
268 if (0 != dirRegexs.Length) dirRegexs.Append("|");
270 dirRegexs.Append("^.*");
271 dirRegexs.Append(Regex.Escape(wildcard));
272 dirRegexs.Append(".*$");
276 if (0 != fileRegexs.Length)
277 fileExcludes = new Regex(fileRegexs.ToString());
279 if (0 != dirRegexs.Length)
280 dirExcludes = new Regex(dirRegexs.ToString());
283 public bool IsExcludedFile(string path)
285 if ((fileExcludes != null) &&
286 (fileExcludes.IsMatch(Path.GetFileName(path))))
287 return true;
289 if ((dirExcludes != null) && (dirExcludes.IsMatch(path)))
290 return true;
292 return false;
295 public void ConfirmFilesSpecified()
297 if (Arguments.Length < 1)
299 Console.WriteLine("No files specified.");
300 Environment.Exit((int)ExitCode.Failure);
304 public string CanonicalPath(string p)
306 return p;
307 // maybe this feature is only interesting to me?
308 //if (runningOnUnix) return p;
309 //return p.Replace('\\', '/');
312 public abstract void Run ();