aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2017-12-31 02:17:12 -0800
committerRob Mensching <rob@firegiant.com>2017-12-31 02:17:12 -0800
commit651ad904724f32f5e993fa73aa11a611d95a1a10 (patch)
treec3f3541f36fe0dda04f2b756b59a0d7c535dbffa /src
parent84d1f05fee656c01938613bcc50bd8139006bbf6 (diff)
downloadwix-651ad904724f32f5e993fa73aa11a611d95a1a10.tar.gz
wix-651ad904724f32f5e993fa73aa11a611d95a1a10.tar.bz2
wix-651ad904724f32f5e993fa73aa11a611d95a1a10.zip
Support filtering localizations by culture
Diffstat (limited to 'src')
-rw-r--r--src/WixToolset.Core/CommandLine/BuildCommand.cs9
-rw-r--r--src/WixToolset.Core/CommandLine/CommandLineParser.cs32
-rw-r--r--src/WixToolset.Core/ResolveContext.cs2
-rw-r--r--src/WixToolset.Core/Resolver.cs66
4 files changed, 95 insertions, 14 deletions
diff --git a/src/WixToolset.Core/CommandLine/BuildCommand.cs b/src/WixToolset.Core/CommandLine/BuildCommand.cs
index 48f1b214..5097bd9b 100644
--- a/src/WixToolset.Core/CommandLine/BuildCommand.cs
+++ b/src/WixToolset.Core/CommandLine/BuildCommand.cs
@@ -13,20 +13,20 @@ namespace WixToolset.Core.CommandLine
13 13
14 internal class BuildCommand : ICommandLineCommand 14 internal class BuildCommand : ICommandLineCommand
15 { 15 {
16 public BuildCommand(IServiceProvider serviceProvider, IEnumerable<SourceFile> sources, IDictionary<string, string> preprocessorVariables, IEnumerable<string> locFiles, IEnumerable<string> libraryFiles, string outputPath, OutputType outputType, string cabCachePath, IEnumerable<string> cultures, bool bindFiles, IEnumerable<BindPath> bindPaths, IEnumerable<string> includeSearchPaths, string intermediateFolder, string contentsFile, string outputsFile, string builtOutputsFile) 16 public BuildCommand(IServiceProvider serviceProvider, IEnumerable<SourceFile> sources, IDictionary<string, string> preprocessorVariables, IEnumerable<string> locFiles, IEnumerable<string> libraryFiles, IEnumerable<string> filterCultures, string outputPath, OutputType outputType, string cabCachePath, bool bindFiles, IEnumerable<BindPath> bindPaths, IEnumerable<string> includeSearchPaths, string intermediateFolder, string contentsFile, string outputsFile, string builtOutputsFile)
17 { 17 {
18 this.ServiceProvider = serviceProvider; 18 this.ServiceProvider = serviceProvider;
19 this.Messaging = serviceProvider.GetService<IMessaging>(); 19 this.Messaging = serviceProvider.GetService<IMessaging>();
20 this.ExtensionManager = serviceProvider.GetService<IExtensionManager>(); 20 this.ExtensionManager = serviceProvider.GetService<IExtensionManager>();
21 this.LocFiles = locFiles; 21 this.LocFiles = locFiles;
22 this.LibraryFiles = libraryFiles; 22 this.LibraryFiles = libraryFiles;
23 this.FilterCultures = filterCultures;
23 this.PreprocessorVariables = preprocessorVariables; 24 this.PreprocessorVariables = preprocessorVariables;
24 this.SourceFiles = sources; 25 this.SourceFiles = sources;
25 this.OutputPath = outputPath; 26 this.OutputPath = outputPath;
26 this.OutputType = outputType; 27 this.OutputType = outputType;
27 28
28 this.CabCachePath = cabCachePath; 29 this.CabCachePath = cabCachePath;
29 this.Cultures = cultures;
30 this.BindFiles = bindFiles; 30 this.BindFiles = bindFiles;
31 this.BindPaths = bindPaths; 31 this.BindPaths = bindPaths;
32 this.IncludeSearchPaths = includeSearchPaths; 32 this.IncludeSearchPaths = includeSearchPaths;
@@ -43,6 +43,8 @@ namespace WixToolset.Core.CommandLine
43 43
44 public IExtensionManager ExtensionManager { get; } 44 public IExtensionManager ExtensionManager { get; }
45 45
46 public IEnumerable<string> FilterCultures { get; }
47
46 public IEnumerable<string> IncludeSearchPaths { get; } 48 public IEnumerable<string> IncludeSearchPaths { get; }
47 49
48 public IEnumerable<string> LocFiles { get; } 50 public IEnumerable<string> LocFiles { get; }
@@ -59,8 +61,6 @@ namespace WixToolset.Core.CommandLine
59 61
60 public string CabCachePath { get; } 62 public string CabCachePath { get; }
61 63
62 public IEnumerable<string> Cultures { get; }
63
64 public bool BindFiles { get; } 64 public bool BindFiles { get; }
65 65
66 public IEnumerable<BindPath> BindPaths { get; } 66 public IEnumerable<BindPath> BindPaths { get; }
@@ -205,6 +205,7 @@ namespace WixToolset.Core.CommandLine
205 { 205 {
206 var resolver = new Resolver(this.ServiceProvider); 206 var resolver = new Resolver(this.ServiceProvider);
207 resolver.BindPaths = this.BindPaths; 207 resolver.BindPaths = this.BindPaths;
208 resolver.FilterCultures = this.FilterCultures;
208 resolver.IntermediateFolder = this.IntermediateFolder; 209 resolver.IntermediateFolder = this.IntermediateFolder;
209 resolver.IntermediateRepresentation = output; 210 resolver.IntermediateRepresentation = output;
210 resolver.Localizations = localizations; 211 resolver.Localizations = localizations;
diff --git a/src/WixToolset.Core/CommandLine/CommandLineParser.cs b/src/WixToolset.Core/CommandLine/CommandLineParser.cs
index 500bed08..f4bc8ade 100644
--- a/src/WixToolset.Core/CommandLine/CommandLineParser.cs
+++ b/src/WixToolset.Core/CommandLine/CommandLineParser.cs
@@ -114,7 +114,7 @@ namespace WixToolset.Core.CommandLine
114 cmdline.GetNextArgumentOrError(ref cabCachePath); 114 cmdline.GetNextArgumentOrError(ref cabCachePath);
115 return true; 115 return true;
116 116
117 case "cultures": 117 case "culture":
118 cmdline.GetNextArgumentOrError(cultures); 118 cmdline.GetNextArgumentOrError(cultures);
119 return true; 119 return true;
120 case "contentsfile": 120 case "contentsfile":
@@ -210,8 +210,9 @@ namespace WixToolset.Core.CommandLine
210 var sourceFiles = GatherSourceFiles(files, outputFolder); 210 var sourceFiles = GatherSourceFiles(files, outputFolder);
211 var variables = this.GatherPreprocessorVariables(defines); 211 var variables = this.GatherPreprocessorVariables(defines);
212 var bindPathList = this.GatherBindPaths(bindPaths); 212 var bindPathList = this.GatherBindPaths(bindPaths);
213 var filterCultures = CalculateFilterCultures(cultures);
213 var type = CalculateOutputType(outputType, outputFile); 214 var type = CalculateOutputType(outputType, outputFile);
214 return new BuildCommand(this.ServiceProvider, sourceFiles, variables, locFiles, libraryFiles, outputFile, type, cabCachePath, cultures, bindFiles, bindPathList, includePaths, intermediateFolder, contentsFile, outputsFile, builtOutputsFile); 215 return new BuildCommand(this.ServiceProvider, sourceFiles, variables, locFiles, libraryFiles, filterCultures, outputFile, type, cabCachePath, bindFiles, bindPathList, includePaths, intermediateFolder, contentsFile, outputsFile, builtOutputsFile);
215 } 216 }
216 217
217 case Commands.Compile: 218 case Commands.Compile:
@@ -225,6 +226,33 @@ namespace WixToolset.Core.CommandLine
225 return null; 226 return null;
226 } 227 }
227 228
229 private static IEnumerable<string> CalculateFilterCultures(List<string> cultures)
230 {
231 var result = new List<string>();
232
233 if (cultures == null)
234 {
235 }
236 else if (cultures.Count == 1 && cultures[0].Equals("null", StringComparison.OrdinalIgnoreCase))
237 {
238 // When null is used treat it as if cultures wasn't specified. This is
239 // needed for batching in the MSBuild task since MSBuild doesn't support
240 // empty items.
241 }
242 else
243 {
244 foreach (var culture in cultures)
245 {
246 // Neutral is different from null. For neutral we still want to do culture filtering.
247 // Set the culture to the empty string = identifier for the invariant culture.
248 var filter = (culture.Equals("neutral", StringComparison.OrdinalIgnoreCase)) ? String.Empty : culture;
249 result.Add(filter);
250 }
251 }
252
253 return result;
254 }
255
228 private static OutputType CalculateOutputType(string outputType, string outputFile) 256 private static OutputType CalculateOutputType(string outputType, string outputFile)
229 { 257 {
230 if (String.IsNullOrEmpty(outputType)) 258 if (String.IsNullOrEmpty(outputType))
diff --git a/src/WixToolset.Core/ResolveContext.cs b/src/WixToolset.Core/ResolveContext.cs
index ca80d99c..d49a7d4b 100644
--- a/src/WixToolset.Core/ResolveContext.cs
+++ b/src/WixToolset.Core/ResolveContext.cs
@@ -25,6 +25,8 @@ namespace WixToolset.Core
25 25
26 public IEnumerable<IExtensionData> ExtensionData { get; set; } 26 public IEnumerable<IExtensionData> ExtensionData { get; set; }
27 27
28 public IEnumerable<string> FilterCultures { get; set; }
29
28 public string IntermediateFolder { get; set; } 30 public string IntermediateFolder { get; set; }
29 31
30 public Intermediate IntermediateRepresentation { get; set; } 32 public Intermediate IntermediateRepresentation { get; set; }
diff --git a/src/WixToolset.Core/Resolver.cs b/src/WixToolset.Core/Resolver.cs
index c2d5cc87..03cf344b 100644
--- a/src/WixToolset.Core/Resolver.cs
+++ b/src/WixToolset.Core/Resolver.cs
@@ -31,6 +31,8 @@ namespace WixToolset.Core
31 31
32 public IEnumerable<Localization> Localizations { get; set; } 32 public IEnumerable<Localization> Localizations { get; set; }
33 33
34 public IEnumerable<string> FilterCultures { get; set; }
35
34 public ResolveResult Execute() 36 public ResolveResult Execute()
35 { 37 {
36 var extensionManager = this.ServiceProvider.GetService<IExtensionManager>(); 38 var extensionManager = this.ServiceProvider.GetService<IExtensionManager>();
@@ -40,6 +42,7 @@ namespace WixToolset.Core
40 context.BindPaths = this.BindPaths; 42 context.BindPaths = this.BindPaths;
41 context.Extensions = extensionManager.Create<IResolverExtension>(); 43 context.Extensions = extensionManager.Create<IResolverExtension>();
42 context.ExtensionData = extensionManager.Create<IExtensionData>(); 44 context.ExtensionData = extensionManager.Create<IExtensionData>();
45 context.FilterCultures = this.FilterCultures;
43 context.IntermediateFolder = this.IntermediateFolder; 46 context.IntermediateFolder = this.IntermediateFolder;
44 context.IntermediateRepresentation = this.IntermediateRepresentation; 47 context.IntermediateRepresentation = this.IntermediateRepresentation;
45 context.Localizations = this.Localizations; 48 context.Localizations = this.Localizations;
@@ -207,29 +210,76 @@ namespace WixToolset.Core
207 { 210 {
208 var creator = context.ServiceProvider.GetService<ITupleDefinitionCreator>(); 211 var creator = context.ServiceProvider.GetService<ITupleDefinitionCreator>();
209 212
213 var localizations = FilterLocalizations(context);
214
215 foreach (var localization in localizations)
216 {
217 context.VariableResolver.AddLocalization(localization);
218 }
219
220 // Gather all the wix variables.
221 var wixVariableTuples = context.IntermediateRepresentation.Sections.SelectMany(s => s.Tuples).OfType<WixVariableTuple>();
222 foreach (var tuple in wixVariableTuples)
223 {
224 context.VariableResolver.AddVariable(tuple.SourceLineNumbers, tuple.WixVariable, tuple.Value, tuple.Overridable);
225 }
226 }
227
228 private static IEnumerable<Localization> FilterLocalizations(IResolveContext context)
229 {
230 var result = new List<Localization>();
231 var filter = CalculateCultureFilter(context);
232
210 var localizations = context.Localizations.Concat(context.IntermediateRepresentation.Localizations).ToList(); 233 var localizations = context.Localizations.Concat(context.IntermediateRepresentation.Localizations).ToList();
211 234
212 // Add localizations from the extensions with data. 235 // If there still is no filter, return all localizations.
236 AddFilteredLocalizations(result, filter, localizations);
237
238 // Filter localizations provided by extensions with data.
239 var creator = context.ServiceProvider.GetService<ITupleDefinitionCreator>();
240
213 foreach (var data in context.ExtensionData) 241 foreach (var data in context.ExtensionData)
214 { 242 {
215 var library = data.GetLibrary(creator); 243 var library = data.GetLibrary(creator);
216 244
217 if (library?.Localizations != null) 245 if (library?.Localizations != null)
218 { 246 {
219 localizations.AddRange(library.Localizations); 247 var extensionFilter = (!filter.Any() && data.DefaultCulture != null) ? new[] { data.DefaultCulture } : filter;
248
249 AddFilteredLocalizations(result, extensionFilter, library.Localizations);
220 } 250 }
221 } 251 }
222 252
223 foreach (var localization in localizations) 253 return result;
254 }
255
256 private static IEnumerable<string> CalculateCultureFilter(IResolveContext context)
257 {
258 var filter = context.FilterCultures ?? Array.Empty<string>();
259
260 // If no filter was specified, look for a language neutral localization file specified
261 // from the command-line (not embedded in the intermediate). If found, filter on language
262 // neutral.
263 if (!filter.Any() && context.Localizations.Any(l => String.IsNullOrEmpty(l.Culture)))
224 { 264 {
225 context.VariableResolver.AddLocalization(localization); 265 filter = new[] { String.Empty };
226 } 266 }
227 267
228 // Gather all the wix variables. 268 return filter;
229 var wixVariableTuples = context.IntermediateRepresentation.Sections.SelectMany(s => s.Tuples).OfType<WixVariableTuple>(); 269 }
230 foreach (var tuple in wixVariableTuples) 270
271 private static void AddFilteredLocalizations(List<Localization> result, IEnumerable<string> filter, IEnumerable<Localization> localizations)
272 {
273 if (!filter.Any())
231 { 274 {
232 context.VariableResolver.AddVariable(tuple.SourceLineNumbers, tuple.WixVariable, tuple.Value, tuple.Overridable); 275 result.AddRange(localizations);
276 }
277 else // filter localizations in order specified by the filter
278 {
279 foreach (var culture in filter)
280 {
281 result.AddRange(localizations.Where(l => culture.Equals(l.Culture, StringComparison.OrdinalIgnoreCase)));
282 }
233 } 283 }
234 } 284 }
235 } 285 }