Merge remote-tracking branch 'refs/remotes/Microsoft/dev' into Issue196-FeedbackHub

This commit is contained in:
Matt Lacey 2017-10-23 14:52:03 +01:00
Родитель 295577cdd3 0b673d0fd1
Коммит 3f63ce991d
1199 изменённых файлов: 10252 добавлений и 4400 удалений

Просмотреть файл

@ -19,7 +19,7 @@ I need an app that uses MVVM Light, uses master detail, can suspend and resume,
|Branch |Gen Tests |Full Tests |WACK Tests |
|:--------|:---------------:|:---------------:|:---------------:|
|master|[![Generation Tests](https://winappstudio.visualstudio.com/_apis/public/build/definitions/5c80cfe7-3bfb-4799-9d04-803c84df7a60/141/badge)](https://winappstudio.visualstudio.com/DefaultCollection/Vegas/_build/index?definitionId=141)|[![Full Integration Tests](https://winappstudio.visualstudio.com/_apis/public/build/definitions/5c80cfe7-3bfb-4799-9d04-803c84df7a60/129/badge)](https://winappstudio.visualstudio.com/DefaultCollection/Vegas/_build/index?definitionId=129)|
|master|[![Generation Tests](https://winappstudio.visualstudio.com/_apis/public/build/definitions/5c80cfe7-3bfb-4799-9d04-803c84df7a60/141/badge)](https://winappstudio.visualstudio.com/DefaultCollection/Vegas/_build/index?definitionId=141)|[![Full Integration Tests](https://winappstudio.visualstudio.com/_apis/public/build/definitions/5c80cfe7-3bfb-4799-9d04-803c84df7a60/129/badge)](https://winappstudio.visualstudio.com/DefaultCollection/Vegas/_build/index?definitionId=129)|[![Wack Tests](https://winappstudio.visualstudio.com/DefaultCollection/_apis/public/build/definitions/5c80cfe7-3bfb-4799-9d04-803c84df7a60/144/badge)](https://winappstudio.visualstudio.com/DefaultCollection/Vegas/_build/index?definitionId=144)
|dev|[![Generation Tests](https://winappstudio.visualstudio.com/_apis/public/build/definitions/5c80cfe7-3bfb-4799-9d04-803c84df7a60/135/badge)](https://winappstudio.visualstudio.com/DefaultCollection/Vegas/_build/index?definitionId=135)|[![Full Integration Tests](https://winappstudio.visualstudio.com/_apis/public/build/definitions/5c80cfe7-3bfb-4799-9d04-803c84df7a60/128/badge)](https://winappstudio.visualstudio.com/DefaultCollection/Vegas/_build/index?definitionId=128)|[![Wack Tests](https://winappstudio.visualstudio.com/DefaultCollection/_apis/public/build/definitions/5c80cfe7-3bfb-4799-9d04-803c84df7a60/142/badge)](https://winappstudio.visualstudio.com/DefaultCollection/Vegas/_build/index?definitionId=142)

Просмотреть файл

@ -0,0 +1,24 @@
$rootPath = (Split-Path $PSScriptRoot)
$scriptPath = Join-Path $rootPath \_build\ParallelTestExecution.ps1
$testrunnerPath = Join-Path $rootPath \Code\packages\xunit.runner.console.2.2.0\tools\xunit.console.exe
$templateTestLibraryPath = Join-Path $rootPath \Code\test\Templates.Test\bin\Analyze\Microsoft.Templates.Test.dll
$coreTestLibraryPath = Join-Path $rootPath \Code\test\Core.Test\bin\Analyze\Microsoft.Templates.Core.Test.dll
$uiTestLibraryPath = Join-Path $rootPath \Code\test\UI.Test\bin\Analyze\Microsoft.UI.Test.dll
$traits = 'ExecutionSet=BuildCodeBehind', 'ExecutionSet=BuildMVVMBasic','ExecutionSet=BuildMVVMLight','ExecutionSet=BuildCaliburnMicro', 'ExecutionSet=BuildStyleCop', 'ExecutionSet=TemplateValidation', 'ExecutionSet=BuildRightClickWithLegacy'
$outputDir = 'C:\temp\testresults'
if (-not (Test-Path $outputDir))
{
New-Item $outputDir -type Directory
}
. $testrunnerPath $coreTestLibraryPath
. $testrunnerPath $uiTestLibraryPath
. $scriptPath $testrunnerPath $templateTestLibraryPath $traits $outputDir
Write-Host $rootPath
Write-Host $scriptPath

Просмотреть файл

@ -0,0 +1,12 @@
ECHO OFF
ECHO VALUE BEFORE: AGENT_DRIVE=%AGENT_DRIVE%
ECHO VALUE BEFORE: Agent.Drive=%Agent.Drive%
SET AGENT_DRIVE=%CD:~0,2%
SET Agent.Drive=%CD:~0,2%
ECHO VALUE AFTER: AGENT_DRIVE=%AGENT_DRIVE%
ECHO VALUE AFTER: Agent.Drive=%Agent.Drive%
IF EXIST "%AGENT_DRIVE%\UIT" ( rd "%AGENT_DRIVE%\UIT" /s /q )

Просмотреть файл

@ -6,59 +6,20 @@
// attributes that are applied to this project.
// Project-level suppressions either have no target or are given
// a specific target and scoped to a namespace, type, member, etc.
using System.Diagnostics.CodeAnalysis;
[assembly: SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1009:ClosingParenthesisMustBeSpacedCorrectly", Justification = "All current violations are due to Tuple shorthand and so valid.")]
[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1101:PrefixLocalCallsWithThis", Justification = "Initially suppressing everything before evaluating what we want and what's appropriate.")]
[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1113:CommaMustBeOnSameLineAsPreviousParameter", Justification = "Initially suppressing everything before evaluating what we want and what's appropriate.")]
[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1116:SplitParametersMustStartOnLineAfterDeclaration", Justification = "Initially suppressing everything before evaluating what we want and what's appropriate.")]
[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1117:ParametersMustBeOnSameLineOrSeparateLines", Justification = "Initially suppressing everything before evaluating what we want and what's appropriate.")]
[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1119:StatementMustNotUseUnnecessaryParenthesis", Justification = "Initially suppressing everything before evaluating what we want and what's appropriate.")]
[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1120:CommentsMustContainText", Justification = "Initially suppressing everything before evaluating what we want and what's appropriate.")]
[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1122:UseStringEmptyForEmptyStrings", Justification = "Initially suppressing everything before evaluating what we want and what's appropriate.")]
[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1124:DoNotUseRegions", Justification = "Initially suppressing everything before evaluating what we want and what's appropriate.")]
[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1127:Generic type constraints must be on their own line", Justification = "Initially suppressing everything before evaluating what we want and what's appropriate.")]
[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1128:Constructor initializers must be on their own line", Justification = "Initially suppressing everything before evaluating what we want and what's appropriate.")]
[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1101:PrefixLocalCallsWithThis", Justification = "We follow the C# Core Coding Style which avoids using `this` unless absolutely necessary.")]
[assembly: SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1200:UsingDirectivesMustBePlacedWithinNamespace", Justification = "Initially suppressing everything before evaluating what we want and what's appropriate.")]
[assembly: SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1201:ElementsMustAppearInTheCorrectOrder", Justification = "Initially suppressing everything before evaluating what we want and what's appropriate.")]
[assembly: SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1202:ElementsMustBeOrderedByAccess", Justification = "Initially suppressing everything before evaluating what we want and what's appropriate.")]
[assembly: SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1203:ConstantsMustAppearBeforeFields", Justification = "Initially suppressing everything before evaluating what we want and what's appropriate.")]
[assembly: SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1204:StaticElementsMustAppearBeforeInstanceElements", Justification = "Initially suppressing everything before evaluating what we want and what's appropriate.")]
[assembly: SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1209:UsingAliasDirectivesMustBePlacedAfterOtherUsingDirectives", Justification = "Initially suppressing everything before evaluating what we want and what's appropriate.")]
[assembly: SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1210:UsingDirectivesMustBeOrderedAlphabeticallyByNamespace", Justification = "Initially suppressing everything before evaluating what we want and what's appropriate.")]
[assembly: SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1200:UsingDirectivesMustBePlacedWithinNamespace", Justification = "We follow the C# Core Coding Style which puts using statements outside the namespace.")]
[assembly: SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1201:ElementsMustAppearInTheCorrectOrder", Justification = "It is not a priority and have hight impact in code changes.")]
[assembly: SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1202:ElementsMustBeOrderedByAccess", Justification = "It is not a priority and have hight impact in code changes.")]
[assembly: SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1203:ConstantsMustAppearBeforeFields", Justification = "It is not a priority and have hight impact in code changes.")]
[assembly: SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1204:StaticElementsMustAppearBeforeInstanceElements", Justification = "It is not a priority and have hight impact in code changes.")]
[assembly: SuppressMessage("StyleCop.CSharp.NamingRules", "SA1300:ElementMustBeginWithUpperCaseLetter", Justification = "Initially suppressing everything before evaluating what we want and what's appropriate.")]
[assembly: SuppressMessage("StyleCop.CSharp.NamingRules", "SA1303:ConstFieldNamesMustBeginWithUpperCaseLetter", Justification = "Initially suppressing everything before evaluating what we want and what's appropriate.")]
[assembly: SuppressMessage("StyleCop.CSharp.NamingRules", "SA1309:FieldNamesMustNotBeginWithUnderscore", Justification = "Initially suppressing everything before evaluating what we want and what's appropriate.")]
[assembly: SuppressMessage("StyleCop.CSharp.NamingRules", "SA1309:FieldNamesMustNotBeginWithUnderscore", Justification = "We follow the C# Core Coding Style which uses underscores as prefixes rather than using `this.`.")]
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1400:AccessModifierMustBeDeclared", Justification = "Initially suppressing everything before evaluating what we want and what's appropriate.")]
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:FieldsMustBePrivate", Justification = "Initially suppressing everything before evaluating what we want and what's appropriate.")]
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleType", Justification = "Initially suppressing everything before evaluating what we want and what's appropriate.")]
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1404:CodeAnalysisSuppressionMustHaveJustification", Justification = "Initially suppressing everything before evaluating what we want and what's appropriate.")]
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1407:ArithmeticExpressionsMustDeclarePrecedence", Justification = "Initially suppressing everything before evaluating what we want and what's appropriate.")]
[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1503:BracesMustNotBeOmitted", Justification = "Initially suppressing everything before evaluating what we want and what's appropriate.")]
[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1512:SingleLineCommentsMustNotBeFollowedByBlankLine", Justification = "Initially suppressing everything before evaluating what we want and what's appropriate.")]
[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1513:ClosingBraceMustBeFollowedByBlankLine", Justification = "Initially suppressing everything before evaluating what we want and what's appropriate.")]
[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1515:SingleLineCommentMustBePrecededByBlankLine", Justification = "Initially suppressing everything before evaluating what we want and what's appropriate.")]
[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1516:ElementsMustBeSeparatedByBlankLine", Justification = "Initially suppressing everything before evaluating what we want and what's appropriate.")]
[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1519:BracesMustNotBeOmittedFromMultiLineChildStatement", Justification = "Initially suppressing everything before evaluating what we want and what's appropriate.")]
[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1611:ElementParametersMustBeDocumented", Justification = "Initially suppressing everything before evaluating what we want and what's appropriate.")]
[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1615:ElementReturnValueMustBeDocumented", Justification = "Initially suppressing everything before evaluating what we want and what's appropriate.")]
[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1623:PropertySummaryDocumentationMustMatchAccessors", Justification = "Initially suppressing everything before evaluating what we want and what's appropriate.")]
[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1649:FileNameMustMatchTypeName", Justification = "Initially suppressing everything before evaluating what we want and what's appropriate.")]
[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1652:EnableXmlDocumentationOutput", Justification = "Initially suppressing everything before evaluating what we want and what's appropriate.")]
[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1652:EnableXmlDocumentationOutput", Justification = "Not enabled as we don't want or need XML documentation.")]
[assembly: SuppressMessage("Microsoft.Design", "CA1009:DeclareEventHandlersCorrectly", Scope = "member", Target = "Microsoft.Templates.Core.Locations.TemplatesSynchronization.#SyncStatusChanged", Justification = "Using an Action<object, SyncStatusEventArgs> does not allow the required notation")]
[assembly: SuppressMessage("Potential Code Quality Issues", "RECS0022:A catch clause that catches System.Exception and has an empty body", Justification = "Review if ccan be more specific in the error or handle it in a different way. And/or add better comments to the exception.", Scope = "member", Target = "~M:Microsoft.Templates.UI.VisualStudio.VsGenShell.GetActiveProject~EnvDTE.Project")]
[assembly: SuppressMessage("Usage", "VSTHRD001:Use Await JoinableTaskFactory.SwitchToMainThreadAsync() to switch to the UI thread", Justification = "Identified during async/await audit but needs further review.")]
[assembly: SuppressMessage("Usage", "VSTHRD002:Synchronously waiting on tasks or awaiters may cause deadlocks", Justification = "Identified during async/await audit but needs further review.")]
[assembly: SuppressMessage("Usage", "VSTHRD010:Use VS services from UI thread", Justification = "Identified during async/await audit but needs further review.")]
[assembly: SuppressMessage("Usage", "VSTHRD100:Async Void methods NOT used as asynchronous event handlers", Justification = "Identified during async/await audit but needs further review.")]
[assembly: SuppressMessage("Usage", "VSTHRD101:Avoid using async lambda for a void returning delegate type", Justification = "Identified during async/await audit but needs further review.")]

Просмотреть файл

@ -6,7 +6,10 @@
"copyrightText": "Licensed to the {companyName} under one or more agreements.\r\nThe {companyName} licenses this file to you under the MIT license.\r\nSee the LICENSE file in the project root for more information.",
"xmlHeader": false,
"headerDecoration": "",
"fileNamingConvention": "metadata"
"fileNamingConvention": "metadata",
"documentInterfaces": false,
"documentExposedElements": false,
"documentInternalElements": false
},
"layoutRules": {
"newlineAtEndOfFile": "require"

Просмотреть файл

@ -22,7 +22,9 @@ namespace Microsoft.Templates.Core
public static CodeGen Instance { get; private set; }
public TemplateCreator Creator { get; }
public EngineEnvironmentSettings Settings { get; }
public TemplateCache Cache
{
get

Просмотреть файл

@ -55,10 +55,10 @@ namespace Microsoft.Templates.Core.Composition
foreach (Match m in queryMatches)
{
sb.Append(m.Value.Replace(" ", "").Trim());
sb.Append(m.Value.Replace(" ", string.Empty).Trim());
}
return sb.ToString() == rawQuery.Replace(" ", "").Trim();
return sb.ToString() == rawQuery.Replace(" ", string.Empty).Trim();
}
public static CompositionQuery Parse(IEnumerable<string> rawQuery)

Просмотреть файл

@ -14,15 +14,18 @@ namespace Microsoft.Templates.Core.Composition
{
}
public InvalidCompositionQueryException(string message) : base(message)
public InvalidCompositionQueryException(string message)
: base(message)
{
}
public InvalidCompositionQueryException(string message, Exception innerException) : base(message, innerException)
public InvalidCompositionQueryException(string message, Exception innerException)
: base(message, innerException)
{
}
protected InvalidCompositionQueryException(SerializationInfo info, StreamingContext context) : base(info, context)
protected InvalidCompositionQueryException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
}

Просмотреть файл

@ -9,8 +9,11 @@ namespace Microsoft.Templates.Core.Composition
private const string ContextPrefix = "$";
public string Field { get; set; }
public QueryOperator Operator { get; set; }
public string Value { get; set; }
public bool IsContext { get; }
public QueryNode(string field, string @operator, string value)

Просмотреть файл

@ -11,6 +11,7 @@ namespace Microsoft.Templates.Core.Composition
public static QueryableProperty Empty => new QueryableProperty(string.Empty, string.Empty);
public string Name { get; }
public string Value { get; }
public QueryableProperty(string name, string value)

Просмотреть файл

@ -11,12 +11,15 @@ namespace Microsoft.Templates.Core.Composition
[Serializable]
public class QueryablePropertyDictionary : Dictionary<string, QueryableProperty>
{
protected QueryablePropertyDictionary(SerializationInfo info, StreamingContext context) : base(info, context)
protected QueryablePropertyDictionary(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
public QueryablePropertyDictionary()
{
}
public void Add(QueryableProperty property)
{
Add(property.Name, property);

Просмотреть файл

@ -12,26 +12,38 @@ using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Microsoft.Templates.Core.Resources;
namespace Microsoft.Templates.Core
{
public class Configuration
{
public string Environment { get; set; } = "Local";
public string CdnUrl { get; set; } = "https://wtsrepository.blob.core.windows.net/dev/Latest";
// Set your Application Insights telemetry instrumentation key here (configure it in a WindowsTemplateStudio.config.json located in the working folder).
public string RemoteTelemetryKey { get; set; } = "<SET_YOUR_OWN_KEY>";
public string LogFileFolderPath { get; set; } = @"WindowsTemplateStudio\Logs";
public string RepositoryFolderName { get; set; } = @"WindowsTemplateStudio";
public string BackupFolderPath { get; set; } = @"WindowsTemplateStudio\Backups";
public string TempGenerationFolderPath { get; set; } = "WTSTempGeneration";
public TraceEventType DiagnosticsTraceLevel { get; set; } = TraceEventType.Verbose;
public int DaysToKeepTempGenerations { get; set; } = 5;
public int DaysToKeepDiagnosticsLogs { get; set; } = 5;
public int VersionCheckingExpirationMinutes { get; set; } = 0;
public List<string> AllowedPublicKeysPins { get; set; } = new List<string>() { };
public string CustomTelemetryEndpoint { get; set; } = string.Empty;
public string GitHubDocsUrl { get; set; } = "https://github.com/Microsoft/WindowsTemplateStudio/blob/master/docs/";
public static string LoadedConfigFile { get; private set; }
@ -39,6 +51,7 @@ namespace Microsoft.Templates.Core
public const string DefaultJsonConfigFileName = "WindowsTemplateStudio.config.json";
private static Configuration _current;
public static Configuration Current
{
get

Просмотреть файл

@ -15,6 +15,7 @@
"AllowedPublicKeysPins": [
"14CAC54E3A89855AF3F33C6C2F88E389094305F15EC3E7CC18844E8ABD4651A8992710E005DE189A313039064B082D62D41077B44BEFA4D837C1FC320083D422",
"51E93470FD838DFCE5F4ADF0D7750D2B66635677499A73160B9CB3BA84884A9EBA5F4E80C346323C0F61D2A8EDDC8EE5E02E7F186D13C953270F68AEB44CFE3D",
"8A79BF09C49440C614229A2338384348443353A4B3DBA4AD46EDC0FE1054ED220A0D3445783493869186DEADBF0D9D8627E0EAC2D37475C9EC991A0324038EA4"
"8A79BF09C49440C614229A2338384348443353A4B3DBA4AD46EDC0FE1054ED220A0D3445783493869186DEADBF0D9D8627E0EAC2D37475C9EC991A0324038EA4",
"2A0A69F1AB9BB46A8AE3563B72702FD6CCB16ECBF669D62A7DC92D217A084E318EC8BB2AE87A4A2C6855BDB9C0F4FD93D77E802AAACDDEB795C2EF718D7D4890"
]
}

Просмотреть файл

@ -92,11 +92,13 @@
<HintPath>..\..\packages\Microsoft.VisualStudio.Telemetry.15.3.789-masterCC863119\lib\net45\Microsoft.VisualStudio.Telemetry.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.Threading, Version=15.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.VisualStudio.Threading.15.0.240\lib\net45\Microsoft.VisualStudio.Threading.dll</HintPath>
<Reference Include="Microsoft.VisualStudio.Threading, Version=15.3.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.VisualStudio.Threading.15.3.23\lib\net45\Microsoft.VisualStudio.Threading.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.Validation, Version=15.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.VisualStudio.Validation.15.0.82\lib\net45\Microsoft.VisualStudio.Validation.dll</HintPath>
<Reference Include="Microsoft.VisualStudio.Validation, Version=15.3.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.VisualStudio.Validation.15.3.15\lib\net45\Microsoft.VisualStudio.Validation.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
@ -187,8 +189,13 @@
<Compile Include="Gen\GenContext.cs" />
<Compile Include="Gen\GenToolBox.cs" />
<Compile Include="Gen\IContextProvider.cs" />
<Compile Include="Mvvm\Observable.cs" />
<Compile Include="Naming\DefaultNamesValidator.cs" />
<Compile Include="Naming\ReservedNamesValidator.cs" />
<Compile Include="Packaging\TemplatePackage.cs" />
<Compile Include="PostActions\Catalog\Merge\MergeResourceDictionaryPostAction.cs" />
<Compile Include="PostActions\Catalog\Merge\ResourceDictionaryWriter.cs" />
<Compile Include="PostActions\Catalog\SortNamespaces\ListStringExtensions.cs" />
<Compile Include="ProgrammingLanguages.cs" />
<Compile Include="Naming\SuggestedDirectoryNameValidator.cs" />
<Compile Include="PostActions\Catalog\Merge\FailedMergePostAction.cs" />
@ -200,17 +207,14 @@
<Compile Include="Locations\SyncStatusEventArgs.cs" />
<Compile Include="Locations\SyncStatus.cs" />
<Compile Include="MetadataLocalizedInfo.cs" />
<Compile Include="Naming\DefaultNameValidator.cs" />
<Compile Include="Naming\ExistingNamesValidator.cs" />
<Compile Include="Naming\FileExistsValidator.cs" />
<Compile Include="Naming\ReservedNameValidator.cs" />
<Compile Include="Naming\Validator.cs" />
<Compile Include="PostActions\Catalog\SortNamespaces\ImportsComparer.cs" />
<Compile Include="PostActions\Catalog\SortNamespaces\NamespaceComparer.cs" />
<Compile Include="PostActions\Catalog\SortNamespaces\SortImportsPostAction.cs" />
<Compile Include="PostActions\Catalog\SortNamespaces\SortNamespacesPostAction.cs" />
<Compile Include="PostActions\Catalog\SortNamespaces\SortUsingsPostAction.cs" />
<Compile Include="PostActions\Catalog\SortNamespaces\IEnumerableExtensions.cs" />
<Compile Include="PostActions\Catalog\SortNamespaces\UsingComparer.cs" />
<Compile Include="PostActions\Catalog\SearchAndReplacePostAction.cs" />
<Compile Include="PostActions\Catalog\AddContextItemsToProjectPostAction.cs" />
@ -300,10 +304,8 @@
<Compile Include="Locations\TemplatesSynchronization.cs" />
<Compile Include="Locations\TemplatesContent.cs" />
<Compile Include="Locations\TemplatesSource.cs" />
<Compile Include="Packaging\Templatex.cs" />
<Compile Include="Packaging\SignCertNotFoundException.cs" />
<Compile Include="MetadataInfo.cs" />
<Compile Include="Mvvm\ObservableBase.cs" />
<Compile Include="Mvvm\RelayCommand.cs" />
<Compile Include="Naming\Naming.cs" />
<Compile Include="Templates\LayoutItem.cs" />

Просмотреть файл

@ -11,13 +11,19 @@ namespace Microsoft.Templates.Core.Diagnostics
public class AppHealth : IDisposable
{
public TraceTracker Verbose { get; private set; }
public TraceTracker Info { get; private set; }
public TraceTracker Warning { get; private set; }
public TraceTracker Error { get; private set; }
public ExceptionTracker Exception { get; private set; }
public TelemetryTracker Telemetry { get; private set; }
static AppHealth _current;
private static AppHealth _current;
public static AppHealth Current
{
get
@ -50,11 +56,15 @@ namespace Microsoft.Templates.Core.Diagnostics
public void AddWriter(IHealthWriter newWriter)
{
if (newWriter.AllowMultipleInstances() || !HealthWriters.Available.Where(w => w.GetType() == newWriter.GetType()).Any())
if (newWriter != null)
{
HealthWriters.Available.Add(newWriter);
if (newWriter.AllowMultipleInstances() || !HealthWriters.Available.Where(w => w.GetType() == newWriter.GetType()).Any())
{
HealthWriters.Available.Add(newWriter);
}
}
}
private void InstanceDefaultWriters()
{
HealthWriters.Available.Add(FileHealthWriter.Current);
@ -86,6 +96,7 @@ namespace Microsoft.Templates.Core.Diagnostics
}
}
}
// free native resources if any.
}
}

Просмотреть файл

@ -18,11 +18,13 @@ namespace Microsoft.Templates.Core.Diagnostics
public class FileHealthWriter : IHealthWriter
{
private static SemaphoreSlim _semaphoreSlim = new SemaphoreSlim(1, 1);
private string _workingFolder;
public string LogFileName { get; private set; }
private static FileHealthWriter _current;
public static FileHealthWriter Current
{
get
@ -35,6 +37,7 @@ namespace Microsoft.Templates.Core.Diagnostics
return _current;
}
}
private FileHealthWriter()
{
_workingFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), Configuration.Current.LogFileFolderPath);
@ -57,6 +60,7 @@ namespace Microsoft.Templates.Core.Diagnostics
await WriteAndFlushAsync(sb.ToString());
}
public async Task WriteExceptionAsync(Exception ex, string message = null)
{
if (ex == null)
@ -65,7 +69,7 @@ namespace Microsoft.Templates.Core.Diagnostics
}
var sb = new StringBuilder();
sb.AppendLine($"{FormattedWriterMessages.LogEntryStart}\t{TraceEventType.Critical.ToString():11}\t{StringRes.ExceptionTrackedString}. {(message ?? "")}");
sb.AppendLine($"{FormattedWriterMessages.LogEntryStart}\t{TraceEventType.Critical.ToString():11}\t{StringRes.ExceptionTrackedString}. {message ?? string.Empty}");
if (ex != null)
{

Просмотреть файл

@ -12,11 +12,14 @@ namespace Microsoft.Templates.Core.Diagnostics
public class FormattedWriterMessages
{
private static string exHeader = $"===================== {StringRes.ExceptionInfoString} =====================";
public static string ExHeader
{
get { return exHeader; }
}
public const string ExFooter = "----------------------------------------------------------";
public static string LogEntryStart
{
get

Просмотреть файл

@ -11,7 +11,9 @@ namespace Microsoft.Templates.Core.Diagnostics
public interface IHealthWriter
{
Task WriteTraceAsync(TraceEventType eventType, string message, Exception ex = null);
Task WriteExceptionAsync(Exception ex, string message = null);
bool AllowMultipleInstances();
}
}

Просмотреть файл

@ -3,20 +3,23 @@
// See the LICENSE file in the project root for more information.
using System;
using System.Diagnostics;
using SystemTasks = System.Threading.Tasks;
using Microsoft.Templates.Core.Gen;
using Microsoft.Templates.Core.Resources;
using SystemTasks = System.Threading.Tasks;
namespace Microsoft.Templates.Core.Diagnostics
{
public class ShellHealthWriter : IHealthWriter
{
GenShell _shell;
private GenShell _shell;
public ShellHealthWriter(GenShell shell)
{
_shell = shell;
}
public async SystemTasks.Task WriteExceptionAsync(Exception ex, string message = null)
{
if (_shell != null)

Просмотреть файл

@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Diagnostics.CodeAnalysis;
namespace Microsoft.Templates.Core.Diagnostics
{
public class TelemetryEvents
@ -9,17 +11,25 @@ namespace Microsoft.Templates.Core.Diagnostics
public const string Prefix = "Wts";
public static string ProjectGen { get; private set; } = Prefix + "ProjectGen";
public static string NewItemGen { get; private set; } = Prefix + "NewItemGen";
public static string PageGen { get; private set; } = Prefix + "PageGen";
public static string FeatureGen { get; private set; } = Prefix + "FeatureGen";
public static string Wizard { get; private set; } = Prefix + "Wizard";
public static string SessionStart { get; private set; } = Prefix + "SessionStart";
public static string EditSummaryItem { get; private set; } = Prefix + "EditSummaryItem";
}
[SuppressMessage("StyleCop", "SA1402", Justification = "This class does not have implementation. Used for constants.")]
public class VsTelemetryEvents
{
public const string Prefix = "Wts.";
public static string WtsGen { get; private set; } = "vs/windowstemplatestudio/wts-generated";
}
}

Просмотреть файл

@ -7,8 +7,11 @@ namespace Microsoft.Templates.Core.Diagnostics
public class TelemetryMetrics
{
public static string PagesCount { get; private set; } = TelemetryEvents.Prefix + "PagesCount";
public static string FeaturesCount { get; private set; } = TelemetryEvents.Prefix + "FeaturesCount";
public static string TimeSpent { get; private set; } = TelemetryEvents.Prefix + "SecTotal";
public static string ProjectMetricsTimeSpent { get; private set; } = TelemetryEvents.Prefix + "Sec";
}
}

Просмотреть файл

@ -7,28 +7,53 @@ namespace Microsoft.Templates.Core.Diagnostics
public class TelemetryProperties
{
public static string WizardFileVersion { get; private set; } = TelemetryEvents.Prefix + "WizardFileVersion";
public static string WizardContentVersion { get; private set; } = TelemetryEvents.Prefix + "TemplatesVersion";
public static string RoleInstanceName { get; private set; } = TelemetryEvents.Prefix + "WizardClient";
public static string Status { get; private set; } = TelemetryEvents.Prefix + "Status";
public static string ProjectType { get; private set; } = TelemetryEvents.Prefix + "ProjectType";
public static string Framework { get; private set; } = TelemetryEvents.Prefix + "Framework";
public static string TemplateName { get; private set; } = TelemetryEvents.Prefix + "TemplateName";
public static string GenEngineStatus { get; private set; } = TelemetryEvents.Prefix + "GenEngineStatus";
public static string GenEngineMessage { get; private set; } = TelemetryEvents.Prefix + "GenEngineMessage";
public static string WizardType { get; private set; } = TelemetryEvents.Prefix + "WizardType";
public static string WizardStatus { get; private set; } = TelemetryEvents.Prefix + "WizardStatus";
public static string WizardAction { get; private set; } = TelemetryEvents.Prefix + "WizardAction";
public static string LastStep { get; private set; } = TelemetryEvents.Prefix + "LastStep";
public static string EventName { get; private set; } = TelemetryEvents.Prefix + "EventName";
public static string Language { get; internal set; } = TelemetryEvents.Prefix + "Language";
public static string VisualStudioVersion { get; private set; } = TelemetryEvents.Prefix + "VsVersion";
public static string VisualStudioExeVersion { get; private set; } = TelemetryEvents.Prefix + "VsExeVersion";
public static string VisualStudioProductVersion { get; private set; } = TelemetryEvents.Prefix + "VsProductVersion";
public static string VisualStudioEdition { get; private set; } = TelemetryEvents.Prefix + "VsEdition";
public static string VisualStudioCulture { get; private set; } = TelemetryEvents.Prefix + "VsCulture";
public static string VisualStudioManifestId { get; private set; } = TelemetryEvents.Prefix + "VsManifestId";
public static string VisualStudioActiveProjectGuid { get; private set; } = TelemetryEvents.Prefix + "VsActiveProjectGuid";
public static string SummaryItemEditAction { get; private set; } = TelemetryEvents.Prefix + "ItemEditAction";
public static string VsProjectCategory { get; private set; } = TelemetryEvents.Prefix + "Category";
public static string NewItemType { get; private set; } = TelemetryEvents.Prefix + "NewItemType";
public static string GenSource { get; private set; } = TelemetryEvents.Prefix + "GenSource";
}
}

Просмотреть файл

@ -22,7 +22,8 @@ namespace Microsoft.Templates.Core.Diagnostics
private TelemetryClient _client;
private bool vsTelemAvailable = false;
public static TelemetryService _current;
private static TelemetryService _current;
public static TelemetryService Current
{
get
@ -177,7 +178,7 @@ namespace Microsoft.Templates.Core.Diagnostics
}
_client.Context.Properties.Add(TelemetryProperties.VisualStudioEdition, vsEdition);
_client.Context.Properties.Add(TelemetryProperties.VisualStudioVersion, vsVersion);
_client.Context.Properties.Add(TelemetryProperties.VisualStudioExeVersion, vsVersion);
_client.Context.Properties.Add(TelemetryProperties.VisualStudioCulture, vsCulture);
_client.Context.Properties.Add(TelemetryProperties.VisualStudioManifestId, vsManifestId);
return result;
@ -225,6 +226,21 @@ namespace Microsoft.Templates.Core.Diagnostics
}
}
public void SetContentVsProductVersionToContext(string vsProductVersion)
{
if (!string.IsNullOrEmpty(vsProductVersion) && _client != null && _client.Context != null && _client.Context.Properties != null)
{
if (!_client.Context.Properties.ContainsKey(TelemetryProperties.VisualStudioProductVersion))
{
_client.Context.Properties.Add(TelemetryProperties.VisualStudioProductVersion, vsProductVersion);
}
else
{
_client.Context.Properties[TelemetryProperties.VisualStudioProductVersion] = vsProductVersion;
}
}
}
public void SafeTrackProjectVsTelemetry(Dictionary<string, string> properties, string pageIdentities, string featureIdentities, Dictionary<string, double> metrics, bool success = true)
{
try
@ -281,6 +297,7 @@ namespace Microsoft.Templates.Core.Diagnostics
Trace.TraceInformation($"Exception tracking New Item Creation in VsTelemetry:\r\n" + ex.ToString());
}
}
private void TrackNewItemVsTelemetry(Dictionary<string, string> properties, string pageIdentities, string featureIdentities, Dictionary<string, double> metrics, bool success = true)
{
VsTelem.TelemetryResult result = success ? VsTelem.TelemetryResult.Success : VsTelem.TelemetryResult.Failure;
@ -295,6 +312,7 @@ namespace Microsoft.Templates.Core.Diagnostics
e.Properties[renamedKey] = properties[key];
}
}
e.Properties.Add(VsTelemetryProperties.Pages, pageIdentities);
e.Properties.Add(VsTelemetryProperties.Features, featureIdentities);
@ -422,6 +440,7 @@ namespace Microsoft.Templates.Core.Diagnostics
// free managed resources
Flush();
}
// free native resources if any
}
}

Просмотреть файл

@ -22,7 +22,7 @@ namespace Microsoft.Templates.Core.Diagnostics
TelemetryService.SetConfiguration(config);
}
public async Task TrackWizardCompletedAsync(WizardTypeEnum wizardType, WizardActionEnum wizardAction)
public async Task TrackWizardCompletedAsync(WizardTypeEnum wizardType, WizardActionEnum wizardAction, string vsProductVersion)
{
var properties = new Dictionary<string, string>()
{
@ -32,10 +32,11 @@ namespace Microsoft.Templates.Core.Diagnostics
{ TelemetryProperties.EventName, TelemetryEvents.Wizard }
};
TelemetryService.Current.SetContentVsProductVersionToContext(vsProductVersion);
await TelemetryService.Current.TrackEventAsync(TelemetryEvents.Wizard, properties).ConfigureAwait(false);
}
public async Task TrackWizardCancelledAsync(WizardTypeEnum wizardType)
public async Task TrackWizardCancelledAsync(WizardTypeEnum wizardType, string vsProductVersion)
{
var properties = new Dictionary<string, string>()
{
@ -44,16 +45,21 @@ namespace Microsoft.Templates.Core.Diagnostics
{ TelemetryProperties.EventName, TelemetryEvents.Wizard }
};
TelemetryService.Current.SetContentVsProductVersionToContext(vsProductVersion);
await TelemetryService.Current.TrackEventAsync(TelemetryEvents.Wizard, properties).ConfigureAwait(false);
}
public async Task TrackProjectGenAsync(ITemplateInfo template, string appProjectType, string appFx, TemplateCreationResult result, Guid vsProjectId, string language, int? pagesCount = null, int? featuresCount = null, string pageIdentities = "", string featureIdentitites = "", double? timeSpent = null, Dictionary<ProjectMetricsEnum, double> performanceCounters = null)
{
if (template == null)
{
throw new ArgumentNullException(nameof(template));
}
if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
if (template.GetTemplateType() != TemplateType.Project)
{
@ -68,10 +74,14 @@ namespace Microsoft.Templates.Core.Diagnostics
public async Task TrackItemGenAsync(ITemplateInfo template, GenSourceEnum genSource, string appProjectType, string appFx, TemplateCreationResult result)
{
if (template == null)
{
throw new ArgumentNullException(nameof(template));
}
if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
if (template != null && result != null)
{
@ -226,6 +236,7 @@ namespace Microsoft.Templates.Core.Diagnostics
// free managed resources
TelemetryService.Current.Dispose();
}
// free native resources if any.
}
}

Просмотреть файл

@ -32,7 +32,10 @@ namespace Microsoft.Templates.Core.Diagnostics
{
try
{
await writer.WriteTraceAsync(_traceEventType, message, ex).ConfigureAwait(false);
if (writer != null)
{
await writer.WriteTraceAsync(_traceEventType, message, ex).ConfigureAwait(false);
}
}
catch (Exception exception)
{

Просмотреть файл

@ -7,7 +7,9 @@ namespace Microsoft.Templates.Core.Diagnostics
public class VsTelemetryProperties
{
public const string Prefix = "Wts.";
public static string Pages { get; private set; } = Prefix + "Pages";
public static string Features { get; private set; } = Prefix + "Features";
}
}

Просмотреть файл

@ -30,7 +30,7 @@ namespace Microsoft.Templates.Core
public static string FormatAsDateHoursMinutes(this DateTime date)
{
return date.ToString("dd_HHmm");
return date.ToString("ddHHmmss");
}
}
}

Просмотреть файл

@ -10,17 +10,17 @@ namespace Microsoft.Templates.Core
{
public static bool IsZero(this Version v)
{
return !(v is null) && (v.Major + v.Minor + v.Build + v.Revision) == 0;
return !v.IsNull() && (v.Major + v.Minor + v.Build + v.Revision) == 0;
}
public static bool IsNull(this Version v)
{
return (v is null);
return v is null;
}
public static bool IsNullOrZero(this Version v)
{
return (v is null) || (v.Major + v.Minor + v.Build + v.Revision) == 0;
return v.IsNull() || (v.Major + v.Minor + v.Build + v.Revision) == 0;
}
}
}

Просмотреть файл

@ -43,12 +43,14 @@ namespace Microsoft.Templates.Core
{
Directory.CreateDirectory(destFolder);
}
var destFile = Path.Combine(destFolder, Path.GetFileName(sourceFile));
if (File.Exists(destFile))
{
EnsureFileEditable(destFile);
}
File.Copy(sourceFile, destFile, overwrite);
}
catch (Exception ex)

Просмотреть файл

@ -10,18 +10,21 @@ using System.Linq;
using System.Reflection;
using Microsoft.Templates.Core.Diagnostics;
using Microsoft.Templates.Core.Resources;
using Microsoft.Templates.Core.Locations;
using Microsoft.Templates.Core.Resources;
namespace Microsoft.Templates.Core.Gen
{
public class GenContext
{
private static IContextProvider _currentContext;
private static string _tempGenerationFolder = Path.Combine(Path.GetTempPath(), Configuration.Current.TempGenerationFolderPath);
public static GenToolBox ToolBox { get; private set; }
public static string InitializedLanguage { get; private set; }
public static bool ContextInitialized => _currentContext != null;
public static IContextProvider Current
@ -54,7 +57,7 @@ namespace Microsoft.Templates.Core.Gen
AppHealth.Current.AddWriter(new ShellHealthWriter(shell));
AppHealth.Current.Info.TrackAsync($"{StringRes.ConfigurationFileLoadedString}: {Configuration.LoadedConfigFile}").FireAndForget();
string hostVersion = $"{shell.GetVsVersion()}-{wizardVersion.Major}.{wizardVersion.Minor}";
string hostVersion = $"{shell.GetVsVersionAndInstance()}-{wizardVersion.Major}.{wizardVersion.Minor}";
CodeGen.Initialize(source.Id, hostVersion);
var repository = new TemplatesRepository(source, wizardVersion, language);

Просмотреть файл

@ -12,7 +12,9 @@ namespace Microsoft.Templates.Core.Gen
public class GenInfo
{
public string Name { get; set; }
public ITemplateInfo Template { get; set; }
public Dictionary<string, string> Parameters { get; } = new Dictionary<string, string>();
public string GetUserName()
@ -21,6 +23,7 @@ namespace Microsoft.Templates.Core.Gen
{
return Parameters[GenParams.Username];
}
return string.Empty;
}

Просмотреть файл

@ -11,21 +11,37 @@ namespace Microsoft.Templates.Core.Gen
public abstract class GenShell
{
public abstract string GetActiveProjectName();
public abstract string GetActiveProjectPath();
public abstract string GetActiveProjectLanguage();
protected abstract string GetSelectedItemPath();
public abstract bool SetActiveConfigurationAndPlatform(string configurationName, string platformName);
public abstract void ShowStatusBarMessage(string message);
public abstract void AddProjectToSolution(string projectFullPath);
public abstract void AddItems(params string[] itemsFullPath);
public abstract void CleanSolution();
public abstract void SaveSolution();
public abstract string GetActiveProjectNamespace();
public abstract void ShowTaskList();
public abstract void ShowModal(Window dialog);
public abstract void CancelWizard(bool back = true);
public abstract void WriteOutput(string data);
public abstract void CloseSolution();
public abstract bool IsDebuggerEnabled();
public abstract Guid GetVsProjectId();
@ -51,6 +67,11 @@ namespace Microsoft.Templates.Core.Gen
return "0.0.0.0";
}
public virtual string GetVsVersionAndInstance()
{
return "0.0.0.0-i";
}
public bool GetActiveProjectIsWts()
{
bool result = false;
@ -64,6 +85,7 @@ namespace Microsoft.Templates.Core.Gen
result = fileContent.Contains("genTemplate:Metadata");
}
}
return result;
}
}

Просмотреть файл

@ -7,8 +7,11 @@ namespace Microsoft.Templates.Core.Gen
public class GenToolBox
{
public TemplatesRepository Repo { get; }
public GenShell Shell { get; }
public string WizardVersion => Repo.WizardVersion;
public string TemplatesVersion => Repo.TemplatesVersion;
public GenToolBox(TemplatesRepository repo, GenShell shell)

Просмотреть файл

@ -11,12 +11,17 @@ namespace Microsoft.Templates.Core.Gen
public interface IContextProvider
{
string ProjectName { get; }
string OutputPath { get; }
string ProjectPath { get; }
List<string> ProjectItems { get; }
List<string> FilesToOpen { get; }
List<FailedMergePostAction> FailedMergePostActions { get; }
Dictionary<string, List<MergeInfo>> MergeFilesFromProject { get; }
Dictionary<ProjectMetricsEnum, double> ProjectMetrics { get; }

Просмотреть файл

@ -2,11 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.IO;
using System.Text;
using System;
using Microsoft.Templates.Core.Packaging;
using System.IO;
namespace Microsoft.Templates.Core.Locations
{
@ -18,24 +15,26 @@ namespace Microsoft.Templates.Core.Locations
protected override bool VerifyPackageSignatures => false;
public override bool ForcedAcquisition { get => base.ForcedAcquisition; protected set => base.ForcedAcquisition = value; }
public string Origin => $@"..\..\..\..\..\{SourceFolderName}";
private string _id;
public override string Id { get => _id; }
private object lockObject = new object();
public override string Id { get => _id; }
protected string FinalDestination { get; set; }
public LocalTemplatesSource() : this("0.0.0.0", "0.0.0.0", true)
public LocalTemplatesSource()
: this("0.0.0.0", "0.0.0.0", true)
{
_id = Configuration.Current.Environment;
_id = Configuration.Current.Environment + GetAgentName();
}
public LocalTemplatesSource(string id) : this("0.0.0.0", "0.0.0.0", true)
public LocalTemplatesSource(string id)
: this("0.0.0.0", "0.0.0.0", true)
{
_id = id;
_id = id + GetAgentName();
}
public LocalTemplatesSource(string wizardVersion, string templatesVersion, bool forcedAdquisition = true)
{
ForcedAcquisition = forcedAdquisition;
@ -43,7 +42,7 @@ namespace Microsoft.Templates.Core.Locations
LocalWizardVersion = wizardVersion;
if (string.IsNullOrEmpty(_id))
{
_id = Configuration.Current.Environment;
_id = Configuration.Current.Environment + GetAgentName();
}
}
@ -75,5 +74,19 @@ namespace Microsoft.Templates.Core.Locations
Fs.CopyRecursive(sourcePath, FinalDestination, true);
}
}
private static string GetAgentName()
{
// If running tests in VSTS concurrently in different agents avoids the collison in templates folders
string agentName = Environment.GetEnvironmentVariable("AGENT_NAME");
if (string.IsNullOrEmpty(agentName))
{
return string.Empty;
}
else
{
return $"-{agentName}";
}
}
}
}

Просмотреть файл

@ -14,7 +14,9 @@ namespace Microsoft.Templates.Core.Locations
public sealed class RemoteTemplatesSource : TemplatesSource
{
public override bool ForcedAcquisition => false;
private readonly string _cdnUrl = Configuration.Current.CdnUrl;
private const string TemplatesPackageFileName = "Templates.mstx";
protected override string AcquireMstx()

Просмотреть файл

@ -14,9 +14,11 @@ namespace Microsoft.Templates.Core.Locations
public class TemplatesContent
{
private const string TemplatesFolderName = "Templates";
private string _defaultContentFolder;
public string TemplatesFolder { get; private set; }
public Version WizardVersion { get; private set; }
public string LatestContentFolder => GetLatestContentFolder(true);
@ -107,6 +109,7 @@ namespace Microsoft.Templates.Core.Locations
{
AppHealth.Current.Verbose.TrackAsync($"{StringRes.CurrentContentExpirationString}: {expiration.ToString()}").FireAndForget();
}
return expired;
}
@ -196,7 +199,7 @@ namespace Microsoft.Templates.Core.Locations
}
else
{
return (v.Major > WizardVersion.Major || (v.Major == WizardVersion.Major && (v.Minor > WizardVersion.Minor)));
return v.Major > WizardVersion.Major || (v.Major == WizardVersion.Major && (v.Minor > WizardVersion.Minor));
}
}
@ -208,7 +211,7 @@ namespace Microsoft.Templates.Core.Locations
}
else
{
return (v.Major < WizardVersion.Major || (v.Major == WizardVersion.Major && (v.Minor < WizardVersion.Minor)));
return v.Major < WizardVersion.Major || (v.Major == WizardVersion.Major && (v.Minor < WizardVersion.Minor));
}
}

Просмотреть файл

@ -3,23 +3,25 @@
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Collections.Generic;
using Microsoft.Templates.Core.Diagnostics;
using Microsoft.Templates.Core.Resources;
using Microsoft.Templates.Core.Packaging;
using Microsoft.Templates.Core.Resources;
namespace Microsoft.Templates.Core.Locations
{
public abstract class TemplatesSource
{
protected const string SourceFolderName = "Templates";
private const string VersionFileName = "version.txt";
private List<string> _tempFoldersUsed = new List<string>();
public virtual bool ForcedAcquisition { get; protected set; }
protected virtual bool VerifyPackageSignatures { get => true; }
@ -88,6 +90,7 @@ namespace Microsoft.Templates.Core.Locations
}
}
}
return result;
}
@ -165,6 +168,7 @@ namespace Microsoft.Templates.Core.Locations
Fs.SafeDeleteDirectory(tempFolder);
removedFolders.Add(tempFolder);
}
foreach (string folder in removedFolders)
{
_tempFoldersUsed.Remove(folder);

Просмотреть файл

@ -4,9 +4,8 @@
using System;
using System.IO;
using System.Threading.Tasks;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Templates.Core.Diagnostics;
using Microsoft.Templates.Core.Resources;
@ -117,6 +116,7 @@ namespace Microsoft.Templates.Core.Locations
await ExtractInstalledContentAsync();
}
}
private async Task<bool> CheckMandatoryAcquireContentAsync()
{
return await AcquireContentAsync(_source.ForcedAcquisition || _content.ExistUnderVersion());
@ -136,6 +136,7 @@ namespace Microsoft.Templates.Core.Locations
acquireContentCalled = true;
SyncStatusChanged?.Invoke(this, new SyncStatusEventArgs { Status = SyncStatus.Acquired });
}
return await Task.FromResult<bool>(acquireContentCalled);
}
@ -282,11 +283,13 @@ namespace Microsoft.Templates.Core.Locations
{
return false;
}
SetInstanceSyncLock();
SyncInProgress = true;
return SyncInProgress;
}
}
private void UnlockSync()
{
lock (syncLock)
@ -295,6 +298,7 @@ namespace Microsoft.Templates.Core.Locations
RemoveInstanceSyncLock();
}
}
private async Task EnsureVsInstancesSyncingAsync()
{
while (IsOtherInstanceSyncing())
@ -329,6 +333,8 @@ namespace Microsoft.Templates.Core.Locations
{
fileInfo.Delete();
}
Fs.EnsureFolder(CurrentTemplatesFolder);
File.WriteAllText(fileInfo.FullName, "Instance syncing");
}
catch (Exception ex)
@ -336,6 +342,7 @@ namespace Microsoft.Templates.Core.Locations
AppHealth.Current.Warning.TrackAsync(StringRes.TemplatesSynchronizationWarnCreatingLockFileMessage, ex).FireAndForget();
}
}
private void RemoveInstanceSyncLock()
{
try

Просмотреть файл

@ -13,15 +13,25 @@ namespace Microsoft.Templates.Core
public class MetadataInfo
{
public string Name { get; set; }
public string DisplayName { get; set; }
public string Icon { get; set; }
public string Summary { get; set; }
public string Description { get; set; }
public string Author { get; set; }
public int Order { get; set; }
public string MetadataType { get; set; }
public string Licenses { get; set; }
public IEnumerable<TemplateLicense> LicenseTerms { get; set; }
public IEnumerable<string> Languages { get; set; }
}
}

Просмотреть файл

@ -13,7 +13,9 @@ namespace Microsoft.Templates.Core
public class MetadataLocalizedInfo
{
public string Name { get; set; }
public string DisplayName { get; set; }
public string Summary { get; set; }
}
}

Просмотреть файл

@ -13,7 +13,9 @@ namespace Microsoft.Templates.Core.Mvvm
protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName]string propertyName = null)
{
if (Equals(storage, value))
{
return false;
}
storage = value;

Просмотреть файл

@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System;
using System.Diagnostics.CodeAnalysis;
using System.Windows.Input;
namespace Microsoft.Templates.Core.Mvvm
@ -12,7 +13,8 @@ namespace Microsoft.Templates.Core.Mvvm
private readonly Action _execute;
private readonly Func<bool> _canExecute;
public RelayCommand(Action execute) : this(execute, null)
public RelayCommand(Action execute)
: this(execute, null)
{
}
@ -40,12 +42,17 @@ namespace Microsoft.Templates.Core.Mvvm
}
}
[SuppressMessage(
"StyleCop.CSharp.MaintainabilityRules",
"SA1402:File may only contain a single class",
Justification = "For simplicity we're allowing generic and non-generic versions in one file.")]
public class RelayCommand<T> : ICommand
{
private readonly Action<T> _execute;
private readonly Func<T, bool> _canExecute;
public RelayCommand(Action<T> execute) : this(execute, null)
public RelayCommand(Action<T> execute)
: this(execute, null)
{
}

Просмотреть файл

@ -12,6 +12,7 @@ namespace Microsoft.Templates.Core
public class DefaultNamesValidator : Validator
{
private static readonly Lazy<string[]> _defaultNames = new Lazy<string[]>(() => GetDefaultNames());
public static string[] DefaultNames => _defaultNames.Value;
private static string[] GetDefaultNames()

Просмотреть файл

@ -9,13 +9,14 @@ namespace Microsoft.Templates.Core
{
public class ExistingNamesValidator : Validator<IEnumerable<string>>
{
public ExistingNamesValidator(IEnumerable<string> config) : base(config)
public ExistingNamesValidator(IEnumerable<string> config)
: base(config)
{
}
public override ValidationResult Validate(string suggestedName)
{
if (_config.Contains(suggestedName))
if (Config.Contains(suggestedName))
{
return new ValidationResult()
{

Просмотреть файл

@ -9,13 +9,14 @@ namespace Microsoft.Templates.Core
{
public class FileExistsValidator : Validator<string>
{
public FileExistsValidator(string config) : base(config)
public FileExistsValidator(string config)
: base(config)
{
}
public override ValidationResult Validate(string suggestedName)
{
var existing = Directory.EnumerateFiles(_config)
var existing = Directory.EnumerateFiles(Config)
.Select(f => Path.GetFileNameWithoutExtension(f))
.ToList();

Просмотреть файл

@ -94,7 +94,7 @@ namespace Microsoft.Templates.Core
foreach (var chunk in valueChunks)
{
result.Append(string.Concat(char.ToUpper(chunk[0]), chunk.Substring(1), ""));
result.Append(string.Concat(char.ToUpper(chunk[0]), chunk.Substring(1), string.Empty));
}
return result.ToString();

Просмотреть файл

@ -10,7 +10,8 @@ namespace Microsoft.Templates.Core
public class SuggestedDirectoryNameValidator : Validator<string>
{
// config should be the path of an existing folder
public SuggestedDirectoryNameValidator(string config) : base(config)
public SuggestedDirectoryNameValidator(string config)
: base(config)
{
}
@ -18,12 +19,12 @@ namespace Microsoft.Templates.Core
public override ValidationResult Validate(string suggestedName)
{
// if the config directory doesn't exist then there's definitely not anything already in it with the suggested name
var suggestedDirectoryExists = Directory.Exists(_config);
var suggestedDirectoryExists = Directory.Exists(Config);
if (suggestedDirectoryExists)
{
// Does a subdirectory with the suggested name already exist?
var existingSubdirectories = Directory.EnumerateDirectories(_config)
var existingSubdirectories = Directory.EnumerateDirectories(Config)
.Select(d => new DirectoryInfo(d).Name)
.ToList();

Просмотреть файл

@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Diagnostics.CodeAnalysis;
namespace Microsoft.Templates.Core
{
public abstract class Validator
@ -9,13 +11,17 @@ namespace Microsoft.Templates.Core
public abstract ValidationResult Validate(string suggestedName);
}
[SuppressMessage(
"StyleCop.CSharp.MaintainabilityRules",
"SA1402:File may only contain a single class",
Justification = "For simplicity we're allowing generic and non-generic versions in one file.")]
public abstract class Validator<TConfig> : Validator
{
protected readonly TConfig _config;
public TConfig Config { get; }
public Validator(TConfig config)
{
_config = config;
Config = config;
}
}
}

Просмотреть файл

@ -14,15 +14,18 @@ namespace Microsoft.Templates.Core.Packaging
{
}
public InvalidSignatureException(string message) : base(message)
public InvalidSignatureException(string message)
: base(message)
{
}
public InvalidSignatureException(string message, Exception innerException) : base(message, innerException)
public InvalidSignatureException(string message, Exception innerException)
: base(message, innerException)
{
}
protected InvalidSignatureException(SerializationInfo info, StreamingContext context) : base(info, context)
protected InvalidSignatureException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
}

Просмотреть файл

@ -14,15 +14,18 @@ namespace Microsoft.Templates.Core.Packaging
{
}
public SignCertNotFoundException(string message) : base(message)
public SignCertNotFoundException(string message)
: base(message)
{
}
public SignCertNotFoundException(string message, Exception innerException) : base(message, innerException)
public SignCertNotFoundException(string message, Exception innerException)
: base(message, innerException)
{
}
protected SignCertNotFoundException(SerializationInfo info, StreamingContext context) : base(info, context)
protected SignCertNotFoundException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
}

Просмотреть файл

@ -22,7 +22,7 @@ namespace Microsoft.Templates.Core.Packaging
{
public const string DefaultExtension = ".mstx";
private const int bufSize = 0x1000;
private const int BufSize = 0x1000;
private const string TemplatesContentRelationshipType = "http://schemas.microsoft.com/opc/2006/06/templates/securecontent";
private static string CreateSourcePath(string source)
@ -74,6 +74,7 @@ namespace Microsoft.Templates.Core.Packaging
return outFile;
}
public static void Pack(string source, string outFile, string mimeMediaType)
{
if (string.IsNullOrWhiteSpace(source))
@ -245,7 +246,9 @@ namespace Microsoft.Templates.Core.Packaging
private static bool ValidateSignatures(Package package)
{
if (package == null)
{
throw new ArgumentNullException("ValidateSignatures(package)");
}
var dsm = new PackageDigitalSignatureManager(package);
bool result = dsm.IsSigned;
@ -315,26 +318,36 @@ namespace Microsoft.Templates.Core.Packaging
var status = PackageDigitalSignatureManager.VerifyCertificate(cert);
AppHealth.Current.Verbose.TrackAsync(string.Format(StringRes.TemplatePackageVerifyCertificateMessage, cert.Subject, status.ToString())).FireAndForget();
return (status == X509ChainStatusFlags.NoError);
return status == X509ChainStatusFlags.NoError;
}
private static bool VerifyAllowedPublicKey(X509Certificate cert)
{
var pubKeyCert = cert.GetPublicKeyString();
var pubKeyPin = pubKeyCert.ObfuscateSHA();
AppHealth.Current.Verbose.TrackAsync($"{StringRes.PackageCertificateString} {cert.Subject}").FireAndForget();
AppHealth.Current.Verbose.TrackAsync($"Key: {pubKeyCert}").FireAndForget();
AppHealth.Current.Verbose.TrackAsync($"Pin: {pubKeyPin}").FireAndForget();
return Configuration.Current.AllowedPublicKeysPins.Where(allowedPin => allowedPin.Equals(pubKeyPin)).Any();
bool pinAllowed = Configuration.Current.AllowedPublicKeysPins.Where(allowedPin => allowedPin.Equals(pubKeyPin)).Any();
AppHealth.Current.Verbose.TrackAsync($"Pin is allowed: {pinAllowed}").FireAndForget();
return pinAllowed;
}
private static void SignAllParts(Package package, X509Certificate cert)
{
if (package == null)
{
throw new ArgumentNullException("SignAllParts(package)");
}
if (cert == null)
{
throw new ArgumentNullException("SignAllParts(cert)");
}
var dsm = new PackageDigitalSignatureManager(package)
{
@ -366,14 +379,15 @@ namespace Microsoft.Templates.Core.Packaging
private static void CopyStream(Stream source, Stream target)
{
var buf = new byte[bufSize];
var buf = new byte[BufSize];
int bytesRead = 0;
while ((bytesRead = source.Read(buf, 0, bufSize)) > 0)
while ((bytesRead = source.Read(buf, 0, BufSize)) > 0)
{
target.Write(buf, 0, bytesRead);
}
}
private static void EnsureDirectory(string dir)
{
if (!string.IsNullOrEmpty(dir) && dir.ToLower() != Environment.CurrentDirectory.ToLower())
@ -407,7 +421,7 @@ namespace Microsoft.Templates.Core.Packaging
if (!Path.IsPathRooted(source))
{
uriString = Path.GetDirectoryName(Path.GetFullPath(source)).Replace(source, "");
uriString = Path.GetDirectoryName(Path.GetFullPath(source)).Replace(source, string.Empty);
if (!File.Exists(source))
{
uriString = uriString + Path.DirectorySeparatorChar;

Просмотреть файл

@ -13,13 +13,14 @@ namespace Microsoft.Templates.Core.PostActions.Catalog
{
public class AddItemToContextPostAction : PostAction<IReadOnlyList<ICreationPath>>
{
public AddItemToContextPostAction(IReadOnlyList<ICreationPath> config) : base(config)
public AddItemToContextPostAction(IReadOnlyList<ICreationPath> config)
: base(config)
{
}
public override void Execute()
{
var itemsToAdd = _config
var itemsToAdd = Config
.Where(o => !string.IsNullOrWhiteSpace(o.Path))
.Select(o => Path.GetFullPath(Path.Combine(GenContext.Current.ProjectPath, o.Path)))
.ToList();

Просмотреть файл

@ -14,14 +14,15 @@ namespace Microsoft.Templates.Core.PostActions.Catalog
{
public class AddProjectToSolutionPostAction : PostAction<IReadOnlyList<ICreationPath>>
{
public AddProjectToSolutionPostAction(IReadOnlyList<ICreationPath> config) : base(config)
public AddProjectToSolutionPostAction(IReadOnlyList<ICreationPath> config)
: base(config)
{
}
public override void Execute()
{
var chrono = Stopwatch.StartNew();
foreach (var output in _config)
foreach (var output in Config)
{
if (!string.IsNullOrWhiteSpace(output.Path))
{
@ -29,6 +30,7 @@ namespace Microsoft.Templates.Core.PostActions.Catalog
GenContext.ToolBox.Shell.AddProjectToSolution(projectPath);
}
}
chrono.Stop();
GenContext.Current.ProjectMetrics[ProjectMetricsEnum.AddProjectToSolution] = chrono.Elapsed.TotalSeconds;
}

Просмотреть файл

@ -16,7 +16,8 @@ namespace Microsoft.Templates.Core.PostActions.Catalog
{
public class GenerateTestCertificatePostAction : PostAction<string>
{
public GenerateTestCertificatePostAction(string config) : base(config)
public GenerateTestCertificatePostAction(string config)
: base(config)
{
}
@ -24,7 +25,7 @@ namespace Microsoft.Templates.Core.PostActions.Catalog
{
try
{
var publisherName = _config;
var publisherName = Config;
var pfx = CreateCertificate(publisherName);
AddToProject(pfx);
@ -46,7 +47,7 @@ namespace Microsoft.Templates.Core.PostActions.Catalog
private static void RemoveFromStore(string base64Encoded)
{
var certificate = new X509Certificate2(Convert.FromBase64String(base64Encoded), "");
var certificate = new X509Certificate2(Convert.FromBase64String(base64Encoded), string.Empty);
var store = new X509Store(StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadWrite);
@ -65,9 +66,11 @@ namespace Microsoft.Templates.Core.PostActions.Catalog
// Specify the hashing algorithm
var hashobj = new CObjectId();
hashobj.InitializeFromAlgorithmName(ObjectIdGroupId.XCN_CRYPT_HASH_ALG_OID_GROUP_ID,
hashobj.InitializeFromAlgorithmName(
ObjectIdGroupId.XCN_CRYPT_HASH_ALG_OID_GROUP_ID,
ObjectIdPublicKeyFlags.XCN_CRYPT_OID_INFO_PUBKEY_ANY,
AlgorithmFlags.AlgorithmFlagsNone, "SHA256");
AlgorithmFlags.AlgorithmFlagsNone,
"SHA256");
cert.HashAlgorithm = hashobj;
cert.Encode();
@ -80,9 +83,9 @@ namespace Microsoft.Templates.Core.PostActions.Catalog
var request = enrollment.CreateRequest();
enrollment.InstallResponse(InstallResponseRestrictionFlags.AllowUntrustedCertificate, request, EncodingType.XCN_CRYPT_STRING_BASE64, "");
enrollment.InstallResponse(InstallResponseRestrictionFlags.AllowUntrustedCertificate, request, EncodingType.XCN_CRYPT_STRING_BASE64, string.Empty);
var base64Encoded = enrollment.CreatePFX("", PFXExportOptions.PFXExportChainWithRoot);
var base64Encoded = enrollment.CreatePFX(string.Empty, PFXExportOptions.PFXExportChainWithRoot);
return base64Encoded;
}
@ -143,7 +146,7 @@ namespace Microsoft.Templates.Core.PostActions.Catalog
// Create the self signing request
var cert = new CX509CertificateRequestCertificate();
cert.InitializeFromPrivateKey(X509CertificateEnrollmentContext.ContextUser, privateKey, "");
cert.InitializeFromPrivateKey(X509CertificateEnrollmentContext.ContextUser, privateKey, string.Empty);
cert.Subject = dn;
cert.Issuer = dn;
cert.NotBefore = DateTime.Now.Date.AddDays(-1);

Просмотреть файл

@ -18,14 +18,14 @@ namespace Microsoft.Templates.Core.PostActions.Catalog.Merge
public const string Extension = "_" + Suffix + ".";
public const string PostactionRegex = @"(\$\S*)?(_" + Suffix + "|_g" + Suffix + @")\.";
public GenerateMergeInfoPostAction(string config) : base(config)
public GenerateMergeInfoPostAction(string config)
: base(config)
{
}
public override void Execute()
{
var fileName = _config;
var postAction = File.ReadAllText(_config).AsUserFriendlyPostAction();
var postAction = File.ReadAllText(Config).AsUserFriendlyPostAction();
var sourceFile = GetFilePath();
var mergeType = GetMergeType();
var relFilePath = sourceFile.Replace(GenContext.Current.OutputPath + Path.DirectorySeparatorChar, string.Empty);
@ -40,7 +40,7 @@ namespace Microsoft.Templates.Core.PostActions.Catalog.Merge
private string GetMergeType()
{
switch (Path.GetExtension(_config).ToLowerInvariant())
switch (Path.GetExtension(Config).ToLowerInvariant())
{
case ".cs":
return "csharp";
@ -57,16 +57,16 @@ namespace Microsoft.Templates.Core.PostActions.Catalog.Merge
private string GetFilePath()
{
if (Path.GetFileName(_config).StartsWith(Extension))
if (Path.GetFileName(Config).StartsWith(Extension))
{
var extension = Path.GetExtension(_config);
var directory = Path.GetDirectoryName(_config);
var extension = Path.GetExtension(Config);
var directory = Path.GetDirectoryName(Config);
return Directory.EnumerateFiles(directory, $"*{extension}").FirstOrDefault(f => !f.Contains(Suffix));
}
else
{
var path = Regex.Replace(_config, PostactionRegex, ".");
var path = Regex.Replace(Config, PostactionRegex, ".");
return path;
}

Просмотреть файл

@ -12,13 +12,14 @@ namespace Microsoft.Templates.Core.PostActions.Catalog.Merge
{
public class GetMergeFilesFromProjectPostAction : PostAction<string>
{
public GetMergeFilesFromProjectPostAction(string config) : base(config)
public GetMergeFilesFromProjectPostAction(string config)
: base(config)
{
}
public override void Execute()
{
if (Regex.IsMatch(_config, MergeConfiguration.GlobalExtension))
if (Regex.IsMatch(Config, MergeConfiguration.GlobalExtension))
{
GetFileFromProject();
}
@ -33,7 +34,7 @@ namespace Microsoft.Templates.Core.PostActions.Catalog.Merge
private void GetFileFromProject()
{
var filePath = GetMergeFileFromDirectory(Path.GetDirectoryName(_config.Replace(GenContext.Current.OutputPath, GenContext.Current.ProjectPath)));
var filePath = GetMergeFileFromDirectory(Path.GetDirectoryName(Config.Replace(GenContext.Current.OutputPath, GenContext.Current.ProjectPath)));
var relFilePath = filePath.Replace(GenContext.Current.ProjectPath + Path.DirectorySeparatorChar, string.Empty);
if (!GenContext.Current.MergeFilesFromProject.ContainsKey(relFilePath))
@ -49,21 +50,21 @@ namespace Microsoft.Templates.Core.PostActions.Catalog.Merge
private bool CheckLocalMergeFileAvailable()
{
var filePath = GetMergeFileFromDirectory(Path.GetDirectoryName(_config));
var filePath = GetMergeFileFromDirectory(Path.GetDirectoryName(Config));
return File.Exists(filePath) ? true : false;
}
private string GetMergeFileFromDirectory(string directory)
{
if (Path.GetFileName(_config).StartsWith(MergeConfiguration.Extension))
if (Path.GetFileName(Config).StartsWith(MergeConfiguration.Extension))
{
var extension = Path.GetExtension(_config);
var extension = Path.GetExtension(Config);
return Directory.EnumerateFiles(directory, $"*{extension}").FirstOrDefault(f => !Regex.IsMatch(f, MergeConfiguration.PostactionRegex));
}
else
{
var filePath = Path.Combine(directory, Path.GetFileName(_config));
var filePath = Path.Combine(directory, Path.GetFileName(Config));
var path = Regex.Replace(filePath, MergeConfiguration.PostactionRegex, ".");
return path;

Просмотреть файл

@ -135,7 +135,8 @@ namespace Microsoft.Templates.Core.PostActions.Catalog.Merge
// VB uses a single character (') to start the comment, C# uses two (//)
int commentIndicatorLength = mergeString[startIndex - 1] == '\'' ? 1 : 2;
var toRemove = mergeString.Substring((startIndex - commentIndicatorLength) + (MacroStartDelete.Length + commentIndicatorLength),
var toRemove = mergeString.Substring(
(startIndex - commentIndicatorLength) + (MacroStartDelete.Length + commentIndicatorLength),
(endIndex - commentIndicatorLength) - (startIndex - commentIndicatorLength) - (MacroStartDelete.Length + commentIndicatorLength));
sourceString = sourceString.Replace(toRemove, string.Empty);
@ -184,6 +185,7 @@ namespace Microsoft.Templates.Core.PostActions.Catalog.Merge
return insertionBuffer.Count;
}
}
return 0;
}

Просмотреть файл

@ -16,7 +16,8 @@ namespace Microsoft.Templates.Core.PostActions.Catalog.Merge
{
public class MergePostAction : PostAction<MergeConfiguration>
{
public MergePostAction(MergeConfiguration config) : base(config)
public MergePostAction(MergeConfiguration config)
: base(config)
{
}
@ -25,27 +26,27 @@ namespace Microsoft.Templates.Core.PostActions.Catalog.Merge
string originalFilePath = GetFilePath();
if (!File.Exists(originalFilePath))
{
if (_config.FailOnError )
if (Config.FailOnError )
{
throw new FileNotFoundException(string.Format(StringRes.MergeFileNotFoundExceptionMessage, _config.FilePath));
throw new FileNotFoundException(string.Format(StringRes.MergeFileNotFoundExceptionMessage, Config.FilePath));
}
else
{
AddFailedMergePostActionsFileNotFound(originalFilePath);
File.Delete(_config.FilePath);
File.Delete(Config.FilePath);
return;
}
}
var source = File.ReadAllLines(originalFilePath).ToList();
var merge = File.ReadAllLines(_config.FilePath).ToList();
var merge = File.ReadAllLines(Config.FilePath).ToList();
IEnumerable<string> result = source.HandleRemovals(merge);
result = result.Merge(merge.RemoveRemovals(), out string errorLine);
if (errorLine != string.Empty)
{
if (_config.FailOnError)
if (Config.FailOnError)
{
throw new InvalidDataException(string.Format(StringRes.MergeLineNotFoundExceptionMessage, errorLine, originalFilePath));
}
@ -60,25 +61,25 @@ namespace Microsoft.Templates.Core.PostActions.Catalog.Merge
File.WriteAllLines(originalFilePath, result, Encoding.UTF8);
// REFRESH PROJECT TO UN-DIRTY IT
if ((Path.GetExtension(_config.FilePath).Equals(".csproj", StringComparison.OrdinalIgnoreCase)
|| Path.GetExtension(_config.FilePath).Equals(".vbproj", StringComparison.OrdinalIgnoreCase))
if ((Path.GetExtension(Config.FilePath).Equals(".csproj", StringComparison.OrdinalIgnoreCase)
|| Path.GetExtension(Config.FilePath).Equals(".vbproj", StringComparison.OrdinalIgnoreCase))
&& (GenContext.Current.OutputPath == GenContext.Current.ProjectPath))
{
Gen.GenContext.ToolBox.Shell.RefreshProject();
}
}
File.Delete(_config.FilePath);
File.Delete(Config.FilePath);
}
protected void AddFailedMergePostActions(string originalFilePath, MergeFailureType mergeFailureType, string description)
{
var sourceFileName = GetRelativePath(originalFilePath);
var postactionFileName = GetRelativePath(_config.FilePath);
var postactionFileName = GetRelativePath(Config.FilePath);
var failedFileName = GetFailedPostActionFileName();
GenContext.Current.FailedMergePostActions.Add(new FailedMergePostAction(sourceFileName, _config.FilePath, failedFileName, description, mergeFailureType));
File.Copy(_config.FilePath, failedFileName, true);
GenContext.Current.FailedMergePostActions.Add(new FailedMergePostAction(sourceFileName, Config.FilePath, failedFileName, description, mergeFailureType));
File.Copy(Config.FilePath, failedFileName, true);
}
protected string GetRelativePath(string path)
@ -100,13 +101,13 @@ namespace Microsoft.Templates.Core.PostActions.Catalog.Merge
private string GetFailedPostActionFileName()
{
var newFileName = Path.GetFileNameWithoutExtension(_config.FilePath).Replace(MergeConfiguration.Suffix, MergeConfiguration.NewSuffix);
var folder = Path.GetDirectoryName(_config.FilePath);
var extension = Path.GetExtension(_config.FilePath);
var newFileName = Path.GetFileNameWithoutExtension(Config.FilePath).Replace(MergeConfiguration.Suffix, MergeConfiguration.NewSuffix);
var folder = Path.GetDirectoryName(Config.FilePath);
var extension = Path.GetExtension(Config.FilePath);
var validator = new List<Validator>
{
new FileExistsValidator(Path.GetDirectoryName(_config.FilePath))
new FileExistsValidator(Path.GetDirectoryName(Config.FilePath))
};
newFileName = Naming.Infer(newFileName, validator);
@ -115,16 +116,16 @@ namespace Microsoft.Templates.Core.PostActions.Catalog.Merge
private string GetFilePath()
{
if (Path.GetFileName(_config.FilePath).StartsWith(MergeConfiguration.Extension, StringComparison.InvariantCultureIgnoreCase))
if (Path.GetFileName(Config.FilePath).StartsWith(MergeConfiguration.Extension, StringComparison.InvariantCultureIgnoreCase))
{
var extension = Path.GetExtension(_config.FilePath);
var directory = Path.GetDirectoryName(_config.FilePath);
var extension = Path.GetExtension(Config.FilePath);
var directory = Path.GetDirectoryName(Config.FilePath);
return Directory.EnumerateFiles(directory, $"*{extension}").FirstOrDefault(f => !f.Contains(MergeConfiguration.Suffix));
}
else
{
var path = Regex.Replace(_config.FilePath, MergeConfiguration.PostactionRegex, ".");
var path = Regex.Replace(Config.FilePath, MergeConfiguration.PostactionRegex, ".");
return path;
}

Просмотреть файл

@ -17,14 +17,15 @@ namespace Microsoft.Templates.Core.PostActions.Catalog.Merge
{
public class MergeResourceDictionaryPostAction : MergePostAction
{
private const string mergeDictionaryPattern = @"<ResourceDictionary.MergedDictionaries>
private const string MergeDictionaryPattern = @"<ResourceDictionary.MergedDictionaries>
<!--^^-->
<!--{[{-->
<ResourceDictionary Source=""{filePath}""/>
<!--}]}-->
</ResourceDictionary.MergedDictionaries>";
public MergeResourceDictionaryPostAction(MergeConfiguration config) : base(config)
public MergeResourceDictionaryPostAction(MergeConfiguration config)
: base(config)
{
}
@ -33,13 +34,13 @@ namespace Microsoft.Templates.Core.PostActions.Catalog.Merge
string originalFilePath = GetFilePath();
if (!File.Exists(originalFilePath))
{
File.Copy(_config.FilePath, originalFilePath);
File.Copy(Config.FilePath, originalFilePath);
GenContext.Current.ProjectItems.Add(originalFilePath.Replace(GenContext.Current.OutputPath, GenContext.Current.ProjectPath));
AddToMergeDictionary(originalFilePath);
}
else
{
var mergeRoot = XElement.Load(_config.FilePath);
var mergeRoot = XElement.Load(Config.FilePath);
var sourceRoot = XElement.Load(originalFilePath);
foreach (var node in GetNodesToMerge(mergeRoot))
@ -54,14 +55,14 @@ namespace Microsoft.Templates.Core.PostActions.Catalog.Merge
if (!XNode.DeepEquals(node, sourceNode))
{
var errorMessage = string.Format(StringRes.FailedMergePostActionKeyAlreadyDefined, GetKey(node));
if (_config.FailOnError)
if (Config.FailOnError)
{
throw new InvalidDataException(errorMessage);
}
else
{
AddFailedMergePostActions(originalFilePath, MergeFailureType.KeyAlreadyDefined, errorMessage);
File.Delete(_config.FilePath);
File.Delete(Config.FilePath);
return;
}
}
@ -73,17 +74,16 @@ namespace Microsoft.Templates.Core.PostActions.Catalog.Merge
var writer = new ResourceDictionaryWriter(writeFile);
writer.WriteResourceDictionary(sourceRoot);
writer.Flush();
writer.Close();
}
}
File.Delete(_config.FilePath);
File.Delete(Config.FilePath);
}
private static void AddToMergeDictionary(string originalFilePath)
{
var relPath = originalFilePath.Replace(GenContext.Current.OutputPath, "").Replace(@"\", @"/");
var postactionContent = mergeDictionaryPattern.Replace("{filePath}", relPath);
var relPath = originalFilePath.Replace(GenContext.Current.OutputPath, string.Empty).Replace(@"\", @"/");
var postactionContent = MergeDictionaryPattern.Replace("{filePath}", relPath);
var mergeDictionaryName = Path.GetFileNameWithoutExtension(originalFilePath);
File.WriteAllText(GenContext.Current.OutputPath + $"/App${mergeDictionaryName}_gpostaction.xaml", postactionContent);
}
@ -101,7 +101,7 @@ namespace Microsoft.Templates.Core.PostActions.Catalog.Merge
private string GetKey(XElement node)
{
XNamespace ns = node.GetNamespaceOfPrefix("x");
return node.Attribute(ns + "Key").Value;
return node.Attribute(ns + "Key")?.Value;
}
private IEnumerable<XElement> GetNodesToMerge(XElement rootNode)
@ -111,7 +111,7 @@ namespace Microsoft.Templates.Core.PostActions.Catalog.Merge
private string GetFilePath()
{
return Regex.Replace(_config.FilePath, MergeConfiguration.PostactionRegex, ".");
return Regex.Replace(Config.FilePath, MergeConfiguration.PostactionRegex, ".");
}
}
}

Просмотреть файл

@ -13,18 +13,21 @@ namespace Microsoft.Templates.Core.PostActions.Catalog.Merge
public class ResourceDictionaryWriter : XmlTextWriter
{
private TextWriter writer;
private const string intend = " ";
private const string Intend = " ";
public ResourceDictionaryWriter(TextWriter w) : base(w)
public ResourceDictionaryWriter(TextWriter w)
: base(w)
{
writer = w;
}
public ResourceDictionaryWriter(Stream w, Encoding encoding) : base(w, encoding)
public ResourceDictionaryWriter(Stream w, Encoding encoding)
: base(w, encoding)
{
}
public ResourceDictionaryWriter(string filename, Encoding encoding) : base(filename, encoding)
public ResourceDictionaryWriter(string filename, Encoding encoding)
: base(filename, encoding)
{
}
@ -33,7 +36,7 @@ namespace Microsoft.Templates.Core.PostActions.Catalog.Merge
if (!string.IsNullOrEmpty(prefix))
{
localName = prefix + ":" + localName;
prefix = "";
prefix = string.Empty;
}
base.WriteStartElement(prefix, localName, ns);
@ -60,6 +63,7 @@ namespace Microsoft.Templates.Core.PostActions.Catalog.Merge
{
WriteElement(node);
}
WriteFullEndElement();
WriteNewLine();
}
@ -67,8 +71,8 @@ namespace Microsoft.Templates.Core.PostActions.Catalog.Merge
private void WriteElement(XElement e)
{
WriteComments(e);
WriteRaw(intend);
WriteStartElement(e.GetPrefixOfNamespace(e.Name.Namespace), e.Name.LocalName, "");
WriteRaw(Intend);
WriteStartElement(e.GetPrefixOfNamespace(e.Name.Namespace), e.Name.LocalName, string.Empty);
WriteAttributes(e);
if (e.Descendants().Count() > 0)
{
@ -78,6 +82,7 @@ namespace Microsoft.Templates.Core.PostActions.Catalog.Merge
{
WriteRaw(e.Value);
}
WriteEndElement();
WriteNewLine();
if (e.Name.LocalName == "Style")
@ -101,7 +106,7 @@ namespace Microsoft.Templates.Core.PostActions.Catalog.Merge
{
if (e.PreviousNode != null && e.PreviousNode.NodeType == XmlNodeType.Comment)
{
WriteRaw(intend);
WriteRaw(Intend);
WriteComment((e.PreviousNode as XComment).Value);
WriteNewLine();
}
@ -112,14 +117,15 @@ namespace Microsoft.Templates.Core.PostActions.Catalog.Merge
WriteNewLine();
foreach (var n in e.Descendants())
{
WriteRaw(intend);
WriteRaw(intend);
WriteStartElement(e.GetPrefixOfNamespace(n.Name.Namespace), n.Name.LocalName, "");
WriteRaw(Intend);
WriteRaw(Intend);
WriteStartElement(e.GetPrefixOfNamespace(n.Name.Namespace), n.Name.LocalName, string.Empty);
WriteAttributes(n);
WriteEndElement();
WriteNewLine();
}
WriteRaw(intend);
WriteRaw(Intend);
}
private void WriteAttributes(XElement e)

Просмотреть файл

@ -14,13 +14,14 @@ namespace Microsoft.Templates.Core.PostActions.Catalog
{
public class CopyFilesToProjectPostAction : PostAction<TempGenerationResult>
{
public CopyFilesToProjectPostAction(TempGenerationResult config) : base(config)
public CopyFilesToProjectPostAction(TempGenerationResult config)
: base(config)
{
}
public override void Execute()
{
foreach (var file in _config.ModifiedFiles)
foreach (var file in Config.ModifiedFiles)
{
var sourceFile = Path.Combine(GenContext.Current.OutputPath, file);
var destFilePath = Path.Combine(GenContext.Current.ProjectPath, file);
@ -31,10 +32,11 @@ namespace Microsoft.Templates.Core.PostActions.Catalog
{
Gen.GenContext.ToolBox.Shell.RefreshProject();
GenContext.ToolBox.Shell.SaveSolution();
GenContext.ToolBox.Shell.CleanSolution();
}
}
foreach (var file in _config.NewFiles)
foreach (var file in Config.NewFiles)
{
var sourceFile = Path.Combine(GenContext.Current.OutputPath, file);
var destFilePath = Path.Combine(GenContext.Current.ProjectPath, file);

Просмотреть файл

@ -9,21 +9,22 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Templates.Core.Gen;
using Microsoft.Templates.Core.Resources;
using Microsoft.Templates.Core.PostActions.Catalog.Merge;
using Microsoft.Templates.Core.Resources;
namespace Microsoft.Templates.Core.PostActions.Catalog
{
public class CreateSummaryPostAction : PostAction<TempGenerationResult>
{
public CreateSummaryPostAction(TempGenerationResult config) : base(config)
public CreateSummaryPostAction(TempGenerationResult config)
: base(config)
{
}
public override void Execute()
{
var fileName = GetFileName();
if (_config.SyncGeneration)
if (Config.SyncGeneration)
{
var newFiles = BuildNewFilesSection(StringRes.SyncSummarySectionNewFiles);
@ -51,7 +52,7 @@ namespace Microsoft.Templates.Core.PostActions.Catalog
private string GetFileName()
{
if (_config.SyncGeneration)
if (Config.SyncGeneration)
{
return Path.Combine(GenContext.Current.OutputPath, StringRes.SyncSummaryFileName);
}
@ -110,15 +111,16 @@ namespace Microsoft.Templates.Core.PostActions.Catalog
sb.AppendLine();
sb.AppendLine($"* {failedMergePostAction.Description}");
}
return sb.ToString();
}
}
private string BuildNewFilesSection(string sectionTemplate)
{
if (_config.NewFiles.Any())
if (Config.NewFiles.Any())
{
return string.Format(sectionTemplate, GetFileList(_config.NewFiles));
return string.Format(sectionTemplate, GetFileList(Config.NewFiles));
}
else
{
@ -128,9 +130,9 @@ namespace Microsoft.Templates.Core.PostActions.Catalog
private string BuildUnchangedFilesSection(string sectionTemplate)
{
if (_config.UnchangedFiles.Any())
if (Config.UnchangedFiles.Any())
{
return string.Format(sectionTemplate, GetFileList(_config.UnchangedFiles));
return string.Format(sectionTemplate, GetFileList(Config.UnchangedFiles));
}
else
{
@ -140,10 +142,10 @@ namespace Microsoft.Templates.Core.PostActions.Catalog
private string BuildConflictingFilesSection(string sectionTemplate)
{
if (_config.ConflictingFiles.Any())
if (Config.ConflictingFiles.Any())
{
var sb = new StringBuilder();
foreach (var conflictFile in _config.ConflictingFiles)
foreach (var conflictFile in Config.ConflictingFiles)
{
sb.AppendLine(GetCompareLink(conflictFile));
}
@ -169,7 +171,7 @@ namespace Microsoft.Templates.Core.PostActions.Catalog
private string GetLinkToFile(string fileName)
{
if (_config.SyncGeneration)
if (Config.SyncGeneration)
{
var filePath = Path.Combine(GenContext.Current.ProjectPath, fileName);
return $"[{fileName}]({FormatFilePath(filePath)})";
@ -179,6 +181,7 @@ namespace Microsoft.Templates.Core.PostActions.Catalog
return $"[{fileName}]({fileName})";
}
}
private static string FormatFilePath(string filePath)
{
return $"about:/{filePath.Replace(" ", "%20").Replace(@"\", "/")}";

Просмотреть файл

@ -20,7 +20,8 @@ namespace Microsoft.Templates.Core.PostActions.Catalog
public const string PostactionRegex = @"(\$\S*)?(_" + Suffix + @")\.";
public SearchAndReplacePostAction(string config) : base(config)
public SearchAndReplacePostAction(string config)
: base(config)
{
}
@ -30,11 +31,11 @@ namespace Microsoft.Templates.Core.PostActions.Catalog
if (string.IsNullOrEmpty(originalFilePath))
{
throw new FileNotFoundException($"There is no merge target for file '{_config}'");
throw new FileNotFoundException($"There is no merge target for file '{Config}'");
}
var source = File.ReadAllLines(originalFilePath).ToList();
var instructions = File.ReadAllLines(_config).ToList();
var instructions = File.ReadAllLines(Config).ToList();
var search = new List<string>();
var replace = new List<string>();
@ -64,10 +65,10 @@ namespace Microsoft.Templates.Core.PostActions.Catalog
result = result.Replace(string.Join(Environment.NewLine, search), string.Join(Environment.NewLine, replace));
File.WriteAllLines(originalFilePath, result.Split(new[] { Environment.NewLine }, StringSplitOptions.None));
File.Delete(_config);
File.Delete(Config);
// REFRESH PROJECT TO UN-DIRTY IT
if (Path.GetExtension(_config).Equals(".csproj", StringComparison.OrdinalIgnoreCase))
if (Path.GetExtension(Config).Equals(".csproj", StringComparison.OrdinalIgnoreCase))
{
Gen.GenContext.ToolBox.Shell.RefreshProject();
}
@ -75,18 +76,18 @@ namespace Microsoft.Templates.Core.PostActions.Catalog
private string GetFilePath()
{
if (Path.GetFileName(_config).StartsWith(Extension, StringComparison.Ordinal))
if (Path.GetFileName(Config).StartsWith(Extension, StringComparison.Ordinal))
{
var extension = Path.GetExtension(_config);
var directory = Path.GetDirectoryName(_config);
var extension = Path.GetExtension(Config);
var directory = Path.GetDirectoryName(Config);
return Directory.EnumerateFiles(directory, $"*{extension}").FirstOrDefault(f => !f.Contains(Suffix));
}
else
{
var path = Regex.Replace(_config, PostactionRegex, ".");
var path = Regex.Replace(Config, PostactionRegex, ".");
return (File.Exists(path) ? path : string.Empty);
return File.Exists(path) ? path : string.Empty;
}
}
}

Просмотреть файл

@ -56,6 +56,7 @@ namespace Microsoft.Templates.Core.PostActions.Catalog.SortNamespaces
{
orderedUsings.Add(string.Empty);
}
var orderedKeys = GetOrderedNs(usings.Select(u => u.Key)).ToList();
foreach (var key in orderedKeys)

Просмотреть файл

@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Diagnostics.CodeAnalysis;
namespace Microsoft.Templates.Core.PostActions
{
public abstract class PostAction
@ -9,13 +11,18 @@ namespace Microsoft.Templates.Core.PostActions
public abstract void Execute();
}
[SuppressMessage(
"StyleCop.CSharp.MaintainabilityRules",
"SA1402:File may only contain a single class",
Justification = "For simplicity we're allowing generic and non-generic versions in one file.")]
public abstract class PostAction<TConfig> : PostAction
{
protected readonly TConfig _config;
protected TConfig Config { get; }
public PostAction(TConfig config)
{
_config = config;
Config = config;
}
}
}

Просмотреть файл

@ -15,6 +15,7 @@ namespace Microsoft.Templates.Core
public static IEnumerable<string> GetAllLanguages()
{
yield return ProgrammingLanguages.CSharp;
// yield return ProgrammingLanguages.VisualBasic; // This is currently disabled until full VB support is enabled
}
}

Просмотреть файл

@ -372,4 +372,19 @@ The following changes could not be integrated: {2}
<data name="SyncSummaryProjectFile" xml:space="preserve">
<value>ProjectFile</value>
</data>
<data name="TemplatesSynchronizationWaitingOtherInstanceMessage" xml:space="preserve">
<value>Other instance is syncing templates... Waiting 5 seconds.</value>
</data>
<data name="TemplatesSynchronizationWarnCreatingLockFileMessage" xml:space="preserve">
<value>Error creating the instance locking file.</value>
</data>
<data name="TemplatesSynchronizationWarnDeletingLockFileMessage" xml:space="preserve">
<value>Error deleting the instance locking file.</value>
</data>
<data name="TemplatesSynchronizationWarnReadingLockFileMessage" xml:space="preserve">
<value>Error reading the instance locking file.</value>
</data>
<data name="FailedMergePostActionKeyAlreadyDefined" xml:space="preserve">
<value>The style with key '{0}' is already defined with different value or elements in this file. Please review the styles to include the changes manually where required in your project.</value>
</data>
</root>

Просмотреть файл

@ -372,4 +372,19 @@ The following changes could not be integrated: {2}
<data name="SyncSummaryProjectFile" xml:space="preserve">
<value>ProjectFile</value>
</data>
<data name="TemplatesSynchronizationWaitingOtherInstanceMessage" xml:space="preserve">
<value>Other instance is syncing templates... Waiting 5 seconds.</value>
</data>
<data name="TemplatesSynchronizationWarnCreatingLockFileMessage" xml:space="preserve">
<value>Error creating the instance locking file.</value>
</data>
<data name="TemplatesSynchronizationWarnDeletingLockFileMessage" xml:space="preserve">
<value>Error deleting the instance locking file.</value>
</data>
<data name="TemplatesSynchronizationWarnReadingLockFileMessage" xml:space="preserve">
<value>Error reading the instance locking file.</value>
</data>
<data name="FailedMergePostActionKeyAlreadyDefined" xml:space="preserve">
<value>The style with key '{0}' is already defined with different value or elements in this file. Please review the styles to include the changes manually where required in your project.</value>
</data>
</root>

Просмотреть файл

@ -372,4 +372,19 @@ The following changes could not be integrated: {2}
<data name="SyncSummaryProjectFile" xml:space="preserve">
<value>ProjectFile</value>
</data>
<data name="TemplatesSynchronizationWaitingOtherInstanceMessage" xml:space="preserve">
<value>Other instance is syncing templates... Waiting 5 seconds.</value>
</data>
<data name="TemplatesSynchronizationWarnCreatingLockFileMessage" xml:space="preserve">
<value>Error creating the instance locking file.</value>
</data>
<data name="TemplatesSynchronizationWarnDeletingLockFileMessage" xml:space="preserve">
<value>Error deleting the instance locking file.</value>
</data>
<data name="TemplatesSynchronizationWarnReadingLockFileMessage" xml:space="preserve">
<value>Error reading the instance locking file.</value>
</data>
<data name="FailedMergePostActionKeyAlreadyDefined" xml:space="preserve">
<value>The style with key '{0}' is already defined with different value or elements in this file. Please review the styles to include the changes manually where required in your project.</value>
</data>
</root>

Просмотреть файл

@ -372,4 +372,19 @@ The following changes could not be integrated: {2}
<data name="SyncSummaryProjectFile" xml:space="preserve">
<value>ProjectFile</value>
</data>
<data name="TemplatesSynchronizationWaitingOtherInstanceMessage" xml:space="preserve">
<value>Other instance is syncing templates... Waiting 5 seconds.</value>
</data>
<data name="TemplatesSynchronizationWarnCreatingLockFileMessage" xml:space="preserve">
<value>Error creating the instance locking file.</value>
</data>
<data name="TemplatesSynchronizationWarnDeletingLockFileMessage" xml:space="preserve">
<value>Error deleting the instance locking file.</value>
</data>
<data name="TemplatesSynchronizationWarnReadingLockFileMessage" xml:space="preserve">
<value>Error reading the instance locking file.</value>
</data>
<data name="FailedMergePostActionKeyAlreadyDefined" xml:space="preserve">
<value>The style with key '{0}' is already defined with different value or elements in this file. Please review the styles to include the changes manually where required in your project.</value>
</data>
</root>

Просмотреть файл

@ -372,4 +372,19 @@ The following changes could not be integrated: {2}
<data name="SyncSummaryProjectFile" xml:space="preserve">
<value>ProjectFile</value>
</data>
<data name="TemplatesSynchronizationWaitingOtherInstanceMessage" xml:space="preserve">
<value>Other instance is syncing templates... Waiting 5 seconds.</value>
</data>
<data name="TemplatesSynchronizationWarnCreatingLockFileMessage" xml:space="preserve">
<value>Error creating the instance locking file.</value>
</data>
<data name="TemplatesSynchronizationWarnDeletingLockFileMessage" xml:space="preserve">
<value>Error deleting the instance locking file.</value>
</data>
<data name="TemplatesSynchronizationWarnReadingLockFileMessage" xml:space="preserve">
<value>Error reading the instance locking file.</value>
</data>
<data name="FailedMergePostActionKeyAlreadyDefined" xml:space="preserve">
<value>The style with key '{0}' is already defined with different value or elements in this file. Please review the styles to include the changes manually where required in your project.</value>
</data>
</root>

Просмотреть файл

@ -372,4 +372,19 @@ The following changes could not be integrated: {2}
<data name="SyncSummaryProjectFile" xml:space="preserve">
<value>ProjectFile</value>
</data>
<data name="TemplatesSynchronizationWaitingOtherInstanceMessage" xml:space="preserve">
<value>Other instance is syncing templates... Waiting 5 seconds.</value>
</data>
<data name="TemplatesSynchronizationWarnCreatingLockFileMessage" xml:space="preserve">
<value>Error creating the instance locking file.</value>
</data>
<data name="TemplatesSynchronizationWarnDeletingLockFileMessage" xml:space="preserve">
<value>Error deleting the instance locking file.</value>
</data>
<data name="TemplatesSynchronizationWarnReadingLockFileMessage" xml:space="preserve">
<value>Error reading the instance locking file.</value>
</data>
<data name="FailedMergePostActionKeyAlreadyDefined" xml:space="preserve">
<value>The style with key '{0}' is already defined with different value or elements in this file. Please review the styles to include the changes manually where required in your project.</value>
</data>
</root>

Просмотреть файл

@ -372,4 +372,19 @@ The following changes could not be integrated: {2}
<data name="SyncSummaryProjectFile" xml:space="preserve">
<value>ProjectFile</value>
</data>
<data name="TemplatesSynchronizationWaitingOtherInstanceMessage" xml:space="preserve">
<value>Other instance is syncing templates... Waiting 5 seconds.</value>
</data>
<data name="TemplatesSynchronizationWarnCreatingLockFileMessage" xml:space="preserve">
<value>Error creating the instance locking file.</value>
</data>
<data name="TemplatesSynchronizationWarnDeletingLockFileMessage" xml:space="preserve">
<value>Error deleting the instance locking file.</value>
</data>
<data name="TemplatesSynchronizationWarnReadingLockFileMessage" xml:space="preserve">
<value>Error reading the instance locking file.</value>
</data>
<data name="FailedMergePostActionKeyAlreadyDefined" xml:space="preserve">
<value>The style with key '{0}' is already defined with different value or elements in this file. Please review the styles to include the changes manually where required in your project.</value>
</data>
</root>

Просмотреть файл

@ -372,4 +372,19 @@ The following changes could not be integrated: {2}
<data name="SyncSummaryProjectFile" xml:space="preserve">
<value>ProjectFile</value>
</data>
<data name="TemplatesSynchronizationWaitingOtherInstanceMessage" xml:space="preserve">
<value>Other instance is syncing templates... Waiting 5 seconds.</value>
</data>
<data name="TemplatesSynchronizationWarnCreatingLockFileMessage" xml:space="preserve">
<value>Error creating the instance locking file.</value>
</data>
<data name="TemplatesSynchronizationWarnDeletingLockFileMessage" xml:space="preserve">
<value>Error deleting the instance locking file.</value>
</data>
<data name="TemplatesSynchronizationWarnReadingLockFileMessage" xml:space="preserve">
<value>Error reading the instance locking file.</value>
</data>
<data name="FailedMergePostActionKeyAlreadyDefined" xml:space="preserve">
<value>The style with key '{0}' is already defined with different value or elements in this file. Please review the styles to include the changes manually where required in your project.</value>
</data>
</root>

Просмотреть файл

@ -372,4 +372,19 @@ The following changes could not be integrated: {2}
<data name="SyncSummaryProjectFile" xml:space="preserve">
<value>ProjectFile</value>
</data>
<data name="TemplatesSynchronizationWaitingOtherInstanceMessage" xml:space="preserve">
<value>Other instance is syncing templates... Waiting 5 seconds.</value>
</data>
<data name="TemplatesSynchronizationWarnCreatingLockFileMessage" xml:space="preserve">
<value>Error creating the instance locking file.</value>
</data>
<data name="TemplatesSynchronizationWarnDeletingLockFileMessage" xml:space="preserve">
<value>Error deleting the instance locking file.</value>
</data>
<data name="TemplatesSynchronizationWarnReadingLockFileMessage" xml:space="preserve">
<value>Error reading the instance locking file.</value>
</data>
<data name="FailedMergePostActionKeyAlreadyDefined" xml:space="preserve">
<value>The style with key '{0}' is already defined with different value or elements in this file. Please review the styles to include the changes manually where required in your project.</value>
</data>
</root>

Просмотреть файл

@ -372,4 +372,19 @@ The following changes could not be integrated: {2}
<data name="SyncSummaryProjectFile" xml:space="preserve">
<value>ProjectFile</value>
</data>
<data name="TemplatesSynchronizationWaitingOtherInstanceMessage" xml:space="preserve">
<value>Other instance is syncing templates... Waiting 5 seconds.</value>
</data>
<data name="TemplatesSynchronizationWarnCreatingLockFileMessage" xml:space="preserve">
<value>Error creating the instance locking file.</value>
</data>
<data name="TemplatesSynchronizationWarnDeletingLockFileMessage" xml:space="preserve">
<value>Error deleting the instance locking file.</value>
</data>
<data name="TemplatesSynchronizationWarnReadingLockFileMessage" xml:space="preserve">
<value>Error reading the instance locking file.</value>
</data>
<data name="FailedMergePostActionKeyAlreadyDefined" xml:space="preserve">
<value>The style with key '{0}' is already defined with different value or elements in this file. Please review the styles to include the changes manually where required in your project.</value>
</data>
</root>

Просмотреть файл

@ -372,4 +372,19 @@ The following changes could not be integrated: {2}
<data name="SyncSummaryProjectFile" xml:space="preserve">
<value>ProjectFile</value>
</data>
<data name="TemplatesSynchronizationWaitingOtherInstanceMessage" xml:space="preserve">
<value>Other instance is syncing templates... Waiting 5 seconds.</value>
</data>
<data name="TemplatesSynchronizationWarnCreatingLockFileMessage" xml:space="preserve">
<value>Error creating the instance locking file.</value>
</data>
<data name="TemplatesSynchronizationWarnDeletingLockFileMessage" xml:space="preserve">
<value>Error deleting the instance locking file.</value>
</data>
<data name="TemplatesSynchronizationWarnReadingLockFileMessage" xml:space="preserve">
<value>Error reading the instance locking file.</value>
</data>
<data name="FailedMergePostActionKeyAlreadyDefined" xml:space="preserve">
<value>The style with key '{0}' is already defined with different value or elements in this file. Please review the styles to include the changes manually where required in your project.</value>
</data>
</root>

Просмотреть файл

@ -372,4 +372,19 @@ The following changes could not be integrated: {2}
<data name="SyncSummaryProjectFile" xml:space="preserve">
<value>ProjectFile</value>
</data>
<data name="TemplatesSynchronizationWaitingOtherInstanceMessage" xml:space="preserve">
<value>Other instance is syncing templates... Waiting 5 seconds.</value>
</data>
<data name="TemplatesSynchronizationWarnCreatingLockFileMessage" xml:space="preserve">
<value>Error creating the instance locking file.</value>
</data>
<data name="TemplatesSynchronizationWarnDeletingLockFileMessage" xml:space="preserve">
<value>Error deleting the instance locking file.</value>
</data>
<data name="TemplatesSynchronizationWarnReadingLockFileMessage" xml:space="preserve">
<value>Error reading the instance locking file.</value>
</data>
<data name="FailedMergePostActionKeyAlreadyDefined" xml:space="preserve">
<value>The style with key '{0}' is already defined with different value or elements in this file. Please review the styles to include the changes manually where required in your project.</value>
</data>
</root>

Просмотреть файл

@ -372,4 +372,19 @@ The following changes could not be integrated: {2}
<data name="SyncSummaryProjectFile" xml:space="preserve">
<value>ProjectFile</value>
</data>
<data name="TemplatesSynchronizationWaitingOtherInstanceMessage" xml:space="preserve">
<value>Other instance is syncing templates... Waiting 5 seconds.</value>
</data>
<data name="TemplatesSynchronizationWarnCreatingLockFileMessage" xml:space="preserve">
<value>Error creating the instance locking file.</value>
</data>
<data name="TemplatesSynchronizationWarnDeletingLockFileMessage" xml:space="preserve">
<value>Error deleting the instance locking file.</value>
</data>
<data name="TemplatesSynchronizationWarnReadingLockFileMessage" xml:space="preserve">
<value>Error reading the instance locking file.</value>
</data>
<data name="FailedMergePostActionKeyAlreadyDefined" xml:space="preserve">
<value>The style with key '{0}' is already defined with different value or elements in this file. Please review the styles to include the changes manually where required in your project.</value>
</data>
</root>

Просмотреть файл

@ -83,7 +83,10 @@ namespace Microsoft.Templates.Core
var configDir = GetConfigDir(ti);
var descriptionFile = Directory.EnumerateFiles(configDir, $"{CultureInfo.CurrentUICulture.IetfLanguageTag}.description.md").FirstOrDefault();
if (string.IsNullOrWhiteSpace(descriptionFile) || !File.Exists(descriptionFile))
{
descriptionFile = Directory.EnumerateFiles(configDir, "description.md").FirstOrDefault();
}
if (!string.IsNullOrEmpty(descriptionFile))
{
return File.ReadAllText(descriptionFile);
@ -346,7 +349,7 @@ namespace Microsoft.Templates.Core
public static bool GetItemNameEditable(this ITemplateInfo ti)
{
return (ti.GetTemplateType() == TemplateType.Page || ti.GetMultipleInstance());
return ti.GetTemplateType() == TemplateType.Page || ti.GetMultipleInstance();
}
private static string GetConfigDir(ITemplateInfo ti)

Просмотреть файл

@ -2,12 +2,19 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Newtonsoft.Json;
namespace Microsoft.Templates.Core
{
public class LayoutItem
{
public string name { get; set; }
public string templateGroupIdentity { get; set; }
public bool @readonly { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("templateGroupIdentity")]
public string TemplateGroupIdentity { get; set; }
[JsonProperty("readonly")]
public bool Readonly { get; set; }
}
}

Просмотреть файл

@ -17,15 +17,18 @@ namespace Microsoft.Templates.Core
{
}
public RepositorySynchronizationException(string message, Exception innerException = null) : base(message, innerException)
public RepositorySynchronizationException(string message, Exception innerException = null)
: base(message, innerException)
{
}
protected RepositorySynchronizationException(SerializationInfo info, StreamingContext context) : base(info, context)
protected RepositorySynchronizationException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
public RepositorySynchronizationException(SyncStatus status, Exception innerException = null) : base($"{StringRes.RepositorySynchronizationExceptionMessage} '{status}'", innerException)
public RepositorySynchronizationException(SyncStatus status, Exception innerException = null)
: base($"{StringRes.RepositorySynchronizationExceptionMessage} '{status}'", innerException)
{
}
}

Просмотреть файл

@ -7,6 +7,7 @@ namespace Microsoft.Templates.Core
public class TemplateLicense
{
public string Text { get; set; }
public string Url { get; set; }
}
}

Просмотреть файл

@ -4,11 +4,11 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Globalization;
using Microsoft.TemplateEngine.Abstractions;
using Microsoft.TemplateEngine.Edge.Template;
@ -22,15 +22,23 @@ namespace Microsoft.Templates.Core
public class TemplatesRepository
{
private readonly string _language;
private const string Separator = "|";
private const string LicensesPattern = @"\[(?<text>.*?)\]\((?<url>.*?)\)\" + Separator + "?";
private const string Catalog = "_catalog";
private static readonly string[] SupportedIconTypes = { ".jpg", ".jpeg", ".png", ".xaml" };
public TemplatesSynchronization Sync { get; private set; }
public string WizardVersion { get; private set; }
public string CurrentContentFolder { get => Sync?.CurrentContentFolder; }
public string TemplatesVersion { get => Sync.CurrentContentVersion?.ToString() ?? string.Empty; }
public bool SyncInProgress { get => TemplatesSynchronization.SyncInProgress; }
public TemplatesRepository(TemplatesSource source, Version wizardVersion, string language)

Просмотреть файл

@ -7,6 +7,7 @@ namespace Microsoft.Templates.Core
public class ValidationResult
{
public bool IsValid { get; set; }
public ValidationErrorType ErrorType { get; set; }
}
}

Просмотреть файл

@ -51,6 +51,10 @@
<assemblyIdentity name="Microsoft.TemplateEngine.Orchestrator.RunnableProjects" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.0.0.234" newVersion="1.0.0.234" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.VisualStudio.Validation" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-15.3.0.0" newVersion="15.3.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

Просмотреть файл

@ -15,10 +15,10 @@
<package id="Microsoft.TemplateEngine.Utils" version="1.0.0-beta2-20170518-234" targetFramework="net462" />
<package id="Microsoft.VisualStudio.RemoteControl" version="14.0.262-masterA5CACE98" targetFramework="net462" />
<package id="Microsoft.VisualStudio.Telemetry" version="15.3.789-masterCC863119" targetFramework="net462" />
<package id="Microsoft.VisualStudio.Threading" version="15.0.240" targetFramework="net462" />
<package id="Microsoft.VisualStudio.Threading" version="15.3.23" targetFramework="net47" />
<package id="Microsoft.VisualStudio.Threading.Analyzers" version="15.0.240" targetFramework="net462" developmentDependency="true" />
<package id="Microsoft.VisualStudio.Utilities.Internal" version="14.0.72-masterF9EB1D39" targetFramework="net462" />
<package id="Microsoft.VisualStudio.Validation" version="15.0.82" targetFramework="net462" />
<package id="Microsoft.VisualStudio.Validation" version="15.3.15" targetFramework="net47" />
<package id="Newtonsoft.Json" version="10.0.3" targetFramework="net462" />
<package id="StyleCop.Analyzers" version="1.0.2" targetFramework="net462" developmentDependency="true" />
<package id="System.Collections" version="4.3.0" targetFramework="net462" />

Просмотреть файл

@ -3,10 +3,7 @@
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics.CodeAnalysis;
namespace Microsoft.Templates.Extension.Commands
{
@ -17,12 +14,14 @@ namespace Microsoft.Templates.Extension.Commands
public const int OpenTempFolder = 0x600;
}
[SuppressMessage("StyleCop", "SA1402", Justification = "This class does not have implementation. Used for constants.")]
internal class PackageGuids
{
/// <summary>
/// RelayCommandPackage GUID string.
/// </summary>
public const string PackageGuidString = "ae1b4c32-9c93-45b8-a36b-8734f4b120dd";
public static Guid GuidRelayCommandPackageCmdSet = Guid.Parse("caa4fb82-0dca-40fe-bae0-081e0f96226f");
public static Guid GuidRelayCommandPackageCmdSet { get; } = Guid.Parse("caa4fb82-0dca-40fe-bae0-081e0f96226f");
}
}

Просмотреть файл

@ -31,6 +31,7 @@ namespace Microsoft.Templates.Extension.Commands
{
menuItem.BeforeQueryStatus += beforeQueryStatus.Invoke;
}
commandService.AddCommand(menuItem);
}
}

Просмотреть файл

@ -3,20 +3,13 @@
// See the LICENSE file in the project root for more information.
using System;
using System.ComponentModel.Design;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Templates.Core.Gen;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.OLE.Interop;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.Win32;
using Microsoft.Templates.UI.Threading;
using Microsoft.Templates.UI.VisualStudio;
using Microsoft.VisualStudio.Shell;
namespace Microsoft.Templates.Extension.Commands
{
@ -30,6 +23,7 @@ namespace Microsoft.Templates.Extension.Commands
public sealed class RelayCommandPackage : AsyncPackage
{
private readonly Lazy<RightClickActions> _rightClickActions = new Lazy<RightClickActions>(() => new RightClickActions());
private RightClickActions RightClickActions => _rightClickActions.Value;
private RelayCommand addPageCommand;
@ -42,7 +36,7 @@ namespace Microsoft.Templates.Extension.Commands
protected override async System.Threading.Tasks.Task InitializeAsync(CancellationToken cancellationToken, IProgress<ServiceProgressData> progress)
{
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
await SafeThreading.JoinableTaskFactory.SwitchToMainThreadAsync();
InitializeCommands();
@ -51,19 +45,22 @@ namespace Microsoft.Templates.Extension.Commands
private void InitializeCommands()
{
addPageCommand = new RelayCommand(this,
addPageCommand = new RelayCommand(
this,
PackageIds.AddPageCommand,
PackageGuids.GuidRelayCommandPackageCmdSet,
AddPage,
RightClickAvailable);
addFeatureCommand = new RelayCommand(this,
addFeatureCommand = new RelayCommand(
this,
PackageIds.AddFeatureCommand,
PackageGuids.GuidRelayCommandPackageCmdSet,
AddFeature,
RightClickAvailable);
openTempFolderCommand = new RelayCommand(this,
openTempFolderCommand = new RelayCommand(
this,
PackageIds.OpenTempFolder,
PackageGuids.GuidRelayCommandPackageCmdSet,
OpenTempFolder,

Просмотреть файл

@ -6,7 +6,7 @@
<!--This header contains the command ids for the menus provided by the shell. -->
<Extern href="vsshlids.h"/>
<VisibilityConstraints>
<VisibilityItem guid="guidRelayCommandPackageCmdSet"
id="AddPageCommand" context="UICONTEXT_SolutionHasSingleProject" />

Просмотреть файл

@ -6,7 +6,7 @@
<!--This header contains the command ids for the menus provided by the shell. -->
<Extern href="vsshlids.h"/>
<VisibilityConstraints>
<VisibilityItem guid="guidRelayCommandPackageCmdSet"
id="AddPageCommand" context="UICONTEXT_SolutionHasSingleProject" />

Просмотреть файл

@ -6,7 +6,7 @@
<!--This header contains the command ids for the menus provided by the shell. -->
<Extern href="vsshlids.h"/>
<VisibilityConstraints>
<VisibilityItem guid="guidRelayCommandPackageCmdSet"
id="AddPageCommand" context="UICONTEXT_SolutionHasSingleProject" />

Просмотреть файл

@ -6,7 +6,7 @@
<!--This header contains the command ids for the menus provided by the shell. -->
<Extern href="vsshlids.h"/>
<VisibilityConstraints>
<VisibilityItem guid="guidRelayCommandPackageCmdSet"
id="AddPageCommand" context="UICONTEXT_SolutionHasSingleProject" />

Просмотреть файл

@ -6,7 +6,7 @@
<!--This header contains the command ids for the menus provided by the shell. -->
<Extern href="vsshlids.h"/>
<VisibilityConstraints>
<VisibilityItem guid="guidRelayCommandPackageCmdSet"
id="AddPageCommand" context="UICONTEXT_SolutionHasSingleProject" />

Просмотреть файл

@ -6,7 +6,7 @@
<!--This header contains the command ids for the menus provided by the shell. -->
<Extern href="vsshlids.h"/>
<VisibilityConstraints>
<VisibilityItem guid="guidRelayCommandPackageCmdSet"
id="AddPageCommand" context="UICONTEXT_SolutionHasSingleProject" />

Просмотреть файл

@ -6,7 +6,7 @@
<!--This header contains the command ids for the menus provided by the shell. -->
<Extern href="vsshlids.h"/>
<VisibilityConstraints>
<VisibilityItem guid="guidRelayCommandPackageCmdSet"
id="AddPageCommand" context="UICONTEXT_SolutionHasSingleProject" />

Просмотреть файл

@ -6,7 +6,7 @@
<!--This header contains the command ids for the menus provided by the shell. -->
<Extern href="vsshlids.h"/>
<VisibilityConstraints>
<VisibilityItem guid="guidRelayCommandPackageCmdSet"
id="AddPageCommand" context="UICONTEXT_SolutionHasSingleProject" />

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше