note.invalid.version.spec
[tfs.git] / tools / opentf / Command.cs
blob5b1e2fba215a8fa9ee59825711504b7c7c48e405
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))
165 VersionSpec spec = VersionSpec.ParseSingleSpec(version, Driver.Username);
166 if (spec == null)
168 Console.WriteLine("Error: Invalid version specification.");
169 Environment.Exit((int)ExitCode.Failure);
171 return spec;
173 else
174 return VersionSpec.Latest;
177 static public string ChangeTypeToString(ChangeType change)
179 string ctype = "edit";
181 if ((change & ChangeType.Add) == ChangeType.Add) ctype = "add";
182 else if ((change & ChangeType.Delete) == ChangeType.Delete) ctype = "delete";
183 else if ((change & ChangeType.Rename) == ChangeType.Rename) ctype = "rename";
185 return ctype;
188 public int WindowWidth
190 get {
191 // if output piped to a file, we don't want 0!
192 // this also throws on weird terminals on msclr
195 int w = Console.WindowWidth;
196 if (w != 0) return w - 1;
198 catch (IOException) {}
199 return 143;
203 public string OwnerFromString(string owner)
205 if (String.IsNullOrEmpty(owner)) return Driver.Username;
206 if (owner == "*") return null;
207 return owner;
210 public VersionControlServer VersionControlServer
212 get { return Driver.VersionControlServer; }
215 public List<string> UnVerifiedFullPaths(string[] args)
217 List<string> paths = new List<string>();
218 for (int i = 0; i < args.Length; i++)
220 string fullPath = Path.GetFullPath(args[i]);
221 paths.Add(fullPath);
224 return paths;
227 public List<string> VerifiedFullPaths(string[] args)
229 List<string> paths = UnVerifiedFullPaths(args);
230 char[] wildcards = { '*', '?' };
232 foreach (string path in paths)
234 // skip wildcarded paths
235 if (-1 != path.IndexOfAny(wildcards)) continue;
237 if (!File.Exists(path) && !Directory.Exists(path))
239 Console.WriteLine("{0}: No such file or directory.", path);
240 Environment.Exit((int)ExitCode.Failure);
244 return paths;
247 public void DeleteReadOnlyFile(string fullName)
249 File.SetAttributes(fullName, FileAttributes.Normal);
250 File.Delete(fullName);
253 static public void ReadFileExcludes()
255 string exclusionList = Settings.Current.Get("File.Excludes");
256 if (String.IsNullOrEmpty(exclusionList)) return;
258 string separatorChar = Path.DirectorySeparatorChar.ToString();
259 string[] wildcards = exclusionList.Split(',');
261 StringBuilder dirRegexs = new StringBuilder();
262 StringBuilder fileRegexs = new StringBuilder();
264 foreach (string wildcard in wildcards)
266 if (-1 == wildcard.IndexOf(separatorChar))
268 if (0 != fileRegexs.Length) fileRegexs.Append("|");
270 fileRegexs.Append("^");
271 fileRegexs.Append(Regex.Escape(wildcard).Replace("\\*", ".*").Replace("\\?", "."));
272 fileRegexs.Append("$");
274 else
276 if (0 != dirRegexs.Length) dirRegexs.Append("|");
278 dirRegexs.Append("^.*");
279 dirRegexs.Append(Regex.Escape(wildcard));
280 dirRegexs.Append(".*$");
284 if (0 != fileRegexs.Length)
285 fileExcludes = new Regex(fileRegexs.ToString());
287 if (0 != dirRegexs.Length)
288 dirExcludes = new Regex(dirRegexs.ToString());
291 public bool IsExcludedFile(string path)
293 if ((fileExcludes != null) &&
294 (fileExcludes.IsMatch(Path.GetFileName(path))))
295 return true;
297 if ((dirExcludes != null) && (dirExcludes.IsMatch(path)))
298 return true;
300 return false;
303 public void ConfirmFilesSpecified()
305 if (Arguments.Length < 1)
307 Console.WriteLine("No files specified.");
308 Environment.Exit((int)ExitCode.Failure);
312 public string CanonicalPath(string p)
314 return p;
315 // maybe this feature is only interesting to me?
316 //if (runningOnUnix) return p;
317 //return p.Replace('\\', '/');
320 public abstract void Run ();