#region CPL License /* Nuclex.NAnt.Tasks Copyright (C) 2009 Nuclex Development Labs This library is free software; you can redistribute it and/or modify it under the terms of the IBM Common Public License as published by the IBM Corporation; either version 1.0 of the License, or (at your option) any later version. This library 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 IBM Common Public License for more details. You should have received a copy of the IBM Common Public License along with this library */ #endregion using System; using System.Collections.Generic; using System.IO; using System.Text; using Microsoft.Win32; using NAnt.Core; using NAnt.Core.Attributes; using NAnt.Core.Types; namespace Nuclex.NAnt.Tasks { /// Adds new files to a working copy [TaskName("subversion-add")] public class SubversionAddTask : Task { /// Initializes a new subversion add task public SubversionAddTask() { this.fileSets = new FileSetCollection(); } /// Files that will be compressed [BuildElementArray("fileset")] public FileSetCollection FileSets { get { return this.fileSets; } set { this.fileSets = value; } } /// Executes the task protected override void ExecuteTask() { this.Log( Level.Info, "Adding {0} files to subversion working copy.", this.fileSets.FileCount ); for(int fileSetIndex = 0; fileSetIndex < this.fileSets.Count; ++fileSetIndex) { FileSet fileSet = this.fileSets[fileSetIndex]; string fileList = createListOfFilesToAdd(fileSet); try { string commandLine = string.Format( "add --targets {0} --no-auth-cache --non-interactive", fileList ); Subversion.Run(fileSet.BaseDirectory.FullName, commandLine); } catch(InvalidOperationException exception) { throw new BuildException( "Error during Subversion add operation: " + exception.Message, this.Location ); } finally { File.Delete(fileList); } } } /// Creates a list of the files that need to be compressed /// /// File set whose file names will be written into a temporary text file /// /// The path to a temporary text file containing the list of files /// /// The caller is responsible for deleting the returned file again when it /// is no longer needed. /// private string createListOfFilesToAdd(FileSet fileSet) { // This generates a temporary filename and writes an actual empty file to // disk which ensures that noone else can get a temp file with this name. string tempFile = Path.GetTempFileName(); // Make sure the temporary file is deleted again if anything goes wrong try { using( FileStream tempFileStream = new FileStream( tempFile, FileMode.Truncate, FileAccess.Write, FileShare.None ) ) { StreamWriter writer = new StreamWriter(tempFileStream); // Write the relative paths of all files in the file set into our // temporary text file for(int fileIndex = 0; fileIndex < fileSet.FileNames.Count; ++fileIndex) { writer.WriteLine( PathHelper.MakeRelative( fileSet.BaseDirectory.FullName, fileSet.FileNames[fileIndex] ) ); } writer.Flush(); } } catch(Exception) { File.Delete(tempFile); throw; } // Nothing went wrong, leave the temporary file in place and return its path return tempFile; } /// Files that will be compressed private FileSetCollection fileSets; } } // namespace Nuclex.NAnt.Tasks