#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 {
/// Deletes files from a working copy
[TaskName("subversion-delete")]
public class SubversionDeleteTask : Task {
/// Initializes a new subversion add task
public SubversionDeleteTask() {
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,
"Deleting {0} files from subversion working copy.",
this.fileSets.FileCount
);
for(int fileSetIndex = 0; fileSetIndex < this.fileSets.Count; ++fileSetIndex) {
FileSet fileSet = this.fileSets[fileSetIndex];
string fileList = createListOfFilesToDelete(fileSet);
try {
string commandLine = string.Format(
"delete --targets {0} --no-auth-cache --non-interactive --force", fileList
);
Subversion.Run(fileSet.BaseDirectory.FullName, commandLine);
}
catch(InvalidOperationException exception) {
throw new BuildException(
"Error during Subversion delete 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 createListOfFilesToDelete(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) {
string relativePath = PathHelper.MakeRelative(
fileSet.BaseDirectory.FullName, fileSet.FileNames[fileIndex]
);
string absolutePath = Path.Combine(
fileSet.BaseDirectory.FullName, relativePath
);
if(File.Exists(absolutePath)) {
writer.WriteLine(relativePath);
} else {
this.Log(
Level.Warning,
"File '{0}' couldn't be deleted because it doesn't exist",
absolutePath
);
}
}
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