-
-
Notifications
You must be signed in to change notification settings - Fork 49
/
BundleFileSetGenerator.cs
119 lines (104 loc) · 4.2 KB
/
BundleFileSetGenerator.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
using System;
using System.Collections.Generic;
using System.Linq;
using Smidge.Core;
using Smidge.FileProcessors;
using Smidge.Models;
using Smidge.Options;
namespace Smidge
{
/// <summary>
/// Returns the ordered file set and ensures that all pre-processor pipelines are applied correctly
/// </summary>
public class BundleFileSetGenerator : IBundleFileSetGenerator
{
private readonly FileProcessingConventions _conventions;
private readonly ISmidgeFileSystem _fileSystem;
public BundleFileSetGenerator(
ISmidgeFileSystem fileSystem,
FileProcessingConventions conventions)
{
_conventions = conventions ?? throw new ArgumentNullException(nameof(conventions));
_fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem));
}
/// <summary>
/// Returns the ordered file set for a bundle and ensures that all pre-processor pipelines are applied correctly
/// </summary>
/// <param name="bundle"></param>
/// <param name="pipeline"></param>
/// <returns></returns>
public IEnumerable<IWebFile> GetOrderedFileSet(Bundle bundle, PreProcessPipeline pipeline)
{
if (bundle == null) throw new ArgumentNullException(nameof(bundle));
if (pipeline == null) throw new ArgumentNullException(nameof(pipeline));
var ordered = GetOrderedFileSet(bundle.Files, pipeline);
//call the registered callback if any is set
return bundle.OrderingCallback == null ? ordered : bundle.OrderingCallback(ordered);
}
/// <summary>
/// Returns the ordered file set for dynamically registered assets and ensures that all pre-processor pipelines are applied correctly
/// </summary>
/// <param name="files"></param>
/// <param name="pipeline"></param>
/// <returns></returns>
public IEnumerable<IWebFile> GetOrderedFileSet(IEnumerable<IWebFile> files, PreProcessPipeline pipeline)
{
var customOrdered = new List<IWebFile>();
var defaultOrdered = new OrderedSet<IWebFile>(WebFilePairEqualityComparer.Instance);
foreach (var file in files)
{
ValidateFile(file);
file.Pipeline ??= pipeline;
var filePaths = _fileSystem.GetMatchingFiles(file.FilePath);
foreach (var f in filePaths)
{
var item = new WebFile
{
FilePath = f,
DependencyType = file.DependencyType,
Pipeline = file.Pipeline,
Order = file.Order
};
if (ApplyConventions(item) is { } webFile)
{
if (file.Order > 0)
{
customOrdered.Add(webFile);
}
else
{
defaultOrdered.Add(webFile);
}
}
}
}
// Add the custom ordered to the end of the list
foreach(var f in customOrdered.OrderBy(x => x.Order))
{
defaultOrdered.Add(f);
}
return defaultOrdered;
}
private IWebFile ApplyConventions(IWebFile file)
{
//Here we can apply some rules about the pipeline based on conventions.
// For example, if the file name ends with .min.js we don't want to have JsMin execute,
// there could be others of course and this should be configurable.
foreach (var convention in _conventions.Values)
{
if (file != null)
{
file = convention.Apply(file);
}
}
return file;
}
private void ValidateFile(IWebFile file)
{
if (file.Order < 0)
{
throw new NotSupportedException("The Order of a web file cannot be less than zero");
}
}
}
}