Update of /cvsroot/sharpcvslib/sharpcvslib/src/ICSharpCode/SharpCvsLib/FileSystem In directory sc8-pr-cvs1:/tmp/cvs-serv6109/src/ICSharpCode/SharpCvsLib/FileSystem Modified Files: Entries.cs Entry.cs Factory.cs Folder.cs Folders.cs ICvsFile.cs Manager.cs PathTranslator.cs Repository.cs Root.cs Tag.cs Added Files: AbstractCvsFile.cs DuplicateEntryException.cs EntryParseException.cs InvalidPathException.cs UnsupportedFileTypeException.cs Log Message: Various changes to get the AddCommand working. Reworked the filesystem to check for duplicates and filter out problems with path. Also added exception if attempt is made to add files outside of the working path. Added a CvsRootParseException, various modifications to fix the formatting from astyle. --- NEW FILE: AbstractCvsFile.cs --- #region "Copyright" // Copyright (C) 2003 Clayton Harbour // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // // As a special exception, the copyright holders of this library give you // permission to link this library with independent modules to produce an // executable, regardless of the license terms of these independent // modules, and to copy and distribute the resulting executable under // terms of your choice, provided that you also meet, for each linked // independent module, the terms and conditions of the license of that // module. An independent module is a module which is not derived from // or based on this library. If you modify this library, you may extend // this exception to your version of the library, but you are not // obligated to do so. If you do not wish to do so, delete this // exception statement from your version. // // <author>Clayton Harbour</author> #endregion using System; using log4net; namespace ICSharpCode.SharpCvsLib.FileSystem { /// <summary> /// The abstract cvs file implements common methods and provides a common /// implementation for all CVS management files. /// </summary> public abstract class AbstractCvsFile { private readonly ILog LOGGER = LogManager.GetLogger(typeof (AbstractCvsFile)); private String fullPath; private String fileContents; /// <summary> /// Return the path to the file that this cvs object is controlling. In /// most cases this is just the full path to the object, however one /// known exception would be the Entry which would have file information /// stripped from the full path. /// </summary> public virtual String Path { get {return this.FullPath;} } /// <summary> /// The full path to the file or directory that this object is managing. /// </summary> public String FullPath { get {return this.fullPath;} set {this.fullPath = value;} } /// <summary> /// Contents that are contained in the management file that this object /// represents. /// </summary> public virtual String FileContents { get {return this.fileContents;} set {this.fileContents = value;} } /// <summary> /// Create a new object that represents the management file that CVS /// uses to hold information about the repository and local file /// system. /// </summary> /// <param name="fullPath">The full path to the file or directory on the /// filesystem that this object is managing.</param> /// <param name="fileContents">A line of comments that represents information /// to be written to the cvs management file, or is written in the /// cvs management file.</param> public AbstractCvsFile(String fullPath, String fileContents) { if (PathTranslator.ContainsCVS(fullPath)) { // attempt recovery if this file contains a cvs folder. fullPath = System.IO.Path.GetDirectoryName(fullPath); if (PathTranslator.ContainsCVS(fullPath)) { throw new Exception("Path information should not contain cvs folder."); } } this.fileContents = fileContents; this.fullPath = fullPath; this.Parse(fileContents); if (LOGGER.IsDebugEnabled) { LOGGER.Debug("Created new entry=[" + this + "]"); if (this.ToString().ToUpper().IndexOf("C:") > 0) { LOGGER.Debug("Should not have an entry formatted like this, should just contain relative paths."); LOGGER.Debug("Stack trace=[" + Environment.StackTrace + "]"); } } } /// <summary> /// Parse command that must be overridden for subclasses. /// </summary> /// <param name="line"></param> public abstract void Parse(String line); } } --- NEW FILE: DuplicateEntryException.cs --- #region Copyright // Copyright (C) 2003 Clayton Harbour // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // // As a special exception, the copyright holders of this library give you // permission to link this library with independent modules to produce an // executable, regardless of the license terms of these independent // modules, and to copy and distribute the resulting executable under // terms of your choice, provided that you also meet, for each linked // independent module, the terms and conditions of the license of that // module. An independent module is a module which is not derived from // or based on this library. If you modify this library, you may extend // this exception to your version of the library, but you are not // obligated to do so. If you do not wish to do so, delete this // exception statement from your version. // // Author: Clayton Harbour #endregion using System; namespace ICSharpCode.SharpCvsLib.FileSystem { /// <summary> /// This exception is thrown if there is no entry matching the specifed /// criteria. /// </summary> public class DuplicateEntryException : Exception { /// <summary> /// Occurs if a duplicate entry has found it's way into the Entries file. /// This is an indication that something has corrupted the cvs repository. /// </summary> public DuplicateEntryException () { } /// <summary> /// Occurs if a duplicate entry has found it's way into the Entries file. /// This is an indication that something has corrupted the cvs repository. /// </summary> /// <param name="message">Additional information to pass on in the /// exception.</param> public DuplicateEntryException (String message) : base (message) { } /// <summary> /// Occurs if a duplicate entry has found it's way into the Entries file. /// This is an indication that something has corrupted the cvs repository. /// </summary> /// <param name="message">A message that will be helpful for someone /// resolving the issue with the library.</param> /// <param name="e">An exception that has caused this error, or has /// led to this error.</param> public DuplicateEntryException (String message, Exception e) : base (message, e) { } } } --- NEW FILE: EntryParseException.cs --- using System; namespace ICSharpCode.SharpCvsLib.FileSystem { /// <summary> /// An invalid cvsroot exception is thrown if the client attempts to send in /// a root that is not understood by the server. /// </summary> public class EntryParseException : Exception{ /// <summary> /// Indicate that an invalid cvsroot has been passed into the library. /// </summary> /// <param name="msg">A useful message that will help a developer debug /// the problem that has occurred.</param> public EntryParseException(String msg) : base (msg) { } /// <summary> /// Indicate that an invalid cvsroot has been passed into the library. /// </summary> /// <param name="msg">A useful message that will help a developer debug /// the problem that has occurred.</param> /// <param name="e"></param> public EntryParseException (String msg, Exception e) : base (msg, e) { } } } --- NEW FILE: InvalidPathException.cs --- #region Copyright // Copyright (C) 2003 Clayton Harbour // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // // As a special exception, the copyright holders of this library give you // permission to link this library with independent modules to produce an // executable, regardless of the license terms of these independent // modules, and to copy and distribute the resulting executable under // terms of your choice, provided that you also meet, for each linked // independent module, the terms and conditions of the license of that // module. An independent module is a module which is not derived from // or based on this library. If you modify this library, you may extend // this exception to your version of the library, but you are not // obligated to do so. If you do not wish to do so, delete this // exception statement from your version. // // Author: Clayton Harbour #endregion using System; namespace ICSharpCode.SharpCvsLib.FileSystem { /// <summary> /// This exception is thrown if there is an attempt to write to a path that is /// outside of the working path. /// </summary> public class InvalidPathException : Exception { /// <summary> /// Occurs if there is an attempt to write to a path that is outside of the working /// path. /// </summary> public InvalidPathException () { } /// <summary> /// Occurs if there is an attempt to write to a path that is outside of the working /// path. /// </summary> /// <param name="message">Additional information to pass on in the /// exception.</param> public InvalidPathException (String message) : base (message) { } /// <summary> /// Occurs if there is an attempt to write to a path that is outside of the working /// path. /// </summary> /// <param name="message">A message that will be helpful for someone /// resolving the issue with the library.</param> /// <param name="e">An exception that has caused this error, or has /// led to this error.</param> public InvalidPathException (String message, Exception e) : base (message, e) { } } } --- NEW FILE: UnsupportedFileTypeException.cs --- #region Copyright // Copyright (C) 2003 Clayton Harbour // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // // As a special exception, the copyright holders of this library give you // permission to link this library with independent modules to produce an // executable, regardless of the license terms of these independent // modules, and to copy and distribute the resulting executable under // terms of your choice, provided that you also meet, for each linked // independent module, the terms and conditions of the license of that // module. An independent module is a module which is not derived from // or based on this library. If you modify this library, you may extend // this exception to your version of the library, but you are not // obligated to do so. If you do not wish to do so, delete this // exception statement from your version. // // Author: Clayton Harbour #endregion using System; namespace ICSharpCode.SharpCvsLib.FileSystem { /// <summary> /// An unsupported file type exception occurs if a file name of file type that /// is not currently known about or not implemented. /// </summary> public class UnsupportedFileTypeException : Exception { /// <summary> /// An unsupported file type exception occurs if a file name of file type that /// is not currently known about or not implemented. /// </summary> public UnsupportedFileTypeException () { } /// <summary> /// An unsupported file type exception occurs if a file name of file type that /// is not currently known about or not implemented. /// </summary> /// <param name="message">Additional information to pass on in the /// exception.</param> public UnsupportedFileTypeException (String message) : base (message) { } /// <summary> /// An unsupported file type exception occurs if a file name of file type that /// is not currently known about or not implemented. /// </summary> /// <param name="message">A message that will be helpful for someone /// resolving the issue with the library.</param> /// <param name="e">An exception that has caused this error, or has /// led to this error.</param> public UnsupportedFileTypeException (String message, Exception e) : base (message, e) { } } } Index: Entries.cs =================================================================== RCS file: /cvsroot/sharpcvslib/sharpcvslib/src/ICSharpCode/SharpCvsLib/FileSystem/Entries.cs,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** Entries.cs 16 Nov 2003 10:04:40 -0000 1.1 --- Entries.cs 5 Dec 2003 05:27:52 -0000 1.2 *************** *** 50,54 **** /// Create a new instance of the entries class. /// </summary> ! public Entries() { } --- 50,55 ---- /// Create a new instance of the entries class. /// </summary> ! public Entries() : base() { ! } *************** *** 57,63 **** /// is the key for the entry. /// </summary> ! public Entry this[int relativePath] { ! get { return ((Entry)(Dictionary[relativePath])); } ! set { Dictionary[relativePath] = value; } } --- 58,64 ---- /// is the key for the entry. /// </summary> ! public Entry this[String fullPath] { ! get { return ((Entry)(Dictionary[fullPath])); } ! set { Dictionary[fullPath] = value; } } *************** *** 89,92 **** --- 90,107 ---- public bool Contains(String path) { return Dictionary.Contains(path); + } + + /// <summary> + /// Render the entries collection as a human readable string. + /// </summary> + /// <returns></returns> + public override String ToString() { + ICSharpCode.SharpCvsLib.Util.ToStringFormatter formatter = new + ICSharpCode.SharpCvsLib.Util.ToStringFormatter("Entries"); + foreach (DictionaryEntry entry in Dictionary) { + formatter.AddProperty("Entry key", entry.Key); + formatter.AddProperty("Entry value", entry.Value); + } + return formatter.ToString(); } } Index: Entry.cs =================================================================== RCS file: /cvsroot/sharpcvslib/sharpcvslib/src/ICSharpCode/SharpCvsLib/FileSystem/Entry.cs,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** Entry.cs 16 Nov 2003 10:04:40 -0000 1.12 --- Entry.cs 5 Dec 2003 05:27:52 -0000 1.13 *************** *** 46,374 **** namespace ICSharpCode.SharpCvsLib.FileSystem { - - /// <summary> - /// Rcs entry. - /// </summary> - public class Entry : ICvsFile - { - private ILog LOGGER = LogManager.GetLogger (typeof (Entry)); - /// <summary> ! /// Indicator specifying if this is a new entry or not. ! /// The default value is <code>true</code>. /// </summary> ! public bool NewEntry = true; ! private bool isDir = false; ! private string name = null; ! private string revision = "1.1.1.1"; ! private DateTime timestamp = DateTime.Now; ! private string conflict = null; ! private string options = null; ! private string tag = null; ! private string date = null; ! private string cvsEntry; ! private Tag tagFile = null; ! /// <summary> ! /// The name of the entries file. ! /// </summary> ! public const String FILE_NAME = "Entries"; ! private String path; ! /// <summary> ! /// The name of the file to write to. ! /// </summary> ! public String Filename { ! get {return Entry.FILE_NAME;} ! } ! /// <summary> ! /// The name of the actual file on the filesystem. ! /// </summary> ! public String ActualFilename { ! get {return System.IO.Path.Combine (this.Path, this.Name);} ! } ! /// <summary> ! /// The path to the folder above the cvs folder. ! /// </summary> ! public String Path { ! get {return this.path;} ! } ! /// <summary> ! /// Timestamp for the file. ! /// </summary> ! public DateTime TimeStamp { get {return timestamp;} set {timestamp = value;} ! } ! ! /// <summary> ! /// String indicating a conflict with the server and ! /// client files (if any). ! /// </summary> ! public string Conflict { ! get {return conflict;} ! set {conflict = value;} ! } ! /// <summary> ! /// Date of the revision. ! /// </summary> ! public string Date { ! get {return date;} ! set { ! date = value; ! SetTimeStamp(); } - } ! /// <summary> ! /// Sticky tag for the file (if any). ! /// </summary> ! public string Tag { ! get {return tag;} ! set {tag = value;} ! } ! /// <summary> ! /// TODO: figure out what this is for. ! /// </summary> ! public string Options { ! get {return options;} ! set {options = value;} ! } ! /// <summary> ! /// The revision number for the file. ! /// </summary> ! public string Revision { ! get {return revision;} ! set {revision = value;} ! } ! /// <summary> ! /// The name of the file or directory. ! /// </summary> ! public string Name { ! get {return name;} ! set {name = value;} ! } ! /// <summary> ! /// <code>true</code> if the item is a directory, <code>false</code> ! /// otherwise. ! /// </summary> ! public bool IsDirectory { ! get {return isDir; } ! set {isDir = value;} ! } ! /// <summary> ! /// <code>true</code> if the options tag specifies the file ! /// is binary (i.e. has the option <code>-kb</code> specified). ! /// </summary> ! public bool IsBinaryFile { ! get {return options == "-kb";} ! set {options = value ? "-kb" : null;} ! } ! /// <summary> ! /// Outputs the formatted cvs entry. ! /// </summary> ! /// <returns>The formatted cvs entry.</returns> ! public String FileContents ! { ! get { ! string str = ""; ! if (isDir) { ! str += "D"; } ! str += "/"; ! if (name != null) { ! str += name + "/"; ! if (revision != null) { ! str += revision; } str += "/"; ! if (date != null && ! date != String.Empty && ! !this.IsDirectory) { ! String dateString; ! // TODO: Determine if this should be pulled out into a seperate class. ! dateString = ! DateParser.GetCvsDateString (this.TimeStamp); ! str += dateString; ! } ! if (conflict != null) { ! str += "+" + conflict; ! } ! str += "/"; ! if (options != null) { ! str += options; ! } ! str += "/"; ! if (tag != null) { ! str += tag; ! } else if (date != null) { ! str += date; } - } ! return str; } - } ! /// <summary> ! /// Constructor. ! /// </summary> ! public Entry() ! { ! } ! /// <summary> ! /// The entry class converts a cvs entry string into an ! /// entry object by parsing the string into the various ! /// components. ! /// </summary> ! /// <param name="path">The local path to the cvs file.</param> ! /// <param name="line">The cvs entry string.</param> ! public Entry(String path, String line) ! { ! this.cvsEntry = line; ! Parse(line); ! NewEntry = false; ! this.path = path; ! } ! /// <summary> ! /// Set the file timestamp. ! /// </summary> ! public void SetTimeStamp() ! { ! this.timestamp = DateParser.ParseCvsDate (date); ! if (LOGGER.IsDebugEnabled) { ! StringBuilder msg = new StringBuilder (); ! msg.Append ("timestamp=[").Append (timestamp).Append ("]"); ! msg.Append ("date=[").Append (date).Append ("]"); ! LOGGER.Debug (msg); } - } ! /// <summary> ! /// Parses the cvs entries file. ! /// </summary> ! /// <param name="line"></param> ! public void Parse(string line) ! { ! if (LOGGER.IsDebugEnabled) { ! String msg = "cvsEntry=[" + line + "]"; ! LOGGER.Debug (msg); ! } ! if (line.StartsWith("D/")) { ! this.isDir = true; ! line = line.Substring(1); ! this.name = ""; ! } ! string[] tokens = line.Split( new char[] { '/' }); ! if (tokens.Length < 6 && !this.isDir) { ! throw new ArgumentException("not enough tokens in entry line (#" + ! tokens.Length + ")\n" + line); } ! else if (tokens.Length > 6) { ! throw new ArgumentException ("Too many tokens in entry line." + ! "tokens.Length=[" + tokens.Length + "]" + ! "line=[" + line + "]"); } ! name = tokens[1]; ! if (!this.isDir) { ! revision = tokens[2]; ! date = tokens[3]; ! int conflictIndex = date.IndexOf('+'); - if (conflictIndex > 0) { - Conflict = date.Substring(conflictIndex + 1); - date = date.Substring(0, conflictIndex); } ! SetTimeStamp(); ! options = tokens[4]; ! tag = tokens[5]; } - } ! /// <summary> ! /// Determine if the two objects are equal. ! /// </summary> ! public override bool Equals (object obj) { ! if (obj is Entry) { ! Entry that = (Entry)obj; ! if (that.GetHashCode ().Equals (this.GetHashCode ())) { ! return true; } } - return false; - } ! /// <summary> ! /// Override the hashcode. This is a combination of the entry ! /// name and the path to the entry file. ! /// </summary> ! public override int GetHashCode () { ! return this.Name.GetHashCode (); ! } ! /// <summary> ! /// Return a human readable string that represents the entry object. ! /// </summary> ! /// <returns>A human readable string that represents the entry object.</returns> ! public override String ToString () { ! return this.FileContents; ! } ! /// <summary>The type of file that this is.</summary> ! public Factory.FileType Type {get {return Factory.FileType.Entries;}} ! /// <summary>Indicates whether the file can contain multiple ! /// lines.</summary> ! /// <returns><code>true</code> if the file can contain multiple ! /// lines; <code>false</code> otherwise.</returns> ! public bool IsMultiLined { ! get {return true;} ! } ! /// <summary> ! /// Holds information on a tag file if there is a ! /// <code>sticky-tag</code> in the cvs directory. If there ! /// is no tag in the cvs directory then this value is null. ! /// </summary> ! public Tag TagFile { ! get {return this.tagFile;} ! set {this.tagFile = value;} ! } ! /// <summary> ! /// <code>true</code> if the cvs entry contains a ! /// <code>sticky-tag</code>; otherwise <code>false</code>. ! /// </summary> ! public bool HasTag { ! get {return null == this.Tag;} } - - } } --- 46,465 ---- namespace ICSharpCode.SharpCvsLib.FileSystem { /// <summary> ! /// Rcs entry. /// </summary> ! public class Entry : AbstractCvsFile, ICvsFile ! { ! private static ILog LOGGER = LogManager.GetLogger (typeof (Entry)); ! /// <summary> ! /// Indicator specifying if this is a new entry or not. ! /// The default value is <code>true</code>. ! /// </summary> ! public bool NewEntry = true; ! private bool isDir = false; ! private string name = null; ! private string revision = "0"; ! private DateTime timestamp = DateTime.Now; ! private string conflict = null; ! private string options = null; ! private string tag = null; ! private string date = null; ! private Tag tagFile = null; ! /// <summary> ! /// The name of the entries file. ! /// </summary> ! public const String FILE_NAME = "Entries"; ! /// <summary> ! /// The name of the file to write to. ! /// </summary> ! public String Filename { ! get {return Entry.FILE_NAME;} ! } ! /// <summary> ! /// Get the path to the folder that contains the file being managed. ! /// </summary> ! public override String Path { ! get { ! String tempPath; ! tempPath = System.IO.Path.GetDirectoryName(this.FullPath); ! return this.GetPathWithDirectorySeperatorChar(tempPath); ! } ! } ! private String GetPathWithDirectorySeperatorChar(String path) { ! if (!path[path.Length - 1].Equals(System.IO.Path.DirectorySeparatorChar)) { ! return path + System.IO.Path.DirectorySeparatorChar; ! } else if (!path[path.Length - 1].Equals('/')) { ! return path + System.IO.Path.DirectorySeparatorChar; ! } ! return path; ! } ! /// <summary> ! /// Timestamp for the file. ! /// </summary> ! public DateTime TimeStamp { get {return timestamp;} set {timestamp = value;} ! } ! /// <summary> ! /// String indicating a conflict with the server and ! /// client files (if any). ! /// </summary> ! public string Conflict { ! get {return conflict;} ! set {conflict = value;} } ! /// <summary> ! /// Date of the revision. ! /// </summary> ! public string Date { ! get {return date;} ! set { ! date = value; ! SetTimeStamp(); ! } ! } ! /// <summary> ! /// Sticky tag for the file (if any). ! /// </summary> ! public string Tag { ! get {return tag;} ! set {tag = value;} ! } ! /// <summary> ! /// TODO: figure out what this is for. ! /// </summary> ! public string Options { ! get {return options;} ! set {options = value;} ! } ! /// <summary> ! /// The revision number for the file. ! /// </summary> ! public string Revision { ! get {return revision;} ! set {revision = value;} ! } ! /// <summary> ! /// The name of the file or directory. ! /// </summary> ! public string Name { ! get {return name;} ! set {name = value;} ! } ! /// <summary> ! /// <code>true</code> if the item is a directory, <code>false</code> ! /// otherwise. ! /// </summary> ! public bool IsDirectory { ! get {return isDir; } ! set {isDir = value;} ! } ! /// <summary> ! /// <code>true</code> if the options tag specifies the file ! /// is binary (i.e. has the option <code>-kb</code> specified). ! /// </summary> ! public bool IsBinaryFile { ! get {return options == "-kb";} ! set {options = value ? "-kb" : null;} } ! ! /// <summary> ! /// Outputs the formatted cvs entry. ! /// </summary> ! /// <returns>The formatted cvs entry.</returns> ! public override String FileContents { ! get { ! string str = ""; ! if (isDir) { ! str += "D"; } str += "/"; + if (name != null) { + str += name + "/"; + if (revision != null && !this.isDir) { + str += revision; + } + str += "/"; ! if (date != null && ! date != String.Empty && ! !this.IsDirectory) { ! String dateString; ! dateString = ! DateParser.GetCvsDateString (this.TimeStamp); ! str += dateString; ! } ! if (conflict != null) { ! str += "+" + conflict; ! } ! str += "/"; ! if (options != null) { ! str += options; ! } ! str += "/"; ! if (tag != null) { ! str += tag; ! } else if (date != null) { ! str += date; ! } } ! LOGGER.Debug("str=[" + str + "]"); ! return str; ! } } ! /// <summary> ! /// Create a new instance of the cvs object. ! /// ! /// NOTE: Derive full path is assumed. What this means is it is assumed ! /// that you are passing in the path to the file and would like to use ! /// the fileContents or entry to get the full path to the managed file. ! /// </summary> ! /// <param name="path">The path to the directory above the object being ! /// managed. The information in the fileContents parameter is used ! /// to fill in the "missing" information about the file location.</param> ! /// <param name="fileContents">The contents of the cvs management file.</param> ! public Entry (String path, String fileContents) : this (path, fileContents, true) { ! } ! /// <summary> ! /// Create a new Cvs entry. If the deriveFullPath is set to false then the ! /// path information specified in the constructor is taken as the ! /// entire path to the file. ! /// </summary> ! /// <param name="path">Either the path to the directory above the CVS directory, ! /// or if the deriveFullPath is set to true then this is the full path ! /// to the file under cvs control.</param> ! /// <param name="fileContents">A line that represents this particular entry ! /// under cvs control.</param> ! /// <param name="deriveFullPath"><code>true</code> if the full path should ! /// be derived from combining the path information and the file name ! /// parsed from the fileContents or if the path information passed ! /// in represents the full path to the file.</param> ! public Entry (String path, String fileContents, bool deriveFullPath) : base(path, fileContents) { ! if (PathTranslator.ContainsCVS(path)) { ! // attempt recovery if this file contains a cvs folder. ! path = System.IO.Path.GetDirectoryName(path); ! if (PathTranslator.ContainsCVS(path)) { ! throw new Exception("Path information should not contain cvs folder."); ! } ! } ! LOGGER.Error("path=[" + path + "]"); ! LOGGER.Error("name=[" + this.Name + "]"); ! if (deriveFullPath) { ! this.FullPath = System.IO.Path.Combine(path, this.Name); ! } else { ! this.FullPath = path; ! } ! if (!File.Exists(this.FullPath) && ! !Directory.Exists(this.FullPath)) { ! StringBuilder msg = new StringBuilder(); ! msg.Append("File does not exist in path."); ! msg.Append("FullPath=[").Append(FullPath).Append("]"); ! msg.Append("Stack trace=[").Append(Environment.StackTrace).Append("]"); ! LOGGER.Warn(msg); ! } ! if (LOGGER.IsDebugEnabled) { ! StringBuilder msg = new StringBuilder(); ! msg.Append("Created new entry=[").Append(this).Append("]"); ! msg.Append("path=[").Append(path).Append("]"); ! LOGGER.Debug(msg); ! if (this.ToString().ToUpper().IndexOf("C:") > 0) { ! LOGGER.Debug("Should not have an entry formatted like this, should just contain relative paths."); ! LOGGER.Debug("Stack trace=[" + Environment.StackTrace + "]"); ! } ! } } ! /// <summary> ! /// Creates a new entry given the path to the file on the filesystem. ! /// </summary> ! /// <param name="fullPath">The path to the file to put under cvs control.</param> ! /// <returns>A new cvs entry, using the full path to the file for the ! /// entry information.</returns> ! public static Entry CreateEntry (String fullPath) { ! String path; ! if (PathTranslator.ContainsCVS(fullPath) || ! fullPath.EndsWith("/")) { ! throw new Exception("Unable to create an entry for CVS files."); ! } ! StringBuilder entryString = new StringBuilder(); ! // Sample directory entry: D/conf//// ! if (Directory.Exists(fullPath) || ! fullPath.EndsWith(System.IO.Path.DirectorySeparatorChar.ToString()) || ! fullPath.EndsWith("/")) { ! entryString.Append("D"); ! // get the directory if the path ends with a slash ! if (fullPath.EndsWith(System.IO.Path.DirectorySeparatorChar.ToString()) || ! fullPath.EndsWith("/")) { ! // strip the slash off so the filename is derived correctly ! fullPath = fullPath.Substring(0, fullPath.Length - 1); ! } ! } ! path = System.IO.Path.GetDirectoryName(fullPath); ! entryString.Append("/").Append(System.IO.Path.GetFileName(fullPath)); ! entryString.Append("/0///"); ! LOGGER.Error("entryString=[" + entryString.ToString() + "]"); ! Entry entry = new Entry(path, ! entryString.ToString()); ! LOGGER.Error("Created entry=[" + entry + "]"); ! LOGGER.Error("Path=[" + entry.Path + "]"); ! LOGGER.Error("FullPath=[" + fullPath + "]"); ! return entry; } ! ! /// <summary> ! /// Set the file timestamp. ! /// </summary> ! public void SetTimeStamp() { ! this.timestamp = DateParser.ParseCvsDate (date); ! if (LOGGER.IsDebugEnabled) { ! StringBuilder msg = new StringBuilder (); ! msg.Append ("timestamp=[").Append (timestamp).Append ("]"); ! msg.Append ("date=[").Append (date).Append ("]"); ! LOGGER.Debug (msg); ! } } ! /// <summary> ! /// Parses the cvs entries file. ! /// </summary> ! /// <param name="line"></param> ! public override void Parse(string line) ! { ! if (LOGGER.IsDebugEnabled) { ! String msg = "cvsEntry=[" + line + "]"; ! LOGGER.Debug (msg); ! } ! if (line.StartsWith("D/")) { ! this.isDir = true; ! line = line.Substring(1); ! this.name = ""; ! } ! string[] tokens = line.Split( new char[] { '/' }); ! if (tokens.Length < 6 && !this.isDir) { ! throw new EntryParseException("not enough tokens in entry line (#" + ! tokens.Length + ")\n" + line); ! } ! else if (tokens.Length > 6) { ! throw new EntryParseException("Too many tokens in entry line." + ! "tokens.Length=[" + tokens.Length + "]" + ! "line=[" + line + "]"); ! } ! ! name = tokens[1]; ! if (!this.isDir) { ! revision = tokens[2]; ! LOGGER.Debug("revision=[" + revision + "]"); ! LOGGER.Debug("line=[" + line + "]"); ! date = tokens[3]; ! ! int conflictIndex = date.IndexOf('+'); ! ! if (conflictIndex > 0) { ! Conflict = date.Substring(conflictIndex + 1); ! date = date.Substring(0, conflictIndex); ! } ! SetTimeStamp(); ! options = tokens[4]; ! tag = tokens[5]; } ! } + /// <summary> + /// Parse the name of the file from the cvs file. + /// </summary> + /// <param name="line">The line to parse.</param> + /// <returns>The name of the entry in the cvs file.</returns> + public static String ParseFileName (String line) { + Entry entry = new Entry(System.IO.Path.GetTempPath(), line); + return entry.Filename; } ! /// <summary> ! /// Determine if the two objects are equal. ! /// </summary> ! public override bool Equals (object obj) { ! if (obj is Entry) { ! Entry that = (Entry)obj; ! if (that.GetHashCode ().Equals (this.GetHashCode ())) { ! return true; ! } } + return false; } ! /// <summary> ! /// Override the hashcode. This is a combination of the entry ! /// name and the path to the entry file. ! /// </summary> ! public override int GetHashCode () { ! return (this.isDir.ToString() + this.FullPath + this.Name).GetHashCode (); ! } ! /// <summary> ! /// Return a human readable string that represents the entry object. ! /// </summary> ! /// <returns>A human readable string that represents the entry object.</returns> ! public override String ToString () { ! return this.FileContents; ! } ! /// <summary>The type of file that this is.</summary> ! public Factory.FileType Type {get {return Factory.FileType.Entries;}} ! /// <summary>Indicates whether the file can contain multiple ! /// lines.</summary> ! /// <returns><code>true</code> if the file can contain multiple ! /// lines; <code>false</code> otherwise.</returns> ! public bool IsMultiLined { ! get {return true;} ! } ! /// <summary> ! /// Holds information on a tag file if there is a ! /// <code>sticky-tag</code> in the cvs directory. If there ! /// is no tag in the cvs directory then this value is null. ! /// </summary> ! public Tag TagFile { ! get {return this.tagFile;} ! set {this.tagFile = value;} ! } ! /// <summary> ! /// <code>true</code> if the cvs entry contains a ! /// <code>sticky-tag</code>; otherwise <code>false</code>. ! /// </summary> ! public bool HasTag { ! get {return null == this.Tag;} ! } } } Index: Factory.cs =================================================================== RCS file: /cvsroot/sharpcvslib/sharpcvslib/src/ICSharpCode/SharpCvsLib/FileSystem/Factory.cs,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** Factory.cs 16 Nov 2003 10:04:40 -0000 1.8 --- Factory.cs 5 Dec 2003 05:27:52 -0000 1.9 *************** *** 74,79 **** /// <summary> ! /// Create the cvs file based on the filename. Returns the ! /// cvs file interface. /// </summary> public ICvsFile CreateCvsObject (String path, --- 74,122 ---- /// <summary> ! /// Create a cvs management object for the given path. The path specified ! /// should be the folder above the cvs directory. The name of the file ! /// and full path is then derived from the cvs line in the case of an ! /// Entries line, or in the case of a single line cvs management file ! /// (i.e. Root, Repository, etc.) the object being managed is the ! /// entire directory. ! /// </summary> ! /// <param name="path">The path to the folder above the cvs directory.</param> ! /// <param name="fileName">The name of the cvs file that is being modified/ ! /// created.</param> ! /// <param name="line">The line to add to the file.</param> ! /// <returns>A new cvs file that contains properties for the different ! /// elements in the line.</returns> ! /// <exception cref="UnsupportedFileTypeException">If the cvs filetype specified ! /// is unknown.</exception> ! /// <example> ! /// The following will produce an entries file ! /// (directory seperator character may be different): ! /// ! /// path = c:/dev/sharpcvslib ! /// fileName = Entries ! /// line = /SharpCvsLib.build/1.1/// ! /// ! /// With the following information: ! /// FileContents = /SharpCvsLib.build/1.1/// ! /// FileName = Entries ! /// FullPath = c:/dev/sharpcvslib/SharpCvsLib.build ! /// IsMultiLined = true ! /// Path = c:/dev/sharpcvslib/ ! /// ! /// NOTE: ! /// <ul> ! /// <li>The path seperator may face the other way</li> ! /// <li>There will be an ending path seperator after every directory, ! /// as in the path.</li> ! /// </ul> ! /// </example> ! public ICvsFile CreateCvsObject (String path, String fileName, String line) { ! FileType fileType = this.GetFileType(fileName); ! return this.CreateCvsObject(path, fileType, line); ! } ! ! /// <summary> ! /// Create the cvs file based on the filename. Returns the ! /// cvs file interface. /// </summary> public ICvsFile CreateCvsObject (String path, *************** *** 82,100 **** ICvsFile entry; switch (fileType) { ! case (FileType.Entries): ! entry = new Entry(path, line); ! break; ! case (FileType.Repository): ! entry = new Repository (path, line); ! break; ! case (FileType.Root): ! entry = new Root (path, line); ! break; ! case (FileType.Tag): ! entry = new Tag (path, line); ! break; ! default: ! String msg = "Unable to create object."; ! throw new Exception (msg); } --- 125,150 ---- ICvsFile entry; switch (fileType) { ! case (FileType.Entries): { ! entry = new Entry(path, line); ! break; ! } ! case (FileType.Repository):{ ! entry = new Repository (path, line); ! break; ! } ! case (FileType.Root):{ ! entry = new Root (path, line); ! break; ! } ! case (FileType.Tag):{ ! entry = new Tag (path, line); ! break; ! } ! default:{ ! StringBuilder msg = new StringBuilder(); ! msg.Append("Unknown file type specified."); ! msg.Append("fileType=[").Append(fileType.ToString()).Append("]"); ! throw new UnsupportedFileTypeException (msg.ToString()); ! } } *************** *** 110,125 **** public String GetFilename (FileType fileType) { switch (fileType) { ! case (FileType.Entries): ! return Entry.FILE_NAME; ! case (FileType.Repository): ! return Repository.FILE_NAME; ! case (FileType.Root): ! return Root.FILE_NAME; ! case (FileType.Tag): ! return Tag.FILE_NAME; ! default: ! String msg = "Unable to create object."; ! throw new Exception (msg); } } --- 160,209 ---- public String GetFilename (FileType fileType) { switch (fileType) { ! case (FileType.Entries):{ ! return Entry.FILE_NAME; ! } ! case (FileType.Repository):{ ! return Repository.FILE_NAME; ! } ! case (FileType.Root):{ ! return Root.FILE_NAME; ! } ! case (FileType.Tag):{ ! return Tag.FILE_NAME; ! } ! default:{ ! StringBuilder msg = new StringBuilder(); ! msg.Append("Unknown file type specified."); ! msg.Append("fileType=[").Append(fileType.ToString()).Append("]"); ! throw new UnsupportedFileTypeException (msg.ToString()); ! } ! } ! } + /// <summary> + /// Derive the file type from the name of the cvs file. + /// </summary> + /// <param name="name">The name of the cvs file.</param> + /// <returns>The type of the file.</returns> + public FileType GetFileType (String name) { + switch (name) { + case (Entry.FILE_NAME): { + return FileType.Entries; + } + case (Repository.FILE_NAME): { + return FileType.Repository; + } + case (Root.FILE_NAME): { + return FileType.Root; + } + case (Tag.FILE_NAME): { + return FileType.Tag; + } + default: { + StringBuilder msg = new StringBuilder(); + msg.Append("Unknown file type specified."); + msg.Append("name=[").Append(name).Append("]"); + throw new UnsupportedFileTypeException (msg.ToString()); + } } } Index: Folder.cs =================================================================== RCS file: /cvsroot/sharpcvslib/sharpcvslib/src/ICSharpCode/SharpCvsLib/FileSystem/Folder.cs,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** Folder.cs 16 Nov 2003 10:04:40 -0000 1.3 --- Folder.cs 5 Dec 2003 05:27:52 -0000 1.4 *************** *** 40,99 **** namespace ICSharpCode.SharpCvsLib.FileSystem { - - /// <summary> - /// Represents a list of entries in the repository or - /// in simple terms a folder or directory on the - /// cvs server. - /// </summary> - public class Folder { - private Entries entries = new Entries(); - private Repository repository; - private Root root; - private Tag tag; - /// <summary> ! /// The repository object. /// </summary> ! [Obsolete ("Please use Repository")] ! public Repository Repos { ! get {return this.repository;} ! set {this.repository = value;} ! } ! /// <summary> ! /// Root file, holds cvsroot information. ! /// </summary> ! public Root Root { ! get {return this.root;} ! set {this.root = value;} ! } ! /// <summary> ! /// Repository file, holds information about the relative path to the ! /// folder on the server. ! /// </summary> ! public Repository Repository { ! get {return this.repository;} ! set {this.repository = value;} ! } ! /// <summary> ! /// Tag file: Optional file that records the current revision that ! /// is checked out. Only present if the revision is not the HEAD ! /// revision. ! /// </summary> ! public Tag Tag { ! get {return this.tag;} ! set {this.tag = value;} ! } ! /// <summary> ! /// List of entries. ! /// </summary> ! public Entries Entries { ! get {return entries;} ! set {this.entries = value;} } - } } --- 40,119 ---- namespace ICSharpCode.SharpCvsLib.FileSystem { /// <summary> ! /// Represents a list of entries in the repository or ! /// in simple terms a folder or directory on the ! /// cvs server. /// </summary> ! public class Folder { ! private Entries entries; ! private Repository repository; ! private Root root; ! private Tag tag; ! /// <summary> ! /// Create a new instance of the folders object. Initialize the entries ! /// collection. ! /// </summary> ! public Folder () { ! this.entries = new Entries(); ! } ! /// <summary> ! /// The repository object. ! /// </summary> ! [Obsolete ("Use Repository")] ! public Repository Repos { ! get {return this.repository;} ! set {this.repository = value;} ! } ! /// <summary> ! /// Root file, holds cvsroot information. ! /// </summary> ! public Root Root { ! get {return this.root;} ! set {this.root = value;} ! } ! /// <summary> ! /// Repository file, holds information about the relative path to the ! /// folder on the server. ! /// </summary> ! public Repository Repository { ! get {return this.repository;} ! set {this.repository = value;} ! } ! /// <summary> ! /// Tag file: Optional file that records the current revision that ! /// is checked out. Only present if the revision is not the HEAD ! /// revision. ! /// </summary> ! public Tag Tag { ! get {return this.tag;} ! set {this.tag = value;} ! } ! ! /// <summary> ! /// List of entries. ! /// </summary> ! public Entries Entries { ! get {return this.entries;} ! set {this.entries = value;} ! } ! ! /// <summary> ! /// Render the object as a human readable string. ! /// </summary> ! /// <returns></returns> ! public override String ToString() { ! ICSharpCode.SharpCvsLib.Util.ToStringFormatter formatter = new ! ICSharpCode.SharpCvsLib.Util.ToStringFormatter("Folder"); ! formatter.AddProperty("Repository", this.Repository); ! formatter.AddProperty("Root", this.Root); ! formatter.AddProperty("Tag", this.Tag); ! formatter.AddProperty("Entries", this.Entries); ! return formatter.ToString(); ! } } } Index: Folders.cs =================================================================== RCS file: /cvsroot/sharpcvslib/sharpcvslib/src/ICSharpCode/SharpCvsLib/FileSystem/Folders.cs,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** Folders.cs 16 Nov 2003 10:04:40 -0000 1.1 --- Folders.cs 5 Dec 2003 05:27:52 -0000 1.2 *************** *** 90,93 **** --- 90,109 ---- return Dictionary.Contains(path); } + + /// <summary> + /// Return a human readable string that represents the folders contained + /// in this dictionary object. + /// </summary> + /// <returns>A human readable string that represents this collection + /// of folders.</returns> + public override String ToString () { + ICSharpCode.SharpCvsLib.Util.ToStringFormatter formatter = new + ICSharpCode.SharpCvsLib.Util.ToStringFormatter("Entries"); + foreach (DictionaryEntry entry in Dictionary) { + formatter.AddProperty("Folder key", entry.Key); + formatter.AddProperty("Folder value", entry.Value); + } + return formatter.ToString(); + } } } Index: ICvsFile.cs =================================================================== RCS file: /cvsroot/sharpcvslib/sharpcvslib/src/ICSharpCode/SharpCvsLib/FileSystem/ICvsFile.cs,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** ICvsFile.cs 5 Nov 2003 08:07:42 -0000 1.6 --- ICvsFile.cs 5 Dec 2003 05:27:52 -0000 1.7 *************** *** 40,80 **** namespace ICSharpCode.SharpCvsLib.FileSystem { - - /// <summary> - /// Interface for all cvs files. Allows the file system manager to store - /// files that contain cvs information such as: - /// <code>Entries</code> - /// <code>Repository</code> - /// <code>Root</code> - /// </summary> - public interface ICvsFile { /// <summary> ! /// The name of the file. This will be a constant for each ! /// type of file (i.e. Repository, Entry, etc.). ! /// </summary> ! String Filename {get;} ! /// <summary> ! /// The path to the folder above the CVS directory. The ! /// CVS directory will be appended to this path by ! /// the manager. /// </summary> ! String Path {get;} ! /// <summary> ! /// The contents that are going to be written to the file. ! /// </summary> ! String FileContents {get;} ! /// <summary> ! /// The type of file that this is. ! /// </summary> ! Factory.FileType Type {get;} ! /// <summary> ! /// Indicates whether the cvs file can contain multiple lines ! /// or if it can only contain a one line entry. ! /// </summary> ! bool IsMultiLined {get;} ! } } --- 40,92 ---- namespace ICSharpCode.SharpCvsLib.FileSystem { /// <summary> ! /// Interface for all cvs files. Allows the file system manager to store ! /// files that contain cvs information such as: ! /// <code>Entries</code> ! /// <code>Repository</code> ! /// <code>Root</code> /// </summary> ! public interface ICvsFile { ! /// <summary> ! /// The name of the file. This will be a constant for each ! /// type of file (i.e. Repository, Entry, etc.). ! /// </summary> ! String Filename {get;} ! /// <summary> ! /// Get the path to the directory above the cvs file. In most cases ! /// this will be the same as full path, with the exception that an ! /// entry will have a FullPath containing the file that the entry is ! /// controlling. ! /// </summary> ! String Path {get;} ! /// <summary> ! /// The full path to the file that the file that this CVS object is managing. ! /// In most cases FullPath will equal Path, with the exception of... [truncated message content] |