-
Notifications
You must be signed in to change notification settings - Fork 1
/
Program.cs
176 lines (147 loc) · 7.26 KB
/
Program.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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
using System.Diagnostics;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Xsl;
namespace Altairis.Xml4web.Compiler;
internal class Program {
public const int ErrorlevelSuccess = 0;
public const int ErrorlevelFailure = 1;
private static BuildConfiguration config;
private static void Main(string[] args) {
var version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
Console.WriteLine();
Console.WriteLine($@"o o o o o o o o XML4web Static Site Generator");
Console.WriteLine($@" \ / |\ /| | | | | Version {version}");
Console.WriteLine($@" O | O | | o--O o o o o-o O-o Copyright (c) 2018-2024");
Console.WriteLine($@" / \ | | | | \ / \ / |-' | | Michal A. Valášek - Altairis");
Console.WriteLine($@"o o o o O---o o o o o-o o-o www.xml4web.com | www.rider.cz");
Console.WriteLine();
var tsw = new Stopwatch();
tsw.Start();
LoadConfiguration(args);
// Delete and copy needed files
PrepareFileSystem();
// Create site metadata document
var metadataFileName = Path.Combine(config.WorkFolder, "metadata.xml");
var metadataDocument = CreateMetadataDocument();
metadataDocument.Save(metadataFileName);
// Run transforms
RunAllTransforms(metadataDocument);
// Check if there are some errors
tsw.Stop();
var logFiles = Directory.GetFiles(config.WorkFolder, "*.log");
if (logFiles.Length == 0) {
Console.WriteLine($"Build completed successfully in {tsw.ElapsedMilliseconds} ms.");
Environment.Exit(ErrorlevelSuccess);
} else {
Console.WriteLine($"Build failed in {tsw.ElapsedMilliseconds} ms. See the following log files:");
Console.WriteLine(string.Join(Environment.NewLine, logFiles));
Environment.Exit(ErrorlevelFailure);
}
}
private static void LoadConfiguration(string[] args) {
// Validate/load arguments
if (args.Length != 1) {
Console.WriteLine("USAGE: x4w-compiler buildscript.json");
Environment.Exit(ErrorlevelSuccess);
}
var buildScriptFileName = args[0];
if (!File.Exists(buildScriptFileName)) {
Console.WriteLine($"ERROR: File '{buildScriptFileName}' was not found!");
Environment.Exit(ErrorlevelFailure);
}
// Load configuration
Console.Write("Loading configuration...");
try {
config = BuildConfiguration.Load(buildScriptFileName);
Console.WriteLine("OK");
} catch (Exception ex) {
Console.WriteLine("Failed!");
Console.WriteLine(ex.Message);
Environment.Exit(ErrorlevelFailure);
}
}
private static void PrepareFileSystem() {
// Delete target and work folder
FileSystemHelper.DirectoryDelete(config.TargetFolder);
Directory.CreateDirectory(config.TargetFolder);
FileSystemHelper.DirectoryDelete(config.WorkFolder);
Directory.CreateDirectory(config.WorkFolder);
// Copy static data to output folder
if (!string.IsNullOrEmpty(config.StaticFolder) && Directory.Exists(config.StaticFolder)) {
Console.Write($"Copying {config.StaticFolder} to {config.TargetFolder}...");
try {
var sw = new Stopwatch();
sw.Start();
FileSystemHelper.DirectoryCopy(config.StaticFolder, config.TargetFolder);
sw.Stop();
Console.WriteLine($"OK in {sw.ElapsedMilliseconds} ms");
} catch (Exception ex) {
Console.WriteLine("Failed!");
Console.WriteLine(ex.Message);
Environment.Exit(ErrorlevelFailure);
}
}
}
private static SiteMetadataDocument CreateMetadataDocument() {
Console.Write("Creating metadata document...");
var sw = new Stopwatch();
sw.Start();
var doc = SiteMetadataDocument.CreateFromFolder(config.SourceFolder);
sw.Stop();
if (doc.Errors.Count > 0) {
Console.WriteLine($"Done in {sw.ElapsedMilliseconds} ms with {doc.Errors.Count} errors, see metadata.xml.log for details.");
File.WriteAllLines(Path.Combine(config.WorkFolder, "metadata.xml.log"), doc.Errors.Select(x => string.Join("\t", x.Key, x.Value)));
} else {
Console.WriteLine($"OK in {sw.ElapsedMilliseconds} ms");
}
return doc;
}
private static void RunAllTransforms(SiteMetadataDocument metadataDocument) {
Console.WriteLine("Running HTML transformations:");
foreach (var transform in config.HtmlTransforms) {
var templateFileName = Path.Combine(config.XsltFolder, transform.Key);
var outputFileName = Path.Combine(config.WorkFolder, Path.GetFileNameWithoutExtension(transform.Key) + ".xml");
RunTransform(metadataDocument, templateFileName, outputFileName);
Console.Write(" Running post-processor...");
var proc = new XmlOutputProcessor(outputFileName, config.TargetFolder);
proc.SaveAllFiles(transform.Value);
Console.WriteLine("OK");
}
// Run raw transforms
Console.WriteLine("Running raw transformations:");
foreach (var transform in config.RawTransforms) {
var templateFileName = Path.Combine(config.XsltFolder, transform.Key);
var outputFileName = Path.Combine(config.TargetFolder, transform.Value);
RunTransform(metadataDocument, templateFileName, outputFileName);
}
}
private static void RunTransform(IXPathNavigable metadataDocument, string templateFileName, string outputFileName) {
Console.Write($" Running {Path.GetFileName(templateFileName)}...");
try {
var sw = new Stopwatch();
sw.Start();
// Create output directory
Directory.CreateDirectory(Path.GetDirectoryName(outputFileName));
// Prepare transformation
var args = new XsltArgumentList();
args.AddExtensionObject(Namespaces.X4H, new XsltHelper(config));
foreach (var item in config.TransformParameters) {
args.AddParam(item.Key, Namespaces.X4C, item.Value);
}
var tran = new XslCompiledTransform();
tran.Load(templateFileName, XsltSettings.TrustedXslt, new XmlUrlResolver());
// Run transformation
using (var writer = File.CreateText(outputFileName)) {
tran.Transform(metadataDocument, args, writer);
}
sw.Stop();
Console.WriteLine($"OK in {sw.ElapsedMilliseconds} ms");
} catch (Exception ex) {
Console.WriteLine("Failed!");
var errorLogName = Path.Combine(config.WorkFolder, Path.GetFileName(templateFileName) + ".log");
Console.WriteLine($"For details see {errorLogName}");
File.WriteAllText(errorLogName, ex.ToString());
}
}
}