Skip to content

Commit

Permalink
Support the same 'Options' on bicep decompile as with bicep build (#2460
Browse files Browse the repository at this point in the history
)
  • Loading branch information
piraces authored May 7, 2021
1 parent fcf1e3b commit 117ae64
Show file tree
Hide file tree
Showing 12 changed files with 534 additions and 153 deletions.
308 changes: 255 additions & 53 deletions src/Bicep.Cli.IntegrationTests/DecompileTests.cs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/Bicep.Cli.IntegrationTests/ProgramTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ public void BuildInvalidInputPathsToStdOutShouldProduceExpectedError(string badP
public void LockedOutputFileShouldProduceExpectedError()
{
var inputFile = FileHelper.SaveResultFile(this.TestContext, "Empty.bicep", DataSets.Empty.Bicep);
var outputFile = PathHelper.GetDefaultOutputPath(inputFile);
var outputFile = PathHelper.GetDefaultBuildOutputPath(inputFile);

// ReSharper disable once ConvertToUsingDeclaration
using (new FileStream(outputFile, FileMode.Create, FileAccess.ReadWrite, FileShare.None))
Expand Down
132 changes: 103 additions & 29 deletions src/Bicep.Cli.UnitTests/ArgumentParserTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,16 @@ public void Wrong_command_should_return_null()
[DataRow(new [] { "build", "--stdout", "--outdir", "dir1", "file1" }, "The --outdir and --stdout parameters cannot both be used")]
[DataRow(new [] { "build", "--outfile", "dir1", "--outdir", "dir2", "file1" }, "The --outdir and --outfile parameters cannot both be used")]
[DataRow(new [] { "decompile" }, "The input file path was not specified")]
[DataRow(new [] { "decompile", "--stdout" }, "The input file path was not specified")]
[DataRow(new [] { "decompile", "file1", "file2" }, "The input file path cannot be specified multiple times")]
[DataRow(new [] { "decompile", "--wibble" }, "Unrecognized parameter \"--wibble\"")]
[DataRow(new [] { "decompile", "--outdir" }, "The --outdir parameter expects an argument")]
[DataRow(new [] { "decompile", "--outdir", "dir1", "--outdir", "dir2" }, "The --outdir parameter cannot be specified twice")]
[DataRow(new [] { "decompile", "--outfile" }, "The --outfile parameter expects an argument")]
[DataRow(new [] { "decompile", "--outfile", "dir1", "--outfile", "dir2" }, "The --outfile parameter cannot be specified twice")]
[DataRow(new [] { "decompile", "--stdout", "--outfile", "dir1", "file1" }, "The --outfile and --stdout parameters cannot both be used")]
[DataRow(new [] { "decompile", "--stdout", "--outdir", "dir1", "file1" }, "The --outdir and --stdout parameters cannot both be used")]
[DataRow(new [] { "decompile", "--outfile", "dir1", "--outdir", "dir2", "file1" }, "The --outdir and --outfile parameters cannot both be used")]
public void Invalid_args_trigger_validation_exceptions(string[] parameters, string expectedException)
{
Action parseFunc = () => ArgumentParser.TryParse(parameters);
Expand All @@ -90,66 +98,71 @@ public void Invalid_args_trigger_validation_exceptions(string[] parameters, stri
[TestMethod]
public void BuildOneFile_ShouldReturnOneFile()
{
var arguments = (BuildArguments?)ArgumentParser.TryParse(new[] {"build", "file1"});
var arguments = ArgumentParser.TryParse(new[] {"build", "file1"});
var bulidOrDecompileArguments = (BuildOrDecompileArguments?) arguments;

// using classic assert so R# understands the value is not null
Assert.IsNotNull(arguments);
arguments!.InputFile.Should().Be("file1");
arguments!.OutputToStdOut.Should().BeFalse();
arguments!.OutputDir.Should().BeNull();
arguments!.OutputFile.Should().BeNull();
bulidOrDecompileArguments!.InputFile.Should().Be("file1");
bulidOrDecompileArguments!.OutputToStdOut.Should().BeFalse();
bulidOrDecompileArguments!.OutputDir.Should().BeNull();
bulidOrDecompileArguments!.OutputFile.Should().BeNull();
}

[TestMethod]
public void BuildOneFileStdOut_ShouldReturnOneFileAndStdout()
{
var arguments = (BuildArguments?)ArgumentParser.TryParse(new[] {"build", "--stdout", "file1"});
var arguments = ArgumentParser.TryParse(new[] {"build", "--stdout", "file1"});
var bulidOrDecompileArguments = (BuildOrDecompileArguments?) arguments;

// using classic assert so R# understands the value is not null
Assert.IsNotNull(arguments);
arguments!.InputFile.Should().Be("file1");
arguments!.OutputToStdOut.Should().BeTrue();
arguments!.OutputDir.Should().BeNull();
arguments!.OutputFile.Should().BeNull();
bulidOrDecompileArguments!.InputFile.Should().Be("file1");
bulidOrDecompileArguments!.OutputToStdOut.Should().BeTrue();
bulidOrDecompileArguments!.OutputDir.Should().BeNull();
bulidOrDecompileArguments!.OutputFile.Should().BeNull();
}

[TestMethod]
public void BuildOneFileStdOutAllCaps_ShouldReturnOneFileAndStdout()
{
var arguments = (BuildArguments?)ArgumentParser.TryParse(new[] {"build", "--STDOUT", "file1"});
var arguments = ArgumentParser.TryParse(new[] {"build", "--STDOUT", "file1"});
var bulidOrDecompileArguments = (BuildOrDecompileArguments?) arguments;

// using classic assert so R# understands the value is not null
Assert.IsNotNull(arguments);
arguments!.InputFile.Should().Be("file1");
arguments!.OutputToStdOut.Should().BeTrue();
arguments!.OutputDir.Should().BeNull();
arguments!.OutputFile.Should().BeNull();
bulidOrDecompileArguments!.InputFile.Should().Be("file1");
bulidOrDecompileArguments!.OutputToStdOut.Should().BeTrue();
bulidOrDecompileArguments!.OutputDir.Should().BeNull();
bulidOrDecompileArguments!.OutputFile.Should().BeNull();
}

[TestMethod]
public void Build_with_outputdir_parameter_should_parse_correctly()
{
var arguments = (BuildArguments?)ArgumentParser.TryParse(new[] {"build", "--outdir", "outdir", "file1"});
var arguments = ArgumentParser.TryParse(new[] {"build", "--outdir", "outdir", "file1"});
var bulidOrDecompileArguments = (BuildOrDecompileArguments?) arguments;

// using classic assert so R# understands the value is not null
Assert.IsNotNull(arguments);
arguments!.InputFile.Should().Be("file1");
arguments!.OutputToStdOut.Should().BeFalse();
arguments!.OutputDir.Should().Be("outdir");
arguments!.OutputFile.Should().BeNull();
bulidOrDecompileArguments!.InputFile.Should().Be("file1");
bulidOrDecompileArguments!.OutputToStdOut.Should().BeFalse();
bulidOrDecompileArguments!.OutputDir.Should().Be("outdir");
bulidOrDecompileArguments!.OutputFile.Should().BeNull();
}

[TestMethod]
public void Build_with_outputfile_parameter_should_parse_correctly()
{
var arguments = (BuildArguments?)ArgumentParser.TryParse(new[] {"build", "--outfile", "jsonFile", "file1"});
var arguments = ArgumentParser.TryParse(new[] {"build", "--outfile", "jsonFile", "file1"});
var bulidOrDecompileArguments = (BuildOrDecompileArguments?) arguments;

// using classic assert so R# understands the value is not null
Assert.IsNotNull(arguments);
arguments!.InputFile.Should().Be("file1");
arguments!.OutputToStdOut.Should().BeFalse();
arguments!.OutputDir.Should().BeNull();
arguments!.OutputFile.Should().Be("jsonFile");
bulidOrDecompileArguments!.InputFile.Should().Be("file1");
bulidOrDecompileArguments!.OutputToStdOut.Should().BeFalse();
bulidOrDecompileArguments!.OutputDir.Should().BeNull();
bulidOrDecompileArguments!.OutputFile.Should().Be("jsonFile");
}

[TestMethod]
Expand Down Expand Up @@ -187,10 +200,71 @@ public void Help_argument_should_return_HelpShortArguments_instance()
[TestMethod]
public void DecompileOneFile_ShouldReturnOneFile()
{
var arguments = ArgumentParser.TryParse(new[] {"decompile", "file1"}) as DecompileArguments;
var arguments = ArgumentParser.TryParse(new[] {"build", "file1"});
var bulidOrDecompileArguments = (BuildOrDecompileArguments?) arguments;

arguments!.Should().NotBeNull();
arguments!.InputFile.Should().Be("file1");
// using classic assert so R# understands the value is not null
Assert.IsNotNull(arguments);
bulidOrDecompileArguments!.InputFile.Should().Be("file1");
bulidOrDecompileArguments!.OutputToStdOut.Should().BeFalse();
bulidOrDecompileArguments!.OutputDir.Should().BeNull();
bulidOrDecompileArguments!.OutputFile.Should().BeNull();
}

[TestMethod]
public void DecompileOneFileStdOut_ShouldReturnOneFileAndStdout()
{
var arguments = ArgumentParser.TryParse(new[] {"build", "--stdout", "file1"});
var bulidOrDecompileArguments = (BuildOrDecompileArguments?) arguments;

// using classic assert so R# understands the value is not null
Assert.IsNotNull(arguments);
bulidOrDecompileArguments!.InputFile.Should().Be("file1");
bulidOrDecompileArguments!.OutputToStdOut.Should().BeTrue();
bulidOrDecompileArguments!.OutputDir.Should().BeNull();
bulidOrDecompileArguments!.OutputFile.Should().BeNull();
}

[TestMethod]
public void DecompileOneFileStdOutAllCaps_ShouldReturnOneFileAndStdout()
{
var arguments = ArgumentParser.TryParse(new[] {"build", "--STDOUT", "file1"});
var bulidOrDecompileArguments = (BuildOrDecompileArguments?) arguments;

// using classic assert so R# understands the value is not null
Assert.IsNotNull(arguments);
bulidOrDecompileArguments!.InputFile.Should().Be("file1");
bulidOrDecompileArguments!.OutputToStdOut.Should().BeTrue();
bulidOrDecompileArguments!.OutputDir.Should().BeNull();
bulidOrDecompileArguments!.OutputFile.Should().BeNull();
}

[TestMethod]
public void Decompile_with_outputdir_parameter_should_parse_correctly()
{
var arguments = ArgumentParser.TryParse(new[] {"build", "--outdir", "outdir", "file1"});
var bulidOrDecompileArguments = (BuildOrDecompileArguments?) arguments;

// using classic assert so R# understands the value is not null
Assert.IsNotNull(arguments);
bulidOrDecompileArguments!.InputFile.Should().Be("file1");
bulidOrDecompileArguments!.OutputToStdOut.Should().BeFalse();
bulidOrDecompileArguments!.OutputDir.Should().Be("outdir");
bulidOrDecompileArguments!.OutputFile.Should().BeNull();
}

[TestMethod]
public void Decompile_with_outputfile_parameter_should_parse_correctly()
{
var arguments = ArgumentParser.TryParse(new[] {"build", "--outfile", "jsonFile", "file1"});
var bulidOrDecompileArguments = (BuildOrDecompileArguments?) arguments;

// using classic assert so R# understands the value is not null
Assert.IsNotNull(arguments);
bulidOrDecompileArguments!.InputFile.Should().Be("file1");
bulidOrDecompileArguments!.OutputToStdOut.Should().BeFalse();
bulidOrDecompileArguments!.OutputDir.Should().BeNull();
bulidOrDecompileArguments!.OutputFile.Should().Be("jsonFile");
}
}
}
}
24 changes: 17 additions & 7 deletions src/Bicep.Cli/CommandLine/ArgumentParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Licensed under the MIT License.
using System;
using System.IO;
using System.Linq;
using Bicep.Cli.CommandLine.Arguments;

namespace Bicep.Cli.CommandLine
Expand All @@ -19,12 +18,12 @@ public static class ArgumentParser
// parse verb
return (args[0].ToLowerInvariant()) switch
{
CliConstants.CommandBuild => new BuildArguments(args[1..]),
CliConstants.CommandDecompile => new DecompileArguments(args[1..]),
CliConstants.ArgumentHelp => new HelpArguments(),
CliConstants.ArgumentHelpShort => new HelpArguments(),
CliConstants.ArgumentVersion => new VersionArguments(),
CliConstants.ArgumentVersionShort => new VersionArguments(),
CliConstants.CommandBuild => new BuildOrDecompileArguments(args[1..], CliConstants.CommandBuild),
CliConstants.CommandDecompile => new BuildOrDecompileArguments(args[1..], CliConstants.CommandDecompile),
CliConstants.ArgumentHelp => new HelpArguments(CliConstants.ArgumentHelp),
CliConstants.ArgumentHelpShort => new HelpArguments(CliConstants.ArgumentHelpShort),
CliConstants.ArgumentVersion => new VersionArguments(CliConstants.ArgumentVersion),
CliConstants.ArgumentVersionShort => new VersionArguments(CliConstants.ArgumentVersionShort),
_ => null,
};
}
Expand Down Expand Up @@ -78,6 +77,17 @@ Attempts to decompile a template .json file to .bicep
Arguments:
<file> The input file.
Options:
--outdir <dir> Saves the output at the specified directory.
--outfile <file> Saves the output as the specified file path.
--stdout Prints the output to stdout.
Examples:
bicep decompile file.json
bicep decompile file.json --stdout
bicep decompile file.json --outdir dir1
bicep decompile file.json --outfile file.bicep
{exeName} [options]
Options:
--version -v Shows bicep version information
Expand Down
6 changes: 6 additions & 0 deletions src/Bicep.Cli/CommandLine/Arguments/ArgumentsBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,11 @@ namespace Bicep.Cli.CommandLine.Arguments
{
public abstract class ArgumentsBase
{
public string CommandName { get; }

protected ArgumentsBase(string commandName)
{
CommandName = commandName;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@

namespace Bicep.Cli.CommandLine.Arguments
{
public class BuildArguments : ArgumentsBase
public class BuildOrDecompileArguments : ArgumentsBase
{
public BuildArguments(string[] args)
public BuildOrDecompileArguments(string[] args, string commandName) : base(commandName)
{
for (var i = 0; i < args.Length; i++)
{
Expand Down Expand Up @@ -80,4 +80,4 @@ public BuildArguments(string[] args)

public string? OutputFile { get; }
}
}
}
35 changes: 0 additions & 35 deletions src/Bicep.Cli/CommandLine/Arguments/DecompileArguments.cs

This file was deleted.

3 changes: 3 additions & 0 deletions src/Bicep.Cli/CommandLine/Arguments/HelpArguments.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,8 @@ namespace Bicep.Cli.CommandLine.Arguments
{
public class HelpArguments : ArgumentsBase
{
public HelpArguments(string commandName) : base(commandName)
{
}
}
}
3 changes: 3 additions & 0 deletions src/Bicep.Cli/CommandLine/Arguments/VersionArguments.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,8 @@ namespace Bicep.Cli.CommandLine.Arguments
{
public class VersionArguments : ArgumentsBase
{
public VersionArguments(string commandName) : base(commandName)
{
}
}
}
Loading

0 comments on commit 117ae64

Please sign in to comment.