nil4 / dotnet-transform-xdt

Modern .NET tools and library for XDT (Xml Document Transformation)
Apache License 2.0
118 stars 12 forks source link

Refactor into library (netstandard20) and tool (netcoreapp21) #25

Closed nil4 closed 6 years ago

nil4 commented 6 years ago

Hopefully address #22 /cc @ericwj

ericwj commented 6 years ago

You can just download dotnet-sdk-2.1.300-win-x64.zip and run

Expand-Archive dotnet-sdk-2.1.300-win-x64.zip $PWD
$env:Path = $PWD + ";" + $env:Path
nil4 commented 6 years ago

@ericwj thanks for the hint, managed to get the build working. Packages are available at https://ci.appveyor.com/project/nil4/dotnet-transform-xdt/build/2.1.33/artifacts if you'd like to test.

ericwj commented 6 years ago

How does this work? I see two packages with the exact same name and url?

If they are different they cannot differ just by case. That wouldn't work for crossplat.

ericwj commented 6 years ago

You can define the <VersionPrefix> and <VersionSuffix> separately such that you can set the latter to e.g. dev for local builds on your machine in the project file (so you get latest from your machine when restoring) and to ci for CI builds or to empty if you are doing a release by using dotnet build /p:VersionSuffix="" - in which case you can have the build also push to NuGet.

nil4 commented 6 years ago

Looking at the the latest 2.1.0-preview.2 artifacts:

The package names are different. DotNet.Xdt (with a dot) is the library.

dotnet-xdt (with a dash) matches the CLI tool conventions; i.e. you install it, and then can invoke it either as:

dotnet-xdt [args]

or

dotnet.exe xdt [args]
ericwj commented 6 years ago

I would make the standalone one not look like a dotnet CLI tool and strip the dotnet- prefix: xdt.exe.

Mmm exes are tricky. I won't be having .NET 4.6.1 on the server. Just .NET Core.

A portable app in a .zip would be great. Or if you feel like building for the whole lot of OS's supported by .NET Core add any number of TFM's/RID's you like (I recommend win-x64) and get it on the CI server with just

$x = [xml]::new()
$x.Load("Project.csproj")
$tfms = $x.Project.PropertyGroup.TargetFrameworks -split ';'
ericwj commented 6 years ago

Can I be a lazy boy and just dump this on you.

    public class TextWriterTransformmationLogger : IXmlTransformationLogger
    {
        readonly TextWriter _defaultWriter;
        readonly TextWriter _errorWriter;
        readonly bool _verbose;
        readonly string _prefix;
        readonly string _warning;
        readonly string _error;
        readonly string _start;
        readonly string _end;

        public TextWriterTransformmationLogger(TextWriter defaultWriter, TextWriter errorWriter, bool verbose = false, string prefix = "[XDT] ", string warning = "WARN", string error = "ERROR", string start = "Start", string end = "End")
        {
            if (defaultWriter is null) throw new ArgumentNullException(nameof(defaultWriter));
            if (errorWriter is null) throw new ArgumentNullException(nameof(errorWriter));
            _defaultWriter = defaultWriter;
            _errorWriter = errorWriter;
            _verbose = verbose;
            _prefix = prefix;
            _warning = warning;
            _error = error;
            _start = start;
            _end = end;
        }

        bool ShouldPrint(MessageType type)
            => type == MessageType.Normal || _verbose;

        public void LogMessage(string message, params object[] messageArgs)
            => _defaultWriter.WriteLine(_prefix + message, messageArgs);

        public void LogMessage(MessageType type, string message, params object[] messageArgs)
        {
            if (ShouldPrint(type)) _defaultWriter.WriteLine($"{_prefix}{type}: {message}", messageArgs);
        }

        public void LogWarning(string message, params object[] messageArgs)
            => _defaultWriter.WriteLine($"{_prefix}{_warning}: {message}", messageArgs);

        public void LogWarning(string file, string message, params object[] messageArgs)
            => _defaultWriter.WriteLine($"{_prefix}{_warning} '{file}': {message}", messageArgs);

        public void LogWarning(string file, int lineNumber, int linePosition, string message, params object[] messageArgs)
            => _defaultWriter.WriteLine($"{_prefix}{_warning} '{file}':{lineNumber}:{linePosition}: {message}", messageArgs);

        public void LogError(string message, params object[] messageArgs)
            => _errorWriter.WriteLine($"{_prefix}{_error}: {message}", messageArgs);

        public void LogError(string file, string message, params object[] messageArgs)
            => _errorWriter.WriteLine($"{_prefix}{_error} '{file}': {message}", messageArgs);

        public void LogError(string file, int lineNumber, int linePosition, string message, params object[] messageArgs)
            => _errorWriter.WriteLine($"{_prefix}{_error} '{file}':{lineNumber}:{linePosition}: {message}", messageArgs);

        public void LogErrorFromException(Exception ex)
            => _errorWriter.WriteLine($"{_prefix}{_error}: {ex}");

        public void LogErrorFromException(Exception ex, string file)
            => _errorWriter.WriteLine($"{_prefix}{_error} '{file}': {ex}");

        public void LogErrorFromException(Exception ex, string file, int lineNumber, int linePosition)
            => _errorWriter.WriteLine($"{_prefix}{_error} '{file}':{lineNumber}:{linePosition}: {ex}");

        public void StartSection(string message, params object[] messageArgs)
            => _defaultWriter.WriteLine($"{_prefix}{_start} {message}", messageArgs);

        public void StartSection(MessageType type, string message, params object[] messageArgs)
        {
            if (ShouldPrint(type)) _defaultWriter.WriteLine($"{_prefix}{type}: {_start} {message}", messageArgs);
        }

        public void EndSection(string message, params object[] messageArgs)
            => _defaultWriter.WriteLine($"{_prefix}{_end} {message}", messageArgs);

        public void EndSection(MessageType type, string message, params object[] messageArgs)
        {
            if (ShouldPrint(type)) _defaultWriter.WriteLine($"{_prefix}{type}: {_end} {message}", messageArgs);
        }
    }
    public class ConsoleTransformationLogger : TextWriterTransformmationLogger
    {
        public ConsoleTransformationLogger(bool verbose = false, string prefix = "[XDT] ", string warning = "WARN", string error = "ERROR", string start = "Start", string end = "End")
            : base(Console.Out, Console.Error, verbose, prefix, warning, error, start, end) { }
    }
    public class NullTransformationLogger : IXmlTransformationLogger
    {
        public static NullTransformationLogger Instance { get; } = new NullTransformationLogger();

        public void EndSection(string message, params object[] messageArgs) { }
        public void EndSection(MessageType type, string message, params object[] messageArgs) { }
        public void LogError(string message, params object[] messageArgs) { }
        public void LogError(string file, string message, params object[] messageArgs) { }
        public void LogError(string file, int lineNumber, int linePosition, string message, params object[] messageArgs) { }
        public void LogErrorFromException(Exception ex) { }
        public void LogErrorFromException(Exception ex, string file) { }
        public void LogErrorFromException(Exception ex, string file, int lineNumber, int linePosition) { }
        public void LogMessage(string message, params object[] messageArgs) { }
        public void LogMessage(MessageType type, string message, params object[] messageArgs) { }
        public void LogWarning(string message, params object[] messageArgs) { }
        public void LogWarning(string file, string message, params object[] messageArgs) { }
        public void LogWarning(string file, int lineNumber, int linePosition, string message, params object[] messageArgs) { }
        public void StartSection(string message, params object[] messageArgs) { }
        public void StartSection(MessageType type, string message, params object[] messageArgs) { }
    }
ericwj commented 6 years ago

If you feel like taking a dependency on Microsoft.Extensions.Logging.Abstractions or adding a project for that purpose I have one that writes to an ILogger, too.

nil4 commented 6 years ago

I'm afraid not, that's about as far as I'll take it for now.

Version 2.1.0-preview.2 of both the CLI tool and the .NET Standard library are published (but currently unlisted) on NuGet. You can install the tool with:

dotnet tool install --global dotnet-xdt --version 2.1.0-preview.2

Or reference the DotNet.Xdt library in your app (or custom command-line tool):

dotnet add package DotNet.Xdt --version 2.1.0-preview.2 

I hope to publish listed/stable versions sometime later this month, after I've had a chance to test a bit more. Would be good to hear if it works out for your use case.

ericwj commented 6 years ago

Thanks,

This looks good, though I will end up copying Program.cs if there is no portable version to download.

I will use the .NET 461 version where I can.

nil4 commented 6 years ago

Version 2.1.0-rc.1 includes:

The classic dotnet-transform-xdt remains available at version 2.0, and can still be used as a project-level XDT tool for past and current .NET Core versions.

Fixes #19