Update of /cvsroot/sharpcvslib/sharpcvslib/src/ICSharpCode/SharpCvsLib/Commands In directory sc8-pr-cvs1:/tmp/cvs-serv6109/src/ICSharpCode/SharpCvsLib/Commands Modified Files: CheckoutModuleCommand.cs CommitCommand.cs UpdateCommand.cs Added Files: AddCommand.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: AddCommand.cs --- #region "Copyright" // AddCommand.cs // 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, if you link this library with other files to // produce an executable, this library does not by itself cause the // resulting executable to be covered by the GNU General Public License. // This exception does not however invalidate any other reasons why the // executable file might be covered by the GNU General Public License. // // <author>Clayton Harbour</author> #endregion using System; using System.Collections; using System.IO; using ICSharpCode.SharpCvsLib.Requests; using ICSharpCode.SharpCvsLib.Misc; using ICSharpCode.SharpCvsLib.Client; using ICSharpCode.SharpCvsLib.FileSystem; using log4net; namespace ICSharpCode.SharpCvsLib.Commands { /// <summary> /// /// copied from: http://developer.apple.com/darwin/tools/cvs/cederquist/cvs_60.html /// /// Command: cvs add [-k kflag] [-m message] files /// /// Schedule files to be added to the repository. The files or directories /// specified with add must already exist in the current directory. To add a /// whole new directory hierarchy to the source repository (for example, files /// received from a third-party vendor), use the import command instead. /// /// The added files are not placed in the source repository until you use commit /// to make the change permanent. Doing an add on a file that was removed with /// the remove command will undo the effect of the remove, unless a commit /// command intervened. /// /// The `-k' option specifies the default way that this file will be checked out; /// for more information see section 12.4 Substitution modes. /// /// The `-m' option specifies a description for the file. This description appears in the history log (if it is enabled, see section C.10 The history file). It will also be saved in the version history inside the repository when the file is committed. The log command displays this description. The description can be changed using `admin -t'. See section A.6 admin--Administration. If you omit the `-m description' flag, an empty string will be used. You will not be prompted for a description. /// /// For example, the following commands add the file `backend.c' to the repository: /// /// $ cvs add backend.c /// $ cvs commit -m "Early version. Not yet compilable." backend.c /// /// When you add a file it is added only on the branch which you are working on (see section 5 Branching and merging). You can later merge the additions to another branch if you want (see section 5.9 Merging can add or remove files). /// </summary> public class AddCommand : ICommand { private WorkingDirectory workingDirectory; private ILog LOGGER = LogManager.GetLogger (typeof (AddCommand)); private Folders folders; /// <summary> /// Folders that will be added/ updated when the add command is executed. /// Each folder contains an entry request, even though the actual entry /// does not exist on the hard drive. /// </summary> public Folders Folders { get {return this.folders;} set {this.folders = value;} } /// <summary> /// Initialize the working directory to be used in the add. /// </summary> public AddCommand(WorkingDirectory workingDirectory) { this.workingDirectory = workingDirectory; } /// <summary> /// Execute checkout module command. /// /// taken from: http://www.elegosoft.com/cvs/cvsclient.html /// add \n /// Response expected: yes. Add a file or directory. This uses any /// previous Argument, Directory, Entry, or Modified requests, if they /// have been sent. The last Directory sent specifies the working /// directory at the time of the operation. To add a directory, send the /// directory to be added using Directory and Argument requests. /// /// </summary> /// <example> /// /// C: Root /u/cvsroot /// . . . /// C: Argument nsdir /// C: Directory nsdir /// C: /u/cvsroot/1dir/nsdir /// C: Directory . /// C: /u/cvsroot/1dir /// C: add /// S: M Directory /u/cvsroot/1dir/nsdir added to the repository /// S: ok /// /// You will notice that the server does not signal to the client in any /// particular way that the directory has been successfully added. The client /// is supposed to just assume that the directory has been added and update /// its records accordingly. Note also that adding a directory is immediate; /// it does not wait until a ci request as files do. To add a file, send the /// file to be added using a Modified request. For example: /// /// C: Argument nfile /// C: Directory . /// C: /u/cvsroot/1dir /// C: Modified nfile /// C: u=rw,g=r,o=r /// C: 6 /// C: hello /// C: add /// S: E cvs server: scheduling file `nfile' for addition /// S: Mode u=rw,g=r,o=r /// S: Checked-in ./ /// S: /u/cvsroot/1dir/nfile /// S: /nfile/0/// /// S: E cvs server: use 'cvs commit' to add this file permanently /// S: ok /// /// Note that the file has not been added to the repository; the only effect /// of a successful add request, for a file, is to supply the client with a /// new entries line containing `0' to indicate an added file. In fact, the /// client probably could perform this operation without contacting the /// server, although using add does cause the server to perform a few more /// checks. The client sends a subsequent ci to actually add the file to the /// repository. Another quirk of the add request is that with CVS 1.9 and /// older, a pathname specified in an Argument request cannot contain `/'. /// There is no good reason for this restriction, and in fact more recent /// CVS servers don't have it. But the way to interoperate with the older /// servers is to ensure that all Directory requests for add (except those /// used to add directories, as described above), use `.' for local-directory. /// Specifying another string for local-directory may not get an error, but /// it will get you strange Checked-in responses from the buggy servers. /// </example> /// <param name="connection">Server connection</param> public void Execute(ICommandConnection connection) { connection.SubmitRequest(new ArgumentRequest(ArgumentRequest.Options.DASH)); int loops = 0; foreach (DictionaryEntry folderEntry in this.Folders) { LOGGER.Debug("loops=[" + loops++ + "]"); Folder folder = (Folder)folderEntry.Value; this.SetDirectory (connection, folder); // send each is-modified request foreach (DictionaryEntry entryEntry in folder.Entries) { Entry entry = (Entry)entryEntry.Value; //connection.SubmitRequest(new IsModifiedRequest(entry.Name)); //String fileName = Path.Combine(entry.Path, entry.Name); this.SendFileRequest (connection, entry); // Add the file to the cvs entries file Manager manager = new Manager(connection.Repository.WorkingPath); manager.Add(entry); if (LOGGER.IsDebugEnabled) { LOGGER.Debug("AddCommand. Entry=[" + entry + "]"); } } // send each argument request foreach (DictionaryEntry entryEntry in folder.Entries) { Entry entry = (Entry)entryEntry.Value; connection.SubmitRequest(new ArgumentRequest(entry.Name)); //String fileName = Path.Combine(entry.Path, entry.Name); //this.SendFileRequest (connection, entry); // Add the file to the cvs entries file Manager manager = new Manager(connection.Repository.WorkingPath); manager.Add(entry); if (LOGGER.IsDebugEnabled) { LOGGER.Debug("AddCommand. Entry=[" + entry + "]"); Entries entries = manager.FetchEntries(entry.FullPath); foreach (DictionaryEntry dicEntry in entries) { LOGGER.Debug("entry=[" + dicEntry.Value + "]"); } } } } connection.SubmitRequest(new AddRequest()); } private void SetDirectory (ICommandConnection connection, Folder folder) { String absoluteDir = connection.Repository.CvsRoot.CvsRepository + "/" + folder.Repository.FileContents; try { connection.SubmitRequest(new DirectoryRequest(".", absoluteDir)); } catch (Exception e) { String msg = "Exception while submitting directory request. " + "path=[" + folder.Repository.FileContents + "]"; LOGGER.Error (e); } } private void SendFileRequest (ICommandConnection connection, Entry entry) { // bool fileExists; DateTime old = entry.TimeStamp; entry.TimeStamp = entry.TimeStamp; // try { // fileExists = File.Exists (entry.Filename); // } // catch (Exception e) { // LOGGER.Error (e); // fileExists = false; // } // if (!fileExists) { connection.SubmitRequest (new EntryRequest (entry)); // } else if (File.GetLastAccessTime(entry.Filename) != // entry.TimeStamp.ToUniversalTime ()) { connection.SubmitRequest(new ModifiedRequest(entry.Name)); connection.SendFile(entry.FullPath, entry.IsBinaryFile); // } else { // connection.SubmitRequest(new EntryRequest(entry)); // connection.SubmitRequest(new UnchangedRequest(entry.Name)); // } entry.TimeStamp = old; } } } Index: CheckoutModuleCommand.cs =================================================================== RCS file: /cvsroot/sharpcvslib/sharpcvslib/src/ICSharpCode/SharpCvsLib/Commands/CheckoutModuleCommand.cs,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** CheckoutModuleCommand.cs 19 Nov 2003 02:42:52 -0000 1.12 --- CheckoutModuleCommand.cs 5 Dec 2003 05:27:51 -0000 1.13 *************** *** 64,69 **** /// </summary> /// <param name="connection">Server connection</param> ! public void Execute(ICommandConnection connection) ! { workingDirectory.Clear(); --- 64,68 ---- /// </summary> /// <param name="connection">Server connection</param> ! public void Execute(ICommandConnection connection) { workingDirectory.Clear(); *************** *** 102,106 **** connection.SubmitRequest(new CheckoutRequest()); ! Manager manager = new Manager (); if (LOGGER.IsDebugEnabled) { LOGGER.Debug ("looking for directories to add to the " + --- 101,105 ---- connection.SubmitRequest(new CheckoutRequest()); ! Manager manager = new Manager (connection.Repository.WorkingPath); if (LOGGER.IsDebugEnabled) { LOGGER.Debug ("looking for directories to add to the " + *************** *** 108,112 **** this.workingDirectory.WorkingPath + "]"); } ! manager.AddDirectories (this.workingDirectory.WorkingPath); } --- 107,111 ---- this.workingDirectory.WorkingPath + "]"); } ! //manager.AddDirectories (this.workingDirectory.WorkingPath); } Index: CommitCommand.cs =================================================================== RCS file: /cvsroot/sharpcvslib/sharpcvslib/src/ICSharpCode/SharpCvsLib/Commands/CommitCommand.cs,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** CommitCommand.cs 5 Nov 2003 08:07:39 -0000 1.5 --- CommitCommand.cs 5 Dec 2003 05:27:51 -0000 1.6 *************** *** 46,149 **** namespace ICSharpCode.SharpCvsLib.Commands { - - /// <summary> - /// Commit command - /// </summary> - public class CommitCommand2 : ICommand - { - private readonly ILog LOGGER = LogManager.GetLogger (typeof (CommitCommand2)); - private WorkingDirectory workingdirectory; - private string logmessage; - private string vendor = "vendor"; - private string release = "release"; - /// <summary> ! /// Log message /// </summary> ! public string LogMessage { ! get { ! return logmessage; ! } ! set { ! logmessage = value; ! } ! } ! /// <summary> ! /// Vendor string ! /// </summary> ! public string VendorString { ! get { ! return vendor; } ! set { ! vendor = value; } - } ! /// <summary> ! /// Release String ! /// </summary> ! public string ReleaseString { ! get { ! return release; } ! set { ! release = value; } - } ! /// <summary> ! /// Commit command two constructor ! /// </summary> ! /// <param name="workingdirectory"></param> ! public CommitCommand2(WorkingDirectory workingdirectory) ! { ! this.workingdirectory = workingdirectory; ! } ! /// <summary> ! /// Execute the commit command ! /// </summary> ! /// <param name="connection">Cvs server connection</param> ! public void Execute(ICommandConnection connection) ! { ! connection.SubmitRequest(new CaseRequest()); ! connection.SubmitRequest(new ArgumentRequest("-m")); ! connection.SubmitRequest(new ArgumentRequest("LOG MESSAGE")); ! StringCollection files = new StringCollection(); ! if (LOGGER.IsDebugEnabled) { ! LOGGER.Debug("workdir cvs repository : " + ! workingdirectory.CvsRoot.CvsRepository); ! } ! foreach (DictionaryEntry folder in workingdirectory.Folders) { ! foreach (Entry entry in ((Folder)folder.Value).Entries) { ! if (!entry.IsDirectory) { ! DateTime old = entry.TimeStamp; ! entry.TimeStamp = entry.TimeStamp; ! string path = Path.Combine (workingdirectory.CvsRoot.CvsRepository, ! folder.Key.ToString()); ! string fileName = Path.Combine (path,entry.Name); ! if (File.GetLastAccessTime(fileName) != entry.TimeStamp) { ! connection.SubmitRequest(new DirectoryRequest(".", path)); ! connection.SubmitRequest(new EntryRequest(entry)); ! connection.SubmitRequest(new ModifiedRequest(entry.Name)); ! files.Add(entry.Name); ! connection.SendFile(fileName, entry.IsBinaryFile); } ! entry.TimeStamp = old; } } } ! // connection.SubmitRequest(new DirectoryRequest(".", workingdirectory.CvsRoot.CvsRepository)); ! foreach (string file in files) { ! connection.SubmitRequest(new ArgumentRequest(file)); } ! connection.SubmitRequest(new CommitRequest()); } - } } --- 46,211 ---- namespace ICSharpCode.SharpCvsLib.Commands { /// <summary> ! /// Commit command /// </summary> ! public class CommitCommand2 : ICommand ! { ! private readonly ILog LOGGER = LogManager.GetLogger (typeof (CommitCommand2)); ! private WorkingDirectory workingdirectory; ! private string logmessage; ! private string vendor = "vendor"; ! private string release = "release"; ! /// <summary> ! /// Log message ! /// </summary> ! public string LogMessage { ! get { ! return logmessage; ! } ! set { ! logmessage = value; ! } } ! ! /// <summary> ! /// Vendor string ! /// </summary> ! public string VendorString { ! get { ! return vendor; ! } ! set { ! vendor = value; ! } } ! /// <summary> ! /// Release String ! /// </summary> ! public string ReleaseString { ! get { ! return release; ! } ! set { ! release = value; ! } } ! ! /// <summary> ! /// Commit command two constructor ! /// </summary> ! /// <param name="workingdirectory"></param> ! public CommitCommand2(WorkingDirectory workingdirectory) ! { ! this.workingdirectory = workingdirectory; } ! /// <summary> ! /// Execute the commit command ! /// </summary> ! /// <param name="connection">Cvs server connection</param> ! public void Execute(ICommandConnection connection) { ! connection.SubmitRequest(new ArgumentRequest("-m")); ! connection.SubmitRequest(new ArgumentRequest("LOG MESSAGE")); ! connection.SubmitRequest(new ArgumentRequest(ArgumentRequest.Options.DASH)); ! // StringCollection files = new StringCollection(); ! // if (LOGGER.IsDebugEnabled) { ! // LOGGER.Debug("workdir cvs repository : " + ! // workingdirectory.CvsRoot.CvsRepository); ! // } ! // connection.SubmitRequest(new DirectoryRequest(".", workingdirectory.CvsRoot.CvsRepository)); ! foreach (DictionaryEntry folderEntry in workingdirectory.Folders) { ! Folder folder = (Folder)folderEntry.Value; ! this.SetDirectory(connection, folder); ! // connection.SubmitRequest(new DirectoryRequest(".", ! // workingdirectory.CvsRoot.CvsRepository + "/" + ! // folder.Repository.FileContents)); ! foreach (DictionaryEntry entryEntry in folder.Entries) { ! Entry entry = (Entry)entryEntry.Value; ! LOGGER.Debug("Commit command. Entry=[" + entry + "]"); ! LOGGER.Debug("entry.FullPath=[" + entry.FullPath + "]"); ! if (!entry.IsDirectory) { ! this.SendFileRequest(connection, entry); ! // DateTime old = entry.TimeStamp; ! // entry.TimeStamp = entry.TimeStamp; ! // string path = Path.Combine (workingdirectory.CvsRoot.CvsRepository, ! // folderEntry.Key.ToString()); ! // string fileName = entry.FullPath; ! // if (File.GetLastAccessTime(fileName) != entry.TimeStamp) { ! // connection.SubmitRequest(new EntryRequest(entry)); ! // connection.SubmitRequest(new ModifiedRequest(entry.Name)); ! // files.Add(entry.Name); ! // connection.SendFile(fileName, entry.IsBinaryFile); ! // } ! // entry.TimeStamp = old; } + } ! this.SetDirectory(connection, folder); ! // connection.SubmitRequest(new DirectoryRequest(".", ! // workingdirectory.CvsRoot.CvsRepository + "/" + ! // folder.Repository.FileContents)); ! ! foreach (DictionaryEntry entryEntry in folder.Entries) { ! Entry entry = (Entry)entryEntry.Value; ! if (!entry.IsDirectory) { ! // if (File.GetLastAccessTime(fileName) != entry.TimeStamp) { ! connection.SubmitRequest(new ArgumentRequest(entry.Name)); ! // } ! } } } + connection.SubmitRequest(new CommitRequest()); } ! ! private void SetDirectory (ICommandConnection connection, ! Folder folder) { ! String absoluteDir = ! connection.Repository.CvsRoot.CvsRepository + "/" + ! folder.Repository.FileContents; ! ! try { ! connection.SubmitRequest(new DirectoryRequest(".", ! absoluteDir)); ! } ! catch (Exception e) { ! String msg = "Exception while submitting directory request. " + ! "path=[" + folder.Repository.FileContents + "]"; ! LOGGER.Error (e); ! } } ! ! private void SendFileRequest (ICommandConnection connection, ! Entry entry) { ! // bool fileExists; ! DateTime old = entry.TimeStamp; ! entry.TimeStamp = entry.TimeStamp; ! // try { ! // fileExists = File.Exists (entry.Filename); ! // } ! // catch (Exception e) { ! // LOGGER.Error (e); ! // fileExists = false; ! // } ! ! // if (!fileExists) { ! connection.SubmitRequest (new EntryRequest (entry)); ! // } else if (File.GetLastAccessTime(entry.Filename) != ! // entry.TimeStamp.ToUniversalTime ()) { ! connection.SubmitRequest(new ModifiedRequest(entry.Name)); ! connection.SendFile(entry.FullPath, entry.IsBinaryFile); ! // } else { ! // connection.SubmitRequest(new EntryRequest(entry)); ! // connection.SubmitRequest(new UnchangedRequest(entry.Name)); ! // } ! ! entry.TimeStamp = old; ! } ! } } Index: UpdateCommand.cs =================================================================== RCS file: /cvsroot/sharpcvslib/sharpcvslib/src/ICSharpCode/SharpCvsLib/Commands/UpdateCommand.cs,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** UpdateCommand.cs 26 Nov 2003 05:33:52 -0000 1.16 --- UpdateCommand.cs 5 Dec 2003 05:27:51 -0000 1.17 *************** *** 145,149 **** entry.TimeStamp = entry.TimeStamp; ! String fileName = Path.Combine(entry.Path, entry.Name); this.SendFileRequest (connection, entry); } --- 145,149 ---- entry.TimeStamp = entry.TimeStamp; ! String fileName = entry.FullPath; this.SendFileRequest (connection, entry); } *************** *** 178,182 **** entry.TimeStamp = entry.TimeStamp; try { ! fileExists = File.Exists (entry.Filename); } catch (Exception e) { --- 178,182 ---- entry.TimeStamp = entry.TimeStamp; try { ! fileExists = File.Exists (entry.FullPath); } catch (Exception e) { *************** *** 187,194 **** if (!fileExists) { connection.SubmitRequest (new EntryRequest (entry)); ! } else if (File.GetLastAccessTime(entry.Filename) != entry.TimeStamp.ToUniversalTime ()) { connection.SubmitRequest(new ModifiedRequest(entry.Name)); ! connection.SendFile(entry.Filename, entry.IsBinaryFile); } else { connection.SubmitRequest(new EntryRequest(entry)); --- 187,194 ---- if (!fileExists) { connection.SubmitRequest (new EntryRequest (entry)); ! } else if (File.GetLastAccessTime(entry.FullPath) != entry.TimeStamp.ToUniversalTime ()) { connection.SubmitRequest(new ModifiedRequest(entry.Name)); ! connection.SendFile(entry.FullPath, entry.IsBinaryFile); } else { connection.SubmitRequest(new EntryRequest(entry)); |