powershell/resources/psruntime/BuildTime/Cmdlets/ExportPsd1.cs (162 lines of code) (raw):
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
using System;
using System.IO;
using System.Linq;
using System.Management.Automation;
using System.Text;
using System.Text.RegularExpressions;
using static Microsoft.Rest.ClientRuntime.PowerShell.PsHelpers;
namespace Microsoft.Rest.ClientRuntime.PowerShell
{
[Cmdlet(VerbsData.Export, "Psd1")]
[DoNotExport]
public class ExportPsd1 : PSCmdlet
{
[Parameter(Mandatory = true)]
[ValidateNotNullOrEmpty]
public string ExportsFolder { get; set; }
[Parameter(Mandatory = true)]
[ValidateNotNullOrEmpty]
public string CustomFolder { get; set; }
[Parameter(Mandatory = true)]
[ValidateNotNullOrEmpty]
public string Psd1Path { get; set; }
[Parameter(Mandatory = true)]
public Guid ModuleGuid { get; set; }
private static readonly bool IsAzure = Convert.ToBoolean(@"${$project.azure}");
private const string CustomFolderRelative = "${$project.customFolder}";
private const string Indent = Psd1Indent;
private const string Undefined = "undefined";
private bool IsUndefined(string value) => string.Equals(Undefined, value, StringComparison.OrdinalIgnoreCase);
protected override void ProcessRecord()
{
try
{
if (!Directory.Exists(ExportsFolder))
{
throw new ArgumentException($"Exports folder '{ExportsFolder}' does not exist");
}
if (!Directory.Exists(CustomFolder))
{
throw new ArgumentException($"Custom folder '{CustomFolder}' does not exist");
}
string version = Convert.ToString(@"${$project.moduleVersion}");
// Validate the module version should be semantic version
// Following regex is official from https://semver.org/
Regex rx = new Regex(@"^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$", RegexOptions.Compiled);
if (rx.Matches(version).Count != 1)
{
throw new ArgumentException("Module-version is not a valid Semantic Version");
}
string previewVersion = null;
if (version.Contains('-'))
{
string[] versions = version.Split("-".ToCharArray(), 2);
version = versions[0];
previewVersion = versions[1];
}
var sb = new StringBuilder();
sb.AppendLine("@{");
sb.AppendLine($@"{GuidStart} = '{ModuleGuid}'");
sb.AppendLine($@"{Indent}RootModule = '{"${$project.psm1}"}'");
sb.AppendLine($@"{Indent}ModuleVersion = '{version}'");
sb.AppendLine($@"{Indent}CompatiblePSEditions = 'Core', 'Desktop'");
sb.AppendLine($@"{Indent}Author = '{"${$project.metadata.authors}"}'");
sb.AppendLine($@"{Indent}CompanyName = '{"${$project.metadata.companyName}"}'");
sb.AppendLine($@"{Indent}Copyright = '{"${$project.metadata.copyright}"}'");
sb.AppendLine($@"{Indent}Description = '{"${$project.metadata.description}"}'");
sb.AppendLine($@"{Indent}PowerShellVersion = '5.1'");
sb.AppendLine($@"{Indent}DotNetFrameworkVersion = '4.7.2'");
// RequiredModules
if (!IsUndefined("${$project.metadata.requiredModulesAsString}"))
{
sb.AppendLine($@"{Indent}RequiredModules = @({"${$project.metadata.requiredModulesAsString}"})");
}
// RequiredAssemblies
if (!IsUndefined("${$project.metadata.requiredAssembliesAsString}"))
{
sb.AppendLine($@"{Indent}RequiredAssemblies = @({"${$project.metadata.requiredAssembliesAsString}"})");
}
else
{
sb.AppendLine($@"{Indent}RequiredAssemblies = '{"${$project.dll}"}'");
}
// NestedModules
if (!IsUndefined("${$project.metadata.nestedModulesAsString}"))
{
sb.AppendLine($@"{Indent}NestedModules = @({"${$project.metadata.nestedModulesAsString}"})");
}
// FormatsToProcess
if (!IsUndefined("${$project.metadata.formatsToProcessAsString}"))
{
sb.AppendLine($@"{Indent}FormatsToProcess = @({"${$project.metadata.formatsToProcessAsString}"})");
}
else
{
var customFormatPs1xmlFiles = Directory.GetFiles(CustomFolder)
.Where(f => f.EndsWith(".format.ps1xml"))
.Select(f => $"{CustomFolderRelative}/{Path.GetFileName(f)}");
var formatList = customFormatPs1xmlFiles.Prepend("${$project.formatPs1xml}").ToPsList();
sb.AppendLine($@"{Indent}FormatsToProcess = {formatList}");
}
// TypesToProcess
if (!IsUndefined("${$project.metadata.typesToProcessAsString}"))
{
sb.AppendLine($@"{Indent}TypesToProcess = @({"${$project.metadata.typesToProcessAsString}"})");
}
// ScriptsToProcess
if (!IsUndefined("${$project.metadata.scriptsToProcessAsString}"))
{
sb.AppendLine($@"{Indent}ScriptsToProcess = @({"${$project.metadata.scriptsToProcessAsString}"})");
}
var functionInfos = GetScriptCmdlets(ExportsFolder).ToArray();
// FunctionsToExport
if (!IsUndefined("${$project.metadata.functionsToExportAsString}"))
{
sb.AppendLine($@"{Indent}FunctionsToExport = @({"${$project.metadata.functionsToExportAsString}"})");
}
else
{
var cmdletsList = functionInfos.Select(fi => fi.Name).Distinct().ToPsList();
sb.AppendLine($@"{Indent}FunctionsToExport = {cmdletsList}");
}
// AliasesToExport
if (!IsUndefined("${$project.metadata.aliasesToExportAsString}"))
{
sb.AppendLine($@"{Indent}AliasesToExport = @({"${$project.metadata.aliasesToExportAsString}"})");
}
else
{
var aliasesList = functionInfos.SelectMany(fi => fi.ScriptBlock.Attributes).ToAliasNames().ToPsList();
if (!String.IsNullOrEmpty(aliasesList)) {
sb.AppendLine($@"{Indent}AliasesToExport = {aliasesList}");
}
}
// CmdletsToExport
if (!IsUndefined("${$project.metadata.cmdletsToExportAsString}"))
{
sb.AppendLine($@"{Indent}CmdletsToExport = @({"${$project.metadata.cmdletsToExportAsString}"})");
}
sb.AppendLine($@"{Indent}PrivateData = @{{");
sb.AppendLine($@"{Indent}{Indent}PSData = @{{");
if (previewVersion != null)
{
sb.AppendLine($@"{Indent}{Indent}{Indent}Prerelease = '{previewVersion}'");
}
sb.AppendLine($@"{Indent}{Indent}{Indent}Tags = {"${$project.metadata.tags}".Split(' ').ToPsList().NullIfEmpty() ?? "''"}");
sb.AppendLine($@"{Indent}{Indent}{Indent}LicenseUri = '{"${$project.metadata.licenseUri}"}'");
sb.AppendLine($@"{Indent}{Indent}{Indent}ProjectUri = '{"${$project.metadata.projectUri}"}'");
sb.AppendLine($@"{Indent}{Indent}{Indent}ReleaseNotes = ''");
var profilesList = "${$project.profiles.map(each => `'` + each + `'`).join(', ')}";
if (IsAzure && !String.IsNullOrEmpty(profilesList))
{
sb.AppendLine($@"{Indent}{Indent}{Indent}Profiles = {profilesList}");
}
sb.AppendLine($@"{Indent}{Indent}}}");
sb.AppendLine($@"{Indent}}}");
sb.AppendLine(@"}");
File.WriteAllText(Psd1Path, sb.ToString());
}
catch (Exception ee)
{
Console.WriteLine($"${ee.GetType().Name}/{ee.StackTrace}");
throw ee;
}
}
}
}