Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Report DacModelExceptions better, and continue processing all files #598

Merged
merged 6 commits into from
Aug 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ jobs:
ports:
- 1433:1433
options: >-
--health-cmd "/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P 'JdMsKZPBBA8kVFXVrj8d' -Q 'SELECT 1' || exit 1"
--health-cmd "/opt/mssql-tools18/bin/sqlcmd -C -S localhost -U sa -P 'JdMsKZPBBA8kVFXVrj8d' -Q 'SELECT 1' || exit 1"
--health-interval 10s
--health-timeout 3s
--health-retries 10
Expand Down Expand Up @@ -267,7 +267,7 @@ jobs:
ports:
- 1433:1433
options: >-
--health-cmd "/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P 'JdMsKZPBBA8kVFXVrj8d' -Q 'SELECT 1' || exit 1"
--health-cmd "/opt/mssql-tools18/bin/sqlcmd -C -S localhost -U sa -P 'JdMsKZPBBA8kVFXVrj8d' -Q 'SELECT 1' || exit 1"
--health-interval 10s
--health-timeout 3s
--health-retries 10
Expand Down
24 changes: 24 additions & 0 deletions src/DacpacTool/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,30 @@ public static string Format(this BatchParserExecutionErrorEventArgs args, string
return outputMessageBuilder.ToString();
}

public static string Format(this DacModelException exception, string fileName)
{
var stringBuilder = new StringBuilder();

foreach (var modelError in exception.Messages)
{
stringBuilder.Append(fileName);
stringBuilder.Append('(');
ErikEJ marked this conversation as resolved.
Show resolved Hide resolved
stringBuilder.Append("1");
stringBuilder.Append(',');
stringBuilder.Append("1");
stringBuilder.Append("):");
stringBuilder.Append(' ');
stringBuilder.Append("Error");
stringBuilder.Append(' ');
stringBuilder.Append(modelError.Prefix);
stringBuilder.Append(modelError.Number);
stringBuilder.Append(": ");
stringBuilder.Append(modelError.Message);
}

return stringBuilder.ToString();
}

public static string GetPreDeploymentScript(this DacPackage package)
{
var stream = package.PreDeploymentScript;
Expand Down
49 changes: 33 additions & 16 deletions src/DacpacTool/PackageBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,21 @@ namespace MSBuild.Sdk.SqlProj.DacpacTool
{
public sealed class PackageBuilder : IDisposable
{
private readonly IConsole _console;
private bool? _modelValid;

private List<int> _suppressedWarnings = new ();
private Dictionary<string,List<int>> _suppressedFileWarnings = new Dictionary<string, List<int>>(StringComparer.InvariantCultureIgnoreCase);

public PackageBuilder(IConsole console)
{
_console = console ?? throw new ArgumentNullException(nameof(console));
}

public void UsingVersion(SqlServerVersion version)
{
Model = new TSqlModel(version, Options);
Console.WriteLine($"Using SQL Server version {version}");
_console.WriteLine($"Using SQL Server version {version}");
}

public void AddReference(string referenceFile, string externalParts = null, bool suppressErrorsForMissingDependencies = false)
Expand All @@ -30,7 +36,7 @@ public void AddReference(string referenceFile, string externalParts = null, bool

ValidateReference(referenceFile);

Console.WriteLine($"Adding reference to {referenceFile} with external parts {externalParts} and SuppressMissingDependenciesErrors {suppressErrorsForMissingDependencies}");
_console.WriteLine($"Adding reference to {referenceFile} with external parts {externalParts} and SuppressMissingDependenciesErrors {suppressErrorsForMissingDependencies}");
Model.AddReference(referenceFile, externalParts, suppressErrorsForMissingDependencies);
}

Expand Down Expand Up @@ -58,7 +64,7 @@ public void AddSqlCmdVariables(string[] variables)
Model.AddSqlCmdVariables(variables);
}

public void AddInputFile(FileInfo inputFile)
public bool AddInputFile(FileInfo inputFile)
{
// Ensure that the model has been created
EnsureModelCreated();
Expand All @@ -73,11 +79,22 @@ public void AddInputFile(FileInfo inputFile)
if (inputFile.Directory.Name.Equals("rules", StringComparison.OrdinalIgnoreCase)
&& inputFile.Extension.EndsWith(".dll", StringComparison.OrdinalIgnoreCase))
{
return;
return true;
}

Console.WriteLine($"Adding {inputFile.FullName} to the model");
Model.AddOrUpdateObjects(File.ReadAllText(inputFile.FullName), inputFile.FullName, new TSqlObjectOptions());
_console.WriteLine($"Adding {inputFile.FullName} to the model");

try
{
TSqlObjectOptions sqlObjectOptions = new TSqlObjectOptions();
Model.AddOrUpdateObjects(File.ReadAllText(inputFile.FullName), inputFile.FullName, new TSqlObjectOptions());
return true;
}
catch (DacModelException dex)
{
_console.WriteLine(dex.Format(inputFile.Name));
return false;
}
}

public void AddPreDeploymentScript(FileInfo script, FileInfo outputFile)
Expand All @@ -103,22 +120,22 @@ public bool ValidateModel()
if (modelError.Severity == ModelErrorSeverity.Error)
{
validationErrors++;
Console.WriteLine(modelError.GetOutputMessage(modelError.Severity));
_console.WriteLine(modelError.GetOutputMessage(modelError.Severity));
}
else if (modelError.Severity == ModelErrorSeverity.Warning)
{
ProcessWarning(modelError);
}
else
{
Console.WriteLine(modelError.GetOutputMessage(modelError.Severity));
_console.WriteLine(modelError.GetOutputMessage(modelError.Severity));
}
}

if (validationErrors > 0)
{
_modelValid = false;
Console.WriteLine($"Found {validationErrors} error(s), skip building package");
_console.WriteLine($"Found {validationErrors} error(s), skip building package");
}
else
{
Expand All @@ -140,7 +157,7 @@ void ProcessWarning(ModelValidationError modelError)
validationErrors++;
}

Console.WriteLine(modelError.GetOutputMessage(TreatTSqlWarningsAsErrors
_console.WriteLine(modelError.GetOutputMessage(TreatTSqlWarningsAsErrors
? ModelErrorSeverity.Error
: ModelErrorSeverity.Warning));
}
Expand All @@ -157,11 +174,11 @@ public void SaveToDisk(FileInfo outputFile, PackageOptions packageOptions = null
if (outputFile.Exists)
{
// Delete the existing file
Console.WriteLine($"Deleting existing file {outputFile.FullName}");
_console.WriteLine($"Deleting existing file {outputFile.FullName}");
outputFile.Delete();
}

Console.WriteLine($"Writing model to {outputFile.FullName}");
_console.WriteLine($"Writing model to {outputFile.FullName}");
DacPackageExtensions.BuildPackage(outputFile.FullName, Model, Metadata, packageOptions ?? new PackageOptions { });
}

Expand All @@ -173,7 +190,7 @@ public void SetMetadata(string name, string version)
Version = version,
};

Console.WriteLine($"Using package name {name} and version {version}");
_console.WriteLine($"Using package name {name} and version {version}");
}

public void SetProperty(string key, string value)
Expand Down Expand Up @@ -258,7 +275,7 @@ public void SetProperty(string key, string value)
PropertyInfo property = typeof(TSqlModelOptions).GetProperty(key, BindingFlags.Public | BindingFlags.Instance);
property.SetValue(Options, propertyValue);

Console.WriteLine($"Setting property {key} to value {value}");
_console.WriteLine($"Setting property {key} to value {value}");
}
catch (FormatException)
{
Expand Down Expand Up @@ -320,7 +337,7 @@ private void AddScript(FileInfo script, FileInfo outputFile, string path)

using (var package = Package.Open(outputFile.FullName, FileMode.Open, FileAccess.ReadWrite))
{
Console.WriteLine($"Adding {script.FullName} to package");
_console.WriteLine($"Adding {script.FullName} to package");
WritePart(script, package, path);

package.Close();
Expand Down Expand Up @@ -388,7 +405,7 @@ public void GenerateCreateScript(FileInfo dacpacFile, string databaseName, DacDe
}

var scriptFileName = $"{databaseName}_Create.sql";
Console.WriteLine($"Generating create script {scriptFileName}");
_console.WriteLine($"Generating create script {scriptFileName}");

using var package = DacPackage.Load(dacpacFile.FullName);
using var file = File.Create(Path.Combine(dacpacFile.DirectoryName, scriptFileName));
Expand Down
11 changes: 8 additions & 3 deletions src/DacpacTool/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ private static int BuildDacpac(BuildOptions options)
WaitForDebuggerToAttach(options);

// Set metadata for the package
using var packageBuilder = new PackageBuilder();
using var packageBuilder = new PackageBuilder(new ActualConsole());
packageBuilder.SetMetadata(options.Name, options.Version);

// Set properties on the model (if defined)
Expand Down Expand Up @@ -134,6 +134,8 @@ private static int BuildDacpac(BuildOptions options)
packageBuilder.AddSqlCmdVariables(options.SqlCmdVar);
}

var modelExceptions = false;

// Add input files by iterating through $Project.InputFiles.txt
if (options.InputFile != null)
{
Expand All @@ -142,7 +144,10 @@ private static int BuildDacpac(BuildOptions options)
foreach (var line in File.ReadLines(options.InputFile.FullName))
{
FileInfo inputFile = new FileInfo(line); // Validation occurs in AddInputFile
packageBuilder.AddInputFile(inputFile);
if (!packageBuilder.AddInputFile(inputFile))
{
modelExceptions = true;
}
}
}
else
Expand Down Expand Up @@ -176,7 +181,7 @@ private static int BuildDacpac(BuildOptions options)
}

// Validate the model
if (!packageBuilder.ValidateModel())
if (modelExceptions || !packageBuilder.ValidateModel())
{
return 1;
}
Expand Down
Loading