Now that .NET Core 1.0 is released I find myself coding more and more in .NET Core instead of Windows PowerShell scripts for every day automation. When you are developing you spend a portion of your time setting up environments, renaming, copying, processing files and folders, for that I used to write Windows PowerShell scripts.
With the release of .NET Core and its excellent command line and Visual Studio Code support, I’m writing plain old C#, but with dotnet run I can alter a C# file on the fly and run it immediately.
Plus the C# code is portable between my Windows Desktop, Mac Book Pro laptop and Linux servers, very nice!
Some examples
Deleting *.css files (excluding the libraries folder)
When you are writing your code in CSS Next you want to keep the CSS Next files in source control, but you don’t want to add the compiled css files in source control, to delete existing css files in a “App” folder, but not the css files in “App/Libraries” I wrote a little .NET Core code:
public
void DeleteCssFiles() {
string projectFolder = @”C:\Projects\MyWebApp”;
string appFolder = Path.Combine(projectFolder, “App”);
string librariesFolder = Path.Combine(appFolder, “Libraries”);
string csprojPath = Path.Combine(projectFolder, @” MyWebApp.csproj”);
int fileCounter = 0;
var files = FindFiles(new
DirectoryInfo(appFolder), “*.css”); // This will get *.css and *.cssn files on Windows, don’t know why.
foreach (FileInfo file in files)
{
if(
!file.FullName.StartsWith(librariesFolder) &&
!file.FullName.EndsWith(“.cssn”)
){
fileCounter++;
File.Delete(file.FullName);
Console.WriteLine($”Delete {file.FullName}“);
}
}
Console.WriteLine($”Total *.css files deleted = {fileCounter}“);
}
Rename all *.css files in the *.csproj file to *.cssn files (excluding the libraries folder) and make them build action “None”
Public async
Task RenameCssToCssnInCsProj() {
string projectFolder = @”C:\Projects\MyWebApp “;
string appFolder = Path.Combine(projectFolder, “App”);
string librariesFolder = Path.Combine(appFolder, “Libraries”);
string csprojPath = Path.Combine(projectFolder, @” MyWebApp.csproj”);
string csprojContent = File.ReadAllText(csprojPath);
int fileCounter = 0;
var files = FindFiles(new
DirectoryInfo(appFolder), “*.css”); // This will get *.css and *.cssn files on Windows, don’t know why.
foreach (FileInfo file in files)
{
var cssnPath = Path.ChangeExtension(file.FullName, “.cssn”);
if(
!file.FullName.StartsWith(librariesFolder)
){
fileCounter++;
string relativePath = file.FullName.Replace(projectFolder + @”\”, string.Empty);
string relativePathCssn = Path.ChangeExtension(relativePath, “.cssn”);
string find = $”<Content Include=\”{relativePath}\” />”;
if(csprojContent.Contains(find))
{
string replace = $”<None Include=\”{relativePathCssn}\” />”;
Console.WriteLine($”find {find}“);
Console.WriteLine($”replace {replace}“);
csprojContent = csprojContent.Replace(find, replace);
}
await CreateOrUpdateFile(csprojPath, csprojContent);
}
}
Console.WriteLine($”Total *.css files = {fileCounter}“);
}
Converting all css files in a Web Application to CSS Next files (where each CSS Next file depends on a shared “variables.cssn” file.
public
async
Task RenameCssToCssnOnDisk() {
string projectFolder = @”C:\Projects\ZvdZ\zvdzonline\Source\ZvdZOnline\ZvdZOnline.Web”;
string appFolder = Path.Combine(projectFolder, “App”);
string librariesFolder = Path.Combine(appFolder, “Libraries”);
int fileCounter = 0;
var files = FindFiles(new
DirectoryInfo(projectFolder), “*.css”); // This will get *.css and *.cssn files, don’t know why.
foreach (FileInfo file in files)
{
var cssnPath = Path.ChangeExtension(file.FullName, “.cssn”);
if(
!file.FullName.StartsWith(librariesFolder) &&
!File.Exists(cssnPath)
){
fileCounter++;
string relativePath = file.FullName.Replace(projectFolder, string.Empty);
Console.WriteLine($”relativePath {relativePath}“);
int seperatorCounter = relativePath.Split(@”\”.ToCharArray()).Length – 1;
Console.WriteLine($”seperatorCounter {seperatorCounter}“);
// Determine the “import” variables line, that should be added to each CSS Next file.
string relativePrefix = string.Empty;
for(var i = 0; i< seperatorCounter; i++) {
relativePrefix += “../”;
}
string importText = $”@import \”{relativePrefix}App/Styles/variables.cssn\”;”;
Console.WriteLine($”importText {importText}“);
string content = File.ReadAllText(file.FullName);
await CreateOrUpdateFile(cssnPath, importText + Environment.NewLine + Environment.NewLine + content );
}
}
Console.WriteLine($”Total *.css files renamed = {fileCounter}“);
}
Some Generic function used in the examples above
public
async
Task CreateOrUpdateFile(string path, string content)
{
byte[] result = Encoding.UTF8.GetBytes(content);
using (var stream = new
FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Write, bufferSize: 4096, useAsync: true))
{
await stream.WriteAsync(result, 0, result.Length);
}
}
public
IEnumerable<FileInfo> FindFiles(DirectoryInfo folder, string pattern)
{
// Note: using EnumerateFiles is faster then using “GetFiles”.
return folder.EnumerateFiles(pattern, SearchOption.AllDirectories);
}